diff --git a/crud/data-preparation/users.json b/crud/.data-preparation/users.json similarity index 100% rename from crud/data-preparation/users.json rename to crud/.data-preparation/users.json diff --git a/crud/data-preparation/users_import.sql b/crud/.data-preparation/users_import.sql similarity index 100% rename from crud/data-preparation/users_import.sql rename to crud/.data-preparation/users_import.sql diff --git a/crud/.server/Makefile b/crud/.server/Makefile new file mode 100644 index 0000000..382134c --- /dev/null +++ b/crud/.server/Makefile @@ -0,0 +1,5 @@ +run: + go run . + +build: + go build -tags prod . \ No newline at end of file diff --git a/crud/.server/api/echo.go b/crud/.server/api/echo.go new file mode 100644 index 0000000..e45fe02 --- /dev/null +++ b/crud/.server/api/echo.go @@ -0,0 +1,98 @@ +package api + +import ( + "encoding/json" + "log" + "mime" + "net/http" + "net/url" + "strings" + +) + +// isJSONLike checks if a string looks like it might be JSON +func isJSONLike(s string) bool { + s = strings.TrimSpace(s) + return (strings.HasPrefix(s, "{") && strings.HasSuffix(s, "}")) || + (strings.HasPrefix(s, "[") && strings.HasSuffix(s, "]")) +} + +// RequestEcho represents the structure of our response +type RequestEcho struct { + URL string `json:"url"` + Method string `json:"method"` + Path string `json:"path"` + QueryParams url.Values `json:"query_params"` + Headers http.Header `json:"headers"` // Use http.Header for canonical keys + Body interface{} `json:"body"` // Can be structured JSON or raw string + BodyRaw string `json:"body_raw"` // Original body as string + RemoteAddr string `json:"remote_addr"` + ContentType string `json:"content_type"` + ContentLength int64 `json:"content_length"` +} + +func EchoHandler() http.Handler + { + // Read body + bodyBytes := c.Body() // Fiber's way to get the body + bodyString := string(bodyBytes) + + // Try to parse body as JSON + var parsedBody interface{} + contentTypeHeader := c.Get("Content-Type") // Get Content-Type header + + if len(bodyBytes) > 0 { + mediaType, _, err := mime.ParseMediaType(contentTypeHeader) + // Only attempt JSON parsing if Content-Type is application/json or it looks like JSON + if (err == nil && mediaType == "application/json") || isJSONLike(bodyString) { + if jsonErr := json.Unmarshal(bodyBytes, &parsedBody); jsonErr != nil { + // If JSON parsing fails, parsedBody remains nil. + // It will be set to bodyString later if it's still nil. + parsedBody = nil + } + } + } + + if parsedBody == nil && len(bodyBytes) > 0 { + // For non-JSON bodies or if JSON parsing failed, use the raw string + parsedBody = bodyString + } + + // Query Parameters + queryParams, _ := url.ParseQuery(string(c.Request().URI().QueryString())) + + // Headers - ensuring canonical keys like net/http.Header + headers := make(http.Header) + c.Context().Request.Header.VisitAll(func(key, value []byte) { + k := string(key) + v := string(value) + headers.Add(k, v) // http.Header.Add appends, and canonicalizes the key on first Set/Add + }) + + // Create our response structure + echo := RequestEcho{ + URL: c.OriginalURL(), // Path and query string + Method: c.Method(), + Path: c.Path(), + QueryParams: queryParams, + Headers: headers, + Body: parsedBody, + BodyRaw: bodyString, + RemoteAddr: c.Context().RemoteAddr().String(), // IP and Port + ContentType: contentTypeHeader, + ContentLength: int64(c.Context().Request.Header.ContentLength()), + } + + // Marshal to JSON and write response + jsonResponse, err := json.MarshalIndent(echo, "", " ") + if err != nil { + log.Printf("Error creating JSON response: %v", err) + return c.Status(http.StatusInternalServerError).SendString("Error creating JSON response") + } + + c.Set("Content-Type", "application/json") + c.Status(http.StatusOK) + // Log the request to stdout + // fmt.Printf("Received %s request to %s\n", c.Method(), c.Path()) + return c.Send(jsonResponse) +} diff --git a/crud/.server/crud b/crud/.server/crud new file mode 100755 index 0000000..86fa185 Binary files /dev/null and b/crud/.server/crud differ diff --git a/crud/.server/datastar/consts.go b/crud/.server/datastar/consts.go new file mode 100644 index 0000000..9b896fa --- /dev/null +++ b/crud/.server/datastar/consts.go @@ -0,0 +1,115 @@ +// This is auto-generated by Datastar. DO NOT EDIT. + +package datastar + +import "time" + +const ( + DatastarKey = "datastar" + Version = "1.0.0-beta.11" + VersionClientByteSize = 40026 + VersionClientByteSizeGzip = 14900 + + //region Default durations + + // The default duration for retrying SSE on connection reset. This is part of the underlying retry mechanism of SSE. + DefaultSseRetryDuration = 1000 * time.Millisecond + + //endregion Default durations + + //region Default strings + + // The default attributes for + + + + +

The CRUD Example

+ +
+
+
+ + + + diff --git a/hypermedia/1-example/pico.blue.css b/crud/.server/frontend/pico.blue.css similarity index 100% rename from hypermedia/1-example/pico.blue.css rename to crud/.server/frontend/pico.blue.css diff --git a/crud/.server/getuser.sql b/crud/.server/getuser.sql new file mode 100644 index 0000000..34cf5ae --- /dev/null +++ b/crud/.server/getuser.sql @@ -0,0 +1,4 @@ +SELECT u.id, u.name, u.username, u.email, u.phone, u.website, a.street, a.suite, a.zipcode, a.city, c.name as company, c.catch_phrase, c.bs +FROM user u +JOIN company c ON u.company_id = c.id +JOIN address a ON u.address_id = a.id; diff --git a/crud/.server/go.mod b/crud/.server/go.mod new file mode 100644 index 0000000..5e6b19d --- /dev/null +++ b/crud/.server/go.mod @@ -0,0 +1,24 @@ +module crud + +go 1.25.0 + +require ( + github.com/CAFxX/httpcompression v0.0.9 + github.com/klauspost/compress v1.18.1 + github.com/valyala/bytebufferpool v1.0.0 + modernc.org/sqlite v1.40.0 +) + +require ( + github.com/andybalholm/brotli v1.0.5 // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/ncruces/go-strftime v0.1.9 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect + golang.org/x/sys v0.36.0 // indirect + modernc.org/libc v1.66.10 // indirect + modernc.org/mathutil v1.7.1 // indirect + modernc.org/memory v1.11.0 // indirect +) diff --git a/crud/.server/go.sum b/crud/.server/go.sum new file mode 100644 index 0000000..6bb762b --- /dev/null +++ b/crud/.server/go.sum @@ -0,0 +1,82 @@ +github.com/CAFxX/httpcompression v0.0.9 h1:0ue2X8dOLEpxTm8tt+OdHcgA+gbDge0OqFQWGKSqgrg= +github.com/CAFxX/httpcompression v0.0.9/go.mod h1:XX8oPZA+4IDcfZ0A71Hz0mZsv/YJOgYygkFhizVPilM= +github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/google/brotli/go/cbrotli v0.0.0-20230829110029-ed738e842d2f h1:jopqB+UTSdJGEJT8tEqYyE29zN91fi2827oLET8tl7k= +github.com/google/brotli/go/cbrotli v0.0.0-20230829110029-ed738e842d2f/go.mod h1:nOPhAkwVliJdNTkj3gXpljmWhjc4wCaVqbMJcPKWP4s= +github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= +github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= +github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= +github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= +github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/gozstd v1.20.1 h1:xPnnnvjmaDDitMFfDxmQ4vpx0+3CdTg2o3lALvXTU/g= +github.com/valyala/gozstd v1.20.1/go.mod h1:y5Ew47GLlP37EkTB+B4s7r6A5rdaeB7ftbl9zoYiIPQ= +golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= +golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= +golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ= +golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg= +golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +modernc.org/cc/v4 v4.26.5 h1:xM3bX7Mve6G8K8b+T11ReenJOT+BmVqQj0FY5T4+5Y4= +modernc.org/cc/v4 v4.26.5/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0= +modernc.org/ccgo/v4 v4.28.1 h1:wPKYn5EC/mYTqBO373jKjvX2n+3+aK7+sICCv4Fjy1A= +modernc.org/ccgo/v4 v4.28.1/go.mod h1:uD+4RnfrVgE6ec9NGguUNdhqzNIeeomeXf6CL0GTE5Q= +modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA= +modernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc= +modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI= +modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito= +modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks= +modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI= +modernc.org/libc v1.66.10 h1:yZkb3YeLx4oynyR+iUsXsybsX4Ubx7MQlSYEw4yj59A= +modernc.org/libc v1.66.10/go.mod h1:8vGSEwvoUoltr4dlywvHqjtAqHBaw0j1jI7iFBTAr2I= +modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= +modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= +modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= +modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= +modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8= +modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns= +modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w= +modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE= +modernc.org/sqlite v1.40.0 h1:bNWEDlYhNPAUdUdBzjAvn8icAs/2gaKlj4vM+tQ6KdQ= +modernc.org/sqlite v1.40.0/go.mod h1:9fjQZ0mB1LLP0GYrp39oOJXx/I2sxEnZtzCmEQIKvGE= +modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= +modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= +modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= +modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= diff --git a/crud/.server/main_dev.go b/crud/.server/main_dev.go new file mode 100644 index 0000000..69f3d18 --- /dev/null +++ b/crud/.server/main_dev.go @@ -0,0 +1,251 @@ +//go:build !prod +// +build !prod + +package main + +import ( + "context" + "crud/datastar" + "crud/sqlite" + "crypto/rand" + "embed" + "encoding/hex" + "fmt" + "html/template" + "io/fs" + "log" + "log/slog" + "net/http" + "os" + "os/signal" + "path/filepath" + "strings" + "sync" + "time" +) + +const ( + exitCodeErr = 1 + exitCodeInterrupt = 2 +) + +//go:embed frontend +var frontend embed.FS + +//go:embed templates +var templates embed.FS + +var templ = template.Must(template.ParseFS(templates, "templates/*.html")) + +// main is the entry point of the application. +// Its task is to check wether all execution conditions are fullfilled. +// Collecting information from the environment: flags, environment vars, configs. +// Calling the run() function. +func main() { + + fmt.Println("Developement mode") + + ctx := context.Background() + + // logging + logFileName := "./crud.log" + logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + log.Printf("error opening file: %v", err) + os.Exit(exitCodeErr) + } + defer logFile.Close() + log.SetOutput(logFile) + + // database + dbName := "./user.db" + db := sqlite.New(dbName) + if err != nil { + log.Printf("Failed to open %s database: %v", dbName, err) + os.Exit(exitCodeErr) + } + + // run the app + if err := run(db, ctx); err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(exitCodeErr) + } + +} + +// Setting up all dependencies +// Creating the server (a central http handler) +func run(db *sqlite.Database, ctx context.Context) error { + + ctx, cancel := signal.NotifyContext(ctx, os.Interrupt) + defer cancel() + + err := db.Open(ctx) + if err != nil { + log.Printf("Failed to open %s database: %v", db.Name(), err) + os.Exit(exitCodeErr) + } + defer db.Close() + + server := NewServer(db) + + httpServer := &http.Server{ + Addr: ":8080", + Handler: server, + } + + go func() { + log.Printf("listening on %s\n", httpServer.Addr) + if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { + fmt.Fprintf(os.Stderr, "error listening and serving: %s\n", err) + } + }() + + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + <-ctx.Done() + // make a new context for the Shutdown (thanks Alessandro Rosetti) + // shutdownCtx := context.Background() + shutdownCtx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + if err := httpServer.Shutdown(shutdownCtx); err != nil { + fmt.Fprintf(os.Stderr, "error shutting down http server: %s\n", err) + } + log.Printf("shut down http server on %s\n", httpServer.Addr) + }() + wg.Wait() + return nil +} + +// The NewServer constructor is responsible for all the top-level HTTP stuff that applies to all endpoints, like CORS, auth middleware, and logging: +func NewServer(db *sqlite.Database) http.Handler { + mux := http.NewServeMux() + + static, err := fs.Sub(frontend, "frontend") + if err != nil { + log.Fatal(err) + } + + // Print the embedded filesystem tree + fmt.Println("Embedded frontend filesystem tree:") + err = printFSTree(static, ".", 0) + if err != nil { + log.Printf("Error printing filesystem tree: %v\n", err) + } + fmt.Println("--- End of tree ---") + + addRoutes( + mux, + db, + static, + // templates, + ) + + mux.HandleFunc("GET /stream", func(w http.ResponseWriter, r *http.Request) { + ticker := time.NewTicker(1000 * time.Millisecond) + + // original: defer ticker.Stop() + + defer func() { + fmt.Println("defer executed") + ticker.Stop() + }() + + sse := datastar.NewSSE(w, r) + for { + select { + case <-r.Context().Done(): + slog.Debug("Client connection closed") + return + case <-ticker.C: + bytes := make([]byte, 3) + + if _, err := rand.Read(bytes); err != nil { + slog.Error("Error generating random bytes: ", slog.String("error", err.Error())) + return + } + hexString := hex.EncodeToString(bytes) + frag := fmt.Sprintf(`%s`, hexString, hexString, hexString) + + sse.MergeFragments(frag) + } + } + }) + + var handler http.Handler = mux + + // handler = authMiddleware(handler) + handler = headerMiddleware(handler) + + return handler +} + +// printFSTree prints a tree-like structure of the given filesystem. +func printFSTree(efs fs.FS, root string, indentLevel int) error { + return fs.WalkDir(efs, root, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + // Skip the root directory itself for cleaner output if it's "." + if path == "." && root == "." { + return nil + } + + indent := strings.Repeat("│ ", indentLevel) + connector := "├── " + // For the last item in a directory, use a different connector. + // This requires knowing if it's the last item, which fs.WalkDir doesn't directly provide. + // For simplicity, we'll use the same connector for all items. + // A more sophisticated approach would involve reading directory entries first. + + fmt.Printf("%s%s%s\n", indent, connector, filepath.Base(path)) + + if d.IsDir() && path != root { // Avoid infinite recursion for the root itself if not handled carefully + // The WalkDir function handles recursion, so we don't need to call printFSTree recursively here. + // We adjust indentLevel based on path depth for visual representation. + // This simple indentation based on WalkDir's path might not be perfect for deep structures + // but gives a good overview. + } + return nil + }) +} + +// authMiddleware is a simple authentication middleware +// func authMiddleware(next http.Handler) http.Handler { +// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { +// user, pass, ok := r.BasicAuth() +// if !ok || !validateUser(user, pass) { +// w.Header().Set("WWW-Authenticate", `Basic realm="Please enter your credentials"`) +// http.Error(w, "Unauthorized", http.StatusUnauthorized) +// return +// } +// next.ServeHTTP(w, r) +// }) +// } + +// authMiddleware is a simple authentication middleware +func headerMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Println("Request URL:", r.URL.String()) + fmt.Println("Request Headers:") + for key, values := range r.Header { + for _, value := range values { + if key == "Referer" || strings.HasPrefix(key, "Hx") { + + fmt.Printf("%s: %s\n", key, value) + } + } + } + fmt.Println() + next.ServeHTTP(w, r) + }) +} + +// validateUser validates the user credentials +func validateUser(username, password string) bool { + // In a real application, these credentials should be stored securely. + return strings.EqualFold(username, "admin") && password == "password" +} diff --git a/crud/.server/main_prod.go b/crud/.server/main_prod.go new file mode 100644 index 0000000..119e7d6 --- /dev/null +++ b/crud/.server/main_prod.go @@ -0,0 +1,252 @@ +//go:build prod +// +build prod + +package main + +import ( + "context" + "crypto/rand" + "embed" + "encoding/hex" + "fmt" + "io/fs" + "log" + "log/slog" + "crud/datastar" + "crud/sqlite" + "net/http" + "os" + "os/signal" + "path/filepath" + "strings" + "sync" + "time" +) + +const ( + exitCodeErr = 1 + exitCodeInterrupt = 2 +) + +//go:embed frontend +var frontend embed.FS + +//go:embed templates +var templates embed.FS + +// var templ = template.Must(template.ParseFS(templates, "templates/*.html")) + +// main is the entry point of the application. +// Its task is to check wether all execution conditions are fullfilled. +// Collecting information from the environment: flags, environment vars, configs. +// Calling the run() function. +func main() { + + // fmt.Println("Production mode") + + ctx := context.Background() + + // logging + logFileName := "./mva.log" + logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666) + if err != nil { + log.Printf("error opening file: %v", err) + os.Exit(exitCodeErr) + } + defer logFile.Close() + log.SetOutput(logFile) + + // database + dbName := "./user.db" + db := sqlite.New(dbName) + if err != nil { + log.Printf("Failed to open %s database: %v", dbName, err) + os.Exit(exitCodeErr) + } + + // run the app + if err := run(db, ctx); err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err) + os.Exit(exitCodeErr) + } + +} + +// Setting up all dependencies +// Creating the server (a central http handler) +func run(db *sqlite.Database, ctx context.Context) error { + + ctx, cancel := signal.NotifyContext(ctx, os.Interrupt) + defer cancel() + + err := db.Open(ctx) + if err != nil { + log.Printf("Failed to open %s database: %v", db.Name(), err) + os.Exit(exitCodeErr) + } + defer db.Close() + + server := NewServer(db) + + httpServer := &http.Server{ + Addr: ":8080", + Handler: server, + } + + go func() { + log.Printf("listening on %s\n", httpServer.Addr) + if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed { + fmt.Fprintf(os.Stderr, "error listening and serving: %s\n", err) + } + }() + + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + <-ctx.Done() + // make a new context for the Shutdown (thanks Alessandro Rosetti) + // shutdownCtx := context.Background() + shutdownCtx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + if err := httpServer.Shutdown(shutdownCtx); err != nil { + fmt.Fprintf(os.Stderr, "error shutting down http server: %s\n", err) + } + log.Printf("shut down http server on %s\n", httpServer.Addr) + }() + wg.Wait() + return nil +} + +// The NewServer constructor is responsible for all the top-level HTTP stuff that applies to all endpoints, like CORS, auth middleware, and logging: +func NewServer(db *sqlite.Database) http.Handler { + mux := http.NewServeMux() + + static, err := fs.Sub(frontend, "frontend") + if err != nil { + log.Fatal(err) + } + + // Print the embedded filesystem tree + fmt.Println("Embedded frontend filesystem tree:") + err = printFSTree(static, ".", 0) + if err != nil { + log.Printf("Error printing filesystem tree: %v\n", err) + } + fmt.Println("--- End of tree ---") + + addRoutes( + mux, + static, + nil, // templ + ) + + + mux.HandleFunc("GET /stream", func(w http.ResponseWriter, r *http.Request) { + ticker := time.NewTicker(1000 * time.Millisecond) + + // original: defer ticker.Stop() + + defer func() { + fmt.Println("defer executed") + ticker.Stop() + }() + + sse := datastar.NewSSE(w, r) + for { + select { + case <-r.Context().Done(): + slog.Debug("Client connection closed") + return + case <-ticker.C: + bytes := make([]byte, 3) + + if _, err := rand.Read(bytes); err != nil { + slog.Error("Error generating random bytes: ", slog.String("error", err.Error())) + return + } + hexString := hex.EncodeToString(bytes) + frag := fmt.Sprintf(`%s`, hexString, hexString, hexString) + + sse.MergeFragments(frag) + } + } + }) + + + + var handler http.Handler = mux + + // handler = authMiddleware(handler) + handler = headerMiddleware(handler) + + return handler +} + +// printFSTree prints a tree-like structure of the given filesystem. +func printFSTree(efs fs.FS, root string, indentLevel int) error { + return fs.WalkDir(efs, root, func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + + // Skip the root directory itself for cleaner output if it's "." + if path == "." && root == "." { + return nil + } + + indent := strings.Repeat("│ ", indentLevel) + connector := "├── " + // For the last item in a directory, use a different connector. + // This requires knowing if it's the last item, which fs.WalkDir doesn't directly provide. + // For simplicity, we'll use the same connector for all items. + // A more sophisticated approach would involve reading directory entries first. + + fmt.Printf("%s%s%s\n", indent, connector, filepath.Base(path)) + + if d.IsDir() && path != root { // Avoid infinite recursion for the root itself if not handled carefully + // The WalkDir function handles recursion, so we don't need to call printFSTree recursively here. + // We adjust indentLevel based on path depth for visual representation. + // This simple indentation based on WalkDir's path might not be perfect for deep structures + // but gives a good overview. + } + return nil + }) +} + +// authMiddleware is a simple authentication middleware +// func authMiddleware(next http.Handler) http.Handler { +// return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { +// user, pass, ok := r.BasicAuth() +// if !ok || !validateUser(user, pass) { +// w.Header().Set("WWW-Authenticate", `Basic realm="Please enter your credentials"`) +// http.Error(w, "Unauthorized", http.StatusUnauthorized) +// return +// } +// next.ServeHTTP(w, r) +// }) +// } + +// authMiddleware is a simple authentication middleware +func headerMiddleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Println("Request URL:", r.URL.String()) + fmt.Println("Request Headers:") + for key, values := range r.Header { + for _, value := range values { + if key == "Referer" || strings.HasPrefix(key, "Hx") { + + fmt.Printf("%s: %s\n", key, value) + } + } + } + fmt.Println() + next.ServeHTTP(w, r) + }) +} + +// validateUser validates the user credentials +func validateUser(username, password string) bool { + // In a real application, these credentials should be stored securely. + return strings.EqualFold(username, "admin") && password == "password" +} diff --git a/crud/.server/routes.go b/crud/.server/routes.go new file mode 100644 index 0000000..03c7ac6 --- /dev/null +++ b/crud/.server/routes.go @@ -0,0 +1,25 @@ +package main + +// This file is the one place in your application where all routes are listed. + +import ( + "crud/sqlite" + "io/fs" + "net/http" +) + +// addRoutes combines the URL endpoints with the applications's services +// and dependencies and required middleware +func addRoutes( + mux *http.ServeMux, + database *sqlite.Database, + static fs.FS, + // templ *template.Template, +) { + mux.Handle("GET /", http.FileServer(http.FS(static))) + // mux.Handle("GET /tables", api.TableList(database)) + // mux.Handle("GET /count", api.ProductCount(database)) + // mux.Handle("GET /nutriments/{page}", api.DataNutriments(database, templ)) + // mux.Handle("GET /products/{page}", api.DataProducts(database, templ)) + // mux.Handle("GET /brandowner/{page}", api.DataBrandOwner(database, templ)) +} diff --git a/crud/.server/sqlite/database.go b/crud/.server/sqlite/database.go new file mode 100644 index 0000000..73de4e3 --- /dev/null +++ b/crud/.server/sqlite/database.go @@ -0,0 +1,614 @@ +package sqlite // name the package as you see fit, it is intended to be vendored + +import ( + "bytes" + "database/sql" + "errors" + "context" + "fmt" + "os" + "strconv" + "text/template" + + _ "modernc.org/sqlite" +) + +/* +Package sqlite provides a simplified wrapper around the modernc.org/sqlite driver. + +It aims to provide a convenient, developer-friendly interface for common database +operations, prioritizing ease of use with a map-based data exchange format (Record). + +Key Concepts: + +- Database Instance: A single `Database` struct instance manages the connection to + a specific database file or an in-memory database. +- Lifecycle: Use `New()` to create an instance, `Open()` or `OpenInMemory()` + to establish the connection, and `defer Close()` to release resources. +- Record Type: `type Record = map[string]any` is the primary type for exchanging + data with the database. Column names become map keys. +- Underlying DB Access: The `DB()` method provides access to the raw `*sql.DB` + object for operations not covered by the wrapper. + +Features: + +- Reading Data: + - `ReadTable(tablename string)`: Reads all rows and columns from a specified table. + - `ReadRecords(query string, args ...any)`: Executes a custom SQL SELECT query + with parameterized arguments and returns multiple records. + - `GetRecord(tablename string, idfield string, key any)`: Retrieves a single + record from a table based on a unique identifier. +- Writing Data: + - `UpsertRecord(tablename string, idfield string, record Record)`: Inserts a new + record or updates an existing one based on the value of the `idfield`. + Uses SQLite's `ON CONFLICT` clause. + - Supports partial updates: Only include fields you want to insert/update in the `Record`. + - Returns the full resulting record (including auto-generated IDs) using `RETURNING *`. +- Deleting Data: + - `DeleteRecord(tablename string, idfield string, id any)`: Deletes a single + record from a table based on its identifier. +- Metadata: + - `TableList()`: Lists all tables in the database. + - `Version()`: Gets the SQLite library version. + - `UserVersion()`: Gets the database's user_version PRAGMA. + +Transaction Handling: + +- `Begin()`: Starts a new database transaction, returning a `*Transaction` object. +- Chaining: Transaction methods (`GetRecord`, `UpsertRecord`, `DeleteRecord`, `Next`) + return the `*Transaction` object, allowing operations to be chained. +- Error Propagation: If any operation within a transaction chain fails, the error + is stored in the `Transaction` object (`tx.Err()`), and subsequent chained + operations become no-ops. +- `Next(action Action)`: Allows executing custom logic within the transaction + by providing a function that receives the raw `*sql.Tx`. +- `End()`: Finalizes the transaction. If `tx.Err()` is non-nil, it performs a + ROLLBACK; otherwise, it performs a COMMIT. Returns the accumulated error. + +Helper Functions: + +- `ValueT any`: A generic helper to safely extract + and type-assert a value from a `Record` map. +- `NoRowsOk([]Record, error)`: A helper to wrap calls that might return + `sql.ErrNoRows` and treat that specific error as a non-error case, returning + nil records and a nil error. + +Prerequisites: + +- For `UpsertRecord` to function correctly, the target table must have a unique + index defined on the specified `idfield`. +- It is highly recommended that the `idfield` is an `INTEGER PRIMARY KEY AUTOINCREMENT` + to leverage SQLite's built-in ID generation and efficient lookups. + +Shortcomings and Important Considerations: + +- SQL Injection Risk: + - Identifiers: Table names, field names, and record keys (used as field names) + are validated to contain only alphanumeric characters and underscores. They are + also quoted by the library. This significantly mitigates SQL injection risks + through identifiers. However, the caller MUST still ensure that these identifiers + refer to the *intended* database objects. + - Query Structure: For `ReadRecords` and `Transaction.Next` actions, if the raw + SQL query string itself is constructed from untrusted user input, it remains a + potential SQL injection vector. Parameterization is used by this library (and + `database/sql`) only for *values*, not for the query structure or identifiers + within a user-provided query string. + +- Simplicity over Edge Cases: This is a simplified layer. More complex scenarios + or advanced SQLite features might require using the underlying `*sql.DB` object + via the `DB()` method. +- Room for Improvement: As a fresh implementation, there is potential for + further optimization and refinement. + +Implementation Details: + +- Uses the `modernc.org/sqlite` driver. +- SQL commands for `UpsertRecord` are dynamically generated using Go's `text/template`. +- Internal interfaces (`iquery`, `iExec`) are used to allow functions like `upsert` + and `deleteRecord` to work seamlessly with both `*sql.DB` and `*sql.Tx`. + +Unit Tests: + +- The package includes unit tests (`database_test.go`, `transaction_test.go`, `helpers_test.go`) + covering core functionality and transaction handling. +*/ + +// ErrInvalidIdentifier is returned when a table or column name contains disallowed characters. +var ErrInvalidIdentifier = errors.New("invalid identifier: contains disallowed characters") + +// This is the data type to exchange data with the database +type Record = map[string]any + +type Database struct { + databaseName string + database *sql.DB +} + +func New(DBName string) *Database { + return &Database{databaseName: DBName} +} + +func (d *Database) Close() error { + return d.database.Close() +} + +// provides access to the internal database object +func (d *Database) DB() *sql.DB { + return d.database +} + +func (d *Database) Name() string { + return d.databaseName +} + +// basePragmas returns a string of common PRAGMA settings for SQLite. +// It excludes user_version, which is typically managed by schema migrations. +func basePragmas() string { + return ` + PRAGMA page_size = 4096; + PRAGMA synchronous = NORMAL; + PRAGMA foreign_keys = ON; + PRAGMA journal_mode = WAL; + ` +} + +func (d *Database) Open(ctx context.Context) (err error) { + d.database, err = openSqliteDB(ctx, d.databaseName) + return err +} + +func (d *Database) OpenInMemory(ctx context.Context) (err error) { + db, err := sql.Open("sqlite", ":memory:") + if err != nil { + return err + } + // Apply base PRAGMAs for consistency in in-memory databases. + _, err = db.ExecContext(ctx, basePragmas()) + d.database = db + return err +} + +func openSqliteDB(ctx context.Context, databasefilename string) (*sql.DB, error) { + + _, err := os.Stat(databasefilename) + if errors.Is(err, os.ErrNotExist) { + return createDB(ctx, databasefilename) + } + if err != nil { + return nil, err + } + return sql.Open("sqlite", databasefilename) + +} + +func createDB(ctx context.Context, dbfileName string) (*sql.DB, error) { + // Apply base pragmas and set initial user_version for new database files. + query := basePragmas() + "PRAGMA user_version = 1;\n" + db, err := sql.Open("sqlite", dbfileName) + if err != nil { + return nil, err + } + _, err = db.ExecContext(ctx, query) + if err != nil { + db.Close() // Best effort to close if ExecContext fails + os.Remove(dbfileName) // Best effort to remove partially created file + return nil, err + } + return db, nil +} + +func (d *Database) TableList(ctx context.Context) (result []Record, err error) { + return d.ReadRecords(ctx, "select name from sqlite_master where type='table';") +} + +func (d *Database) ReadTable(ctx context.Context, tablename string) (result []Record, err error) { + if !isValidIdentifier(tablename) { + return nil, fmt.Errorf("ReadTable: %w: table name '%s'", ErrInvalidIdentifier, tablename) + } + return d.ReadRecords(ctx, fmt.Sprintf("select * from \"%s\";", tablename)) // Use double quotes for identifiers +} + +func (d *Database) ReadRecords(ctx context.Context, query string, args ...any) (result []Record, err error) { + // Note: For ReadRecords, the query string itself is provided by the caller. + // The library cannot validate the structure of this query beyond what the driver does. + // The SQL injection caveat for arbitrary query strings remains critical here. + rows, err := d.DB().QueryContext(ctx, query, args...) + if err != nil { + return result, err + } + defer rows.Close() + return Rows2records(rows) +} + +func (d *Database) GetRecord(ctx context.Context, tablename string, idfield string, key any) (result Record, err error) { + if !isValidIdentifier(tablename) { + return nil, fmt.Errorf("GetRecord: %w: table name '%s'", ErrInvalidIdentifier, tablename) + } + if !isValidIdentifier(idfield) { + return nil, fmt.Errorf("GetRecord: %w: id field '%s'", ErrInvalidIdentifier, idfield) + } + + query := fmt.Sprintf("select * from \"%s\" where \"%s\" = ?;", tablename, idfield) // Quote identifiers + res, err := d.DB().QueryContext(ctx, query, key) + if err != nil { + return result, err + } + defer res.Close() + return Rows2record(res) + +} + +func (d *Database) UpsertRecord(ctx context.Context, tablename string, idfield string, record Record) (result Record, err error) { + if !isValidIdentifier(tablename) { + return nil, fmt.Errorf("UpsertRecord: %w: table name '%s'", ErrInvalidIdentifier, tablename) + } + if !isValidIdentifier(idfield) { + return nil, fmt.Errorf("UpsertRecord: %w: id field '%s'", ErrInvalidIdentifier, idfield) + } + return upsert(ctx, d.DB(), tablename, idfield, record) + +} + +func (d *Database) DeleteRecord(ctx context.Context, tablename string, idfield string, id any) (err error) { + // Validation for tablename and idfield will be done by deleteRecord internal helper + // to ensure consistency for both Database and Transaction calls. + return deleteRecord(ctx, d.DB(), tablename, idfield, id) + +} + +// *sql.DB and *sql.Tx both have a method named 'Query', +// this way they can both be passed into upsert and deleteRecord function +type iqueryContext interface { + QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) +} + +// iExec is an interface satisfied by both *sql.DB and *sql.Tx for Exec method +type iExecContext interface { + ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) +} + +func upsert(ctx context.Context, q iqueryContext, tablename string, idfield string, record Record) (result Record, err error) { + // tablename and idfield are assumed to be validated by the public-facing methods (Database.UpsertRecord, Transaction.UpsertRecord) + + fields := []string{} + data := []any{} + for k, v := range record { + if !isValidIdentifier(k) { + return nil, fmt.Errorf("upsert: %w: field name '%s'", ErrInvalidIdentifier, k) + } + fields = append(fields, k) + data = append(data, v) + } + // Ensure idfield is part of the record if it's used for conflict and update, + // or handle cases where it might only be for conflict target and not in SET. + // The current buildUpsertCommand uses all fields from the record for the SET clause. + if _, present := record[idfield]; !present && len(record) > 0 { + // This situation is complex: if idfield is not in the record, + // it implies it might be auto-generated on INSERT, but for UPDATE, + // it's needed to identify the row. The ON CONFLICT target uses idfield. + // The current template includes all record fields in the SET clause. + // If idfield is not in record, it won't be in the SET clause unless explicitly added. + // For simplicity and current template, we assume if idfield is for update, it should be in the record. + } + if len(fields) == 0 { + return nil, errors.New("UpsertRecord: input record cannot be empty") + } + query, err := buildUpsertCommand(tablename, idfield, fields) + if err != nil { + return result, err + } + res, err := q.QueryContext(ctx, query, data...) // res contains the full record - see SQLite: RETURNING * + if err != nil { + return result, err + } + defer res.Close() + return Rows2record(res) +} + +func deleteRecord(ctx context.Context, e iExecContext, tablename string, idfield string, id any) (err error) { + if !isValidIdentifier(tablename) { + return fmt.Errorf("deleteRecord: %w: table name '%s'", ErrInvalidIdentifier, tablename) + } + if !isValidIdentifier(idfield) { + return fmt.Errorf("deleteRecord: %w: id field '%s'", ErrInvalidIdentifier, idfield) + } + + query := fmt.Sprintf("DELETE FROM \"%s\" WHERE \"%s\" = ?;", tablename, idfield) + _, err = e.ExecContext(ctx, query, id) + // Note: err could be sql.ErrNoRows if the driver/db supports it for Exec, + // or nil if delete affected 0 rows. Caller might want to check result.RowsAffected(). + // For simplicity here, we just return the error from Exec. + return err + +} + +func buildUpsertCommand(tablename string, idfield string, fields []string) (result string, err error) { + // Assumes tablename, idfield, and all elements in fields are already validated + // by the calling function (e.g., upsert). + // And that fields is not empty. + + pname := map[string]string{} // assign correct index for parameter name + // parameter position, starts at 1 in sql! So it needs to be calculated by function pname inside template + + for i, k := range fields { + pname[k] = strconv.Itoa(i + 1) + } + funcMap := template.FuncMap{ + "pname": func(fieldname string) string { + return pname[fieldname] + }, + } + tableDef := struct { + Tablename string + KeyField string + LastField int + FieldNames []string + }{ + Tablename: tablename, + KeyField: idfield, + LastField: len(fields) - 1, + FieldNames: fields, + } + var templString = `{{$last := .LastField}}INSERT INTO "{{ .Tablename }}"({{ range $i,$el := .FieldNames }} "{{$el}}"{{if ne $i $last}},{{end}}{{end}}) + VALUES({{ range $i,$el := .FieldNames }} ?{{pname $el}}{{if ne $i $last}},{{end}}{{end}}) + ON CONFLICT("{{ .Tablename }}"."{{.KeyField}}") + DO UPDATE SET {{ range $i,$el := .FieldNames }}"{{$el}}"= ?{{pname $el}}{{if ne $i $last}},{{end}}{{end}} + RETURNING *;` + + dbTempl, err := template.New("upsertDB").Funcs(funcMap).Parse(templString) + if err != nil { + return result, err + } + var templBytes bytes.Buffer + err = dbTempl.Execute(&templBytes, tableDef) + if err != nil { + return result, err + } + return templBytes.String(), nil +} + +func Rows2record(rows *sql.Rows) (Record, error) { + columns, err := rows.Columns() + if err != nil { + return nil, err + } + values := make([]any, len(columns)) + valuePtrs := make([]any, len(columns)) + for i := range values { + valuePtrs[i] = &values[i] + } + result := Record{} + + if !rows.Next() { + if err := rows.Err(); err != nil { // Check for errors during iteration attempt + return nil, err + } + return nil, sql.ErrNoRows // Standard error for no rows + } + + if err := rows.Scan(valuePtrs...); err != nil { + return nil, err + } + for i, col := range columns { + result[col] = values[i] + } + + // Check for errors encountered during iteration (e.g., if Next() was called multiple times). + if err := rows.Err(); err != nil { + return nil, err + } + + return result, nil +} + +func Rows2records(rows *sql.Rows) ([]Record, error) { + columns, err := rows.Columns() + if err != nil { + return nil, err + } + recLength := len(columns) + results := []Record{} + for rows.Next() { + valuePtrs := make([]any, recLength) + values := make([]any, recLength) + for i := range values { + valuePtrs[i] = &values[i] + } + record := Record{} + if err := rows.Scan(valuePtrs...); err != nil { + return nil, err + } + for i, col := range columns { + record[col] = values[i] + } + results = append(results, record) + } + // Check for errors encountered during iteration. + if err := rows.Err(); err != nil { + return nil, err + } + + if len(results) == 0 { + // For a function returning a slice, an empty slice and nil error is often preferred for "no rows". + // However, if the expectation is that Rows2records is used where rows *should* exist, sql.ErrNoRows is appropriate. + return nil, sql.ErrNoRows // Or: return []Record{}, nil if empty slice is the desired "no rows" outcome + } + return results, nil +} + +func (d *Database) Version(ctx context.Context) (string, error) { + var version string + err := d.DB().QueryRowContext(ctx, "SELECT sqlite_version();").Scan(&version) + return version, err +} + +func (d *Database) UserVersion(ctx context.Context) (int64, error) { + var result int64 + // PRAGMA user_version; returns a single row with a single column named "user_version". + // QueryRow().Scan() is appropriate here. + err := d.DB().QueryRowContext(ctx, "PRAGMA user_version;").Scan(&result) + return result, err +} + +func (d *Database) BeginTx(ctx context.Context, opts *sql.TxOptions) *Transaction { + tx, err := d.database.BeginTx(ctx, opts) + return &Transaction{tx, err} +} + +type Transaction struct { + tx *sql.Tx + err error +} + +// Err returns the current error state of the transaction. +func (t *Transaction) Err() error { + return t.err +} + +type Action func(ctx context.Context, tx *sql.Tx) error + +func (t *Transaction) Next(ctx context.Context, action Action) *Transaction { + if t.err != nil { + return t + } + t.err = action(ctx, t.tx) + return t +} + +func (t *Transaction) End() error { + if t.tx == nil { // Transaction was never begun or already ended + return t.err // Return any prior error + } + if t.err != nil { + err := t.tx.Rollback() // Rollback does not take context + if err != nil { + t.err = errors.Join(t.err, err) + } + return t.err + } + t.err = t.tx.Commit() + return t.err +} + +func (t *Transaction) GetRecord(ctx context.Context, tablename string, idfield string, key any, output Record) *Transaction { + if !isValidIdentifier(tablename) { + t.err = fmt.Errorf("Transaction.GetRecord: %w: table name '%s'", ErrInvalidIdentifier, tablename) + return t + } + if !isValidIdentifier(idfield) { + t.err = fmt.Errorf("Transaction.GetRecord: %w: id field '%s'", ErrInvalidIdentifier, idfield) + return t + } + + if t.err != nil { + return t + } + query := fmt.Sprintf("select * from \"%s\" where \"%s\" = ?;", tablename, idfield) // Quote identifiers + res, err := t.tx.QueryContext(ctx, query, key) + if err != nil { + t.err = err + return t + } + defer res.Close() + result, err := Rows2record(res) + if err != nil { + t.err = err + return t + } + for k := range output { + delete(output, k) + } + for k, v := range result { + output[k] = v + } + return t +} + +func (t *Transaction) UpsertRecord(ctx context.Context, tablename string, idfield string, record Record, output Record) *Transaction { + if !isValidIdentifier(tablename) { + t.err = fmt.Errorf("Transaction.UpsertRecord: %w: table name '%s'", ErrInvalidIdentifier, tablename) + return t + } + if !isValidIdentifier(idfield) { + t.err = fmt.Errorf("Transaction.UpsertRecord: %w: id field '%s'", ErrInvalidIdentifier, idfield) + return t + } + + if t.err != nil { + return t + } + result, err := upsert(ctx, t.tx, tablename, idfield, record) + if err != nil { + t.err = err + return t + } + for k := range output { + delete(output, k) + } + for k, v := range result { + output[k] = v + } + return t +} + +func (t *Transaction) DeleteRecord(ctx context.Context, tablename string, idfield string, id any) *Transaction { + // Validation will be done by the internal deleteRecord helper + // if !isValidIdentifier(tablename) { + // t.err = fmt.Errorf("Transaction.DeleteRecord: %w: table name '%s'", ErrInvalidIdentifier, tablename) + // return t + // } + // if !isValidIdentifier(idfield) { + // t.err = fmt.Errorf("Transaction.DeleteRecord: %w: id field '%s'", ErrInvalidIdentifier, idfield) + // return t + // } + + if t.err != nil { + return t + } + err := deleteRecord(ctx, t.tx, tablename, idfield, id) // t.tx satisfies iExecContext + if err != nil { + t.err = err + } + return t +} + +// returns a value of the provided type, if the field exist and if it can be cast into the provided type parameter +func Value[T any](rec Record, field string) (value T, ok bool) { + var v any + // No validation for 'field' here as it's used to access a map key from an existing Record, + // not to construct SQL. + if v, ok = rec[field]; ok { + value, ok = v.(T) + } + return +} + +// don't report an error if there are simply just 'no rows found' +func NoRowsOk(recs []Record, err error) ([]Record, error) { + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + // Return an empty, non-nil slice and nil error to indicate "no rows found, but that's okay". + // This makes it safer for callers to immediately use len() or range over the result. + return []Record{}, nil + } + return recs, err + } + return recs, nil +} + +// isValidIdentifier checks if the given string is a safe identifier. +// Allows alphanumeric characters and underscores. Must not be empty. +func isValidIdentifier(identifier string) bool { + if len(identifier) == 0 { + return false + } + for _, r := range identifier { + if !((r >= 'a' && r <= 'z') || + (r >= 'A' && r <= 'Z') || + (r >= '0' && r <= '9') || + r == '_') { + return false + } + } + return true +} diff --git a/crud/.server/templates/board-content.html b/crud/.server/templates/board-content.html new file mode 100644 index 0000000..e69de29 diff --git a/crud/.show-it b/crud/.show-it new file mode 100644 index 0000000..b9c658a --- /dev/null +++ b/crud/.show-it @@ -0,0 +1,5 @@ +clear +cp .user.db user.db +ls -l +echo "The CRUD Example" +---PAUSE--- diff --git a/hypermedia/2-example/datastar.js b/crud/datastar.js similarity index 100% rename from hypermedia/2-example/datastar.js rename to crud/datastar.js diff --git a/hypermedia/2-example/datastar.js.map b/crud/datastar.js.map similarity index 100% rename from hypermedia/2-example/datastar.js.map rename to crud/datastar.js.map diff --git a/hypermedia/1-example/index.html b/crud/index.html similarity index 100% rename from hypermedia/1-example/index.html rename to crud/index.html diff --git a/hypermedia/2-example/pico.blue.css b/crud/pico.blue.css similarity index 100% rename from hypermedia/2-example/pico.blue.css rename to crud/pico.blue.css diff --git a/demo/data-/.index.html b/demo/data-/.index.html new file mode 100644 index 0000000..58831ec --- /dev/null +++ b/demo/data-/.index.html @@ -0,0 +1,35 @@ + + + + + + + + Random Number Buttons + + + + +
+

Click for Random Numbers

+
+ + + +
+
+ + + + + diff --git a/demo/data-/.show-it b/demo/data-/.show-it index bfc4482..04b4bb8 100644 --- a/demo/data-/.show-it +++ b/demo/data-/.show-it @@ -1,4 +1,5 @@ clear +cp .index.html index.html ls -l ---PAUSE--- echo "live-server is running - press ctrl-c" diff --git a/demo/data-/buttons.css b/demo/data-/buttons.css new file mode 100644 index 0000000..0676eb3 --- /dev/null +++ b/demo/data-/buttons.css @@ -0,0 +1,33 @@ +button { + transition: background-color 0.3s ease; +} + +/* Red: 10+ clicks (2 or more digits) - put this FIRST */ +button[data-count]:not([data-count="1"]):not([data-count="2"]):not([data-count="3"]):not([data-count="4"]):not([data-count="5"]):not([data-count="6"]):not([data-count="7"]):not([data-count="8"]):not([data-count="9"]) { + background-color: #ef4444; + border-color: #ef4444; +} + +/* Green: 1-3 clicks - these override red due to higher specificity */ +button[data-count="1"], +button[data-count="2"], +button[data-count="3"] { + background-color: #22c55e; + border-color: #22c55e; +} + +/* Yellow: 4-6 clicks */ +button[data-count="4"], +button[data-count="5"], +button[data-count="6"] { + background-color: #eab308; + border-color: #eab308; +} + +/* Orange: 7-9 clicks */ +button[data-count="7"], +button[data-count="8"], +button[data-count="9"] { + background-color: #f97316; + border-color: #f97316; +} \ No newline at end of file diff --git a/demo/data-/index.html b/demo/data-/index.html index 2a6de71..abf127a 100644 --- a/demo/data-/index.html +++ b/demo/data-/index.html @@ -6,12 +6,12 @@ Random Number Buttons - +
-

Click for Random Numbers

+

Click for Random Numbers

@@ -27,9 +27,9 @@ el.textContent = randomNum; el.dataset.count = (el.dataset.count | 0) + 1; - + } - \ No newline at end of file + diff --git a/hypermedia/1-example/.show-it b/demo/datasstar-static/html-snippets/.show-it similarity index 100% rename from hypermedia/1-example/.show-it rename to demo/datasstar-static/html-snippets/.show-it diff --git a/demo/datasstar-static/html-snippets/datastar.js b/demo/datasstar-static/html-snippets/datastar.js new file mode 100644 index 0000000..be57e9d --- /dev/null +++ b/demo/datasstar-static/html-snippets/datastar.js @@ -0,0 +1,9 @@ +// Datastar v1.0.0-RC.6 +var nt=/🖕JS_DS🚀/.source,De=nt.slice(0,5),Ve=nt.slice(4),q="datastar-fetch",z="datastar-signal-patch";var de=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/([a-z])([0-9]+)/gi,"$1-$2").replace(/([0-9]+)([a-z])/gi,"$1-$2").toLowerCase();var rt=e=>de(e).replace(/-/g,"_");var re=e=>{try{return JSON.parse(e)}catch{return Function(`return (${e})`)()}},st={camel:e=>e.replace(/-[a-z]/g,t=>t[1].toUpperCase()),snake:e=>e.replace(/-/g,"_"),pascal:e=>e[0].toUpperCase()+st.camel(e.slice(1))},R=(e,t,n="camel")=>{for(let r of t.get("case")||[n])e=st[r]?.(e)||e;return e},Q=e=>`data-${e}`;var _=Object.hasOwn??Object.prototype.hasOwnProperty.call;var se=e=>e!==null&&typeof e=="object"&&(Object.getPrototypeOf(e)===Object.prototype||Object.getPrototypeOf(e)===null),it=e=>{for(let t in e)if(_(e,t))return!1;return!0},Z=(e,t)=>{for(let n in e){let r=e[n];se(r)||Array.isArray(r)?Z(r,t):e[n]=t(r)}},Te=e=>{let t={};for(let[n,r]of e){let s=n.split("."),i=s.pop(),a=s.reduce((o,c)=>o[c]??={},t);a[i]=r}return t};var Ae=[],Ie=[],Fe=0,Re=0,$e=0,qe,G,we=0,w=()=>{Fe++},M=()=>{--Fe||(ct(),Y())},V=e=>{qe=G,G=e},I=()=>{G=qe,qe=void 0},me=e=>It.bind(0,{previousValue:e,t:e,e:1}),Ge=Symbol("computed"),Ne=e=>{let t=$t.bind(0,{e:17,getter:e});return t[Ge]=1,t},E=e=>{let t={d:e,e:2};G&&Be(t,G),V(t),w();try{t.d()}finally{M(),I()}return dt.bind(0,t)},ct=()=>{for(;Re<$e;){let e=Ie[Re];Ie[Re++]=void 0,ut(e,e.e&=-65)}Re=0,$e=0},ot=e=>"getter"in e?lt(e):ft(e,e.t),lt=e=>{V(e),mt(e);try{let t=e.t;return t!==(e.t=e.getter(t))}finally{I(),pt(e)}},ft=(e,t)=>(e.e=1,e.previousValue!==(e.previousValue=t)),je=e=>{let t=e.e;if(!(t&64)){e.e=t|64;let n=e.r;n?je(n.o):Ie[$e++]=e}},ut=(e,t)=>{if(t&16||t&32&>(e.s,e)){V(e),mt(e),w();try{e.d()}finally{M(),I(),pt(e)}return}t&32&&(e.e=t&-33);let n=e.s;for(;n;){let r=n.c,s=r.e;s&64&&ut(r,r.e=s&-65),n=n.i}},It=(e,...t)=>{if(t.length){if(e.t!==(e.t=t[0])){e.e=17;let r=e.r;return r&&(qt(r),Fe||ct()),!0}return!1}let n=e.t;if(e.e&16&&ft(e,n)){let r=e.r;r&&Le(r)}return G&&Be(e,G),n},$t=e=>{let t=e.e;if(t&16||t&32&>(e.s,e)){if(lt(e)){let n=e.r;n&&Le(n)}}else t&32&&(e.e=t&-33);return G&&Be(e,G),e.t},dt=e=>{let t=e.s;for(;t;)t=xe(t,e);let n=e.r;n&&xe(n),e.e=0},Be=(e,t)=>{let n=t.a;if(n&&n.c===e)return;let r=n?n.i:t.s;if(r&&r.c===e){r.m=we,t.a=r;return}let s=e.p;if(s&&s.m===we&&s.o===t)return;let i=t.a=e.p={m:we,c:e,o:t,l:n,i:r,f:s};r&&(r.l=i),n?n.i=i:t.s=i,s?s.n=i:e.r=i},xe=(e,t=e.o)=>{let n=e.c,r=e.l,s=e.i,i=e.n,a=e.f;if(s?s.l=r:t.a=r,r?r.i=s:t.s=s,i?i.f=a:n.p=a,a)a.n=i;else if(!(n.r=i))if("getter"in n){let o=n.s;if(o){n.e=17;do o=xe(o,n);while(o)}}else"previousValue"in n||dt(n);return s},qt=e=>{let t=e.n,n;e:for(;;){let r=e.o,s=r.e;if(s&60?s&12?s&4?!(s&48)&&Gt(e,r)?(r.e=s|40,s&=1):s=0:r.e=s&-9|32:s=0:r.e=s|32,s&2&&je(r),s&1){let i=r.r;if(i){let a=(e=i).n;a&&(n={t,u:n},t=a);continue}}if(e=t){t=e.n;continue}for(;n;)if(e=n.t,n=n.u,e){t=e.n;continue e}break}},mt=e=>{we++,e.a=void 0,e.e=e.e&-57|4},pt=e=>{let t=e.a,n=t?t.i:e.s;for(;n;)n=xe(n,e);e.e&=-5},gt=(e,t)=>{let n,r=0,s=!1;e:for(;;){let i=e.c,a=i.e;if(t.e&16)s=!0;else if((a&17)===17){if(ot(i)){let o=i.r;o.n&&Le(o),s=!0}}else if((a&33)===33){(e.n||e.f)&&(n={t:e,u:n}),e=i.s,t=i,++r;continue}if(!s){let o=e.i;if(o){e=o;continue}}for(;r--;){let o=t.r,c=o.n;if(c?(e=n.t,n=n.u):e=o,s){if(ot(t)){c&&Le(o),t=e.o;continue}s=!1}else t.e&=-33;if(t=e.o,e.i){e=e.i;continue e}}return s}},Le=e=>{do{let t=e.o,n=t.e;(n&48)===32&&(t.e=n|16,n&2&&je(t))}while(e=e.n)},Gt=(e,t)=>{let n=t.a;for(;n;){if(n===e)return!0;n=n.l}return!1},ie=e=>{let t=X,n=e.split(".");for(let r of n){if(t==null||!_(t,r))return;t=t[r]}return t},Me=(e,t="")=>{let n=Array.isArray(e);if(n||se(e)){let r=n?[]:{};for(let i in e)r[i]=me(Me(e[i],`${t+i}.`));let s=me(0);return new Proxy(r,{get(i,a){if(!(a==="toJSON"&&!_(r,a)))return n&&a in Array.prototype?(s(),r[a]):typeof a=="symbol"?r[a]:((!_(r,a)||r[a]()==null)&&(r[a]=me(""),Y(t+a,""),s(s()+1)),r[a]())},set(i,a,o){let c=t+a;if(n&&a==="length"){let l=r[a]-o;if(r[a]=o,l>0){let f={};for(let d=o;d{if(e!==void 0&&t!==void 0&&Ae.push([e,t]),!Fe&&Ae.length){let n=Te(Ae);Ae.length=0,document.dispatchEvent(new CustomEvent(z,{detail:n}))}},C=(e,{ifMissing:t}={})=>{w();for(let n in e)e[n]==null?t||delete X[n]:ht(e[n],n,X,"",t);M()},S=(e,t)=>C(Te(e),t),ht=(e,t,n,r,s)=>{if(se(e)){_(n,t)&&(se(n[t])||Array.isArray(n[t]))||(n[t]={});for(let i in e)e[i]==null?s||delete n[t][i]:ht(e[i],i,n[t],`${r+t}.`,s)}else s&&_(n,t)||(n[t]=e)},at=e=>typeof e=="string"?RegExp(e.replace(/^\/|\/$/g,"")):e,D=({include:e=/.*/,exclude:t=/(?!)/}={},n=X)=>{let r=at(e),s=at(t),i=[],a=[[n,""]];for(;a.length;){let[o,c]=a.pop();for(let l in o){let f=c+l;se(o[l])?a.push([o[l],`${f}.`]):r.test(f)&&!s.test(f)&&i.push([f,ie(f)])}}return Te(i)},X=Me({});var W=e=>e instanceof HTMLElement||e instanceof SVGElement||e instanceof MathMLElement;var jt="https://data-star.dev/errors",pe=(e,t,n={})=>{Object.assign(n,e);let r=new Error,s=rt(t),i=new URLSearchParams({metadata:JSON.stringify(n)}).toString(),a=JSON.stringify(n,null,2);return r.message=`${t} +More info: ${jt}/${s}?${i} +Context: ${a}`,r},Oe=new Map,vt=new Map,bt=new Map,Et=new Proxy({},{get:(e,t)=>Oe.get(t)?.apply,has:(e,t)=>Oe.has(t),ownKeys:()=>Reflect.ownKeys(Oe),set:()=>!1,deleteProperty:()=>!1}),ge=new Map,Ce=[],We=new Set,p=e=>{Ce.push(e),Ce.length===1&&setTimeout(()=>{for(let t of Ce)We.add(t.name),vt.set(t.name,t);Ce.length=0,Jt(),We.clear()})},O=e=>{Oe.set(e.name,e)};document.addEventListener(q,e=>{let t=bt.get(e.detail.type);t&&t.apply({error:pe.bind(0,{plugin:{type:"watcher",name:t.name},element:{id:e.target.id,tag:e.target.tagName}})},e.detail.argsRaw)});var he=e=>{bt.set(e.name,e)},yt=e=>{for(let t of e){let n=ge.get(t);if(ge.delete(t)){for(let r of n.values())r();n.clear()}}},St=Q("ignore"),Bt=`[${St}]`,Tt=e=>e.hasAttribute(`${St}__self`)||!!e.closest(Bt),Pe=(e,t)=>{for(let n of e)if(!Tt(n))for(let r in n.dataset)At(n,r.replace(/[A-Z]/g,"-$&").toLowerCase(),n.dataset[r],t)},Wt=e=>{for(let{target:t,type:n,attributeName:r,addedNodes:s,removedNodes:i}of e)if(n==="childList"){for(let a of i)W(a)&&(yt([a]),yt(a.querySelectorAll("*")));for(let a of s)W(a)&&(Pe([a]),Pe(a.querySelectorAll("*")))}else if(n==="attributes"&&r.startsWith("data-")&&W(t)&&!Tt(t)){let a=r.slice(5),o=t.getAttribute(r);if(o===null){let c=ge.get(t);c&&(c.get(a)?.(),c.delete(a))}else At(t,a,o)}},Ut=new MutationObserver(Wt),Jt=(e=document.documentElement)=>{W(e)&&Pe([e],!0),Pe(e.querySelectorAll("*"),!0),Ut.observe(e,{subtree:!0,childList:!0,attributes:!0})},At=(e,t,n,r)=>{{let s=t,[i,...a]=s.split("__"),[o,c]=i.split(/:(.+)/),l=vt.get(o);if((!r||We.has(o))&&l){let f={el:e,rawKey:s,mods:new Map,error:pe.bind(0,{plugin:{type:"attribute",name:l.name},element:{id:e.id,tag:e.tagName},expression:{rawKey:s,key:c,value:n}}),key:c,value:n,rx:void 0},d=l.requirement&&(typeof l.requirement=="string"?l.requirement:l.requirement.key)||"allowed",x=l.requirement&&(typeof l.requirement=="string"?l.requirement:l.requirement.value)||"allowed";if(c){if(d==="denied")throw f.error("KeyNotAllowed")}else if(d==="must")throw f.error("KeyRequired");if(n){if(x==="denied")throw f.error("ValueNotAllowed")}else if(x==="must")throw f.error("ValueRequired");if(d==="exclusive"||x==="exclusive"){if(c&&n)throw f.error("KeyAndValueProvided");if(!c&&!n)throw f.error("KeyOrValueRequired")}if(n){let m;f.rx=(...h)=>(m||(m=Kt(n,{returnsValue:l.returnsValue,argNames:l.argNames})),m(e,...h))}for(let m of a){let[h,...v]=m.split(".");f.mods.set(h,new Set(v))}let u=l.apply(f);if(u){let m=ge.get(e);m?m.get(s)?.():(m=new Map,ge.set(e,m)),m.set(s,u)}}}},Kt=(e,{returnsValue:t=!1,argNames:n=[]}={})=>{let r="";if(t){let o=/(\/(\\\/|[^/])*\/|"(\\"|[^"])*"|'(\\'|[^'])*'|`(\\`|[^`])*`|\(\s*((function)\s*\(\s*\)|(\(\s*\))\s*=>)\s*(?:\{[\s\S]*?\}|[^;){]*)\s*\)\s*\(\s*\)|[^;])+/gm,c=e.trim().match(o);if(c){let l=c.length-1,f=c[l].trim();f.startsWith("return")||(c[l]=`return (${f});`),r=c.join(`; +`)}}else r=e.trim();let s=new Map,i=RegExp(`(?:${De})(.*?)(?:${Ve})`,"gm"),a=0;for(let o of r.matchAll(i)){let c=o[1],l=`__escaped${a++}`;s.set(l,c),r=r.replace(De+c+Ve,l)}r=r.replace(/\$\['([a-zA-Z_$\d][\w$]*)'\]/g,"$$$1").replace(/\$([a-zA-Z_\d]\w*(?:[.-]\w+)*)/g,(o,c)=>c.split(".").reduce((l,f)=>`${l}['${f}']`,"$")).replace(/\[(\$[a-zA-Z_\d]\w*)\]/g,(o,c)=>`[$['${c.slice(1)}']]`),r=r.replaceAll(/@(\w+)\(/g,'__action("$1",evt,');for(let[o,c]of s)r=r.replace(o,c);try{let o=Function("el","$","__action","evt",...n,r);return(c,...l)=>{let f=(d,x,...u)=>{let m=pe.bind(0,{plugin:{type:"action",name:d},element:{id:c.id,tag:c.tagName},expression:{fnContent:r,value:e}}),h=Et[d];if(h)return h({el:c,evt:x,error:m},...u);throw m("UndefinedAction")};try{return o(c,X,f,void 0,...l)}catch(d){throw console.error(d),pe({element:{id:c.id,tag:c.tagName},expression:{fnContent:r,value:e},error:d.message},"ExecuteExpression")}}}catch(o){throw console.error(o),pe({expression:{fnContent:r,value:e},error:o.message},"GenerateExpression")}};var P=new Map,ae=new Set,oe=new Map,ye=new Set,ce=document.createElement("div");ce.hidden=!0;var ve=Q("ignore-morph"),zt=`[${ve}]`,Ke=(e,t,n="outer")=>{if(W(e)&&W(t)&&e.hasAttribute(ve)&&t.hasAttribute(ve)||e.parentElement?.closest(zt))return;let r=document.createElement("div");r.append(t),document.body.insertAdjacentElement("afterend",ce);let s=e.querySelectorAll("[id]");for(let{id:o,tagName:c}of s)oe.has(o)?ye.add(o):oe.set(o,c);e instanceof Element&&e.id&&(oe.has(e.id)?ye.add(e.id):oe.set(e.id,e.tagName)),ae.clear();let i=r.querySelectorAll("[id]");for(let{id:o,tagName:c}of i)ae.has(o)?ye.add(o):oe.get(o)===c&&ae.add(o);for(let o of ye)ae.delete(o);oe.clear(),ye.clear(),P.clear();let a=n==="outer"?e.parentElement:e;wt(a,s),wt(r,i),Mt(a,r,n==="outer"?e:null,e.nextSibling),ce.remove()},Mt=(e,t,n=null,r=null)=>{e instanceof HTMLTemplateElement&&t instanceof HTMLTemplateElement&&(e=e.content,t=t.content),n??=e.firstChild;for(let s of t.childNodes){if(n&&n!==r){let i=Qt(s,n,r);if(i){if(i!==n){let a=n;for(;a&&a!==i;){let o=a;a=a.nextSibling,Je(o)}}Ue(i,s),n=i.nextSibling;continue}}if(s instanceof Element&&ae.has(s.id)){let i=document.getElementById(s.id),a=i;for(;a=a.parentNode;){let o=P.get(a);o&&(o.delete(s.id),o.size||P.delete(a))}xt(e,i,n),Ue(i,s),n=i.nextSibling;continue}if(P.has(s)){let i=document.createElement(s.tagName);e.insertBefore(i,n),Ue(i,s),n=i.nextSibling}else{let i=document.importNode(s,!0);e.insertBefore(i,n),n=i.nextSibling}}for(;n&&n!==r;){let s=n;n=n.nextSibling,Je(s)}},Qt=(e,t,n)=>{let r=null,s=e.nextSibling,i=0,a=0,o=P.get(e)?.size||0,c=t;for(;c&&c!==n;){if(Rt(c,e)){let l=!1,f=P.get(c),d=P.get(e);if(d&&f){for(let x of f)if(d.has(x)){l=!0;break}}if(l)return c;if(!r&&!P.has(c)){if(!o)return c;r=c}}if(a+=P.get(c)?.size||0,a>o)break;r===null&&s&&Rt(c,s)&&(i++,s=s.nextSibling,i>=2&&(r=void 0)),c=c.nextSibling}return r||null},Rt=(e,t)=>e.nodeType===t.nodeType&&e.tagName===t.tagName&&(!e.id||e.id===t.id),Je=e=>{P.has(e)?xt(ce,e,null):e.parentNode?.removeChild(e)},xt=Je.call.bind(ce.moveBefore??ce.insertBefore),Zt=Q("preserve-attr"),Ue=(e,t)=>{let n=t.nodeType;if(n===1){let r=e,s=t;if(r.hasAttribute(ve)&&s.hasAttribute(ve))return e;r instanceof HTMLInputElement&&s instanceof HTMLInputElement&&s.type!=="file"?s.getAttribute("value")!==r.getAttribute("value")&&(r.value=s.getAttribute("value")??""):r instanceof HTMLTextAreaElement&&s instanceof HTMLTextAreaElement&&(s.value!==r.value&&(r.value=s.value),r.firstChild&&r.firstChild.nodeValue!==s.value&&(r.firstChild.nodeValue=s.value));let i=(t.getAttribute(Zt)??"").split(" ");for(let{name:a,value:o}of s.attributes)r.getAttribute(a)!==o&&!i.includes(a)&&r.setAttribute(a,o);for(let a=r.attributes.length-1;a>=0;a--){let{name:o}=r.attributes[a];!s.hasAttribute(o)&&!i.includes(o)&&r.removeAttribute(o)}r.isEqualNode(s)||Mt(r,s)}return(n===8||n===3)&&e.nodeValue!==t.nodeValue&&(e.nodeValue=t.nodeValue),e},wt=(e,t)=>{for(let n of t)if(ae.has(n.id)){let r=n;for(;r&&r!==e;){let s=P.get(r);s||(s=new Set,P.set(r,s)),s.add(n.id),r=r.parentElement}}};O({name:"peek",apply(e,t){V();try{return t()}finally{I()}}});O({name:"setAll",apply(e,t,n){V();let r=D(n);Z(r,()=>t),C(r),I()}});O({name:"toggleAll",apply(e,t){V();let n=D(t);Z(n,r=>!r),C(n),I()}});var He=new WeakMap,be=(e,t)=>O({name:e,apply:async({el:n,evt:r,error:s},i,{selector:a,headers:o,contentType:c="json",filterSignals:{include:l=/.*/,exclude:f=/(^|\.)_/}={},openWhenHidden:d=!1,retryInterval:x=1e3,retryScaler:u=2,retryMaxWaitMs:m=3e4,retryMaxCount:h=10,requestCancellation:v="auto"}={})=>{let L=v instanceof AbortController?v:new AbortController,A=v==="disabled";if(!A){let T=He.get(n);T&&(T.abort(),await Promise.resolve())}!A&&!(v instanceof AbortController)&&He.set(n,L);try{let T=new MutationObserver(j=>{for(let H of j)for(let B of H.removedNodes)B===n&&(L.abort(),K())});n.parentNode&&T.observe(n.parentNode,{childList:!0});let K=()=>{T.disconnect()};try{if(!i?.length)throw s("FetchNoUrlProvided",{action:O});let j={Accept:"text/event-stream, text/html, application/json","Datastar-Request":!0};c==="json"&&(j["Content-Type"]="application/json");let H=Object.assign({},j,o),B={method:t,headers:H,openWhenHidden:d,retryInterval:x,retryScaler:u,retryMaxWaitMs:m,retryMaxCount:h,signal:L.signal,onopen:async g=>{g.status>=400&&ee(Yt,n,{status:g.status.toString()})},onmessage:g=>{if(!g.event.startsWith("datastar"))return;let $=g.event,b={};for(let N of g.data.split(` +`)){let y=N.indexOf(" "),k=N.slice(0,y),ue=N.slice(y+1);(b[k]||=[]).push(ue)}let F=Object.fromEntries(Object.entries(b).map(([N,y])=>[N,y.join(` +`)]));ee($,n,F)},onerror:g=>{if(Lt(g))throw g("FetchExpectedTextEventStream",{url:i});g&&(console.error(g.message),ee(Xt,n,{message:g.message}))}},fe=new URL(i,document.baseURI),ne=new URLSearchParams(fe.search);if(c==="json"){let g=JSON.stringify(D({include:l,exclude:f}));t==="GET"?ne.set("datastar",g):B.body=g}else if(c==="form"){let g=a?document.querySelector(a):n.closest("form");if(!g)throw s("FetchFormNotFound",{action:O,selector:a});if(!g.checkValidity()){g.reportValidity(),K();return}let $=new FormData(g),b=n;if(n===g&&r instanceof SubmitEvent)b=r.submitter;else{let y=k=>k.preventDefault();g.addEventListener("submit",y),K=()=>{g.removeEventListener("submit",y),T.disconnect()}}if(b instanceof HTMLButtonElement){let y=b.getAttribute("name");y&&$.append(y,b.value)}let F=g.getAttribute("enctype")==="multipart/form-data";F||(H["Content-Type"]="application/x-www-form-urlencoded");let N=new URLSearchParams($);if(t==="GET")for(let[y,k]of N)ne.append(y,k);else F?B.body=$:B.body=N}else throw s("FetchInvalidContentType",{action:O,contentType:c});ee(ze,n,{}),fe.search=ne.toString();try{await on(fe.toString(),n,B)}catch(g){if(!Lt(g))throw s("FetchFailed",{method:t,url:i,error:g.message})}}finally{ee(Qe,n,{}),K()}}finally{He.get(n)===L&&He.delete(n)}}});be("delete","DELETE");be("get","GET");be("patch","PATCH");be("post","POST");be("put","PUT");var ze="started",Qe="finished",Yt="error",Xt="retrying",en="retries-failed",ee=(e,t,n)=>document.dispatchEvent(new CustomEvent(q,{detail:{type:e,el:t,argsRaw:n}})),Lt=e=>`${e}`.includes("text/event-stream"),tn=async(e,t)=>{let n=e.getReader(),r=await n.read();for(;!r.done;)t(r.value),r=await n.read()},nn=e=>{let t,n,r,s=!1;return i=>{t?t=sn(t,i):(t=i,n=0,r=-1);let a=t.length,o=0;for(;n{let r=Ft(),s=new TextDecoder;return(i,a)=>{if(!i.length)n?.(r),r=Ft();else if(a>0){let o=s.decode(i.subarray(0,a)),c=a+(i[a+1]===32?2:1),l=s.decode(i.subarray(c));switch(o){case"data":r.data=r.data?`${r.data} +${l}`:l;break;case"event":r.event=l;break;case"id":e(r.id=l);break;case"retry":{let f=+l;Number.isNaN(f)||t(r.retry=f);break}}}}},sn=(e,t)=>{let n=new Uint8Array(e.length+t.length);return n.set(e),n.set(t,e.length),n},Ft=()=>({data:"",event:"",id:"",retry:void 0}),on=(e,t,{signal:n,headers:r,onopen:s,onmessage:i,onclose:a,onerror:o,openWhenHidden:c,fetch:l,retryInterval:f=1e3,retryScaler:d=2,retryMaxWaitMs:x=3e4,retryMaxCount:u=10,overrides:m,...h})=>new Promise((v,L)=>{let A={...r},T,K=()=>{T.abort(),document.hidden||$()};c||document.addEventListener("visibilitychange",K);let j=0,H=()=>{document.removeEventListener("visibilitychange",K),clearTimeout(j),T.abort()};n?.addEventListener("abort",()=>{H(),v()});let B=l||window.fetch,fe=s||(()=>{}),ne=0,g=f,$=async()=>{T=new AbortController;try{let b=await B(e,{...h,headers:A,signal:T.signal});ne=0,f=g,await fe(b);let F=async(y,k,ue,Ee,...Vt)=>{let tt={[ue]:await k.text()};for(let ke of Vt){let _e=k.headers.get(`datastar-${de(ke)}`);if(Ee){let Se=Ee[ke];Se&&(_e=typeof Se=="string"?Se:JSON.stringify(Se))}_e&&(tt[ke]=_e)}ee(y,t,tt),H(),v()},N=b.headers.get("Content-Type");if(N?.includes("text/html"))return await F("datastar-patch-elements",b,"elements",m,"selector","mode","useViewTransition");if(N?.includes("application/json"))return await F("datastar-patch-signals",b,"signals",m,"onlyIfMissing");if(N?.includes("text/javascript")){let y=document.createElement("script"),k=b.headers.get("datastar-script-attributes");if(k)for(let[ue,Ee]of Object.entries(JSON.parse(k)))y.setAttribute(ue,Ee);y.textContent=await b.text(),document.head.appendChild(y),H();return}await tn(b.body,nn(rn(y=>{y?A["last-event-id"]=y:delete A["last-event-id"]},y=>{g=f=y},i))),a?.(),H(),v()}catch(b){if(!T.signal.aborted)try{let F=o?.(b)||f;clearTimeout(j),j=setTimeout($,F),f=Math.min(f*d,x),++ne>=u?(ee(en,t,{}),H(),L("Max retries reached.")):console.error(`Datastar failed to reach ${e.toString()} retrying in ${F}ms.`)}catch(F){H(),L(F)}}};$()});p({name:"attr",requirement:{value:"must"},returnsValue:!0,apply({el:e,key:t,rx:n}){let r=(o,c)=>{c===""||c===!0?e.setAttribute(o,""):c===!1||c==null?e.removeAttribute(o):typeof c=="string"?e.setAttribute(o,c):e.setAttribute(o,JSON.stringify(c))},s=t?()=>{i.disconnect();let o=n();r(t,o),i.observe(e,{attributeFilter:[t]})}:()=>{i.disconnect();let o=n(),c=Object.keys(o);for(let l of c)r(l,o[l]);i.observe(e,{attributeFilter:c})},i=new MutationObserver(s),a=E(s);return()=>{i.disconnect(),a()}}});var an=/^data:(?[^;]+);base64,(?.*)$/,Nt=Symbol("empty"),Ct=Q("bind");p({name:"bind",requirement:"exclusive",apply({el:e,key:t,mods:n,value:r,error:s}){let i=t!=null?R(t,n):r,a=(u,m)=>m==="number"?+u.value:u.value,o=u=>{e.value=`${u}`};if(e instanceof HTMLInputElement)switch(e.type){case"range":case"number":a=(u,m)=>m==="string"?u.value:+u.value;break;case"checkbox":a=(u,m)=>u.value!=="on"?m==="boolean"?u.checked:u.checked?u.value:"":m==="string"?u.checked?u.value:"":u.checked,o=u=>{e.checked=typeof u=="string"?u===e.value:u};break;case"radio":e.getAttribute("name")?.length||e.setAttribute("name",i),a=(u,m)=>u.checked?m==="number"?+u.value:u.value:Nt,o=u=>{e.checked=u===(typeof u=="number"?+e.value:e.value)};break;case"file":{let u=()=>{let m=[...e.files||[]],h=[];Promise.all(m.map(v=>new Promise(L=>{let A=new FileReader;A.onload=()=>{if(typeof A.result!="string")throw s("InvalidFileResultType",{resultType:typeof A.result});let T=A.result.match(an);if(!T?.groups)throw s("InvalidDataUri",{result:A.result});h.push({name:v.name,contents:T.groups.contents,mime:T.groups.mime})},A.onloadend=()=>L(),A.readAsDataURL(v)}))).then(()=>{S([[i,h]])})};return e.addEventListener("change",u),e.addEventListener("input",u),()=>{e.removeEventListener("change",u),e.removeEventListener("input",u)}}}else if(e instanceof HTMLSelectElement){if(e.multiple){let u=new Map;a=m=>[...m.selectedOptions].map(h=>{let v=u.get(h.value);return v==="string"||v==null?h.value:+h.value}),o=m=>{for(let h of e.options)m.includes(h.value)?(u.set(h.value,"string"),h.selected=!0):m.includes(+h.value)?(u.set(h.value,"number"),h.selected=!0):h.selected=!1}}}else e instanceof HTMLTextAreaElement||(a=u=>"value"in u?u.value:u.getAttribute("value"),o=u=>{"value"in e?e.value=u:e.setAttribute("value",u)});let c=ie(i),l=typeof c,f=i;if(Array.isArray(c)&&!(e instanceof HTMLSelectElement&&e.multiple)){let u=t||r,m=document.querySelectorAll(`[${Ct}\\:${CSS.escape(u)}],[${Ct}="${CSS.escape(u)}"]`),h=[],v=0;for(let L of m){if(h.push([`${f}.${v}`,a(L,"none")]),e===L)break;v++}S(h,{ifMissing:!0}),f=`${f}.${v}`}else S([[f,a(e,l)]],{ifMissing:!0});let d=()=>{let u=ie(f);if(u!=null){let m=a(e,typeof u);m!==Nt&&S([[f,m]])}};e.addEventListener("input",d),e.addEventListener("change",d);let x=E(()=>{o(ie(f))});return()=>{x(),e.removeEventListener("input",d),e.removeEventListener("change",d)}}});p({name:"class",requirement:{value:"must"},returnsValue:!0,apply({key:e,el:t,mods:n,rx:r}){e&&(e=R(e,n,"kebab"));let s=()=>{i.disconnect();let o=e?{[e]:r()}:r();for(let c in o){let l=c.split(/\s+/).filter(f=>f.length>0);if(o[c])for(let f of l)t.classList.contains(f)||t.classList.add(f);else for(let f of l)t.classList.contains(f)&&t.classList.remove(f)}i.observe(t,{attributeFilter:["class"]})},i=new MutationObserver(s),a=E(s);return()=>{i.disconnect(),a();let o=e?{[e]:r()}:r();for(let c in o){let l=c.split(/\s+/).filter(f=>f.length>0);for(let f of l)t.classList.remove(f)}}}});p({name:"computed",requirement:{value:"must"},returnsValue:!0,apply({key:e,mods:t,rx:n,error:r}){if(e)S([[R(e,t),Ne(n)]]);else{let s=Object.assign({},n());Z(s,i=>{if(typeof i=="function")return Ne(i);throw r("ComputedExpectedFunction")}),C(s)}}});p({name:"effect",requirement:{key:"denied",value:"must"},apply:({rx:e})=>E(e)});p({name:"indicator",requirement:"exclusive",apply({el:e,key:t,mods:n,value:r}){let s=t!=null?R(t,n):r;S([[s,!1]]);let i=a=>{let{type:o,el:c}=a.detail;if(c===e)switch(o){case ze:S([[s,!0]]);break;case Qe:S([[s,!1]]);break}};return document.addEventListener(q,i),()=>{S([[s,!1]]),document.removeEventListener(q,i)}}});p({name:"json-signals",requirement:{key:"denied"},apply({el:e,value:t,mods:n}){let r=n.has("terse")?0:2,s={};t&&(s=re(t));let i=()=>{a.disconnect(),e.textContent=JSON.stringify(D(s),null,r),a.observe(e,{childList:!0,characterData:!0,subtree:!0})},a=new MutationObserver(i),o=E(i);return()=>{a.disconnect(),o()}}});var U=e=>{if(!e||e.size<=0)return 0;for(let t of e){if(t.endsWith("ms"))return+t.replace("ms","");if(t.endsWith("s"))return+t.replace("s","")*1e3;try{return Number.parseFloat(t)}catch{}}return 0},te=(e,t,n=!1)=>e?e.has(t.toLowerCase()):n;var Ze=(e,t)=>(...n)=>{setTimeout(()=>{e(...n)},t)},cn=(e,t,n=!1,r=!0)=>{let s=0;return(...i)=>{s&&clearTimeout(s),n&&!s&&e(...i),s=setTimeout(()=>{r&&e(...i),s&&clearTimeout(s),s=0},t)}},ln=(e,t,n=!0,r=!1)=>{let s=!1;return(...i)=>{s||(n&&e(...i),s=!0,setTimeout(()=>{r&&e(...i),s=!1},t))}},le=(e,t)=>{let n=t.get("delay");if(n){let i=U(n);e=Ze(e,i)}let r=t.get("debounce");if(r){let i=U(r),a=te(r,"leading",!1),o=!te(r,"notrailing",!1);e=cn(e,i,a,o)}let s=t.get("throttle");if(s){let i=U(s),a=!te(s,"noleading",!1),o=te(s,"trailing",!1);e=ln(e,i,a,o)}return e};var Ye=!!document.startViewTransition,J=(e,t)=>{if(t.has("viewtransition")&&Ye){let n=e;e=(...r)=>document.startViewTransition(()=>n(...r))}return e};p({name:"on",requirement:"must",argNames:["evt"],apply({el:e,key:t,mods:n,rx:r}){let s=e;n.has("window")&&(s=window);let i=c=>{c&&(n.has("prevent")&&c.preventDefault(),n.has("stop")&&c.stopPropagation()),w(),r(c),M()};i=J(i,n),i=le(i,n);let a={capture:n.has("capture"),passive:n.has("passive"),once:n.has("once")};if(n.has("outside")){s=document;let c=i;i=l=>{e.contains(l?.target)||c(l)}}let o=R(t,n,"kebab");if((o===q||o===z)&&(s=document),e instanceof HTMLFormElement&&o==="submit"){let c=i;i=l=>{l?.preventDefault(),c(l)}}return s.addEventListener(o,i,a),()=>{s.removeEventListener(o,i)}}});var Xe=new WeakSet;p({name:"on-intersect",requirement:{key:"denied",value:"must"},apply({el:e,mods:t,rx:n}){let r=()=>{w(),n(),M()};r=J(r,t),r=le(r,t);let s={threshold:0};t.has("full")?s.threshold=1:t.has("half")&&(s.threshold=.5);let i=new IntersectionObserver(a=>{for(let o of a)o.isIntersecting&&(r(),i&&Xe.has(e)&&i.disconnect())},s);return i.observe(e),t.has("once")&&Xe.add(e),()=>{t.has("once")||Xe.delete(e),i&&(i.disconnect(),i=null)}}});p({name:"on-interval",requirement:{key:"denied",value:"must"},apply({mods:e,rx:t}){let n=()=>{w(),t(),M()};n=J(n,e);let r=1e3,s=e.get("duration");s&&(r=U(s),te(s,"leading",!1)&&n());let i=setInterval(n,r);return()=>{clearInterval(i)}}});p({name:"init",requirement:{key:"denied",value:"must"},apply({rx:e,mods:t}){let n=()=>{w(),e(),M()};n=J(n,t);let r=0,s=t.get("delay");s&&(r=U(s),r>0&&(n=Ze(n,r))),n()}});p({name:"on-signal-patch",requirement:{value:"must"},argNames:["patch"],returnsValue:!0,apply({el:e,key:t,mods:n,rx:r,error:s}){if(t&&t!=="filter")throw s("KeyNotAllowed");let i=e.getAttribute("data-on-signal-patch-filter"),a={};i&&(a=re(i));let o=le(c=>{let l=D(a,c.detail);it(l)||(w(),r(l),M())},n);return document.addEventListener(z,o),()=>{document.removeEventListener(z,o)}}});p({name:"ref",requirement:"exclusive",apply({el:e,key:t,mods:n,value:r}){let s=t!=null?R(t,n):r;S([[s,e]])}});var Ot="none",Pt="display";p({name:"show",requirement:{key:"denied",value:"must"},returnsValue:!0,apply({el:e,rx:t}){let n=()=>{r.disconnect(),t()?e.style.display===Ot&&e.style.removeProperty(Pt):e.style.setProperty(Pt,Ot),r.observe(e,{attributeFilter:["style"]})},r=new MutationObserver(n),s=E(n);return()=>{r.disconnect(),s()}}});p({name:"signals",returnsValue:!0,apply({key:e,mods:t,rx:n}){let r=t.has("ifmissing");if(e)e=R(e,t),S([[e,n?.()]],{ifMissing:r});else{let s=Object.assign({},n?.());C(s,{ifMissing:r})}}});p({name:"style",requirement:{value:"must"},returnsValue:!0,apply({key:e,el:t,rx:n}){let{style:r}=t,s=new Map,i=(l,f)=>{let d=s.get(l);!f&&f!==0?d!==void 0&&(d?r.setProperty(l,d):r.removeProperty(l)):(d===void 0&&s.set(l,r.getPropertyValue(l)),r.setProperty(l,String(f)))},a=()=>{if(o.disconnect(),e)i(e,n());else{let l=n();for(let[f,d]of s)f in l||(d?r.setProperty(f,d):r.removeProperty(f));for(let f in l)i(de(f),l[f])}o.observe(t,{attributeFilter:["style"]})},o=new MutationObserver(a),c=E(a);return()=>{o.disconnect(),c();for(let[l,f]of s)f?r.setProperty(l,f):r.removeProperty(l)}}});p({name:"text",requirement:{key:"denied",value:"must"},returnsValue:!0,apply({el:e,rx:t}){let n=()=>{r.disconnect(),e.textContent=`${t()}`,r.observe(e,{childList:!0,characterData:!0,subtree:!0})},r=new MutationObserver(n),s=E(n);return()=>{r.disconnect(),s()}}});he({name:"datastar-patch-elements",apply(e,{elements:t="",selector:n="",mode:r="outer",useViewTransition:s}){switch(r){case"remove":case"outer":case"inner":case"replace":case"prepend":case"append":case"before":case"after":break;default:throw e.error("PatchElementsInvalidMode",{mode:r})}if(!n&&r!=="outer"&&r!=="replace")throw e.error("PatchElementsExpectedSelector");let i={mode:r,selector:n,elements:t,useViewTransition:s?.trim()==="true"};Ye&&s?document.startViewTransition(()=>Ht(e,i)):Ht(e,i)}});var Ht=({error:e},{elements:t,selector:n,mode:r})=>{let s=t.replace(/]*>|>)([\s\S]*?)<\/svg>/gim,""),i=/<\/html>/.test(s),a=/<\/head>/.test(s),o=/<\/body>/.test(s),c=new DOMParser().parseFromString(i||a||o?t:``,"text/html"),l=document.createDocumentFragment();if(i?l.appendChild(c.documentElement):a&&o?(l.appendChild(c.head),l.appendChild(c.body)):a?l.appendChild(c.head):o?l.appendChild(c.body):l=c.querySelector("template").content,!n&&(r==="outer"||r==="replace"))for(let f of l.children){let d;if(f instanceof HTMLHtmlElement)d=document.documentElement;else if(f instanceof HTMLBodyElement)d=document.body;else if(f instanceof HTMLHeadElement)d=document.head;else if(d=document.getElementById(f.id),!d){console.warn(e("PatchElementsNoTargetsFound"),{element:{id:f.id}});continue}_t(r,f,[d])}else{let f=document.querySelectorAll(n);if(!f.length){console.warn(e("PatchElementsNoTargetsFound"),{selector:n});return}_t(r,l,f)}},et=new WeakSet;for(let e of document.querySelectorAll("script"))et.add(e);var Dt=e=>{let t=e instanceof HTMLScriptElement?[e]:e.querySelectorAll("script");for(let n of t)if(!et.has(n)){let r=document.createElement("script");for(let{name:s,value:i}of n.attributes)r.setAttribute(s,i);r.text=n.text,n.replaceWith(r),et.add(r)}},kt=(e,t,n)=>{for(let r of e){let s=t.cloneNode(!0);Dt(s),r[n](s)}},_t=(e,t,n)=>{switch(e){case"remove":for(let r of n)r.remove();break;case"outer":case"inner":for(let r of n)Ke(r,t.cloneNode(!0),e),Dt(r);break;case"replace":kt(n,t,"replaceWith");break;case"prepend":case"append":case"before":case"after":kt(n,t,e)}};he({name:"datastar-patch-signals",apply({error:e},{signals:t,onlyIfMissing:n}){if(t){let r=n?.trim()==="true";C(re(t),{ifMissing:r})}else throw e("PatchSignalsExpectedSignals")}});export{O as action,Et as actions,p as attribute,w as beginBatch,Ne as computed,E as effect,M as endBatch,D as filtered,ie as getPath,C as mergePatch,S as mergePaths,Ke as morph,X as root,me as signal,V as startPeeking,I as stopPeeking,he as watcher}; +//# sourceMappingURL=datastar.js.map diff --git a/demo/datasstar-static/html-snippets/datastar.js.map b/demo/datasstar-static/html-snippets/datastar.js.map new file mode 100644 index 0000000..f82819f --- /dev/null +++ b/demo/datasstar-static/html-snippets/datastar.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../library/src/engine/consts.ts", "../library/src/utils/text.ts", "../library/src/utils/polyfills.ts", "../library/src/utils/paths.ts", "../library/src/engine/signals.ts", "../library/src/utils/dom.ts", "../library/src/engine/engine.ts", "../library/src/engine/morph.ts", "../library/src/plugins/actions/peek.ts", "../library/src/plugins/actions/setAll.ts", "../library/src/plugins/actions/toggleAll.ts", "../library/src/plugins/actions/fetch.ts", "../library/src/plugins/attributes/attr.ts", "../library/src/plugins/attributes/bind.ts", "../library/src/plugins/attributes/class.ts", "../library/src/plugins/attributes/computed.ts", "../library/src/plugins/attributes/effect.ts", "../library/src/plugins/attributes/indicator.ts", "../library/src/plugins/attributes/jsonSignals.ts", "../library/src/utils/tags.ts", "../library/src/utils/timing.ts", "../library/src/utils/view-transitions.ts", "../library/src/plugins/attributes/on.ts", "../library/src/plugins/attributes/onIntersect.ts", "../library/src/plugins/attributes/onInterval.ts", "../library/src/plugins/attributes/init.ts", "../library/src/plugins/attributes/onSignalPatch.ts", "../library/src/plugins/attributes/ref.ts", "../library/src/plugins/attributes/show.ts", "../library/src/plugins/attributes/signals.ts", "../library/src/plugins/attributes/style.ts", "../library/src/plugins/attributes/text.ts", "../library/src/plugins/watchers/patchElements.ts", "../library/src/plugins/watchers/patchSignals.ts"], + "sourcesContent": ["const lol = /\uD83D\uDD95JS_DS\uD83D\uDE80/.source\nexport const DSP = lol.slice(0, 5)\nexport const DSS = lol.slice(4)\nexport const DATASTAR_FETCH_EVENT = 'datastar-fetch'\nexport const DATASTAR_SIGNAL_PATCH_EVENT = 'datastar-signal-patch'\n", "import type { Modifiers } from '@engine/types'\n\nexport const kebab = (str: string): string =>\n str\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/([a-z])([0-9]+)/gi, '$1-$2')\n .replace(/([0-9]+)([a-z])/gi, '$1-$2')\n .toLowerCase()\n\nexport const camel = (str: string): string =>\n kebab(str).replace(/-./g, (x) => x[1].toUpperCase())\n\nexport const snake = (str: string): string => kebab(str).replace(/-/g, '_')\n\nexport const pascal = (str: string): string =>\n camel(str).replace(/(^.|(?<=\\.).)/g, (x) => x[0].toUpperCase())\n\nexport const jsStrToObject = (raw: string) => {\n try {\n return JSON.parse(raw)\n } catch {\n // If JSON parsing fails, try to evaluate as a JavaScript object\n // This is less safe and should be used with caution\n return Function(`return (${raw})`)()\n }\n}\n\nconst caseFns: Record string> = {\n camel: (str) => str.replace(/-[a-z]/g, (x) => x[1].toUpperCase()),\n snake: (str) => str.replace(/-/g, '_'),\n pascal: (str) => str[0].toUpperCase() + caseFns.camel(str.slice(1)),\n}\n\nexport const modifyCasing = (\n str: string,\n mods: Modifiers,\n defaultCase = 'camel',\n): string => {\n for (const c of mods.get('case') || [defaultCase]) {\n str = caseFns[c]?.(str) || str\n }\n return str\n}\n\nexport const aliasify = (name: string) =>\n ALIAS ? `data-${ALIAS}-${name}` : `data-${name}`\n", "export const hasOwn: (obj: object, prop: PropertyKey) => boolean =\n // @ts-expect-error\n Object.hasOwn ?? Object.prototype.hasOwnProperty.call\n", "import type { Paths } from '@engine/types'\nimport { hasOwn } from '@utils/polyfills'\n\nexport const isPojo = (obj: any): obj is Record =>\n obj !== null &&\n typeof obj === 'object' &&\n (Object.getPrototypeOf(obj) === Object.prototype ||\n Object.getPrototypeOf(obj) === null)\n\nexport const isEmpty = (obj: Record): boolean => {\n for (const prop in obj) {\n if (hasOwn(obj, prop)) {\n return false\n }\n }\n return true\n}\n\nexport const updateLeaves = (\n obj: Record,\n fn: (oldValue: any) => any,\n) => {\n for (const key in obj) {\n const val = obj[key]\n if (isPojo(val) || Array.isArray(val)) {\n updateLeaves(val, fn)\n } else {\n obj[key] = fn(val)\n }\n }\n}\n\nexport const pathToObj = (paths: Paths): Record => {\n const result: Record = {}\n for (const [path, value] of paths) {\n const keys = path.split('.')\n const lastKey = keys.pop()!\n const obj = keys.reduce((acc, key) => (acc[key] ??= {}), result)\n obj[lastKey] = value\n }\n return result\n}\n", "import { DATASTAR_SIGNAL_PATCH_EVENT } from '@engine/consts'\nimport type {\n Computed,\n Effect,\n JSONPatch,\n MergePatchArgs,\n Paths,\n Signal,\n SignalFilterOptions,\n} from '@engine/types'\nimport { isPojo, pathToObj } from '@utils/paths'\nimport { hasOwn } from '@utils/polyfills'\n\ninterface ReactiveNode {\n deps_?: Link\n depsTail_?: Link\n subs_?: Link\n subsTail_?: Link\n flags_: ReactiveFlags\n}\n\ninterface Link {\n version_: number\n dep_: ReactiveNode\n sub_: ReactiveNode\n prevSub_?: Link\n nextSub_?: Link\n prevDep_?: Link\n nextDep_?: Link\n}\n\ninterface Stack {\n value_: T\n prev_?: Stack\n}\n\nenum ReactiveFlags {\n None = 0,\n Mutable = 1 << 0,\n Watching = 1 << 1,\n RecursedCheck = 1 << 2,\n Recursed = 1 << 3,\n Dirty = 1 << 4,\n Pending = 1 << 5,\n}\n\nenum EffectFlags {\n Queued = 1 << 6,\n}\n\ninterface AlienEffect extends ReactiveNode {\n fn_(): void\n}\n\ninterface AlienComputed extends ReactiveNode {\n value_?: T\n getter(previousValue?: T): T\n}\n\ninterface AlienSignal extends ReactiveNode {\n previousValue: T\n value_: T\n}\n\nconst currentPatch: Paths = []\nconst queuedEffects: (AlienEffect | undefined)[] = []\nlet batchDepth = 0\nlet notifyIndex = 0\nlet queuedEffectsLength = 0\nlet prevSub: ReactiveNode | undefined\nlet activeSub: ReactiveNode | undefined\nlet version = 0\n\nexport const beginBatch = (): void => {\n batchDepth++\n}\n\nexport const endBatch = (): void => {\n if (!--batchDepth) {\n flush()\n dispatch()\n }\n}\n\nexport const startPeeking = (sub?: ReactiveNode): void => {\n prevSub = activeSub\n activeSub = sub\n}\n\nexport const stopPeeking = (): void => {\n activeSub = prevSub\n prevSub = undefined\n}\n\nexport const signal = (initialValue?: T): Signal => {\n return signalOper.bind(0, {\n previousValue: initialValue,\n value_: initialValue,\n flags_: 1 satisfies ReactiveFlags.Mutable,\n }) as Signal\n}\n\nconst computedSymbol = Symbol('computed')\nexport const computed = (getter: (previousValue?: T) => T): Computed => {\n const c = computedOper.bind(0, {\n flags_: 17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty,\n getter,\n }) as Computed\n // @ts-expect-error\n c[computedSymbol] = 1\n return c\n}\n\nexport const effect = (fn: () => void): Effect => {\n const e: AlienEffect = {\n fn_: fn,\n flags_: 2 satisfies ReactiveFlags.Watching,\n }\n if (activeSub) {\n link(e, activeSub)\n }\n startPeeking(e)\n beginBatch()\n try {\n e.fn_()\n } finally {\n endBatch()\n stopPeeking()\n }\n return effectOper.bind(0, e)\n}\n\nconst flush = () => {\n while (notifyIndex < queuedEffectsLength) {\n const effect = queuedEffects[notifyIndex]!\n queuedEffects[notifyIndex++] = undefined\n run(effect, (effect.flags_ &= ~EffectFlags.Queued))\n }\n notifyIndex = 0\n queuedEffectsLength = 0\n}\n\nconst update = (signal: AlienSignal | AlienComputed): boolean => {\n if ('getter' in signal) {\n return updateComputed(signal)\n }\n return updateSignal(signal, signal.value_)\n}\n\nconst updateComputed = (c: AlienComputed): boolean => {\n startPeeking(c)\n startTracking(c)\n try {\n const oldValue = c.value_\n return oldValue !== (c.value_ = c.getter(oldValue))\n } finally {\n stopPeeking()\n endTracking(c)\n }\n}\n\nconst updateSignal = (s: AlienSignal, value: T): boolean => {\n s.flags_ = 1 satisfies ReactiveFlags.Mutable\n return s.previousValue !== (s.previousValue = value)\n}\n\nconst notify = (e: AlienEffect): void => {\n const flags = e.flags_\n if (!(flags & EffectFlags.Queued)) {\n e.flags_ = flags | EffectFlags.Queued\n const subs = e.subs_\n if (subs) {\n notify(subs.sub_ as AlienEffect)\n } else {\n queuedEffects[queuedEffectsLength++] = e\n }\n }\n}\n\nconst run = (e: AlienEffect, flags: ReactiveFlags): void => {\n if (\n flags & (16 satisfies ReactiveFlags.Dirty) ||\n (flags & (32 satisfies ReactiveFlags.Pending) && checkDirty(e.deps_!, e))\n ) {\n startPeeking(e)\n startTracking(e)\n beginBatch()\n try {\n e.fn_()\n } finally {\n endBatch()\n stopPeeking()\n endTracking(e)\n }\n return\n }\n if (flags & (32 satisfies ReactiveFlags.Pending)) {\n e.flags_ = flags & ~(32 satisfies ReactiveFlags.Pending)\n }\n let link = e.deps_\n while (link) {\n const dep = link.dep_\n const depFlags = dep.flags_\n if (depFlags & EffectFlags.Queued) {\n run(dep as AlienEffect, (dep.flags_ = depFlags & ~EffectFlags.Queued))\n }\n link = link.nextDep_\n }\n}\n\nconst signalOper = (s: AlienSignal, ...value: [T]): T | boolean => {\n if (value.length) {\n if (s.value_ !== (s.value_ = value[0])) {\n s.flags_ = 17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty\n const subs = s.subs_\n if (subs) {\n propagate(subs)\n if (!batchDepth) {\n flush()\n }\n }\n return true\n }\n return false\n }\n const currentValue = s.value_\n if (s.flags_ & (16 satisfies ReactiveFlags.Dirty)) {\n if (updateSignal(s, currentValue)) {\n const subs_ = s.subs_\n if (subs_) {\n shallowPropagate(subs_)\n }\n }\n }\n if (activeSub) {\n link(s, activeSub)\n }\n return currentValue\n}\n\nconst computedOper = (c: AlienComputed): T => {\n const flags = c.flags_\n if (\n flags & (16 satisfies ReactiveFlags.Dirty) ||\n (flags & (32 satisfies ReactiveFlags.Pending) && checkDirty(c.deps_!, c))\n ) {\n if (updateComputed(c)) {\n const subs = c.subs_\n if (subs) {\n shallowPropagate(subs)\n }\n }\n } else if (flags & (32 satisfies ReactiveFlags.Pending)) {\n c.flags_ = flags & ~(32 satisfies ReactiveFlags.Pending)\n }\n if (activeSub) {\n link(c, activeSub)\n }\n return c.value_!\n}\n\nconst effectOper = (e: AlienEffect): void => {\n let dep = e.deps_\n while (dep) {\n dep = unlink(dep, e)\n }\n const sub = e.subs_\n if (sub) {\n unlink(sub)\n }\n e.flags_ = 0 satisfies ReactiveFlags.None\n}\n\nconst link = (dep: ReactiveNode, sub: ReactiveNode): void => {\n const prevDep = sub.depsTail_\n if (prevDep && prevDep.dep_ === dep) {\n return\n }\n const nextDep = prevDep ? prevDep.nextDep_ : sub.deps_\n if (nextDep && nextDep.dep_ === dep) {\n nextDep.version_ = version\n sub.depsTail_ = nextDep\n return\n }\n const prevSub = dep.subsTail_\n if (prevSub && prevSub.version_ === version && prevSub.sub_ === sub) {\n return\n }\n const newLink =\n (sub.depsTail_ =\n dep.subsTail_ =\n {\n version_: version,\n dep_: dep,\n sub_: sub,\n prevDep_: prevDep,\n nextDep_: nextDep,\n prevSub_: prevSub,\n })\n if (nextDep) {\n nextDep.prevDep_ = newLink\n }\n if (prevDep) {\n prevDep.nextDep_ = newLink\n } else {\n sub.deps_ = newLink\n }\n if (prevSub) {\n prevSub.nextSub_ = newLink\n } else {\n dep.subs_ = newLink\n }\n}\n\nconst unlink = (link: Link, sub = link.sub_): Link | undefined => {\n const dep_ = link.dep_\n const prevDep_ = link.prevDep_\n const nextDep_ = link.nextDep_\n const nextSub_ = link.nextSub_\n const prevSub_ = link.prevSub_\n if (nextDep_) {\n nextDep_.prevDep_ = prevDep_\n } else {\n sub.depsTail_ = prevDep_\n }\n if (prevDep_) {\n prevDep_.nextDep_ = nextDep_\n } else {\n sub.deps_ = nextDep_\n }\n if (nextSub_) {\n nextSub_.prevSub_ = prevSub_\n } else {\n dep_.subsTail_ = prevSub_\n }\n if (prevSub_) {\n prevSub_.nextSub_ = nextSub_\n } else if (!(dep_.subs_ = nextSub_)) {\n if ('getter' in dep_) {\n let toRemove = dep_.deps_\n if (toRemove) {\n dep_.flags_ = 17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty\n do {\n toRemove = unlink(toRemove, dep_)\n } while (toRemove)\n }\n } else if (!('previousValue' in dep_)) {\n effectOper(dep_ as AlienEffect)\n }\n }\n return nextDep_\n}\n\nconst propagate = (link: Link): void => {\n let next = link.nextSub_\n let stack: Stack | undefined\n\n top: while (true) {\n const sub = link.sub_\n\n let flags = sub.flags_\n\n if (\n !(\n flags &\n (60 as\n | ReactiveFlags.RecursedCheck\n | ReactiveFlags.Recursed\n | ReactiveFlags.Dirty\n | ReactiveFlags.Pending)\n )\n ) {\n sub.flags_ = flags | (32 satisfies ReactiveFlags.Pending)\n } else if (\n !(flags & (12 as ReactiveFlags.RecursedCheck | ReactiveFlags.Recursed))\n ) {\n flags = 0 satisfies ReactiveFlags.None\n } else if (!(flags & (4 satisfies ReactiveFlags.RecursedCheck))) {\n sub.flags_ =\n (flags & ~(8 satisfies ReactiveFlags.Recursed)) |\n (32 satisfies ReactiveFlags.Pending)\n } else if (\n !(flags & (48 as ReactiveFlags.Dirty | ReactiveFlags.Pending)) &&\n isValidLink(link, sub)\n ) {\n sub.flags_ =\n flags | (40 as ReactiveFlags.Recursed | ReactiveFlags.Pending)\n flags &= 1 satisfies ReactiveFlags.Mutable\n } else {\n flags = 0 satisfies ReactiveFlags.None\n }\n\n if (flags & (2 satisfies ReactiveFlags.Watching)) {\n notify(sub as AlienEffect)\n }\n\n if (flags & (1 satisfies ReactiveFlags.Mutable)) {\n const subSubs = sub.subs_\n if (subSubs) {\n const nextSub = (link = subSubs).nextSub_\n if (nextSub) {\n stack = { value_: next, prev_: stack }\n next = nextSub\n }\n continue\n }\n }\n\n if ((link = next!)) {\n next = link.nextSub_\n continue\n }\n\n while (stack) {\n link = stack.value_!\n stack = stack.prev_\n if (link) {\n next = link.nextSub_\n continue top\n }\n }\n\n break\n }\n}\n\nconst startTracking = (sub: ReactiveNode): void => {\n version++\n sub.depsTail_ = undefined\n sub.flags_ =\n (sub.flags_ &\n ~(56 as\n | ReactiveFlags.Recursed\n | ReactiveFlags.Dirty\n | ReactiveFlags.Pending)) |\n (4 satisfies ReactiveFlags.RecursedCheck)\n}\n\nconst endTracking = (sub: ReactiveNode): void => {\n const depsTail_ = sub.depsTail_\n let toRemove = depsTail_ ? depsTail_.nextDep_ : sub.deps_\n while (toRemove) {\n toRemove = unlink(toRemove, sub)\n }\n sub.flags_ &= ~(4 satisfies ReactiveFlags.RecursedCheck)\n}\n\nconst checkDirty = (link: Link, sub: ReactiveNode): boolean => {\n let stack: Stack | undefined\n let checkDepth = 0\n let dirty = false\n\n top: while (true) {\n const dep = link.dep_\n const flags = dep.flags_\n\n if (sub.flags_ & (16 satisfies ReactiveFlags.Dirty)) {\n dirty = true\n } else if (\n (flags & (17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty)) ===\n (17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty)\n ) {\n if (update(dep as AlienSignal | AlienComputed)) {\n const subs = dep.subs_!\n if (subs.nextSub_) {\n shallowPropagate(subs)\n }\n dirty = true\n }\n } else if (\n (flags & (33 as ReactiveFlags.Mutable | ReactiveFlags.Pending)) ===\n (33 as ReactiveFlags.Mutable | ReactiveFlags.Pending)\n ) {\n if (link.nextSub_ || link.prevSub_) {\n stack = { value_: link, prev_: stack }\n }\n link = dep.deps_!\n sub = dep\n ++checkDepth\n continue\n }\n\n if (!dirty) {\n const nextDep = link.nextDep_\n if (nextDep) {\n link = nextDep\n continue\n }\n }\n\n while (checkDepth--) {\n const firstSub = sub.subs_!\n const hasMultipleSubs = firstSub.nextSub_\n if (hasMultipleSubs) {\n link = stack!.value_\n stack = stack!.prev_\n } else {\n link = firstSub\n }\n if (dirty) {\n if (update(sub as AlienSignal | AlienComputed)) {\n if (hasMultipleSubs) {\n shallowPropagate(firstSub)\n }\n sub = link.sub_\n continue\n }\n dirty = false\n } else {\n sub.flags_ &= ~(32 satisfies ReactiveFlags.Pending)\n }\n sub = link.sub_\n if (link.nextDep_) {\n link = link.nextDep_\n continue top\n }\n }\n\n return dirty\n }\n}\n\nconst shallowPropagate = (link: Link): void => {\n do {\n const sub = link.sub_\n const flags = sub.flags_\n if (\n (flags & (48 as ReactiveFlags.Pending | ReactiveFlags.Dirty)) ===\n (32 satisfies ReactiveFlags.Pending)\n ) {\n sub.flags_ = flags | (16 satisfies ReactiveFlags.Dirty)\n if (flags & (2 satisfies ReactiveFlags.Watching)) {\n notify(sub as AlienEffect)\n }\n }\n } while ((link = link.nextSub_!))\n}\n\nconst isValidLink = (checkLink: Link, sub: ReactiveNode): boolean => {\n let link = sub.depsTail_\n while (link) {\n if (link === checkLink) {\n return true\n }\n link = link.prevDep_\n }\n return false\n}\n\nexport const getPath = (path: string): T | undefined => {\n let result = root\n const split = path.split('.')\n for (const path of split) {\n if (result == null || !hasOwn(result, path)) {\n return\n }\n result = result[path]\n }\n return result as T\n}\n\nconst deep = (value: any, prefix = ''): any => {\n const isArr = Array.isArray(value)\n if (isArr || isPojo(value)) {\n const deepObj = (isArr ? [] : {}) as Record>\n for (const key in value) {\n deepObj[key] = signal(\n deep((value as Record>)[key], `${prefix + key}.`),\n )\n }\n const keys = signal(0)\n return new Proxy(deepObj, {\n get(_, prop: string) {\n // JSON.stringify calls `.toJSON()` directly instead of checking if it exists on the object\n // so we have to check if `toJSON` is being called and prevent a signal from automatically\n // being made so JSON.stringify can fallback to the default stringify\n if (!(prop === 'toJSON' && !hasOwn(deepObj, prop))) {\n // special case for when prop is an array function because every array function needs to\n // be reactive to when the keys change\n if (isArr && prop in Array.prototype) {\n keys()\n return deepObj[prop]\n }\n // if prop is a symbol just return the symbol because we don't want to make up that theres\n // an iterator symbol on an object or not\n if (typeof prop === 'symbol') {\n return deepObj[prop]\n }\n // if obj doesnt have prop OR prop is null or undefined then create a signal and default\n // to an empty string\n if (!hasOwn(deepObj, prop) || deepObj[prop]() == null) {\n deepObj[prop] = signal('')\n dispatch(prefix + prop, '')\n keys(keys() + 1)\n }\n return deepObj[prop]()\n }\n },\n set(_, prop: string, newValue) {\n const path = prefix + prop\n // special case for when setting length so we can make a diff patch\n if (isArr && prop === 'length') {\n const diff = (deepObj[prop] as unknown as number) - newValue\n deepObj[prop] = newValue\n // manually make a diff patch for now, shouldnt have to do this when object diffing is\n // implemented. see https://github.com/starfederation/datastar-dev/issues/274\n if (diff > 0) {\n const patch: Record = {}\n for (let i = newValue; i < deepObj[prop]; i++) {\n patch[i] = null\n }\n dispatch(prefix.slice(0, -1), patch)\n keys(keys() + 1)\n }\n } else if (hasOwn(deepObj, prop)) {\n if (newValue == null) {\n delete deepObj[prop]\n // if newValue is a computed set the computed directly instead of wrapping in signal\n } else if (hasOwn(newValue, computedSymbol)) {\n deepObj[prop] = newValue\n dispatch(path, '')\n // if prop changed after setting it then dispatch\n } else if (deepObj[prop](deep(newValue, `${path}.`))) {\n dispatch(path, newValue)\n }\n // if newValue is null or undefined then noop\n } else if (newValue != null) {\n // if newValue is a computed set the computed directly instead of wrapping in signal\n if (hasOwn(newValue, computedSymbol)) {\n deepObj[prop] = newValue\n dispatch(path, '')\n } else {\n deepObj[prop] = signal(deep(newValue, `${path}.`))\n dispatch(path, newValue)\n }\n keys(keys() + 1)\n }\n\n return true\n },\n deleteProperty(_, prop: string) {\n delete deepObj[prop]\n keys(keys() + 1)\n return true\n },\n ownKeys() {\n keys()\n return Reflect.ownKeys(deepObj)\n },\n has(_, prop) {\n keys()\n return prop in deepObj\n },\n })\n }\n return value\n}\n\nconst dispatch = (path?: string, value?: any) => {\n if (path !== undefined && value !== undefined) {\n currentPatch.push([path, value])\n }\n if (!batchDepth && currentPatch.length) {\n const detail = pathToObj(currentPatch)\n currentPatch.length = 0\n document.dispatchEvent(\n new CustomEvent(DATASTAR_SIGNAL_PATCH_EVENT, {\n detail,\n }),\n )\n }\n}\n\nexport const mergePatch = (\n patch: JSONPatch,\n { ifMissing }: MergePatchArgs = {},\n): void => {\n beginBatch()\n for (const key in patch) {\n if (patch[key] == null) {\n if (!ifMissing) {\n delete root[key]\n }\n } else {\n mergeInner(patch[key], key, root, '', ifMissing)\n }\n }\n endBatch()\n}\n\nexport const mergePaths = (paths: Paths, options?: MergePatchArgs): void =>\n mergePatch(pathToObj(paths), options)\n\nconst mergeInner = (\n patch: any,\n target: string,\n targetParent: Record,\n prefix: string,\n ifMissing: boolean | undefined,\n): void => {\n if (isPojo(patch)) {\n if (\n !(\n hasOwn(targetParent, target) &&\n (isPojo(targetParent[target]) || Array.isArray(targetParent[target]))\n )\n ) {\n targetParent[target] = {}\n }\n\n for (const key in patch) {\n if (patch[key] == null) {\n if (!ifMissing) {\n delete targetParent[target][key]\n }\n } else {\n mergeInner(\n patch[key],\n key,\n targetParent[target],\n `${prefix + target}.`,\n ifMissing,\n )\n }\n }\n } else if (!(ifMissing && hasOwn(targetParent, target))) {\n targetParent[target] = patch\n }\n}\n\nconst toRegExp = (val: string | RegExp): RegExp =>\n typeof val === 'string' ? RegExp(val.replace(/^\\/|\\/$/g, '')) : val\n\n/**\n * Filters the root store based on an include and exclude RegExp\n *\n * @returns The filtered object\n */\nexport const filtered = (\n { include = /.*/, exclude = /(?!)/ }: SignalFilterOptions = {},\n obj: JSONPatch = root,\n): Record => {\n const includeRe = toRegExp(include)\n const excludeRe = toRegExp(exclude)\n const paths: Paths = []\n const stack: [any, string][] = [[obj, '']]\n\n while (stack.length) {\n const [node, prefix] = stack.pop()!\n\n for (const key in node) {\n const path = prefix + key\n if (isPojo(node[key])) {\n stack.push([node[key], `${path}.`])\n } else if (includeRe.test(path) && !excludeRe.test(path)) {\n paths.push([path, getPath(path)])\n }\n }\n }\n\n return pathToObj(paths)\n}\n\nexport const root: Record = deep({})\n", "import type { HTMLOrSVG } from '@engine/types'\n\nexport const isHTMLOrSVG = (el: Node): el is HTMLOrSVG =>\n el instanceof HTMLElement ||\n el instanceof SVGElement ||\n el instanceof MathMLElement\n", "import { DATASTAR_FETCH_EVENT, DSP, DSS } from '@engine/consts'\nimport { snake } from '@utils/text'\nimport { root } from '@engine/signals'\nimport type {\n ActionPlugin,\n ActionContext,\n AttributeContext,\n AttributePlugin,\n DatastarFetchEvent,\n HTMLOrSVG,\n Requirement,\n WatcherPlugin,\n} from '@engine/types'\nimport { isHTMLOrSVG } from '@utils/dom'\nimport { aliasify } from '@utils/text'\n\nconst url = 'https://data-star.dev/errors'\n\nconst error = (\n ctx: Record,\n reason: string,\n metadata: Record = {},\n) => {\n Object.assign(metadata, ctx)\n const e = new Error()\n const r = snake(reason)\n const q = new URLSearchParams({\n metadata: JSON.stringify(metadata),\n }).toString()\n const c = JSON.stringify(metadata, null, 2)\n e.message = `${reason}\\nMore info: ${url}/${r}?${q}\\nContext: ${c}`\n return e\n}\n\nconst actionPlugins: Map = new Map()\nconst attributePlugins: Map = new Map()\nconst watcherPlugins: Map = new Map()\n\nexport const actions: Record<\n string,\n (ctx: ActionContext, ...args: any[]) => any\n> = new Proxy(\n {},\n {\n get: (_, prop: string) => actionPlugins.get(prop)?.apply,\n has: (_, prop: string) => actionPlugins.has(prop),\n ownKeys: () => Reflect.ownKeys(actionPlugins),\n set: () => false,\n deleteProperty: () => false,\n },\n)\n\n// Map of cleanups keyed by element and attribute name\nconst removals = new Map void>>()\n\nconst queuedAttributes: AttributePlugin[] = []\nconst queuedAttributeNames = new Set()\nexport const attribute = (\n plugin: AttributePlugin,\n): void => {\n queuedAttributes.push(plugin as unknown as AttributePlugin)\n\n if (queuedAttributes.length === 1) {\n setTimeout(() => {\n for (const attribute of queuedAttributes) {\n queuedAttributeNames.add(attribute.name)\n attributePlugins.set(attribute.name, attribute)\n }\n queuedAttributes.length = 0\n apply()\n queuedAttributeNames.clear()\n })\n }\n}\n\nexport const action = (plugin: ActionPlugin): void => {\n actionPlugins.set(plugin.name, plugin)\n}\n\ndocument.addEventListener(DATASTAR_FETCH_EVENT, ((\n evt: CustomEvent,\n) => {\n const plugin = watcherPlugins.get(evt.detail.type)\n if (plugin) {\n plugin.apply(\n {\n error: error.bind(0, {\n plugin: { type: 'watcher', name: plugin.name },\n element: {\n id: (evt.target as Element).id,\n tag: (evt.target as Element).tagName,\n },\n }),\n },\n evt.detail.argsRaw,\n )\n }\n}) as EventListener)\n\nexport const watcher = (plugin: WatcherPlugin): void => {\n watcherPlugins.set(plugin.name, plugin)\n}\n\nconst cleanupEls = (els: Iterable): void => {\n for (const el of els) {\n const cleanups = removals.get(el)\n // If removals has el, delete it and run all cleanup functions\n if (removals.delete(el)) {\n for (const cleanup of cleanups!.values()) {\n cleanup()\n }\n cleanups!.clear()\n }\n }\n}\n\nconst aliasedIgnore = aliasify('ignore')\nconst aliasedIgnoreAttr = `[${aliasedIgnore}]`\nconst shouldIgnore = (el: HTMLOrSVG) =>\n el.hasAttribute(`${aliasedIgnore}__self`) || !!el.closest(aliasedIgnoreAttr)\n\nconst applyEls = (els: Iterable, onlyNew?: boolean): void => {\n for (const el of els) {\n if (!shouldIgnore(el)) {\n for (const key in el.dataset) {\n applyAttributePlugin(\n el,\n key.replace(/[A-Z]/g, '-$&').toLowerCase(),\n el.dataset[key]!,\n onlyNew,\n )\n }\n }\n }\n}\n\nconst observe = (mutations: MutationRecord[]) => {\n for (const {\n target,\n type,\n attributeName,\n addedNodes,\n removedNodes,\n } of mutations) {\n if (type === 'childList') {\n for (const node of removedNodes) {\n if (isHTMLOrSVG(node)) {\n cleanupEls([node])\n cleanupEls(node.querySelectorAll('*'))\n }\n }\n\n for (const node of addedNodes) {\n if (isHTMLOrSVG(node)) {\n applyEls([node])\n applyEls(node.querySelectorAll('*'))\n }\n }\n } else if (\n type === 'attributes' &&\n attributeName!.startsWith('data-') &&\n isHTMLOrSVG(target) &&\n !shouldIgnore(target)\n ) {\n // skip over 'data-'\n const key = attributeName!.slice(5)\n const value = target.getAttribute(attributeName!)\n if (value === null) {\n const cleanups = removals.get(target)\n if (cleanups) {\n cleanups.get(key)?.()\n cleanups.delete(key)\n }\n } else {\n applyAttributePlugin(target, key, value)\n }\n }\n }\n}\n\n// TODO: mutation observer per root so applying to web component doesnt overwrite main observer\nconst mutationObserver = new MutationObserver(observe)\n\nexport const apply = (\n root: HTMLOrSVG | ShadowRoot = document.documentElement,\n): void => {\n if (isHTMLOrSVG(root)) {\n applyEls([root], true)\n }\n applyEls(root.querySelectorAll('*'), true)\n\n mutationObserver.observe(root, {\n subtree: true,\n childList: true,\n attributes: true,\n })\n}\n\nconst applyAttributePlugin = (\n el: HTMLOrSVG,\n attrKey: string,\n value: string,\n onlyNew?: boolean,\n): void => {\n if (!ALIAS || attrKey.startsWith(`${ALIAS}-`)) {\n const rawKey = ALIAS ? attrKey.slice(ALIAS.length + 1) : attrKey\n const [namePart, ...rawModifiers] = rawKey.split('__')\n const [pluginName, key] = namePart.split(/:(.+)/)\n const plugin = attributePlugins.get(pluginName)\n if ((!onlyNew || queuedAttributeNames.has(pluginName)) && plugin) {\n const ctx = {\n el,\n rawKey,\n mods: new Map(),\n error: error.bind(0, {\n plugin: { type: 'attribute', name: plugin.name },\n element: { id: el.id, tag: el.tagName },\n expression: { rawKey, key, value },\n }),\n key,\n value,\n rx: undefined,\n } as AttributeContext\n\n const keyReq =\n (plugin.requirement &&\n (typeof plugin.requirement === 'string'\n ? plugin.requirement\n : plugin.requirement.key)) ||\n 'allowed'\n const valueReq =\n (plugin.requirement &&\n (typeof plugin.requirement === 'string'\n ? plugin.requirement\n : plugin.requirement.value)) ||\n 'allowed'\n\n if (key) {\n if (keyReq === 'denied') {\n throw ctx.error('KeyNotAllowed')\n }\n } else if (keyReq === 'must') {\n throw ctx.error('KeyRequired')\n }\n\n if (value) {\n if (valueReq === 'denied') {\n throw ctx.error('ValueNotAllowed')\n }\n } else if (valueReq === 'must') {\n throw ctx.error('ValueRequired')\n }\n\n if (keyReq === 'exclusive' || valueReq === 'exclusive') {\n if (key && value) {\n throw ctx.error('KeyAndValueProvided')\n }\n if (!key && !value) {\n throw ctx.error('KeyOrValueRequired')\n }\n }\n\n if (value) {\n let cachedRx: GenRxFn\n ctx.rx = (...args: any[]) => {\n if (!cachedRx) {\n cachedRx = genRx(value, {\n returnsValue: plugin.returnsValue,\n argNames: plugin.argNames,\n })\n }\n return cachedRx(el, ...args)\n }\n }\n\n for (const rawMod of rawModifiers) {\n const [label, ...mod] = rawMod.split('.')\n ctx.mods.set(label, new Set(mod))\n }\n\n const cleanup = plugin.apply(ctx)\n if (cleanup) {\n let cleanups = removals.get(el)\n if (cleanups) {\n cleanups.get(rawKey)?.()\n } else {\n cleanups = new Map()\n removals.set(el, cleanups)\n }\n cleanups.set(rawKey, cleanup)\n }\n }\n }\n}\n\ntype GenRxOptions = {\n returnsValue?: boolean\n argNames?: string[]\n}\n\ntype GenRxFn = (el: HTMLOrSVG, ...args: any[]) => T\n\nconst genRx = (\n value: string,\n { returnsValue = false, argNames = [] }: GenRxOptions = {},\n): GenRxFn => {\n let expr = ''\n if (returnsValue) {\n // This regex allows Datastar expressions to support nested\n // regex and strings that contain ; without breaking.\n //\n // Each of these regex defines a block type we want to match\n // (importantly we ignore the content within these blocks):\n //\n // regex \\/(\\\\\\/|[^\\/])*\\/\n // double quotes \"(\\\\\"|[^\\\"])*\"\n // single quotes '(\\\\'|[^'])*'\n // ticks `(\\\\`|[^`])*`\n // iife \\(\\s*((function)\\s*\\(\\s*\\)|(\\(\\s*\\))\\s*=>)\\s*(?:\\{[\\s\\S]*?\\}|[^;)\\{]*)\\s*\\)\\s*\\(\\s*\\)\n //\n // The iife support is (intentionally) limited. It only supports\n // function and arrow syntax with no arguments, and no nested IIFEs.\n //\n // We also want to match the non delimiter part of statements\n // note we only support ; statement delimiters:\n //\n // [^;]\n //\n const statementRe =\n /(\\/(\\\\\\/|[^/])*\\/|\"(\\\\\"|[^\"])*\"|'(\\\\'|[^'])*'|`(\\\\`|[^`])*`|\\(\\s*((function)\\s*\\(\\s*\\)|(\\(\\s*\\))\\s*=>)\\s*(?:\\{[\\s\\S]*?\\}|[^;){]*)\\s*\\)\\s*\\(\\s*\\)|[^;])+/gm\n const statements = value.trim().match(statementRe)\n if (statements) {\n const lastIdx = statements.length - 1\n const last = statements[lastIdx].trim()\n if (!last.startsWith('return')) {\n statements[lastIdx] = `return (${last});`\n }\n expr = statements.join(';\\n')\n }\n } else {\n expr = value.trim()\n }\n\n // Ignore any escaped values\n const escaped = new Map()\n const escapeRe = RegExp(`(?:${DSP})(.*?)(?:${DSS})`, 'gm')\n let counter = 0\n for (const match of expr.matchAll(escapeRe)) {\n const k = match[1]\n const v = `__escaped${counter++}`\n escaped.set(v, k)\n expr = expr.replace(DSP + k + DSS, v)\n }\n\n // Replace signal references with bracket notation\n // Examples:\n // $count -> $['count']\n // $count-- -> $['count']--\n // $foo.bar -> $['foo']['bar']\n // $foo-bar -> $['foo-bar']\n // $foo.bar-baz -> $['foo']['bar-baz']\n // $foo-$bar -> $['foo']-$['bar']\n // $arr[$index] -> $['arr'][$['index']]\n // $['foo'] -> $['foo']\n // $foo[obj.bar] -> $['foo'][obj.bar]\n // $foo['bar.baz'] -> $['foo']['bar.baz']\n // $123 -> $['123']\n // $foo.0.name -> $['foo']['0']['name']\n\n expr = expr\n // $['x'] -> $x (normalize existing bracket notation)\n .replace(/\\$\\['([a-zA-Z_$\\d][\\w$]*)'\\]/g, '$$$1')\n // $x -> $['x'] (including dots and hyphens)\n .replace(/\\$([a-zA-Z_\\d]\\w*(?:[.-]\\w+)*)/g, (_, signalName) =>\n signalName\n .split('.')\n .reduce((acc: string, part: string) => `${acc}['${part}']`, '$'),\n )\n // [$x] -> [$['x']] ($ inside brackets)\n .replace(\n /\\[(\\$[a-zA-Z_\\d]\\w*)\\]/g,\n (_, varName) => `[$['${varName.slice(1)}']]`,\n )\n\n expr = expr.replaceAll(/@(\\w+)\\(/g, '__action(\"$1\",evt,')\n\n // Replace any escaped values\n for (const [k, v] of escaped) {\n expr = expr.replace(k, v)\n }\n\n try {\n const fn = Function('el', '$', '__action', 'evt', ...argNames, expr)\n return (el: HTMLOrSVG, ...args: any[]) => {\n const action = (name: string, evt: Event | undefined, ...args: any[]) => {\n const err = error.bind(0, {\n plugin: { type: 'action', name },\n element: { id: el.id, tag: el.tagName },\n expression: {\n fnContent: expr,\n value,\n },\n })\n const fn = actions[name]\n if (fn) {\n return fn(\n {\n el,\n evt,\n error: err,\n },\n ...args,\n )\n }\n throw err('UndefinedAction')\n }\n try {\n return fn(el, root, action, undefined, ...args)\n } catch (e: any) {\n console.error(e)\n throw error(\n {\n element: { id: el.id, tag: el.tagName },\n expression: {\n fnContent: expr,\n value,\n },\n error: e.message,\n },\n 'ExecuteExpression',\n )\n }\n }\n } catch (e: any) {\n console.error(e)\n throw error(\n {\n expression: {\n fnContent: expr,\n value,\n },\n error: e.message,\n },\n 'GenerateExpression',\n )\n }\n}\n", "import { isHTMLOrSVG } from '@utils/dom'\nimport { aliasify } from '@utils/text'\n\nconst ctxIdMap = new Map>()\nconst ctxPersistentIds = new Set()\nconst oldIdTagNameMap = new Map()\nconst duplicateIds = new Set()\nconst ctxPantry = document.createElement('div')\nctxPantry.hidden = true\n\nconst aliasedIgnoreMorph = aliasify('ignore-morph')\nconst aliasedIgnoreMorphAttr = `[${aliasedIgnoreMorph}]`\nexport const morph = (\n oldElt: Element | ShadowRoot,\n newContent: DocumentFragment | Element,\n mode: 'outer' | 'inner' = 'outer',\n): void => {\n if (\n (isHTMLOrSVG(oldElt) &&\n isHTMLOrSVG(newContent) &&\n oldElt.hasAttribute(aliasedIgnoreMorph) &&\n newContent.hasAttribute(aliasedIgnoreMorph)) ||\n oldElt.parentElement?.closest(aliasedIgnoreMorphAttr)\n ) {\n return\n }\n\n const normalizedElt = document.createElement('div')\n normalizedElt.append(newContent)\n document.body.insertAdjacentElement('afterend', ctxPantry)\n\n // Computes the set of IDs that persist between the two contents excluding duplicates\n const oldIdElements = oldElt.querySelectorAll('[id]')\n for (const { id, tagName } of oldIdElements) {\n if (oldIdTagNameMap.has(id)) {\n duplicateIds.add(id)\n } else {\n oldIdTagNameMap.set(id, tagName)\n }\n }\n if (oldElt instanceof Element && oldElt.id) {\n if (oldIdTagNameMap.has(oldElt.id)) {\n duplicateIds.add(oldElt.id)\n } else {\n oldIdTagNameMap.set(oldElt.id, oldElt.tagName)\n }\n }\n\n ctxPersistentIds.clear()\n const newIdElements = normalizedElt.querySelectorAll('[id]')\n for (const { id, tagName } of newIdElements) {\n if (ctxPersistentIds.has(id)) {\n duplicateIds.add(id)\n } else if (oldIdTagNameMap.get(id) === tagName) {\n ctxPersistentIds.add(id)\n }\n }\n\n for (const id of duplicateIds) {\n ctxPersistentIds.delete(id)\n }\n\n oldIdTagNameMap.clear()\n duplicateIds.clear()\n ctxIdMap.clear()\n\n const parent = mode === 'outer' ? oldElt.parentElement! : oldElt\n populateIdMapWithTree(parent, oldIdElements)\n populateIdMapWithTree(normalizedElt, newIdElements)\n\n morphChildren(\n parent,\n normalizedElt,\n mode === 'outer' ? oldElt : null,\n oldElt.nextSibling,\n )\n\n ctxPantry.remove()\n}\n\n// This is the core algorithm for matching up children.\n// The idea is to use ID sets to try to match up nodes as faithfully as possible.\n// We greedily match, which allows us to keep the algorithm fast,\n// but by using ID sets, we are able to better match up with content deeper in the DOM.\nconst morphChildren = (\n oldParent: Element | ShadowRoot, // the old content that we are merging the new content into\n newParent: Element, // the parent element of the new content\n insertionPoint: Node | null = null, // the point in the DOM we start morphing at (defaults to first child)\n endPoint: Node | null = null, // the point in the DOM we stop morphing at (defaults to after last child)\n): void => {\n // normalize\n if (\n oldParent instanceof HTMLTemplateElement &&\n newParent instanceof HTMLTemplateElement\n ) {\n // we can pretend the DocumentElement is an Element\n oldParent = oldParent.content as unknown as Element\n newParent = newParent.content as unknown as Element\n }\n insertionPoint ??= oldParent.firstChild\n\n // run through all the new content\n for (const newChild of newParent.childNodes) {\n // once we reach the end of the old parent content skip to the end and insert the rest\n if (insertionPoint && insertionPoint !== endPoint) {\n const bestMatch = findBestMatch(newChild, insertionPoint, endPoint)\n if (bestMatch) {\n // if the node to morph is not at the insertion point then remove/move up to it\n if (bestMatch !== insertionPoint) {\n let cursor: Node | null = insertionPoint\n // Remove nodes between the start and end nodes\n while (cursor && cursor !== bestMatch) {\n const tempNode = cursor\n cursor = cursor.nextSibling\n removeNode(tempNode)\n }\n }\n morphNode(bestMatch, newChild)\n insertionPoint = bestMatch.nextSibling\n continue\n }\n }\n\n // if the matching node is elsewhere in the original content\n if (newChild instanceof Element && ctxPersistentIds.has(newChild.id)) {\n // move it and all its children here and morph, will always be found\n // Search for an element by ID within the document and pantry, and move it using moveBefore.\n const movedChild = document.getElementById(newChild.id) as Element\n\n // Removes an element from its ancestors' ID maps.\n // This is needed when an element is moved from the \"future\" via `moveBeforeId`.\n // Otherwise, its erstwhile ancestors could be mistakenly moved to the pantry rather than being deleted,\n // preventing their removal hooks from being called.\n let current = movedChild\n while ((current = current.parentNode as Element)) {\n const idSet = ctxIdMap.get(current)\n if (idSet) {\n idSet.delete(newChild.id)\n if (!idSet.size) {\n ctxIdMap.delete(current)\n }\n }\n }\n\n moveBefore(oldParent, movedChild, insertionPoint)\n morphNode(movedChild, newChild)\n insertionPoint = movedChild.nextSibling\n continue\n }\n\n // This performs the action of inserting a new node while handling situations where the node contains\n // elements with persistent IDs and possible state info we can still preserve by moving in and then morphing\n if (ctxIdMap.has(newChild)) {\n // node has children with IDs with possible state so create a dummy elt of same type and apply full morph algorithm\n const newEmptyChild = document.createElement(\n (newChild as Element).tagName,\n )\n oldParent.insertBefore(newEmptyChild, insertionPoint)\n morphNode(newEmptyChild, newChild)\n insertionPoint = newEmptyChild.nextSibling\n } else {\n // optimization: no id state to preserve so we can just insert a clone of the newChild and its descendants\n const newClonedChild = document.importNode(newChild, true) // importNode to not mutate newParent\n oldParent.insertBefore(newClonedChild, insertionPoint)\n insertionPoint = newClonedChild.nextSibling\n }\n }\n\n // remove any remaining old nodes that didn't match up with new content\n while (insertionPoint && insertionPoint !== endPoint) {\n const tempNode = insertionPoint\n insertionPoint = insertionPoint.nextSibling\n removeNode(tempNode)\n }\n}\n\n// Scans forward from the startPoint to the endPoint looking for a match for the node.\n// It looks for an id set match first, then a soft match.\n// We abort soft matching if we find two future soft matches, to reduce churn.\nconst findBestMatch = (\n node: Node,\n startPoint: Node | null,\n endPoint: Node | null,\n): Node | null => {\n let bestMatch: Node | null | undefined = null\n let nextSibling = node.nextSibling\n let siblingSoftMatchCount = 0\n let displaceMatchCount = 0\n\n // Max ID matches we are willing to displace in our search\n const nodeMatchCount = ctxIdMap.get(node)?.size || 0\n\n let cursor = startPoint\n while (cursor && cursor !== endPoint) {\n // soft matching is a prerequisite for id set matching\n if (isSoftMatch(cursor, node)) {\n let isIdSetMatch = false\n const oldSet = ctxIdMap.get(cursor)\n const newSet = ctxIdMap.get(node)\n\n if (newSet && oldSet) {\n for (const id of oldSet) {\n // a potential match is an id in the new and old nodes that\n // has not already been merged into the DOM\n // But the newNode content we call this on has not been\n // merged yet and we don't allow duplicate IDs so it is simple\n if (newSet.has(id)) {\n isIdSetMatch = true\n break\n }\n }\n }\n\n if (isIdSetMatch) {\n return cursor // found an id set match, we're done!\n }\n\n // we haven\u2019t yet saved a soft match fallback\n // the current soft match will hard match something else in the future, leave it\n if (!bestMatch && !ctxIdMap.has(cursor)) {\n // optimization: if node can't id set match, we can just return the soft match immediately\n if (!nodeMatchCount) {\n return cursor\n }\n // save this as the fallback if we get through the loop without finding a hard match\n bestMatch = cursor\n }\n }\n\n // check for IDs we may be displaced when matching\n displaceMatchCount += ctxIdMap.get(cursor)?.size || 0\n if (displaceMatchCount > nodeMatchCount) {\n // if we are going to displace more IDs than the node contains then\n // we do not have a good candidate for an ID match, so return\n break\n }\n\n if (bestMatch === null && nextSibling && isSoftMatch(cursor, nextSibling)) {\n // The next new node has a soft match with this node, so\n // increment the count of future soft matches\n siblingSoftMatchCount++\n nextSibling = nextSibling.nextSibling\n\n // If there are two future soft matches, block soft matching for this node to allow\n // future siblings to soft match. This is to reduce churn in the DOM when an element\n // is prepended.\n if (siblingSoftMatchCount >= 2) {\n bestMatch = undefined\n }\n }\n\n cursor = cursor.nextSibling\n }\n\n return bestMatch || null\n}\n\n// ok to cast: if one is not element, `id` and `tagName` will be null and we'll just compare that.\nconst isSoftMatch = (oldNode: Node, newNode: Node): boolean =>\n oldNode.nodeType === newNode.nodeType &&\n (oldNode as Element).tagName === (newNode as Element).tagName &&\n // If oldElt has an `id` with possible state and it doesn\u2019t match newElt.id then avoid morphing.\n // We'll still match an anonymous node with an IDed newElt, though, because if it got this far,\n // its not persistent, and new nodes can't have any hidden state.\n (!(oldNode as Element).id ||\n (oldNode as Element).id === (newNode as Element).id)\n\n// Gets rid of an unwanted DOM node; strategy depends on nature of its reuse:\n// - Persistent nodes will be moved to the pantry for later reuse\n// - Other nodes will have their hooks called, and then are removed\nconst removeNode = (node: Node): void => {\n // are we going to id set match this later?\n ctxIdMap.has(node)\n ? // skip callbacks and move to pantry\n moveBefore(ctxPantry, node, null)\n : // remove for realsies\n node.parentNode?.removeChild(node)\n}\n\n// Moves an element before another element within the same parent.\n// Uses the proposed `moveBefore` API if available (and working), otherwise falls back to `insertBefore`.\n// This is essentially a forward-compat wrapper.\nconst moveBefore: (parentNode: Node, node: Node, after: Node | null) => void =\n // @ts-expect-error\n removeNode.call.bind(ctxPantry.moveBefore ?? ctxPantry.insertBefore)\n\nconst aliasedPreserveAttr = aliasify('preserve-attr')\n\n// syncs the oldNode to the newNode, copying over all attributes and\n// inner element state from the newNode to the oldNode\nconst morphNode = (\n oldNode: Node, // root node to merge content into\n newNode: Node, // new content to merge\n): Node => {\n const type = newNode.nodeType\n\n // if is an element type, sync the attributes from the\n // new node into the new node\n if (type === 1 /* element type */) {\n const oldElt = oldNode as Element\n const newElt = newNode as Element\n if (\n oldElt.hasAttribute(aliasedIgnoreMorph) &&\n newElt.hasAttribute(aliasedIgnoreMorph)\n ) {\n return oldNode\n }\n\n // many bothans died to bring us this information:\n // https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n // https://github.com/choojs/nanomorph/blob/master/lib/morph.js#L113\n if (\n oldElt instanceof HTMLInputElement &&\n newElt instanceof HTMLInputElement &&\n newElt.type !== 'file'\n ) {\n // https://github.com/bigskysoftware/idiomorph/issues/27\n // | old input value | new input value | behaviour |\n // | --------------- | ---------------- | -------------------------------------- |\n // | `null` | `null` | preserve old input value |\n // | some value | the same value | preserve old input value |\n // | some value | `null` | set old input value to `\"\"` |\n // | `null` | some value | set old input value to new input value |\n // | some value | some other value | set old input value to new input value |\n if (newElt.getAttribute('value') !== oldElt.getAttribute('value')) {\n oldElt.value = newElt.getAttribute('value') ?? ''\n }\n } else if (\n oldElt instanceof HTMLTextAreaElement &&\n newElt instanceof HTMLTextAreaElement\n ) {\n if (newElt.value !== oldElt.value) {\n oldElt.value = newElt.value\n }\n if (oldElt.firstChild && oldElt.firstChild.nodeValue !== newElt.value) {\n oldElt.firstChild.nodeValue = newElt.value\n }\n }\n\n const preserveAttrs = (\n (newNode as HTMLElement).getAttribute(aliasedPreserveAttr) ?? ''\n ).split(' ')\n\n for (const { name, value } of newElt.attributes) {\n if (\n oldElt.getAttribute(name) !== value &&\n !preserveAttrs.includes(name)\n ) {\n oldElt.setAttribute(name, value)\n }\n }\n\n for (let i = oldElt.attributes.length - 1; i >= 0; i--) {\n const { name } = oldElt.attributes[i]!\n if (!newElt.hasAttribute(name) && !preserveAttrs.includes(name)) {\n oldElt.removeAttribute(name)\n }\n }\n\n if (!oldElt.isEqualNode(newElt)) {\n morphChildren(oldElt, newElt)\n }\n }\n\n if (type === 8 /* comment */ || type === 3 /* text */) {\n if (oldNode.nodeValue !== newNode.nodeValue) {\n oldNode.nodeValue = newNode.nodeValue\n }\n }\n\n return oldNode\n}\n\n// A bottom-up algorithm that populates a map of Element -> IdSet.\n// The ID set for a given element is the set of all IDs contained within its subtree.\n// As an optimization, we filter these IDs through the given list of persistent IDs,\n// because we don't need to bother considering IDed elements that won't be in the new content.\nconst populateIdMapWithTree = (\n root: Element | ShadowRoot | null,\n elements: Iterable,\n): void => {\n for (const elt of elements) {\n if (ctxPersistentIds.has(elt.id)) {\n let current: Element | null = elt\n // walk up the parent hierarchy of that element, adding the ID of element to the parent's ID set\n while (current && current !== root) {\n let idSet = ctxIdMap.get(current)\n // if the ID set doesn\u2019t exist, create it and insert it in the map\n if (!idSet) {\n idSet = new Set()\n ctxIdMap.set(current, idSet)\n }\n idSet.add(elt.id)\n current = current.parentElement\n }\n }\n }\n}\n", "// Icon: ion:eye\n// Slug: Access signals without subscribing to changes.\n// Description: Allows accessing signals without subscribing to their changes in expressions.\n\nimport { action } from '@engine'\nimport { startPeeking, stopPeeking } from '@engine/signals'\n\naction({\n name: 'peek',\n apply(_, fn: () => any) {\n startPeeking()\n try {\n return fn()\n } finally {\n stopPeeking()\n }\n },\n})\n", "// Icon: ion:checkmark-round\n// Slug: Sets the value of all matching signals.\n// Description: Sets the value of all matching signals (or all signals if no filter is used) to the expression provided in the first argument.\n\nimport { action } from '@engine'\nimport {\n filtered,\n mergePatch,\n startPeeking,\n stopPeeking,\n} from '@engine/signals'\nimport type { SignalFilterOptions } from '@engine/types'\nimport { updateLeaves } from '@utils/paths'\n\naction({\n name: 'setAll',\n apply(_, value: any, filter: SignalFilterOptions) {\n // peek because in an effect you would be subscribing to signals and then setting them which\n // would cause an infinite loop and why would you want to infinite loop on purpose\n startPeeking()\n const masked = filtered(filter)\n updateLeaves(masked, () => value)\n mergePatch(masked)\n stopPeeking()\n },\n})\n", "// Icon: material-symbols:toggle-off\n// Slug: Toggles the value of all matching signals.\n// Description: Toggles the boolean value of all matching signals (or all signals if no filter is used).\n\nimport { action } from '@engine'\nimport {\n filtered,\n mergePatch,\n startPeeking,\n stopPeeking,\n} from '@engine/signals'\nimport type { SignalFilterOptions } from '@engine/types'\nimport { updateLeaves } from '@utils/paths'\n\naction({\n name: 'toggleAll',\n apply(_, filter: SignalFilterOptions) {\n // peek because in an effect you would be subscribing to signals and then setting them which\n // would cause an infinite loop and why would you want to infinite loop on purpose\n startPeeking()\n const masked = filtered(filter)\n updateLeaves(masked, (oldValue: any) => !oldValue)\n mergePatch(masked)\n stopPeeking()\n },\n})\n", "// Icon: ion:eye\n// Slug: Access signals without subscribing to changes.\n// Description: Allows accessing signals without subscribing to their changes in expressions.\n\nimport { action } from '@engine'\nimport { DATASTAR_FETCH_EVENT } from '@engine/consts'\nimport { filtered } from '@engine/signals'\nimport type {\n DatastarFetchEvent,\n HTMLOrSVG,\n SignalFilterOptions,\n} from '@engine/types'\nimport { kebab } from '@utils/text'\n\nconst fetchAbortControllers = new WeakMap()\n\nconst createHttpMethod = (name: string, method: string): void =>\n action({\n name,\n apply: async (\n { el, evt, error },\n url: string,\n {\n selector,\n headers: userHeaders,\n contentType = 'json',\n filterSignals: { include = /.*/, exclude = /(^|\\.)_/ } = {},\n openWhenHidden = false,\n retryInterval = 1000,\n retryScaler = 2,\n retryMaxWaitMs = 30_000,\n retryMaxCount = 10,\n requestCancellation = 'auto',\n }: FetchArgs = {},\n ) => {\n const controller =\n requestCancellation instanceof AbortController\n ? requestCancellation\n : new AbortController()\n const isDisabled = requestCancellation === 'disabled'\n if (!isDisabled) {\n const oldController = fetchAbortControllers.get(el)\n if (oldController) {\n oldController.abort()\n // wait one tick for FINISHED to fire\n await Promise.resolve()\n }\n }\n\n if (!isDisabled && !(requestCancellation instanceof AbortController)) {\n fetchAbortControllers.set(el, controller)\n }\n\n try {\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const removed of mutation.removedNodes) {\n if (removed === el) {\n controller.abort()\n cleanupFn()\n }\n }\n }\n })\n if (el.parentNode) {\n observer.observe(el.parentNode, { childList: true })\n }\n\n let cleanupFn = () => {\n observer.disconnect()\n }\n\n try {\n if (!url?.length) {\n throw error('FetchNoUrlProvided', { action })\n }\n\n const initialHeaders: Record = {\n Accept: 'text/event-stream, text/html, application/json',\n 'Datastar-Request': true,\n }\n if (contentType === 'json') {\n initialHeaders['Content-Type'] = 'application/json'\n }\n const headers = Object.assign({}, initialHeaders, userHeaders)\n\n // We ignore the content-type header if using form data\n // if missing the boundary will be set automatically\n\n const req: FetchEventSourceInit = {\n method,\n headers,\n openWhenHidden,\n retryInterval,\n retryScaler,\n retryMaxWaitMs,\n retryMaxCount,\n signal: controller.signal,\n onopen: async (response: Response) => {\n if (response.status >= 400)\n dispatchFetch(ERROR, el, { status: response.status.toString() })\n },\n onmessage: (evt) => {\n if (!evt.event.startsWith('datastar')) return\n const type = evt.event\n const argsRawLines: Record = {}\n\n for (const line of evt.data.split('\\n')) {\n const i = line.indexOf(' ')\n const k = line.slice(0, i)\n const v = line.slice(i + 1)\n ;(argsRawLines[k] ||= []).push(v)\n }\n\n const argsRaw = Object.fromEntries(\n Object.entries(argsRawLines).map(([k, v]) => [k, v.join('\\n')]),\n )\n\n dispatchFetch(type, el, argsRaw)\n },\n onerror: (error) => {\n if (isWrongContent(error)) {\n // don't retry if the content-type is wrong\n throw error('FetchExpectedTextEventStream', { url })\n }\n // do nothing and it will retry\n if (error) {\n console.error(error.message)\n dispatchFetch(RETRYING, el, { message: error.message })\n }\n },\n }\n\n const urlInstance = new URL(url, document.baseURI)\n const queryParams = new URLSearchParams(urlInstance.search)\n\n if (contentType === 'json') {\n const res = JSON.stringify(filtered({ include, exclude }))\n if (method === 'GET') {\n queryParams.set('datastar', res)\n } else {\n req.body = res\n }\n } else if (contentType === 'form') {\n const formEl = (\n selector ? document.querySelector(selector) : el.closest('form')\n ) as HTMLFormElement\n if (!formEl) {\n throw error('FetchFormNotFound', { action, selector })\n }\n\n // Validate the form\n if (!formEl.checkValidity()) {\n formEl.reportValidity()\n cleanupFn()\n return\n }\n\n // Collect the form data\n\n const formData = new FormData(formEl)\n let submitter = el as HTMLElement | null\n\n if (el === formEl && evt instanceof SubmitEvent) {\n // Get the submitter from the event\n submitter = evt.submitter\n } else {\n // Prevent the form being submitted\n const preventDefault = (evt: Event) => evt.preventDefault()\n formEl.addEventListener('submit', preventDefault)\n cleanupFn = () => {\n formEl.removeEventListener('submit', preventDefault)\n observer.disconnect()\n }\n }\n\n // Append the value of the form submitter if it is a button with a name\n if (submitter instanceof HTMLButtonElement) {\n const name = submitter.getAttribute('name')\n if (name) formData.append(name, submitter.value)\n }\n\n const multipart =\n formEl.getAttribute('enctype') === 'multipart/form-data'\n // Leave the `Content-Type` header empty for multipart encoding so the browser can set it automatically with the correct boundary\n if (!multipart) {\n headers['Content-Type'] = 'application/x-www-form-urlencoded'\n }\n\n const formParams = new URLSearchParams(formData as any)\n if (method === 'GET') {\n for (const [key, value] of formParams) {\n queryParams.append(key, value)\n }\n } else if (multipart) {\n req.body = formData\n } else {\n req.body = formParams\n }\n } else {\n throw error('FetchInvalidContentType', { action, contentType })\n }\n\n dispatchFetch(STARTED, el, {})\n urlInstance.search = queryParams.toString()\n\n try {\n await fetchEventSource(urlInstance.toString(), el, req)\n } catch (e: any) {\n if (!isWrongContent(e)) {\n throw error('FetchFailed', { method, url, error: e.message })\n }\n // exit gracefully and do nothing if the content-type is wrong\n // this can happen if the client is sending a request\n // where no response is expected, and they haven\u2019t\n // set the content-type to text/event-stream\n }\n } finally {\n dispatchFetch(FINISHED, el, {})\n cleanupFn()\n }\n } finally {\n if (fetchAbortControllers.get(el) === controller) {\n fetchAbortControllers.delete(el)\n }\n }\n },\n })\n\ncreateHttpMethod('delete', 'DELETE')\ncreateHttpMethod('get', 'GET')\ncreateHttpMethod('patch', 'PATCH')\ncreateHttpMethod('post', 'POST')\ncreateHttpMethod('put', 'PUT')\n\nexport const STARTED = 'started'\nexport const FINISHED = 'finished'\nexport const ERROR = 'error'\nexport const RETRYING = 'retrying'\nexport const RETRIES_FAILED = 'retries-failed'\n\nconst dispatchFetch = (\n type: string,\n el: HTMLOrSVG,\n argsRaw: Record,\n) =>\n document.dispatchEvent(\n new CustomEvent(DATASTAR_FETCH_EVENT, {\n detail: { type, el, argsRaw },\n }),\n )\n\nconst isWrongContent = (err: any) => `${err}`.includes('text/event-stream')\n\ntype ResponseOverrides =\n | {\n selector?: string\n mode?: string\n useViewTransition?: boolean\n }\n | {\n onlyIfMissing?: boolean\n }\n\nexport type FetchArgs = {\n headers?: Record\n openWhenHidden?: boolean\n retryInterval?: number\n retryScaler?: number\n retryMaxWaitMs?: number\n retryMaxCount?: number\n responseOverrides?: ResponseOverrides\n contentType?: 'json' | 'form'\n filterSignals?: SignalFilterOptions\n selector?: string\n requestCancellation?: 'auto' | 'disabled' | AbortController\n}\n\n// Below originally from https://github.com/Azure/fetch-event-source/blob/main/LICENSE\n\n/**\n * Represents a message sent in an event stream\n * https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format\n */\n\ninterface EventSourceMessage {\n id: string\n event: string\n data: string\n retry?: number\n}\n\n/**\n * Converts a ReadableStream into a callback pattern.\n * @param stream The input ReadableStream.\n * @param onChunk A function that will be called on each new byte chunk in the stream.\n * @returns {Promise} A promise that will be resolved when the stream closes.\n */\nconst getBytes = async (\n stream: ReadableStream,\n onChunk: (arr: Uint8Array) => void,\n): Promise => {\n const reader = stream.getReader()\n let result = await reader.read()\n while (!result.done) {\n onChunk(result.value)\n result = await reader.read()\n }\n}\n\nconst getLines = (onLine: (line: Uint8Array, fieldLength: number) => void) => {\n let buffer: Uint8Array | undefined\n let position: number // current read position\n let fieldLength: number // length of the `field` portion of the line\n let discardTrailingNewline = false\n\n // return a function that can process each incoming byte chunk:\n return (arr: Uint8Array) => {\n if (!buffer) {\n buffer = arr\n position = 0\n fieldLength = -1\n } else {\n // we're still parsing the old line. Append the new bytes into buffer:\n buffer = concat(buffer, arr)\n }\n\n const bufLength = buffer.length\n let lineStart = 0 // index where the current line starts\n while (position < bufLength) {\n if (discardTrailingNewline) {\n if (buffer[position] === 10) lineStart = ++position // skip to next char\n discardTrailingNewline = false\n }\n\n // start looking forward till the end of line:\n let lineEnd = -1 // index of the \\r or \\n char\n for (; position < bufLength && lineEnd === -1; ++position) {\n switch (buffer[position]) {\n case 58: // :\n if (fieldLength === -1) {\n // first colon in line\n fieldLength = position - lineStart\n }\n break\n // @ts-expect-error:7029 \\r case below should fallthrough to \\n:\n // biome-ignore lint/suspicious/noFallthroughSwitchClause: intentional fallthrough for CR to LF\n case 13: // \\r\n discardTrailingNewline = true\n case 10: // \\n\n lineEnd = position\n break\n }\n }\n\n if (lineEnd === -1) break // Wait for the next arr and then continue parsing\n\n // we've reached the line end, send it out:\n onLine(buffer.subarray(lineStart, lineEnd), fieldLength)\n lineStart = position // we're now on the next line\n fieldLength = -1\n }\n\n if (lineStart === bufLength)\n buffer = undefined // we've finished reading it\n else if (lineStart) {\n // Create a new view into buffer beginning at lineStart so we don't\n // need to copy over the previous lines when we get the new arr:\n buffer = buffer.subarray(lineStart)\n position -= lineStart\n }\n }\n}\n\nconst getMessages = (\n onId: (id: string) => void,\n onRetry: (retry: number) => void,\n onMessage?: (msg: EventSourceMessage) => void,\n): ((line: Uint8Array, fieldLength: number) => void) => {\n let message = newMessage()\n const decoder = new TextDecoder()\n\n // return a function that can process each incoming line buffer:\n return (line, fieldLength) => {\n if (!line.length) {\n // empty line denotes end of message. Trigger the callback and start a new message:\n onMessage?.(message)\n message = newMessage()\n } else if (fieldLength > 0) {\n // exclude comments and lines with no values\n // line is of format \":\" or \": \"\n // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation\n const field = decoder.decode(line.subarray(0, fieldLength))\n const valueOffset = fieldLength + (line[fieldLength + 1] === 32 ? 2 : 1)\n const value = decoder.decode(line.subarray(valueOffset))\n\n switch (field) {\n case 'data':\n message.data = message.data ? `${message.data}\\n${value}` : value\n break\n case 'event':\n message.event = value\n break\n case 'id':\n onId((message.id = value))\n break\n case 'retry': {\n const retry = +value\n if (!Number.isNaN(retry)) {\n // per spec, ignore non-integers\n onRetry((message.retry = retry))\n }\n break\n }\n }\n }\n }\n}\n\nconst concat = (a: Uint8Array, b: Uint8Array) => {\n const res = new Uint8Array(a.length + b.length)\n res.set(a)\n res.set(b, a.length)\n return res\n}\n\nconst newMessage = (): EventSourceMessage => ({\n // data, event, and id must be initialized to empty strings:\n // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation\n // retry should be initialized to undefined so we return a consistent shape\n // to the js engine all the time: https://mathiasbynens.be/notes/shapes-ics#takeaways\n data: '',\n event: '',\n id: '',\n retry: undefined,\n})\n\ntype FetchEventSourceInit = RequestInit & {\n headers?: Record\n onopen?: (response: Response) => Promise\n onmessage?: (ev: EventSourceMessage) => void\n onclose?: () => void\n onerror?: (err: any) => number | null | undefined | void\n openWhenHidden?: boolean\n fetch?: typeof fetch\n retryInterval?: number\n retryScaler?: number\n retryMaxWaitMs?: number\n retryMaxCount?: number\n overrides?: ResponseOverrides\n}\n\nconst fetchEventSource = (\n input: RequestInfo,\n el: HTMLOrSVG,\n {\n signal: inputSignal,\n headers: inputHeaders,\n onopen: inputOnOpen,\n onmessage,\n onclose,\n onerror,\n openWhenHidden,\n fetch: inputFetch,\n retryInterval = 1_000,\n retryScaler = 2,\n retryMaxWaitMs = 30_000,\n retryMaxCount = 10,\n overrides,\n ...rest\n }: FetchEventSourceInit,\n): Promise => {\n return new Promise((resolve, reject) => {\n // make a copy of the input headers since we may modify it below:\n const headers: Record = {\n ...inputHeaders,\n }\n\n let curRequestController: AbortController\n const onVisibilityChange = () => {\n curRequestController.abort() // close existing request on every visibility change\n if (!document.hidden) create() // page is now visible again, recreate request.\n }\n\n if (!openWhenHidden) {\n document.addEventListener('visibilitychange', onVisibilityChange)\n }\n\n let retryTimer = 0\n const dispose = () => {\n document.removeEventListener('visibilitychange', onVisibilityChange)\n clearTimeout(retryTimer)\n curRequestController.abort()\n }\n\n // if the incoming signal aborts, dispose resources and resolve:\n inputSignal?.addEventListener('abort', () => {\n dispose()\n resolve() // don't waste time constructing/logging errors\n })\n\n const fetch = inputFetch || window.fetch\n const onopen = inputOnOpen || (() => {})\n\n let retries = 0\n let baseRetryInterval = retryInterval\n const create = async () => {\n curRequestController = new AbortController()\n try {\n const response = await fetch(input, {\n ...rest,\n headers,\n signal: curRequestController.signal,\n })\n\n // on successful connection, reset the retry logic\n retries = 0\n retryInterval = baseRetryInterval\n\n await onopen(response)\n\n const dispatchNonSSE = async (\n dispatchType: string,\n response: Response,\n name: string,\n overrides?: ResponseOverrides,\n ...argNames: string[]\n ) => {\n const argsRaw: Record = {\n [name]: await response.text(),\n }\n for (const n of argNames) {\n let v = response.headers.get(`datastar-${kebab(n)}`)\n if (overrides) {\n const o = (overrides as any)[n]\n if (o) v = typeof o === 'string' ? o : JSON.stringify(o)\n }\n if (v) argsRaw[n] = v\n }\n\n dispatchFetch(dispatchType, el, argsRaw)\n dispose()\n resolve()\n }\n\n const ct = response.headers.get('Content-Type')\n if (ct?.includes('text/html')) {\n return await dispatchNonSSE(\n 'datastar-patch-elements',\n response,\n 'elements',\n overrides,\n 'selector',\n 'mode',\n 'useViewTransition',\n )\n }\n\n if (ct?.includes('application/json')) {\n return await dispatchNonSSE(\n 'datastar-patch-signals',\n response,\n 'signals',\n overrides,\n 'onlyIfMissing',\n )\n }\n\n if (ct?.includes('text/javascript')) {\n const script = document.createElement('script')\n const scriptAttributesHeader = response.headers.get(\n 'datastar-script-attributes',\n )\n\n if (scriptAttributesHeader) {\n for (const [name, value] of Object.entries(\n JSON.parse(scriptAttributesHeader),\n )) {\n script.setAttribute(name, value as string)\n }\n }\n script.textContent = await response.text()\n document.head.appendChild(script)\n dispose()\n return\n }\n\n await getBytes(\n response.body!,\n getLines(\n getMessages(\n (id) => {\n if (id) {\n // signals the id and send it back on the next retry:\n headers['last-event-id'] = id\n } else {\n // don't send the last-event-id header anymore:\n delete headers['last-event-id']\n }\n },\n (retry) => {\n baseRetryInterval = retryInterval = retry\n },\n onmessage,\n ),\n ),\n )\n\n onclose?.()\n dispose()\n resolve()\n } catch (err) {\n if (!curRequestController.signal.aborted) {\n // if we haven\u2019t aborted the request ourselves:\n try {\n // check if we need to retry:\n const interval: any = onerror?.(err) || retryInterval\n clearTimeout(retryTimer)\n retryTimer = setTimeout(create, interval)\n retryInterval = Math.min(\n retryInterval * retryScaler,\n retryMaxWaitMs,\n ) // exponential backoff\n if (++retries >= retryMaxCount) {\n dispatchFetch(RETRIES_FAILED, el, {})\n // we should not retry anymore:\n dispose()\n reject('Max retries reached.') // Max retries reached, check your server or network connection\n } else {\n console.error(\n `Datastar failed to reach ${input.toString()} retrying in ${interval}ms.`,\n )\n }\n } catch (innerErr) {\n // we should not retry anymore:\n dispose()\n reject(innerErr)\n }\n }\n }\n }\n\n create()\n })\n}\n", "// Icon: material-symbols:edit-attributes-outline\n// Slug: Syncs the value of an attribute with an expression.\n// Description: Sets the value of any HTML attribute to an expression, and keeps it in sync.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nattribute({\n name: 'attr',\n requirement: { value: 'must' },\n returnsValue: true,\n apply({ el, key, rx }) {\n const syncAttr = (key: string, val: any) => {\n if (val === '' || val === true) {\n el.setAttribute(key, '')\n } else if (val === false || val == null) {\n el.removeAttribute(key)\n } else if (typeof val === 'string') {\n el.setAttribute(key, val)\n } else {\n el.setAttribute(key, JSON.stringify(val))\n }\n }\n\n const update = key\n ? () => {\n observer.disconnect()\n const val = rx() as string\n syncAttr(key, val)\n observer.observe(el, {\n attributeFilter: [key],\n })\n }\n : () => {\n observer.disconnect()\n const obj = rx() as Record\n const attributeFilter = Object.keys(obj)\n for (const key of attributeFilter) {\n syncAttr(key, obj[key])\n }\n observer.observe(el, {\n attributeFilter,\n })\n }\n\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "// Icon: akar-icons:link-chain\n// Slug: Creates a signal with two-way data binding.\n// Description: Creates a signal (if one doesn\u2019t already exist) and sets up two-way data binding between it and an element\u2019s value.\n\nimport { attribute } from '@engine'\nimport { effect, getPath, mergePaths } from '@engine/signals'\nimport type { Paths } from '@engine/types'\nimport { aliasify, modifyCasing } from '@utils/text'\n\ntype SignalFile = {\n name: string\n contents: string\n mime: string\n}\n\nconst dataURIRegex = /^data:(?[^;]+);base64,(?.*)$/\nconst empty = Symbol('empty')\n\nconst aliasedBind = aliasify('bind')\n\nattribute({\n name: 'bind',\n requirement: 'exclusive',\n apply({ el, key, mods, value, error }) {\n const signalName = key != null ? modifyCasing(key, mods) : value\n\n let get = (el: any, type: string) =>\n type === 'number' ? +el.value : el.value\n\n let set = (value: any) => {\n ;(el as HTMLInputElement).value = `${value}`\n }\n\n if (el instanceof HTMLInputElement) {\n switch (el.type) {\n case 'range':\n case 'number':\n get = (el: any, type: string) =>\n type === 'string' ? el.value : +el.value\n break\n\n case 'checkbox':\n get = (el: HTMLInputElement, type: string) => {\n if (el.value !== 'on') {\n if (type === 'boolean') {\n return el.checked\n } else {\n return el.checked ? el.value : ''\n }\n } else {\n if (type === 'string') {\n return el.checked ? el.value : ''\n } else {\n return el.checked\n }\n }\n }\n set = (value: string | boolean) => {\n el.checked = typeof value === 'string' ? value === el.value : value\n }\n break\n\n case 'radio':\n // Set up radio button name attribute if not present\n if (!el.getAttribute('name')?.length) {\n el.setAttribute('name', signalName)\n }\n\n get = (el: HTMLInputElement, type: string) =>\n el.checked ? (type === 'number' ? +el.value : el.value) : empty\n set = (value: string | number) => {\n el.checked =\n value === (typeof value === 'number' ? +el.value : el.value)\n }\n break\n case 'file': {\n const syncSignal = () => {\n const files = [...(el.files || [])]\n const signalFiles: SignalFile[] = []\n Promise.all(\n files.map(\n (f) =>\n new Promise((resolve) => {\n const reader = new FileReader()\n reader.onload = () => {\n if (typeof reader.result !== 'string') {\n throw error('InvalidFileResultType', {\n resultType: typeof reader.result,\n })\n }\n const match = reader.result.match(dataURIRegex)\n if (!match?.groups) {\n throw error('InvalidDataUri', {\n result: reader.result,\n })\n }\n signalFiles.push({\n name: f.name,\n contents: match.groups.contents,\n mime: match.groups.mime,\n })\n }\n reader.onloadend = () => resolve()\n reader.readAsDataURL(f)\n }),\n ),\n ).then(() => {\n mergePaths([[signalName, signalFiles]])\n })\n }\n\n el.addEventListener('change', syncSignal)\n el.addEventListener('input', syncSignal)\n\n return () => {\n el.removeEventListener('change', syncSignal)\n el.removeEventListener('input', syncSignal)\n }\n }\n }\n } else if (el instanceof HTMLSelectElement) {\n if (el.multiple) {\n const typeMap = new Map()\n get = (el: HTMLSelectElement) =>\n [...el.selectedOptions].map((option) => {\n const type = typeMap.get(option.value)\n return type === 'string' || type == null\n ? option.value\n : +option.value\n })\n\n set = (value: (string | number)[]) => {\n for (const option of el.options) {\n if (value.includes(option.value)) {\n typeMap.set(option.value, 'string')\n option.selected = true\n } else if (value.includes(+option.value)) {\n typeMap.set(option.value, 'number')\n option.selected = true\n } else {\n option.selected = false\n }\n }\n }\n }\n } else if (el instanceof HTMLTextAreaElement) {\n // default case\n } else {\n // web component\n get = (el: Element) =>\n 'value' in el ? el.value : el.getAttribute('value')\n set = (value: any) => {\n if ('value' in el) {\n el.value = value\n } else {\n el.setAttribute('value', value)\n }\n }\n }\n\n const initialValue = getPath(signalName)\n const type = typeof initialValue\n\n let path = signalName\n if (\n Array.isArray(initialValue) &&\n !(el instanceof HTMLSelectElement && el.multiple)\n ) {\n const signalNameKebab = key ? key : value!\n const inputs = document.querySelectorAll(\n `[${aliasedBind}\\\\:${CSS.escape(signalNameKebab)}],[${aliasedBind}=\"${CSS.escape(signalNameKebab)}\"]`,\n ) as NodeListOf\n\n const paths: Paths = []\n let i = 0\n for (const input of inputs) {\n paths.push([`${path}.${i}`, get(input, 'none')])\n\n if (el === input) {\n break\n }\n i++\n }\n mergePaths(paths, { ifMissing: true })\n path = `${path}.${i}`\n } else {\n mergePaths([[path, get(el, type)]], {\n ifMissing: true,\n })\n }\n\n const syncSignal = () => {\n const signalValue = getPath(path)\n if (signalValue != null) {\n const value = get(el, typeof signalValue)\n if (value !== empty) {\n mergePaths([[path, value]])\n }\n }\n }\n\n el.addEventListener('input', syncSignal)\n el.addEventListener('change', syncSignal)\n const cleanup = effect(() => {\n set(getPath(path))\n })\n\n return () => {\n cleanup()\n el.removeEventListener('input', syncSignal)\n el.removeEventListener('change', syncSignal)\n }\n },\n})\n", "// Icon: ic:baseline-format-paint\n// Slug: Adds or removes a class based on an expression.\n// Description: Adds or removes a class to or from an element based on an expression.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'class',\n requirement: {\n value: 'must',\n },\n returnsValue: true,\n apply({ key, el, mods, rx }) {\n if (key) {\n key = modifyCasing(key, mods, 'kebab')\n }\n\n const callback = () => {\n observer.disconnect()\n\n const classes = key\n ? { [key]: rx() as boolean }\n : (rx() as Record)\n\n for (const k in classes) {\n const classNames = k.split(/\\s+/).filter((cn) => cn.length > 0)\n if (classes[k]) {\n for (const name of classNames) {\n if (!el.classList.contains(name)) {\n el.classList.add(name)\n }\n }\n } else {\n for (const name of classNames) {\n if (el.classList.contains(name)) {\n el.classList.remove(name)\n }\n }\n }\n }\n\n observer.observe(el, { attributeFilter: ['class'] })\n }\n\n const observer = new MutationObserver(callback)\n const cleanup = effect(callback)\n\n return () => {\n observer.disconnect()\n cleanup()\n\n const classes = key\n ? { [key]: rx() as boolean }\n : (rx() as Record)\n\n for (const k in classes) {\n const classNames = k.split(/\\s+/).filter((cn) => cn.length > 0)\n for (const name of classNames) {\n el.classList.remove(name)\n }\n }\n }\n },\n})\n", "// Icon: streamline-ultimate:wifi-signal-2\n// Slug: Creates a computed signal.\n// Description: Creates a signal that is computed based on an expression.\n\nimport { attribute } from '@engine'\nimport { computed, mergePaths, mergePatch } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\nimport { updateLeaves } from '@utils/paths'\n\nattribute({\n name: 'computed',\n requirement: {\n value: 'must',\n },\n returnsValue: true,\n apply({ key, mods, rx, error }) {\n if (key) {\n mergePaths([[modifyCasing(key, mods), computed(rx)]])\n } else {\n const patch = Object.assign({}, rx() as Record any>)\n updateLeaves(patch, (old) => {\n if (typeof old === 'function') {\n return computed(old)\n } else {\n throw error('ComputedExpectedFunction')\n }\n })\n mergePatch(patch)\n }\n },\n})\n", "// Icon: oui:security-signal\n// Slug: Executes an expression when signals change.\n// Description: Executes an expression on page load and whenever any signals in the expression change.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nattribute({\n name: 'effect',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply: ({ rx }) => effect(rx),\n})\n", "// Icon: streamline:signal-loading-remix\n// Slug: Creates an indicator for whether an SSE request is in flight.\n// Description: Creates a signal and sets its value to `true` while an SSE request request is in flight, otherwise `false`.\n\nimport { attribute } from '@engine'\nimport { DATASTAR_FETCH_EVENT } from '@engine/consts'\nimport { mergePaths } from '@engine/signals'\nimport type { DatastarFetchEvent } from '@engine/types'\nimport { FINISHED, STARTED } from '@plugins/actions/fetch'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'indicator',\n requirement: 'exclusive',\n apply({ el, key, mods, value }) {\n const signalName = key != null ? modifyCasing(key, mods) : value\n\n mergePaths([[signalName, false]])\n\n const watcher = ((event: CustomEvent) => {\n const { type, el: elt } = event.detail\n if (elt !== el) {\n return\n }\n switch (type) {\n case STARTED:\n mergePaths([[signalName, true]])\n break\n case FINISHED:\n mergePaths([[signalName, false]])\n break\n }\n }) as EventListener\n document.addEventListener(DATASTAR_FETCH_EVENT, watcher)\n return () => {\n mergePaths([[signalName, false]])\n document.removeEventListener(DATASTAR_FETCH_EVENT, watcher)\n }\n },\n})\n", "// Icon: si:json-fill\n// Slug: Outputs a JSON stringified version of signals.\n// Description: Sets the text content of an element to a reactive JSON stringified version of signals.\n\nimport { attribute } from '@engine'\nimport { effect, filtered } from '@engine/signals'\nimport type { SignalFilterOptions } from '@engine/types'\nimport { jsStrToObject } from '@utils/text'\n\nattribute({\n name: 'json-signals',\n requirement: {\n key: 'denied',\n },\n apply({ el, value, mods }) {\n const spaces = mods.has('terse') ? 0 : 2\n let filters: SignalFilterOptions = {}\n if (value) {\n filters = jsStrToObject(value)\n }\n\n const callback = () => {\n observer.disconnect()\n el.textContent = JSON.stringify(filtered(filters), null, spaces)\n observer.observe(el, {\n childList: true,\n characterData: true,\n subtree: true,\n })\n }\n const observer = new MutationObserver(callback)\n const cleanup = effect(callback)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "export const tagToMs = (args: Set) => {\n if (!args || args.size <= 0) return 0\n for (const arg of args) {\n if (arg.endsWith('ms')) {\n return +arg.replace('ms', '')\n }\n if (arg.endsWith('s')) {\n return +arg.replace('s', '') * 1000\n }\n try {\n return Number.parseFloat(arg)\n } catch (_) {}\n }\n return 0\n}\n\nexport const tagHas = (\n tags: Set,\n tag: string,\n defaultValue = false,\n) => {\n if (!tags) return defaultValue\n return tags.has(tag.toLowerCase())\n}\n\nexport const tagFirst = (tags?: Set, defaultValue = ''): string => {\n if (tags && tags.size > 0) {\n for (const tag of tags) {\n return tag\n }\n }\n return defaultValue\n}\n", "import type { EventCallbackHandler, Modifiers } from '@engine/types'\nimport { tagHas, tagToMs } from '@utils/tags'\n\nexport const delay = (\n callback: EventCallbackHandler,\n wait: number,\n): EventCallbackHandler => {\n return (...args: any[]) => {\n setTimeout(() => {\n callback(...args)\n }, wait)\n }\n}\n\nexport const debounce = (\n callback: EventCallbackHandler,\n wait: number,\n leading = false,\n trailing = true,\n): EventCallbackHandler => {\n let timer = 0\n return (...args: any[]) => {\n timer && clearTimeout(timer)\n\n if (leading && !timer) {\n callback(...args)\n }\n\n timer = setTimeout(() => {\n if (trailing) {\n callback(...args)\n }\n timer && clearTimeout(timer)\n timer = 0\n }, wait)\n }\n}\n\nexport const throttle = (\n callback: EventCallbackHandler,\n wait: number,\n leading = true,\n trailing = false,\n): EventCallbackHandler => {\n let waiting = false\n\n return (...args: any[]) => {\n if (waiting) return\n\n if (leading) {\n callback(...args)\n }\n\n waiting = true\n setTimeout(() => {\n if (trailing) {\n callback(...args)\n }\n waiting = false\n }, wait)\n }\n}\n\nexport const modifyTiming = (\n callback: EventCallbackHandler,\n mods: Modifiers,\n): EventCallbackHandler => {\n const delayArgs = mods.get('delay')\n if (delayArgs) {\n const wait = tagToMs(delayArgs)\n callback = delay(callback, wait)\n }\n\n const debounceArgs = mods.get('debounce')\n if (debounceArgs) {\n const wait = tagToMs(debounceArgs)\n const leading = tagHas(debounceArgs, 'leading', false)\n const trailing = !tagHas(debounceArgs, 'notrailing', false)\n callback = debounce(callback, wait, leading, trailing)\n }\n\n const throttleArgs = mods.get('throttle')\n if (throttleArgs) {\n const wait = tagToMs(throttleArgs)\n const leading = !tagHas(throttleArgs, 'noleading', false)\n const trailing = tagHas(throttleArgs, 'trailing', false)\n callback = throttle(callback, wait, leading, trailing)\n }\n\n return callback\n}\n", "import type { EventCallbackHandler, Modifiers } from '@engine/types'\n\nexport const supportsViewTransitions = !!document.startViewTransition\n\nexport const modifyViewTransition = (\n callback: EventCallbackHandler,\n mods: Modifiers,\n): EventCallbackHandler => {\n if (mods.has('viewtransition') && supportsViewTransitions) {\n const cb = callback // I hate javascript\n callback = (...args: any[]) =>\n document.startViewTransition(() => cb(...args))\n }\n\n return callback\n}\n", "// Icon: material-symbols:mail\n// Slug: Attaches an event listener to an element.\n// Description: Attaches an event listener to an element, executing an expression whenever the event is triggered.\n\nimport { attribute } from '@engine'\nimport {\n DATASTAR_FETCH_EVENT,\n DATASTAR_SIGNAL_PATCH_EVENT,\n} from '@engine/consts'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\nimport { modifyTiming } from '@utils/timing'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nattribute({\n name: 'on',\n requirement: 'must',\n argNames: ['evt'],\n apply({ el, key, mods, rx }) {\n let target: Element | Window | Document = el\n if (mods.has('window')) target = window\n let callback = (evt?: Event) => {\n if (evt) {\n if (mods.has('prevent')) {\n evt.preventDefault()\n }\n if (mods.has('stop')) {\n evt.stopPropagation()\n }\n }\n beginBatch()\n rx(evt)\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n callback = modifyTiming(callback, mods)\n const evtListOpts: AddEventListenerOptions = {\n capture: mods.has('capture'),\n passive: mods.has('passive'),\n once: mods.has('once'),\n }\n if (mods.has('outside')) {\n target = document\n const cb = callback\n callback = (evt?: Event) => {\n if (!el.contains(evt?.target as HTMLElement)) {\n cb(evt)\n }\n }\n }\n const eventName = modifyCasing(key, mods, 'kebab')\n // Listen for Datastar events on the document\n if (\n eventName === DATASTAR_FETCH_EVENT ||\n eventName === DATASTAR_SIGNAL_PATCH_EVENT\n ) {\n target = document\n }\n // Prevent default on form submit events\n if (el instanceof HTMLFormElement && eventName === 'submit') {\n const cb = callback\n callback = (evt?: Event) => {\n evt?.preventDefault()\n cb(evt)\n }\n }\n target.addEventListener(eventName, callback, evtListOpts)\n return () => {\n target.removeEventListener(eventName, callback)\n }\n },\n})\n", "// Icon: mdi-light:vector-intersection\n// Slug: Runs an expression on intersection.\n// Description: Runs an expression when the element intersects with the viewport.\n\nimport { attribute } from '@engine'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport type { HTMLOrSVG } from '@engine/types'\nimport { modifyTiming } from '@utils/timing'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nconst once = new WeakSet()\n\nattribute({\n name: 'on-intersect',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply({ el, mods, rx }) {\n let callback = () => {\n beginBatch()\n rx()\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n callback = modifyTiming(callback, mods)\n const options = { threshold: 0 }\n if (mods.has('full')) {\n options.threshold = 1\n } else if (mods.has('half')) {\n options.threshold = 0.5\n }\n let observer: IntersectionObserver | null = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n callback()\n if (observer && once.has(el)) {\n observer.disconnect()\n }\n }\n }\n },\n options,\n )\n observer.observe(el)\n if (mods.has('once')) {\n once.add(el)\n }\n return () => {\n if (!mods.has('once')) {\n once.delete(el)\n }\n if (observer) {\n observer.disconnect()\n observer = null\n }\n }\n },\n})\n", "// Icon: material-symbols:timer-outline\n// Slug: Runs an expression at a regular interval.\n// Description: Runs an expression at a regular interval.\n\nimport { attribute } from '@engine'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport { tagHas, tagToMs } from '@utils/tags'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nattribute({\n name: 'on-interval',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply({ mods, rx }) {\n let callback = () => {\n beginBatch()\n rx()\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n let duration = 1000\n const durationArgs = mods.get('duration')\n if (durationArgs) {\n duration = tagToMs(durationArgs)\n const leading = tagHas(durationArgs, 'leading', false)\n if (leading) {\n callback()\n }\n }\n const intervalId = setInterval(callback, duration)\n return () => {\n clearInterval(intervalId)\n }\n },\n})\n", "// Icon: material-symbols:timer-play-outline\n// Slug: Runs an expression when loaded into the DOM.\n// Description: Runs an expression when the element is loaded into the DOM.\n\nimport { attribute } from '@engine'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport { tagToMs } from '@utils/tags'\nimport { delay } from '@utils/timing'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nattribute({\n name: 'init',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply({ rx, mods }) {\n let callback = () => {\n beginBatch()\n rx()\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n let wait = 0\n const delayArgs = mods.get('delay')\n if (delayArgs) {\n wait = tagToMs(delayArgs)\n if (wait > 0) {\n callback = delay(callback, wait)\n }\n }\n callback()\n },\n})\n", "// Icon: material-symbols:change-circle-outline\n// Slug: Runs an expression when signals are patched.\n// Description: Runs an expression whenever one or more signals are patched.\n\nimport { attribute } from '@engine'\nimport { DATASTAR_SIGNAL_PATCH_EVENT } from '@engine/consts'\nimport { beginBatch, endBatch, filtered } from '@engine/signals'\nimport type { JSONPatch, SignalFilterOptions } from '@engine/types'\nimport { isEmpty } from '@utils/paths'\nimport { jsStrToObject } from '@utils/text'\nimport { modifyTiming } from '@utils/timing'\n\nattribute({\n name: 'on-signal-patch',\n requirement: {\n value: 'must',\n },\n argNames: ['patch'],\n returnsValue: true,\n apply({ el, key, mods, rx, error }) {\n if (!!key && key !== 'filter') {\n throw error('KeyNotAllowed')\n }\n\n // Look for data-on-signal-patch-filter data attribute\n const filtersRaw = el.getAttribute('data-on-signal-patch-filter')\n let filters: SignalFilterOptions = {}\n if (filtersRaw) {\n filters = jsStrToObject(filtersRaw)\n }\n\n const callback: EventListener = modifyTiming(\n (evt: CustomEvent) => {\n const watched = filtered(filters, evt.detail)\n if (!isEmpty(watched)) {\n beginBatch()\n rx(watched)\n endBatch()\n }\n },\n mods,\n )\n\n document.addEventListener(DATASTAR_SIGNAL_PATCH_EVENT, callback)\n return () => {\n document.removeEventListener(DATASTAR_SIGNAL_PATCH_EVENT, callback)\n }\n },\n})\n", "// Icon: mdi:cursor-pointer\n// Slug: Creates a reference to an element.\n// Description: Creates a new signal that is a reference to the element on which the data attribute is placed.\n\nimport { attribute } from '@engine'\nimport { mergePaths } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'ref',\n requirement: 'exclusive',\n apply({ el, key, mods, value }) {\n const signalName = key != null ? modifyCasing(key, mods) : value\n mergePaths([[signalName, el]])\n },\n})\n", "// Icon: streamline:interface-edit-view-eye-eyeball-open-view\n// Slug: Shows or hides an element.\n// Description: Shows or hides an element based on whether an expression evaluates to `true` or `false`.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nconst NONE = 'none'\nconst DISPLAY = 'display'\n\nattribute({\n name: 'show',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n returnsValue: true,\n apply({ el, rx }) {\n const update = () => {\n observer.disconnect()\n const shouldShow = rx()\n if (shouldShow) {\n if (el.style.display === NONE) el.style.removeProperty(DISPLAY)\n } else {\n el.style.setProperty(DISPLAY, NONE)\n }\n observer.observe(el, { attributeFilter: ['style'] })\n }\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "// Icon: streamline:wifi-signal-full-remix\n// Slug: Patches signals into the existing signals.\n// Description: Patches (adds, updates or removes) one or more signals into the existing signals.\n\nimport { attribute } from '@engine'\nimport { mergePatch, mergePaths } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'signals',\n returnsValue: true,\n apply({ key, mods, rx }) {\n const ifMissing = mods.has('ifmissing')\n\n if (key) {\n key = modifyCasing(key, mods)\n mergePaths([[key, rx?.()]], { ifMissing })\n } else {\n const patch = Object.assign({}, rx?.() as Record)\n mergePatch(patch, { ifMissing })\n }\n },\n})\n", "// Icon: material-symbols:format-paint-outline\n// Slug: Sets inline styles on an element based on an expression.\n// Description: Sets CSS styles on an element using either key-based or object syntax, and keeps them in sync with reactive signals.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\nimport { kebab } from '@utils/text'\n\nattribute({\n name: 'style',\n requirement: {\n value: 'must',\n },\n returnsValue: true,\n apply({ key, el, rx }) {\n const { style } = el\n const initialStyles = new Map()\n\n const apply = (prop: string, value: any) => {\n const initial = initialStyles.get(prop)\n if (!value && value !== 0) {\n initial !== undefined &&\n (initial\n ? style.setProperty(prop, initial)\n : style.removeProperty(prop))\n } else {\n initial === undefined &&\n initialStyles.set(prop, style.getPropertyValue(prop))\n style.setProperty(prop, String(value))\n }\n }\n\n const update = () => {\n observer.disconnect()\n\n if (key) {\n apply(key, rx())\n } else {\n const styles = rx() as Record\n\n for (const [prop, initial] of initialStyles) {\n prop in styles ||\n (initial\n ? style.setProperty(prop, initial)\n : style.removeProperty(prop))\n }\n\n for (const prop in styles) {\n apply(kebab(prop), styles[prop])\n }\n }\n\n observer.observe(el, { attributeFilter: ['style'] })\n }\n\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n for (const [prop, initial] of initialStyles) {\n initial ? style.setProperty(prop, initial) : style.removeProperty(prop)\n }\n }\n },\n})\n", "// Icon: icon-park-outline:text\n// Slug: Binds the text content of an element.\n// Description: Binds the text content of an element to an expression.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nattribute({\n name: 'text',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n returnsValue: true,\n apply({ el, rx }) {\n const update = () => {\n observer.disconnect()\n el.textContent = `${rx()}`\n observer.observe(el, {\n childList: true,\n characterData: true,\n subtree: true,\n })\n }\n\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "// Icon: material-symbols:cloud-download\n// Slug: Patches elements into the DOM.\n// Description: Patches elements into the DOM.\n\nimport { watcher } from '@engine'\nimport type { WatcherContext } from '@engine/types'\nimport { morph } from '@engine/morph'\nimport { supportsViewTransitions } from '@utils/view-transitions'\n\ntype PatchElementsMode =\n | 'remove'\n | 'outer'\n | 'inner'\n | 'replace'\n | 'prepend'\n | 'append'\n | 'before'\n | 'after'\n\ntype PatchElementsArgs = {\n elements: string\n mode: PatchElementsMode\n selector: string\n useViewTransition: boolean\n}\n\nwatcher({\n name: 'datastar-patch-elements',\n apply(\n ctx,\n { elements = '', selector = '', mode = 'outer', useViewTransition },\n ) {\n switch (mode) {\n case 'remove':\n case 'outer':\n case 'inner':\n case 'replace':\n case 'prepend':\n case 'append':\n case 'before':\n case 'after':\n break\n default:\n throw ctx.error('PatchElementsInvalidMode', { mode })\n }\n\n if (!selector && mode !== 'outer' && mode !== 'replace') {\n throw ctx.error('PatchElementsExpectedSelector')\n }\n\n const args2: PatchElementsArgs = {\n mode,\n selector,\n elements,\n useViewTransition: useViewTransition?.trim() === 'true',\n }\n\n if (supportsViewTransitions && useViewTransition) {\n document.startViewTransition(() => onPatchElements(ctx, args2))\n } else {\n onPatchElements(ctx, args2)\n }\n },\n})\n\nconst onPatchElements = (\n { error }: WatcherContext,\n { elements, selector, mode }: PatchElementsArgs,\n) => {\n const elementsWithSvgsRemoved = elements.replace(\n /]*>|>)([\\s\\S]*?)<\\/svg>/gim,\n '',\n )\n const hasHtml = /<\\/html>/.test(elementsWithSvgsRemoved)\n const hasHead = /<\\/head>/.test(elementsWithSvgsRemoved)\n const hasBody = /<\\/body>/.test(elementsWithSvgsRemoved)\n\n const newDocument = new DOMParser().parseFromString(\n hasHtml || hasHead || hasBody\n ? elements\n : ``,\n 'text/html',\n )\n\n let newContent = document.createDocumentFragment()\n if (hasHtml) {\n newContent.appendChild(newDocument.documentElement)\n } else if (hasHead && hasBody) {\n newContent.appendChild(newDocument.head)\n newContent.appendChild(newDocument.body)\n } else if (hasHead) {\n newContent.appendChild(newDocument.head)\n } else if (hasBody) {\n newContent.appendChild(newDocument.body)\n } else {\n newContent = newDocument.querySelector('template')!.content\n }\n\n if (!selector && (mode === 'outer' || mode === 'replace')) {\n for (const child of newContent.children) {\n let target: Element\n if (child instanceof HTMLHtmlElement) {\n target = document.documentElement\n } else if (child instanceof HTMLBodyElement) {\n target = document.body\n } else if (child instanceof HTMLHeadElement) {\n target = document.head\n } else {\n target = document.getElementById(child.id)!\n if (!target) {\n console.warn(error('PatchElementsNoTargetsFound'), {\n element: { id: child.id },\n })\n continue\n }\n }\n\n applyToTargets(mode as PatchElementsMode, child, [target])\n }\n } else {\n const targets = document.querySelectorAll(selector)\n if (!targets.length) {\n console.warn(error('PatchElementsNoTargetsFound'), { selector })\n return\n }\n\n applyToTargets(mode as PatchElementsMode, newContent, targets)\n }\n}\n\nconst scripts = new WeakSet()\nfor (const script of document.querySelectorAll('script')) {\n scripts.add(script)\n}\n\nconst execute = (target: Element): void => {\n const elScripts =\n target instanceof HTMLScriptElement\n ? [target]\n : target.querySelectorAll('script')\n for (const old of elScripts) {\n if (!scripts.has(old)) {\n const script = document.createElement('script')\n for (const { name, value } of old.attributes) {\n script.setAttribute(name, value)\n }\n script.text = old.text\n old.replaceWith(script)\n scripts.add(script)\n }\n }\n}\n\nconst applyPatchMode = (\n targets: Iterable,\n element: DocumentFragment | Element,\n action: string,\n) => {\n for (const target of targets) {\n const cloned = element.cloneNode(true) as Element\n execute(cloned)\n // @ts-expect-error\n target[action](cloned)\n }\n}\n\nconst applyToTargets = (\n mode: PatchElementsMode,\n element: DocumentFragment | Element,\n targets: Iterable,\n) => {\n switch (mode) {\n case 'remove':\n for (const target of targets) {\n target.remove()\n }\n break\n case 'outer':\n case 'inner':\n for (const target of targets) {\n morph(target, element.cloneNode(true) as Element, mode)\n execute(target)\n }\n break\n case 'replace':\n applyPatchMode(targets, element, 'replaceWith')\n break\n case 'prepend':\n case 'append':\n case 'before':\n case 'after':\n applyPatchMode(targets, element, mode)\n }\n}\n", "// Icon: material-symbols:settings-input-antenna\n// Slug: Patches signals.\n// Description: Patches signals.\n\nimport { watcher } from '@engine'\nimport { mergePatch } from '@engine/signals'\nimport { jsStrToObject } from '@utils/text'\n\nwatcher({\n name: 'datastar-patch-signals',\n apply({ error }, { signals, onlyIfMissing }) {\n if (signals) {\n const ifMissing = onlyIfMissing?.trim() === 'true'\n mergePatch(jsStrToObject(signals), { ifMissing })\n } else {\n throw error('PatchSignalsExpectedSignals')\n }\n },\n})\n"], + "mappings": "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", + "names": ["lol", "DSP", "DSS", "DATASTAR_FETCH_EVENT", "DATASTAR_SIGNAL_PATCH_EVENT", "kebab", "str", "snake", "str", "kebab", "jsStrToObject", "raw", "caseFns", "str", "x", "modifyCasing", "mods", "defaultCase", "c", "aliasify", "name", "hasOwn", "isPojo", "obj", "isEmpty", "prop", "hasOwn", "updateLeaves", "fn", "key", "val", "pathToObj", "paths", "result", "path", "value", "keys", "lastKey", "acc", "currentPatch", "queuedEffects", "batchDepth", "notifyIndex", "queuedEffectsLength", "prevSub", "activeSub", "version", "beginBatch", "endBatch", "flush", "dispatch", "startPeeking", "sub", "stopPeeking", "signal", "initialValue", "signalOper", "value_", "flags_", "computedSymbol", "computed", "getter", "c", "computedOper", "effect", "fn", "e", "fn_", "link", "effectOper", "run", "update", "updateComputed", "updateSignal", "startTracking", "oldValue", "endTracking", "s", "value", "notify", "flags", "subs", "subs_", "sub_", "checkDirty", "deps_", "dep", "dep_", "depFlags", "nextDep_", "propagate", "currentValue", "shallowPropagate", "unlink", "prevDep", "depsTail_", "nextDep", "version_", "subsTail_", "newLink", "prevDep_", "prevSub_", "nextSub_", "toRemove", "next", "stack", "top", "isValidLink", "subSubs", "nextSub", "prev_", "checkDepth", "dirty", "firstSub", "hasMultipleSubs", "checkLink", "getPath", "path", "result", "root", "split", "hasOwn", "deep", "prefix", "isArr", "isPojo", "deepObj", "key", "keys", "_", "prop", "newValue", "diff", "patch", "i", "detail", "pathToObj", "DATASTAR_SIGNAL_PATCH_EVENT", "mergePatch", "ifMissing", "mergeInner", "mergePaths", "paths", "options", "target", "targetParent", "toRegExp", "val", "filtered", "include", "exclude", "obj", "includeRe", "excludeRe", "node", "isHTMLOrSVG", "el", "url", "error", "ctx", "reason", "metadata", "e", "r", "snake", "q", "c", "actionPlugins", "attributePlugins", "watcherPlugins", "actions", "_", "prop", "removals", "queuedAttributes", "queuedAttributeNames", "attribute", "plugin", "apply", "action", "DATASTAR_FETCH_EVENT", "evt", "watcher", "cleanupEls", "els", "el", "cleanups", "cleanup", "aliasedIgnore", "aliasify", "aliasedIgnoreAttr", "shouldIgnore", "applyEls", "onlyNew", "key", "applyAttributePlugin", "observe", "mutations", "target", "type", "attributeName", "addedNodes", "removedNodes", "node", "isHTMLOrSVG", "value", "mutationObserver", "root", "attrKey", "rawKey", "namePart", "rawModifiers", "pluginName", "keyReq", "valueReq", "cachedRx", "args", "genRx", "rawMod", "label", "mod", "returnsValue", "argNames", "expr", "statementRe", "statements", "lastIdx", "last", "escaped", "escapeRe", "DSP", "DSS", "counter", "match", "k", "v", "signalName", "acc", "part", "varName", "fn", "name", "err", "ctxIdMap", "ctxPersistentIds", "oldIdTagNameMap", "duplicateIds", "ctxPantry", "aliasedIgnoreMorph", "aliasify", "aliasedIgnoreMorphAttr", "morph", "oldElt", "newContent", "mode", "isHTMLOrSVG", "normalizedElt", "oldIdElements", "id", "tagName", "newIdElements", "parent", "populateIdMapWithTree", "morphChildren", "oldParent", "newParent", "insertionPoint", "endPoint", "newChild", "bestMatch", "findBestMatch", "cursor", "tempNode", "removeNode", "morphNode", "movedChild", "current", "idSet", "moveBefore", "newEmptyChild", "newClonedChild", "node", "startPoint", "nextSibling", "siblingSoftMatchCount", "displaceMatchCount", "nodeMatchCount", "isSoftMatch", "isIdSetMatch", "oldSet", "newSet", "oldNode", "newNode", "aliasedPreserveAttr", "type", "newElt", "preserveAttrs", "name", "value", "i", "root", "elements", "elt", "action", "_", "fn", "startPeeking", "stopPeeking", "action", "_", "value", "filter", "startPeeking", "masked", "filtered", "updateLeaves", "mergePatch", "stopPeeking", "action", "_", "filter", "startPeeking", "masked", "filtered", "updateLeaves", "oldValue", "mergePatch", "stopPeeking", "fetchAbortControllers", "createHttpMethod", "name", "method", "action", "el", "evt", "error", "url", "selector", "userHeaders", "contentType", "include", "exclude", "openWhenHidden", "retryInterval", "retryScaler", "retryMaxWaitMs", "retryMaxCount", "requestCancellation", "controller", "isDisabled", "oldController", "observer", "mutations", "mutation", "removed", "cleanupFn", "initialHeaders", "headers", "req", "response", "dispatchFetch", "ERROR", "type", "argsRawLines", "line", "i", "v", "argsRaw", "k", "isWrongContent", "RETRYING", "urlInstance", "queryParams", "res", "filtered", "formEl", "formData", "submitter", "preventDefault", "multipart", "formParams", "key", "value", "STARTED", "fetchEventSource", "e", "FINISHED", "RETRIES_FAILED", "DATASTAR_FETCH_EVENT", "err", "getBytes", "stream", "onChunk", "reader", "result", "getLines", "onLine", "buffer", "position", "fieldLength", "discardTrailingNewline", "arr", "concat", "bufLength", "lineStart", "lineEnd", "getMessages", "onId", "onRetry", "onMessage", "message", "newMessage", "decoder", "field", "valueOffset", "retry", "a", "b", "input", "inputSignal", "inputHeaders", "inputOnOpen", "onmessage", "onclose", "onerror", "inputFetch", "overrides", "rest", "resolve", "reject", "curRequestController", "onVisibilityChange", "create", "retryTimer", "dispose", "fetch", "onopen", "retries", "baseRetryInterval", "dispatchNonSSE", "dispatchType", "argNames", "n", "kebab", "o", "ct", "script", "scriptAttributesHeader", "id", "interval", "innerErr", "attribute", "el", "key", "rx", "syncAttr", "val", "update", "observer", "obj", "attributeFilter", "cleanup", "effect", "dataURIRegex", "empty", "aliasedBind", "aliasify", "attribute", "el", "key", "mods", "value", "error", "signalName", "modifyCasing", "get", "type", "set", "syncSignal", "files", "signalFiles", "f", "resolve", "reader", "match", "mergePaths", "typeMap", "option", "initialValue", "getPath", "path", "signalNameKebab", "inputs", "paths", "i", "input", "signalValue", "cleanup", "effect", "attribute", "key", "el", "mods", "rx", "modifyCasing", "callback", "observer", "classes", "k", "classNames", "cn", "name", "cleanup", "effect", "attribute", "key", "mods", "rx", "error", "mergePaths", "modifyCasing", "computed", "patch", "updateLeaves", "old", "mergePatch", "attribute", "rx", "effect", "attribute", "el", "key", "mods", "value", "signalName", "modifyCasing", "mergePaths", "watcher", "event", "type", "elt", "STARTED", "FINISHED", "DATASTAR_FETCH_EVENT", "attribute", "el", "value", "mods", "spaces", "filters", "jsStrToObject", "callback", "observer", "filtered", "cleanup", "effect", "tagToMs", "args", "arg", "tagHas", "tags", "tag", "defaultValue", "delay", "callback", "wait", "args", "debounce", "leading", "trailing", "timer", "throttle", "waiting", "modifyTiming", "mods", "delayArgs", "tagToMs", "debounceArgs", "tagHas", "throttleArgs", "supportsViewTransitions", "modifyViewTransition", "callback", "mods", "cb", "args", "attribute", "el", "key", "mods", "rx", "target", "callback", "evt", "beginBatch", "endBatch", "modifyViewTransition", "modifyTiming", "evtListOpts", "cb", "eventName", "modifyCasing", "DATASTAR_FETCH_EVENT", "DATASTAR_SIGNAL_PATCH_EVENT", "once", "attribute", "el", "mods", "rx", "callback", "beginBatch", "endBatch", "modifyViewTransition", "modifyTiming", "options", "observer", "entries", "entry", "attribute", "mods", "rx", "callback", "beginBatch", "endBatch", "modifyViewTransition", "duration", "durationArgs", "tagToMs", "tagHas", "intervalId", "attribute", "rx", "mods", "callback", "beginBatch", "endBatch", "modifyViewTransition", "wait", "delayArgs", "tagToMs", "delay", "attribute", "el", "key", "mods", "rx", "error", "filtersRaw", "filters", "jsStrToObject", "callback", "modifyTiming", "evt", "watched", "filtered", "isEmpty", "beginBatch", "endBatch", "DATASTAR_SIGNAL_PATCH_EVENT", "attribute", "el", "key", "mods", "value", "signalName", "modifyCasing", "mergePaths", "NONE", "DISPLAY", "attribute", "el", "rx", "update", "observer", "cleanup", "effect", "attribute", "key", "mods", "rx", "ifMissing", "modifyCasing", "mergePaths", "patch", "mergePatch", "attribute", "key", "el", "rx", "style", "initialStyles", "apply", "prop", "value", "initial", "update", "observer", "styles", "kebab", "cleanup", "effect", "attribute", "el", "rx", "update", "observer", "cleanup", "effect", "watcher", "ctx", "elements", "selector", "mode", "useViewTransition", "args2", "supportsViewTransitions", "onPatchElements", "error", "elementsWithSvgsRemoved", "hasHtml", "hasHead", "hasBody", "newDocument", "newContent", "child", "target", "applyToTargets", "targets", "scripts", "script", "execute", "elScripts", "old", "name", "value", "applyPatchMode", "element", "action", "cloned", "morph", "watcher", "error", "signals", "onlyIfMissing", "ifMissing", "mergePatch", "jsStrToObject"] +} diff --git a/hypermedia/1-example/deleted-record1.html b/demo/datasstar-static/html-snippets/deleted-record1.html similarity index 100% rename from hypermedia/1-example/deleted-record1.html rename to demo/datasstar-static/html-snippets/deleted-record1.html diff --git a/hypermedia/1-example/deleted-record2.html b/demo/datasstar-static/html-snippets/deleted-record2.html similarity index 100% rename from hypermedia/1-example/deleted-record2.html rename to demo/datasstar-static/html-snippets/deleted-record2.html diff --git a/hypermedia/1-example/deleted-record3.html b/demo/datasstar-static/html-snippets/deleted-record3.html similarity index 100% rename from hypermedia/1-example/deleted-record3.html rename to demo/datasstar-static/html-snippets/deleted-record3.html diff --git a/hypermedia/1-example/display-record1.html b/demo/datasstar-static/html-snippets/display-record1.html similarity index 100% rename from hypermedia/1-example/display-record1.html rename to demo/datasstar-static/html-snippets/display-record1.html diff --git a/hypermedia/1-example/display-record2.html b/demo/datasstar-static/html-snippets/display-record2.html similarity index 100% rename from hypermedia/1-example/display-record2.html rename to demo/datasstar-static/html-snippets/display-record2.html diff --git a/hypermedia/1-example/display-record3.html b/demo/datasstar-static/html-snippets/display-record3.html similarity index 100% rename from hypermedia/1-example/display-record3.html rename to demo/datasstar-static/html-snippets/display-record3.html diff --git a/hypermedia/1-example/edit-record1.html b/demo/datasstar-static/html-snippets/edit-record1.html similarity index 100% rename from hypermedia/1-example/edit-record1.html rename to demo/datasstar-static/html-snippets/edit-record1.html diff --git a/hypermedia/1-example/edit-record2.html b/demo/datasstar-static/html-snippets/edit-record2.html similarity index 100% rename from hypermedia/1-example/edit-record2.html rename to demo/datasstar-static/html-snippets/edit-record2.html diff --git a/hypermedia/1-example/edit-record3.html b/demo/datasstar-static/html-snippets/edit-record3.html similarity index 100% rename from hypermedia/1-example/edit-record3.html rename to demo/datasstar-static/html-snippets/edit-record3.html diff --git a/demo/datasstar-static/html-snippets/index.html b/demo/datasstar-static/html-snippets/index.html new file mode 100644 index 0000000..43e961b --- /dev/null +++ b/demo/datasstar-static/html-snippets/index.html @@ -0,0 +1,25 @@ + + + + + + + Hypermedia + + + + + + + +

Hypermedia as the Engine of Application State

+ +
+
+
+
+
+ + + + diff --git a/hypermedia/pico.blue.css b/demo/datasstar-static/html-snippets/pico.blue.css similarity index 99% rename from hypermedia/pico.blue.css rename to demo/datasstar-static/html-snippets/pico.blue.css index acb44ef..e76f23b 100644 --- a/hypermedia/pico.blue.css +++ b/demo/datasstar-static/html-snippets/pico.blue.css @@ -6,6 +6,12 @@ /** * Styles */ + +@view-transition { + navigation: auto; +} + + :root { --pico-font-family-emoji: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; --pico-font-family-sans-serif: system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, Helvetica, Arial, "Helvetica Neue", sans-serif, var(--pico-font-family-emoji); diff --git a/hypermedia/2-example/.show-it b/demo/datasstar-static/signals/.show-it similarity index 70% rename from hypermedia/2-example/.show-it rename to demo/datasstar-static/signals/.show-it index 0ee9f36..884f638 100644 --- a/hypermedia/2-example/.show-it +++ b/demo/datasstar-static/signals/.show-it @@ -4,4 +4,4 @@ echo "patch signals with json data" ls -l ---PAUSE--- echo "live-server is running - press ctrl-c" -live-server | micro index.html record1.json record3.json record3.json +live-server | micro index.html record1.json record2.json record3.json diff --git a/demo/datasstar-static/signals/datastar.js b/demo/datasstar-static/signals/datastar.js new file mode 100644 index 0000000..be57e9d --- /dev/null +++ b/demo/datasstar-static/signals/datastar.js @@ -0,0 +1,9 @@ +// Datastar v1.0.0-RC.6 +var nt=/🖕JS_DS🚀/.source,De=nt.slice(0,5),Ve=nt.slice(4),q="datastar-fetch",z="datastar-signal-patch";var de=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/([a-z])([0-9]+)/gi,"$1-$2").replace(/([0-9]+)([a-z])/gi,"$1-$2").toLowerCase();var rt=e=>de(e).replace(/-/g,"_");var re=e=>{try{return JSON.parse(e)}catch{return Function(`return (${e})`)()}},st={camel:e=>e.replace(/-[a-z]/g,t=>t[1].toUpperCase()),snake:e=>e.replace(/-/g,"_"),pascal:e=>e[0].toUpperCase()+st.camel(e.slice(1))},R=(e,t,n="camel")=>{for(let r of t.get("case")||[n])e=st[r]?.(e)||e;return e},Q=e=>`data-${e}`;var _=Object.hasOwn??Object.prototype.hasOwnProperty.call;var se=e=>e!==null&&typeof e=="object"&&(Object.getPrototypeOf(e)===Object.prototype||Object.getPrototypeOf(e)===null),it=e=>{for(let t in e)if(_(e,t))return!1;return!0},Z=(e,t)=>{for(let n in e){let r=e[n];se(r)||Array.isArray(r)?Z(r,t):e[n]=t(r)}},Te=e=>{let t={};for(let[n,r]of e){let s=n.split("."),i=s.pop(),a=s.reduce((o,c)=>o[c]??={},t);a[i]=r}return t};var Ae=[],Ie=[],Fe=0,Re=0,$e=0,qe,G,we=0,w=()=>{Fe++},M=()=>{--Fe||(ct(),Y())},V=e=>{qe=G,G=e},I=()=>{G=qe,qe=void 0},me=e=>It.bind(0,{previousValue:e,t:e,e:1}),Ge=Symbol("computed"),Ne=e=>{let t=$t.bind(0,{e:17,getter:e});return t[Ge]=1,t},E=e=>{let t={d:e,e:2};G&&Be(t,G),V(t),w();try{t.d()}finally{M(),I()}return dt.bind(0,t)},ct=()=>{for(;Re<$e;){let e=Ie[Re];Ie[Re++]=void 0,ut(e,e.e&=-65)}Re=0,$e=0},ot=e=>"getter"in e?lt(e):ft(e,e.t),lt=e=>{V(e),mt(e);try{let t=e.t;return t!==(e.t=e.getter(t))}finally{I(),pt(e)}},ft=(e,t)=>(e.e=1,e.previousValue!==(e.previousValue=t)),je=e=>{let t=e.e;if(!(t&64)){e.e=t|64;let n=e.r;n?je(n.o):Ie[$e++]=e}},ut=(e,t)=>{if(t&16||t&32&>(e.s,e)){V(e),mt(e),w();try{e.d()}finally{M(),I(),pt(e)}return}t&32&&(e.e=t&-33);let n=e.s;for(;n;){let r=n.c,s=r.e;s&64&&ut(r,r.e=s&-65),n=n.i}},It=(e,...t)=>{if(t.length){if(e.t!==(e.t=t[0])){e.e=17;let r=e.r;return r&&(qt(r),Fe||ct()),!0}return!1}let n=e.t;if(e.e&16&&ft(e,n)){let r=e.r;r&&Le(r)}return G&&Be(e,G),n},$t=e=>{let t=e.e;if(t&16||t&32&>(e.s,e)){if(lt(e)){let n=e.r;n&&Le(n)}}else t&32&&(e.e=t&-33);return G&&Be(e,G),e.t},dt=e=>{let t=e.s;for(;t;)t=xe(t,e);let n=e.r;n&&xe(n),e.e=0},Be=(e,t)=>{let n=t.a;if(n&&n.c===e)return;let r=n?n.i:t.s;if(r&&r.c===e){r.m=we,t.a=r;return}let s=e.p;if(s&&s.m===we&&s.o===t)return;let i=t.a=e.p={m:we,c:e,o:t,l:n,i:r,f:s};r&&(r.l=i),n?n.i=i:t.s=i,s?s.n=i:e.r=i},xe=(e,t=e.o)=>{let n=e.c,r=e.l,s=e.i,i=e.n,a=e.f;if(s?s.l=r:t.a=r,r?r.i=s:t.s=s,i?i.f=a:n.p=a,a)a.n=i;else if(!(n.r=i))if("getter"in n){let o=n.s;if(o){n.e=17;do o=xe(o,n);while(o)}}else"previousValue"in n||dt(n);return s},qt=e=>{let t=e.n,n;e:for(;;){let r=e.o,s=r.e;if(s&60?s&12?s&4?!(s&48)&&Gt(e,r)?(r.e=s|40,s&=1):s=0:r.e=s&-9|32:s=0:r.e=s|32,s&2&&je(r),s&1){let i=r.r;if(i){let a=(e=i).n;a&&(n={t,u:n},t=a);continue}}if(e=t){t=e.n;continue}for(;n;)if(e=n.t,n=n.u,e){t=e.n;continue e}break}},mt=e=>{we++,e.a=void 0,e.e=e.e&-57|4},pt=e=>{let t=e.a,n=t?t.i:e.s;for(;n;)n=xe(n,e);e.e&=-5},gt=(e,t)=>{let n,r=0,s=!1;e:for(;;){let i=e.c,a=i.e;if(t.e&16)s=!0;else if((a&17)===17){if(ot(i)){let o=i.r;o.n&&Le(o),s=!0}}else if((a&33)===33){(e.n||e.f)&&(n={t:e,u:n}),e=i.s,t=i,++r;continue}if(!s){let o=e.i;if(o){e=o;continue}}for(;r--;){let o=t.r,c=o.n;if(c?(e=n.t,n=n.u):e=o,s){if(ot(t)){c&&Le(o),t=e.o;continue}s=!1}else t.e&=-33;if(t=e.o,e.i){e=e.i;continue e}}return s}},Le=e=>{do{let t=e.o,n=t.e;(n&48)===32&&(t.e=n|16,n&2&&je(t))}while(e=e.n)},Gt=(e,t)=>{let n=t.a;for(;n;){if(n===e)return!0;n=n.l}return!1},ie=e=>{let t=X,n=e.split(".");for(let r of n){if(t==null||!_(t,r))return;t=t[r]}return t},Me=(e,t="")=>{let n=Array.isArray(e);if(n||se(e)){let r=n?[]:{};for(let i in e)r[i]=me(Me(e[i],`${t+i}.`));let s=me(0);return new Proxy(r,{get(i,a){if(!(a==="toJSON"&&!_(r,a)))return n&&a in Array.prototype?(s(),r[a]):typeof a=="symbol"?r[a]:((!_(r,a)||r[a]()==null)&&(r[a]=me(""),Y(t+a,""),s(s()+1)),r[a]())},set(i,a,o){let c=t+a;if(n&&a==="length"){let l=r[a]-o;if(r[a]=o,l>0){let f={};for(let d=o;d{if(e!==void 0&&t!==void 0&&Ae.push([e,t]),!Fe&&Ae.length){let n=Te(Ae);Ae.length=0,document.dispatchEvent(new CustomEvent(z,{detail:n}))}},C=(e,{ifMissing:t}={})=>{w();for(let n in e)e[n]==null?t||delete X[n]:ht(e[n],n,X,"",t);M()},S=(e,t)=>C(Te(e),t),ht=(e,t,n,r,s)=>{if(se(e)){_(n,t)&&(se(n[t])||Array.isArray(n[t]))||(n[t]={});for(let i in e)e[i]==null?s||delete n[t][i]:ht(e[i],i,n[t],`${r+t}.`,s)}else s&&_(n,t)||(n[t]=e)},at=e=>typeof e=="string"?RegExp(e.replace(/^\/|\/$/g,"")):e,D=({include:e=/.*/,exclude:t=/(?!)/}={},n=X)=>{let r=at(e),s=at(t),i=[],a=[[n,""]];for(;a.length;){let[o,c]=a.pop();for(let l in o){let f=c+l;se(o[l])?a.push([o[l],`${f}.`]):r.test(f)&&!s.test(f)&&i.push([f,ie(f)])}}return Te(i)},X=Me({});var W=e=>e instanceof HTMLElement||e instanceof SVGElement||e instanceof MathMLElement;var jt="https://data-star.dev/errors",pe=(e,t,n={})=>{Object.assign(n,e);let r=new Error,s=rt(t),i=new URLSearchParams({metadata:JSON.stringify(n)}).toString(),a=JSON.stringify(n,null,2);return r.message=`${t} +More info: ${jt}/${s}?${i} +Context: ${a}`,r},Oe=new Map,vt=new Map,bt=new Map,Et=new Proxy({},{get:(e,t)=>Oe.get(t)?.apply,has:(e,t)=>Oe.has(t),ownKeys:()=>Reflect.ownKeys(Oe),set:()=>!1,deleteProperty:()=>!1}),ge=new Map,Ce=[],We=new Set,p=e=>{Ce.push(e),Ce.length===1&&setTimeout(()=>{for(let t of Ce)We.add(t.name),vt.set(t.name,t);Ce.length=0,Jt(),We.clear()})},O=e=>{Oe.set(e.name,e)};document.addEventListener(q,e=>{let t=bt.get(e.detail.type);t&&t.apply({error:pe.bind(0,{plugin:{type:"watcher",name:t.name},element:{id:e.target.id,tag:e.target.tagName}})},e.detail.argsRaw)});var he=e=>{bt.set(e.name,e)},yt=e=>{for(let t of e){let n=ge.get(t);if(ge.delete(t)){for(let r of n.values())r();n.clear()}}},St=Q("ignore"),Bt=`[${St}]`,Tt=e=>e.hasAttribute(`${St}__self`)||!!e.closest(Bt),Pe=(e,t)=>{for(let n of e)if(!Tt(n))for(let r in n.dataset)At(n,r.replace(/[A-Z]/g,"-$&").toLowerCase(),n.dataset[r],t)},Wt=e=>{for(let{target:t,type:n,attributeName:r,addedNodes:s,removedNodes:i}of e)if(n==="childList"){for(let a of i)W(a)&&(yt([a]),yt(a.querySelectorAll("*")));for(let a of s)W(a)&&(Pe([a]),Pe(a.querySelectorAll("*")))}else if(n==="attributes"&&r.startsWith("data-")&&W(t)&&!Tt(t)){let a=r.slice(5),o=t.getAttribute(r);if(o===null){let c=ge.get(t);c&&(c.get(a)?.(),c.delete(a))}else At(t,a,o)}},Ut=new MutationObserver(Wt),Jt=(e=document.documentElement)=>{W(e)&&Pe([e],!0),Pe(e.querySelectorAll("*"),!0),Ut.observe(e,{subtree:!0,childList:!0,attributes:!0})},At=(e,t,n,r)=>{{let s=t,[i,...a]=s.split("__"),[o,c]=i.split(/:(.+)/),l=vt.get(o);if((!r||We.has(o))&&l){let f={el:e,rawKey:s,mods:new Map,error:pe.bind(0,{plugin:{type:"attribute",name:l.name},element:{id:e.id,tag:e.tagName},expression:{rawKey:s,key:c,value:n}}),key:c,value:n,rx:void 0},d=l.requirement&&(typeof l.requirement=="string"?l.requirement:l.requirement.key)||"allowed",x=l.requirement&&(typeof l.requirement=="string"?l.requirement:l.requirement.value)||"allowed";if(c){if(d==="denied")throw f.error("KeyNotAllowed")}else if(d==="must")throw f.error("KeyRequired");if(n){if(x==="denied")throw f.error("ValueNotAllowed")}else if(x==="must")throw f.error("ValueRequired");if(d==="exclusive"||x==="exclusive"){if(c&&n)throw f.error("KeyAndValueProvided");if(!c&&!n)throw f.error("KeyOrValueRequired")}if(n){let m;f.rx=(...h)=>(m||(m=Kt(n,{returnsValue:l.returnsValue,argNames:l.argNames})),m(e,...h))}for(let m of a){let[h,...v]=m.split(".");f.mods.set(h,new Set(v))}let u=l.apply(f);if(u){let m=ge.get(e);m?m.get(s)?.():(m=new Map,ge.set(e,m)),m.set(s,u)}}}},Kt=(e,{returnsValue:t=!1,argNames:n=[]}={})=>{let r="";if(t){let o=/(\/(\\\/|[^/])*\/|"(\\"|[^"])*"|'(\\'|[^'])*'|`(\\`|[^`])*`|\(\s*((function)\s*\(\s*\)|(\(\s*\))\s*=>)\s*(?:\{[\s\S]*?\}|[^;){]*)\s*\)\s*\(\s*\)|[^;])+/gm,c=e.trim().match(o);if(c){let l=c.length-1,f=c[l].trim();f.startsWith("return")||(c[l]=`return (${f});`),r=c.join(`; +`)}}else r=e.trim();let s=new Map,i=RegExp(`(?:${De})(.*?)(?:${Ve})`,"gm"),a=0;for(let o of r.matchAll(i)){let c=o[1],l=`__escaped${a++}`;s.set(l,c),r=r.replace(De+c+Ve,l)}r=r.replace(/\$\['([a-zA-Z_$\d][\w$]*)'\]/g,"$$$1").replace(/\$([a-zA-Z_\d]\w*(?:[.-]\w+)*)/g,(o,c)=>c.split(".").reduce((l,f)=>`${l}['${f}']`,"$")).replace(/\[(\$[a-zA-Z_\d]\w*)\]/g,(o,c)=>`[$['${c.slice(1)}']]`),r=r.replaceAll(/@(\w+)\(/g,'__action("$1",evt,');for(let[o,c]of s)r=r.replace(o,c);try{let o=Function("el","$","__action","evt",...n,r);return(c,...l)=>{let f=(d,x,...u)=>{let m=pe.bind(0,{plugin:{type:"action",name:d},element:{id:c.id,tag:c.tagName},expression:{fnContent:r,value:e}}),h=Et[d];if(h)return h({el:c,evt:x,error:m},...u);throw m("UndefinedAction")};try{return o(c,X,f,void 0,...l)}catch(d){throw console.error(d),pe({element:{id:c.id,tag:c.tagName},expression:{fnContent:r,value:e},error:d.message},"ExecuteExpression")}}}catch(o){throw console.error(o),pe({expression:{fnContent:r,value:e},error:o.message},"GenerateExpression")}};var P=new Map,ae=new Set,oe=new Map,ye=new Set,ce=document.createElement("div");ce.hidden=!0;var ve=Q("ignore-morph"),zt=`[${ve}]`,Ke=(e,t,n="outer")=>{if(W(e)&&W(t)&&e.hasAttribute(ve)&&t.hasAttribute(ve)||e.parentElement?.closest(zt))return;let r=document.createElement("div");r.append(t),document.body.insertAdjacentElement("afterend",ce);let s=e.querySelectorAll("[id]");for(let{id:o,tagName:c}of s)oe.has(o)?ye.add(o):oe.set(o,c);e instanceof Element&&e.id&&(oe.has(e.id)?ye.add(e.id):oe.set(e.id,e.tagName)),ae.clear();let i=r.querySelectorAll("[id]");for(let{id:o,tagName:c}of i)ae.has(o)?ye.add(o):oe.get(o)===c&&ae.add(o);for(let o of ye)ae.delete(o);oe.clear(),ye.clear(),P.clear();let a=n==="outer"?e.parentElement:e;wt(a,s),wt(r,i),Mt(a,r,n==="outer"?e:null,e.nextSibling),ce.remove()},Mt=(e,t,n=null,r=null)=>{e instanceof HTMLTemplateElement&&t instanceof HTMLTemplateElement&&(e=e.content,t=t.content),n??=e.firstChild;for(let s of t.childNodes){if(n&&n!==r){let i=Qt(s,n,r);if(i){if(i!==n){let a=n;for(;a&&a!==i;){let o=a;a=a.nextSibling,Je(o)}}Ue(i,s),n=i.nextSibling;continue}}if(s instanceof Element&&ae.has(s.id)){let i=document.getElementById(s.id),a=i;for(;a=a.parentNode;){let o=P.get(a);o&&(o.delete(s.id),o.size||P.delete(a))}xt(e,i,n),Ue(i,s),n=i.nextSibling;continue}if(P.has(s)){let i=document.createElement(s.tagName);e.insertBefore(i,n),Ue(i,s),n=i.nextSibling}else{let i=document.importNode(s,!0);e.insertBefore(i,n),n=i.nextSibling}}for(;n&&n!==r;){let s=n;n=n.nextSibling,Je(s)}},Qt=(e,t,n)=>{let r=null,s=e.nextSibling,i=0,a=0,o=P.get(e)?.size||0,c=t;for(;c&&c!==n;){if(Rt(c,e)){let l=!1,f=P.get(c),d=P.get(e);if(d&&f){for(let x of f)if(d.has(x)){l=!0;break}}if(l)return c;if(!r&&!P.has(c)){if(!o)return c;r=c}}if(a+=P.get(c)?.size||0,a>o)break;r===null&&s&&Rt(c,s)&&(i++,s=s.nextSibling,i>=2&&(r=void 0)),c=c.nextSibling}return r||null},Rt=(e,t)=>e.nodeType===t.nodeType&&e.tagName===t.tagName&&(!e.id||e.id===t.id),Je=e=>{P.has(e)?xt(ce,e,null):e.parentNode?.removeChild(e)},xt=Je.call.bind(ce.moveBefore??ce.insertBefore),Zt=Q("preserve-attr"),Ue=(e,t)=>{let n=t.nodeType;if(n===1){let r=e,s=t;if(r.hasAttribute(ve)&&s.hasAttribute(ve))return e;r instanceof HTMLInputElement&&s instanceof HTMLInputElement&&s.type!=="file"?s.getAttribute("value")!==r.getAttribute("value")&&(r.value=s.getAttribute("value")??""):r instanceof HTMLTextAreaElement&&s instanceof HTMLTextAreaElement&&(s.value!==r.value&&(r.value=s.value),r.firstChild&&r.firstChild.nodeValue!==s.value&&(r.firstChild.nodeValue=s.value));let i=(t.getAttribute(Zt)??"").split(" ");for(let{name:a,value:o}of s.attributes)r.getAttribute(a)!==o&&!i.includes(a)&&r.setAttribute(a,o);for(let a=r.attributes.length-1;a>=0;a--){let{name:o}=r.attributes[a];!s.hasAttribute(o)&&!i.includes(o)&&r.removeAttribute(o)}r.isEqualNode(s)||Mt(r,s)}return(n===8||n===3)&&e.nodeValue!==t.nodeValue&&(e.nodeValue=t.nodeValue),e},wt=(e,t)=>{for(let n of t)if(ae.has(n.id)){let r=n;for(;r&&r!==e;){let s=P.get(r);s||(s=new Set,P.set(r,s)),s.add(n.id),r=r.parentElement}}};O({name:"peek",apply(e,t){V();try{return t()}finally{I()}}});O({name:"setAll",apply(e,t,n){V();let r=D(n);Z(r,()=>t),C(r),I()}});O({name:"toggleAll",apply(e,t){V();let n=D(t);Z(n,r=>!r),C(n),I()}});var He=new WeakMap,be=(e,t)=>O({name:e,apply:async({el:n,evt:r,error:s},i,{selector:a,headers:o,contentType:c="json",filterSignals:{include:l=/.*/,exclude:f=/(^|\.)_/}={},openWhenHidden:d=!1,retryInterval:x=1e3,retryScaler:u=2,retryMaxWaitMs:m=3e4,retryMaxCount:h=10,requestCancellation:v="auto"}={})=>{let L=v instanceof AbortController?v:new AbortController,A=v==="disabled";if(!A){let T=He.get(n);T&&(T.abort(),await Promise.resolve())}!A&&!(v instanceof AbortController)&&He.set(n,L);try{let T=new MutationObserver(j=>{for(let H of j)for(let B of H.removedNodes)B===n&&(L.abort(),K())});n.parentNode&&T.observe(n.parentNode,{childList:!0});let K=()=>{T.disconnect()};try{if(!i?.length)throw s("FetchNoUrlProvided",{action:O});let j={Accept:"text/event-stream, text/html, application/json","Datastar-Request":!0};c==="json"&&(j["Content-Type"]="application/json");let H=Object.assign({},j,o),B={method:t,headers:H,openWhenHidden:d,retryInterval:x,retryScaler:u,retryMaxWaitMs:m,retryMaxCount:h,signal:L.signal,onopen:async g=>{g.status>=400&&ee(Yt,n,{status:g.status.toString()})},onmessage:g=>{if(!g.event.startsWith("datastar"))return;let $=g.event,b={};for(let N of g.data.split(` +`)){let y=N.indexOf(" "),k=N.slice(0,y),ue=N.slice(y+1);(b[k]||=[]).push(ue)}let F=Object.fromEntries(Object.entries(b).map(([N,y])=>[N,y.join(` +`)]));ee($,n,F)},onerror:g=>{if(Lt(g))throw g("FetchExpectedTextEventStream",{url:i});g&&(console.error(g.message),ee(Xt,n,{message:g.message}))}},fe=new URL(i,document.baseURI),ne=new URLSearchParams(fe.search);if(c==="json"){let g=JSON.stringify(D({include:l,exclude:f}));t==="GET"?ne.set("datastar",g):B.body=g}else if(c==="form"){let g=a?document.querySelector(a):n.closest("form");if(!g)throw s("FetchFormNotFound",{action:O,selector:a});if(!g.checkValidity()){g.reportValidity(),K();return}let $=new FormData(g),b=n;if(n===g&&r instanceof SubmitEvent)b=r.submitter;else{let y=k=>k.preventDefault();g.addEventListener("submit",y),K=()=>{g.removeEventListener("submit",y),T.disconnect()}}if(b instanceof HTMLButtonElement){let y=b.getAttribute("name");y&&$.append(y,b.value)}let F=g.getAttribute("enctype")==="multipart/form-data";F||(H["Content-Type"]="application/x-www-form-urlencoded");let N=new URLSearchParams($);if(t==="GET")for(let[y,k]of N)ne.append(y,k);else F?B.body=$:B.body=N}else throw s("FetchInvalidContentType",{action:O,contentType:c});ee(ze,n,{}),fe.search=ne.toString();try{await on(fe.toString(),n,B)}catch(g){if(!Lt(g))throw s("FetchFailed",{method:t,url:i,error:g.message})}}finally{ee(Qe,n,{}),K()}}finally{He.get(n)===L&&He.delete(n)}}});be("delete","DELETE");be("get","GET");be("patch","PATCH");be("post","POST");be("put","PUT");var ze="started",Qe="finished",Yt="error",Xt="retrying",en="retries-failed",ee=(e,t,n)=>document.dispatchEvent(new CustomEvent(q,{detail:{type:e,el:t,argsRaw:n}})),Lt=e=>`${e}`.includes("text/event-stream"),tn=async(e,t)=>{let n=e.getReader(),r=await n.read();for(;!r.done;)t(r.value),r=await n.read()},nn=e=>{let t,n,r,s=!1;return i=>{t?t=sn(t,i):(t=i,n=0,r=-1);let a=t.length,o=0;for(;n{let r=Ft(),s=new TextDecoder;return(i,a)=>{if(!i.length)n?.(r),r=Ft();else if(a>0){let o=s.decode(i.subarray(0,a)),c=a+(i[a+1]===32?2:1),l=s.decode(i.subarray(c));switch(o){case"data":r.data=r.data?`${r.data} +${l}`:l;break;case"event":r.event=l;break;case"id":e(r.id=l);break;case"retry":{let f=+l;Number.isNaN(f)||t(r.retry=f);break}}}}},sn=(e,t)=>{let n=new Uint8Array(e.length+t.length);return n.set(e),n.set(t,e.length),n},Ft=()=>({data:"",event:"",id:"",retry:void 0}),on=(e,t,{signal:n,headers:r,onopen:s,onmessage:i,onclose:a,onerror:o,openWhenHidden:c,fetch:l,retryInterval:f=1e3,retryScaler:d=2,retryMaxWaitMs:x=3e4,retryMaxCount:u=10,overrides:m,...h})=>new Promise((v,L)=>{let A={...r},T,K=()=>{T.abort(),document.hidden||$()};c||document.addEventListener("visibilitychange",K);let j=0,H=()=>{document.removeEventListener("visibilitychange",K),clearTimeout(j),T.abort()};n?.addEventListener("abort",()=>{H(),v()});let B=l||window.fetch,fe=s||(()=>{}),ne=0,g=f,$=async()=>{T=new AbortController;try{let b=await B(e,{...h,headers:A,signal:T.signal});ne=0,f=g,await fe(b);let F=async(y,k,ue,Ee,...Vt)=>{let tt={[ue]:await k.text()};for(let ke of Vt){let _e=k.headers.get(`datastar-${de(ke)}`);if(Ee){let Se=Ee[ke];Se&&(_e=typeof Se=="string"?Se:JSON.stringify(Se))}_e&&(tt[ke]=_e)}ee(y,t,tt),H(),v()},N=b.headers.get("Content-Type");if(N?.includes("text/html"))return await F("datastar-patch-elements",b,"elements",m,"selector","mode","useViewTransition");if(N?.includes("application/json"))return await F("datastar-patch-signals",b,"signals",m,"onlyIfMissing");if(N?.includes("text/javascript")){let y=document.createElement("script"),k=b.headers.get("datastar-script-attributes");if(k)for(let[ue,Ee]of Object.entries(JSON.parse(k)))y.setAttribute(ue,Ee);y.textContent=await b.text(),document.head.appendChild(y),H();return}await tn(b.body,nn(rn(y=>{y?A["last-event-id"]=y:delete A["last-event-id"]},y=>{g=f=y},i))),a?.(),H(),v()}catch(b){if(!T.signal.aborted)try{let F=o?.(b)||f;clearTimeout(j),j=setTimeout($,F),f=Math.min(f*d,x),++ne>=u?(ee(en,t,{}),H(),L("Max retries reached.")):console.error(`Datastar failed to reach ${e.toString()} retrying in ${F}ms.`)}catch(F){H(),L(F)}}};$()});p({name:"attr",requirement:{value:"must"},returnsValue:!0,apply({el:e,key:t,rx:n}){let r=(o,c)=>{c===""||c===!0?e.setAttribute(o,""):c===!1||c==null?e.removeAttribute(o):typeof c=="string"?e.setAttribute(o,c):e.setAttribute(o,JSON.stringify(c))},s=t?()=>{i.disconnect();let o=n();r(t,o),i.observe(e,{attributeFilter:[t]})}:()=>{i.disconnect();let o=n(),c=Object.keys(o);for(let l of c)r(l,o[l]);i.observe(e,{attributeFilter:c})},i=new MutationObserver(s),a=E(s);return()=>{i.disconnect(),a()}}});var an=/^data:(?[^;]+);base64,(?.*)$/,Nt=Symbol("empty"),Ct=Q("bind");p({name:"bind",requirement:"exclusive",apply({el:e,key:t,mods:n,value:r,error:s}){let i=t!=null?R(t,n):r,a=(u,m)=>m==="number"?+u.value:u.value,o=u=>{e.value=`${u}`};if(e instanceof HTMLInputElement)switch(e.type){case"range":case"number":a=(u,m)=>m==="string"?u.value:+u.value;break;case"checkbox":a=(u,m)=>u.value!=="on"?m==="boolean"?u.checked:u.checked?u.value:"":m==="string"?u.checked?u.value:"":u.checked,o=u=>{e.checked=typeof u=="string"?u===e.value:u};break;case"radio":e.getAttribute("name")?.length||e.setAttribute("name",i),a=(u,m)=>u.checked?m==="number"?+u.value:u.value:Nt,o=u=>{e.checked=u===(typeof u=="number"?+e.value:e.value)};break;case"file":{let u=()=>{let m=[...e.files||[]],h=[];Promise.all(m.map(v=>new Promise(L=>{let A=new FileReader;A.onload=()=>{if(typeof A.result!="string")throw s("InvalidFileResultType",{resultType:typeof A.result});let T=A.result.match(an);if(!T?.groups)throw s("InvalidDataUri",{result:A.result});h.push({name:v.name,contents:T.groups.contents,mime:T.groups.mime})},A.onloadend=()=>L(),A.readAsDataURL(v)}))).then(()=>{S([[i,h]])})};return e.addEventListener("change",u),e.addEventListener("input",u),()=>{e.removeEventListener("change",u),e.removeEventListener("input",u)}}}else if(e instanceof HTMLSelectElement){if(e.multiple){let u=new Map;a=m=>[...m.selectedOptions].map(h=>{let v=u.get(h.value);return v==="string"||v==null?h.value:+h.value}),o=m=>{for(let h of e.options)m.includes(h.value)?(u.set(h.value,"string"),h.selected=!0):m.includes(+h.value)?(u.set(h.value,"number"),h.selected=!0):h.selected=!1}}}else e instanceof HTMLTextAreaElement||(a=u=>"value"in u?u.value:u.getAttribute("value"),o=u=>{"value"in e?e.value=u:e.setAttribute("value",u)});let c=ie(i),l=typeof c,f=i;if(Array.isArray(c)&&!(e instanceof HTMLSelectElement&&e.multiple)){let u=t||r,m=document.querySelectorAll(`[${Ct}\\:${CSS.escape(u)}],[${Ct}="${CSS.escape(u)}"]`),h=[],v=0;for(let L of m){if(h.push([`${f}.${v}`,a(L,"none")]),e===L)break;v++}S(h,{ifMissing:!0}),f=`${f}.${v}`}else S([[f,a(e,l)]],{ifMissing:!0});let d=()=>{let u=ie(f);if(u!=null){let m=a(e,typeof u);m!==Nt&&S([[f,m]])}};e.addEventListener("input",d),e.addEventListener("change",d);let x=E(()=>{o(ie(f))});return()=>{x(),e.removeEventListener("input",d),e.removeEventListener("change",d)}}});p({name:"class",requirement:{value:"must"},returnsValue:!0,apply({key:e,el:t,mods:n,rx:r}){e&&(e=R(e,n,"kebab"));let s=()=>{i.disconnect();let o=e?{[e]:r()}:r();for(let c in o){let l=c.split(/\s+/).filter(f=>f.length>0);if(o[c])for(let f of l)t.classList.contains(f)||t.classList.add(f);else for(let f of l)t.classList.contains(f)&&t.classList.remove(f)}i.observe(t,{attributeFilter:["class"]})},i=new MutationObserver(s),a=E(s);return()=>{i.disconnect(),a();let o=e?{[e]:r()}:r();for(let c in o){let l=c.split(/\s+/).filter(f=>f.length>0);for(let f of l)t.classList.remove(f)}}}});p({name:"computed",requirement:{value:"must"},returnsValue:!0,apply({key:e,mods:t,rx:n,error:r}){if(e)S([[R(e,t),Ne(n)]]);else{let s=Object.assign({},n());Z(s,i=>{if(typeof i=="function")return Ne(i);throw r("ComputedExpectedFunction")}),C(s)}}});p({name:"effect",requirement:{key:"denied",value:"must"},apply:({rx:e})=>E(e)});p({name:"indicator",requirement:"exclusive",apply({el:e,key:t,mods:n,value:r}){let s=t!=null?R(t,n):r;S([[s,!1]]);let i=a=>{let{type:o,el:c}=a.detail;if(c===e)switch(o){case ze:S([[s,!0]]);break;case Qe:S([[s,!1]]);break}};return document.addEventListener(q,i),()=>{S([[s,!1]]),document.removeEventListener(q,i)}}});p({name:"json-signals",requirement:{key:"denied"},apply({el:e,value:t,mods:n}){let r=n.has("terse")?0:2,s={};t&&(s=re(t));let i=()=>{a.disconnect(),e.textContent=JSON.stringify(D(s),null,r),a.observe(e,{childList:!0,characterData:!0,subtree:!0})},a=new MutationObserver(i),o=E(i);return()=>{a.disconnect(),o()}}});var U=e=>{if(!e||e.size<=0)return 0;for(let t of e){if(t.endsWith("ms"))return+t.replace("ms","");if(t.endsWith("s"))return+t.replace("s","")*1e3;try{return Number.parseFloat(t)}catch{}}return 0},te=(e,t,n=!1)=>e?e.has(t.toLowerCase()):n;var Ze=(e,t)=>(...n)=>{setTimeout(()=>{e(...n)},t)},cn=(e,t,n=!1,r=!0)=>{let s=0;return(...i)=>{s&&clearTimeout(s),n&&!s&&e(...i),s=setTimeout(()=>{r&&e(...i),s&&clearTimeout(s),s=0},t)}},ln=(e,t,n=!0,r=!1)=>{let s=!1;return(...i)=>{s||(n&&e(...i),s=!0,setTimeout(()=>{r&&e(...i),s=!1},t))}},le=(e,t)=>{let n=t.get("delay");if(n){let i=U(n);e=Ze(e,i)}let r=t.get("debounce");if(r){let i=U(r),a=te(r,"leading",!1),o=!te(r,"notrailing",!1);e=cn(e,i,a,o)}let s=t.get("throttle");if(s){let i=U(s),a=!te(s,"noleading",!1),o=te(s,"trailing",!1);e=ln(e,i,a,o)}return e};var Ye=!!document.startViewTransition,J=(e,t)=>{if(t.has("viewtransition")&&Ye){let n=e;e=(...r)=>document.startViewTransition(()=>n(...r))}return e};p({name:"on",requirement:"must",argNames:["evt"],apply({el:e,key:t,mods:n,rx:r}){let s=e;n.has("window")&&(s=window);let i=c=>{c&&(n.has("prevent")&&c.preventDefault(),n.has("stop")&&c.stopPropagation()),w(),r(c),M()};i=J(i,n),i=le(i,n);let a={capture:n.has("capture"),passive:n.has("passive"),once:n.has("once")};if(n.has("outside")){s=document;let c=i;i=l=>{e.contains(l?.target)||c(l)}}let o=R(t,n,"kebab");if((o===q||o===z)&&(s=document),e instanceof HTMLFormElement&&o==="submit"){let c=i;i=l=>{l?.preventDefault(),c(l)}}return s.addEventListener(o,i,a),()=>{s.removeEventListener(o,i)}}});var Xe=new WeakSet;p({name:"on-intersect",requirement:{key:"denied",value:"must"},apply({el:e,mods:t,rx:n}){let r=()=>{w(),n(),M()};r=J(r,t),r=le(r,t);let s={threshold:0};t.has("full")?s.threshold=1:t.has("half")&&(s.threshold=.5);let i=new IntersectionObserver(a=>{for(let o of a)o.isIntersecting&&(r(),i&&Xe.has(e)&&i.disconnect())},s);return i.observe(e),t.has("once")&&Xe.add(e),()=>{t.has("once")||Xe.delete(e),i&&(i.disconnect(),i=null)}}});p({name:"on-interval",requirement:{key:"denied",value:"must"},apply({mods:e,rx:t}){let n=()=>{w(),t(),M()};n=J(n,e);let r=1e3,s=e.get("duration");s&&(r=U(s),te(s,"leading",!1)&&n());let i=setInterval(n,r);return()=>{clearInterval(i)}}});p({name:"init",requirement:{key:"denied",value:"must"},apply({rx:e,mods:t}){let n=()=>{w(),e(),M()};n=J(n,t);let r=0,s=t.get("delay");s&&(r=U(s),r>0&&(n=Ze(n,r))),n()}});p({name:"on-signal-patch",requirement:{value:"must"},argNames:["patch"],returnsValue:!0,apply({el:e,key:t,mods:n,rx:r,error:s}){if(t&&t!=="filter")throw s("KeyNotAllowed");let i=e.getAttribute("data-on-signal-patch-filter"),a={};i&&(a=re(i));let o=le(c=>{let l=D(a,c.detail);it(l)||(w(),r(l),M())},n);return document.addEventListener(z,o),()=>{document.removeEventListener(z,o)}}});p({name:"ref",requirement:"exclusive",apply({el:e,key:t,mods:n,value:r}){let s=t!=null?R(t,n):r;S([[s,e]])}});var Ot="none",Pt="display";p({name:"show",requirement:{key:"denied",value:"must"},returnsValue:!0,apply({el:e,rx:t}){let n=()=>{r.disconnect(),t()?e.style.display===Ot&&e.style.removeProperty(Pt):e.style.setProperty(Pt,Ot),r.observe(e,{attributeFilter:["style"]})},r=new MutationObserver(n),s=E(n);return()=>{r.disconnect(),s()}}});p({name:"signals",returnsValue:!0,apply({key:e,mods:t,rx:n}){let r=t.has("ifmissing");if(e)e=R(e,t),S([[e,n?.()]],{ifMissing:r});else{let s=Object.assign({},n?.());C(s,{ifMissing:r})}}});p({name:"style",requirement:{value:"must"},returnsValue:!0,apply({key:e,el:t,rx:n}){let{style:r}=t,s=new Map,i=(l,f)=>{let d=s.get(l);!f&&f!==0?d!==void 0&&(d?r.setProperty(l,d):r.removeProperty(l)):(d===void 0&&s.set(l,r.getPropertyValue(l)),r.setProperty(l,String(f)))},a=()=>{if(o.disconnect(),e)i(e,n());else{let l=n();for(let[f,d]of s)f in l||(d?r.setProperty(f,d):r.removeProperty(f));for(let f in l)i(de(f),l[f])}o.observe(t,{attributeFilter:["style"]})},o=new MutationObserver(a),c=E(a);return()=>{o.disconnect(),c();for(let[l,f]of s)f?r.setProperty(l,f):r.removeProperty(l)}}});p({name:"text",requirement:{key:"denied",value:"must"},returnsValue:!0,apply({el:e,rx:t}){let n=()=>{r.disconnect(),e.textContent=`${t()}`,r.observe(e,{childList:!0,characterData:!0,subtree:!0})},r=new MutationObserver(n),s=E(n);return()=>{r.disconnect(),s()}}});he({name:"datastar-patch-elements",apply(e,{elements:t="",selector:n="",mode:r="outer",useViewTransition:s}){switch(r){case"remove":case"outer":case"inner":case"replace":case"prepend":case"append":case"before":case"after":break;default:throw e.error("PatchElementsInvalidMode",{mode:r})}if(!n&&r!=="outer"&&r!=="replace")throw e.error("PatchElementsExpectedSelector");let i={mode:r,selector:n,elements:t,useViewTransition:s?.trim()==="true"};Ye&&s?document.startViewTransition(()=>Ht(e,i)):Ht(e,i)}});var Ht=({error:e},{elements:t,selector:n,mode:r})=>{let s=t.replace(/]*>|>)([\s\S]*?)<\/svg>/gim,""),i=/<\/html>/.test(s),a=/<\/head>/.test(s),o=/<\/body>/.test(s),c=new DOMParser().parseFromString(i||a||o?t:``,"text/html"),l=document.createDocumentFragment();if(i?l.appendChild(c.documentElement):a&&o?(l.appendChild(c.head),l.appendChild(c.body)):a?l.appendChild(c.head):o?l.appendChild(c.body):l=c.querySelector("template").content,!n&&(r==="outer"||r==="replace"))for(let f of l.children){let d;if(f instanceof HTMLHtmlElement)d=document.documentElement;else if(f instanceof HTMLBodyElement)d=document.body;else if(f instanceof HTMLHeadElement)d=document.head;else if(d=document.getElementById(f.id),!d){console.warn(e("PatchElementsNoTargetsFound"),{element:{id:f.id}});continue}_t(r,f,[d])}else{let f=document.querySelectorAll(n);if(!f.length){console.warn(e("PatchElementsNoTargetsFound"),{selector:n});return}_t(r,l,f)}},et=new WeakSet;for(let e of document.querySelectorAll("script"))et.add(e);var Dt=e=>{let t=e instanceof HTMLScriptElement?[e]:e.querySelectorAll("script");for(let n of t)if(!et.has(n)){let r=document.createElement("script");for(let{name:s,value:i}of n.attributes)r.setAttribute(s,i);r.text=n.text,n.replaceWith(r),et.add(r)}},kt=(e,t,n)=>{for(let r of e){let s=t.cloneNode(!0);Dt(s),r[n](s)}},_t=(e,t,n)=>{switch(e){case"remove":for(let r of n)r.remove();break;case"outer":case"inner":for(let r of n)Ke(r,t.cloneNode(!0),e),Dt(r);break;case"replace":kt(n,t,"replaceWith");break;case"prepend":case"append":case"before":case"after":kt(n,t,e)}};he({name:"datastar-patch-signals",apply({error:e},{signals:t,onlyIfMissing:n}){if(t){let r=n?.trim()==="true";C(re(t),{ifMissing:r})}else throw e("PatchSignalsExpectedSignals")}});export{O as action,Et as actions,p as attribute,w as beginBatch,Ne as computed,E as effect,M as endBatch,D as filtered,ie as getPath,C as mergePatch,S as mergePaths,Ke as morph,X as root,me as signal,V as startPeeking,I as stopPeeking,he as watcher}; +//# sourceMappingURL=datastar.js.map diff --git a/demo/datasstar-static/signals/datastar.js.map b/demo/datasstar-static/signals/datastar.js.map new file mode 100644 index 0000000..f82819f --- /dev/null +++ b/demo/datasstar-static/signals/datastar.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../library/src/engine/consts.ts", "../library/src/utils/text.ts", "../library/src/utils/polyfills.ts", "../library/src/utils/paths.ts", "../library/src/engine/signals.ts", "../library/src/utils/dom.ts", "../library/src/engine/engine.ts", "../library/src/engine/morph.ts", "../library/src/plugins/actions/peek.ts", "../library/src/plugins/actions/setAll.ts", "../library/src/plugins/actions/toggleAll.ts", "../library/src/plugins/actions/fetch.ts", "../library/src/plugins/attributes/attr.ts", "../library/src/plugins/attributes/bind.ts", "../library/src/plugins/attributes/class.ts", "../library/src/plugins/attributes/computed.ts", "../library/src/plugins/attributes/effect.ts", "../library/src/plugins/attributes/indicator.ts", "../library/src/plugins/attributes/jsonSignals.ts", "../library/src/utils/tags.ts", "../library/src/utils/timing.ts", "../library/src/utils/view-transitions.ts", "../library/src/plugins/attributes/on.ts", "../library/src/plugins/attributes/onIntersect.ts", "../library/src/plugins/attributes/onInterval.ts", "../library/src/plugins/attributes/init.ts", "../library/src/plugins/attributes/onSignalPatch.ts", "../library/src/plugins/attributes/ref.ts", "../library/src/plugins/attributes/show.ts", "../library/src/plugins/attributes/signals.ts", "../library/src/plugins/attributes/style.ts", "../library/src/plugins/attributes/text.ts", "../library/src/plugins/watchers/patchElements.ts", "../library/src/plugins/watchers/patchSignals.ts"], + "sourcesContent": ["const lol = /\uD83D\uDD95JS_DS\uD83D\uDE80/.source\nexport const DSP = lol.slice(0, 5)\nexport const DSS = lol.slice(4)\nexport const DATASTAR_FETCH_EVENT = 'datastar-fetch'\nexport const DATASTAR_SIGNAL_PATCH_EVENT = 'datastar-signal-patch'\n", "import type { Modifiers } from '@engine/types'\n\nexport const kebab = (str: string): string =>\n str\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/([a-z])([0-9]+)/gi, '$1-$2')\n .replace(/([0-9]+)([a-z])/gi, '$1-$2')\n .toLowerCase()\n\nexport const camel = (str: string): string =>\n kebab(str).replace(/-./g, (x) => x[1].toUpperCase())\n\nexport const snake = (str: string): string => kebab(str).replace(/-/g, '_')\n\nexport const pascal = (str: string): string =>\n camel(str).replace(/(^.|(?<=\\.).)/g, (x) => x[0].toUpperCase())\n\nexport const jsStrToObject = (raw: string) => {\n try {\n return JSON.parse(raw)\n } catch {\n // If JSON parsing fails, try to evaluate as a JavaScript object\n // This is less safe and should be used with caution\n return Function(`return (${raw})`)()\n }\n}\n\nconst caseFns: Record string> = {\n camel: (str) => str.replace(/-[a-z]/g, (x) => x[1].toUpperCase()),\n snake: (str) => str.replace(/-/g, '_'),\n pascal: (str) => str[0].toUpperCase() + caseFns.camel(str.slice(1)),\n}\n\nexport const modifyCasing = (\n str: string,\n mods: Modifiers,\n defaultCase = 'camel',\n): string => {\n for (const c of mods.get('case') || [defaultCase]) {\n str = caseFns[c]?.(str) || str\n }\n return str\n}\n\nexport const aliasify = (name: string) =>\n ALIAS ? `data-${ALIAS}-${name}` : `data-${name}`\n", "export const hasOwn: (obj: object, prop: PropertyKey) => boolean =\n // @ts-expect-error\n Object.hasOwn ?? Object.prototype.hasOwnProperty.call\n", "import type { Paths } from '@engine/types'\nimport { hasOwn } from '@utils/polyfills'\n\nexport const isPojo = (obj: any): obj is Record =>\n obj !== null &&\n typeof obj === 'object' &&\n (Object.getPrototypeOf(obj) === Object.prototype ||\n Object.getPrototypeOf(obj) === null)\n\nexport const isEmpty = (obj: Record): boolean => {\n for (const prop in obj) {\n if (hasOwn(obj, prop)) {\n return false\n }\n }\n return true\n}\n\nexport const updateLeaves = (\n obj: Record,\n fn: (oldValue: any) => any,\n) => {\n for (const key in obj) {\n const val = obj[key]\n if (isPojo(val) || Array.isArray(val)) {\n updateLeaves(val, fn)\n } else {\n obj[key] = fn(val)\n }\n }\n}\n\nexport const pathToObj = (paths: Paths): Record => {\n const result: Record = {}\n for (const [path, value] of paths) {\n const keys = path.split('.')\n const lastKey = keys.pop()!\n const obj = keys.reduce((acc, key) => (acc[key] ??= {}), result)\n obj[lastKey] = value\n }\n return result\n}\n", "import { DATASTAR_SIGNAL_PATCH_EVENT } from '@engine/consts'\nimport type {\n Computed,\n Effect,\n JSONPatch,\n MergePatchArgs,\n Paths,\n Signal,\n SignalFilterOptions,\n} from '@engine/types'\nimport { isPojo, pathToObj } from '@utils/paths'\nimport { hasOwn } from '@utils/polyfills'\n\ninterface ReactiveNode {\n deps_?: Link\n depsTail_?: Link\n subs_?: Link\n subsTail_?: Link\n flags_: ReactiveFlags\n}\n\ninterface Link {\n version_: number\n dep_: ReactiveNode\n sub_: ReactiveNode\n prevSub_?: Link\n nextSub_?: Link\n prevDep_?: Link\n nextDep_?: Link\n}\n\ninterface Stack {\n value_: T\n prev_?: Stack\n}\n\nenum ReactiveFlags {\n None = 0,\n Mutable = 1 << 0,\n Watching = 1 << 1,\n RecursedCheck = 1 << 2,\n Recursed = 1 << 3,\n Dirty = 1 << 4,\n Pending = 1 << 5,\n}\n\nenum EffectFlags {\n Queued = 1 << 6,\n}\n\ninterface AlienEffect extends ReactiveNode {\n fn_(): void\n}\n\ninterface AlienComputed extends ReactiveNode {\n value_?: T\n getter(previousValue?: T): T\n}\n\ninterface AlienSignal extends ReactiveNode {\n previousValue: T\n value_: T\n}\n\nconst currentPatch: Paths = []\nconst queuedEffects: (AlienEffect | undefined)[] = []\nlet batchDepth = 0\nlet notifyIndex = 0\nlet queuedEffectsLength = 0\nlet prevSub: ReactiveNode | undefined\nlet activeSub: ReactiveNode | undefined\nlet version = 0\n\nexport const beginBatch = (): void => {\n batchDepth++\n}\n\nexport const endBatch = (): void => {\n if (!--batchDepth) {\n flush()\n dispatch()\n }\n}\n\nexport const startPeeking = (sub?: ReactiveNode): void => {\n prevSub = activeSub\n activeSub = sub\n}\n\nexport const stopPeeking = (): void => {\n activeSub = prevSub\n prevSub = undefined\n}\n\nexport const signal = (initialValue?: T): Signal => {\n return signalOper.bind(0, {\n previousValue: initialValue,\n value_: initialValue,\n flags_: 1 satisfies ReactiveFlags.Mutable,\n }) as Signal\n}\n\nconst computedSymbol = Symbol('computed')\nexport const computed = (getter: (previousValue?: T) => T): Computed => {\n const c = computedOper.bind(0, {\n flags_: 17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty,\n getter,\n }) as Computed\n // @ts-expect-error\n c[computedSymbol] = 1\n return c\n}\n\nexport const effect = (fn: () => void): Effect => {\n const e: AlienEffect = {\n fn_: fn,\n flags_: 2 satisfies ReactiveFlags.Watching,\n }\n if (activeSub) {\n link(e, activeSub)\n }\n startPeeking(e)\n beginBatch()\n try {\n e.fn_()\n } finally {\n endBatch()\n stopPeeking()\n }\n return effectOper.bind(0, e)\n}\n\nconst flush = () => {\n while (notifyIndex < queuedEffectsLength) {\n const effect = queuedEffects[notifyIndex]!\n queuedEffects[notifyIndex++] = undefined\n run(effect, (effect.flags_ &= ~EffectFlags.Queued))\n }\n notifyIndex = 0\n queuedEffectsLength = 0\n}\n\nconst update = (signal: AlienSignal | AlienComputed): boolean => {\n if ('getter' in signal) {\n return updateComputed(signal)\n }\n return updateSignal(signal, signal.value_)\n}\n\nconst updateComputed = (c: AlienComputed): boolean => {\n startPeeking(c)\n startTracking(c)\n try {\n const oldValue = c.value_\n return oldValue !== (c.value_ = c.getter(oldValue))\n } finally {\n stopPeeking()\n endTracking(c)\n }\n}\n\nconst updateSignal = (s: AlienSignal, value: T): boolean => {\n s.flags_ = 1 satisfies ReactiveFlags.Mutable\n return s.previousValue !== (s.previousValue = value)\n}\n\nconst notify = (e: AlienEffect): void => {\n const flags = e.flags_\n if (!(flags & EffectFlags.Queued)) {\n e.flags_ = flags | EffectFlags.Queued\n const subs = e.subs_\n if (subs) {\n notify(subs.sub_ as AlienEffect)\n } else {\n queuedEffects[queuedEffectsLength++] = e\n }\n }\n}\n\nconst run = (e: AlienEffect, flags: ReactiveFlags): void => {\n if (\n flags & (16 satisfies ReactiveFlags.Dirty) ||\n (flags & (32 satisfies ReactiveFlags.Pending) && checkDirty(e.deps_!, e))\n ) {\n startPeeking(e)\n startTracking(e)\n beginBatch()\n try {\n e.fn_()\n } finally {\n endBatch()\n stopPeeking()\n endTracking(e)\n }\n return\n }\n if (flags & (32 satisfies ReactiveFlags.Pending)) {\n e.flags_ = flags & ~(32 satisfies ReactiveFlags.Pending)\n }\n let link = e.deps_\n while (link) {\n const dep = link.dep_\n const depFlags = dep.flags_\n if (depFlags & EffectFlags.Queued) {\n run(dep as AlienEffect, (dep.flags_ = depFlags & ~EffectFlags.Queued))\n }\n link = link.nextDep_\n }\n}\n\nconst signalOper = (s: AlienSignal, ...value: [T]): T | boolean => {\n if (value.length) {\n if (s.value_ !== (s.value_ = value[0])) {\n s.flags_ = 17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty\n const subs = s.subs_\n if (subs) {\n propagate(subs)\n if (!batchDepth) {\n flush()\n }\n }\n return true\n }\n return false\n }\n const currentValue = s.value_\n if (s.flags_ & (16 satisfies ReactiveFlags.Dirty)) {\n if (updateSignal(s, currentValue)) {\n const subs_ = s.subs_\n if (subs_) {\n shallowPropagate(subs_)\n }\n }\n }\n if (activeSub) {\n link(s, activeSub)\n }\n return currentValue\n}\n\nconst computedOper = (c: AlienComputed): T => {\n const flags = c.flags_\n if (\n flags & (16 satisfies ReactiveFlags.Dirty) ||\n (flags & (32 satisfies ReactiveFlags.Pending) && checkDirty(c.deps_!, c))\n ) {\n if (updateComputed(c)) {\n const subs = c.subs_\n if (subs) {\n shallowPropagate(subs)\n }\n }\n } else if (flags & (32 satisfies ReactiveFlags.Pending)) {\n c.flags_ = flags & ~(32 satisfies ReactiveFlags.Pending)\n }\n if (activeSub) {\n link(c, activeSub)\n }\n return c.value_!\n}\n\nconst effectOper = (e: AlienEffect): void => {\n let dep = e.deps_\n while (dep) {\n dep = unlink(dep, e)\n }\n const sub = e.subs_\n if (sub) {\n unlink(sub)\n }\n e.flags_ = 0 satisfies ReactiveFlags.None\n}\n\nconst link = (dep: ReactiveNode, sub: ReactiveNode): void => {\n const prevDep = sub.depsTail_\n if (prevDep && prevDep.dep_ === dep) {\n return\n }\n const nextDep = prevDep ? prevDep.nextDep_ : sub.deps_\n if (nextDep && nextDep.dep_ === dep) {\n nextDep.version_ = version\n sub.depsTail_ = nextDep\n return\n }\n const prevSub = dep.subsTail_\n if (prevSub && prevSub.version_ === version && prevSub.sub_ === sub) {\n return\n }\n const newLink =\n (sub.depsTail_ =\n dep.subsTail_ =\n {\n version_: version,\n dep_: dep,\n sub_: sub,\n prevDep_: prevDep,\n nextDep_: nextDep,\n prevSub_: prevSub,\n })\n if (nextDep) {\n nextDep.prevDep_ = newLink\n }\n if (prevDep) {\n prevDep.nextDep_ = newLink\n } else {\n sub.deps_ = newLink\n }\n if (prevSub) {\n prevSub.nextSub_ = newLink\n } else {\n dep.subs_ = newLink\n }\n}\n\nconst unlink = (link: Link, sub = link.sub_): Link | undefined => {\n const dep_ = link.dep_\n const prevDep_ = link.prevDep_\n const nextDep_ = link.nextDep_\n const nextSub_ = link.nextSub_\n const prevSub_ = link.prevSub_\n if (nextDep_) {\n nextDep_.prevDep_ = prevDep_\n } else {\n sub.depsTail_ = prevDep_\n }\n if (prevDep_) {\n prevDep_.nextDep_ = nextDep_\n } else {\n sub.deps_ = nextDep_\n }\n if (nextSub_) {\n nextSub_.prevSub_ = prevSub_\n } else {\n dep_.subsTail_ = prevSub_\n }\n if (prevSub_) {\n prevSub_.nextSub_ = nextSub_\n } else if (!(dep_.subs_ = nextSub_)) {\n if ('getter' in dep_) {\n let toRemove = dep_.deps_\n if (toRemove) {\n dep_.flags_ = 17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty\n do {\n toRemove = unlink(toRemove, dep_)\n } while (toRemove)\n }\n } else if (!('previousValue' in dep_)) {\n effectOper(dep_ as AlienEffect)\n }\n }\n return nextDep_\n}\n\nconst propagate = (link: Link): void => {\n let next = link.nextSub_\n let stack: Stack | undefined\n\n top: while (true) {\n const sub = link.sub_\n\n let flags = sub.flags_\n\n if (\n !(\n flags &\n (60 as\n | ReactiveFlags.RecursedCheck\n | ReactiveFlags.Recursed\n | ReactiveFlags.Dirty\n | ReactiveFlags.Pending)\n )\n ) {\n sub.flags_ = flags | (32 satisfies ReactiveFlags.Pending)\n } else if (\n !(flags & (12 as ReactiveFlags.RecursedCheck | ReactiveFlags.Recursed))\n ) {\n flags = 0 satisfies ReactiveFlags.None\n } else if (!(flags & (4 satisfies ReactiveFlags.RecursedCheck))) {\n sub.flags_ =\n (flags & ~(8 satisfies ReactiveFlags.Recursed)) |\n (32 satisfies ReactiveFlags.Pending)\n } else if (\n !(flags & (48 as ReactiveFlags.Dirty | ReactiveFlags.Pending)) &&\n isValidLink(link, sub)\n ) {\n sub.flags_ =\n flags | (40 as ReactiveFlags.Recursed | ReactiveFlags.Pending)\n flags &= 1 satisfies ReactiveFlags.Mutable\n } else {\n flags = 0 satisfies ReactiveFlags.None\n }\n\n if (flags & (2 satisfies ReactiveFlags.Watching)) {\n notify(sub as AlienEffect)\n }\n\n if (flags & (1 satisfies ReactiveFlags.Mutable)) {\n const subSubs = sub.subs_\n if (subSubs) {\n const nextSub = (link = subSubs).nextSub_\n if (nextSub) {\n stack = { value_: next, prev_: stack }\n next = nextSub\n }\n continue\n }\n }\n\n if ((link = next!)) {\n next = link.nextSub_\n continue\n }\n\n while (stack) {\n link = stack.value_!\n stack = stack.prev_\n if (link) {\n next = link.nextSub_\n continue top\n }\n }\n\n break\n }\n}\n\nconst startTracking = (sub: ReactiveNode): void => {\n version++\n sub.depsTail_ = undefined\n sub.flags_ =\n (sub.flags_ &\n ~(56 as\n | ReactiveFlags.Recursed\n | ReactiveFlags.Dirty\n | ReactiveFlags.Pending)) |\n (4 satisfies ReactiveFlags.RecursedCheck)\n}\n\nconst endTracking = (sub: ReactiveNode): void => {\n const depsTail_ = sub.depsTail_\n let toRemove = depsTail_ ? depsTail_.nextDep_ : sub.deps_\n while (toRemove) {\n toRemove = unlink(toRemove, sub)\n }\n sub.flags_ &= ~(4 satisfies ReactiveFlags.RecursedCheck)\n}\n\nconst checkDirty = (link: Link, sub: ReactiveNode): boolean => {\n let stack: Stack | undefined\n let checkDepth = 0\n let dirty = false\n\n top: while (true) {\n const dep = link.dep_\n const flags = dep.flags_\n\n if (sub.flags_ & (16 satisfies ReactiveFlags.Dirty)) {\n dirty = true\n } else if (\n (flags & (17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty)) ===\n (17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty)\n ) {\n if (update(dep as AlienSignal | AlienComputed)) {\n const subs = dep.subs_!\n if (subs.nextSub_) {\n shallowPropagate(subs)\n }\n dirty = true\n }\n } else if (\n (flags & (33 as ReactiveFlags.Mutable | ReactiveFlags.Pending)) ===\n (33 as ReactiveFlags.Mutable | ReactiveFlags.Pending)\n ) {\n if (link.nextSub_ || link.prevSub_) {\n stack = { value_: link, prev_: stack }\n }\n link = dep.deps_!\n sub = dep\n ++checkDepth\n continue\n }\n\n if (!dirty) {\n const nextDep = link.nextDep_\n if (nextDep) {\n link = nextDep\n continue\n }\n }\n\n while (checkDepth--) {\n const firstSub = sub.subs_!\n const hasMultipleSubs = firstSub.nextSub_\n if (hasMultipleSubs) {\n link = stack!.value_\n stack = stack!.prev_\n } else {\n link = firstSub\n }\n if (dirty) {\n if (update(sub as AlienSignal | AlienComputed)) {\n if (hasMultipleSubs) {\n shallowPropagate(firstSub)\n }\n sub = link.sub_\n continue\n }\n dirty = false\n } else {\n sub.flags_ &= ~(32 satisfies ReactiveFlags.Pending)\n }\n sub = link.sub_\n if (link.nextDep_) {\n link = link.nextDep_\n continue top\n }\n }\n\n return dirty\n }\n}\n\nconst shallowPropagate = (link: Link): void => {\n do {\n const sub = link.sub_\n const flags = sub.flags_\n if (\n (flags & (48 as ReactiveFlags.Pending | ReactiveFlags.Dirty)) ===\n (32 satisfies ReactiveFlags.Pending)\n ) {\n sub.flags_ = flags | (16 satisfies ReactiveFlags.Dirty)\n if (flags & (2 satisfies ReactiveFlags.Watching)) {\n notify(sub as AlienEffect)\n }\n }\n } while ((link = link.nextSub_!))\n}\n\nconst isValidLink = (checkLink: Link, sub: ReactiveNode): boolean => {\n let link = sub.depsTail_\n while (link) {\n if (link === checkLink) {\n return true\n }\n link = link.prevDep_\n }\n return false\n}\n\nexport const getPath = (path: string): T | undefined => {\n let result = root\n const split = path.split('.')\n for (const path of split) {\n if (result == null || !hasOwn(result, path)) {\n return\n }\n result = result[path]\n }\n return result as T\n}\n\nconst deep = (value: any, prefix = ''): any => {\n const isArr = Array.isArray(value)\n if (isArr || isPojo(value)) {\n const deepObj = (isArr ? [] : {}) as Record>\n for (const key in value) {\n deepObj[key] = signal(\n deep((value as Record>)[key], `${prefix + key}.`),\n )\n }\n const keys = signal(0)\n return new Proxy(deepObj, {\n get(_, prop: string) {\n // JSON.stringify calls `.toJSON()` directly instead of checking if it exists on the object\n // so we have to check if `toJSON` is being called and prevent a signal from automatically\n // being made so JSON.stringify can fallback to the default stringify\n if (!(prop === 'toJSON' && !hasOwn(deepObj, prop))) {\n // special case for when prop is an array function because every array function needs to\n // be reactive to when the keys change\n if (isArr && prop in Array.prototype) {\n keys()\n return deepObj[prop]\n }\n // if prop is a symbol just return the symbol because we don't want to make up that theres\n // an iterator symbol on an object or not\n if (typeof prop === 'symbol') {\n return deepObj[prop]\n }\n // if obj doesnt have prop OR prop is null or undefined then create a signal and default\n // to an empty string\n if (!hasOwn(deepObj, prop) || deepObj[prop]() == null) {\n deepObj[prop] = signal('')\n dispatch(prefix + prop, '')\n keys(keys() + 1)\n }\n return deepObj[prop]()\n }\n },\n set(_, prop: string, newValue) {\n const path = prefix + prop\n // special case for when setting length so we can make a diff patch\n if (isArr && prop === 'length') {\n const diff = (deepObj[prop] as unknown as number) - newValue\n deepObj[prop] = newValue\n // manually make a diff patch for now, shouldnt have to do this when object diffing is\n // implemented. see https://github.com/starfederation/datastar-dev/issues/274\n if (diff > 0) {\n const patch: Record = {}\n for (let i = newValue; i < deepObj[prop]; i++) {\n patch[i] = null\n }\n dispatch(prefix.slice(0, -1), patch)\n keys(keys() + 1)\n }\n } else if (hasOwn(deepObj, prop)) {\n if (newValue == null) {\n delete deepObj[prop]\n // if newValue is a computed set the computed directly instead of wrapping in signal\n } else if (hasOwn(newValue, computedSymbol)) {\n deepObj[prop] = newValue\n dispatch(path, '')\n // if prop changed after setting it then dispatch\n } else if (deepObj[prop](deep(newValue, `${path}.`))) {\n dispatch(path, newValue)\n }\n // if newValue is null or undefined then noop\n } else if (newValue != null) {\n // if newValue is a computed set the computed directly instead of wrapping in signal\n if (hasOwn(newValue, computedSymbol)) {\n deepObj[prop] = newValue\n dispatch(path, '')\n } else {\n deepObj[prop] = signal(deep(newValue, `${path}.`))\n dispatch(path, newValue)\n }\n keys(keys() + 1)\n }\n\n return true\n },\n deleteProperty(_, prop: string) {\n delete deepObj[prop]\n keys(keys() + 1)\n return true\n },\n ownKeys() {\n keys()\n return Reflect.ownKeys(deepObj)\n },\n has(_, prop) {\n keys()\n return prop in deepObj\n },\n })\n }\n return value\n}\n\nconst dispatch = (path?: string, value?: any) => {\n if (path !== undefined && value !== undefined) {\n currentPatch.push([path, value])\n }\n if (!batchDepth && currentPatch.length) {\n const detail = pathToObj(currentPatch)\n currentPatch.length = 0\n document.dispatchEvent(\n new CustomEvent(DATASTAR_SIGNAL_PATCH_EVENT, {\n detail,\n }),\n )\n }\n}\n\nexport const mergePatch = (\n patch: JSONPatch,\n { ifMissing }: MergePatchArgs = {},\n): void => {\n beginBatch()\n for (const key in patch) {\n if (patch[key] == null) {\n if (!ifMissing) {\n delete root[key]\n }\n } else {\n mergeInner(patch[key], key, root, '', ifMissing)\n }\n }\n endBatch()\n}\n\nexport const mergePaths = (paths: Paths, options?: MergePatchArgs): void =>\n mergePatch(pathToObj(paths), options)\n\nconst mergeInner = (\n patch: any,\n target: string,\n targetParent: Record,\n prefix: string,\n ifMissing: boolean | undefined,\n): void => {\n if (isPojo(patch)) {\n if (\n !(\n hasOwn(targetParent, target) &&\n (isPojo(targetParent[target]) || Array.isArray(targetParent[target]))\n )\n ) {\n targetParent[target] = {}\n }\n\n for (const key in patch) {\n if (patch[key] == null) {\n if (!ifMissing) {\n delete targetParent[target][key]\n }\n } else {\n mergeInner(\n patch[key],\n key,\n targetParent[target],\n `${prefix + target}.`,\n ifMissing,\n )\n }\n }\n } else if (!(ifMissing && hasOwn(targetParent, target))) {\n targetParent[target] = patch\n }\n}\n\nconst toRegExp = (val: string | RegExp): RegExp =>\n typeof val === 'string' ? RegExp(val.replace(/^\\/|\\/$/g, '')) : val\n\n/**\n * Filters the root store based on an include and exclude RegExp\n *\n * @returns The filtered object\n */\nexport const filtered = (\n { include = /.*/, exclude = /(?!)/ }: SignalFilterOptions = {},\n obj: JSONPatch = root,\n): Record => {\n const includeRe = toRegExp(include)\n const excludeRe = toRegExp(exclude)\n const paths: Paths = []\n const stack: [any, string][] = [[obj, '']]\n\n while (stack.length) {\n const [node, prefix] = stack.pop()!\n\n for (const key in node) {\n const path = prefix + key\n if (isPojo(node[key])) {\n stack.push([node[key], `${path}.`])\n } else if (includeRe.test(path) && !excludeRe.test(path)) {\n paths.push([path, getPath(path)])\n }\n }\n }\n\n return pathToObj(paths)\n}\n\nexport const root: Record = deep({})\n", "import type { HTMLOrSVG } from '@engine/types'\n\nexport const isHTMLOrSVG = (el: Node): el is HTMLOrSVG =>\n el instanceof HTMLElement ||\n el instanceof SVGElement ||\n el instanceof MathMLElement\n", "import { DATASTAR_FETCH_EVENT, DSP, DSS } from '@engine/consts'\nimport { snake } from '@utils/text'\nimport { root } from '@engine/signals'\nimport type {\n ActionPlugin,\n ActionContext,\n AttributeContext,\n AttributePlugin,\n DatastarFetchEvent,\n HTMLOrSVG,\n Requirement,\n WatcherPlugin,\n} from '@engine/types'\nimport { isHTMLOrSVG } from '@utils/dom'\nimport { aliasify } from '@utils/text'\n\nconst url = 'https://data-star.dev/errors'\n\nconst error = (\n ctx: Record,\n reason: string,\n metadata: Record = {},\n) => {\n Object.assign(metadata, ctx)\n const e = new Error()\n const r = snake(reason)\n const q = new URLSearchParams({\n metadata: JSON.stringify(metadata),\n }).toString()\n const c = JSON.stringify(metadata, null, 2)\n e.message = `${reason}\\nMore info: ${url}/${r}?${q}\\nContext: ${c}`\n return e\n}\n\nconst actionPlugins: Map = new Map()\nconst attributePlugins: Map = new Map()\nconst watcherPlugins: Map = new Map()\n\nexport const actions: Record<\n string,\n (ctx: ActionContext, ...args: any[]) => any\n> = new Proxy(\n {},\n {\n get: (_, prop: string) => actionPlugins.get(prop)?.apply,\n has: (_, prop: string) => actionPlugins.has(prop),\n ownKeys: () => Reflect.ownKeys(actionPlugins),\n set: () => false,\n deleteProperty: () => false,\n },\n)\n\n// Map of cleanups keyed by element and attribute name\nconst removals = new Map void>>()\n\nconst queuedAttributes: AttributePlugin[] = []\nconst queuedAttributeNames = new Set()\nexport const attribute = (\n plugin: AttributePlugin,\n): void => {\n queuedAttributes.push(plugin as unknown as AttributePlugin)\n\n if (queuedAttributes.length === 1) {\n setTimeout(() => {\n for (const attribute of queuedAttributes) {\n queuedAttributeNames.add(attribute.name)\n attributePlugins.set(attribute.name, attribute)\n }\n queuedAttributes.length = 0\n apply()\n queuedAttributeNames.clear()\n })\n }\n}\n\nexport const action = (plugin: ActionPlugin): void => {\n actionPlugins.set(plugin.name, plugin)\n}\n\ndocument.addEventListener(DATASTAR_FETCH_EVENT, ((\n evt: CustomEvent,\n) => {\n const plugin = watcherPlugins.get(evt.detail.type)\n if (plugin) {\n plugin.apply(\n {\n error: error.bind(0, {\n plugin: { type: 'watcher', name: plugin.name },\n element: {\n id: (evt.target as Element).id,\n tag: (evt.target as Element).tagName,\n },\n }),\n },\n evt.detail.argsRaw,\n )\n }\n}) as EventListener)\n\nexport const watcher = (plugin: WatcherPlugin): void => {\n watcherPlugins.set(plugin.name, plugin)\n}\n\nconst cleanupEls = (els: Iterable): void => {\n for (const el of els) {\n const cleanups = removals.get(el)\n // If removals has el, delete it and run all cleanup functions\n if (removals.delete(el)) {\n for (const cleanup of cleanups!.values()) {\n cleanup()\n }\n cleanups!.clear()\n }\n }\n}\n\nconst aliasedIgnore = aliasify('ignore')\nconst aliasedIgnoreAttr = `[${aliasedIgnore}]`\nconst shouldIgnore = (el: HTMLOrSVG) =>\n el.hasAttribute(`${aliasedIgnore}__self`) || !!el.closest(aliasedIgnoreAttr)\n\nconst applyEls = (els: Iterable, onlyNew?: boolean): void => {\n for (const el of els) {\n if (!shouldIgnore(el)) {\n for (const key in el.dataset) {\n applyAttributePlugin(\n el,\n key.replace(/[A-Z]/g, '-$&').toLowerCase(),\n el.dataset[key]!,\n onlyNew,\n )\n }\n }\n }\n}\n\nconst observe = (mutations: MutationRecord[]) => {\n for (const {\n target,\n type,\n attributeName,\n addedNodes,\n removedNodes,\n } of mutations) {\n if (type === 'childList') {\n for (const node of removedNodes) {\n if (isHTMLOrSVG(node)) {\n cleanupEls([node])\n cleanupEls(node.querySelectorAll('*'))\n }\n }\n\n for (const node of addedNodes) {\n if (isHTMLOrSVG(node)) {\n applyEls([node])\n applyEls(node.querySelectorAll('*'))\n }\n }\n } else if (\n type === 'attributes' &&\n attributeName!.startsWith('data-') &&\n isHTMLOrSVG(target) &&\n !shouldIgnore(target)\n ) {\n // skip over 'data-'\n const key = attributeName!.slice(5)\n const value = target.getAttribute(attributeName!)\n if (value === null) {\n const cleanups = removals.get(target)\n if (cleanups) {\n cleanups.get(key)?.()\n cleanups.delete(key)\n }\n } else {\n applyAttributePlugin(target, key, value)\n }\n }\n }\n}\n\n// TODO: mutation observer per root so applying to web component doesnt overwrite main observer\nconst mutationObserver = new MutationObserver(observe)\n\nexport const apply = (\n root: HTMLOrSVG | ShadowRoot = document.documentElement,\n): void => {\n if (isHTMLOrSVG(root)) {\n applyEls([root], true)\n }\n applyEls(root.querySelectorAll('*'), true)\n\n mutationObserver.observe(root, {\n subtree: true,\n childList: true,\n attributes: true,\n })\n}\n\nconst applyAttributePlugin = (\n el: HTMLOrSVG,\n attrKey: string,\n value: string,\n onlyNew?: boolean,\n): void => {\n if (!ALIAS || attrKey.startsWith(`${ALIAS}-`)) {\n const rawKey = ALIAS ? attrKey.slice(ALIAS.length + 1) : attrKey\n const [namePart, ...rawModifiers] = rawKey.split('__')\n const [pluginName, key] = namePart.split(/:(.+)/)\n const plugin = attributePlugins.get(pluginName)\n if ((!onlyNew || queuedAttributeNames.has(pluginName)) && plugin) {\n const ctx = {\n el,\n rawKey,\n mods: new Map(),\n error: error.bind(0, {\n plugin: { type: 'attribute', name: plugin.name },\n element: { id: el.id, tag: el.tagName },\n expression: { rawKey, key, value },\n }),\n key,\n value,\n rx: undefined,\n } as AttributeContext\n\n const keyReq =\n (plugin.requirement &&\n (typeof plugin.requirement === 'string'\n ? plugin.requirement\n : plugin.requirement.key)) ||\n 'allowed'\n const valueReq =\n (plugin.requirement &&\n (typeof plugin.requirement === 'string'\n ? plugin.requirement\n : plugin.requirement.value)) ||\n 'allowed'\n\n if (key) {\n if (keyReq === 'denied') {\n throw ctx.error('KeyNotAllowed')\n }\n } else if (keyReq === 'must') {\n throw ctx.error('KeyRequired')\n }\n\n if (value) {\n if (valueReq === 'denied') {\n throw ctx.error('ValueNotAllowed')\n }\n } else if (valueReq === 'must') {\n throw ctx.error('ValueRequired')\n }\n\n if (keyReq === 'exclusive' || valueReq === 'exclusive') {\n if (key && value) {\n throw ctx.error('KeyAndValueProvided')\n }\n if (!key && !value) {\n throw ctx.error('KeyOrValueRequired')\n }\n }\n\n if (value) {\n let cachedRx: GenRxFn\n ctx.rx = (...args: any[]) => {\n if (!cachedRx) {\n cachedRx = genRx(value, {\n returnsValue: plugin.returnsValue,\n argNames: plugin.argNames,\n })\n }\n return cachedRx(el, ...args)\n }\n }\n\n for (const rawMod of rawModifiers) {\n const [label, ...mod] = rawMod.split('.')\n ctx.mods.set(label, new Set(mod))\n }\n\n const cleanup = plugin.apply(ctx)\n if (cleanup) {\n let cleanups = removals.get(el)\n if (cleanups) {\n cleanups.get(rawKey)?.()\n } else {\n cleanups = new Map()\n removals.set(el, cleanups)\n }\n cleanups.set(rawKey, cleanup)\n }\n }\n }\n}\n\ntype GenRxOptions = {\n returnsValue?: boolean\n argNames?: string[]\n}\n\ntype GenRxFn = (el: HTMLOrSVG, ...args: any[]) => T\n\nconst genRx = (\n value: string,\n { returnsValue = false, argNames = [] }: GenRxOptions = {},\n): GenRxFn => {\n let expr = ''\n if (returnsValue) {\n // This regex allows Datastar expressions to support nested\n // regex and strings that contain ; without breaking.\n //\n // Each of these regex defines a block type we want to match\n // (importantly we ignore the content within these blocks):\n //\n // regex \\/(\\\\\\/|[^\\/])*\\/\n // double quotes \"(\\\\\"|[^\\\"])*\"\n // single quotes '(\\\\'|[^'])*'\n // ticks `(\\\\`|[^`])*`\n // iife \\(\\s*((function)\\s*\\(\\s*\\)|(\\(\\s*\\))\\s*=>)\\s*(?:\\{[\\s\\S]*?\\}|[^;)\\{]*)\\s*\\)\\s*\\(\\s*\\)\n //\n // The iife support is (intentionally) limited. It only supports\n // function and arrow syntax with no arguments, and no nested IIFEs.\n //\n // We also want to match the non delimiter part of statements\n // note we only support ; statement delimiters:\n //\n // [^;]\n //\n const statementRe =\n /(\\/(\\\\\\/|[^/])*\\/|\"(\\\\\"|[^\"])*\"|'(\\\\'|[^'])*'|`(\\\\`|[^`])*`|\\(\\s*((function)\\s*\\(\\s*\\)|(\\(\\s*\\))\\s*=>)\\s*(?:\\{[\\s\\S]*?\\}|[^;){]*)\\s*\\)\\s*\\(\\s*\\)|[^;])+/gm\n const statements = value.trim().match(statementRe)\n if (statements) {\n const lastIdx = statements.length - 1\n const last = statements[lastIdx].trim()\n if (!last.startsWith('return')) {\n statements[lastIdx] = `return (${last});`\n }\n expr = statements.join(';\\n')\n }\n } else {\n expr = value.trim()\n }\n\n // Ignore any escaped values\n const escaped = new Map()\n const escapeRe = RegExp(`(?:${DSP})(.*?)(?:${DSS})`, 'gm')\n let counter = 0\n for (const match of expr.matchAll(escapeRe)) {\n const k = match[1]\n const v = `__escaped${counter++}`\n escaped.set(v, k)\n expr = expr.replace(DSP + k + DSS, v)\n }\n\n // Replace signal references with bracket notation\n // Examples:\n // $count -> $['count']\n // $count-- -> $['count']--\n // $foo.bar -> $['foo']['bar']\n // $foo-bar -> $['foo-bar']\n // $foo.bar-baz -> $['foo']['bar-baz']\n // $foo-$bar -> $['foo']-$['bar']\n // $arr[$index] -> $['arr'][$['index']]\n // $['foo'] -> $['foo']\n // $foo[obj.bar] -> $['foo'][obj.bar]\n // $foo['bar.baz'] -> $['foo']['bar.baz']\n // $123 -> $['123']\n // $foo.0.name -> $['foo']['0']['name']\n\n expr = expr\n // $['x'] -> $x (normalize existing bracket notation)\n .replace(/\\$\\['([a-zA-Z_$\\d][\\w$]*)'\\]/g, '$$$1')\n // $x -> $['x'] (including dots and hyphens)\n .replace(/\\$([a-zA-Z_\\d]\\w*(?:[.-]\\w+)*)/g, (_, signalName) =>\n signalName\n .split('.')\n .reduce((acc: string, part: string) => `${acc}['${part}']`, '$'),\n )\n // [$x] -> [$['x']] ($ inside brackets)\n .replace(\n /\\[(\\$[a-zA-Z_\\d]\\w*)\\]/g,\n (_, varName) => `[$['${varName.slice(1)}']]`,\n )\n\n expr = expr.replaceAll(/@(\\w+)\\(/g, '__action(\"$1\",evt,')\n\n // Replace any escaped values\n for (const [k, v] of escaped) {\n expr = expr.replace(k, v)\n }\n\n try {\n const fn = Function('el', '$', '__action', 'evt', ...argNames, expr)\n return (el: HTMLOrSVG, ...args: any[]) => {\n const action = (name: string, evt: Event | undefined, ...args: any[]) => {\n const err = error.bind(0, {\n plugin: { type: 'action', name },\n element: { id: el.id, tag: el.tagName },\n expression: {\n fnContent: expr,\n value,\n },\n })\n const fn = actions[name]\n if (fn) {\n return fn(\n {\n el,\n evt,\n error: err,\n },\n ...args,\n )\n }\n throw err('UndefinedAction')\n }\n try {\n return fn(el, root, action, undefined, ...args)\n } catch (e: any) {\n console.error(e)\n throw error(\n {\n element: { id: el.id, tag: el.tagName },\n expression: {\n fnContent: expr,\n value,\n },\n error: e.message,\n },\n 'ExecuteExpression',\n )\n }\n }\n } catch (e: any) {\n console.error(e)\n throw error(\n {\n expression: {\n fnContent: expr,\n value,\n },\n error: e.message,\n },\n 'GenerateExpression',\n )\n }\n}\n", "import { isHTMLOrSVG } from '@utils/dom'\nimport { aliasify } from '@utils/text'\n\nconst ctxIdMap = new Map>()\nconst ctxPersistentIds = new Set()\nconst oldIdTagNameMap = new Map()\nconst duplicateIds = new Set()\nconst ctxPantry = document.createElement('div')\nctxPantry.hidden = true\n\nconst aliasedIgnoreMorph = aliasify('ignore-morph')\nconst aliasedIgnoreMorphAttr = `[${aliasedIgnoreMorph}]`\nexport const morph = (\n oldElt: Element | ShadowRoot,\n newContent: DocumentFragment | Element,\n mode: 'outer' | 'inner' = 'outer',\n): void => {\n if (\n (isHTMLOrSVG(oldElt) &&\n isHTMLOrSVG(newContent) &&\n oldElt.hasAttribute(aliasedIgnoreMorph) &&\n newContent.hasAttribute(aliasedIgnoreMorph)) ||\n oldElt.parentElement?.closest(aliasedIgnoreMorphAttr)\n ) {\n return\n }\n\n const normalizedElt = document.createElement('div')\n normalizedElt.append(newContent)\n document.body.insertAdjacentElement('afterend', ctxPantry)\n\n // Computes the set of IDs that persist between the two contents excluding duplicates\n const oldIdElements = oldElt.querySelectorAll('[id]')\n for (const { id, tagName } of oldIdElements) {\n if (oldIdTagNameMap.has(id)) {\n duplicateIds.add(id)\n } else {\n oldIdTagNameMap.set(id, tagName)\n }\n }\n if (oldElt instanceof Element && oldElt.id) {\n if (oldIdTagNameMap.has(oldElt.id)) {\n duplicateIds.add(oldElt.id)\n } else {\n oldIdTagNameMap.set(oldElt.id, oldElt.tagName)\n }\n }\n\n ctxPersistentIds.clear()\n const newIdElements = normalizedElt.querySelectorAll('[id]')\n for (const { id, tagName } of newIdElements) {\n if (ctxPersistentIds.has(id)) {\n duplicateIds.add(id)\n } else if (oldIdTagNameMap.get(id) === tagName) {\n ctxPersistentIds.add(id)\n }\n }\n\n for (const id of duplicateIds) {\n ctxPersistentIds.delete(id)\n }\n\n oldIdTagNameMap.clear()\n duplicateIds.clear()\n ctxIdMap.clear()\n\n const parent = mode === 'outer' ? oldElt.parentElement! : oldElt\n populateIdMapWithTree(parent, oldIdElements)\n populateIdMapWithTree(normalizedElt, newIdElements)\n\n morphChildren(\n parent,\n normalizedElt,\n mode === 'outer' ? oldElt : null,\n oldElt.nextSibling,\n )\n\n ctxPantry.remove()\n}\n\n// This is the core algorithm for matching up children.\n// The idea is to use ID sets to try to match up nodes as faithfully as possible.\n// We greedily match, which allows us to keep the algorithm fast,\n// but by using ID sets, we are able to better match up with content deeper in the DOM.\nconst morphChildren = (\n oldParent: Element | ShadowRoot, // the old content that we are merging the new content into\n newParent: Element, // the parent element of the new content\n insertionPoint: Node | null = null, // the point in the DOM we start morphing at (defaults to first child)\n endPoint: Node | null = null, // the point in the DOM we stop morphing at (defaults to after last child)\n): void => {\n // normalize\n if (\n oldParent instanceof HTMLTemplateElement &&\n newParent instanceof HTMLTemplateElement\n ) {\n // we can pretend the DocumentElement is an Element\n oldParent = oldParent.content as unknown as Element\n newParent = newParent.content as unknown as Element\n }\n insertionPoint ??= oldParent.firstChild\n\n // run through all the new content\n for (const newChild of newParent.childNodes) {\n // once we reach the end of the old parent content skip to the end and insert the rest\n if (insertionPoint && insertionPoint !== endPoint) {\n const bestMatch = findBestMatch(newChild, insertionPoint, endPoint)\n if (bestMatch) {\n // if the node to morph is not at the insertion point then remove/move up to it\n if (bestMatch !== insertionPoint) {\n let cursor: Node | null = insertionPoint\n // Remove nodes between the start and end nodes\n while (cursor && cursor !== bestMatch) {\n const tempNode = cursor\n cursor = cursor.nextSibling\n removeNode(tempNode)\n }\n }\n morphNode(bestMatch, newChild)\n insertionPoint = bestMatch.nextSibling\n continue\n }\n }\n\n // if the matching node is elsewhere in the original content\n if (newChild instanceof Element && ctxPersistentIds.has(newChild.id)) {\n // move it and all its children here and morph, will always be found\n // Search for an element by ID within the document and pantry, and move it using moveBefore.\n const movedChild = document.getElementById(newChild.id) as Element\n\n // Removes an element from its ancestors' ID maps.\n // This is needed when an element is moved from the \"future\" via `moveBeforeId`.\n // Otherwise, its erstwhile ancestors could be mistakenly moved to the pantry rather than being deleted,\n // preventing their removal hooks from being called.\n let current = movedChild\n while ((current = current.parentNode as Element)) {\n const idSet = ctxIdMap.get(current)\n if (idSet) {\n idSet.delete(newChild.id)\n if (!idSet.size) {\n ctxIdMap.delete(current)\n }\n }\n }\n\n moveBefore(oldParent, movedChild, insertionPoint)\n morphNode(movedChild, newChild)\n insertionPoint = movedChild.nextSibling\n continue\n }\n\n // This performs the action of inserting a new node while handling situations where the node contains\n // elements with persistent IDs and possible state info we can still preserve by moving in and then morphing\n if (ctxIdMap.has(newChild)) {\n // node has children with IDs with possible state so create a dummy elt of same type and apply full morph algorithm\n const newEmptyChild = document.createElement(\n (newChild as Element).tagName,\n )\n oldParent.insertBefore(newEmptyChild, insertionPoint)\n morphNode(newEmptyChild, newChild)\n insertionPoint = newEmptyChild.nextSibling\n } else {\n // optimization: no id state to preserve so we can just insert a clone of the newChild and its descendants\n const newClonedChild = document.importNode(newChild, true) // importNode to not mutate newParent\n oldParent.insertBefore(newClonedChild, insertionPoint)\n insertionPoint = newClonedChild.nextSibling\n }\n }\n\n // remove any remaining old nodes that didn't match up with new content\n while (insertionPoint && insertionPoint !== endPoint) {\n const tempNode = insertionPoint\n insertionPoint = insertionPoint.nextSibling\n removeNode(tempNode)\n }\n}\n\n// Scans forward from the startPoint to the endPoint looking for a match for the node.\n// It looks for an id set match first, then a soft match.\n// We abort soft matching if we find two future soft matches, to reduce churn.\nconst findBestMatch = (\n node: Node,\n startPoint: Node | null,\n endPoint: Node | null,\n): Node | null => {\n let bestMatch: Node | null | undefined = null\n let nextSibling = node.nextSibling\n let siblingSoftMatchCount = 0\n let displaceMatchCount = 0\n\n // Max ID matches we are willing to displace in our search\n const nodeMatchCount = ctxIdMap.get(node)?.size || 0\n\n let cursor = startPoint\n while (cursor && cursor !== endPoint) {\n // soft matching is a prerequisite for id set matching\n if (isSoftMatch(cursor, node)) {\n let isIdSetMatch = false\n const oldSet = ctxIdMap.get(cursor)\n const newSet = ctxIdMap.get(node)\n\n if (newSet && oldSet) {\n for (const id of oldSet) {\n // a potential match is an id in the new and old nodes that\n // has not already been merged into the DOM\n // But the newNode content we call this on has not been\n // merged yet and we don't allow duplicate IDs so it is simple\n if (newSet.has(id)) {\n isIdSetMatch = true\n break\n }\n }\n }\n\n if (isIdSetMatch) {\n return cursor // found an id set match, we're done!\n }\n\n // we haven\u2019t yet saved a soft match fallback\n // the current soft match will hard match something else in the future, leave it\n if (!bestMatch && !ctxIdMap.has(cursor)) {\n // optimization: if node can't id set match, we can just return the soft match immediately\n if (!nodeMatchCount) {\n return cursor\n }\n // save this as the fallback if we get through the loop without finding a hard match\n bestMatch = cursor\n }\n }\n\n // check for IDs we may be displaced when matching\n displaceMatchCount += ctxIdMap.get(cursor)?.size || 0\n if (displaceMatchCount > nodeMatchCount) {\n // if we are going to displace more IDs than the node contains then\n // we do not have a good candidate for an ID match, so return\n break\n }\n\n if (bestMatch === null && nextSibling && isSoftMatch(cursor, nextSibling)) {\n // The next new node has a soft match with this node, so\n // increment the count of future soft matches\n siblingSoftMatchCount++\n nextSibling = nextSibling.nextSibling\n\n // If there are two future soft matches, block soft matching for this node to allow\n // future siblings to soft match. This is to reduce churn in the DOM when an element\n // is prepended.\n if (siblingSoftMatchCount >= 2) {\n bestMatch = undefined\n }\n }\n\n cursor = cursor.nextSibling\n }\n\n return bestMatch || null\n}\n\n// ok to cast: if one is not element, `id` and `tagName` will be null and we'll just compare that.\nconst isSoftMatch = (oldNode: Node, newNode: Node): boolean =>\n oldNode.nodeType === newNode.nodeType &&\n (oldNode as Element).tagName === (newNode as Element).tagName &&\n // If oldElt has an `id` with possible state and it doesn\u2019t match newElt.id then avoid morphing.\n // We'll still match an anonymous node with an IDed newElt, though, because if it got this far,\n // its not persistent, and new nodes can't have any hidden state.\n (!(oldNode as Element).id ||\n (oldNode as Element).id === (newNode as Element).id)\n\n// Gets rid of an unwanted DOM node; strategy depends on nature of its reuse:\n// - Persistent nodes will be moved to the pantry for later reuse\n// - Other nodes will have their hooks called, and then are removed\nconst removeNode = (node: Node): void => {\n // are we going to id set match this later?\n ctxIdMap.has(node)\n ? // skip callbacks and move to pantry\n moveBefore(ctxPantry, node, null)\n : // remove for realsies\n node.parentNode?.removeChild(node)\n}\n\n// Moves an element before another element within the same parent.\n// Uses the proposed `moveBefore` API if available (and working), otherwise falls back to `insertBefore`.\n// This is essentially a forward-compat wrapper.\nconst moveBefore: (parentNode: Node, node: Node, after: Node | null) => void =\n // @ts-expect-error\n removeNode.call.bind(ctxPantry.moveBefore ?? ctxPantry.insertBefore)\n\nconst aliasedPreserveAttr = aliasify('preserve-attr')\n\n// syncs the oldNode to the newNode, copying over all attributes and\n// inner element state from the newNode to the oldNode\nconst morphNode = (\n oldNode: Node, // root node to merge content into\n newNode: Node, // new content to merge\n): Node => {\n const type = newNode.nodeType\n\n // if is an element type, sync the attributes from the\n // new node into the new node\n if (type === 1 /* element type */) {\n const oldElt = oldNode as Element\n const newElt = newNode as Element\n if (\n oldElt.hasAttribute(aliasedIgnoreMorph) &&\n newElt.hasAttribute(aliasedIgnoreMorph)\n ) {\n return oldNode\n }\n\n // many bothans died to bring us this information:\n // https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n // https://github.com/choojs/nanomorph/blob/master/lib/morph.js#L113\n if (\n oldElt instanceof HTMLInputElement &&\n newElt instanceof HTMLInputElement &&\n newElt.type !== 'file'\n ) {\n // https://github.com/bigskysoftware/idiomorph/issues/27\n // | old input value | new input value | behaviour |\n // | --------------- | ---------------- | -------------------------------------- |\n // | `null` | `null` | preserve old input value |\n // | some value | the same value | preserve old input value |\n // | some value | `null` | set old input value to `\"\"` |\n // | `null` | some value | set old input value to new input value |\n // | some value | some other value | set old input value to new input value |\n if (newElt.getAttribute('value') !== oldElt.getAttribute('value')) {\n oldElt.value = newElt.getAttribute('value') ?? ''\n }\n } else if (\n oldElt instanceof HTMLTextAreaElement &&\n newElt instanceof HTMLTextAreaElement\n ) {\n if (newElt.value !== oldElt.value) {\n oldElt.value = newElt.value\n }\n if (oldElt.firstChild && oldElt.firstChild.nodeValue !== newElt.value) {\n oldElt.firstChild.nodeValue = newElt.value\n }\n }\n\n const preserveAttrs = (\n (newNode as HTMLElement).getAttribute(aliasedPreserveAttr) ?? ''\n ).split(' ')\n\n for (const { name, value } of newElt.attributes) {\n if (\n oldElt.getAttribute(name) !== value &&\n !preserveAttrs.includes(name)\n ) {\n oldElt.setAttribute(name, value)\n }\n }\n\n for (let i = oldElt.attributes.length - 1; i >= 0; i--) {\n const { name } = oldElt.attributes[i]!\n if (!newElt.hasAttribute(name) && !preserveAttrs.includes(name)) {\n oldElt.removeAttribute(name)\n }\n }\n\n if (!oldElt.isEqualNode(newElt)) {\n morphChildren(oldElt, newElt)\n }\n }\n\n if (type === 8 /* comment */ || type === 3 /* text */) {\n if (oldNode.nodeValue !== newNode.nodeValue) {\n oldNode.nodeValue = newNode.nodeValue\n }\n }\n\n return oldNode\n}\n\n// A bottom-up algorithm that populates a map of Element -> IdSet.\n// The ID set for a given element is the set of all IDs contained within its subtree.\n// As an optimization, we filter these IDs through the given list of persistent IDs,\n// because we don't need to bother considering IDed elements that won't be in the new content.\nconst populateIdMapWithTree = (\n root: Element | ShadowRoot | null,\n elements: Iterable,\n): void => {\n for (const elt of elements) {\n if (ctxPersistentIds.has(elt.id)) {\n let current: Element | null = elt\n // walk up the parent hierarchy of that element, adding the ID of element to the parent's ID set\n while (current && current !== root) {\n let idSet = ctxIdMap.get(current)\n // if the ID set doesn\u2019t exist, create it and insert it in the map\n if (!idSet) {\n idSet = new Set()\n ctxIdMap.set(current, idSet)\n }\n idSet.add(elt.id)\n current = current.parentElement\n }\n }\n }\n}\n", "// Icon: ion:eye\n// Slug: Access signals without subscribing to changes.\n// Description: Allows accessing signals without subscribing to their changes in expressions.\n\nimport { action } from '@engine'\nimport { startPeeking, stopPeeking } from '@engine/signals'\n\naction({\n name: 'peek',\n apply(_, fn: () => any) {\n startPeeking()\n try {\n return fn()\n } finally {\n stopPeeking()\n }\n },\n})\n", "// Icon: ion:checkmark-round\n// Slug: Sets the value of all matching signals.\n// Description: Sets the value of all matching signals (or all signals if no filter is used) to the expression provided in the first argument.\n\nimport { action } from '@engine'\nimport {\n filtered,\n mergePatch,\n startPeeking,\n stopPeeking,\n} from '@engine/signals'\nimport type { SignalFilterOptions } from '@engine/types'\nimport { updateLeaves } from '@utils/paths'\n\naction({\n name: 'setAll',\n apply(_, value: any, filter: SignalFilterOptions) {\n // peek because in an effect you would be subscribing to signals and then setting them which\n // would cause an infinite loop and why would you want to infinite loop on purpose\n startPeeking()\n const masked = filtered(filter)\n updateLeaves(masked, () => value)\n mergePatch(masked)\n stopPeeking()\n },\n})\n", "// Icon: material-symbols:toggle-off\n// Slug: Toggles the value of all matching signals.\n// Description: Toggles the boolean value of all matching signals (or all signals if no filter is used).\n\nimport { action } from '@engine'\nimport {\n filtered,\n mergePatch,\n startPeeking,\n stopPeeking,\n} from '@engine/signals'\nimport type { SignalFilterOptions } from '@engine/types'\nimport { updateLeaves } from '@utils/paths'\n\naction({\n name: 'toggleAll',\n apply(_, filter: SignalFilterOptions) {\n // peek because in an effect you would be subscribing to signals and then setting them which\n // would cause an infinite loop and why would you want to infinite loop on purpose\n startPeeking()\n const masked = filtered(filter)\n updateLeaves(masked, (oldValue: any) => !oldValue)\n mergePatch(masked)\n stopPeeking()\n },\n})\n", "// Icon: ion:eye\n// Slug: Access signals without subscribing to changes.\n// Description: Allows accessing signals without subscribing to their changes in expressions.\n\nimport { action } from '@engine'\nimport { DATASTAR_FETCH_EVENT } from '@engine/consts'\nimport { filtered } from '@engine/signals'\nimport type {\n DatastarFetchEvent,\n HTMLOrSVG,\n SignalFilterOptions,\n} from '@engine/types'\nimport { kebab } from '@utils/text'\n\nconst fetchAbortControllers = new WeakMap()\n\nconst createHttpMethod = (name: string, method: string): void =>\n action({\n name,\n apply: async (\n { el, evt, error },\n url: string,\n {\n selector,\n headers: userHeaders,\n contentType = 'json',\n filterSignals: { include = /.*/, exclude = /(^|\\.)_/ } = {},\n openWhenHidden = false,\n retryInterval = 1000,\n retryScaler = 2,\n retryMaxWaitMs = 30_000,\n retryMaxCount = 10,\n requestCancellation = 'auto',\n }: FetchArgs = {},\n ) => {\n const controller =\n requestCancellation instanceof AbortController\n ? requestCancellation\n : new AbortController()\n const isDisabled = requestCancellation === 'disabled'\n if (!isDisabled) {\n const oldController = fetchAbortControllers.get(el)\n if (oldController) {\n oldController.abort()\n // wait one tick for FINISHED to fire\n await Promise.resolve()\n }\n }\n\n if (!isDisabled && !(requestCancellation instanceof AbortController)) {\n fetchAbortControllers.set(el, controller)\n }\n\n try {\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const removed of mutation.removedNodes) {\n if (removed === el) {\n controller.abort()\n cleanupFn()\n }\n }\n }\n })\n if (el.parentNode) {\n observer.observe(el.parentNode, { childList: true })\n }\n\n let cleanupFn = () => {\n observer.disconnect()\n }\n\n try {\n if (!url?.length) {\n throw error('FetchNoUrlProvided', { action })\n }\n\n const initialHeaders: Record = {\n Accept: 'text/event-stream, text/html, application/json',\n 'Datastar-Request': true,\n }\n if (contentType === 'json') {\n initialHeaders['Content-Type'] = 'application/json'\n }\n const headers = Object.assign({}, initialHeaders, userHeaders)\n\n // We ignore the content-type header if using form data\n // if missing the boundary will be set automatically\n\n const req: FetchEventSourceInit = {\n method,\n headers,\n openWhenHidden,\n retryInterval,\n retryScaler,\n retryMaxWaitMs,\n retryMaxCount,\n signal: controller.signal,\n onopen: async (response: Response) => {\n if (response.status >= 400)\n dispatchFetch(ERROR, el, { status: response.status.toString() })\n },\n onmessage: (evt) => {\n if (!evt.event.startsWith('datastar')) return\n const type = evt.event\n const argsRawLines: Record = {}\n\n for (const line of evt.data.split('\\n')) {\n const i = line.indexOf(' ')\n const k = line.slice(0, i)\n const v = line.slice(i + 1)\n ;(argsRawLines[k] ||= []).push(v)\n }\n\n const argsRaw = Object.fromEntries(\n Object.entries(argsRawLines).map(([k, v]) => [k, v.join('\\n')]),\n )\n\n dispatchFetch(type, el, argsRaw)\n },\n onerror: (error) => {\n if (isWrongContent(error)) {\n // don't retry if the content-type is wrong\n throw error('FetchExpectedTextEventStream', { url })\n }\n // do nothing and it will retry\n if (error) {\n console.error(error.message)\n dispatchFetch(RETRYING, el, { message: error.message })\n }\n },\n }\n\n const urlInstance = new URL(url, document.baseURI)\n const queryParams = new URLSearchParams(urlInstance.search)\n\n if (contentType === 'json') {\n const res = JSON.stringify(filtered({ include, exclude }))\n if (method === 'GET') {\n queryParams.set('datastar', res)\n } else {\n req.body = res\n }\n } else if (contentType === 'form') {\n const formEl = (\n selector ? document.querySelector(selector) : el.closest('form')\n ) as HTMLFormElement\n if (!formEl) {\n throw error('FetchFormNotFound', { action, selector })\n }\n\n // Validate the form\n if (!formEl.checkValidity()) {\n formEl.reportValidity()\n cleanupFn()\n return\n }\n\n // Collect the form data\n\n const formData = new FormData(formEl)\n let submitter = el as HTMLElement | null\n\n if (el === formEl && evt instanceof SubmitEvent) {\n // Get the submitter from the event\n submitter = evt.submitter\n } else {\n // Prevent the form being submitted\n const preventDefault = (evt: Event) => evt.preventDefault()\n formEl.addEventListener('submit', preventDefault)\n cleanupFn = () => {\n formEl.removeEventListener('submit', preventDefault)\n observer.disconnect()\n }\n }\n\n // Append the value of the form submitter if it is a button with a name\n if (submitter instanceof HTMLButtonElement) {\n const name = submitter.getAttribute('name')\n if (name) formData.append(name, submitter.value)\n }\n\n const multipart =\n formEl.getAttribute('enctype') === 'multipart/form-data'\n // Leave the `Content-Type` header empty for multipart encoding so the browser can set it automatically with the correct boundary\n if (!multipart) {\n headers['Content-Type'] = 'application/x-www-form-urlencoded'\n }\n\n const formParams = new URLSearchParams(formData as any)\n if (method === 'GET') {\n for (const [key, value] of formParams) {\n queryParams.append(key, value)\n }\n } else if (multipart) {\n req.body = formData\n } else {\n req.body = formParams\n }\n } else {\n throw error('FetchInvalidContentType', { action, contentType })\n }\n\n dispatchFetch(STARTED, el, {})\n urlInstance.search = queryParams.toString()\n\n try {\n await fetchEventSource(urlInstance.toString(), el, req)\n } catch (e: any) {\n if (!isWrongContent(e)) {\n throw error('FetchFailed', { method, url, error: e.message })\n }\n // exit gracefully and do nothing if the content-type is wrong\n // this can happen if the client is sending a request\n // where no response is expected, and they haven\u2019t\n // set the content-type to text/event-stream\n }\n } finally {\n dispatchFetch(FINISHED, el, {})\n cleanupFn()\n }\n } finally {\n if (fetchAbortControllers.get(el) === controller) {\n fetchAbortControllers.delete(el)\n }\n }\n },\n })\n\ncreateHttpMethod('delete', 'DELETE')\ncreateHttpMethod('get', 'GET')\ncreateHttpMethod('patch', 'PATCH')\ncreateHttpMethod('post', 'POST')\ncreateHttpMethod('put', 'PUT')\n\nexport const STARTED = 'started'\nexport const FINISHED = 'finished'\nexport const ERROR = 'error'\nexport const RETRYING = 'retrying'\nexport const RETRIES_FAILED = 'retries-failed'\n\nconst dispatchFetch = (\n type: string,\n el: HTMLOrSVG,\n argsRaw: Record,\n) =>\n document.dispatchEvent(\n new CustomEvent(DATASTAR_FETCH_EVENT, {\n detail: { type, el, argsRaw },\n }),\n )\n\nconst isWrongContent = (err: any) => `${err}`.includes('text/event-stream')\n\ntype ResponseOverrides =\n | {\n selector?: string\n mode?: string\n useViewTransition?: boolean\n }\n | {\n onlyIfMissing?: boolean\n }\n\nexport type FetchArgs = {\n headers?: Record\n openWhenHidden?: boolean\n retryInterval?: number\n retryScaler?: number\n retryMaxWaitMs?: number\n retryMaxCount?: number\n responseOverrides?: ResponseOverrides\n contentType?: 'json' | 'form'\n filterSignals?: SignalFilterOptions\n selector?: string\n requestCancellation?: 'auto' | 'disabled' | AbortController\n}\n\n// Below originally from https://github.com/Azure/fetch-event-source/blob/main/LICENSE\n\n/**\n * Represents a message sent in an event stream\n * https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format\n */\n\ninterface EventSourceMessage {\n id: string\n event: string\n data: string\n retry?: number\n}\n\n/**\n * Converts a ReadableStream into a callback pattern.\n * @param stream The input ReadableStream.\n * @param onChunk A function that will be called on each new byte chunk in the stream.\n * @returns {Promise} A promise that will be resolved when the stream closes.\n */\nconst getBytes = async (\n stream: ReadableStream,\n onChunk: (arr: Uint8Array) => void,\n): Promise => {\n const reader = stream.getReader()\n let result = await reader.read()\n while (!result.done) {\n onChunk(result.value)\n result = await reader.read()\n }\n}\n\nconst getLines = (onLine: (line: Uint8Array, fieldLength: number) => void) => {\n let buffer: Uint8Array | undefined\n let position: number // current read position\n let fieldLength: number // length of the `field` portion of the line\n let discardTrailingNewline = false\n\n // return a function that can process each incoming byte chunk:\n return (arr: Uint8Array) => {\n if (!buffer) {\n buffer = arr\n position = 0\n fieldLength = -1\n } else {\n // we're still parsing the old line. Append the new bytes into buffer:\n buffer = concat(buffer, arr)\n }\n\n const bufLength = buffer.length\n let lineStart = 0 // index where the current line starts\n while (position < bufLength) {\n if (discardTrailingNewline) {\n if (buffer[position] === 10) lineStart = ++position // skip to next char\n discardTrailingNewline = false\n }\n\n // start looking forward till the end of line:\n let lineEnd = -1 // index of the \\r or \\n char\n for (; position < bufLength && lineEnd === -1; ++position) {\n switch (buffer[position]) {\n case 58: // :\n if (fieldLength === -1) {\n // first colon in line\n fieldLength = position - lineStart\n }\n break\n // @ts-expect-error:7029 \\r case below should fallthrough to \\n:\n // biome-ignore lint/suspicious/noFallthroughSwitchClause: intentional fallthrough for CR to LF\n case 13: // \\r\n discardTrailingNewline = true\n case 10: // \\n\n lineEnd = position\n break\n }\n }\n\n if (lineEnd === -1) break // Wait for the next arr and then continue parsing\n\n // we've reached the line end, send it out:\n onLine(buffer.subarray(lineStart, lineEnd), fieldLength)\n lineStart = position // we're now on the next line\n fieldLength = -1\n }\n\n if (lineStart === bufLength)\n buffer = undefined // we've finished reading it\n else if (lineStart) {\n // Create a new view into buffer beginning at lineStart so we don't\n // need to copy over the previous lines when we get the new arr:\n buffer = buffer.subarray(lineStart)\n position -= lineStart\n }\n }\n}\n\nconst getMessages = (\n onId: (id: string) => void,\n onRetry: (retry: number) => void,\n onMessage?: (msg: EventSourceMessage) => void,\n): ((line: Uint8Array, fieldLength: number) => void) => {\n let message = newMessage()\n const decoder = new TextDecoder()\n\n // return a function that can process each incoming line buffer:\n return (line, fieldLength) => {\n if (!line.length) {\n // empty line denotes end of message. Trigger the callback and start a new message:\n onMessage?.(message)\n message = newMessage()\n } else if (fieldLength > 0) {\n // exclude comments and lines with no values\n // line is of format \":\" or \": \"\n // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation\n const field = decoder.decode(line.subarray(0, fieldLength))\n const valueOffset = fieldLength + (line[fieldLength + 1] === 32 ? 2 : 1)\n const value = decoder.decode(line.subarray(valueOffset))\n\n switch (field) {\n case 'data':\n message.data = message.data ? `${message.data}\\n${value}` : value\n break\n case 'event':\n message.event = value\n break\n case 'id':\n onId((message.id = value))\n break\n case 'retry': {\n const retry = +value\n if (!Number.isNaN(retry)) {\n // per spec, ignore non-integers\n onRetry((message.retry = retry))\n }\n break\n }\n }\n }\n }\n}\n\nconst concat = (a: Uint8Array, b: Uint8Array) => {\n const res = new Uint8Array(a.length + b.length)\n res.set(a)\n res.set(b, a.length)\n return res\n}\n\nconst newMessage = (): EventSourceMessage => ({\n // data, event, and id must be initialized to empty strings:\n // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation\n // retry should be initialized to undefined so we return a consistent shape\n // to the js engine all the time: https://mathiasbynens.be/notes/shapes-ics#takeaways\n data: '',\n event: '',\n id: '',\n retry: undefined,\n})\n\ntype FetchEventSourceInit = RequestInit & {\n headers?: Record\n onopen?: (response: Response) => Promise\n onmessage?: (ev: EventSourceMessage) => void\n onclose?: () => void\n onerror?: (err: any) => number | null | undefined | void\n openWhenHidden?: boolean\n fetch?: typeof fetch\n retryInterval?: number\n retryScaler?: number\n retryMaxWaitMs?: number\n retryMaxCount?: number\n overrides?: ResponseOverrides\n}\n\nconst fetchEventSource = (\n input: RequestInfo,\n el: HTMLOrSVG,\n {\n signal: inputSignal,\n headers: inputHeaders,\n onopen: inputOnOpen,\n onmessage,\n onclose,\n onerror,\n openWhenHidden,\n fetch: inputFetch,\n retryInterval = 1_000,\n retryScaler = 2,\n retryMaxWaitMs = 30_000,\n retryMaxCount = 10,\n overrides,\n ...rest\n }: FetchEventSourceInit,\n): Promise => {\n return new Promise((resolve, reject) => {\n // make a copy of the input headers since we may modify it below:\n const headers: Record = {\n ...inputHeaders,\n }\n\n let curRequestController: AbortController\n const onVisibilityChange = () => {\n curRequestController.abort() // close existing request on every visibility change\n if (!document.hidden) create() // page is now visible again, recreate request.\n }\n\n if (!openWhenHidden) {\n document.addEventListener('visibilitychange', onVisibilityChange)\n }\n\n let retryTimer = 0\n const dispose = () => {\n document.removeEventListener('visibilitychange', onVisibilityChange)\n clearTimeout(retryTimer)\n curRequestController.abort()\n }\n\n // if the incoming signal aborts, dispose resources and resolve:\n inputSignal?.addEventListener('abort', () => {\n dispose()\n resolve() // don't waste time constructing/logging errors\n })\n\n const fetch = inputFetch || window.fetch\n const onopen = inputOnOpen || (() => {})\n\n let retries = 0\n let baseRetryInterval = retryInterval\n const create = async () => {\n curRequestController = new AbortController()\n try {\n const response = await fetch(input, {\n ...rest,\n headers,\n signal: curRequestController.signal,\n })\n\n // on successful connection, reset the retry logic\n retries = 0\n retryInterval = baseRetryInterval\n\n await onopen(response)\n\n const dispatchNonSSE = async (\n dispatchType: string,\n response: Response,\n name: string,\n overrides?: ResponseOverrides,\n ...argNames: string[]\n ) => {\n const argsRaw: Record = {\n [name]: await response.text(),\n }\n for (const n of argNames) {\n let v = response.headers.get(`datastar-${kebab(n)}`)\n if (overrides) {\n const o = (overrides as any)[n]\n if (o) v = typeof o === 'string' ? o : JSON.stringify(o)\n }\n if (v) argsRaw[n] = v\n }\n\n dispatchFetch(dispatchType, el, argsRaw)\n dispose()\n resolve()\n }\n\n const ct = response.headers.get('Content-Type')\n if (ct?.includes('text/html')) {\n return await dispatchNonSSE(\n 'datastar-patch-elements',\n response,\n 'elements',\n overrides,\n 'selector',\n 'mode',\n 'useViewTransition',\n )\n }\n\n if (ct?.includes('application/json')) {\n return await dispatchNonSSE(\n 'datastar-patch-signals',\n response,\n 'signals',\n overrides,\n 'onlyIfMissing',\n )\n }\n\n if (ct?.includes('text/javascript')) {\n const script = document.createElement('script')\n const scriptAttributesHeader = response.headers.get(\n 'datastar-script-attributes',\n )\n\n if (scriptAttributesHeader) {\n for (const [name, value] of Object.entries(\n JSON.parse(scriptAttributesHeader),\n )) {\n script.setAttribute(name, value as string)\n }\n }\n script.textContent = await response.text()\n document.head.appendChild(script)\n dispose()\n return\n }\n\n await getBytes(\n response.body!,\n getLines(\n getMessages(\n (id) => {\n if (id) {\n // signals the id and send it back on the next retry:\n headers['last-event-id'] = id\n } else {\n // don't send the last-event-id header anymore:\n delete headers['last-event-id']\n }\n },\n (retry) => {\n baseRetryInterval = retryInterval = retry\n },\n onmessage,\n ),\n ),\n )\n\n onclose?.()\n dispose()\n resolve()\n } catch (err) {\n if (!curRequestController.signal.aborted) {\n // if we haven\u2019t aborted the request ourselves:\n try {\n // check if we need to retry:\n const interval: any = onerror?.(err) || retryInterval\n clearTimeout(retryTimer)\n retryTimer = setTimeout(create, interval)\n retryInterval = Math.min(\n retryInterval * retryScaler,\n retryMaxWaitMs,\n ) // exponential backoff\n if (++retries >= retryMaxCount) {\n dispatchFetch(RETRIES_FAILED, el, {})\n // we should not retry anymore:\n dispose()\n reject('Max retries reached.') // Max retries reached, check your server or network connection\n } else {\n console.error(\n `Datastar failed to reach ${input.toString()} retrying in ${interval}ms.`,\n )\n }\n } catch (innerErr) {\n // we should not retry anymore:\n dispose()\n reject(innerErr)\n }\n }\n }\n }\n\n create()\n })\n}\n", "// Icon: material-symbols:edit-attributes-outline\n// Slug: Syncs the value of an attribute with an expression.\n// Description: Sets the value of any HTML attribute to an expression, and keeps it in sync.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nattribute({\n name: 'attr',\n requirement: { value: 'must' },\n returnsValue: true,\n apply({ el, key, rx }) {\n const syncAttr = (key: string, val: any) => {\n if (val === '' || val === true) {\n el.setAttribute(key, '')\n } else if (val === false || val == null) {\n el.removeAttribute(key)\n } else if (typeof val === 'string') {\n el.setAttribute(key, val)\n } else {\n el.setAttribute(key, JSON.stringify(val))\n }\n }\n\n const update = key\n ? () => {\n observer.disconnect()\n const val = rx() as string\n syncAttr(key, val)\n observer.observe(el, {\n attributeFilter: [key],\n })\n }\n : () => {\n observer.disconnect()\n const obj = rx() as Record\n const attributeFilter = Object.keys(obj)\n for (const key of attributeFilter) {\n syncAttr(key, obj[key])\n }\n observer.observe(el, {\n attributeFilter,\n })\n }\n\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "// Icon: akar-icons:link-chain\n// Slug: Creates a signal with two-way data binding.\n// Description: Creates a signal (if one doesn\u2019t already exist) and sets up two-way data binding between it and an element\u2019s value.\n\nimport { attribute } from '@engine'\nimport { effect, getPath, mergePaths } from '@engine/signals'\nimport type { Paths } from '@engine/types'\nimport { aliasify, modifyCasing } from '@utils/text'\n\ntype SignalFile = {\n name: string\n contents: string\n mime: string\n}\n\nconst dataURIRegex = /^data:(?[^;]+);base64,(?.*)$/\nconst empty = Symbol('empty')\n\nconst aliasedBind = aliasify('bind')\n\nattribute({\n name: 'bind',\n requirement: 'exclusive',\n apply({ el, key, mods, value, error }) {\n const signalName = key != null ? modifyCasing(key, mods) : value\n\n let get = (el: any, type: string) =>\n type === 'number' ? +el.value : el.value\n\n let set = (value: any) => {\n ;(el as HTMLInputElement).value = `${value}`\n }\n\n if (el instanceof HTMLInputElement) {\n switch (el.type) {\n case 'range':\n case 'number':\n get = (el: any, type: string) =>\n type === 'string' ? el.value : +el.value\n break\n\n case 'checkbox':\n get = (el: HTMLInputElement, type: string) => {\n if (el.value !== 'on') {\n if (type === 'boolean') {\n return el.checked\n } else {\n return el.checked ? el.value : ''\n }\n } else {\n if (type === 'string') {\n return el.checked ? el.value : ''\n } else {\n return el.checked\n }\n }\n }\n set = (value: string | boolean) => {\n el.checked = typeof value === 'string' ? value === el.value : value\n }\n break\n\n case 'radio':\n // Set up radio button name attribute if not present\n if (!el.getAttribute('name')?.length) {\n el.setAttribute('name', signalName)\n }\n\n get = (el: HTMLInputElement, type: string) =>\n el.checked ? (type === 'number' ? +el.value : el.value) : empty\n set = (value: string | number) => {\n el.checked =\n value === (typeof value === 'number' ? +el.value : el.value)\n }\n break\n case 'file': {\n const syncSignal = () => {\n const files = [...(el.files || [])]\n const signalFiles: SignalFile[] = []\n Promise.all(\n files.map(\n (f) =>\n new Promise((resolve) => {\n const reader = new FileReader()\n reader.onload = () => {\n if (typeof reader.result !== 'string') {\n throw error('InvalidFileResultType', {\n resultType: typeof reader.result,\n })\n }\n const match = reader.result.match(dataURIRegex)\n if (!match?.groups) {\n throw error('InvalidDataUri', {\n result: reader.result,\n })\n }\n signalFiles.push({\n name: f.name,\n contents: match.groups.contents,\n mime: match.groups.mime,\n })\n }\n reader.onloadend = () => resolve()\n reader.readAsDataURL(f)\n }),\n ),\n ).then(() => {\n mergePaths([[signalName, signalFiles]])\n })\n }\n\n el.addEventListener('change', syncSignal)\n el.addEventListener('input', syncSignal)\n\n return () => {\n el.removeEventListener('change', syncSignal)\n el.removeEventListener('input', syncSignal)\n }\n }\n }\n } else if (el instanceof HTMLSelectElement) {\n if (el.multiple) {\n const typeMap = new Map()\n get = (el: HTMLSelectElement) =>\n [...el.selectedOptions].map((option) => {\n const type = typeMap.get(option.value)\n return type === 'string' || type == null\n ? option.value\n : +option.value\n })\n\n set = (value: (string | number)[]) => {\n for (const option of el.options) {\n if (value.includes(option.value)) {\n typeMap.set(option.value, 'string')\n option.selected = true\n } else if (value.includes(+option.value)) {\n typeMap.set(option.value, 'number')\n option.selected = true\n } else {\n option.selected = false\n }\n }\n }\n }\n } else if (el instanceof HTMLTextAreaElement) {\n // default case\n } else {\n // web component\n get = (el: Element) =>\n 'value' in el ? el.value : el.getAttribute('value')\n set = (value: any) => {\n if ('value' in el) {\n el.value = value\n } else {\n el.setAttribute('value', value)\n }\n }\n }\n\n const initialValue = getPath(signalName)\n const type = typeof initialValue\n\n let path = signalName\n if (\n Array.isArray(initialValue) &&\n !(el instanceof HTMLSelectElement && el.multiple)\n ) {\n const signalNameKebab = key ? key : value!\n const inputs = document.querySelectorAll(\n `[${aliasedBind}\\\\:${CSS.escape(signalNameKebab)}],[${aliasedBind}=\"${CSS.escape(signalNameKebab)}\"]`,\n ) as NodeListOf\n\n const paths: Paths = []\n let i = 0\n for (const input of inputs) {\n paths.push([`${path}.${i}`, get(input, 'none')])\n\n if (el === input) {\n break\n }\n i++\n }\n mergePaths(paths, { ifMissing: true })\n path = `${path}.${i}`\n } else {\n mergePaths([[path, get(el, type)]], {\n ifMissing: true,\n })\n }\n\n const syncSignal = () => {\n const signalValue = getPath(path)\n if (signalValue != null) {\n const value = get(el, typeof signalValue)\n if (value !== empty) {\n mergePaths([[path, value]])\n }\n }\n }\n\n el.addEventListener('input', syncSignal)\n el.addEventListener('change', syncSignal)\n const cleanup = effect(() => {\n set(getPath(path))\n })\n\n return () => {\n cleanup()\n el.removeEventListener('input', syncSignal)\n el.removeEventListener('change', syncSignal)\n }\n },\n})\n", "// Icon: ic:baseline-format-paint\n// Slug: Adds or removes a class based on an expression.\n// Description: Adds or removes a class to or from an element based on an expression.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'class',\n requirement: {\n value: 'must',\n },\n returnsValue: true,\n apply({ key, el, mods, rx }) {\n if (key) {\n key = modifyCasing(key, mods, 'kebab')\n }\n\n const callback = () => {\n observer.disconnect()\n\n const classes = key\n ? { [key]: rx() as boolean }\n : (rx() as Record)\n\n for (const k in classes) {\n const classNames = k.split(/\\s+/).filter((cn) => cn.length > 0)\n if (classes[k]) {\n for (const name of classNames) {\n if (!el.classList.contains(name)) {\n el.classList.add(name)\n }\n }\n } else {\n for (const name of classNames) {\n if (el.classList.contains(name)) {\n el.classList.remove(name)\n }\n }\n }\n }\n\n observer.observe(el, { attributeFilter: ['class'] })\n }\n\n const observer = new MutationObserver(callback)\n const cleanup = effect(callback)\n\n return () => {\n observer.disconnect()\n cleanup()\n\n const classes = key\n ? { [key]: rx() as boolean }\n : (rx() as Record)\n\n for (const k in classes) {\n const classNames = k.split(/\\s+/).filter((cn) => cn.length > 0)\n for (const name of classNames) {\n el.classList.remove(name)\n }\n }\n }\n },\n})\n", "// Icon: streamline-ultimate:wifi-signal-2\n// Slug: Creates a computed signal.\n// Description: Creates a signal that is computed based on an expression.\n\nimport { attribute } from '@engine'\nimport { computed, mergePaths, mergePatch } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\nimport { updateLeaves } from '@utils/paths'\n\nattribute({\n name: 'computed',\n requirement: {\n value: 'must',\n },\n returnsValue: true,\n apply({ key, mods, rx, error }) {\n if (key) {\n mergePaths([[modifyCasing(key, mods), computed(rx)]])\n } else {\n const patch = Object.assign({}, rx() as Record any>)\n updateLeaves(patch, (old) => {\n if (typeof old === 'function') {\n return computed(old)\n } else {\n throw error('ComputedExpectedFunction')\n }\n })\n mergePatch(patch)\n }\n },\n})\n", "// Icon: oui:security-signal\n// Slug: Executes an expression when signals change.\n// Description: Executes an expression on page load and whenever any signals in the expression change.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nattribute({\n name: 'effect',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply: ({ rx }) => effect(rx),\n})\n", "// Icon: streamline:signal-loading-remix\n// Slug: Creates an indicator for whether an SSE request is in flight.\n// Description: Creates a signal and sets its value to `true` while an SSE request request is in flight, otherwise `false`.\n\nimport { attribute } from '@engine'\nimport { DATASTAR_FETCH_EVENT } from '@engine/consts'\nimport { mergePaths } from '@engine/signals'\nimport type { DatastarFetchEvent } from '@engine/types'\nimport { FINISHED, STARTED } from '@plugins/actions/fetch'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'indicator',\n requirement: 'exclusive',\n apply({ el, key, mods, value }) {\n const signalName = key != null ? modifyCasing(key, mods) : value\n\n mergePaths([[signalName, false]])\n\n const watcher = ((event: CustomEvent) => {\n const { type, el: elt } = event.detail\n if (elt !== el) {\n return\n }\n switch (type) {\n case STARTED:\n mergePaths([[signalName, true]])\n break\n case FINISHED:\n mergePaths([[signalName, false]])\n break\n }\n }) as EventListener\n document.addEventListener(DATASTAR_FETCH_EVENT, watcher)\n return () => {\n mergePaths([[signalName, false]])\n document.removeEventListener(DATASTAR_FETCH_EVENT, watcher)\n }\n },\n})\n", "// Icon: si:json-fill\n// Slug: Outputs a JSON stringified version of signals.\n// Description: Sets the text content of an element to a reactive JSON stringified version of signals.\n\nimport { attribute } from '@engine'\nimport { effect, filtered } from '@engine/signals'\nimport type { SignalFilterOptions } from '@engine/types'\nimport { jsStrToObject } from '@utils/text'\n\nattribute({\n name: 'json-signals',\n requirement: {\n key: 'denied',\n },\n apply({ el, value, mods }) {\n const spaces = mods.has('terse') ? 0 : 2\n let filters: SignalFilterOptions = {}\n if (value) {\n filters = jsStrToObject(value)\n }\n\n const callback = () => {\n observer.disconnect()\n el.textContent = JSON.stringify(filtered(filters), null, spaces)\n observer.observe(el, {\n childList: true,\n characterData: true,\n subtree: true,\n })\n }\n const observer = new MutationObserver(callback)\n const cleanup = effect(callback)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "export const tagToMs = (args: Set) => {\n if (!args || args.size <= 0) return 0\n for (const arg of args) {\n if (arg.endsWith('ms')) {\n return +arg.replace('ms', '')\n }\n if (arg.endsWith('s')) {\n return +arg.replace('s', '') * 1000\n }\n try {\n return Number.parseFloat(arg)\n } catch (_) {}\n }\n return 0\n}\n\nexport const tagHas = (\n tags: Set,\n tag: string,\n defaultValue = false,\n) => {\n if (!tags) return defaultValue\n return tags.has(tag.toLowerCase())\n}\n\nexport const tagFirst = (tags?: Set, defaultValue = ''): string => {\n if (tags && tags.size > 0) {\n for (const tag of tags) {\n return tag\n }\n }\n return defaultValue\n}\n", "import type { EventCallbackHandler, Modifiers } from '@engine/types'\nimport { tagHas, tagToMs } from '@utils/tags'\n\nexport const delay = (\n callback: EventCallbackHandler,\n wait: number,\n): EventCallbackHandler => {\n return (...args: any[]) => {\n setTimeout(() => {\n callback(...args)\n }, wait)\n }\n}\n\nexport const debounce = (\n callback: EventCallbackHandler,\n wait: number,\n leading = false,\n trailing = true,\n): EventCallbackHandler => {\n let timer = 0\n return (...args: any[]) => {\n timer && clearTimeout(timer)\n\n if (leading && !timer) {\n callback(...args)\n }\n\n timer = setTimeout(() => {\n if (trailing) {\n callback(...args)\n }\n timer && clearTimeout(timer)\n timer = 0\n }, wait)\n }\n}\n\nexport const throttle = (\n callback: EventCallbackHandler,\n wait: number,\n leading = true,\n trailing = false,\n): EventCallbackHandler => {\n let waiting = false\n\n return (...args: any[]) => {\n if (waiting) return\n\n if (leading) {\n callback(...args)\n }\n\n waiting = true\n setTimeout(() => {\n if (trailing) {\n callback(...args)\n }\n waiting = false\n }, wait)\n }\n}\n\nexport const modifyTiming = (\n callback: EventCallbackHandler,\n mods: Modifiers,\n): EventCallbackHandler => {\n const delayArgs = mods.get('delay')\n if (delayArgs) {\n const wait = tagToMs(delayArgs)\n callback = delay(callback, wait)\n }\n\n const debounceArgs = mods.get('debounce')\n if (debounceArgs) {\n const wait = tagToMs(debounceArgs)\n const leading = tagHas(debounceArgs, 'leading', false)\n const trailing = !tagHas(debounceArgs, 'notrailing', false)\n callback = debounce(callback, wait, leading, trailing)\n }\n\n const throttleArgs = mods.get('throttle')\n if (throttleArgs) {\n const wait = tagToMs(throttleArgs)\n const leading = !tagHas(throttleArgs, 'noleading', false)\n const trailing = tagHas(throttleArgs, 'trailing', false)\n callback = throttle(callback, wait, leading, trailing)\n }\n\n return callback\n}\n", "import type { EventCallbackHandler, Modifiers } from '@engine/types'\n\nexport const supportsViewTransitions = !!document.startViewTransition\n\nexport const modifyViewTransition = (\n callback: EventCallbackHandler,\n mods: Modifiers,\n): EventCallbackHandler => {\n if (mods.has('viewtransition') && supportsViewTransitions) {\n const cb = callback // I hate javascript\n callback = (...args: any[]) =>\n document.startViewTransition(() => cb(...args))\n }\n\n return callback\n}\n", "// Icon: material-symbols:mail\n// Slug: Attaches an event listener to an element.\n// Description: Attaches an event listener to an element, executing an expression whenever the event is triggered.\n\nimport { attribute } from '@engine'\nimport {\n DATASTAR_FETCH_EVENT,\n DATASTAR_SIGNAL_PATCH_EVENT,\n} from '@engine/consts'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\nimport { modifyTiming } from '@utils/timing'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nattribute({\n name: 'on',\n requirement: 'must',\n argNames: ['evt'],\n apply({ el, key, mods, rx }) {\n let target: Element | Window | Document = el\n if (mods.has('window')) target = window\n let callback = (evt?: Event) => {\n if (evt) {\n if (mods.has('prevent')) {\n evt.preventDefault()\n }\n if (mods.has('stop')) {\n evt.stopPropagation()\n }\n }\n beginBatch()\n rx(evt)\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n callback = modifyTiming(callback, mods)\n const evtListOpts: AddEventListenerOptions = {\n capture: mods.has('capture'),\n passive: mods.has('passive'),\n once: mods.has('once'),\n }\n if (mods.has('outside')) {\n target = document\n const cb = callback\n callback = (evt?: Event) => {\n if (!el.contains(evt?.target as HTMLElement)) {\n cb(evt)\n }\n }\n }\n const eventName = modifyCasing(key, mods, 'kebab')\n // Listen for Datastar events on the document\n if (\n eventName === DATASTAR_FETCH_EVENT ||\n eventName === DATASTAR_SIGNAL_PATCH_EVENT\n ) {\n target = document\n }\n // Prevent default on form submit events\n if (el instanceof HTMLFormElement && eventName === 'submit') {\n const cb = callback\n callback = (evt?: Event) => {\n evt?.preventDefault()\n cb(evt)\n }\n }\n target.addEventListener(eventName, callback, evtListOpts)\n return () => {\n target.removeEventListener(eventName, callback)\n }\n },\n})\n", "// Icon: mdi-light:vector-intersection\n// Slug: Runs an expression on intersection.\n// Description: Runs an expression when the element intersects with the viewport.\n\nimport { attribute } from '@engine'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport type { HTMLOrSVG } from '@engine/types'\nimport { modifyTiming } from '@utils/timing'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nconst once = new WeakSet()\n\nattribute({\n name: 'on-intersect',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply({ el, mods, rx }) {\n let callback = () => {\n beginBatch()\n rx()\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n callback = modifyTiming(callback, mods)\n const options = { threshold: 0 }\n if (mods.has('full')) {\n options.threshold = 1\n } else if (mods.has('half')) {\n options.threshold = 0.5\n }\n let observer: IntersectionObserver | null = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n callback()\n if (observer && once.has(el)) {\n observer.disconnect()\n }\n }\n }\n },\n options,\n )\n observer.observe(el)\n if (mods.has('once')) {\n once.add(el)\n }\n return () => {\n if (!mods.has('once')) {\n once.delete(el)\n }\n if (observer) {\n observer.disconnect()\n observer = null\n }\n }\n },\n})\n", "// Icon: material-symbols:timer-outline\n// Slug: Runs an expression at a regular interval.\n// Description: Runs an expression at a regular interval.\n\nimport { attribute } from '@engine'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport { tagHas, tagToMs } from '@utils/tags'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nattribute({\n name: 'on-interval',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply({ mods, rx }) {\n let callback = () => {\n beginBatch()\n rx()\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n let duration = 1000\n const durationArgs = mods.get('duration')\n if (durationArgs) {\n duration = tagToMs(durationArgs)\n const leading = tagHas(durationArgs, 'leading', false)\n if (leading) {\n callback()\n }\n }\n const intervalId = setInterval(callback, duration)\n return () => {\n clearInterval(intervalId)\n }\n },\n})\n", "// Icon: material-symbols:timer-play-outline\n// Slug: Runs an expression when loaded into the DOM.\n// Description: Runs an expression when the element is loaded into the DOM.\n\nimport { attribute } from '@engine'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport { tagToMs } from '@utils/tags'\nimport { delay } from '@utils/timing'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nattribute({\n name: 'init',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply({ rx, mods }) {\n let callback = () => {\n beginBatch()\n rx()\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n let wait = 0\n const delayArgs = mods.get('delay')\n if (delayArgs) {\n wait = tagToMs(delayArgs)\n if (wait > 0) {\n callback = delay(callback, wait)\n }\n }\n callback()\n },\n})\n", "// Icon: material-symbols:change-circle-outline\n// Slug: Runs an expression when signals are patched.\n// Description: Runs an expression whenever one or more signals are patched.\n\nimport { attribute } from '@engine'\nimport { DATASTAR_SIGNAL_PATCH_EVENT } from '@engine/consts'\nimport { beginBatch, endBatch, filtered } from '@engine/signals'\nimport type { JSONPatch, SignalFilterOptions } from '@engine/types'\nimport { isEmpty } from '@utils/paths'\nimport { jsStrToObject } from '@utils/text'\nimport { modifyTiming } from '@utils/timing'\n\nattribute({\n name: 'on-signal-patch',\n requirement: {\n value: 'must',\n },\n argNames: ['patch'],\n returnsValue: true,\n apply({ el, key, mods, rx, error }) {\n if (!!key && key !== 'filter') {\n throw error('KeyNotAllowed')\n }\n\n // Look for data-on-signal-patch-filter data attribute\n const filtersRaw = el.getAttribute('data-on-signal-patch-filter')\n let filters: SignalFilterOptions = {}\n if (filtersRaw) {\n filters = jsStrToObject(filtersRaw)\n }\n\n const callback: EventListener = modifyTiming(\n (evt: CustomEvent) => {\n const watched = filtered(filters, evt.detail)\n if (!isEmpty(watched)) {\n beginBatch()\n rx(watched)\n endBatch()\n }\n },\n mods,\n )\n\n document.addEventListener(DATASTAR_SIGNAL_PATCH_EVENT, callback)\n return () => {\n document.removeEventListener(DATASTAR_SIGNAL_PATCH_EVENT, callback)\n }\n },\n})\n", "// Icon: mdi:cursor-pointer\n// Slug: Creates a reference to an element.\n// Description: Creates a new signal that is a reference to the element on which the data attribute is placed.\n\nimport { attribute } from '@engine'\nimport { mergePaths } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'ref',\n requirement: 'exclusive',\n apply({ el, key, mods, value }) {\n const signalName = key != null ? modifyCasing(key, mods) : value\n mergePaths([[signalName, el]])\n },\n})\n", "// Icon: streamline:interface-edit-view-eye-eyeball-open-view\n// Slug: Shows or hides an element.\n// Description: Shows or hides an element based on whether an expression evaluates to `true` or `false`.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nconst NONE = 'none'\nconst DISPLAY = 'display'\n\nattribute({\n name: 'show',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n returnsValue: true,\n apply({ el, rx }) {\n const update = () => {\n observer.disconnect()\n const shouldShow = rx()\n if (shouldShow) {\n if (el.style.display === NONE) el.style.removeProperty(DISPLAY)\n } else {\n el.style.setProperty(DISPLAY, NONE)\n }\n observer.observe(el, { attributeFilter: ['style'] })\n }\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "// Icon: streamline:wifi-signal-full-remix\n// Slug: Patches signals into the existing signals.\n// Description: Patches (adds, updates or removes) one or more signals into the existing signals.\n\nimport { attribute } from '@engine'\nimport { mergePatch, mergePaths } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'signals',\n returnsValue: true,\n apply({ key, mods, rx }) {\n const ifMissing = mods.has('ifmissing')\n\n if (key) {\n key = modifyCasing(key, mods)\n mergePaths([[key, rx?.()]], { ifMissing })\n } else {\n const patch = Object.assign({}, rx?.() as Record)\n mergePatch(patch, { ifMissing })\n }\n },\n})\n", "// Icon: material-symbols:format-paint-outline\n// Slug: Sets inline styles on an element based on an expression.\n// Description: Sets CSS styles on an element using either key-based or object syntax, and keeps them in sync with reactive signals.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\nimport { kebab } from '@utils/text'\n\nattribute({\n name: 'style',\n requirement: {\n value: 'must',\n },\n returnsValue: true,\n apply({ key, el, rx }) {\n const { style } = el\n const initialStyles = new Map()\n\n const apply = (prop: string, value: any) => {\n const initial = initialStyles.get(prop)\n if (!value && value !== 0) {\n initial !== undefined &&\n (initial\n ? style.setProperty(prop, initial)\n : style.removeProperty(prop))\n } else {\n initial === undefined &&\n initialStyles.set(prop, style.getPropertyValue(prop))\n style.setProperty(prop, String(value))\n }\n }\n\n const update = () => {\n observer.disconnect()\n\n if (key) {\n apply(key, rx())\n } else {\n const styles = rx() as Record\n\n for (const [prop, initial] of initialStyles) {\n prop in styles ||\n (initial\n ? style.setProperty(prop, initial)\n : style.removeProperty(prop))\n }\n\n for (const prop in styles) {\n apply(kebab(prop), styles[prop])\n }\n }\n\n observer.observe(el, { attributeFilter: ['style'] })\n }\n\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n for (const [prop, initial] of initialStyles) {\n initial ? style.setProperty(prop, initial) : style.removeProperty(prop)\n }\n }\n },\n})\n", "// Icon: icon-park-outline:text\n// Slug: Binds the text content of an element.\n// Description: Binds the text content of an element to an expression.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nattribute({\n name: 'text',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n returnsValue: true,\n apply({ el, rx }) {\n const update = () => {\n observer.disconnect()\n el.textContent = `${rx()}`\n observer.observe(el, {\n childList: true,\n characterData: true,\n subtree: true,\n })\n }\n\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "// Icon: material-symbols:cloud-download\n// Slug: Patches elements into the DOM.\n// Description: Patches elements into the DOM.\n\nimport { watcher } from '@engine'\nimport type { WatcherContext } from '@engine/types'\nimport { morph } from '@engine/morph'\nimport { supportsViewTransitions } from '@utils/view-transitions'\n\ntype PatchElementsMode =\n | 'remove'\n | 'outer'\n | 'inner'\n | 'replace'\n | 'prepend'\n | 'append'\n | 'before'\n | 'after'\n\ntype PatchElementsArgs = {\n elements: string\n mode: PatchElementsMode\n selector: string\n useViewTransition: boolean\n}\n\nwatcher({\n name: 'datastar-patch-elements',\n apply(\n ctx,\n { elements = '', selector = '', mode = 'outer', useViewTransition },\n ) {\n switch (mode) {\n case 'remove':\n case 'outer':\n case 'inner':\n case 'replace':\n case 'prepend':\n case 'append':\n case 'before':\n case 'after':\n break\n default:\n throw ctx.error('PatchElementsInvalidMode', { mode })\n }\n\n if (!selector && mode !== 'outer' && mode !== 'replace') {\n throw ctx.error('PatchElementsExpectedSelector')\n }\n\n const args2: PatchElementsArgs = {\n mode,\n selector,\n elements,\n useViewTransition: useViewTransition?.trim() === 'true',\n }\n\n if (supportsViewTransitions && useViewTransition) {\n document.startViewTransition(() => onPatchElements(ctx, args2))\n } else {\n onPatchElements(ctx, args2)\n }\n },\n})\n\nconst onPatchElements = (\n { error }: WatcherContext,\n { elements, selector, mode }: PatchElementsArgs,\n) => {\n const elementsWithSvgsRemoved = elements.replace(\n /]*>|>)([\\s\\S]*?)<\\/svg>/gim,\n '',\n )\n const hasHtml = /<\\/html>/.test(elementsWithSvgsRemoved)\n const hasHead = /<\\/head>/.test(elementsWithSvgsRemoved)\n const hasBody = /<\\/body>/.test(elementsWithSvgsRemoved)\n\n const newDocument = new DOMParser().parseFromString(\n hasHtml || hasHead || hasBody\n ? elements\n : ``,\n 'text/html',\n )\n\n let newContent = document.createDocumentFragment()\n if (hasHtml) {\n newContent.appendChild(newDocument.documentElement)\n } else if (hasHead && hasBody) {\n newContent.appendChild(newDocument.head)\n newContent.appendChild(newDocument.body)\n } else if (hasHead) {\n newContent.appendChild(newDocument.head)\n } else if (hasBody) {\n newContent.appendChild(newDocument.body)\n } else {\n newContent = newDocument.querySelector('template')!.content\n }\n\n if (!selector && (mode === 'outer' || mode === 'replace')) {\n for (const child of newContent.children) {\n let target: Element\n if (child instanceof HTMLHtmlElement) {\n target = document.documentElement\n } else if (child instanceof HTMLBodyElement) {\n target = document.body\n } else if (child instanceof HTMLHeadElement) {\n target = document.head\n } else {\n target = document.getElementById(child.id)!\n if (!target) {\n console.warn(error('PatchElementsNoTargetsFound'), {\n element: { id: child.id },\n })\n continue\n }\n }\n\n applyToTargets(mode as PatchElementsMode, child, [target])\n }\n } else {\n const targets = document.querySelectorAll(selector)\n if (!targets.length) {\n console.warn(error('PatchElementsNoTargetsFound'), { selector })\n return\n }\n\n applyToTargets(mode as PatchElementsMode, newContent, targets)\n }\n}\n\nconst scripts = new WeakSet()\nfor (const script of document.querySelectorAll('script')) {\n scripts.add(script)\n}\n\nconst execute = (target: Element): void => {\n const elScripts =\n target instanceof HTMLScriptElement\n ? [target]\n : target.querySelectorAll('script')\n for (const old of elScripts) {\n if (!scripts.has(old)) {\n const script = document.createElement('script')\n for (const { name, value } of old.attributes) {\n script.setAttribute(name, value)\n }\n script.text = old.text\n old.replaceWith(script)\n scripts.add(script)\n }\n }\n}\n\nconst applyPatchMode = (\n targets: Iterable,\n element: DocumentFragment | Element,\n action: string,\n) => {\n for (const target of targets) {\n const cloned = element.cloneNode(true) as Element\n execute(cloned)\n // @ts-expect-error\n target[action](cloned)\n }\n}\n\nconst applyToTargets = (\n mode: PatchElementsMode,\n element: DocumentFragment | Element,\n targets: Iterable,\n) => {\n switch (mode) {\n case 'remove':\n for (const target of targets) {\n target.remove()\n }\n break\n case 'outer':\n case 'inner':\n for (const target of targets) {\n morph(target, element.cloneNode(true) as Element, mode)\n execute(target)\n }\n break\n case 'replace':\n applyPatchMode(targets, element, 'replaceWith')\n break\n case 'prepend':\n case 'append':\n case 'before':\n case 'after':\n applyPatchMode(targets, element, mode)\n }\n}\n", "// Icon: material-symbols:settings-input-antenna\n// Slug: Patches signals.\n// Description: Patches signals.\n\nimport { watcher } from '@engine'\nimport { mergePatch } from '@engine/signals'\nimport { jsStrToObject } from '@utils/text'\n\nwatcher({\n name: 'datastar-patch-signals',\n apply({ error }, { signals, onlyIfMissing }) {\n if (signals) {\n const ifMissing = onlyIfMissing?.trim() === 'true'\n mergePatch(jsStrToObject(signals), { ifMissing })\n } else {\n throw error('PatchSignalsExpectedSignals')\n }\n },\n})\n"], + "mappings": "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", + "names": ["lol", "DSP", "DSS", "DATASTAR_FETCH_EVENT", "DATASTAR_SIGNAL_PATCH_EVENT", "kebab", "str", "snake", "str", "kebab", "jsStrToObject", "raw", "caseFns", "str", "x", "modifyCasing", "mods", "defaultCase", "c", "aliasify", "name", "hasOwn", "isPojo", "obj", "isEmpty", "prop", "hasOwn", "updateLeaves", "fn", "key", "val", "pathToObj", "paths", "result", "path", "value", "keys", "lastKey", "acc", "currentPatch", "queuedEffects", "batchDepth", "notifyIndex", "queuedEffectsLength", "prevSub", "activeSub", "version", "beginBatch", "endBatch", "flush", "dispatch", "startPeeking", "sub", "stopPeeking", "signal", "initialValue", "signalOper", "value_", "flags_", "computedSymbol", "computed", "getter", "c", "computedOper", "effect", "fn", "e", "fn_", "link", "effectOper", "run", "update", "updateComputed", "updateSignal", "startTracking", "oldValue", "endTracking", "s", "value", "notify", "flags", "subs", "subs_", "sub_", "checkDirty", "deps_", "dep", "dep_", "depFlags", "nextDep_", "propagate", "currentValue", "shallowPropagate", "unlink", "prevDep", "depsTail_", "nextDep", "version_", "subsTail_", "newLink", "prevDep_", "prevSub_", "nextSub_", "toRemove", "next", "stack", "top", "isValidLink", "subSubs", "nextSub", "prev_", "checkDepth", "dirty", "firstSub", "hasMultipleSubs", "checkLink", "getPath", "path", "result", "root", "split", "hasOwn", "deep", "prefix", "isArr", "isPojo", "deepObj", "key", "keys", "_", "prop", "newValue", "diff", "patch", "i", "detail", "pathToObj", "DATASTAR_SIGNAL_PATCH_EVENT", "mergePatch", "ifMissing", "mergeInner", "mergePaths", "paths", "options", "target", "targetParent", "toRegExp", "val", "filtered", "include", "exclude", "obj", "includeRe", "excludeRe", "node", "isHTMLOrSVG", "el", "url", "error", "ctx", "reason", "metadata", "e", "r", "snake", "q", "c", "actionPlugins", "attributePlugins", "watcherPlugins", "actions", "_", "prop", "removals", "queuedAttributes", "queuedAttributeNames", "attribute", "plugin", "apply", "action", "DATASTAR_FETCH_EVENT", "evt", "watcher", "cleanupEls", "els", "el", "cleanups", "cleanup", "aliasedIgnore", "aliasify", "aliasedIgnoreAttr", "shouldIgnore", "applyEls", "onlyNew", "key", "applyAttributePlugin", "observe", "mutations", "target", "type", "attributeName", "addedNodes", "removedNodes", "node", "isHTMLOrSVG", "value", "mutationObserver", "root", "attrKey", "rawKey", "namePart", "rawModifiers", "pluginName", "keyReq", "valueReq", "cachedRx", "args", "genRx", "rawMod", "label", "mod", "returnsValue", "argNames", "expr", "statementRe", "statements", "lastIdx", "last", "escaped", "escapeRe", "DSP", "DSS", "counter", "match", "k", "v", "signalName", "acc", "part", "varName", "fn", "name", "err", "ctxIdMap", "ctxPersistentIds", "oldIdTagNameMap", "duplicateIds", "ctxPantry", "aliasedIgnoreMorph", "aliasify", "aliasedIgnoreMorphAttr", "morph", "oldElt", "newContent", "mode", "isHTMLOrSVG", "normalizedElt", "oldIdElements", "id", "tagName", "newIdElements", "parent", "populateIdMapWithTree", "morphChildren", "oldParent", "newParent", "insertionPoint", "endPoint", "newChild", "bestMatch", "findBestMatch", "cursor", "tempNode", "removeNode", "morphNode", "movedChild", "current", "idSet", "moveBefore", "newEmptyChild", "newClonedChild", "node", "startPoint", "nextSibling", "siblingSoftMatchCount", "displaceMatchCount", "nodeMatchCount", "isSoftMatch", "isIdSetMatch", "oldSet", "newSet", "oldNode", "newNode", "aliasedPreserveAttr", "type", "newElt", "preserveAttrs", "name", "value", "i", "root", "elements", "elt", "action", "_", "fn", "startPeeking", "stopPeeking", "action", "_", "value", "filter", "startPeeking", "masked", "filtered", "updateLeaves", "mergePatch", "stopPeeking", "action", "_", "filter", "startPeeking", "masked", "filtered", "updateLeaves", "oldValue", "mergePatch", "stopPeeking", "fetchAbortControllers", "createHttpMethod", "name", "method", "action", "el", "evt", "error", "url", "selector", "userHeaders", "contentType", "include", "exclude", "openWhenHidden", "retryInterval", "retryScaler", "retryMaxWaitMs", "retryMaxCount", "requestCancellation", "controller", "isDisabled", "oldController", "observer", "mutations", "mutation", "removed", "cleanupFn", "initialHeaders", "headers", "req", "response", "dispatchFetch", "ERROR", "type", "argsRawLines", "line", "i", "v", "argsRaw", "k", "isWrongContent", "RETRYING", "urlInstance", "queryParams", "res", "filtered", "formEl", "formData", "submitter", "preventDefault", "multipart", "formParams", "key", "value", "STARTED", "fetchEventSource", "e", "FINISHED", "RETRIES_FAILED", "DATASTAR_FETCH_EVENT", "err", "getBytes", "stream", "onChunk", "reader", "result", "getLines", "onLine", "buffer", "position", "fieldLength", "discardTrailingNewline", "arr", "concat", "bufLength", "lineStart", "lineEnd", "getMessages", "onId", "onRetry", "onMessage", "message", "newMessage", "decoder", "field", "valueOffset", "retry", "a", "b", "input", "inputSignal", "inputHeaders", "inputOnOpen", "onmessage", "onclose", "onerror", "inputFetch", "overrides", "rest", "resolve", "reject", "curRequestController", "onVisibilityChange", "create", "retryTimer", "dispose", "fetch", "onopen", "retries", "baseRetryInterval", "dispatchNonSSE", "dispatchType", "argNames", "n", "kebab", "o", "ct", "script", "scriptAttributesHeader", "id", "interval", "innerErr", "attribute", "el", "key", "rx", "syncAttr", "val", "update", "observer", "obj", "attributeFilter", "cleanup", "effect", "dataURIRegex", "empty", "aliasedBind", "aliasify", "attribute", "el", "key", "mods", "value", "error", "signalName", "modifyCasing", "get", "type", "set", "syncSignal", "files", "signalFiles", "f", "resolve", "reader", "match", "mergePaths", "typeMap", "option", "initialValue", "getPath", "path", "signalNameKebab", "inputs", "paths", "i", "input", "signalValue", "cleanup", "effect", "attribute", "key", "el", "mods", "rx", "modifyCasing", "callback", "observer", "classes", "k", "classNames", "cn", "name", "cleanup", "effect", "attribute", "key", "mods", "rx", "error", "mergePaths", "modifyCasing", "computed", "patch", "updateLeaves", "old", "mergePatch", "attribute", "rx", "effect", "attribute", "el", "key", "mods", "value", "signalName", "modifyCasing", "mergePaths", "watcher", "event", "type", "elt", "STARTED", "FINISHED", "DATASTAR_FETCH_EVENT", "attribute", "el", "value", "mods", "spaces", "filters", "jsStrToObject", "callback", "observer", "filtered", "cleanup", "effect", "tagToMs", "args", "arg", "tagHas", "tags", "tag", "defaultValue", "delay", "callback", "wait", "args", "debounce", "leading", "trailing", "timer", "throttle", "waiting", "modifyTiming", "mods", "delayArgs", "tagToMs", "debounceArgs", "tagHas", "throttleArgs", "supportsViewTransitions", "modifyViewTransition", "callback", "mods", "cb", "args", "attribute", "el", "key", "mods", "rx", "target", "callback", "evt", "beginBatch", "endBatch", "modifyViewTransition", "modifyTiming", "evtListOpts", "cb", "eventName", "modifyCasing", "DATASTAR_FETCH_EVENT", "DATASTAR_SIGNAL_PATCH_EVENT", "once", "attribute", "el", "mods", "rx", "callback", "beginBatch", "endBatch", "modifyViewTransition", "modifyTiming", "options", "observer", "entries", "entry", "attribute", "mods", "rx", "callback", "beginBatch", "endBatch", "modifyViewTransition", "duration", "durationArgs", "tagToMs", "tagHas", "intervalId", "attribute", "rx", "mods", "callback", "beginBatch", "endBatch", "modifyViewTransition", "wait", "delayArgs", "tagToMs", "delay", "attribute", "el", "key", "mods", "rx", "error", "filtersRaw", "filters", "jsStrToObject", "callback", "modifyTiming", "evt", "watched", "filtered", "isEmpty", "beginBatch", "endBatch", "DATASTAR_SIGNAL_PATCH_EVENT", "attribute", "el", "key", "mods", "value", "signalName", "modifyCasing", "mergePaths", "NONE", "DISPLAY", "attribute", "el", "rx", "update", "observer", "cleanup", "effect", "attribute", "key", "mods", "rx", "ifMissing", "modifyCasing", "mergePaths", "patch", "mergePatch", "attribute", "key", "el", "rx", "style", "initialStyles", "apply", "prop", "value", "initial", "update", "observer", "styles", "kebab", "cleanup", "effect", "attribute", "el", "rx", "update", "observer", "cleanup", "effect", "watcher", "ctx", "elements", "selector", "mode", "useViewTransition", "args2", "supportsViewTransitions", "onPatchElements", "error", "elementsWithSvgsRemoved", "hasHtml", "hasHead", "hasBody", "newDocument", "newContent", "child", "target", "applyToTargets", "targets", "scripts", "script", "execute", "elScripts", "old", "name", "value", "applyPatchMode", "element", "action", "cloned", "morph", "watcher", "error", "signals", "onlyIfMissing", "ifMissing", "mergePatch", "jsStrToObject"] +} diff --git a/hypermedia/2-example/index.html b/demo/datasstar-static/signals/index.html similarity index 100% rename from hypermedia/2-example/index.html rename to demo/datasstar-static/signals/index.html diff --git a/demo/datasstar-static/signals/pico.blue.css b/demo/datasstar-static/signals/pico.blue.css new file mode 100644 index 0000000..e76f23b --- /dev/null +++ b/demo/datasstar-static/signals/pico.blue.css @@ -0,0 +1,2808 @@ +@charset "UTF-8"; +/*! + * Pico CSS ✨ v2.0.6 (https://picocss.com) + * Copyright 2019-2024 - Licensed under MIT + */ +/** + * Styles + */ + +@view-transition { + navigation: auto; +} + + +:root { + --pico-font-family-emoji: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --pico-font-family-sans-serif: system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, Helvetica, Arial, "Helvetica Neue", sans-serif, var(--pico-font-family-emoji); + --pico-font-family-monospace: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace, var(--pico-font-family-emoji); + --pico-font-family: var(--pico-font-family-sans-serif); + --pico-line-height: 1.5; + --pico-font-weight: 400; + --pico-font-size: 100%; + --pico-text-underline-offset: 0.1rem; + --pico-border-radius: 0.25rem; + --pico-border-width: 0.0625rem; + --pico-outline-width: 0.125rem; + --pico-transition: 0.2s ease-in-out; + --pico-spacing: 1rem; + --pico-typography-spacing-vertical: 1rem; + --pico-block-spacing-vertical: var(--pico-spacing); + --pico-block-spacing-horizontal: var(--pico-spacing); + --pico-grid-column-gap: var(--pico-spacing); + --pico-grid-row-gap: var(--pico-spacing); + --pico-form-element-spacing-vertical: 0.75rem; + --pico-form-element-spacing-horizontal: 1rem; + --pico-group-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-group-box-shadow-focus-with-button: 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); + --pico-group-box-shadow-focus-with-input: 0 0 0 0.0625rem var(--pico-form-element-border-color); + --pico-modal-overlay-backdrop-filter: blur(0.375rem); + --pico-nav-element-spacing-vertical: 1rem; + --pico-nav-element-spacing-horizontal: 0.5rem; + --pico-nav-link-spacing-vertical: 0.5rem; + --pico-nav-link-spacing-horizontal: 0.5rem; + --pico-nav-breadcrumb-divider: ">"; + --pico-icon-checkbox: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-minus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-date: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-time: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-loading: url("data:image/svg+xml,%3Csvg fill='none' height='24' width='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' %3E%3Cstyle%3E g %7B animation: rotate 2s linear infinite; transform-origin: center center; %7D circle %7B stroke-dasharray: 75,100; stroke-dashoffset: -5; animation: dash 1.5s ease-in-out infinite; stroke-linecap: round; %7D @keyframes rotate %7B 0%25 %7B transform: rotate(0deg); %7D 100%25 %7B transform: rotate(360deg); %7D %7D @keyframes dash %7B 0%25 %7B stroke-dasharray: 1,100; stroke-dashoffset: 0; %7D 50%25 %7B stroke-dasharray: 44.5,100; stroke-dashoffset: -17.5; %7D 100%25 %7B stroke-dasharray: 44.5,100; stroke-dashoffset: -62; %7D %7D %3C/style%3E%3Cg%3E%3Ccircle cx='12' cy='12' r='10' fill='none' stroke='rgb(136, 145, 164)' stroke-width='4' /%3E%3C/g%3E%3C/svg%3E"); +} +@media (min-width: 576px) { + :root { + --pico-font-size: 106.25%; + } +} +@media (min-width: 768px) { + :root { + --pico-font-size: 112.5%; + } +} +@media (min-width: 1024px) { + :root { + --pico-font-size: 118.75%; + } +} +@media (min-width: 1280px) { + :root { + --pico-font-size: 125%; + } +} +@media (min-width: 1536px) { + :root { + --pico-font-size: 131.25%; + } +} + +a { + --pico-text-decoration: underline; +} +a.secondary, a.contrast { + --pico-text-decoration: underline; +} + +small { + --pico-font-size: 0.875em; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + --pico-font-weight: 700; +} + +h1 { + --pico-font-size: 2rem; + --pico-line-height: 1.125; + --pico-typography-spacing-top: 3rem; +} + +h2 { + --pico-font-size: 1.75rem; + --pico-line-height: 1.15; + --pico-typography-spacing-top: 2.625rem; +} + +h3 { + --pico-font-size: 1.5rem; + --pico-line-height: 1.175; + --pico-typography-spacing-top: 2.25rem; +} + +h4 { + --pico-font-size: 1.25rem; + --pico-line-height: 1.2; + --pico-typography-spacing-top: 1.874rem; +} + +h5 { + --pico-font-size: 1.125rem; + --pico-line-height: 1.225; + --pico-typography-spacing-top: 1.6875rem; +} + +h6 { + --pico-font-size: 1rem; + --pico-line-height: 1.25; + --pico-typography-spacing-top: 1.5rem; +} + +thead th, +thead td, +tfoot th, +tfoot td { + --pico-font-weight: 600; + --pico-border-width: 0.1875rem; +} + +pre, +code, +kbd, +samp { + --pico-font-family: var(--pico-font-family-monospace); +} + +kbd { + --pico-font-weight: bolder; +} + +input:not([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]), +:where(select, textarea) { + --pico-outline-width: 0.0625rem; +} + +[type=search] { + --pico-border-radius: 5rem; +} + +[type=checkbox], +[type=radio] { + --pico-border-width: 0.125rem; +} + +[type=checkbox][role=switch] { + --pico-border-width: 0.1875rem; +} + +details.dropdown summary:not([role=button]) { + --pico-outline-width: 0.0625rem; +} + +nav details.dropdown summary:focus-visible { + --pico-outline-width: 0.125rem; +} + +[role=search] { + --pico-border-radius: 5rem; +} + +[role=search]:has(button.secondary:focus, +[type=submit].secondary:focus, +[type=button].secondary:focus, +[role=button].secondary:focus), +[role=group]:has(button.secondary:focus, +[type=submit].secondary:focus, +[type=button].secondary:focus, +[role=button].secondary:focus) { + --pico-group-box-shadow-focus-with-button: 0 0 0 var(--pico-outline-width) var(--pico-secondary-focus); +} +[role=search]:has(button.contrast:focus, +[type=submit].contrast:focus, +[type=button].contrast:focus, +[role=button].contrast:focus), +[role=group]:has(button.contrast:focus, +[type=submit].contrast:focus, +[type=button].contrast:focus, +[role=button].contrast:focus) { + --pico-group-box-shadow-focus-with-button: 0 0 0 var(--pico-outline-width) var(--pico-contrast-focus); +} +[role=search] button, +[role=search] [type=submit], +[role=search] [type=button], +[role=search] [role=button], +[role=group] button, +[role=group] [type=submit], +[role=group] [type=button], +[role=group] [role=button] { + --pico-form-element-spacing-horizontal: 2rem; +} + +details summary[role=button]:not(.outline)::after { + filter: brightness(0) invert(1); +} + +[aria-busy=true]:not(input, select, textarea):is(button, [type=submit], [type=button], [type=reset], [role=button]):not(.outline)::before { + filter: brightness(0) invert(1); +} + +/** + * Color schemes + */ +[data-theme=light], +:root:not([data-theme=dark]) { + --pico-background-color: #fff; + --pico-color: #373c44; + --pico-text-selection-color: rgba(116, 139, 248, 0.25); + --pico-muted-color: #646b79; + --pico-muted-border-color: #e7eaf0; + --pico-primary: #2060df; + --pico-primary-background: #2060df; + --pico-primary-border: var(--pico-primary-background); + --pico-primary-underline: rgba(32, 96, 223, 0.5); + --pico-primary-hover: #184eb8; + --pico-primary-hover-background: #1d59d0; + --pico-primary-hover-border: var(--pico-primary-hover-background); + --pico-primary-hover-underline: var(--pico-primary-hover); + --pico-primary-focus: rgba(116, 139, 248, 0.5); + --pico-primary-inverse: #fff; + --pico-secondary: #5d6b89; + --pico-secondary-background: #525f7a; + --pico-secondary-border: var(--pico-secondary-background); + --pico-secondary-underline: rgba(93, 107, 137, 0.5); + --pico-secondary-hover: #48536b; + --pico-secondary-hover-background: #48536b; + --pico-secondary-hover-border: var(--pico-secondary-hover-background); + --pico-secondary-hover-underline: var(--pico-secondary-hover); + --pico-secondary-focus: rgba(93, 107, 137, 0.25); + --pico-secondary-inverse: #fff; + --pico-contrast: #181c25; + --pico-contrast-background: #181c25; + --pico-contrast-border: var(--pico-contrast-background); + --pico-contrast-underline: rgba(24, 28, 37, 0.5); + --pico-contrast-hover: #000; + --pico-contrast-hover-background: #000; + --pico-contrast-hover-border: var(--pico-contrast-hover-background); + --pico-contrast-hover-underline: var(--pico-secondary-hover); + --pico-contrast-focus: rgba(93, 107, 137, 0.25); + --pico-contrast-inverse: #fff; + --pico-box-shadow: 0.0145rem 0.029rem 0.174rem rgba(129, 145, 181, 0.01698), 0.0335rem 0.067rem 0.402rem rgba(129, 145, 181, 0.024), 0.0625rem 0.125rem 0.75rem rgba(129, 145, 181, 0.03), 0.1125rem 0.225rem 1.35rem rgba(129, 145, 181, 0.036), 0.2085rem 0.417rem 2.502rem rgba(129, 145, 181, 0.04302), 0.5rem 1rem 6rem rgba(129, 145, 181, 0.06), 0 0 0 0.0625rem rgba(129, 145, 181, 0.015); + --pico-h1-color: #2d3138; + --pico-h2-color: #373c44; + --pico-h3-color: #424751; + --pico-h4-color: #4d535e; + --pico-h5-color: #5c6370; + --pico-h6-color: #646b79; + --pico-mark-background-color: #fde7c0; + --pico-mark-color: #0f1114; + --pico-ins-color: #1d6a54; + --pico-del-color: #883935; + --pico-blockquote-border-color: var(--pico-muted-border-color); + --pico-blockquote-footer-color: var(--pico-muted-color); + --pico-button-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-table-border-color: var(--pico-muted-border-color); + --pico-table-row-stripped-background-color: rgba(111, 120, 135, 0.0375); + --pico-code-background-color: #f3f5f7; + --pico-code-color: #646b79; + --pico-code-kbd-background-color: var(--pico-color); + --pico-code-kbd-color: var(--pico-background-color); + --pico-form-element-background-color: #fbfcfc; + --pico-form-element-selected-background-color: #dfe3eb; + --pico-form-element-border-color: #cfd5e2; + --pico-form-element-color: #23262c; + --pico-form-element-placeholder-color: var(--pico-muted-color); + --pico-form-element-active-background-color: #fff; + --pico-form-element-active-border-color: var(--pico-primary-border); + --pico-form-element-focus-color: var(--pico-primary-border); + --pico-form-element-disabled-opacity: 0.5; + --pico-form-element-invalid-border-color: #b86a6b; + --pico-form-element-invalid-active-border-color: #c84f48; + --pico-form-element-invalid-focus-color: var(--pico-form-element-invalid-active-border-color); + --pico-form-element-valid-border-color: #4c9b8a; + --pico-form-element-valid-active-border-color: #279977; + --pico-form-element-valid-focus-color: var(--pico-form-element-valid-active-border-color); + --pico-switch-background-color: #bfc7d9; + --pico-switch-checked-background-color: var(--pico-primary-background); + --pico-switch-color: #fff; + --pico-switch-thumb-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-range-border-color: #dfe3eb; + --pico-range-active-border-color: #bfc7d9; + --pico-range-thumb-border-color: var(--pico-background-color); + --pico-range-thumb-color: var(--pico-secondary-background); + --pico-range-thumb-active-color: var(--pico-primary-background); + --pico-accordion-border-color: var(--pico-muted-border-color); + --pico-accordion-active-summary-color: var(--pico-primary-hover); + --pico-accordion-close-summary-color: var(--pico-color); + --pico-accordion-open-summary-color: var(--pico-muted-color); + --pico-card-background-color: var(--pico-background-color); + --pico-card-border-color: var(--pico-muted-border-color); + --pico-card-box-shadow: var(--pico-box-shadow); + --pico-card-sectioning-background-color: #fbfcfc; + --pico-dropdown-background-color: #fff; + --pico-dropdown-border-color: #eff1f4; + --pico-dropdown-box-shadow: var(--pico-box-shadow); + --pico-dropdown-color: var(--pico-color); + --pico-dropdown-hover-background-color: #eff1f4; + --pico-loading-spinner-opacity: 0.5; + --pico-modal-overlay-background-color: rgba(232, 234, 237, 0.75); + --pico-progress-background-color: #dfe3eb; + --pico-progress-color: var(--pico-primary-background); + --pico-tooltip-background-color: var(--pico-contrast-background); + --pico-tooltip-color: var(--pico-contrast-inverse); + --pico-icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(76, 155, 138)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(200, 79, 72)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); + color-scheme: light; +} +[data-theme=light] input:is([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]), +:root:not([data-theme=dark]) input:is([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]) { + --pico-form-element-focus-color: var(--pico-primary-focus); +} + +@media only screen and (prefers-color-scheme: dark) { + :root:not([data-theme]) { + --pico-background-color: #13171f; + --pico-color: #c2c7d0; + --pico-text-selection-color: rgba(137, 153, 249, 0.1875); + --pico-muted-color: #7b8495; + --pico-muted-border-color: #202632; + --pico-primary: #8999f9; + --pico-primary-background: #2060df; + --pico-primary-border: var(--pico-primary-background); + --pico-primary-underline: rgba(137, 153, 249, 0.5); + --pico-primary-hover: #aeb5fb; + --pico-primary-hover-background: #3c71f7; + --pico-primary-hover-border: var(--pico-primary-hover-background); + --pico-primary-hover-underline: var(--pico-primary-hover); + --pico-primary-focus: rgba(137, 153, 249, 0.375); + --pico-primary-inverse: #fff; + --pico-secondary: #969eaf; + --pico-secondary-background: #525f7a; + --pico-secondary-border: var(--pico-secondary-background); + --pico-secondary-underline: rgba(150, 158, 175, 0.5); + --pico-secondary-hover: #b3b9c5; + --pico-secondary-hover-background: #5d6b89; + --pico-secondary-hover-border: var(--pico-secondary-hover-background); + --pico-secondary-hover-underline: var(--pico-secondary-hover); + --pico-secondary-focus: rgba(144, 158, 190, 0.25); + --pico-secondary-inverse: #fff; + --pico-contrast: #dfe3eb; + --pico-contrast-background: #eff1f4; + --pico-contrast-border: var(--pico-contrast-background); + --pico-contrast-underline: rgba(223, 227, 235, 0.5); + --pico-contrast-hover: #fff; + --pico-contrast-hover-background: #fff; + --pico-contrast-hover-border: var(--pico-contrast-hover-background); + --pico-contrast-hover-underline: var(--pico-contrast-hover); + --pico-contrast-focus: rgba(207, 213, 226, 0.25); + --pico-contrast-inverse: #000; + --pico-box-shadow: 0.0145rem 0.029rem 0.174rem rgba(7, 9, 12, 0.01698), 0.0335rem 0.067rem 0.402rem rgba(7, 9, 12, 0.024), 0.0625rem 0.125rem 0.75rem rgba(7, 9, 12, 0.03), 0.1125rem 0.225rem 1.35rem rgba(7, 9, 12, 0.036), 0.2085rem 0.417rem 2.502rem rgba(7, 9, 12, 0.04302), 0.5rem 1rem 6rem rgba(7, 9, 12, 0.06), 0 0 0 0.0625rem rgba(7, 9, 12, 0.015); + --pico-h1-color: #f0f1f3; + --pico-h2-color: #e0e3e7; + --pico-h3-color: #c2c7d0; + --pico-h4-color: #b3b9c5; + --pico-h5-color: #a4acba; + --pico-h6-color: #8891a4; + --pico-mark-background-color: #014063; + --pico-mark-color: #fff; + --pico-ins-color: #62af9a; + --pico-del-color: #ce7e7b; + --pico-blockquote-border-color: var(--pico-muted-border-color); + --pico-blockquote-footer-color: var(--pico-muted-color); + --pico-button-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-table-border-color: var(--pico-muted-border-color); + --pico-table-row-stripped-background-color: rgba(111, 120, 135, 0.0375); + --pico-code-background-color: #1a1f28; + --pico-code-color: #8891a4; + --pico-code-kbd-background-color: var(--pico-color); + --pico-code-kbd-color: var(--pico-background-color); + --pico-form-element-background-color: #1c212c; + --pico-form-element-selected-background-color: #2a3140; + --pico-form-element-border-color: #2a3140; + --pico-form-element-color: #e0e3e7; + --pico-form-element-placeholder-color: #8891a4; + --pico-form-element-active-background-color: #1a1f28; + --pico-form-element-active-border-color: var(--pico-primary-border); + --pico-form-element-focus-color: var(--pico-primary-border); + --pico-form-element-disabled-opacity: 0.5; + --pico-form-element-invalid-border-color: #964a50; + --pico-form-element-invalid-active-border-color: #b7403b; + --pico-form-element-invalid-focus-color: var(--pico-form-element-invalid-active-border-color); + --pico-form-element-valid-border-color: #2a7b6f; + --pico-form-element-valid-active-border-color: #16896a; + --pico-form-element-valid-focus-color: var(--pico-form-element-valid-active-border-color); + --pico-switch-background-color: #333c4e; + --pico-switch-checked-background-color: var(--pico-primary-background); + --pico-switch-color: #fff; + --pico-switch-thumb-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-range-border-color: #202632; + --pico-range-active-border-color: #2a3140; + --pico-range-thumb-border-color: var(--pico-background-color); + --pico-range-thumb-color: var(--pico-secondary-background); + --pico-range-thumb-active-color: var(--pico-primary-background); + --pico-accordion-border-color: var(--pico-muted-border-color); + --pico-accordion-active-summary-color: var(--pico-primary-hover); + --pico-accordion-close-summary-color: var(--pico-color); + --pico-accordion-open-summary-color: var(--pico-muted-color); + --pico-card-background-color: #181c25; + --pico-card-border-color: var(--pico-card-background-color); + --pico-card-box-shadow: var(--pico-box-shadow); + --pico-card-sectioning-background-color: #1a1f28; + --pico-dropdown-background-color: #181c25; + --pico-dropdown-border-color: #202632; + --pico-dropdown-box-shadow: var(--pico-box-shadow); + --pico-dropdown-color: var(--pico-color); + --pico-dropdown-hover-background-color: #202632; + --pico-loading-spinner-opacity: 0.5; + --pico-modal-overlay-background-color: rgba(8, 9, 10, 0.75); + --pico-progress-background-color: #202632; + --pico-progress-color: var(--pico-primary-background); + --pico-tooltip-background-color: var(--pico-contrast-background); + --pico-tooltip-color: var(--pico-contrast-inverse); + --pico-icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(42, 123, 111)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(150, 74, 80)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); + color-scheme: dark; + } + :root:not([data-theme]) input:is([type=submit], + [type=button], + [type=reset], + [type=checkbox], + [type=radio], + [type=file]) { + --pico-form-element-focus-color: var(--pico-primary-focus); + } + :root:not([data-theme]) details summary[role=button].contrast:not(.outline)::after { + filter: brightness(0); + } + :root:not([data-theme]) [aria-busy=true]:not(input, select, textarea).contrast:is(button, + [type=submit], + [type=button], + [type=reset], + [role=button]):not(.outline)::before { + filter: brightness(0); + } +} +[data-theme=dark] { + --pico-background-color: #13171f; + --pico-color: #c2c7d0; + --pico-text-selection-color: rgba(137, 153, 249, 0.1875); + --pico-muted-color: #7b8495; + --pico-muted-border-color: #202632; + --pico-primary: #8999f9; + --pico-primary-background: #2060df; + --pico-primary-border: var(--pico-primary-background); + --pico-primary-underline: rgba(137, 153, 249, 0.5); + --pico-primary-hover: #aeb5fb; + --pico-primary-hover-background: #3c71f7; + --pico-primary-hover-border: var(--pico-primary-hover-background); + --pico-primary-hover-underline: var(--pico-primary-hover); + --pico-primary-focus: rgba(137, 153, 249, 0.375); + --pico-primary-inverse: #fff; + --pico-secondary: #969eaf; + --pico-secondary-background: #525f7a; + --pico-secondary-border: var(--pico-secondary-background); + --pico-secondary-underline: rgba(150, 158, 175, 0.5); + --pico-secondary-hover: #b3b9c5; + --pico-secondary-hover-background: #5d6b89; + --pico-secondary-hover-border: var(--pico-secondary-hover-background); + --pico-secondary-hover-underline: var(--pico-secondary-hover); + --pico-secondary-focus: rgba(144, 158, 190, 0.25); + --pico-secondary-inverse: #fff; + --pico-contrast: #dfe3eb; + --pico-contrast-background: #eff1f4; + --pico-contrast-border: var(--pico-contrast-background); + --pico-contrast-underline: rgba(223, 227, 235, 0.5); + --pico-contrast-hover: #fff; + --pico-contrast-hover-background: #fff; + --pico-contrast-hover-border: var(--pico-contrast-hover-background); + --pico-contrast-hover-underline: var(--pico-contrast-hover); + --pico-contrast-focus: rgba(207, 213, 226, 0.25); + --pico-contrast-inverse: #000; + --pico-box-shadow: 0.0145rem 0.029rem 0.174rem rgba(7, 9, 12, 0.01698), 0.0335rem 0.067rem 0.402rem rgba(7, 9, 12, 0.024), 0.0625rem 0.125rem 0.75rem rgba(7, 9, 12, 0.03), 0.1125rem 0.225rem 1.35rem rgba(7, 9, 12, 0.036), 0.2085rem 0.417rem 2.502rem rgba(7, 9, 12, 0.04302), 0.5rem 1rem 6rem rgba(7, 9, 12, 0.06), 0 0 0 0.0625rem rgba(7, 9, 12, 0.015); + --pico-h1-color: #f0f1f3; + --pico-h2-color: #e0e3e7; + --pico-h3-color: #c2c7d0; + --pico-h4-color: #b3b9c5; + --pico-h5-color: #a4acba; + --pico-h6-color: #8891a4; + --pico-mark-background-color: #014063; + --pico-mark-color: #fff; + --pico-ins-color: #62af9a; + --pico-del-color: #ce7e7b; + --pico-blockquote-border-color: var(--pico-muted-border-color); + --pico-blockquote-footer-color: var(--pico-muted-color); + --pico-button-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-table-border-color: var(--pico-muted-border-color); + --pico-table-row-stripped-background-color: rgba(111, 120, 135, 0.0375); + --pico-code-background-color: #1a1f28; + --pico-code-color: #8891a4; + --pico-code-kbd-background-color: var(--pico-color); + --pico-code-kbd-color: var(--pico-background-color); + --pico-form-element-background-color: #1c212c; + --pico-form-element-selected-background-color: #2a3140; + --pico-form-element-border-color: #2a3140; + --pico-form-element-color: #e0e3e7; + --pico-form-element-placeholder-color: #8891a4; + --pico-form-element-active-background-color: #1a1f28; + --pico-form-element-active-border-color: var(--pico-primary-border); + --pico-form-element-focus-color: var(--pico-primary-border); + --pico-form-element-disabled-opacity: 0.5; + --pico-form-element-invalid-border-color: #964a50; + --pico-form-element-invalid-active-border-color: #b7403b; + --pico-form-element-invalid-focus-color: var(--pico-form-element-invalid-active-border-color); + --pico-form-element-valid-border-color: #2a7b6f; + --pico-form-element-valid-active-border-color: #16896a; + --pico-form-element-valid-focus-color: var(--pico-form-element-valid-active-border-color); + --pico-switch-background-color: #333c4e; + --pico-switch-checked-background-color: var(--pico-primary-background); + --pico-switch-color: #fff; + --pico-switch-thumb-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-range-border-color: #202632; + --pico-range-active-border-color: #2a3140; + --pico-range-thumb-border-color: var(--pico-background-color); + --pico-range-thumb-color: var(--pico-secondary-background); + --pico-range-thumb-active-color: var(--pico-primary-background); + --pico-accordion-border-color: var(--pico-muted-border-color); + --pico-accordion-active-summary-color: var(--pico-primary-hover); + --pico-accordion-close-summary-color: var(--pico-color); + --pico-accordion-open-summary-color: var(--pico-muted-color); + --pico-card-background-color: #181c25; + --pico-card-border-color: var(--pico-card-background-color); + --pico-card-box-shadow: var(--pico-box-shadow); + --pico-card-sectioning-background-color: #1a1f28; + --pico-dropdown-background-color: #181c25; + --pico-dropdown-border-color: #202632; + --pico-dropdown-box-shadow: var(--pico-box-shadow); + --pico-dropdown-color: var(--pico-color); + --pico-dropdown-hover-background-color: #202632; + --pico-loading-spinner-opacity: 0.5; + --pico-modal-overlay-background-color: rgba(8, 9, 10, 0.75); + --pico-progress-background-color: #202632; + --pico-progress-color: var(--pico-primary-background); + --pico-tooltip-background-color: var(--pico-contrast-background); + --pico-tooltip-color: var(--pico-contrast-inverse); + --pico-icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(42, 123, 111)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(150, 74, 80)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); + color-scheme: dark; +} +[data-theme=dark] input:is([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]) { + --pico-form-element-focus-color: var(--pico-primary-focus); +} +[data-theme=dark] details summary[role=button].contrast:not(.outline)::after { + filter: brightness(0); +} +[data-theme=dark] [aria-busy=true]:not(input, select, textarea).contrast:is(button, +[type=submit], +[type=button], +[type=reset], +[role=button]):not(.outline)::before { + filter: brightness(0); +} + +progress, +[type=checkbox], +[type=radio], +[type=range] { + accent-color: var(--pico-primary); +} + +/** + * Document + * Content-box & Responsive typography + */ +*, +*::before, +*::after { + box-sizing: border-box; + background-repeat: no-repeat; +} + +::before, +::after { + text-decoration: inherit; + vertical-align: inherit; +} + +:where(:root) { + -webkit-tap-highlight-color: transparent; + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + text-size-adjust: 100%; + background-color: var(--pico-background-color); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + font-size: var(--pico-font-size); + line-height: var(--pico-line-height); + font-family: var(--pico-font-family); + text-underline-offset: var(--pico-text-underline-offset); + text-rendering: optimizeLegibility; + overflow-wrap: break-word; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; +} + +/** + * Landmarks + */ +body { + width: 100%; + margin: 0; +} + +main { + display: block; +} + +body > header, +body > main, +body > footer { + padding-block: var(--pico-block-spacing-vertical); +} + +/** + * Section + */ +section { + margin-bottom: var(--pico-block-spacing-vertical); +} + +/** + * Container + */ +.container, +.container-fluid { + width: 100%; + margin-right: auto; + margin-left: auto; + padding-right: var(--pico-spacing); + padding-left: var(--pico-spacing); +} + +@media (min-width: 576px) { + .container { + max-width: 510px; + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 768px) { + .container { + max-width: 700px; + } +} +@media (min-width: 1024px) { + .container { + max-width: 950px; + } +} +@media (min-width: 1280px) { + .container { + max-width: 1200px; + } +} +@media (min-width: 1536px) { + .container { + max-width: 1450px; + } +} + +/** + * Grid + * Minimal grid system with auto-layout columns + */ +.grid { + grid-column-gap: var(--pico-grid-column-gap); + grid-row-gap: var(--pico-grid-row-gap); + display: grid; + grid-template-columns: 1fr; +} +@media (min-width: 768px) { + .grid { + grid-template-columns: repeat(auto-fit, minmax(0%, 1fr)); + } +} +.grid > * { + min-width: 0; +} + +/** + * Overflow auto + */ +.overflow-auto { + overflow: auto; +} + +/** + * Typography + */ +b, +strong { + font-weight: bolder; +} + +sub, +sup { + position: relative; + font-size: 0.75em; + line-height: 0; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +address, +blockquote, +dl, +ol, +p, +pre, +table, +ul { + margin-top: 0; + margin-bottom: var(--pico-typography-spacing-vertical); + color: var(--pico-color); + font-style: normal; + font-weight: var(--pico-font-weight); +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin-top: 0; + margin-bottom: var(--pico-typography-spacing-vertical); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + font-size: var(--pico-font-size); + line-height: var(--pico-line-height); + font-family: var(--pico-font-family); +} + +h1 { + --pico-color: var(--pico-h1-color); +} + +h2 { + --pico-color: var(--pico-h2-color); +} + +h3 { + --pico-color: var(--pico-h3-color); +} + +h4 { + --pico-color: var(--pico-h4-color); +} + +h5 { + --pico-color: var(--pico-h5-color); +} + +h6 { + --pico-color: var(--pico-h6-color); +} + +:where(article, address, blockquote, dl, figure, form, ol, p, pre, table, ul) ~ :is(h1, h2, h3, h4, h5, h6) { + margin-top: var(--pico-typography-spacing-top); +} + +p { + margin-bottom: var(--pico-typography-spacing-vertical); +} + +hgroup { + margin-bottom: var(--pico-typography-spacing-vertical); +} +hgroup > * { + margin-top: 0; + margin-bottom: 0; +} +hgroup > *:not(:first-child):last-child { + --pico-color: var(--pico-muted-color); + --pico-font-weight: unset; + font-size: 1rem; +} + +:where(ol, ul) li { + margin-bottom: calc(var(--pico-typography-spacing-vertical) * 0.25); +} + +:where(dl, ol, ul) :where(dl, ol, ul) { + margin: 0; + margin-top: calc(var(--pico-typography-spacing-vertical) * 0.25); +} + +ul li { + list-style: square; +} + +mark { + padding: 0.125rem 0.25rem; + background-color: var(--pico-mark-background-color); + color: var(--pico-mark-color); + vertical-align: baseline; +} + +blockquote { + display: block; + margin: var(--pico-typography-spacing-vertical) 0; + padding: var(--pico-spacing); + border-right: none; + border-left: 0.25rem solid var(--pico-blockquote-border-color); + border-inline-start: 0.25rem solid var(--pico-blockquote-border-color); + border-inline-end: none; +} +blockquote footer { + margin-top: calc(var(--pico-typography-spacing-vertical) * 0.5); + color: var(--pico-blockquote-footer-color); +} + +abbr[title] { + border-bottom: 1px dotted; + text-decoration: none; + cursor: help; +} + +ins { + color: var(--pico-ins-color); + text-decoration: none; +} + +del { + color: var(--pico-del-color); +} + +::-moz-selection { + background-color: var(--pico-text-selection-color); +} + +::selection { + background-color: var(--pico-text-selection-color); +} + +/** + * Link + */ +:where(a:not([role=button])), +[role=link] { + --pico-color: var(--pico-primary); + --pico-background-color: transparent; + --pico-underline: var(--pico-primary-underline); + outline: none; + background-color: var(--pico-background-color); + color: var(--pico-color); + -webkit-text-decoration: var(--pico-text-decoration); + text-decoration: var(--pico-text-decoration); + text-decoration-color: var(--pico-underline); + text-underline-offset: 0.125em; + transition: background-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition), -webkit-text-decoration var(--pico-transition); + transition: background-color var(--pico-transition), color var(--pico-transition), text-decoration var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), color var(--pico-transition), text-decoration var(--pico-transition), box-shadow var(--pico-transition), -webkit-text-decoration var(--pico-transition); +} +:where(a:not([role=button])):is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[role=link]:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-primary-hover); + --pico-underline: var(--pico-primary-hover-underline); + --pico-text-decoration: underline; +} +:where(a:not([role=button])):focus-visible, +[role=link]:focus-visible { + box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); +} +:where(a:not([role=button])).secondary, +[role=link].secondary { + --pico-color: var(--pico-secondary); + --pico-underline: var(--pico-secondary-underline); +} +:where(a:not([role=button])).secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[role=link].secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-secondary-hover); + --pico-underline: var(--pico-secondary-hover-underline); +} +:where(a:not([role=button])).contrast, +[role=link].contrast { + --pico-color: var(--pico-contrast); + --pico-underline: var(--pico-contrast-underline); +} +:where(a:not([role=button])).contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[role=link].contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-contrast-hover); + --pico-underline: var(--pico-contrast-hover-underline); +} + +a[role=button] { + display: inline-block; +} + +/** + * Button + */ +button { + margin: 0; + overflow: visible; + font-family: inherit; + text-transform: none; +} + +button, +[type=submit], +[type=reset], +[type=button] { + -webkit-appearance: button; +} + +button, +[type=submit], +[type=reset], +[type=button], +[type=file]::file-selector-button, +[role=button] { + --pico-background-color: var(--pico-primary-background); + --pico-border-color: var(--pico-primary-border); + --pico-color: var(--pico-primary-inverse); + --pico-box-shadow: var(--pico-button-box-shadow, 0 0 0 rgba(0, 0, 0, 0)); + padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal); + border: var(--pico-border-width) solid var(--pico-border-color); + border-radius: var(--pico-border-radius); + outline: none; + background-color: var(--pico-background-color); + box-shadow: var(--pico-box-shadow); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + font-size: 1rem; + line-height: var(--pico-line-height); + text-align: center; + text-decoration: none; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + transition: background-color var(--pico-transition), border-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition); +} +button:is([aria-current]:not([aria-current=false])), button:is(:hover, :active, :focus), +[type=submit]:is([aria-current]:not([aria-current=false])), +[type=submit]:is(:hover, :active, :focus), +[type=reset]:is([aria-current]:not([aria-current=false])), +[type=reset]:is(:hover, :active, :focus), +[type=button]:is([aria-current]:not([aria-current=false])), +[type=button]:is(:hover, :active, :focus), +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])), +[type=file]::file-selector-button:is(:hover, :active, :focus), +[role=button]:is([aria-current]:not([aria-current=false])), +[role=button]:is(:hover, :active, :focus) { + --pico-background-color: var(--pico-primary-hover-background); + --pico-border-color: var(--pico-primary-hover-border); + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)); + --pico-color: var(--pico-primary-inverse); +} +button:focus, button:is([aria-current]:not([aria-current=false])):focus, +[type=submit]:focus, +[type=submit]:is([aria-current]:not([aria-current=false])):focus, +[type=reset]:focus, +[type=reset]:is([aria-current]:not([aria-current=false])):focus, +[type=button]:focus, +[type=button]:is([aria-current]:not([aria-current=false])):focus, +[type=file]::file-selector-button:focus, +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])):focus, +[role=button]:focus, +[role=button]:is([aria-current]:not([aria-current=false])):focus { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); +} + +[type=submit], +[type=reset], +[type=button] { + margin-bottom: var(--pico-spacing); +} + +:is(button, [type=submit], [type=button], [role=button]).secondary, +[type=reset], +[type=file]::file-selector-button { + --pico-background-color: var(--pico-secondary-background); + --pico-border-color: var(--pico-secondary-border); + --pico-color: var(--pico-secondary-inverse); + cursor: pointer; +} +:is(button, [type=submit], [type=button], [role=button]).secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=reset]:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-background-color: var(--pico-secondary-hover-background); + --pico-border-color: var(--pico-secondary-hover-border); + --pico-color: var(--pico-secondary-inverse); +} +:is(button, [type=submit], [type=button], [role=button]).secondary:focus, :is(button, [type=submit], [type=button], [role=button]).secondary:is([aria-current]:not([aria-current=false])):focus, +[type=reset]:focus, +[type=reset]:is([aria-current]:not([aria-current=false])):focus, +[type=file]::file-selector-button:focus, +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])):focus { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-secondary-focus); +} + +:is(button, [type=submit], [type=button], [role=button]).contrast { + --pico-background-color: var(--pico-contrast-background); + --pico-border-color: var(--pico-contrast-border); + --pico-color: var(--pico-contrast-inverse); +} +:is(button, [type=submit], [type=button], [role=button]).contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-background-color: var(--pico-contrast-hover-background); + --pico-border-color: var(--pico-contrast-hover-border); + --pico-color: var(--pico-contrast-inverse); +} +:is(button, [type=submit], [type=button], [role=button]).contrast:focus, :is(button, [type=submit], [type=button], [role=button]).contrast:is([aria-current]:not([aria-current=false])):focus { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-contrast-focus); +} + +:is(button, [type=submit], [type=button], [role=button]).outline, +[type=reset].outline { + --pico-background-color: transparent; + --pico-color: var(--pico-primary); + --pico-border-color: var(--pico-primary); +} +:is(button, [type=submit], [type=button], [role=button]).outline:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=reset].outline:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-background-color: transparent; + --pico-color: var(--pico-primary-hover); + --pico-border-color: var(--pico-primary-hover); +} + +:is(button, [type=submit], [type=button], [role=button]).outline.secondary, +[type=reset].outline { + --pico-color: var(--pico-secondary); + --pico-border-color: var(--pico-secondary); +} +:is(button, [type=submit], [type=button], [role=button]).outline.secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=reset].outline:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-secondary-hover); + --pico-border-color: var(--pico-secondary-hover); +} + +:is(button, [type=submit], [type=button], [role=button]).outline.contrast { + --pico-color: var(--pico-contrast); + --pico-border-color: var(--pico-contrast); +} +:is(button, [type=submit], [type=button], [role=button]).outline.contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-contrast-hover); + --pico-border-color: var(--pico-contrast-hover); +} + +:where(button, [type=submit], [type=reset], [type=button], [role=button])[disabled], +:where(fieldset[disabled]) :is(button, [type=submit], [type=button], [type=reset], [role=button]) { + opacity: 0.5; + pointer-events: none; +} + +/** + * Table + */ +:where(table) { + width: 100%; + border-collapse: collapse; + border-spacing: 0; + text-indent: 0; +} + +th, +td { + padding: calc(var(--pico-spacing) / 2) var(--pico-spacing); + border-bottom: var(--pico-border-width) solid var(--pico-table-border-color); + background-color: var(--pico-background-color); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + text-align: left; + text-align: start; +} + +tfoot th, +tfoot td { + border-top: var(--pico-border-width) solid var(--pico-table-border-color); + border-bottom: 0; +} + +table.striped tbody tr:nth-child(odd) th, +table.striped tbody tr:nth-child(odd) td { + background-color: var(--pico-table-row-stripped-background-color); +} + +/** + * Embedded content + */ +:where(audio, canvas, iframe, img, svg, video) { + vertical-align: middle; +} + +audio, +video { + display: inline-block; +} + +audio:not([controls]) { + display: none; + height: 0; +} + +:where(iframe) { + border-style: none; +} + +img { + max-width: 100%; + height: auto; + border-style: none; +} + +:where(svg:not([fill])) { + fill: currentColor; +} + +svg:not(:root) { + overflow: hidden; +} + +/** + * Code + */ +pre, +code, +kbd, +samp { + font-size: 0.875em; + font-family: var(--pico-font-family); +} + +pre code { + font-size: inherit; + font-family: inherit; +} + +pre { + -ms-overflow-style: scrollbar; + overflow: auto; +} + +pre, +code, +kbd { + border-radius: var(--pico-border-radius); + background: var(--pico-code-background-color); + color: var(--pico-code-color); + font-weight: var(--pico-font-weight); + line-height: initial; +} + +code, +kbd { + display: inline-block; + padding: 0.375rem; +} + +pre { + display: block; + margin-bottom: var(--pico-spacing); + overflow-x: auto; +} +pre > code { + display: block; + padding: var(--pico-spacing); + background: none; + line-height: var(--pico-line-height); +} + +kbd { + background-color: var(--pico-code-kbd-background-color); + color: var(--pico-code-kbd-color); + vertical-align: baseline; +} + +/** + * Figure + */ +figure { + display: block; + margin: 0; + padding: 0; +} +figure figcaption { + padding: calc(var(--pico-spacing) * 0.5) 0; + color: var(--pico-muted-color); +} + +/** + * Miscs + */ +hr { + height: 0; + margin: var(--pico-typography-spacing-vertical) 0; + border: 0; + border-top: 1px solid var(--pico-muted-border-color); + color: inherit; +} + +[hidden], +template { + display: none !important; +} + +canvas { + display: inline-block; +} + +/** + * Basics form elements + */ +input, +optgroup, +select, +textarea { + margin: 0; + font-size: 1rem; + line-height: var(--pico-line-height); + font-family: inherit; + letter-spacing: inherit; +} + +input { + overflow: visible; +} + +select { + text-transform: none; +} + +legend { + max-width: 100%; + padding: 0; + color: inherit; + white-space: normal; +} + +textarea { + overflow: auto; +} + +[type=checkbox], +[type=radio] { + padding: 0; +} + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +[type=search] { + -webkit-appearance: textfield; + outline-offset: -2px; +} + +[type=search]::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; +} + +::-moz-focus-inner { + padding: 0; + border-style: none; +} + +:-moz-focusring { + outline: none; +} + +:-moz-ui-invalid { + box-shadow: none; +} + +::-ms-expand { + display: none; +} + +[type=file], +[type=range] { + padding: 0; + border-width: 0; +} + +input:not([type=checkbox], [type=radio], [type=range]) { + height: calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2); +} + +fieldset { + width: 100%; + margin: 0; + margin-bottom: var(--pico-spacing); + padding: 0; + border: 0; +} + +label, +fieldset legend { + display: block; + margin-bottom: calc(var(--pico-spacing) * 0.375); + color: var(--pico-color); + font-weight: var(--pico-form-label-font-weight, var(--pico-font-weight)); +} + +fieldset legend { + margin-bottom: calc(var(--pico-spacing) * 0.5); +} + +input:not([type=checkbox], [type=radio]), +button[type=submit], +select, +textarea { + width: 100%; +} + +input:not([type=checkbox], [type=radio], [type=range], [type=file]), +select, +textarea { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal); +} + +input, +select, +textarea { + --pico-background-color: var(--pico-form-element-background-color); + --pico-border-color: var(--pico-form-element-border-color); + --pico-color: var(--pico-form-element-color); + --pico-box-shadow: none; + border: var(--pico-border-width) solid var(--pico-border-color); + border-radius: var(--pico-border-radius); + outline: none; + background-color: var(--pico-background-color); + box-shadow: var(--pico-box-shadow); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + transition: background-color var(--pico-transition), border-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition); +} + +input:not([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[readonly]):is(:active, :focus), +:where(select, textarea):not([readonly]):is(:active, :focus) { + --pico-background-color: var(--pico-form-element-active-background-color); +} + +input:not([type=submit], [type=button], [type=reset], [role=switch], [readonly]):is(:active, :focus), +:where(select, textarea):not([readonly]):is(:active, :focus) { + --pico-border-color: var(--pico-form-element-active-border-color); +} + +input:not([type=submit], +[type=button], +[type=reset], +[type=range], +[type=file], +[readonly]):focus, +:where(select, textarea):not([readonly]):focus { + --pico-box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-focus-color); +} + +input:not([type=submit], [type=button], [type=reset])[disabled], +select[disabled], +textarea[disabled], +label[aria-disabled=true], +:where(fieldset[disabled]) :is(input:not([type=submit], [type=button], [type=reset]), select, textarea) { + opacity: var(--pico-form-element-disabled-opacity); + pointer-events: none; +} + +label[aria-disabled=true] input[disabled] { + opacity: 1; +} + +:where(input, select, textarea):not([type=checkbox], +[type=radio], +[type=date], +[type=datetime-local], +[type=month], +[type=time], +[type=week], +[type=range])[aria-invalid] { + padding-right: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem) !important; + padding-left: var(--pico-form-element-spacing-horizontal); + padding-inline-start: var(--pico-form-element-spacing-horizontal) !important; + padding-inline-end: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem) !important; + background-position: center right 0.75rem; + background-size: 1rem auto; + background-repeat: no-repeat; +} +:where(input, select, textarea):not([type=checkbox], +[type=radio], +[type=date], +[type=datetime-local], +[type=month], +[type=time], +[type=week], +[type=range])[aria-invalid=false]:not(select) { + background-image: var(--pico-icon-valid); +} +:where(input, select, textarea):not([type=checkbox], +[type=radio], +[type=date], +[type=datetime-local], +[type=month], +[type=time], +[type=week], +[type=range])[aria-invalid=true]:not(select) { + background-image: var(--pico-icon-invalid); +} +:where(input, select, textarea)[aria-invalid=false] { + --pico-border-color: var(--pico-form-element-valid-border-color); +} +:where(input, select, textarea)[aria-invalid=false]:is(:active, :focus) { + --pico-border-color: var(--pico-form-element-valid-active-border-color) !important; +} +:where(input, select, textarea)[aria-invalid=false]:is(:active, :focus):not([type=checkbox], [type=radio]) { + --pico-box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-valid-focus-color) !important; +} +:where(input, select, textarea)[aria-invalid=true] { + --pico-border-color: var(--pico-form-element-invalid-border-color); +} +:where(input, select, textarea)[aria-invalid=true]:is(:active, :focus) { + --pico-border-color: var(--pico-form-element-invalid-active-border-color) !important; +} +:where(input, select, textarea)[aria-invalid=true]:is(:active, :focus):not([type=checkbox], [type=radio]) { + --pico-box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-invalid-focus-color) !important; +} + +[dir=rtl] :where(input, select, textarea):not([type=checkbox], [type=radio]):is([aria-invalid], [aria-invalid=true], [aria-invalid=false]) { + background-position: center left 0.75rem; +} + +input::placeholder, +input::-webkit-input-placeholder, +textarea::placeholder, +textarea::-webkit-input-placeholder, +select:invalid { + color: var(--pico-form-element-placeholder-color); + opacity: 1; +} + +input:not([type=checkbox], [type=radio]), +select, +textarea { + margin-bottom: var(--pico-spacing); +} + +select::-ms-expand { + border: 0; + background-color: transparent; +} +select:not([multiple], [size]) { + padding-right: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem); + padding-left: var(--pico-form-element-spacing-horizontal); + padding-inline-start: var(--pico-form-element-spacing-horizontal); + padding-inline-end: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem); + background-image: var(--pico-icon-chevron); + background-position: center right 0.75rem; + background-size: 1rem auto; + background-repeat: no-repeat; +} +select[multiple] option:checked { + background: var(--pico-form-element-selected-background-color); + color: var(--pico-form-element-color); +} + +[dir=rtl] select:not([multiple], [size]) { + background-position: center left 0.75rem; +} + +textarea { + display: block; + resize: vertical; +} +textarea[aria-invalid] { + --pico-icon-height: calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2); + background-position: top right 0.75rem !important; + background-size: 1rem var(--pico-icon-height) !important; +} + +:where(input, select, textarea, fieldset, .grid) + small { + display: block; + width: 100%; + margin-top: calc(var(--pico-spacing) * -0.75); + margin-bottom: var(--pico-spacing); + color: var(--pico-muted-color); +} +:where(input, select, textarea, fieldset, .grid)[aria-invalid=false] + small { + color: var(--pico-ins-color); +} +:where(input, select, textarea, fieldset, .grid)[aria-invalid=true] + small { + color: var(--pico-del-color); +} + +label > :where(input, select, textarea) { + margin-top: calc(var(--pico-spacing) * 0.25); +} + +/** + * Checkboxes, Radios and Switches + */ +label:has([type=checkbox], [type=radio]) { + width: -moz-fit-content; + width: fit-content; + cursor: pointer; +} + +[type=checkbox], +[type=radio] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: 1.25em; + height: 1.25em; + margin-top: -0.125em; + margin-inline-end: 0.5em; + border-width: var(--pico-border-width); + vertical-align: middle; + cursor: pointer; +} +[type=checkbox]::-ms-check, +[type=radio]::-ms-check { + display: none; +} +[type=checkbox]:checked, [type=checkbox]:checked:active, [type=checkbox]:checked:focus, +[type=radio]:checked, +[type=radio]:checked:active, +[type=radio]:checked:focus { + --pico-background-color: var(--pico-primary-background); + --pico-border-color: var(--pico-primary-border); + background-image: var(--pico-icon-checkbox); + background-position: center; + background-size: 0.75em auto; + background-repeat: no-repeat; +} +[type=checkbox] ~ label, +[type=radio] ~ label { + display: inline-block; + margin-bottom: 0; + cursor: pointer; +} +[type=checkbox] ~ label:not(:last-of-type), +[type=radio] ~ label:not(:last-of-type) { + margin-inline-end: 1em; +} + +[type=checkbox]:indeterminate { + --pico-background-color: var(--pico-primary-background); + --pico-border-color: var(--pico-primary-border); + background-image: var(--pico-icon-minus); + background-position: center; + background-size: 0.75em auto; + background-repeat: no-repeat; +} + +[type=radio] { + border-radius: 50%; +} +[type=radio]:checked, [type=radio]:checked:active, [type=radio]:checked:focus { + --pico-background-color: var(--pico-primary-inverse); + border-width: 0.35em; + background-image: none; +} + +[type=checkbox][role=switch] { + --pico-background-color: var(--pico-switch-background-color); + --pico-color: var(--pico-switch-color); + width: 2.25em; + height: 1.25em; + border: var(--pico-border-width) solid var(--pico-border-color); + border-radius: 1.25em; + background-color: var(--pico-background-color); + line-height: 1.25em; +} +[type=checkbox][role=switch]:not([aria-invalid]) { + --pico-border-color: var(--pico-switch-background-color); +} +[type=checkbox][role=switch]:before { + display: block; + aspect-ratio: 1; + height: 100%; + border-radius: 50%; + background-color: var(--pico-color); + box-shadow: var(--pico-switch-thumb-box-shadow); + content: ""; + transition: margin 0.1s ease-in-out; +} +[type=checkbox][role=switch]:focus { + --pico-background-color: var(--pico-switch-background-color); + --pico-border-color: var(--pico-switch-background-color); +} +[type=checkbox][role=switch]:checked { + --pico-background-color: var(--pico-switch-checked-background-color); + --pico-border-color: var(--pico-switch-checked-background-color); + background-image: none; +} +[type=checkbox][role=switch]:checked::before { + margin-inline-start: calc(2.25em - 1.25em); +} +[type=checkbox][role=switch][disabled] { + --pico-background-color: var(--pico-border-color); +} + +[type=checkbox][aria-invalid=false]:checked, [type=checkbox][aria-invalid=false]:checked:active, [type=checkbox][aria-invalid=false]:checked:focus, +[type=checkbox][role=switch][aria-invalid=false]:checked, +[type=checkbox][role=switch][aria-invalid=false]:checked:active, +[type=checkbox][role=switch][aria-invalid=false]:checked:focus { + --pico-background-color: var(--pico-form-element-valid-border-color); +} +[type=checkbox]:checked[aria-invalid=true], [type=checkbox]:checked:active[aria-invalid=true], [type=checkbox]:checked:focus[aria-invalid=true], +[type=checkbox][role=switch]:checked[aria-invalid=true], +[type=checkbox][role=switch]:checked:active[aria-invalid=true], +[type=checkbox][role=switch]:checked:focus[aria-invalid=true] { + --pico-background-color: var(--pico-form-element-invalid-border-color); +} + +[type=checkbox][aria-invalid=false]:checked, [type=checkbox][aria-invalid=false]:checked:active, [type=checkbox][aria-invalid=false]:checked:focus, +[type=radio][aria-invalid=false]:checked, +[type=radio][aria-invalid=false]:checked:active, +[type=radio][aria-invalid=false]:checked:focus, +[type=checkbox][role=switch][aria-invalid=false]:checked, +[type=checkbox][role=switch][aria-invalid=false]:checked:active, +[type=checkbox][role=switch][aria-invalid=false]:checked:focus { + --pico-border-color: var(--pico-form-element-valid-border-color); +} +[type=checkbox]:checked[aria-invalid=true], [type=checkbox]:checked:active[aria-invalid=true], [type=checkbox]:checked:focus[aria-invalid=true], +[type=radio]:checked[aria-invalid=true], +[type=radio]:checked:active[aria-invalid=true], +[type=radio]:checked:focus[aria-invalid=true], +[type=checkbox][role=switch]:checked[aria-invalid=true], +[type=checkbox][role=switch]:checked:active[aria-invalid=true], +[type=checkbox][role=switch]:checked:focus[aria-invalid=true] { + --pico-border-color: var(--pico-form-element-invalid-border-color); +} + +/** + * Input type color + */ +[type=color]::-webkit-color-swatch-wrapper { + padding: 0; +} +[type=color]::-moz-focus-inner { + padding: 0; +} +[type=color]::-webkit-color-swatch { + border: 0; + border-radius: calc(var(--pico-border-radius) * 0.5); +} +[type=color]::-moz-color-swatch { + border: 0; + border-radius: calc(var(--pico-border-radius) * 0.5); +} + +/** + * Input type datetime + */ +input:not([type=checkbox], [type=radio], [type=range], [type=file]):is([type=date], [type=datetime-local], [type=month], [type=time], [type=week]) { + --pico-icon-position: 0.75rem; + --pico-icon-width: 1rem; + padding-right: calc(var(--pico-icon-width) + var(--pico-icon-position)); + background-image: var(--pico-icon-date); + background-position: center right var(--pico-icon-position); + background-size: var(--pico-icon-width) auto; + background-repeat: no-repeat; +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=time] { + background-image: var(--pico-icon-time); +} + +[type=date]::-webkit-calendar-picker-indicator, +[type=datetime-local]::-webkit-calendar-picker-indicator, +[type=month]::-webkit-calendar-picker-indicator, +[type=time]::-webkit-calendar-picker-indicator, +[type=week]::-webkit-calendar-picker-indicator { + width: var(--pico-icon-width); + margin-right: calc(var(--pico-icon-width) * -1); + margin-left: var(--pico-icon-position); + opacity: 0; +} + +@-moz-document url-prefix() { + [type=date], + [type=datetime-local], + [type=month], + [type=time], + [type=week] { + padding-right: var(--pico-form-element-spacing-horizontal) !important; + background-image: none !important; + } +} +[dir=rtl] :is([type=date], [type=datetime-local], [type=month], [type=time], [type=week]) { + text-align: right; +} + +/** + * Input type file + */ +[type=file] { + --pico-color: var(--pico-muted-color); + margin-left: calc(var(--pico-outline-width) * -1); + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) 0; + padding-left: var(--pico-outline-width); + border: 0; + border-radius: 0; + background: none; +} +[type=file]::file-selector-button { + margin-right: calc(var(--pico-spacing) / 2); + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) var(--pico-form-element-spacing-horizontal); +} +[type=file]:is(:hover, :active, :focus)::file-selector-button { + --pico-background-color: var(--pico-secondary-hover-background); + --pico-border-color: var(--pico-secondary-hover-border); +} +[type=file]:focus::file-selector-button { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-secondary-focus); +} + +/** + * Input type range + */ +[type=range] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: 100%; + height: 1.25rem; + background: none; +} +[type=range]::-webkit-slider-runnable-track { + width: 100%; + height: 0.375rem; + border-radius: var(--pico-border-radius); + background-color: var(--pico-range-border-color); + -webkit-transition: background-color var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), box-shadow var(--pico-transition); +} +[type=range]::-moz-range-track { + width: 100%; + height: 0.375rem; + border-radius: var(--pico-border-radius); + background-color: var(--pico-range-border-color); + -moz-transition: background-color var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), box-shadow var(--pico-transition); +} +[type=range]::-ms-track { + width: 100%; + height: 0.375rem; + border-radius: var(--pico-border-radius); + background-color: var(--pico-range-border-color); + -ms-transition: background-color var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), box-shadow var(--pico-transition); +} +[type=range]::-webkit-slider-thumb { + -webkit-appearance: none; + width: 1.25rem; + height: 1.25rem; + margin-top: -0.4375rem; + border: 2px solid var(--pico-range-thumb-border-color); + border-radius: 50%; + background-color: var(--pico-range-thumb-color); + cursor: pointer; + -webkit-transition: background-color var(--pico-transition), transform var(--pico-transition); + transition: background-color var(--pico-transition), transform var(--pico-transition); +} +[type=range]::-moz-range-thumb { + -webkit-appearance: none; + width: 1.25rem; + height: 1.25rem; + margin-top: -0.4375rem; + border: 2px solid var(--pico-range-thumb-border-color); + border-radius: 50%; + background-color: var(--pico-range-thumb-color); + cursor: pointer; + -moz-transition: background-color var(--pico-transition), transform var(--pico-transition); + transition: background-color var(--pico-transition), transform var(--pico-transition); +} +[type=range]::-ms-thumb { + -webkit-appearance: none; + width: 1.25rem; + height: 1.25rem; + margin-top: -0.4375rem; + border: 2px solid var(--pico-range-thumb-border-color); + border-radius: 50%; + background-color: var(--pico-range-thumb-color); + cursor: pointer; + -ms-transition: background-color var(--pico-transition), transform var(--pico-transition); + transition: background-color var(--pico-transition), transform var(--pico-transition); +} +[type=range]:active, [type=range]:focus-within { + --pico-range-border-color: var(--pico-range-active-border-color); + --pico-range-thumb-color: var(--pico-range-thumb-active-color); +} +[type=range]:active::-webkit-slider-thumb { + transform: scale(1.25); +} +[type=range]:active::-moz-range-thumb { + transform: scale(1.25); +} +[type=range]:active::-ms-thumb { + transform: scale(1.25); +} + +/** + * Input type search + */ +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search] { + padding-inline-start: calc(var(--pico-form-element-spacing-horizontal) + 1.75rem); + background-image: var(--pico-icon-search); + background-position: center left calc(var(--pico-form-element-spacing-horizontal) + 0.125rem); + background-size: 1rem auto; + background-repeat: no-repeat; +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid] { + padding-inline-start: calc(var(--pico-form-element-spacing-horizontal) + 1.75rem) !important; + background-position: center left 1.125rem, center right 0.75rem; +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid=false] { + background-image: var(--pico-icon-search), var(--pico-icon-valid); +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid=true] { + background-image: var(--pico-icon-search), var(--pico-icon-invalid); +} + +[dir=rtl] :where(input):not([type=checkbox], [type=radio], [type=range], [type=file])[type=search] { + background-position: center right 1.125rem; +} +[dir=rtl] :where(input):not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid] { + background-position: center right 1.125rem, center left 0.75rem; +} + +/** + * Accordion (
) + */ +details { + display: block; + margin-bottom: var(--pico-spacing); +} +details summary { + line-height: 1rem; + list-style-type: none; + cursor: pointer; + transition: color var(--pico-transition); +} +details summary:not([role]) { + color: var(--pico-accordion-close-summary-color); +} +details summary::-webkit-details-marker { + display: none; +} +details summary::marker { + display: none; +} +details summary::-moz-list-bullet { + list-style-type: none; +} +details summary::after { + display: block; + width: 1rem; + height: 1rem; + margin-inline-start: calc(var(--pico-spacing, 1rem) * 0.5); + float: right; + transform: rotate(-90deg); + background-image: var(--pico-icon-chevron); + background-position: right center; + background-size: 1rem auto; + background-repeat: no-repeat; + content: ""; + transition: transform var(--pico-transition); +} +details summary:focus { + outline: none; +} +details summary:focus:not([role]) { + color: var(--pico-accordion-active-summary-color); +} +details summary:focus-visible:not([role]) { + outline: var(--pico-outline-width) solid var(--pico-primary-focus); + outline-offset: calc(var(--pico-spacing, 1rem) * 0.5); + color: var(--pico-primary); +} +details summary[role=button] { + width: 100%; + text-align: left; +} +details summary[role=button]::after { + height: calc(1rem * var(--pico-line-height, 1.5)); +} +details[open] > summary { + margin-bottom: var(--pico-spacing); +} +details[open] > summary:not([role]):not(:focus) { + color: var(--pico-accordion-open-summary-color); +} +details[open] > summary::after { + transform: rotate(0); +} + +[dir=rtl] details summary { + text-align: right; +} +[dir=rtl] details summary::after { + float: left; + background-position: left center; +} + +/** + * Card (
) + */ +article { + margin-bottom: var(--pico-block-spacing-vertical); + padding: var(--pico-block-spacing-vertical) var(--pico-block-spacing-horizontal); + border-radius: var(--pico-border-radius); + background: var(--pico-card-background-color); + box-shadow: var(--pico-card-box-shadow); +} +article > header, +article > footer { + margin-right: calc(var(--pico-block-spacing-horizontal) * -1); + margin-left: calc(var(--pico-block-spacing-horizontal) * -1); + padding: calc(var(--pico-block-spacing-vertical) * 0.66) var(--pico-block-spacing-horizontal); + background-color: var(--pico-card-sectioning-background-color); +} +article > header { + margin-top: calc(var(--pico-block-spacing-vertical) * -1); + margin-bottom: var(--pico-block-spacing-vertical); + border-bottom: var(--pico-border-width) solid var(--pico-card-border-color); + border-top-right-radius: var(--pico-border-radius); + border-top-left-radius: var(--pico-border-radius); +} +article > footer { + margin-top: var(--pico-block-spacing-vertical); + margin-bottom: calc(var(--pico-block-spacing-vertical) * -1); + border-top: var(--pico-border-width) solid var(--pico-card-border-color); + border-bottom-right-radius: var(--pico-border-radius); + border-bottom-left-radius: var(--pico-border-radius); +} + +/** + * Dropdown (details.dropdown) + */ +details.dropdown { + position: relative; + border-bottom: none; +} +details.dropdown summary::after, +details.dropdown > button::after, +details.dropdown > a::after { + display: block; + width: 1rem; + height: calc(1rem * var(--pico-line-height, 1.5)); + margin-inline-start: 0.25rem; + float: right; + transform: rotate(0deg) translateX(0.2rem); + background-image: var(--pico-icon-chevron); + background-position: right center; + background-size: 1rem auto; + background-repeat: no-repeat; + content: ""; +} + +nav details.dropdown { + margin-bottom: 0; +} + +details.dropdown summary:not([role]) { + height: calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2); + padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal); + border: var(--pico-border-width) solid var(--pico-form-element-border-color); + border-radius: var(--pico-border-radius); + background-color: var(--pico-form-element-background-color); + color: var(--pico-form-element-placeholder-color); + line-height: inherit; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + transition: background-color var(--pico-transition), border-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition); +} +details.dropdown summary:not([role]):active, details.dropdown summary:not([role]):focus { + border-color: var(--pico-form-element-active-border-color); + background-color: var(--pico-form-element-active-background-color); +} +details.dropdown summary:not([role]):focus { + box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-focus-color); +} +details.dropdown summary:not([role]):focus-visible { + outline: none; +} +details.dropdown summary:not([role])[aria-invalid=false] { + --pico-form-element-border-color: var(--pico-form-element-valid-border-color); + --pico-form-element-active-border-color: var(--pico-form-element-valid-focus-color); + --pico-form-element-focus-color: var(--pico-form-element-valid-focus-color); +} +details.dropdown summary:not([role])[aria-invalid=true] { + --pico-form-element-border-color: var(--pico-form-element-invalid-border-color); + --pico-form-element-active-border-color: var(--pico-form-element-invalid-focus-color); + --pico-form-element-focus-color: var(--pico-form-element-invalid-focus-color); +} + +nav details.dropdown { + display: inline; + margin: calc(var(--pico-nav-element-spacing-vertical) * -1) 0; +} +nav details.dropdown summary::after { + transform: rotate(0deg) translateX(0rem); +} +nav details.dropdown summary:not([role]) { + height: calc(1rem * var(--pico-line-height) + var(--pico-nav-link-spacing-vertical) * 2); + padding: calc(var(--pico-nav-link-spacing-vertical) - var(--pico-border-width) * 2) var(--pico-nav-link-spacing-horizontal); +} +nav details.dropdown summary:not([role]):focus-visible { + box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); +} + +details.dropdown summary + ul { + display: flex; + z-index: 99; + position: absolute; + left: 0; + flex-direction: column; + width: 100%; + min-width: -moz-fit-content; + min-width: fit-content; + margin: 0; + margin-top: var(--pico-outline-width); + padding: 0; + border: var(--pico-border-width) solid var(--pico-dropdown-border-color); + border-radius: var(--pico-border-radius); + background-color: var(--pico-dropdown-background-color); + box-shadow: var(--pico-dropdown-box-shadow); + color: var(--pico-dropdown-color); + white-space: nowrap; + opacity: 0; + transition: opacity var(--pico-transition), transform 0s ease-in-out 1s; +} +details.dropdown summary + ul[dir=rtl] { + right: 0; + left: auto; +} +details.dropdown summary + ul li { + width: 100%; + margin-bottom: 0; + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) var(--pico-form-element-spacing-horizontal); + list-style: none; +} +details.dropdown summary + ul li:first-of-type { + margin-top: calc(var(--pico-form-element-spacing-vertical) * 0.5); +} +details.dropdown summary + ul li:last-of-type { + margin-bottom: calc(var(--pico-form-element-spacing-vertical) * 0.5); +} +details.dropdown summary + ul li a { + display: block; + margin: calc(var(--pico-form-element-spacing-vertical) * -0.5) calc(var(--pico-form-element-spacing-horizontal) * -1); + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) var(--pico-form-element-spacing-horizontal); + overflow: hidden; + border-radius: 0; + color: var(--pico-dropdown-color); + text-decoration: none; + text-overflow: ellipsis; +} +details.dropdown summary + ul li a:hover, details.dropdown summary + ul li a:focus, details.dropdown summary + ul li a:active, details.dropdown summary + ul li a:focus-visible, details.dropdown summary + ul li a[aria-current]:not([aria-current=false]) { + background-color: var(--pico-dropdown-hover-background-color); +} +details.dropdown summary + ul li label { + width: 100%; +} +details.dropdown summary + ul li:has(label):hover { + background-color: var(--pico-dropdown-hover-background-color); +} + +details.dropdown[open] summary { + margin-bottom: 0; +} + +details.dropdown[open] summary + ul { + transform: scaleY(1); + opacity: 1; + transition: opacity var(--pico-transition), transform 0s ease-in-out 0s; +} + +details.dropdown[open] summary::before { + display: block; + z-index: 1; + position: fixed; + width: 100vw; + height: 100vh; + inset: 0; + background: none; + content: ""; + cursor: default; +} + +label > details.dropdown { + margin-top: calc(var(--pico-spacing) * 0.25); +} + +/** + * Group ([role="group"], [role="search"]) + */ +[role=search], +[role=group] { + display: inline-flex; + position: relative; + width: 100%; + margin-bottom: var(--pico-spacing); + border-radius: var(--pico-border-radius); + box-shadow: var(--pico-group-box-shadow, 0 0 0 rgba(0, 0, 0, 0)); + vertical-align: middle; + transition: box-shadow var(--pico-transition); +} +[role=search] > *, +[role=search] input:not([type=checkbox], [type=radio]), +[role=search] select, +[role=group] > *, +[role=group] input:not([type=checkbox], [type=radio]), +[role=group] select { + position: relative; + flex: 1 1 auto; + margin-bottom: 0; +} +[role=search] > *:not(:first-child), +[role=search] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=search] select:not(:first-child), +[role=group] > *:not(:first-child), +[role=group] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=group] select:not(:first-child) { + margin-left: 0; + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +[role=search] > *:not(:last-child), +[role=search] input:not([type=checkbox], [type=radio]):not(:last-child), +[role=search] select:not(:last-child), +[role=group] > *:not(:last-child), +[role=group] input:not([type=checkbox], [type=radio]):not(:last-child), +[role=group] select:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +[role=search] > *:focus, +[role=search] input:not([type=checkbox], [type=radio]):focus, +[role=search] select:focus, +[role=group] > *:focus, +[role=group] input:not([type=checkbox], [type=radio]):focus, +[role=group] select:focus { + z-index: 2; +} +[role=search] button:not(:first-child), +[role=search] [type=submit]:not(:first-child), +[role=search] [type=reset]:not(:first-child), +[role=search] [type=button]:not(:first-child), +[role=search] [role=button]:not(:first-child), +[role=search] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=search] select:not(:first-child), +[role=group] button:not(:first-child), +[role=group] [type=submit]:not(:first-child), +[role=group] [type=reset]:not(:first-child), +[role=group] [type=button]:not(:first-child), +[role=group] [role=button]:not(:first-child), +[role=group] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=group] select:not(:first-child) { + margin-left: calc(var(--pico-border-width) * -1); +} +[role=search] button, +[role=search] [type=submit], +[role=search] [type=reset], +[role=search] [type=button], +[role=search] [role=button], +[role=group] button, +[role=group] [type=submit], +[role=group] [type=reset], +[role=group] [type=button], +[role=group] [role=button] { + width: auto; +} +@supports selector(:has(*)) { + [role=search]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus), + [role=group]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) { + --pico-group-box-shadow: var(--pico-group-box-shadow-focus-with-button); + } + [role=search]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) input:not([type=checkbox], [type=radio]), + [role=search]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) select, + [role=group]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) input:not([type=checkbox], [type=radio]), + [role=group]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) select { + border-color: transparent; + } + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus), + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) { + --pico-group-box-shadow: var(--pico-group-box-shadow-focus-with-input); + } + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) button, + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=submit], + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=button], + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) [role=button], + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) button, + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=submit], + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=button], + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) [role=button] { + --pico-button-box-shadow: 0 0 0 var(--pico-border-width) var(--pico-primary-border); + --pico-button-hover-box-shadow: 0 0 0 var(--pico-border-width) var(--pico-primary-hover-border); + } + [role=search] button:focus, + [role=search] [type=submit]:focus, + [role=search] [type=reset]:focus, + [role=search] [type=button]:focus, + [role=search] [role=button]:focus, + [role=group] button:focus, + [role=group] [type=submit]:focus, + [role=group] [type=reset]:focus, + [role=group] [type=button]:focus, + [role=group] [role=button]:focus { + box-shadow: none; + } +} + +[role=search] > *:first-child { + border-top-left-radius: 5rem; + border-bottom-left-radius: 5rem; +} +[role=search] > *:last-child { + border-top-right-radius: 5rem; + border-bottom-right-radius: 5rem; +} + +/** + * Loading ([aria-busy=true]) + */ +[aria-busy=true]:not(input, select, textarea, html) { + white-space: nowrap; +} +[aria-busy=true]:not(input, select, textarea, html)::before { + display: inline-block; + width: 1em; + height: 1em; + background-image: var(--pico-icon-loading); + background-size: 1em auto; + background-repeat: no-repeat; + content: ""; + vertical-align: -0.125em; +} +[aria-busy=true]:not(input, select, textarea, html):not(:empty)::before { + margin-inline-end: calc(var(--pico-spacing) * 0.5); +} +[aria-busy=true]:not(input, select, textarea, html):empty { + text-align: center; +} + +button[aria-busy=true], +[type=submit][aria-busy=true], +[type=button][aria-busy=true], +[type=reset][aria-busy=true], +[role=button][aria-busy=true], +a[aria-busy=true] { + pointer-events: none; +} + +/** + * Modal () + */ +:root { + --pico-scrollbar-width: 0px; +} + +dialog { + display: flex; + z-index: 999; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + align-items: center; + justify-content: center; + width: inherit; + min-width: 100%; + height: inherit; + min-height: 100%; + padding: 0; + border: 0; + -webkit-backdrop-filter: var(--pico-modal-overlay-backdrop-filter); + backdrop-filter: var(--pico-modal-overlay-backdrop-filter); + background-color: var(--pico-modal-overlay-background-color); + color: var(--pico-color); +} +dialog article { + width: 100%; + max-height: calc(100vh - var(--pico-spacing) * 2); + margin: var(--pico-spacing); + overflow: auto; +} +@media (min-width: 576px) { + dialog article { + max-width: 510px; + } +} +@media (min-width: 768px) { + dialog article { + max-width: 700px; + } +} +dialog article > header > * { + margin-bottom: 0; +} +dialog article > header .close, dialog article > header :is(a, button)[rel=prev] { + margin: 0; + margin-left: var(--pico-spacing); + padding: 0; + float: right; +} +dialog article > footer { + text-align: right; +} +dialog article > footer button, +dialog article > footer [role=button] { + margin-bottom: 0; +} +dialog article > footer button:not(:first-of-type), +dialog article > footer [role=button]:not(:first-of-type) { + margin-left: calc(var(--pico-spacing) * 0.5); +} +dialog article .close, dialog article :is(a, button)[rel=prev] { + display: block; + width: 1rem; + height: 1rem; + margin-top: calc(var(--pico-spacing) * -1); + margin-bottom: var(--pico-spacing); + margin-left: auto; + border: none; + background-image: var(--pico-icon-close); + background-position: center; + background-size: auto 1rem; + background-repeat: no-repeat; + background-color: transparent; + opacity: 0.5; + transition: opacity var(--pico-transition); +} +dialog article .close:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), dialog article :is(a, button)[rel=prev]:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + opacity: 1; +} +dialog:not([open]), dialog[open=false] { + display: none; +} + +.modal-is-open { + padding-right: var(--pico-scrollbar-width, 0px); + overflow: hidden; + pointer-events: none; + touch-action: none; +} +.modal-is-open dialog { + pointer-events: auto; + touch-action: auto; +} + +:where(.modal-is-opening, .modal-is-closing) dialog, +:where(.modal-is-opening, .modal-is-closing) dialog > article { + animation-duration: 0.2s; + animation-timing-function: ease-in-out; + animation-fill-mode: both; +} +:where(.modal-is-opening, .modal-is-closing) dialog { + animation-duration: 0.8s; + animation-name: modal-overlay; +} +:where(.modal-is-opening, .modal-is-closing) dialog > article { + animation-delay: 0.2s; + animation-name: modal; +} + +.modal-is-closing dialog, +.modal-is-closing dialog > article { + animation-delay: 0s; + animation-direction: reverse; +} + +@keyframes modal-overlay { + from { + -webkit-backdrop-filter: none; + backdrop-filter: none; + background-color: transparent; + } +} +@keyframes modal { + from { + transform: translateY(-100%); + opacity: 0; + } +} +/** + * Nav + */ +:where(nav li)::before { + float: left; + content: "​"; +} + +nav, +nav ul { + display: flex; +} + +nav { + justify-content: space-between; + overflow: visible; +} +nav ol, +nav ul { + align-items: center; + margin-bottom: 0; + padding: 0; + list-style: none; +} +nav ol:first-of-type, +nav ul:first-of-type { + margin-left: calc(var(--pico-nav-element-spacing-horizontal) * -1); +} +nav ol:last-of-type, +nav ul:last-of-type { + margin-right: calc(var(--pico-nav-element-spacing-horizontal) * -1); +} +nav li { + display: inline-block; + margin: 0; + padding: var(--pico-nav-element-spacing-vertical) var(--pico-nav-element-spacing-horizontal); +} +nav li :where(a, [role=link]) { + display: inline-block; + margin: calc(var(--pico-nav-link-spacing-vertical) * -1) calc(var(--pico-nav-link-spacing-horizontal) * -1); + padding: var(--pico-nav-link-spacing-vertical) var(--pico-nav-link-spacing-horizontal); + border-radius: var(--pico-border-radius); +} +nav li :where(a, [role=link]):not(:hover) { + text-decoration: none; +} +nav li button, +nav li [role=button], +nav li [type=button], +nav li input:not([type=checkbox], [type=radio], [type=range], [type=file]), +nav li select { + height: auto; + margin-right: inherit; + margin-bottom: 0; + margin-left: inherit; + padding: calc(var(--pico-nav-link-spacing-vertical) - var(--pico-border-width) * 2) var(--pico-nav-link-spacing-horizontal); +} +nav[aria-label=breadcrumb] { + align-items: center; + justify-content: start; +} +nav[aria-label=breadcrumb] ul li:not(:first-child) { + margin-inline-start: var(--pico-nav-link-spacing-horizontal); +} +nav[aria-label=breadcrumb] ul li a { + margin: calc(var(--pico-nav-link-spacing-vertical) * -1) 0; + margin-inline-start: calc(var(--pico-nav-link-spacing-horizontal) * -1); +} +nav[aria-label=breadcrumb] ul li:not(:last-child)::after { + display: inline-block; + position: absolute; + width: calc(var(--pico-nav-link-spacing-horizontal) * 4); + margin: 0 calc(var(--pico-nav-link-spacing-horizontal) * -1); + content: var(--pico-nav-breadcrumb-divider); + color: var(--pico-muted-color); + text-align: center; + text-decoration: none; + white-space: nowrap; +} +nav[aria-label=breadcrumb] a[aria-current]:not([aria-current=false]) { + background-color: transparent; + color: inherit; + text-decoration: none; + pointer-events: none; +} + +aside nav, +aside ol, +aside ul, +aside li { + display: block; +} +aside li { + padding: calc(var(--pico-nav-element-spacing-vertical) * 0.5) var(--pico-nav-element-spacing-horizontal); +} +aside li a { + display: block; +} +aside li [role=button] { + margin: inherit; +} + +[dir=rtl] nav[aria-label=breadcrumb] ul li:not(:last-child) ::after { + content: "\\"; +} + +/** + * Progress + */ +progress { + display: inline-block; + vertical-align: baseline; +} + +progress { + -webkit-appearance: none; + -moz-appearance: none; + display: inline-block; + appearance: none; + width: 100%; + height: 0.5rem; + margin-bottom: calc(var(--pico-spacing) * 0.5); + overflow: hidden; + border: 0; + border-radius: var(--pico-border-radius); + background-color: var(--pico-progress-background-color); + color: var(--pico-progress-color); +} +progress::-webkit-progress-bar { + border-radius: var(--pico-border-radius); + background: none; +} +progress[value]::-webkit-progress-value { + background-color: var(--pico-progress-color); + -webkit-transition: inline-size var(--pico-transition); + transition: inline-size var(--pico-transition); +} +progress::-moz-progress-bar { + background-color: var(--pico-progress-color); +} +@media (prefers-reduced-motion: no-preference) { + progress:indeterminate { + background: var(--pico-progress-background-color) linear-gradient(to right, var(--pico-progress-color) 30%, var(--pico-progress-background-color) 30%) top left/150% 150% no-repeat; + animation: progress-indeterminate 1s linear infinite; + } + progress:indeterminate[value]::-webkit-progress-value { + background-color: transparent; + } + progress:indeterminate::-moz-progress-bar { + background-color: transparent; + } +} + +@media (prefers-reduced-motion: no-preference) { + [dir=rtl] progress:indeterminate { + animation-direction: reverse; + } +} + +@keyframes progress-indeterminate { + 0% { + background-position: 200% 0; + } + 100% { + background-position: -200% 0; + } +} +/** + * Tooltip ([data-tooltip]) + */ +[data-tooltip] { + position: relative; +} +[data-tooltip]:not(a, button, input) { + border-bottom: 1px dotted; + text-decoration: none; + cursor: help; +} +[data-tooltip][data-placement=top]::before, [data-tooltip][data-placement=top]::after, [data-tooltip]::before, [data-tooltip]::after { + display: block; + z-index: 99; + position: absolute; + bottom: 100%; + left: 50%; + padding: 0.25rem 0.5rem; + overflow: hidden; + transform: translate(-50%, -0.25rem); + border-radius: var(--pico-border-radius); + background: var(--pico-tooltip-background-color); + content: attr(data-tooltip); + color: var(--pico-tooltip-color); + font-style: normal; + font-weight: var(--pico-font-weight); + font-size: 0.875rem; + text-decoration: none; + text-overflow: ellipsis; + white-space: nowrap; + opacity: 0; + pointer-events: none; +} +[data-tooltip][data-placement=top]::after, [data-tooltip]::after { + padding: 0; + transform: translate(-50%, 0rem); + border-top: 0.3rem solid; + border-right: 0.3rem solid transparent; + border-left: 0.3rem solid transparent; + border-radius: 0; + background-color: transparent; + content: ""; + color: var(--pico-tooltip-background-color); +} +[data-tooltip][data-placement=bottom]::before, [data-tooltip][data-placement=bottom]::after { + top: 100%; + bottom: auto; + transform: translate(-50%, 0.25rem); +} +[data-tooltip][data-placement=bottom]:after { + transform: translate(-50%, -0.3rem); + border: 0.3rem solid transparent; + border-bottom: 0.3rem solid; +} +[data-tooltip][data-placement=left]::before, [data-tooltip][data-placement=left]::after { + top: 50%; + right: 100%; + bottom: auto; + left: auto; + transform: translate(-0.25rem, -50%); +} +[data-tooltip][data-placement=left]:after { + transform: translate(0.3rem, -50%); + border: 0.3rem solid transparent; + border-left: 0.3rem solid; +} +[data-tooltip][data-placement=right]::before, [data-tooltip][data-placement=right]::after { + top: 50%; + right: auto; + bottom: auto; + left: 100%; + transform: translate(0.25rem, -50%); +} +[data-tooltip][data-placement=right]:after { + transform: translate(-0.3rem, -50%); + border: 0.3rem solid transparent; + border-right: 0.3rem solid; +} +[data-tooltip]:focus::before, [data-tooltip]:focus::after, [data-tooltip]:hover::before, [data-tooltip]:hover::after { + opacity: 1; +} +@media (hover: hover) and (pointer: fine) { + [data-tooltip]:focus::before, [data-tooltip]:focus::after, [data-tooltip]:hover::before, [data-tooltip]:hover::after { + --pico-tooltip-slide-to: translate(-50%, -0.25rem); + transform: translate(-50%, 0.75rem); + animation-duration: 0.2s; + animation-fill-mode: forwards; + animation-name: tooltip-slide; + opacity: 0; + } + [data-tooltip]:focus::after, [data-tooltip]:hover::after { + --pico-tooltip-caret-slide-to: translate(-50%, 0rem); + transform: translate(-50%, -0.25rem); + animation-name: tooltip-caret-slide; + } + [data-tooltip][data-placement=bottom]:focus::before, [data-tooltip][data-placement=bottom]:focus::after, [data-tooltip][data-placement=bottom]:hover::before, [data-tooltip][data-placement=bottom]:hover::after { + --pico-tooltip-slide-to: translate(-50%, 0.25rem); + transform: translate(-50%, -0.75rem); + animation-name: tooltip-slide; + } + [data-tooltip][data-placement=bottom]:focus::after, [data-tooltip][data-placement=bottom]:hover::after { + --pico-tooltip-caret-slide-to: translate(-50%, -0.3rem); + transform: translate(-50%, -0.5rem); + animation-name: tooltip-caret-slide; + } + [data-tooltip][data-placement=left]:focus::before, [data-tooltip][data-placement=left]:focus::after, [data-tooltip][data-placement=left]:hover::before, [data-tooltip][data-placement=left]:hover::after { + --pico-tooltip-slide-to: translate(-0.25rem, -50%); + transform: translate(0.75rem, -50%); + animation-name: tooltip-slide; + } + [data-tooltip][data-placement=left]:focus::after, [data-tooltip][data-placement=left]:hover::after { + --pico-tooltip-caret-slide-to: translate(0.3rem, -50%); + transform: translate(0.05rem, -50%); + animation-name: tooltip-caret-slide; + } + [data-tooltip][data-placement=right]:focus::before, [data-tooltip][data-placement=right]:focus::after, [data-tooltip][data-placement=right]:hover::before, [data-tooltip][data-placement=right]:hover::after { + --pico-tooltip-slide-to: translate(0.25rem, -50%); + transform: translate(-0.75rem, -50%); + animation-name: tooltip-slide; + } + [data-tooltip][data-placement=right]:focus::after, [data-tooltip][data-placement=right]:hover::after { + --pico-tooltip-caret-slide-to: translate(-0.3rem, -50%); + transform: translate(-0.05rem, -50%); + animation-name: tooltip-caret-slide; + } +} +@keyframes tooltip-slide { + to { + transform: var(--pico-tooltip-slide-to); + opacity: 1; + } +} +@keyframes tooltip-caret-slide { + 50% { + opacity: 0; + } + to { + transform: var(--pico-tooltip-caret-slide-to); + opacity: 1; + } +} + +/** + * Accessibility & User interaction + */ +[aria-controls] { + cursor: pointer; +} + +[aria-disabled=true], +[disabled] { + cursor: not-allowed; +} + +[aria-hidden=false][hidden] { + display: initial; +} + +[aria-hidden=false][hidden]:not(:focus) { + clip: rect(0, 0, 0, 0); + position: absolute; +} + +a, +area, +button, +input, +label, +select, +summary, +textarea, +[tabindex] { + -ms-touch-action: manipulation; +} + +[dir=rtl] { + direction: rtl; +} + +/** + * Reduce Motion Features + */ +@media (prefers-reduced-motion: reduce) { + *:not([aria-busy=true]), + :not([aria-busy=true])::before, + :not([aria-busy=true])::after { + background-attachment: initial !important; + animation-duration: 1ms !important; + animation-delay: -1ms !important; + animation-iteration-count: 1 !important; + scroll-behavior: auto !important; + transition-delay: 0s !important; + transition-duration: 0s !important; + } +} \ No newline at end of file diff --git a/hypermedia/2-example/record1.json b/demo/datasstar-static/signals/record1.json similarity index 100% rename from hypermedia/2-example/record1.json rename to demo/datasstar-static/signals/record1.json diff --git a/hypermedia/2-example/record2.json b/demo/datasstar-static/signals/record2.json similarity index 100% rename from hypermedia/2-example/record2.json rename to demo/datasstar-static/signals/record2.json diff --git a/hypermedia/2-example/record3.json b/demo/datasstar-static/signals/record3.json similarity index 100% rename from hypermedia/2-example/record3.json rename to demo/datasstar-static/signals/record3.json diff --git a/hypermedia/2-example/record4.json b/demo/datasstar-static/signals/record4.json similarity index 100% rename from hypermedia/2-example/record4.json rename to demo/datasstar-static/signals/record4.json diff --git a/hypermedia/2-example/record5.json b/demo/datasstar-static/signals/record5.json similarity index 100% rename from hypermedia/2-example/record5.json rename to demo/datasstar-static/signals/record5.json diff --git a/hypermedia/2-example/record6.json b/demo/datasstar-static/signals/record6.json similarity index 100% rename from hypermedia/2-example/record6.json rename to demo/datasstar-static/signals/record6.json diff --git a/experiments/patchsignals/index.html b/experiments/patchsignals/index.html new file mode 100644 index 0000000..5548c5f --- /dev/null +++ b/experiments/patchsignals/index.html @@ -0,0 +1,42 @@ + + + + + + + + Document + + + + + +
+ + + + \ No newline at end of file diff --git a/experiments/patchsignals/main.css b/experiments/patchsignals/main.css new file mode 100644 index 0000000..266de8b --- /dev/null +++ b/experiments/patchsignals/main.css @@ -0,0 +1,35 @@ +*, +*::before, +*::after { + box-sizing: border-box; +} + +* { + margin: 0; +} + +:root { + --base-color: oklch(92.2% 0 0); + --base-color-content: oklch(25.3267% 0.015896 252.417568); +} + +@media (prefers-color-scheme: dark) { + :root { + --base-color: oklch(25.3267% 0.015896 252.417568); + --base-color-content: oklch(92.2% 0 0); + } +} + +body { + display: grid; + place-content: center; + background-color: var(--base-color); + font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", + "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + height: 100vh; +} + +div { + color: var(--base-color-content); + font-size: 4rem; +} \ No newline at end of file diff --git a/experiments/patchsignals/main.js b/experiments/patchsignals/main.js new file mode 100644 index 0000000..7158bc8 --- /dev/null +++ b/experiments/patchsignals/main.js @@ -0,0 +1,21 @@ +let counter = 0; + +// helper function that activates the PatchSignals +// watcher plugin to simulate a completed fetch request +const patchSignals = (count) => { + // a simulated `datastar-patch-signals` event + const detail = { + type: "datastar-patch-signals", + argsRaw: { + signals: JSON.stringify({ count }) + } + }; + + // trigger the SSEEventWatcher by simulating a `datastar-fetch` event + document.dispatchEvent(new CustomEvent("datastar-fetch", { detail })); +}; + +setInterval(() => { + patchSignals(counter); + counter++; +}, 250); diff --git a/experiments/simple/frontend/datastar.js b/experiments/simple/frontend/datastar.js new file mode 100644 index 0000000..be57e9d --- /dev/null +++ b/experiments/simple/frontend/datastar.js @@ -0,0 +1,9 @@ +// Datastar v1.0.0-RC.6 +var nt=/🖕JS_DS🚀/.source,De=nt.slice(0,5),Ve=nt.slice(4),q="datastar-fetch",z="datastar-signal-patch";var de=e=>e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/([a-z])([0-9]+)/gi,"$1-$2").replace(/([0-9]+)([a-z])/gi,"$1-$2").toLowerCase();var rt=e=>de(e).replace(/-/g,"_");var re=e=>{try{return JSON.parse(e)}catch{return Function(`return (${e})`)()}},st={camel:e=>e.replace(/-[a-z]/g,t=>t[1].toUpperCase()),snake:e=>e.replace(/-/g,"_"),pascal:e=>e[0].toUpperCase()+st.camel(e.slice(1))},R=(e,t,n="camel")=>{for(let r of t.get("case")||[n])e=st[r]?.(e)||e;return e},Q=e=>`data-${e}`;var _=Object.hasOwn??Object.prototype.hasOwnProperty.call;var se=e=>e!==null&&typeof e=="object"&&(Object.getPrototypeOf(e)===Object.prototype||Object.getPrototypeOf(e)===null),it=e=>{for(let t in e)if(_(e,t))return!1;return!0},Z=(e,t)=>{for(let n in e){let r=e[n];se(r)||Array.isArray(r)?Z(r,t):e[n]=t(r)}},Te=e=>{let t={};for(let[n,r]of e){let s=n.split("."),i=s.pop(),a=s.reduce((o,c)=>o[c]??={},t);a[i]=r}return t};var Ae=[],Ie=[],Fe=0,Re=0,$e=0,qe,G,we=0,w=()=>{Fe++},M=()=>{--Fe||(ct(),Y())},V=e=>{qe=G,G=e},I=()=>{G=qe,qe=void 0},me=e=>It.bind(0,{previousValue:e,t:e,e:1}),Ge=Symbol("computed"),Ne=e=>{let t=$t.bind(0,{e:17,getter:e});return t[Ge]=1,t},E=e=>{let t={d:e,e:2};G&&Be(t,G),V(t),w();try{t.d()}finally{M(),I()}return dt.bind(0,t)},ct=()=>{for(;Re<$e;){let e=Ie[Re];Ie[Re++]=void 0,ut(e,e.e&=-65)}Re=0,$e=0},ot=e=>"getter"in e?lt(e):ft(e,e.t),lt=e=>{V(e),mt(e);try{let t=e.t;return t!==(e.t=e.getter(t))}finally{I(),pt(e)}},ft=(e,t)=>(e.e=1,e.previousValue!==(e.previousValue=t)),je=e=>{let t=e.e;if(!(t&64)){e.e=t|64;let n=e.r;n?je(n.o):Ie[$e++]=e}},ut=(e,t)=>{if(t&16||t&32&>(e.s,e)){V(e),mt(e),w();try{e.d()}finally{M(),I(),pt(e)}return}t&32&&(e.e=t&-33);let n=e.s;for(;n;){let r=n.c,s=r.e;s&64&&ut(r,r.e=s&-65),n=n.i}},It=(e,...t)=>{if(t.length){if(e.t!==(e.t=t[0])){e.e=17;let r=e.r;return r&&(qt(r),Fe||ct()),!0}return!1}let n=e.t;if(e.e&16&&ft(e,n)){let r=e.r;r&&Le(r)}return G&&Be(e,G),n},$t=e=>{let t=e.e;if(t&16||t&32&>(e.s,e)){if(lt(e)){let n=e.r;n&&Le(n)}}else t&32&&(e.e=t&-33);return G&&Be(e,G),e.t},dt=e=>{let t=e.s;for(;t;)t=xe(t,e);let n=e.r;n&&xe(n),e.e=0},Be=(e,t)=>{let n=t.a;if(n&&n.c===e)return;let r=n?n.i:t.s;if(r&&r.c===e){r.m=we,t.a=r;return}let s=e.p;if(s&&s.m===we&&s.o===t)return;let i=t.a=e.p={m:we,c:e,o:t,l:n,i:r,f:s};r&&(r.l=i),n?n.i=i:t.s=i,s?s.n=i:e.r=i},xe=(e,t=e.o)=>{let n=e.c,r=e.l,s=e.i,i=e.n,a=e.f;if(s?s.l=r:t.a=r,r?r.i=s:t.s=s,i?i.f=a:n.p=a,a)a.n=i;else if(!(n.r=i))if("getter"in n){let o=n.s;if(o){n.e=17;do o=xe(o,n);while(o)}}else"previousValue"in n||dt(n);return s},qt=e=>{let t=e.n,n;e:for(;;){let r=e.o,s=r.e;if(s&60?s&12?s&4?!(s&48)&&Gt(e,r)?(r.e=s|40,s&=1):s=0:r.e=s&-9|32:s=0:r.e=s|32,s&2&&je(r),s&1){let i=r.r;if(i){let a=(e=i).n;a&&(n={t,u:n},t=a);continue}}if(e=t){t=e.n;continue}for(;n;)if(e=n.t,n=n.u,e){t=e.n;continue e}break}},mt=e=>{we++,e.a=void 0,e.e=e.e&-57|4},pt=e=>{let t=e.a,n=t?t.i:e.s;for(;n;)n=xe(n,e);e.e&=-5},gt=(e,t)=>{let n,r=0,s=!1;e:for(;;){let i=e.c,a=i.e;if(t.e&16)s=!0;else if((a&17)===17){if(ot(i)){let o=i.r;o.n&&Le(o),s=!0}}else if((a&33)===33){(e.n||e.f)&&(n={t:e,u:n}),e=i.s,t=i,++r;continue}if(!s){let o=e.i;if(o){e=o;continue}}for(;r--;){let o=t.r,c=o.n;if(c?(e=n.t,n=n.u):e=o,s){if(ot(t)){c&&Le(o),t=e.o;continue}s=!1}else t.e&=-33;if(t=e.o,e.i){e=e.i;continue e}}return s}},Le=e=>{do{let t=e.o,n=t.e;(n&48)===32&&(t.e=n|16,n&2&&je(t))}while(e=e.n)},Gt=(e,t)=>{let n=t.a;for(;n;){if(n===e)return!0;n=n.l}return!1},ie=e=>{let t=X,n=e.split(".");for(let r of n){if(t==null||!_(t,r))return;t=t[r]}return t},Me=(e,t="")=>{let n=Array.isArray(e);if(n||se(e)){let r=n?[]:{};for(let i in e)r[i]=me(Me(e[i],`${t+i}.`));let s=me(0);return new Proxy(r,{get(i,a){if(!(a==="toJSON"&&!_(r,a)))return n&&a in Array.prototype?(s(),r[a]):typeof a=="symbol"?r[a]:((!_(r,a)||r[a]()==null)&&(r[a]=me(""),Y(t+a,""),s(s()+1)),r[a]())},set(i,a,o){let c=t+a;if(n&&a==="length"){let l=r[a]-o;if(r[a]=o,l>0){let f={};for(let d=o;d{if(e!==void 0&&t!==void 0&&Ae.push([e,t]),!Fe&&Ae.length){let n=Te(Ae);Ae.length=0,document.dispatchEvent(new CustomEvent(z,{detail:n}))}},C=(e,{ifMissing:t}={})=>{w();for(let n in e)e[n]==null?t||delete X[n]:ht(e[n],n,X,"",t);M()},S=(e,t)=>C(Te(e),t),ht=(e,t,n,r,s)=>{if(se(e)){_(n,t)&&(se(n[t])||Array.isArray(n[t]))||(n[t]={});for(let i in e)e[i]==null?s||delete n[t][i]:ht(e[i],i,n[t],`${r+t}.`,s)}else s&&_(n,t)||(n[t]=e)},at=e=>typeof e=="string"?RegExp(e.replace(/^\/|\/$/g,"")):e,D=({include:e=/.*/,exclude:t=/(?!)/}={},n=X)=>{let r=at(e),s=at(t),i=[],a=[[n,""]];for(;a.length;){let[o,c]=a.pop();for(let l in o){let f=c+l;se(o[l])?a.push([o[l],`${f}.`]):r.test(f)&&!s.test(f)&&i.push([f,ie(f)])}}return Te(i)},X=Me({});var W=e=>e instanceof HTMLElement||e instanceof SVGElement||e instanceof MathMLElement;var jt="https://data-star.dev/errors",pe=(e,t,n={})=>{Object.assign(n,e);let r=new Error,s=rt(t),i=new URLSearchParams({metadata:JSON.stringify(n)}).toString(),a=JSON.stringify(n,null,2);return r.message=`${t} +More info: ${jt}/${s}?${i} +Context: ${a}`,r},Oe=new Map,vt=new Map,bt=new Map,Et=new Proxy({},{get:(e,t)=>Oe.get(t)?.apply,has:(e,t)=>Oe.has(t),ownKeys:()=>Reflect.ownKeys(Oe),set:()=>!1,deleteProperty:()=>!1}),ge=new Map,Ce=[],We=new Set,p=e=>{Ce.push(e),Ce.length===1&&setTimeout(()=>{for(let t of Ce)We.add(t.name),vt.set(t.name,t);Ce.length=0,Jt(),We.clear()})},O=e=>{Oe.set(e.name,e)};document.addEventListener(q,e=>{let t=bt.get(e.detail.type);t&&t.apply({error:pe.bind(0,{plugin:{type:"watcher",name:t.name},element:{id:e.target.id,tag:e.target.tagName}})},e.detail.argsRaw)});var he=e=>{bt.set(e.name,e)},yt=e=>{for(let t of e){let n=ge.get(t);if(ge.delete(t)){for(let r of n.values())r();n.clear()}}},St=Q("ignore"),Bt=`[${St}]`,Tt=e=>e.hasAttribute(`${St}__self`)||!!e.closest(Bt),Pe=(e,t)=>{for(let n of e)if(!Tt(n))for(let r in n.dataset)At(n,r.replace(/[A-Z]/g,"-$&").toLowerCase(),n.dataset[r],t)},Wt=e=>{for(let{target:t,type:n,attributeName:r,addedNodes:s,removedNodes:i}of e)if(n==="childList"){for(let a of i)W(a)&&(yt([a]),yt(a.querySelectorAll("*")));for(let a of s)W(a)&&(Pe([a]),Pe(a.querySelectorAll("*")))}else if(n==="attributes"&&r.startsWith("data-")&&W(t)&&!Tt(t)){let a=r.slice(5),o=t.getAttribute(r);if(o===null){let c=ge.get(t);c&&(c.get(a)?.(),c.delete(a))}else At(t,a,o)}},Ut=new MutationObserver(Wt),Jt=(e=document.documentElement)=>{W(e)&&Pe([e],!0),Pe(e.querySelectorAll("*"),!0),Ut.observe(e,{subtree:!0,childList:!0,attributes:!0})},At=(e,t,n,r)=>{{let s=t,[i,...a]=s.split("__"),[o,c]=i.split(/:(.+)/),l=vt.get(o);if((!r||We.has(o))&&l){let f={el:e,rawKey:s,mods:new Map,error:pe.bind(0,{plugin:{type:"attribute",name:l.name},element:{id:e.id,tag:e.tagName},expression:{rawKey:s,key:c,value:n}}),key:c,value:n,rx:void 0},d=l.requirement&&(typeof l.requirement=="string"?l.requirement:l.requirement.key)||"allowed",x=l.requirement&&(typeof l.requirement=="string"?l.requirement:l.requirement.value)||"allowed";if(c){if(d==="denied")throw f.error("KeyNotAllowed")}else if(d==="must")throw f.error("KeyRequired");if(n){if(x==="denied")throw f.error("ValueNotAllowed")}else if(x==="must")throw f.error("ValueRequired");if(d==="exclusive"||x==="exclusive"){if(c&&n)throw f.error("KeyAndValueProvided");if(!c&&!n)throw f.error("KeyOrValueRequired")}if(n){let m;f.rx=(...h)=>(m||(m=Kt(n,{returnsValue:l.returnsValue,argNames:l.argNames})),m(e,...h))}for(let m of a){let[h,...v]=m.split(".");f.mods.set(h,new Set(v))}let u=l.apply(f);if(u){let m=ge.get(e);m?m.get(s)?.():(m=new Map,ge.set(e,m)),m.set(s,u)}}}},Kt=(e,{returnsValue:t=!1,argNames:n=[]}={})=>{let r="";if(t){let o=/(\/(\\\/|[^/])*\/|"(\\"|[^"])*"|'(\\'|[^'])*'|`(\\`|[^`])*`|\(\s*((function)\s*\(\s*\)|(\(\s*\))\s*=>)\s*(?:\{[\s\S]*?\}|[^;){]*)\s*\)\s*\(\s*\)|[^;])+/gm,c=e.trim().match(o);if(c){let l=c.length-1,f=c[l].trim();f.startsWith("return")||(c[l]=`return (${f});`),r=c.join(`; +`)}}else r=e.trim();let s=new Map,i=RegExp(`(?:${De})(.*?)(?:${Ve})`,"gm"),a=0;for(let o of r.matchAll(i)){let c=o[1],l=`__escaped${a++}`;s.set(l,c),r=r.replace(De+c+Ve,l)}r=r.replace(/\$\['([a-zA-Z_$\d][\w$]*)'\]/g,"$$$1").replace(/\$([a-zA-Z_\d]\w*(?:[.-]\w+)*)/g,(o,c)=>c.split(".").reduce((l,f)=>`${l}['${f}']`,"$")).replace(/\[(\$[a-zA-Z_\d]\w*)\]/g,(o,c)=>`[$['${c.slice(1)}']]`),r=r.replaceAll(/@(\w+)\(/g,'__action("$1",evt,');for(let[o,c]of s)r=r.replace(o,c);try{let o=Function("el","$","__action","evt",...n,r);return(c,...l)=>{let f=(d,x,...u)=>{let m=pe.bind(0,{plugin:{type:"action",name:d},element:{id:c.id,tag:c.tagName},expression:{fnContent:r,value:e}}),h=Et[d];if(h)return h({el:c,evt:x,error:m},...u);throw m("UndefinedAction")};try{return o(c,X,f,void 0,...l)}catch(d){throw console.error(d),pe({element:{id:c.id,tag:c.tagName},expression:{fnContent:r,value:e},error:d.message},"ExecuteExpression")}}}catch(o){throw console.error(o),pe({expression:{fnContent:r,value:e},error:o.message},"GenerateExpression")}};var P=new Map,ae=new Set,oe=new Map,ye=new Set,ce=document.createElement("div");ce.hidden=!0;var ve=Q("ignore-morph"),zt=`[${ve}]`,Ke=(e,t,n="outer")=>{if(W(e)&&W(t)&&e.hasAttribute(ve)&&t.hasAttribute(ve)||e.parentElement?.closest(zt))return;let r=document.createElement("div");r.append(t),document.body.insertAdjacentElement("afterend",ce);let s=e.querySelectorAll("[id]");for(let{id:o,tagName:c}of s)oe.has(o)?ye.add(o):oe.set(o,c);e instanceof Element&&e.id&&(oe.has(e.id)?ye.add(e.id):oe.set(e.id,e.tagName)),ae.clear();let i=r.querySelectorAll("[id]");for(let{id:o,tagName:c}of i)ae.has(o)?ye.add(o):oe.get(o)===c&&ae.add(o);for(let o of ye)ae.delete(o);oe.clear(),ye.clear(),P.clear();let a=n==="outer"?e.parentElement:e;wt(a,s),wt(r,i),Mt(a,r,n==="outer"?e:null,e.nextSibling),ce.remove()},Mt=(e,t,n=null,r=null)=>{e instanceof HTMLTemplateElement&&t instanceof HTMLTemplateElement&&(e=e.content,t=t.content),n??=e.firstChild;for(let s of t.childNodes){if(n&&n!==r){let i=Qt(s,n,r);if(i){if(i!==n){let a=n;for(;a&&a!==i;){let o=a;a=a.nextSibling,Je(o)}}Ue(i,s),n=i.nextSibling;continue}}if(s instanceof Element&&ae.has(s.id)){let i=document.getElementById(s.id),a=i;for(;a=a.parentNode;){let o=P.get(a);o&&(o.delete(s.id),o.size||P.delete(a))}xt(e,i,n),Ue(i,s),n=i.nextSibling;continue}if(P.has(s)){let i=document.createElement(s.tagName);e.insertBefore(i,n),Ue(i,s),n=i.nextSibling}else{let i=document.importNode(s,!0);e.insertBefore(i,n),n=i.nextSibling}}for(;n&&n!==r;){let s=n;n=n.nextSibling,Je(s)}},Qt=(e,t,n)=>{let r=null,s=e.nextSibling,i=0,a=0,o=P.get(e)?.size||0,c=t;for(;c&&c!==n;){if(Rt(c,e)){let l=!1,f=P.get(c),d=P.get(e);if(d&&f){for(let x of f)if(d.has(x)){l=!0;break}}if(l)return c;if(!r&&!P.has(c)){if(!o)return c;r=c}}if(a+=P.get(c)?.size||0,a>o)break;r===null&&s&&Rt(c,s)&&(i++,s=s.nextSibling,i>=2&&(r=void 0)),c=c.nextSibling}return r||null},Rt=(e,t)=>e.nodeType===t.nodeType&&e.tagName===t.tagName&&(!e.id||e.id===t.id),Je=e=>{P.has(e)?xt(ce,e,null):e.parentNode?.removeChild(e)},xt=Je.call.bind(ce.moveBefore??ce.insertBefore),Zt=Q("preserve-attr"),Ue=(e,t)=>{let n=t.nodeType;if(n===1){let r=e,s=t;if(r.hasAttribute(ve)&&s.hasAttribute(ve))return e;r instanceof HTMLInputElement&&s instanceof HTMLInputElement&&s.type!=="file"?s.getAttribute("value")!==r.getAttribute("value")&&(r.value=s.getAttribute("value")??""):r instanceof HTMLTextAreaElement&&s instanceof HTMLTextAreaElement&&(s.value!==r.value&&(r.value=s.value),r.firstChild&&r.firstChild.nodeValue!==s.value&&(r.firstChild.nodeValue=s.value));let i=(t.getAttribute(Zt)??"").split(" ");for(let{name:a,value:o}of s.attributes)r.getAttribute(a)!==o&&!i.includes(a)&&r.setAttribute(a,o);for(let a=r.attributes.length-1;a>=0;a--){let{name:o}=r.attributes[a];!s.hasAttribute(o)&&!i.includes(o)&&r.removeAttribute(o)}r.isEqualNode(s)||Mt(r,s)}return(n===8||n===3)&&e.nodeValue!==t.nodeValue&&(e.nodeValue=t.nodeValue),e},wt=(e,t)=>{for(let n of t)if(ae.has(n.id)){let r=n;for(;r&&r!==e;){let s=P.get(r);s||(s=new Set,P.set(r,s)),s.add(n.id),r=r.parentElement}}};O({name:"peek",apply(e,t){V();try{return t()}finally{I()}}});O({name:"setAll",apply(e,t,n){V();let r=D(n);Z(r,()=>t),C(r),I()}});O({name:"toggleAll",apply(e,t){V();let n=D(t);Z(n,r=>!r),C(n),I()}});var He=new WeakMap,be=(e,t)=>O({name:e,apply:async({el:n,evt:r,error:s},i,{selector:a,headers:o,contentType:c="json",filterSignals:{include:l=/.*/,exclude:f=/(^|\.)_/}={},openWhenHidden:d=!1,retryInterval:x=1e3,retryScaler:u=2,retryMaxWaitMs:m=3e4,retryMaxCount:h=10,requestCancellation:v="auto"}={})=>{let L=v instanceof AbortController?v:new AbortController,A=v==="disabled";if(!A){let T=He.get(n);T&&(T.abort(),await Promise.resolve())}!A&&!(v instanceof AbortController)&&He.set(n,L);try{let T=new MutationObserver(j=>{for(let H of j)for(let B of H.removedNodes)B===n&&(L.abort(),K())});n.parentNode&&T.observe(n.parentNode,{childList:!0});let K=()=>{T.disconnect()};try{if(!i?.length)throw s("FetchNoUrlProvided",{action:O});let j={Accept:"text/event-stream, text/html, application/json","Datastar-Request":!0};c==="json"&&(j["Content-Type"]="application/json");let H=Object.assign({},j,o),B={method:t,headers:H,openWhenHidden:d,retryInterval:x,retryScaler:u,retryMaxWaitMs:m,retryMaxCount:h,signal:L.signal,onopen:async g=>{g.status>=400&&ee(Yt,n,{status:g.status.toString()})},onmessage:g=>{if(!g.event.startsWith("datastar"))return;let $=g.event,b={};for(let N of g.data.split(` +`)){let y=N.indexOf(" "),k=N.slice(0,y),ue=N.slice(y+1);(b[k]||=[]).push(ue)}let F=Object.fromEntries(Object.entries(b).map(([N,y])=>[N,y.join(` +`)]));ee($,n,F)},onerror:g=>{if(Lt(g))throw g("FetchExpectedTextEventStream",{url:i});g&&(console.error(g.message),ee(Xt,n,{message:g.message}))}},fe=new URL(i,document.baseURI),ne=new URLSearchParams(fe.search);if(c==="json"){let g=JSON.stringify(D({include:l,exclude:f}));t==="GET"?ne.set("datastar",g):B.body=g}else if(c==="form"){let g=a?document.querySelector(a):n.closest("form");if(!g)throw s("FetchFormNotFound",{action:O,selector:a});if(!g.checkValidity()){g.reportValidity(),K();return}let $=new FormData(g),b=n;if(n===g&&r instanceof SubmitEvent)b=r.submitter;else{let y=k=>k.preventDefault();g.addEventListener("submit",y),K=()=>{g.removeEventListener("submit",y),T.disconnect()}}if(b instanceof HTMLButtonElement){let y=b.getAttribute("name");y&&$.append(y,b.value)}let F=g.getAttribute("enctype")==="multipart/form-data";F||(H["Content-Type"]="application/x-www-form-urlencoded");let N=new URLSearchParams($);if(t==="GET")for(let[y,k]of N)ne.append(y,k);else F?B.body=$:B.body=N}else throw s("FetchInvalidContentType",{action:O,contentType:c});ee(ze,n,{}),fe.search=ne.toString();try{await on(fe.toString(),n,B)}catch(g){if(!Lt(g))throw s("FetchFailed",{method:t,url:i,error:g.message})}}finally{ee(Qe,n,{}),K()}}finally{He.get(n)===L&&He.delete(n)}}});be("delete","DELETE");be("get","GET");be("patch","PATCH");be("post","POST");be("put","PUT");var ze="started",Qe="finished",Yt="error",Xt="retrying",en="retries-failed",ee=(e,t,n)=>document.dispatchEvent(new CustomEvent(q,{detail:{type:e,el:t,argsRaw:n}})),Lt=e=>`${e}`.includes("text/event-stream"),tn=async(e,t)=>{let n=e.getReader(),r=await n.read();for(;!r.done;)t(r.value),r=await n.read()},nn=e=>{let t,n,r,s=!1;return i=>{t?t=sn(t,i):(t=i,n=0,r=-1);let a=t.length,o=0;for(;n{let r=Ft(),s=new TextDecoder;return(i,a)=>{if(!i.length)n?.(r),r=Ft();else if(a>0){let o=s.decode(i.subarray(0,a)),c=a+(i[a+1]===32?2:1),l=s.decode(i.subarray(c));switch(o){case"data":r.data=r.data?`${r.data} +${l}`:l;break;case"event":r.event=l;break;case"id":e(r.id=l);break;case"retry":{let f=+l;Number.isNaN(f)||t(r.retry=f);break}}}}},sn=(e,t)=>{let n=new Uint8Array(e.length+t.length);return n.set(e),n.set(t,e.length),n},Ft=()=>({data:"",event:"",id:"",retry:void 0}),on=(e,t,{signal:n,headers:r,onopen:s,onmessage:i,onclose:a,onerror:o,openWhenHidden:c,fetch:l,retryInterval:f=1e3,retryScaler:d=2,retryMaxWaitMs:x=3e4,retryMaxCount:u=10,overrides:m,...h})=>new Promise((v,L)=>{let A={...r},T,K=()=>{T.abort(),document.hidden||$()};c||document.addEventListener("visibilitychange",K);let j=0,H=()=>{document.removeEventListener("visibilitychange",K),clearTimeout(j),T.abort()};n?.addEventListener("abort",()=>{H(),v()});let B=l||window.fetch,fe=s||(()=>{}),ne=0,g=f,$=async()=>{T=new AbortController;try{let b=await B(e,{...h,headers:A,signal:T.signal});ne=0,f=g,await fe(b);let F=async(y,k,ue,Ee,...Vt)=>{let tt={[ue]:await k.text()};for(let ke of Vt){let _e=k.headers.get(`datastar-${de(ke)}`);if(Ee){let Se=Ee[ke];Se&&(_e=typeof Se=="string"?Se:JSON.stringify(Se))}_e&&(tt[ke]=_e)}ee(y,t,tt),H(),v()},N=b.headers.get("Content-Type");if(N?.includes("text/html"))return await F("datastar-patch-elements",b,"elements",m,"selector","mode","useViewTransition");if(N?.includes("application/json"))return await F("datastar-patch-signals",b,"signals",m,"onlyIfMissing");if(N?.includes("text/javascript")){let y=document.createElement("script"),k=b.headers.get("datastar-script-attributes");if(k)for(let[ue,Ee]of Object.entries(JSON.parse(k)))y.setAttribute(ue,Ee);y.textContent=await b.text(),document.head.appendChild(y),H();return}await tn(b.body,nn(rn(y=>{y?A["last-event-id"]=y:delete A["last-event-id"]},y=>{g=f=y},i))),a?.(),H(),v()}catch(b){if(!T.signal.aborted)try{let F=o?.(b)||f;clearTimeout(j),j=setTimeout($,F),f=Math.min(f*d,x),++ne>=u?(ee(en,t,{}),H(),L("Max retries reached.")):console.error(`Datastar failed to reach ${e.toString()} retrying in ${F}ms.`)}catch(F){H(),L(F)}}};$()});p({name:"attr",requirement:{value:"must"},returnsValue:!0,apply({el:e,key:t,rx:n}){let r=(o,c)=>{c===""||c===!0?e.setAttribute(o,""):c===!1||c==null?e.removeAttribute(o):typeof c=="string"?e.setAttribute(o,c):e.setAttribute(o,JSON.stringify(c))},s=t?()=>{i.disconnect();let o=n();r(t,o),i.observe(e,{attributeFilter:[t]})}:()=>{i.disconnect();let o=n(),c=Object.keys(o);for(let l of c)r(l,o[l]);i.observe(e,{attributeFilter:c})},i=new MutationObserver(s),a=E(s);return()=>{i.disconnect(),a()}}});var an=/^data:(?[^;]+);base64,(?.*)$/,Nt=Symbol("empty"),Ct=Q("bind");p({name:"bind",requirement:"exclusive",apply({el:e,key:t,mods:n,value:r,error:s}){let i=t!=null?R(t,n):r,a=(u,m)=>m==="number"?+u.value:u.value,o=u=>{e.value=`${u}`};if(e instanceof HTMLInputElement)switch(e.type){case"range":case"number":a=(u,m)=>m==="string"?u.value:+u.value;break;case"checkbox":a=(u,m)=>u.value!=="on"?m==="boolean"?u.checked:u.checked?u.value:"":m==="string"?u.checked?u.value:"":u.checked,o=u=>{e.checked=typeof u=="string"?u===e.value:u};break;case"radio":e.getAttribute("name")?.length||e.setAttribute("name",i),a=(u,m)=>u.checked?m==="number"?+u.value:u.value:Nt,o=u=>{e.checked=u===(typeof u=="number"?+e.value:e.value)};break;case"file":{let u=()=>{let m=[...e.files||[]],h=[];Promise.all(m.map(v=>new Promise(L=>{let A=new FileReader;A.onload=()=>{if(typeof A.result!="string")throw s("InvalidFileResultType",{resultType:typeof A.result});let T=A.result.match(an);if(!T?.groups)throw s("InvalidDataUri",{result:A.result});h.push({name:v.name,contents:T.groups.contents,mime:T.groups.mime})},A.onloadend=()=>L(),A.readAsDataURL(v)}))).then(()=>{S([[i,h]])})};return e.addEventListener("change",u),e.addEventListener("input",u),()=>{e.removeEventListener("change",u),e.removeEventListener("input",u)}}}else if(e instanceof HTMLSelectElement){if(e.multiple){let u=new Map;a=m=>[...m.selectedOptions].map(h=>{let v=u.get(h.value);return v==="string"||v==null?h.value:+h.value}),o=m=>{for(let h of e.options)m.includes(h.value)?(u.set(h.value,"string"),h.selected=!0):m.includes(+h.value)?(u.set(h.value,"number"),h.selected=!0):h.selected=!1}}}else e instanceof HTMLTextAreaElement||(a=u=>"value"in u?u.value:u.getAttribute("value"),o=u=>{"value"in e?e.value=u:e.setAttribute("value",u)});let c=ie(i),l=typeof c,f=i;if(Array.isArray(c)&&!(e instanceof HTMLSelectElement&&e.multiple)){let u=t||r,m=document.querySelectorAll(`[${Ct}\\:${CSS.escape(u)}],[${Ct}="${CSS.escape(u)}"]`),h=[],v=0;for(let L of m){if(h.push([`${f}.${v}`,a(L,"none")]),e===L)break;v++}S(h,{ifMissing:!0}),f=`${f}.${v}`}else S([[f,a(e,l)]],{ifMissing:!0});let d=()=>{let u=ie(f);if(u!=null){let m=a(e,typeof u);m!==Nt&&S([[f,m]])}};e.addEventListener("input",d),e.addEventListener("change",d);let x=E(()=>{o(ie(f))});return()=>{x(),e.removeEventListener("input",d),e.removeEventListener("change",d)}}});p({name:"class",requirement:{value:"must"},returnsValue:!0,apply({key:e,el:t,mods:n,rx:r}){e&&(e=R(e,n,"kebab"));let s=()=>{i.disconnect();let o=e?{[e]:r()}:r();for(let c in o){let l=c.split(/\s+/).filter(f=>f.length>0);if(o[c])for(let f of l)t.classList.contains(f)||t.classList.add(f);else for(let f of l)t.classList.contains(f)&&t.classList.remove(f)}i.observe(t,{attributeFilter:["class"]})},i=new MutationObserver(s),a=E(s);return()=>{i.disconnect(),a();let o=e?{[e]:r()}:r();for(let c in o){let l=c.split(/\s+/).filter(f=>f.length>0);for(let f of l)t.classList.remove(f)}}}});p({name:"computed",requirement:{value:"must"},returnsValue:!0,apply({key:e,mods:t,rx:n,error:r}){if(e)S([[R(e,t),Ne(n)]]);else{let s=Object.assign({},n());Z(s,i=>{if(typeof i=="function")return Ne(i);throw r("ComputedExpectedFunction")}),C(s)}}});p({name:"effect",requirement:{key:"denied",value:"must"},apply:({rx:e})=>E(e)});p({name:"indicator",requirement:"exclusive",apply({el:e,key:t,mods:n,value:r}){let s=t!=null?R(t,n):r;S([[s,!1]]);let i=a=>{let{type:o,el:c}=a.detail;if(c===e)switch(o){case ze:S([[s,!0]]);break;case Qe:S([[s,!1]]);break}};return document.addEventListener(q,i),()=>{S([[s,!1]]),document.removeEventListener(q,i)}}});p({name:"json-signals",requirement:{key:"denied"},apply({el:e,value:t,mods:n}){let r=n.has("terse")?0:2,s={};t&&(s=re(t));let i=()=>{a.disconnect(),e.textContent=JSON.stringify(D(s),null,r),a.observe(e,{childList:!0,characterData:!0,subtree:!0})},a=new MutationObserver(i),o=E(i);return()=>{a.disconnect(),o()}}});var U=e=>{if(!e||e.size<=0)return 0;for(let t of e){if(t.endsWith("ms"))return+t.replace("ms","");if(t.endsWith("s"))return+t.replace("s","")*1e3;try{return Number.parseFloat(t)}catch{}}return 0},te=(e,t,n=!1)=>e?e.has(t.toLowerCase()):n;var Ze=(e,t)=>(...n)=>{setTimeout(()=>{e(...n)},t)},cn=(e,t,n=!1,r=!0)=>{let s=0;return(...i)=>{s&&clearTimeout(s),n&&!s&&e(...i),s=setTimeout(()=>{r&&e(...i),s&&clearTimeout(s),s=0},t)}},ln=(e,t,n=!0,r=!1)=>{let s=!1;return(...i)=>{s||(n&&e(...i),s=!0,setTimeout(()=>{r&&e(...i),s=!1},t))}},le=(e,t)=>{let n=t.get("delay");if(n){let i=U(n);e=Ze(e,i)}let r=t.get("debounce");if(r){let i=U(r),a=te(r,"leading",!1),o=!te(r,"notrailing",!1);e=cn(e,i,a,o)}let s=t.get("throttle");if(s){let i=U(s),a=!te(s,"noleading",!1),o=te(s,"trailing",!1);e=ln(e,i,a,o)}return e};var Ye=!!document.startViewTransition,J=(e,t)=>{if(t.has("viewtransition")&&Ye){let n=e;e=(...r)=>document.startViewTransition(()=>n(...r))}return e};p({name:"on",requirement:"must",argNames:["evt"],apply({el:e,key:t,mods:n,rx:r}){let s=e;n.has("window")&&(s=window);let i=c=>{c&&(n.has("prevent")&&c.preventDefault(),n.has("stop")&&c.stopPropagation()),w(),r(c),M()};i=J(i,n),i=le(i,n);let a={capture:n.has("capture"),passive:n.has("passive"),once:n.has("once")};if(n.has("outside")){s=document;let c=i;i=l=>{e.contains(l?.target)||c(l)}}let o=R(t,n,"kebab");if((o===q||o===z)&&(s=document),e instanceof HTMLFormElement&&o==="submit"){let c=i;i=l=>{l?.preventDefault(),c(l)}}return s.addEventListener(o,i,a),()=>{s.removeEventListener(o,i)}}});var Xe=new WeakSet;p({name:"on-intersect",requirement:{key:"denied",value:"must"},apply({el:e,mods:t,rx:n}){let r=()=>{w(),n(),M()};r=J(r,t),r=le(r,t);let s={threshold:0};t.has("full")?s.threshold=1:t.has("half")&&(s.threshold=.5);let i=new IntersectionObserver(a=>{for(let o of a)o.isIntersecting&&(r(),i&&Xe.has(e)&&i.disconnect())},s);return i.observe(e),t.has("once")&&Xe.add(e),()=>{t.has("once")||Xe.delete(e),i&&(i.disconnect(),i=null)}}});p({name:"on-interval",requirement:{key:"denied",value:"must"},apply({mods:e,rx:t}){let n=()=>{w(),t(),M()};n=J(n,e);let r=1e3,s=e.get("duration");s&&(r=U(s),te(s,"leading",!1)&&n());let i=setInterval(n,r);return()=>{clearInterval(i)}}});p({name:"init",requirement:{key:"denied",value:"must"},apply({rx:e,mods:t}){let n=()=>{w(),e(),M()};n=J(n,t);let r=0,s=t.get("delay");s&&(r=U(s),r>0&&(n=Ze(n,r))),n()}});p({name:"on-signal-patch",requirement:{value:"must"},argNames:["patch"],returnsValue:!0,apply({el:e,key:t,mods:n,rx:r,error:s}){if(t&&t!=="filter")throw s("KeyNotAllowed");let i=e.getAttribute("data-on-signal-patch-filter"),a={};i&&(a=re(i));let o=le(c=>{let l=D(a,c.detail);it(l)||(w(),r(l),M())},n);return document.addEventListener(z,o),()=>{document.removeEventListener(z,o)}}});p({name:"ref",requirement:"exclusive",apply({el:e,key:t,mods:n,value:r}){let s=t!=null?R(t,n):r;S([[s,e]])}});var Ot="none",Pt="display";p({name:"show",requirement:{key:"denied",value:"must"},returnsValue:!0,apply({el:e,rx:t}){let n=()=>{r.disconnect(),t()?e.style.display===Ot&&e.style.removeProperty(Pt):e.style.setProperty(Pt,Ot),r.observe(e,{attributeFilter:["style"]})},r=new MutationObserver(n),s=E(n);return()=>{r.disconnect(),s()}}});p({name:"signals",returnsValue:!0,apply({key:e,mods:t,rx:n}){let r=t.has("ifmissing");if(e)e=R(e,t),S([[e,n?.()]],{ifMissing:r});else{let s=Object.assign({},n?.());C(s,{ifMissing:r})}}});p({name:"style",requirement:{value:"must"},returnsValue:!0,apply({key:e,el:t,rx:n}){let{style:r}=t,s=new Map,i=(l,f)=>{let d=s.get(l);!f&&f!==0?d!==void 0&&(d?r.setProperty(l,d):r.removeProperty(l)):(d===void 0&&s.set(l,r.getPropertyValue(l)),r.setProperty(l,String(f)))},a=()=>{if(o.disconnect(),e)i(e,n());else{let l=n();for(let[f,d]of s)f in l||(d?r.setProperty(f,d):r.removeProperty(f));for(let f in l)i(de(f),l[f])}o.observe(t,{attributeFilter:["style"]})},o=new MutationObserver(a),c=E(a);return()=>{o.disconnect(),c();for(let[l,f]of s)f?r.setProperty(l,f):r.removeProperty(l)}}});p({name:"text",requirement:{key:"denied",value:"must"},returnsValue:!0,apply({el:e,rx:t}){let n=()=>{r.disconnect(),e.textContent=`${t()}`,r.observe(e,{childList:!0,characterData:!0,subtree:!0})},r=new MutationObserver(n),s=E(n);return()=>{r.disconnect(),s()}}});he({name:"datastar-patch-elements",apply(e,{elements:t="",selector:n="",mode:r="outer",useViewTransition:s}){switch(r){case"remove":case"outer":case"inner":case"replace":case"prepend":case"append":case"before":case"after":break;default:throw e.error("PatchElementsInvalidMode",{mode:r})}if(!n&&r!=="outer"&&r!=="replace")throw e.error("PatchElementsExpectedSelector");let i={mode:r,selector:n,elements:t,useViewTransition:s?.trim()==="true"};Ye&&s?document.startViewTransition(()=>Ht(e,i)):Ht(e,i)}});var Ht=({error:e},{elements:t,selector:n,mode:r})=>{let s=t.replace(/]*>|>)([\s\S]*?)<\/svg>/gim,""),i=/<\/html>/.test(s),a=/<\/head>/.test(s),o=/<\/body>/.test(s),c=new DOMParser().parseFromString(i||a||o?t:``,"text/html"),l=document.createDocumentFragment();if(i?l.appendChild(c.documentElement):a&&o?(l.appendChild(c.head),l.appendChild(c.body)):a?l.appendChild(c.head):o?l.appendChild(c.body):l=c.querySelector("template").content,!n&&(r==="outer"||r==="replace"))for(let f of l.children){let d;if(f instanceof HTMLHtmlElement)d=document.documentElement;else if(f instanceof HTMLBodyElement)d=document.body;else if(f instanceof HTMLHeadElement)d=document.head;else if(d=document.getElementById(f.id),!d){console.warn(e("PatchElementsNoTargetsFound"),{element:{id:f.id}});continue}_t(r,f,[d])}else{let f=document.querySelectorAll(n);if(!f.length){console.warn(e("PatchElementsNoTargetsFound"),{selector:n});return}_t(r,l,f)}},et=new WeakSet;for(let e of document.querySelectorAll("script"))et.add(e);var Dt=e=>{let t=e instanceof HTMLScriptElement?[e]:e.querySelectorAll("script");for(let n of t)if(!et.has(n)){let r=document.createElement("script");for(let{name:s,value:i}of n.attributes)r.setAttribute(s,i);r.text=n.text,n.replaceWith(r),et.add(r)}},kt=(e,t,n)=>{for(let r of e){let s=t.cloneNode(!0);Dt(s),r[n](s)}},_t=(e,t,n)=>{switch(e){case"remove":for(let r of n)r.remove();break;case"outer":case"inner":for(let r of n)Ke(r,t.cloneNode(!0),e),Dt(r);break;case"replace":kt(n,t,"replaceWith");break;case"prepend":case"append":case"before":case"after":kt(n,t,e)}};he({name:"datastar-patch-signals",apply({error:e},{signals:t,onlyIfMissing:n}){if(t){let r=n?.trim()==="true";C(re(t),{ifMissing:r})}else throw e("PatchSignalsExpectedSignals")}});export{O as action,Et as actions,p as attribute,w as beginBatch,Ne as computed,E as effect,M as endBatch,D as filtered,ie as getPath,C as mergePatch,S as mergePaths,Ke as morph,X as root,me as signal,V as startPeeking,I as stopPeeking,he as watcher}; +//# sourceMappingURL=datastar.js.map diff --git a/experiments/simple/frontend/datastar.js.map b/experiments/simple/frontend/datastar.js.map new file mode 100644 index 0000000..f82819f --- /dev/null +++ b/experiments/simple/frontend/datastar.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["../library/src/engine/consts.ts", "../library/src/utils/text.ts", "../library/src/utils/polyfills.ts", "../library/src/utils/paths.ts", "../library/src/engine/signals.ts", "../library/src/utils/dom.ts", "../library/src/engine/engine.ts", "../library/src/engine/morph.ts", "../library/src/plugins/actions/peek.ts", "../library/src/plugins/actions/setAll.ts", "../library/src/plugins/actions/toggleAll.ts", "../library/src/plugins/actions/fetch.ts", "../library/src/plugins/attributes/attr.ts", "../library/src/plugins/attributes/bind.ts", "../library/src/plugins/attributes/class.ts", "../library/src/plugins/attributes/computed.ts", "../library/src/plugins/attributes/effect.ts", "../library/src/plugins/attributes/indicator.ts", "../library/src/plugins/attributes/jsonSignals.ts", "../library/src/utils/tags.ts", "../library/src/utils/timing.ts", "../library/src/utils/view-transitions.ts", "../library/src/plugins/attributes/on.ts", "../library/src/plugins/attributes/onIntersect.ts", "../library/src/plugins/attributes/onInterval.ts", "../library/src/plugins/attributes/init.ts", "../library/src/plugins/attributes/onSignalPatch.ts", "../library/src/plugins/attributes/ref.ts", "../library/src/plugins/attributes/show.ts", "../library/src/plugins/attributes/signals.ts", "../library/src/plugins/attributes/style.ts", "../library/src/plugins/attributes/text.ts", "../library/src/plugins/watchers/patchElements.ts", "../library/src/plugins/watchers/patchSignals.ts"], + "sourcesContent": ["const lol = /\uD83D\uDD95JS_DS\uD83D\uDE80/.source\nexport const DSP = lol.slice(0, 5)\nexport const DSS = lol.slice(4)\nexport const DATASTAR_FETCH_EVENT = 'datastar-fetch'\nexport const DATASTAR_SIGNAL_PATCH_EVENT = 'datastar-signal-patch'\n", "import type { Modifiers } from '@engine/types'\n\nexport const kebab = (str: string): string =>\n str\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/([a-z])([0-9]+)/gi, '$1-$2')\n .replace(/([0-9]+)([a-z])/gi, '$1-$2')\n .toLowerCase()\n\nexport const camel = (str: string): string =>\n kebab(str).replace(/-./g, (x) => x[1].toUpperCase())\n\nexport const snake = (str: string): string => kebab(str).replace(/-/g, '_')\n\nexport const pascal = (str: string): string =>\n camel(str).replace(/(^.|(?<=\\.).)/g, (x) => x[0].toUpperCase())\n\nexport const jsStrToObject = (raw: string) => {\n try {\n return JSON.parse(raw)\n } catch {\n // If JSON parsing fails, try to evaluate as a JavaScript object\n // This is less safe and should be used with caution\n return Function(`return (${raw})`)()\n }\n}\n\nconst caseFns: Record string> = {\n camel: (str) => str.replace(/-[a-z]/g, (x) => x[1].toUpperCase()),\n snake: (str) => str.replace(/-/g, '_'),\n pascal: (str) => str[0].toUpperCase() + caseFns.camel(str.slice(1)),\n}\n\nexport const modifyCasing = (\n str: string,\n mods: Modifiers,\n defaultCase = 'camel',\n): string => {\n for (const c of mods.get('case') || [defaultCase]) {\n str = caseFns[c]?.(str) || str\n }\n return str\n}\n\nexport const aliasify = (name: string) =>\n ALIAS ? `data-${ALIAS}-${name}` : `data-${name}`\n", "export const hasOwn: (obj: object, prop: PropertyKey) => boolean =\n // @ts-expect-error\n Object.hasOwn ?? Object.prototype.hasOwnProperty.call\n", "import type { Paths } from '@engine/types'\nimport { hasOwn } from '@utils/polyfills'\n\nexport const isPojo = (obj: any): obj is Record =>\n obj !== null &&\n typeof obj === 'object' &&\n (Object.getPrototypeOf(obj) === Object.prototype ||\n Object.getPrototypeOf(obj) === null)\n\nexport const isEmpty = (obj: Record): boolean => {\n for (const prop in obj) {\n if (hasOwn(obj, prop)) {\n return false\n }\n }\n return true\n}\n\nexport const updateLeaves = (\n obj: Record,\n fn: (oldValue: any) => any,\n) => {\n for (const key in obj) {\n const val = obj[key]\n if (isPojo(val) || Array.isArray(val)) {\n updateLeaves(val, fn)\n } else {\n obj[key] = fn(val)\n }\n }\n}\n\nexport const pathToObj = (paths: Paths): Record => {\n const result: Record = {}\n for (const [path, value] of paths) {\n const keys = path.split('.')\n const lastKey = keys.pop()!\n const obj = keys.reduce((acc, key) => (acc[key] ??= {}), result)\n obj[lastKey] = value\n }\n return result\n}\n", "import { DATASTAR_SIGNAL_PATCH_EVENT } from '@engine/consts'\nimport type {\n Computed,\n Effect,\n JSONPatch,\n MergePatchArgs,\n Paths,\n Signal,\n SignalFilterOptions,\n} from '@engine/types'\nimport { isPojo, pathToObj } from '@utils/paths'\nimport { hasOwn } from '@utils/polyfills'\n\ninterface ReactiveNode {\n deps_?: Link\n depsTail_?: Link\n subs_?: Link\n subsTail_?: Link\n flags_: ReactiveFlags\n}\n\ninterface Link {\n version_: number\n dep_: ReactiveNode\n sub_: ReactiveNode\n prevSub_?: Link\n nextSub_?: Link\n prevDep_?: Link\n nextDep_?: Link\n}\n\ninterface Stack {\n value_: T\n prev_?: Stack\n}\n\nenum ReactiveFlags {\n None = 0,\n Mutable = 1 << 0,\n Watching = 1 << 1,\n RecursedCheck = 1 << 2,\n Recursed = 1 << 3,\n Dirty = 1 << 4,\n Pending = 1 << 5,\n}\n\nenum EffectFlags {\n Queued = 1 << 6,\n}\n\ninterface AlienEffect extends ReactiveNode {\n fn_(): void\n}\n\ninterface AlienComputed extends ReactiveNode {\n value_?: T\n getter(previousValue?: T): T\n}\n\ninterface AlienSignal extends ReactiveNode {\n previousValue: T\n value_: T\n}\n\nconst currentPatch: Paths = []\nconst queuedEffects: (AlienEffect | undefined)[] = []\nlet batchDepth = 0\nlet notifyIndex = 0\nlet queuedEffectsLength = 0\nlet prevSub: ReactiveNode | undefined\nlet activeSub: ReactiveNode | undefined\nlet version = 0\n\nexport const beginBatch = (): void => {\n batchDepth++\n}\n\nexport const endBatch = (): void => {\n if (!--batchDepth) {\n flush()\n dispatch()\n }\n}\n\nexport const startPeeking = (sub?: ReactiveNode): void => {\n prevSub = activeSub\n activeSub = sub\n}\n\nexport const stopPeeking = (): void => {\n activeSub = prevSub\n prevSub = undefined\n}\n\nexport const signal = (initialValue?: T): Signal => {\n return signalOper.bind(0, {\n previousValue: initialValue,\n value_: initialValue,\n flags_: 1 satisfies ReactiveFlags.Mutable,\n }) as Signal\n}\n\nconst computedSymbol = Symbol('computed')\nexport const computed = (getter: (previousValue?: T) => T): Computed => {\n const c = computedOper.bind(0, {\n flags_: 17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty,\n getter,\n }) as Computed\n // @ts-expect-error\n c[computedSymbol] = 1\n return c\n}\n\nexport const effect = (fn: () => void): Effect => {\n const e: AlienEffect = {\n fn_: fn,\n flags_: 2 satisfies ReactiveFlags.Watching,\n }\n if (activeSub) {\n link(e, activeSub)\n }\n startPeeking(e)\n beginBatch()\n try {\n e.fn_()\n } finally {\n endBatch()\n stopPeeking()\n }\n return effectOper.bind(0, e)\n}\n\nconst flush = () => {\n while (notifyIndex < queuedEffectsLength) {\n const effect = queuedEffects[notifyIndex]!\n queuedEffects[notifyIndex++] = undefined\n run(effect, (effect.flags_ &= ~EffectFlags.Queued))\n }\n notifyIndex = 0\n queuedEffectsLength = 0\n}\n\nconst update = (signal: AlienSignal | AlienComputed): boolean => {\n if ('getter' in signal) {\n return updateComputed(signal)\n }\n return updateSignal(signal, signal.value_)\n}\n\nconst updateComputed = (c: AlienComputed): boolean => {\n startPeeking(c)\n startTracking(c)\n try {\n const oldValue = c.value_\n return oldValue !== (c.value_ = c.getter(oldValue))\n } finally {\n stopPeeking()\n endTracking(c)\n }\n}\n\nconst updateSignal = (s: AlienSignal, value: T): boolean => {\n s.flags_ = 1 satisfies ReactiveFlags.Mutable\n return s.previousValue !== (s.previousValue = value)\n}\n\nconst notify = (e: AlienEffect): void => {\n const flags = e.flags_\n if (!(flags & EffectFlags.Queued)) {\n e.flags_ = flags | EffectFlags.Queued\n const subs = e.subs_\n if (subs) {\n notify(subs.sub_ as AlienEffect)\n } else {\n queuedEffects[queuedEffectsLength++] = e\n }\n }\n}\n\nconst run = (e: AlienEffect, flags: ReactiveFlags): void => {\n if (\n flags & (16 satisfies ReactiveFlags.Dirty) ||\n (flags & (32 satisfies ReactiveFlags.Pending) && checkDirty(e.deps_!, e))\n ) {\n startPeeking(e)\n startTracking(e)\n beginBatch()\n try {\n e.fn_()\n } finally {\n endBatch()\n stopPeeking()\n endTracking(e)\n }\n return\n }\n if (flags & (32 satisfies ReactiveFlags.Pending)) {\n e.flags_ = flags & ~(32 satisfies ReactiveFlags.Pending)\n }\n let link = e.deps_\n while (link) {\n const dep = link.dep_\n const depFlags = dep.flags_\n if (depFlags & EffectFlags.Queued) {\n run(dep as AlienEffect, (dep.flags_ = depFlags & ~EffectFlags.Queued))\n }\n link = link.nextDep_\n }\n}\n\nconst signalOper = (s: AlienSignal, ...value: [T]): T | boolean => {\n if (value.length) {\n if (s.value_ !== (s.value_ = value[0])) {\n s.flags_ = 17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty\n const subs = s.subs_\n if (subs) {\n propagate(subs)\n if (!batchDepth) {\n flush()\n }\n }\n return true\n }\n return false\n }\n const currentValue = s.value_\n if (s.flags_ & (16 satisfies ReactiveFlags.Dirty)) {\n if (updateSignal(s, currentValue)) {\n const subs_ = s.subs_\n if (subs_) {\n shallowPropagate(subs_)\n }\n }\n }\n if (activeSub) {\n link(s, activeSub)\n }\n return currentValue\n}\n\nconst computedOper = (c: AlienComputed): T => {\n const flags = c.flags_\n if (\n flags & (16 satisfies ReactiveFlags.Dirty) ||\n (flags & (32 satisfies ReactiveFlags.Pending) && checkDirty(c.deps_!, c))\n ) {\n if (updateComputed(c)) {\n const subs = c.subs_\n if (subs) {\n shallowPropagate(subs)\n }\n }\n } else if (flags & (32 satisfies ReactiveFlags.Pending)) {\n c.flags_ = flags & ~(32 satisfies ReactiveFlags.Pending)\n }\n if (activeSub) {\n link(c, activeSub)\n }\n return c.value_!\n}\n\nconst effectOper = (e: AlienEffect): void => {\n let dep = e.deps_\n while (dep) {\n dep = unlink(dep, e)\n }\n const sub = e.subs_\n if (sub) {\n unlink(sub)\n }\n e.flags_ = 0 satisfies ReactiveFlags.None\n}\n\nconst link = (dep: ReactiveNode, sub: ReactiveNode): void => {\n const prevDep = sub.depsTail_\n if (prevDep && prevDep.dep_ === dep) {\n return\n }\n const nextDep = prevDep ? prevDep.nextDep_ : sub.deps_\n if (nextDep && nextDep.dep_ === dep) {\n nextDep.version_ = version\n sub.depsTail_ = nextDep\n return\n }\n const prevSub = dep.subsTail_\n if (prevSub && prevSub.version_ === version && prevSub.sub_ === sub) {\n return\n }\n const newLink =\n (sub.depsTail_ =\n dep.subsTail_ =\n {\n version_: version,\n dep_: dep,\n sub_: sub,\n prevDep_: prevDep,\n nextDep_: nextDep,\n prevSub_: prevSub,\n })\n if (nextDep) {\n nextDep.prevDep_ = newLink\n }\n if (prevDep) {\n prevDep.nextDep_ = newLink\n } else {\n sub.deps_ = newLink\n }\n if (prevSub) {\n prevSub.nextSub_ = newLink\n } else {\n dep.subs_ = newLink\n }\n}\n\nconst unlink = (link: Link, sub = link.sub_): Link | undefined => {\n const dep_ = link.dep_\n const prevDep_ = link.prevDep_\n const nextDep_ = link.nextDep_\n const nextSub_ = link.nextSub_\n const prevSub_ = link.prevSub_\n if (nextDep_) {\n nextDep_.prevDep_ = prevDep_\n } else {\n sub.depsTail_ = prevDep_\n }\n if (prevDep_) {\n prevDep_.nextDep_ = nextDep_\n } else {\n sub.deps_ = nextDep_\n }\n if (nextSub_) {\n nextSub_.prevSub_ = prevSub_\n } else {\n dep_.subsTail_ = prevSub_\n }\n if (prevSub_) {\n prevSub_.nextSub_ = nextSub_\n } else if (!(dep_.subs_ = nextSub_)) {\n if ('getter' in dep_) {\n let toRemove = dep_.deps_\n if (toRemove) {\n dep_.flags_ = 17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty\n do {\n toRemove = unlink(toRemove, dep_)\n } while (toRemove)\n }\n } else if (!('previousValue' in dep_)) {\n effectOper(dep_ as AlienEffect)\n }\n }\n return nextDep_\n}\n\nconst propagate = (link: Link): void => {\n let next = link.nextSub_\n let stack: Stack | undefined\n\n top: while (true) {\n const sub = link.sub_\n\n let flags = sub.flags_\n\n if (\n !(\n flags &\n (60 as\n | ReactiveFlags.RecursedCheck\n | ReactiveFlags.Recursed\n | ReactiveFlags.Dirty\n | ReactiveFlags.Pending)\n )\n ) {\n sub.flags_ = flags | (32 satisfies ReactiveFlags.Pending)\n } else if (\n !(flags & (12 as ReactiveFlags.RecursedCheck | ReactiveFlags.Recursed))\n ) {\n flags = 0 satisfies ReactiveFlags.None\n } else if (!(flags & (4 satisfies ReactiveFlags.RecursedCheck))) {\n sub.flags_ =\n (flags & ~(8 satisfies ReactiveFlags.Recursed)) |\n (32 satisfies ReactiveFlags.Pending)\n } else if (\n !(flags & (48 as ReactiveFlags.Dirty | ReactiveFlags.Pending)) &&\n isValidLink(link, sub)\n ) {\n sub.flags_ =\n flags | (40 as ReactiveFlags.Recursed | ReactiveFlags.Pending)\n flags &= 1 satisfies ReactiveFlags.Mutable\n } else {\n flags = 0 satisfies ReactiveFlags.None\n }\n\n if (flags & (2 satisfies ReactiveFlags.Watching)) {\n notify(sub as AlienEffect)\n }\n\n if (flags & (1 satisfies ReactiveFlags.Mutable)) {\n const subSubs = sub.subs_\n if (subSubs) {\n const nextSub = (link = subSubs).nextSub_\n if (nextSub) {\n stack = { value_: next, prev_: stack }\n next = nextSub\n }\n continue\n }\n }\n\n if ((link = next!)) {\n next = link.nextSub_\n continue\n }\n\n while (stack) {\n link = stack.value_!\n stack = stack.prev_\n if (link) {\n next = link.nextSub_\n continue top\n }\n }\n\n break\n }\n}\n\nconst startTracking = (sub: ReactiveNode): void => {\n version++\n sub.depsTail_ = undefined\n sub.flags_ =\n (sub.flags_ &\n ~(56 as\n | ReactiveFlags.Recursed\n | ReactiveFlags.Dirty\n | ReactiveFlags.Pending)) |\n (4 satisfies ReactiveFlags.RecursedCheck)\n}\n\nconst endTracking = (sub: ReactiveNode): void => {\n const depsTail_ = sub.depsTail_\n let toRemove = depsTail_ ? depsTail_.nextDep_ : sub.deps_\n while (toRemove) {\n toRemove = unlink(toRemove, sub)\n }\n sub.flags_ &= ~(4 satisfies ReactiveFlags.RecursedCheck)\n}\n\nconst checkDirty = (link: Link, sub: ReactiveNode): boolean => {\n let stack: Stack | undefined\n let checkDepth = 0\n let dirty = false\n\n top: while (true) {\n const dep = link.dep_\n const flags = dep.flags_\n\n if (sub.flags_ & (16 satisfies ReactiveFlags.Dirty)) {\n dirty = true\n } else if (\n (flags & (17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty)) ===\n (17 as ReactiveFlags.Mutable | ReactiveFlags.Dirty)\n ) {\n if (update(dep as AlienSignal | AlienComputed)) {\n const subs = dep.subs_!\n if (subs.nextSub_) {\n shallowPropagate(subs)\n }\n dirty = true\n }\n } else if (\n (flags & (33 as ReactiveFlags.Mutable | ReactiveFlags.Pending)) ===\n (33 as ReactiveFlags.Mutable | ReactiveFlags.Pending)\n ) {\n if (link.nextSub_ || link.prevSub_) {\n stack = { value_: link, prev_: stack }\n }\n link = dep.deps_!\n sub = dep\n ++checkDepth\n continue\n }\n\n if (!dirty) {\n const nextDep = link.nextDep_\n if (nextDep) {\n link = nextDep\n continue\n }\n }\n\n while (checkDepth--) {\n const firstSub = sub.subs_!\n const hasMultipleSubs = firstSub.nextSub_\n if (hasMultipleSubs) {\n link = stack!.value_\n stack = stack!.prev_\n } else {\n link = firstSub\n }\n if (dirty) {\n if (update(sub as AlienSignal | AlienComputed)) {\n if (hasMultipleSubs) {\n shallowPropagate(firstSub)\n }\n sub = link.sub_\n continue\n }\n dirty = false\n } else {\n sub.flags_ &= ~(32 satisfies ReactiveFlags.Pending)\n }\n sub = link.sub_\n if (link.nextDep_) {\n link = link.nextDep_\n continue top\n }\n }\n\n return dirty\n }\n}\n\nconst shallowPropagate = (link: Link): void => {\n do {\n const sub = link.sub_\n const flags = sub.flags_\n if (\n (flags & (48 as ReactiveFlags.Pending | ReactiveFlags.Dirty)) ===\n (32 satisfies ReactiveFlags.Pending)\n ) {\n sub.flags_ = flags | (16 satisfies ReactiveFlags.Dirty)\n if (flags & (2 satisfies ReactiveFlags.Watching)) {\n notify(sub as AlienEffect)\n }\n }\n } while ((link = link.nextSub_!))\n}\n\nconst isValidLink = (checkLink: Link, sub: ReactiveNode): boolean => {\n let link = sub.depsTail_\n while (link) {\n if (link === checkLink) {\n return true\n }\n link = link.prevDep_\n }\n return false\n}\n\nexport const getPath = (path: string): T | undefined => {\n let result = root\n const split = path.split('.')\n for (const path of split) {\n if (result == null || !hasOwn(result, path)) {\n return\n }\n result = result[path]\n }\n return result as T\n}\n\nconst deep = (value: any, prefix = ''): any => {\n const isArr = Array.isArray(value)\n if (isArr || isPojo(value)) {\n const deepObj = (isArr ? [] : {}) as Record>\n for (const key in value) {\n deepObj[key] = signal(\n deep((value as Record>)[key], `${prefix + key}.`),\n )\n }\n const keys = signal(0)\n return new Proxy(deepObj, {\n get(_, prop: string) {\n // JSON.stringify calls `.toJSON()` directly instead of checking if it exists on the object\n // so we have to check if `toJSON` is being called and prevent a signal from automatically\n // being made so JSON.stringify can fallback to the default stringify\n if (!(prop === 'toJSON' && !hasOwn(deepObj, prop))) {\n // special case for when prop is an array function because every array function needs to\n // be reactive to when the keys change\n if (isArr && prop in Array.prototype) {\n keys()\n return deepObj[prop]\n }\n // if prop is a symbol just return the symbol because we don't want to make up that theres\n // an iterator symbol on an object or not\n if (typeof prop === 'symbol') {\n return deepObj[prop]\n }\n // if obj doesnt have prop OR prop is null or undefined then create a signal and default\n // to an empty string\n if (!hasOwn(deepObj, prop) || deepObj[prop]() == null) {\n deepObj[prop] = signal('')\n dispatch(prefix + prop, '')\n keys(keys() + 1)\n }\n return deepObj[prop]()\n }\n },\n set(_, prop: string, newValue) {\n const path = prefix + prop\n // special case for when setting length so we can make a diff patch\n if (isArr && prop === 'length') {\n const diff = (deepObj[prop] as unknown as number) - newValue\n deepObj[prop] = newValue\n // manually make a diff patch for now, shouldnt have to do this when object diffing is\n // implemented. see https://github.com/starfederation/datastar-dev/issues/274\n if (diff > 0) {\n const patch: Record = {}\n for (let i = newValue; i < deepObj[prop]; i++) {\n patch[i] = null\n }\n dispatch(prefix.slice(0, -1), patch)\n keys(keys() + 1)\n }\n } else if (hasOwn(deepObj, prop)) {\n if (newValue == null) {\n delete deepObj[prop]\n // if newValue is a computed set the computed directly instead of wrapping in signal\n } else if (hasOwn(newValue, computedSymbol)) {\n deepObj[prop] = newValue\n dispatch(path, '')\n // if prop changed after setting it then dispatch\n } else if (deepObj[prop](deep(newValue, `${path}.`))) {\n dispatch(path, newValue)\n }\n // if newValue is null or undefined then noop\n } else if (newValue != null) {\n // if newValue is a computed set the computed directly instead of wrapping in signal\n if (hasOwn(newValue, computedSymbol)) {\n deepObj[prop] = newValue\n dispatch(path, '')\n } else {\n deepObj[prop] = signal(deep(newValue, `${path}.`))\n dispatch(path, newValue)\n }\n keys(keys() + 1)\n }\n\n return true\n },\n deleteProperty(_, prop: string) {\n delete deepObj[prop]\n keys(keys() + 1)\n return true\n },\n ownKeys() {\n keys()\n return Reflect.ownKeys(deepObj)\n },\n has(_, prop) {\n keys()\n return prop in deepObj\n },\n })\n }\n return value\n}\n\nconst dispatch = (path?: string, value?: any) => {\n if (path !== undefined && value !== undefined) {\n currentPatch.push([path, value])\n }\n if (!batchDepth && currentPatch.length) {\n const detail = pathToObj(currentPatch)\n currentPatch.length = 0\n document.dispatchEvent(\n new CustomEvent(DATASTAR_SIGNAL_PATCH_EVENT, {\n detail,\n }),\n )\n }\n}\n\nexport const mergePatch = (\n patch: JSONPatch,\n { ifMissing }: MergePatchArgs = {},\n): void => {\n beginBatch()\n for (const key in patch) {\n if (patch[key] == null) {\n if (!ifMissing) {\n delete root[key]\n }\n } else {\n mergeInner(patch[key], key, root, '', ifMissing)\n }\n }\n endBatch()\n}\n\nexport const mergePaths = (paths: Paths, options?: MergePatchArgs): void =>\n mergePatch(pathToObj(paths), options)\n\nconst mergeInner = (\n patch: any,\n target: string,\n targetParent: Record,\n prefix: string,\n ifMissing: boolean | undefined,\n): void => {\n if (isPojo(patch)) {\n if (\n !(\n hasOwn(targetParent, target) &&\n (isPojo(targetParent[target]) || Array.isArray(targetParent[target]))\n )\n ) {\n targetParent[target] = {}\n }\n\n for (const key in patch) {\n if (patch[key] == null) {\n if (!ifMissing) {\n delete targetParent[target][key]\n }\n } else {\n mergeInner(\n patch[key],\n key,\n targetParent[target],\n `${prefix + target}.`,\n ifMissing,\n )\n }\n }\n } else if (!(ifMissing && hasOwn(targetParent, target))) {\n targetParent[target] = patch\n }\n}\n\nconst toRegExp = (val: string | RegExp): RegExp =>\n typeof val === 'string' ? RegExp(val.replace(/^\\/|\\/$/g, '')) : val\n\n/**\n * Filters the root store based on an include and exclude RegExp\n *\n * @returns The filtered object\n */\nexport const filtered = (\n { include = /.*/, exclude = /(?!)/ }: SignalFilterOptions = {},\n obj: JSONPatch = root,\n): Record => {\n const includeRe = toRegExp(include)\n const excludeRe = toRegExp(exclude)\n const paths: Paths = []\n const stack: [any, string][] = [[obj, '']]\n\n while (stack.length) {\n const [node, prefix] = stack.pop()!\n\n for (const key in node) {\n const path = prefix + key\n if (isPojo(node[key])) {\n stack.push([node[key], `${path}.`])\n } else if (includeRe.test(path) && !excludeRe.test(path)) {\n paths.push([path, getPath(path)])\n }\n }\n }\n\n return pathToObj(paths)\n}\n\nexport const root: Record = deep({})\n", "import type { HTMLOrSVG } from '@engine/types'\n\nexport const isHTMLOrSVG = (el: Node): el is HTMLOrSVG =>\n el instanceof HTMLElement ||\n el instanceof SVGElement ||\n el instanceof MathMLElement\n", "import { DATASTAR_FETCH_EVENT, DSP, DSS } from '@engine/consts'\nimport { snake } from '@utils/text'\nimport { root } from '@engine/signals'\nimport type {\n ActionPlugin,\n ActionContext,\n AttributeContext,\n AttributePlugin,\n DatastarFetchEvent,\n HTMLOrSVG,\n Requirement,\n WatcherPlugin,\n} from '@engine/types'\nimport { isHTMLOrSVG } from '@utils/dom'\nimport { aliasify } from '@utils/text'\n\nconst url = 'https://data-star.dev/errors'\n\nconst error = (\n ctx: Record,\n reason: string,\n metadata: Record = {},\n) => {\n Object.assign(metadata, ctx)\n const e = new Error()\n const r = snake(reason)\n const q = new URLSearchParams({\n metadata: JSON.stringify(metadata),\n }).toString()\n const c = JSON.stringify(metadata, null, 2)\n e.message = `${reason}\\nMore info: ${url}/${r}?${q}\\nContext: ${c}`\n return e\n}\n\nconst actionPlugins: Map = new Map()\nconst attributePlugins: Map = new Map()\nconst watcherPlugins: Map = new Map()\n\nexport const actions: Record<\n string,\n (ctx: ActionContext, ...args: any[]) => any\n> = new Proxy(\n {},\n {\n get: (_, prop: string) => actionPlugins.get(prop)?.apply,\n has: (_, prop: string) => actionPlugins.has(prop),\n ownKeys: () => Reflect.ownKeys(actionPlugins),\n set: () => false,\n deleteProperty: () => false,\n },\n)\n\n// Map of cleanups keyed by element and attribute name\nconst removals = new Map void>>()\n\nconst queuedAttributes: AttributePlugin[] = []\nconst queuedAttributeNames = new Set()\nexport const attribute = (\n plugin: AttributePlugin,\n): void => {\n queuedAttributes.push(plugin as unknown as AttributePlugin)\n\n if (queuedAttributes.length === 1) {\n setTimeout(() => {\n for (const attribute of queuedAttributes) {\n queuedAttributeNames.add(attribute.name)\n attributePlugins.set(attribute.name, attribute)\n }\n queuedAttributes.length = 0\n apply()\n queuedAttributeNames.clear()\n })\n }\n}\n\nexport const action = (plugin: ActionPlugin): void => {\n actionPlugins.set(plugin.name, plugin)\n}\n\ndocument.addEventListener(DATASTAR_FETCH_EVENT, ((\n evt: CustomEvent,\n) => {\n const plugin = watcherPlugins.get(evt.detail.type)\n if (plugin) {\n plugin.apply(\n {\n error: error.bind(0, {\n plugin: { type: 'watcher', name: plugin.name },\n element: {\n id: (evt.target as Element).id,\n tag: (evt.target as Element).tagName,\n },\n }),\n },\n evt.detail.argsRaw,\n )\n }\n}) as EventListener)\n\nexport const watcher = (plugin: WatcherPlugin): void => {\n watcherPlugins.set(plugin.name, plugin)\n}\n\nconst cleanupEls = (els: Iterable): void => {\n for (const el of els) {\n const cleanups = removals.get(el)\n // If removals has el, delete it and run all cleanup functions\n if (removals.delete(el)) {\n for (const cleanup of cleanups!.values()) {\n cleanup()\n }\n cleanups!.clear()\n }\n }\n}\n\nconst aliasedIgnore = aliasify('ignore')\nconst aliasedIgnoreAttr = `[${aliasedIgnore}]`\nconst shouldIgnore = (el: HTMLOrSVG) =>\n el.hasAttribute(`${aliasedIgnore}__self`) || !!el.closest(aliasedIgnoreAttr)\n\nconst applyEls = (els: Iterable, onlyNew?: boolean): void => {\n for (const el of els) {\n if (!shouldIgnore(el)) {\n for (const key in el.dataset) {\n applyAttributePlugin(\n el,\n key.replace(/[A-Z]/g, '-$&').toLowerCase(),\n el.dataset[key]!,\n onlyNew,\n )\n }\n }\n }\n}\n\nconst observe = (mutations: MutationRecord[]) => {\n for (const {\n target,\n type,\n attributeName,\n addedNodes,\n removedNodes,\n } of mutations) {\n if (type === 'childList') {\n for (const node of removedNodes) {\n if (isHTMLOrSVG(node)) {\n cleanupEls([node])\n cleanupEls(node.querySelectorAll('*'))\n }\n }\n\n for (const node of addedNodes) {\n if (isHTMLOrSVG(node)) {\n applyEls([node])\n applyEls(node.querySelectorAll('*'))\n }\n }\n } else if (\n type === 'attributes' &&\n attributeName!.startsWith('data-') &&\n isHTMLOrSVG(target) &&\n !shouldIgnore(target)\n ) {\n // skip over 'data-'\n const key = attributeName!.slice(5)\n const value = target.getAttribute(attributeName!)\n if (value === null) {\n const cleanups = removals.get(target)\n if (cleanups) {\n cleanups.get(key)?.()\n cleanups.delete(key)\n }\n } else {\n applyAttributePlugin(target, key, value)\n }\n }\n }\n}\n\n// TODO: mutation observer per root so applying to web component doesnt overwrite main observer\nconst mutationObserver = new MutationObserver(observe)\n\nexport const apply = (\n root: HTMLOrSVG | ShadowRoot = document.documentElement,\n): void => {\n if (isHTMLOrSVG(root)) {\n applyEls([root], true)\n }\n applyEls(root.querySelectorAll('*'), true)\n\n mutationObserver.observe(root, {\n subtree: true,\n childList: true,\n attributes: true,\n })\n}\n\nconst applyAttributePlugin = (\n el: HTMLOrSVG,\n attrKey: string,\n value: string,\n onlyNew?: boolean,\n): void => {\n if (!ALIAS || attrKey.startsWith(`${ALIAS}-`)) {\n const rawKey = ALIAS ? attrKey.slice(ALIAS.length + 1) : attrKey\n const [namePart, ...rawModifiers] = rawKey.split('__')\n const [pluginName, key] = namePart.split(/:(.+)/)\n const plugin = attributePlugins.get(pluginName)\n if ((!onlyNew || queuedAttributeNames.has(pluginName)) && plugin) {\n const ctx = {\n el,\n rawKey,\n mods: new Map(),\n error: error.bind(0, {\n plugin: { type: 'attribute', name: plugin.name },\n element: { id: el.id, tag: el.tagName },\n expression: { rawKey, key, value },\n }),\n key,\n value,\n rx: undefined,\n } as AttributeContext\n\n const keyReq =\n (plugin.requirement &&\n (typeof plugin.requirement === 'string'\n ? plugin.requirement\n : plugin.requirement.key)) ||\n 'allowed'\n const valueReq =\n (plugin.requirement &&\n (typeof plugin.requirement === 'string'\n ? plugin.requirement\n : plugin.requirement.value)) ||\n 'allowed'\n\n if (key) {\n if (keyReq === 'denied') {\n throw ctx.error('KeyNotAllowed')\n }\n } else if (keyReq === 'must') {\n throw ctx.error('KeyRequired')\n }\n\n if (value) {\n if (valueReq === 'denied') {\n throw ctx.error('ValueNotAllowed')\n }\n } else if (valueReq === 'must') {\n throw ctx.error('ValueRequired')\n }\n\n if (keyReq === 'exclusive' || valueReq === 'exclusive') {\n if (key && value) {\n throw ctx.error('KeyAndValueProvided')\n }\n if (!key && !value) {\n throw ctx.error('KeyOrValueRequired')\n }\n }\n\n if (value) {\n let cachedRx: GenRxFn\n ctx.rx = (...args: any[]) => {\n if (!cachedRx) {\n cachedRx = genRx(value, {\n returnsValue: plugin.returnsValue,\n argNames: plugin.argNames,\n })\n }\n return cachedRx(el, ...args)\n }\n }\n\n for (const rawMod of rawModifiers) {\n const [label, ...mod] = rawMod.split('.')\n ctx.mods.set(label, new Set(mod))\n }\n\n const cleanup = plugin.apply(ctx)\n if (cleanup) {\n let cleanups = removals.get(el)\n if (cleanups) {\n cleanups.get(rawKey)?.()\n } else {\n cleanups = new Map()\n removals.set(el, cleanups)\n }\n cleanups.set(rawKey, cleanup)\n }\n }\n }\n}\n\ntype GenRxOptions = {\n returnsValue?: boolean\n argNames?: string[]\n}\n\ntype GenRxFn = (el: HTMLOrSVG, ...args: any[]) => T\n\nconst genRx = (\n value: string,\n { returnsValue = false, argNames = [] }: GenRxOptions = {},\n): GenRxFn => {\n let expr = ''\n if (returnsValue) {\n // This regex allows Datastar expressions to support nested\n // regex and strings that contain ; without breaking.\n //\n // Each of these regex defines a block type we want to match\n // (importantly we ignore the content within these blocks):\n //\n // regex \\/(\\\\\\/|[^\\/])*\\/\n // double quotes \"(\\\\\"|[^\\\"])*\"\n // single quotes '(\\\\'|[^'])*'\n // ticks `(\\\\`|[^`])*`\n // iife \\(\\s*((function)\\s*\\(\\s*\\)|(\\(\\s*\\))\\s*=>)\\s*(?:\\{[\\s\\S]*?\\}|[^;)\\{]*)\\s*\\)\\s*\\(\\s*\\)\n //\n // The iife support is (intentionally) limited. It only supports\n // function and arrow syntax with no arguments, and no nested IIFEs.\n //\n // We also want to match the non delimiter part of statements\n // note we only support ; statement delimiters:\n //\n // [^;]\n //\n const statementRe =\n /(\\/(\\\\\\/|[^/])*\\/|\"(\\\\\"|[^\"])*\"|'(\\\\'|[^'])*'|`(\\\\`|[^`])*`|\\(\\s*((function)\\s*\\(\\s*\\)|(\\(\\s*\\))\\s*=>)\\s*(?:\\{[\\s\\S]*?\\}|[^;){]*)\\s*\\)\\s*\\(\\s*\\)|[^;])+/gm\n const statements = value.trim().match(statementRe)\n if (statements) {\n const lastIdx = statements.length - 1\n const last = statements[lastIdx].trim()\n if (!last.startsWith('return')) {\n statements[lastIdx] = `return (${last});`\n }\n expr = statements.join(';\\n')\n }\n } else {\n expr = value.trim()\n }\n\n // Ignore any escaped values\n const escaped = new Map()\n const escapeRe = RegExp(`(?:${DSP})(.*?)(?:${DSS})`, 'gm')\n let counter = 0\n for (const match of expr.matchAll(escapeRe)) {\n const k = match[1]\n const v = `__escaped${counter++}`\n escaped.set(v, k)\n expr = expr.replace(DSP + k + DSS, v)\n }\n\n // Replace signal references with bracket notation\n // Examples:\n // $count -> $['count']\n // $count-- -> $['count']--\n // $foo.bar -> $['foo']['bar']\n // $foo-bar -> $['foo-bar']\n // $foo.bar-baz -> $['foo']['bar-baz']\n // $foo-$bar -> $['foo']-$['bar']\n // $arr[$index] -> $['arr'][$['index']]\n // $['foo'] -> $['foo']\n // $foo[obj.bar] -> $['foo'][obj.bar]\n // $foo['bar.baz'] -> $['foo']['bar.baz']\n // $123 -> $['123']\n // $foo.0.name -> $['foo']['0']['name']\n\n expr = expr\n // $['x'] -> $x (normalize existing bracket notation)\n .replace(/\\$\\['([a-zA-Z_$\\d][\\w$]*)'\\]/g, '$$$1')\n // $x -> $['x'] (including dots and hyphens)\n .replace(/\\$([a-zA-Z_\\d]\\w*(?:[.-]\\w+)*)/g, (_, signalName) =>\n signalName\n .split('.')\n .reduce((acc: string, part: string) => `${acc}['${part}']`, '$'),\n )\n // [$x] -> [$['x']] ($ inside brackets)\n .replace(\n /\\[(\\$[a-zA-Z_\\d]\\w*)\\]/g,\n (_, varName) => `[$['${varName.slice(1)}']]`,\n )\n\n expr = expr.replaceAll(/@(\\w+)\\(/g, '__action(\"$1\",evt,')\n\n // Replace any escaped values\n for (const [k, v] of escaped) {\n expr = expr.replace(k, v)\n }\n\n try {\n const fn = Function('el', '$', '__action', 'evt', ...argNames, expr)\n return (el: HTMLOrSVG, ...args: any[]) => {\n const action = (name: string, evt: Event | undefined, ...args: any[]) => {\n const err = error.bind(0, {\n plugin: { type: 'action', name },\n element: { id: el.id, tag: el.tagName },\n expression: {\n fnContent: expr,\n value,\n },\n })\n const fn = actions[name]\n if (fn) {\n return fn(\n {\n el,\n evt,\n error: err,\n },\n ...args,\n )\n }\n throw err('UndefinedAction')\n }\n try {\n return fn(el, root, action, undefined, ...args)\n } catch (e: any) {\n console.error(e)\n throw error(\n {\n element: { id: el.id, tag: el.tagName },\n expression: {\n fnContent: expr,\n value,\n },\n error: e.message,\n },\n 'ExecuteExpression',\n )\n }\n }\n } catch (e: any) {\n console.error(e)\n throw error(\n {\n expression: {\n fnContent: expr,\n value,\n },\n error: e.message,\n },\n 'GenerateExpression',\n )\n }\n}\n", "import { isHTMLOrSVG } from '@utils/dom'\nimport { aliasify } from '@utils/text'\n\nconst ctxIdMap = new Map>()\nconst ctxPersistentIds = new Set()\nconst oldIdTagNameMap = new Map()\nconst duplicateIds = new Set()\nconst ctxPantry = document.createElement('div')\nctxPantry.hidden = true\n\nconst aliasedIgnoreMorph = aliasify('ignore-morph')\nconst aliasedIgnoreMorphAttr = `[${aliasedIgnoreMorph}]`\nexport const morph = (\n oldElt: Element | ShadowRoot,\n newContent: DocumentFragment | Element,\n mode: 'outer' | 'inner' = 'outer',\n): void => {\n if (\n (isHTMLOrSVG(oldElt) &&\n isHTMLOrSVG(newContent) &&\n oldElt.hasAttribute(aliasedIgnoreMorph) &&\n newContent.hasAttribute(aliasedIgnoreMorph)) ||\n oldElt.parentElement?.closest(aliasedIgnoreMorphAttr)\n ) {\n return\n }\n\n const normalizedElt = document.createElement('div')\n normalizedElt.append(newContent)\n document.body.insertAdjacentElement('afterend', ctxPantry)\n\n // Computes the set of IDs that persist between the two contents excluding duplicates\n const oldIdElements = oldElt.querySelectorAll('[id]')\n for (const { id, tagName } of oldIdElements) {\n if (oldIdTagNameMap.has(id)) {\n duplicateIds.add(id)\n } else {\n oldIdTagNameMap.set(id, tagName)\n }\n }\n if (oldElt instanceof Element && oldElt.id) {\n if (oldIdTagNameMap.has(oldElt.id)) {\n duplicateIds.add(oldElt.id)\n } else {\n oldIdTagNameMap.set(oldElt.id, oldElt.tagName)\n }\n }\n\n ctxPersistentIds.clear()\n const newIdElements = normalizedElt.querySelectorAll('[id]')\n for (const { id, tagName } of newIdElements) {\n if (ctxPersistentIds.has(id)) {\n duplicateIds.add(id)\n } else if (oldIdTagNameMap.get(id) === tagName) {\n ctxPersistentIds.add(id)\n }\n }\n\n for (const id of duplicateIds) {\n ctxPersistentIds.delete(id)\n }\n\n oldIdTagNameMap.clear()\n duplicateIds.clear()\n ctxIdMap.clear()\n\n const parent = mode === 'outer' ? oldElt.parentElement! : oldElt\n populateIdMapWithTree(parent, oldIdElements)\n populateIdMapWithTree(normalizedElt, newIdElements)\n\n morphChildren(\n parent,\n normalizedElt,\n mode === 'outer' ? oldElt : null,\n oldElt.nextSibling,\n )\n\n ctxPantry.remove()\n}\n\n// This is the core algorithm for matching up children.\n// The idea is to use ID sets to try to match up nodes as faithfully as possible.\n// We greedily match, which allows us to keep the algorithm fast,\n// but by using ID sets, we are able to better match up with content deeper in the DOM.\nconst morphChildren = (\n oldParent: Element | ShadowRoot, // the old content that we are merging the new content into\n newParent: Element, // the parent element of the new content\n insertionPoint: Node | null = null, // the point in the DOM we start morphing at (defaults to first child)\n endPoint: Node | null = null, // the point in the DOM we stop morphing at (defaults to after last child)\n): void => {\n // normalize\n if (\n oldParent instanceof HTMLTemplateElement &&\n newParent instanceof HTMLTemplateElement\n ) {\n // we can pretend the DocumentElement is an Element\n oldParent = oldParent.content as unknown as Element\n newParent = newParent.content as unknown as Element\n }\n insertionPoint ??= oldParent.firstChild\n\n // run through all the new content\n for (const newChild of newParent.childNodes) {\n // once we reach the end of the old parent content skip to the end and insert the rest\n if (insertionPoint && insertionPoint !== endPoint) {\n const bestMatch = findBestMatch(newChild, insertionPoint, endPoint)\n if (bestMatch) {\n // if the node to morph is not at the insertion point then remove/move up to it\n if (bestMatch !== insertionPoint) {\n let cursor: Node | null = insertionPoint\n // Remove nodes between the start and end nodes\n while (cursor && cursor !== bestMatch) {\n const tempNode = cursor\n cursor = cursor.nextSibling\n removeNode(tempNode)\n }\n }\n morphNode(bestMatch, newChild)\n insertionPoint = bestMatch.nextSibling\n continue\n }\n }\n\n // if the matching node is elsewhere in the original content\n if (newChild instanceof Element && ctxPersistentIds.has(newChild.id)) {\n // move it and all its children here and morph, will always be found\n // Search for an element by ID within the document and pantry, and move it using moveBefore.\n const movedChild = document.getElementById(newChild.id) as Element\n\n // Removes an element from its ancestors' ID maps.\n // This is needed when an element is moved from the \"future\" via `moveBeforeId`.\n // Otherwise, its erstwhile ancestors could be mistakenly moved to the pantry rather than being deleted,\n // preventing their removal hooks from being called.\n let current = movedChild\n while ((current = current.parentNode as Element)) {\n const idSet = ctxIdMap.get(current)\n if (idSet) {\n idSet.delete(newChild.id)\n if (!idSet.size) {\n ctxIdMap.delete(current)\n }\n }\n }\n\n moveBefore(oldParent, movedChild, insertionPoint)\n morphNode(movedChild, newChild)\n insertionPoint = movedChild.nextSibling\n continue\n }\n\n // This performs the action of inserting a new node while handling situations where the node contains\n // elements with persistent IDs and possible state info we can still preserve by moving in and then morphing\n if (ctxIdMap.has(newChild)) {\n // node has children with IDs with possible state so create a dummy elt of same type and apply full morph algorithm\n const newEmptyChild = document.createElement(\n (newChild as Element).tagName,\n )\n oldParent.insertBefore(newEmptyChild, insertionPoint)\n morphNode(newEmptyChild, newChild)\n insertionPoint = newEmptyChild.nextSibling\n } else {\n // optimization: no id state to preserve so we can just insert a clone of the newChild and its descendants\n const newClonedChild = document.importNode(newChild, true) // importNode to not mutate newParent\n oldParent.insertBefore(newClonedChild, insertionPoint)\n insertionPoint = newClonedChild.nextSibling\n }\n }\n\n // remove any remaining old nodes that didn't match up with new content\n while (insertionPoint && insertionPoint !== endPoint) {\n const tempNode = insertionPoint\n insertionPoint = insertionPoint.nextSibling\n removeNode(tempNode)\n }\n}\n\n// Scans forward from the startPoint to the endPoint looking for a match for the node.\n// It looks for an id set match first, then a soft match.\n// We abort soft matching if we find two future soft matches, to reduce churn.\nconst findBestMatch = (\n node: Node,\n startPoint: Node | null,\n endPoint: Node | null,\n): Node | null => {\n let bestMatch: Node | null | undefined = null\n let nextSibling = node.nextSibling\n let siblingSoftMatchCount = 0\n let displaceMatchCount = 0\n\n // Max ID matches we are willing to displace in our search\n const nodeMatchCount = ctxIdMap.get(node)?.size || 0\n\n let cursor = startPoint\n while (cursor && cursor !== endPoint) {\n // soft matching is a prerequisite for id set matching\n if (isSoftMatch(cursor, node)) {\n let isIdSetMatch = false\n const oldSet = ctxIdMap.get(cursor)\n const newSet = ctxIdMap.get(node)\n\n if (newSet && oldSet) {\n for (const id of oldSet) {\n // a potential match is an id in the new and old nodes that\n // has not already been merged into the DOM\n // But the newNode content we call this on has not been\n // merged yet and we don't allow duplicate IDs so it is simple\n if (newSet.has(id)) {\n isIdSetMatch = true\n break\n }\n }\n }\n\n if (isIdSetMatch) {\n return cursor // found an id set match, we're done!\n }\n\n // we haven\u2019t yet saved a soft match fallback\n // the current soft match will hard match something else in the future, leave it\n if (!bestMatch && !ctxIdMap.has(cursor)) {\n // optimization: if node can't id set match, we can just return the soft match immediately\n if (!nodeMatchCount) {\n return cursor\n }\n // save this as the fallback if we get through the loop without finding a hard match\n bestMatch = cursor\n }\n }\n\n // check for IDs we may be displaced when matching\n displaceMatchCount += ctxIdMap.get(cursor)?.size || 0\n if (displaceMatchCount > nodeMatchCount) {\n // if we are going to displace more IDs than the node contains then\n // we do not have a good candidate for an ID match, so return\n break\n }\n\n if (bestMatch === null && nextSibling && isSoftMatch(cursor, nextSibling)) {\n // The next new node has a soft match with this node, so\n // increment the count of future soft matches\n siblingSoftMatchCount++\n nextSibling = nextSibling.nextSibling\n\n // If there are two future soft matches, block soft matching for this node to allow\n // future siblings to soft match. This is to reduce churn in the DOM when an element\n // is prepended.\n if (siblingSoftMatchCount >= 2) {\n bestMatch = undefined\n }\n }\n\n cursor = cursor.nextSibling\n }\n\n return bestMatch || null\n}\n\n// ok to cast: if one is not element, `id` and `tagName` will be null and we'll just compare that.\nconst isSoftMatch = (oldNode: Node, newNode: Node): boolean =>\n oldNode.nodeType === newNode.nodeType &&\n (oldNode as Element).tagName === (newNode as Element).tagName &&\n // If oldElt has an `id` with possible state and it doesn\u2019t match newElt.id then avoid morphing.\n // We'll still match an anonymous node with an IDed newElt, though, because if it got this far,\n // its not persistent, and new nodes can't have any hidden state.\n (!(oldNode as Element).id ||\n (oldNode as Element).id === (newNode as Element).id)\n\n// Gets rid of an unwanted DOM node; strategy depends on nature of its reuse:\n// - Persistent nodes will be moved to the pantry for later reuse\n// - Other nodes will have their hooks called, and then are removed\nconst removeNode = (node: Node): void => {\n // are we going to id set match this later?\n ctxIdMap.has(node)\n ? // skip callbacks and move to pantry\n moveBefore(ctxPantry, node, null)\n : // remove for realsies\n node.parentNode?.removeChild(node)\n}\n\n// Moves an element before another element within the same parent.\n// Uses the proposed `moveBefore` API if available (and working), otherwise falls back to `insertBefore`.\n// This is essentially a forward-compat wrapper.\nconst moveBefore: (parentNode: Node, node: Node, after: Node | null) => void =\n // @ts-expect-error\n removeNode.call.bind(ctxPantry.moveBefore ?? ctxPantry.insertBefore)\n\nconst aliasedPreserveAttr = aliasify('preserve-attr')\n\n// syncs the oldNode to the newNode, copying over all attributes and\n// inner element state from the newNode to the oldNode\nconst morphNode = (\n oldNode: Node, // root node to merge content into\n newNode: Node, // new content to merge\n): Node => {\n const type = newNode.nodeType\n\n // if is an element type, sync the attributes from the\n // new node into the new node\n if (type === 1 /* element type */) {\n const oldElt = oldNode as Element\n const newElt = newNode as Element\n if (\n oldElt.hasAttribute(aliasedIgnoreMorph) &&\n newElt.hasAttribute(aliasedIgnoreMorph)\n ) {\n return oldNode\n }\n\n // many bothans died to bring us this information:\n // https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n // https://github.com/choojs/nanomorph/blob/master/lib/morph.js#L113\n if (\n oldElt instanceof HTMLInputElement &&\n newElt instanceof HTMLInputElement &&\n newElt.type !== 'file'\n ) {\n // https://github.com/bigskysoftware/idiomorph/issues/27\n // | old input value | new input value | behaviour |\n // | --------------- | ---------------- | -------------------------------------- |\n // | `null` | `null` | preserve old input value |\n // | some value | the same value | preserve old input value |\n // | some value | `null` | set old input value to `\"\"` |\n // | `null` | some value | set old input value to new input value |\n // | some value | some other value | set old input value to new input value |\n if (newElt.getAttribute('value') !== oldElt.getAttribute('value')) {\n oldElt.value = newElt.getAttribute('value') ?? ''\n }\n } else if (\n oldElt instanceof HTMLTextAreaElement &&\n newElt instanceof HTMLTextAreaElement\n ) {\n if (newElt.value !== oldElt.value) {\n oldElt.value = newElt.value\n }\n if (oldElt.firstChild && oldElt.firstChild.nodeValue !== newElt.value) {\n oldElt.firstChild.nodeValue = newElt.value\n }\n }\n\n const preserveAttrs = (\n (newNode as HTMLElement).getAttribute(aliasedPreserveAttr) ?? ''\n ).split(' ')\n\n for (const { name, value } of newElt.attributes) {\n if (\n oldElt.getAttribute(name) !== value &&\n !preserveAttrs.includes(name)\n ) {\n oldElt.setAttribute(name, value)\n }\n }\n\n for (let i = oldElt.attributes.length - 1; i >= 0; i--) {\n const { name } = oldElt.attributes[i]!\n if (!newElt.hasAttribute(name) && !preserveAttrs.includes(name)) {\n oldElt.removeAttribute(name)\n }\n }\n\n if (!oldElt.isEqualNode(newElt)) {\n morphChildren(oldElt, newElt)\n }\n }\n\n if (type === 8 /* comment */ || type === 3 /* text */) {\n if (oldNode.nodeValue !== newNode.nodeValue) {\n oldNode.nodeValue = newNode.nodeValue\n }\n }\n\n return oldNode\n}\n\n// A bottom-up algorithm that populates a map of Element -> IdSet.\n// The ID set for a given element is the set of all IDs contained within its subtree.\n// As an optimization, we filter these IDs through the given list of persistent IDs,\n// because we don't need to bother considering IDed elements that won't be in the new content.\nconst populateIdMapWithTree = (\n root: Element | ShadowRoot | null,\n elements: Iterable,\n): void => {\n for (const elt of elements) {\n if (ctxPersistentIds.has(elt.id)) {\n let current: Element | null = elt\n // walk up the parent hierarchy of that element, adding the ID of element to the parent's ID set\n while (current && current !== root) {\n let idSet = ctxIdMap.get(current)\n // if the ID set doesn\u2019t exist, create it and insert it in the map\n if (!idSet) {\n idSet = new Set()\n ctxIdMap.set(current, idSet)\n }\n idSet.add(elt.id)\n current = current.parentElement\n }\n }\n }\n}\n", "// Icon: ion:eye\n// Slug: Access signals without subscribing to changes.\n// Description: Allows accessing signals without subscribing to their changes in expressions.\n\nimport { action } from '@engine'\nimport { startPeeking, stopPeeking } from '@engine/signals'\n\naction({\n name: 'peek',\n apply(_, fn: () => any) {\n startPeeking()\n try {\n return fn()\n } finally {\n stopPeeking()\n }\n },\n})\n", "// Icon: ion:checkmark-round\n// Slug: Sets the value of all matching signals.\n// Description: Sets the value of all matching signals (or all signals if no filter is used) to the expression provided in the first argument.\n\nimport { action } from '@engine'\nimport {\n filtered,\n mergePatch,\n startPeeking,\n stopPeeking,\n} from '@engine/signals'\nimport type { SignalFilterOptions } from '@engine/types'\nimport { updateLeaves } from '@utils/paths'\n\naction({\n name: 'setAll',\n apply(_, value: any, filter: SignalFilterOptions) {\n // peek because in an effect you would be subscribing to signals and then setting them which\n // would cause an infinite loop and why would you want to infinite loop on purpose\n startPeeking()\n const masked = filtered(filter)\n updateLeaves(masked, () => value)\n mergePatch(masked)\n stopPeeking()\n },\n})\n", "// Icon: material-symbols:toggle-off\n// Slug: Toggles the value of all matching signals.\n// Description: Toggles the boolean value of all matching signals (or all signals if no filter is used).\n\nimport { action } from '@engine'\nimport {\n filtered,\n mergePatch,\n startPeeking,\n stopPeeking,\n} from '@engine/signals'\nimport type { SignalFilterOptions } from '@engine/types'\nimport { updateLeaves } from '@utils/paths'\n\naction({\n name: 'toggleAll',\n apply(_, filter: SignalFilterOptions) {\n // peek because in an effect you would be subscribing to signals and then setting them which\n // would cause an infinite loop and why would you want to infinite loop on purpose\n startPeeking()\n const masked = filtered(filter)\n updateLeaves(masked, (oldValue: any) => !oldValue)\n mergePatch(masked)\n stopPeeking()\n },\n})\n", "// Icon: ion:eye\n// Slug: Access signals without subscribing to changes.\n// Description: Allows accessing signals without subscribing to their changes in expressions.\n\nimport { action } from '@engine'\nimport { DATASTAR_FETCH_EVENT } from '@engine/consts'\nimport { filtered } from '@engine/signals'\nimport type {\n DatastarFetchEvent,\n HTMLOrSVG,\n SignalFilterOptions,\n} from '@engine/types'\nimport { kebab } from '@utils/text'\n\nconst fetchAbortControllers = new WeakMap()\n\nconst createHttpMethod = (name: string, method: string): void =>\n action({\n name,\n apply: async (\n { el, evt, error },\n url: string,\n {\n selector,\n headers: userHeaders,\n contentType = 'json',\n filterSignals: { include = /.*/, exclude = /(^|\\.)_/ } = {},\n openWhenHidden = false,\n retryInterval = 1000,\n retryScaler = 2,\n retryMaxWaitMs = 30_000,\n retryMaxCount = 10,\n requestCancellation = 'auto',\n }: FetchArgs = {},\n ) => {\n const controller =\n requestCancellation instanceof AbortController\n ? requestCancellation\n : new AbortController()\n const isDisabled = requestCancellation === 'disabled'\n if (!isDisabled) {\n const oldController = fetchAbortControllers.get(el)\n if (oldController) {\n oldController.abort()\n // wait one tick for FINISHED to fire\n await Promise.resolve()\n }\n }\n\n if (!isDisabled && !(requestCancellation instanceof AbortController)) {\n fetchAbortControllers.set(el, controller)\n }\n\n try {\n const observer = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n for (const removed of mutation.removedNodes) {\n if (removed === el) {\n controller.abort()\n cleanupFn()\n }\n }\n }\n })\n if (el.parentNode) {\n observer.observe(el.parentNode, { childList: true })\n }\n\n let cleanupFn = () => {\n observer.disconnect()\n }\n\n try {\n if (!url?.length) {\n throw error('FetchNoUrlProvided', { action })\n }\n\n const initialHeaders: Record = {\n Accept: 'text/event-stream, text/html, application/json',\n 'Datastar-Request': true,\n }\n if (contentType === 'json') {\n initialHeaders['Content-Type'] = 'application/json'\n }\n const headers = Object.assign({}, initialHeaders, userHeaders)\n\n // We ignore the content-type header if using form data\n // if missing the boundary will be set automatically\n\n const req: FetchEventSourceInit = {\n method,\n headers,\n openWhenHidden,\n retryInterval,\n retryScaler,\n retryMaxWaitMs,\n retryMaxCount,\n signal: controller.signal,\n onopen: async (response: Response) => {\n if (response.status >= 400)\n dispatchFetch(ERROR, el, { status: response.status.toString() })\n },\n onmessage: (evt) => {\n if (!evt.event.startsWith('datastar')) return\n const type = evt.event\n const argsRawLines: Record = {}\n\n for (const line of evt.data.split('\\n')) {\n const i = line.indexOf(' ')\n const k = line.slice(0, i)\n const v = line.slice(i + 1)\n ;(argsRawLines[k] ||= []).push(v)\n }\n\n const argsRaw = Object.fromEntries(\n Object.entries(argsRawLines).map(([k, v]) => [k, v.join('\\n')]),\n )\n\n dispatchFetch(type, el, argsRaw)\n },\n onerror: (error) => {\n if (isWrongContent(error)) {\n // don't retry if the content-type is wrong\n throw error('FetchExpectedTextEventStream', { url })\n }\n // do nothing and it will retry\n if (error) {\n console.error(error.message)\n dispatchFetch(RETRYING, el, { message: error.message })\n }\n },\n }\n\n const urlInstance = new URL(url, document.baseURI)\n const queryParams = new URLSearchParams(urlInstance.search)\n\n if (contentType === 'json') {\n const res = JSON.stringify(filtered({ include, exclude }))\n if (method === 'GET') {\n queryParams.set('datastar', res)\n } else {\n req.body = res\n }\n } else if (contentType === 'form') {\n const formEl = (\n selector ? document.querySelector(selector) : el.closest('form')\n ) as HTMLFormElement\n if (!formEl) {\n throw error('FetchFormNotFound', { action, selector })\n }\n\n // Validate the form\n if (!formEl.checkValidity()) {\n formEl.reportValidity()\n cleanupFn()\n return\n }\n\n // Collect the form data\n\n const formData = new FormData(formEl)\n let submitter = el as HTMLElement | null\n\n if (el === formEl && evt instanceof SubmitEvent) {\n // Get the submitter from the event\n submitter = evt.submitter\n } else {\n // Prevent the form being submitted\n const preventDefault = (evt: Event) => evt.preventDefault()\n formEl.addEventListener('submit', preventDefault)\n cleanupFn = () => {\n formEl.removeEventListener('submit', preventDefault)\n observer.disconnect()\n }\n }\n\n // Append the value of the form submitter if it is a button with a name\n if (submitter instanceof HTMLButtonElement) {\n const name = submitter.getAttribute('name')\n if (name) formData.append(name, submitter.value)\n }\n\n const multipart =\n formEl.getAttribute('enctype') === 'multipart/form-data'\n // Leave the `Content-Type` header empty for multipart encoding so the browser can set it automatically with the correct boundary\n if (!multipart) {\n headers['Content-Type'] = 'application/x-www-form-urlencoded'\n }\n\n const formParams = new URLSearchParams(formData as any)\n if (method === 'GET') {\n for (const [key, value] of formParams) {\n queryParams.append(key, value)\n }\n } else if (multipart) {\n req.body = formData\n } else {\n req.body = formParams\n }\n } else {\n throw error('FetchInvalidContentType', { action, contentType })\n }\n\n dispatchFetch(STARTED, el, {})\n urlInstance.search = queryParams.toString()\n\n try {\n await fetchEventSource(urlInstance.toString(), el, req)\n } catch (e: any) {\n if (!isWrongContent(e)) {\n throw error('FetchFailed', { method, url, error: e.message })\n }\n // exit gracefully and do nothing if the content-type is wrong\n // this can happen if the client is sending a request\n // where no response is expected, and they haven\u2019t\n // set the content-type to text/event-stream\n }\n } finally {\n dispatchFetch(FINISHED, el, {})\n cleanupFn()\n }\n } finally {\n if (fetchAbortControllers.get(el) === controller) {\n fetchAbortControllers.delete(el)\n }\n }\n },\n })\n\ncreateHttpMethod('delete', 'DELETE')\ncreateHttpMethod('get', 'GET')\ncreateHttpMethod('patch', 'PATCH')\ncreateHttpMethod('post', 'POST')\ncreateHttpMethod('put', 'PUT')\n\nexport const STARTED = 'started'\nexport const FINISHED = 'finished'\nexport const ERROR = 'error'\nexport const RETRYING = 'retrying'\nexport const RETRIES_FAILED = 'retries-failed'\n\nconst dispatchFetch = (\n type: string,\n el: HTMLOrSVG,\n argsRaw: Record,\n) =>\n document.dispatchEvent(\n new CustomEvent(DATASTAR_FETCH_EVENT, {\n detail: { type, el, argsRaw },\n }),\n )\n\nconst isWrongContent = (err: any) => `${err}`.includes('text/event-stream')\n\ntype ResponseOverrides =\n | {\n selector?: string\n mode?: string\n useViewTransition?: boolean\n }\n | {\n onlyIfMissing?: boolean\n }\n\nexport type FetchArgs = {\n headers?: Record\n openWhenHidden?: boolean\n retryInterval?: number\n retryScaler?: number\n retryMaxWaitMs?: number\n retryMaxCount?: number\n responseOverrides?: ResponseOverrides\n contentType?: 'json' | 'form'\n filterSignals?: SignalFilterOptions\n selector?: string\n requestCancellation?: 'auto' | 'disabled' | AbortController\n}\n\n// Below originally from https://github.com/Azure/fetch-event-source/blob/main/LICENSE\n\n/**\n * Represents a message sent in an event stream\n * https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format\n */\n\ninterface EventSourceMessage {\n id: string\n event: string\n data: string\n retry?: number\n}\n\n/**\n * Converts a ReadableStream into a callback pattern.\n * @param stream The input ReadableStream.\n * @param onChunk A function that will be called on each new byte chunk in the stream.\n * @returns {Promise} A promise that will be resolved when the stream closes.\n */\nconst getBytes = async (\n stream: ReadableStream,\n onChunk: (arr: Uint8Array) => void,\n): Promise => {\n const reader = stream.getReader()\n let result = await reader.read()\n while (!result.done) {\n onChunk(result.value)\n result = await reader.read()\n }\n}\n\nconst getLines = (onLine: (line: Uint8Array, fieldLength: number) => void) => {\n let buffer: Uint8Array | undefined\n let position: number // current read position\n let fieldLength: number // length of the `field` portion of the line\n let discardTrailingNewline = false\n\n // return a function that can process each incoming byte chunk:\n return (arr: Uint8Array) => {\n if (!buffer) {\n buffer = arr\n position = 0\n fieldLength = -1\n } else {\n // we're still parsing the old line. Append the new bytes into buffer:\n buffer = concat(buffer, arr)\n }\n\n const bufLength = buffer.length\n let lineStart = 0 // index where the current line starts\n while (position < bufLength) {\n if (discardTrailingNewline) {\n if (buffer[position] === 10) lineStart = ++position // skip to next char\n discardTrailingNewline = false\n }\n\n // start looking forward till the end of line:\n let lineEnd = -1 // index of the \\r or \\n char\n for (; position < bufLength && lineEnd === -1; ++position) {\n switch (buffer[position]) {\n case 58: // :\n if (fieldLength === -1) {\n // first colon in line\n fieldLength = position - lineStart\n }\n break\n // @ts-expect-error:7029 \\r case below should fallthrough to \\n:\n // biome-ignore lint/suspicious/noFallthroughSwitchClause: intentional fallthrough for CR to LF\n case 13: // \\r\n discardTrailingNewline = true\n case 10: // \\n\n lineEnd = position\n break\n }\n }\n\n if (lineEnd === -1) break // Wait for the next arr and then continue parsing\n\n // we've reached the line end, send it out:\n onLine(buffer.subarray(lineStart, lineEnd), fieldLength)\n lineStart = position // we're now on the next line\n fieldLength = -1\n }\n\n if (lineStart === bufLength)\n buffer = undefined // we've finished reading it\n else if (lineStart) {\n // Create a new view into buffer beginning at lineStart so we don't\n // need to copy over the previous lines when we get the new arr:\n buffer = buffer.subarray(lineStart)\n position -= lineStart\n }\n }\n}\n\nconst getMessages = (\n onId: (id: string) => void,\n onRetry: (retry: number) => void,\n onMessage?: (msg: EventSourceMessage) => void,\n): ((line: Uint8Array, fieldLength: number) => void) => {\n let message = newMessage()\n const decoder = new TextDecoder()\n\n // return a function that can process each incoming line buffer:\n return (line, fieldLength) => {\n if (!line.length) {\n // empty line denotes end of message. Trigger the callback and start a new message:\n onMessage?.(message)\n message = newMessage()\n } else if (fieldLength > 0) {\n // exclude comments and lines with no values\n // line is of format \":\" or \": \"\n // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation\n const field = decoder.decode(line.subarray(0, fieldLength))\n const valueOffset = fieldLength + (line[fieldLength + 1] === 32 ? 2 : 1)\n const value = decoder.decode(line.subarray(valueOffset))\n\n switch (field) {\n case 'data':\n message.data = message.data ? `${message.data}\\n${value}` : value\n break\n case 'event':\n message.event = value\n break\n case 'id':\n onId((message.id = value))\n break\n case 'retry': {\n const retry = +value\n if (!Number.isNaN(retry)) {\n // per spec, ignore non-integers\n onRetry((message.retry = retry))\n }\n break\n }\n }\n }\n }\n}\n\nconst concat = (a: Uint8Array, b: Uint8Array) => {\n const res = new Uint8Array(a.length + b.length)\n res.set(a)\n res.set(b, a.length)\n return res\n}\n\nconst newMessage = (): EventSourceMessage => ({\n // data, event, and id must be initialized to empty strings:\n // https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation\n // retry should be initialized to undefined so we return a consistent shape\n // to the js engine all the time: https://mathiasbynens.be/notes/shapes-ics#takeaways\n data: '',\n event: '',\n id: '',\n retry: undefined,\n})\n\ntype FetchEventSourceInit = RequestInit & {\n headers?: Record\n onopen?: (response: Response) => Promise\n onmessage?: (ev: EventSourceMessage) => void\n onclose?: () => void\n onerror?: (err: any) => number | null | undefined | void\n openWhenHidden?: boolean\n fetch?: typeof fetch\n retryInterval?: number\n retryScaler?: number\n retryMaxWaitMs?: number\n retryMaxCount?: number\n overrides?: ResponseOverrides\n}\n\nconst fetchEventSource = (\n input: RequestInfo,\n el: HTMLOrSVG,\n {\n signal: inputSignal,\n headers: inputHeaders,\n onopen: inputOnOpen,\n onmessage,\n onclose,\n onerror,\n openWhenHidden,\n fetch: inputFetch,\n retryInterval = 1_000,\n retryScaler = 2,\n retryMaxWaitMs = 30_000,\n retryMaxCount = 10,\n overrides,\n ...rest\n }: FetchEventSourceInit,\n): Promise => {\n return new Promise((resolve, reject) => {\n // make a copy of the input headers since we may modify it below:\n const headers: Record = {\n ...inputHeaders,\n }\n\n let curRequestController: AbortController\n const onVisibilityChange = () => {\n curRequestController.abort() // close existing request on every visibility change\n if (!document.hidden) create() // page is now visible again, recreate request.\n }\n\n if (!openWhenHidden) {\n document.addEventListener('visibilitychange', onVisibilityChange)\n }\n\n let retryTimer = 0\n const dispose = () => {\n document.removeEventListener('visibilitychange', onVisibilityChange)\n clearTimeout(retryTimer)\n curRequestController.abort()\n }\n\n // if the incoming signal aborts, dispose resources and resolve:\n inputSignal?.addEventListener('abort', () => {\n dispose()\n resolve() // don't waste time constructing/logging errors\n })\n\n const fetch = inputFetch || window.fetch\n const onopen = inputOnOpen || (() => {})\n\n let retries = 0\n let baseRetryInterval = retryInterval\n const create = async () => {\n curRequestController = new AbortController()\n try {\n const response = await fetch(input, {\n ...rest,\n headers,\n signal: curRequestController.signal,\n })\n\n // on successful connection, reset the retry logic\n retries = 0\n retryInterval = baseRetryInterval\n\n await onopen(response)\n\n const dispatchNonSSE = async (\n dispatchType: string,\n response: Response,\n name: string,\n overrides?: ResponseOverrides,\n ...argNames: string[]\n ) => {\n const argsRaw: Record = {\n [name]: await response.text(),\n }\n for (const n of argNames) {\n let v = response.headers.get(`datastar-${kebab(n)}`)\n if (overrides) {\n const o = (overrides as any)[n]\n if (o) v = typeof o === 'string' ? o : JSON.stringify(o)\n }\n if (v) argsRaw[n] = v\n }\n\n dispatchFetch(dispatchType, el, argsRaw)\n dispose()\n resolve()\n }\n\n const ct = response.headers.get('Content-Type')\n if (ct?.includes('text/html')) {\n return await dispatchNonSSE(\n 'datastar-patch-elements',\n response,\n 'elements',\n overrides,\n 'selector',\n 'mode',\n 'useViewTransition',\n )\n }\n\n if (ct?.includes('application/json')) {\n return await dispatchNonSSE(\n 'datastar-patch-signals',\n response,\n 'signals',\n overrides,\n 'onlyIfMissing',\n )\n }\n\n if (ct?.includes('text/javascript')) {\n const script = document.createElement('script')\n const scriptAttributesHeader = response.headers.get(\n 'datastar-script-attributes',\n )\n\n if (scriptAttributesHeader) {\n for (const [name, value] of Object.entries(\n JSON.parse(scriptAttributesHeader),\n )) {\n script.setAttribute(name, value as string)\n }\n }\n script.textContent = await response.text()\n document.head.appendChild(script)\n dispose()\n return\n }\n\n await getBytes(\n response.body!,\n getLines(\n getMessages(\n (id) => {\n if (id) {\n // signals the id and send it back on the next retry:\n headers['last-event-id'] = id\n } else {\n // don't send the last-event-id header anymore:\n delete headers['last-event-id']\n }\n },\n (retry) => {\n baseRetryInterval = retryInterval = retry\n },\n onmessage,\n ),\n ),\n )\n\n onclose?.()\n dispose()\n resolve()\n } catch (err) {\n if (!curRequestController.signal.aborted) {\n // if we haven\u2019t aborted the request ourselves:\n try {\n // check if we need to retry:\n const interval: any = onerror?.(err) || retryInterval\n clearTimeout(retryTimer)\n retryTimer = setTimeout(create, interval)\n retryInterval = Math.min(\n retryInterval * retryScaler,\n retryMaxWaitMs,\n ) // exponential backoff\n if (++retries >= retryMaxCount) {\n dispatchFetch(RETRIES_FAILED, el, {})\n // we should not retry anymore:\n dispose()\n reject('Max retries reached.') // Max retries reached, check your server or network connection\n } else {\n console.error(\n `Datastar failed to reach ${input.toString()} retrying in ${interval}ms.`,\n )\n }\n } catch (innerErr) {\n // we should not retry anymore:\n dispose()\n reject(innerErr)\n }\n }\n }\n }\n\n create()\n })\n}\n", "// Icon: material-symbols:edit-attributes-outline\n// Slug: Syncs the value of an attribute with an expression.\n// Description: Sets the value of any HTML attribute to an expression, and keeps it in sync.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nattribute({\n name: 'attr',\n requirement: { value: 'must' },\n returnsValue: true,\n apply({ el, key, rx }) {\n const syncAttr = (key: string, val: any) => {\n if (val === '' || val === true) {\n el.setAttribute(key, '')\n } else if (val === false || val == null) {\n el.removeAttribute(key)\n } else if (typeof val === 'string') {\n el.setAttribute(key, val)\n } else {\n el.setAttribute(key, JSON.stringify(val))\n }\n }\n\n const update = key\n ? () => {\n observer.disconnect()\n const val = rx() as string\n syncAttr(key, val)\n observer.observe(el, {\n attributeFilter: [key],\n })\n }\n : () => {\n observer.disconnect()\n const obj = rx() as Record\n const attributeFilter = Object.keys(obj)\n for (const key of attributeFilter) {\n syncAttr(key, obj[key])\n }\n observer.observe(el, {\n attributeFilter,\n })\n }\n\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "// Icon: akar-icons:link-chain\n// Slug: Creates a signal with two-way data binding.\n// Description: Creates a signal (if one doesn\u2019t already exist) and sets up two-way data binding between it and an element\u2019s value.\n\nimport { attribute } from '@engine'\nimport { effect, getPath, mergePaths } from '@engine/signals'\nimport type { Paths } from '@engine/types'\nimport { aliasify, modifyCasing } from '@utils/text'\n\ntype SignalFile = {\n name: string\n contents: string\n mime: string\n}\n\nconst dataURIRegex = /^data:(?[^;]+);base64,(?.*)$/\nconst empty = Symbol('empty')\n\nconst aliasedBind = aliasify('bind')\n\nattribute({\n name: 'bind',\n requirement: 'exclusive',\n apply({ el, key, mods, value, error }) {\n const signalName = key != null ? modifyCasing(key, mods) : value\n\n let get = (el: any, type: string) =>\n type === 'number' ? +el.value : el.value\n\n let set = (value: any) => {\n ;(el as HTMLInputElement).value = `${value}`\n }\n\n if (el instanceof HTMLInputElement) {\n switch (el.type) {\n case 'range':\n case 'number':\n get = (el: any, type: string) =>\n type === 'string' ? el.value : +el.value\n break\n\n case 'checkbox':\n get = (el: HTMLInputElement, type: string) => {\n if (el.value !== 'on') {\n if (type === 'boolean') {\n return el.checked\n } else {\n return el.checked ? el.value : ''\n }\n } else {\n if (type === 'string') {\n return el.checked ? el.value : ''\n } else {\n return el.checked\n }\n }\n }\n set = (value: string | boolean) => {\n el.checked = typeof value === 'string' ? value === el.value : value\n }\n break\n\n case 'radio':\n // Set up radio button name attribute if not present\n if (!el.getAttribute('name')?.length) {\n el.setAttribute('name', signalName)\n }\n\n get = (el: HTMLInputElement, type: string) =>\n el.checked ? (type === 'number' ? +el.value : el.value) : empty\n set = (value: string | number) => {\n el.checked =\n value === (typeof value === 'number' ? +el.value : el.value)\n }\n break\n case 'file': {\n const syncSignal = () => {\n const files = [...(el.files || [])]\n const signalFiles: SignalFile[] = []\n Promise.all(\n files.map(\n (f) =>\n new Promise((resolve) => {\n const reader = new FileReader()\n reader.onload = () => {\n if (typeof reader.result !== 'string') {\n throw error('InvalidFileResultType', {\n resultType: typeof reader.result,\n })\n }\n const match = reader.result.match(dataURIRegex)\n if (!match?.groups) {\n throw error('InvalidDataUri', {\n result: reader.result,\n })\n }\n signalFiles.push({\n name: f.name,\n contents: match.groups.contents,\n mime: match.groups.mime,\n })\n }\n reader.onloadend = () => resolve()\n reader.readAsDataURL(f)\n }),\n ),\n ).then(() => {\n mergePaths([[signalName, signalFiles]])\n })\n }\n\n el.addEventListener('change', syncSignal)\n el.addEventListener('input', syncSignal)\n\n return () => {\n el.removeEventListener('change', syncSignal)\n el.removeEventListener('input', syncSignal)\n }\n }\n }\n } else if (el instanceof HTMLSelectElement) {\n if (el.multiple) {\n const typeMap = new Map()\n get = (el: HTMLSelectElement) =>\n [...el.selectedOptions].map((option) => {\n const type = typeMap.get(option.value)\n return type === 'string' || type == null\n ? option.value\n : +option.value\n })\n\n set = (value: (string | number)[]) => {\n for (const option of el.options) {\n if (value.includes(option.value)) {\n typeMap.set(option.value, 'string')\n option.selected = true\n } else if (value.includes(+option.value)) {\n typeMap.set(option.value, 'number')\n option.selected = true\n } else {\n option.selected = false\n }\n }\n }\n }\n } else if (el instanceof HTMLTextAreaElement) {\n // default case\n } else {\n // web component\n get = (el: Element) =>\n 'value' in el ? el.value : el.getAttribute('value')\n set = (value: any) => {\n if ('value' in el) {\n el.value = value\n } else {\n el.setAttribute('value', value)\n }\n }\n }\n\n const initialValue = getPath(signalName)\n const type = typeof initialValue\n\n let path = signalName\n if (\n Array.isArray(initialValue) &&\n !(el instanceof HTMLSelectElement && el.multiple)\n ) {\n const signalNameKebab = key ? key : value!\n const inputs = document.querySelectorAll(\n `[${aliasedBind}\\\\:${CSS.escape(signalNameKebab)}],[${aliasedBind}=\"${CSS.escape(signalNameKebab)}\"]`,\n ) as NodeListOf\n\n const paths: Paths = []\n let i = 0\n for (const input of inputs) {\n paths.push([`${path}.${i}`, get(input, 'none')])\n\n if (el === input) {\n break\n }\n i++\n }\n mergePaths(paths, { ifMissing: true })\n path = `${path}.${i}`\n } else {\n mergePaths([[path, get(el, type)]], {\n ifMissing: true,\n })\n }\n\n const syncSignal = () => {\n const signalValue = getPath(path)\n if (signalValue != null) {\n const value = get(el, typeof signalValue)\n if (value !== empty) {\n mergePaths([[path, value]])\n }\n }\n }\n\n el.addEventListener('input', syncSignal)\n el.addEventListener('change', syncSignal)\n const cleanup = effect(() => {\n set(getPath(path))\n })\n\n return () => {\n cleanup()\n el.removeEventListener('input', syncSignal)\n el.removeEventListener('change', syncSignal)\n }\n },\n})\n", "// Icon: ic:baseline-format-paint\n// Slug: Adds or removes a class based on an expression.\n// Description: Adds or removes a class to or from an element based on an expression.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'class',\n requirement: {\n value: 'must',\n },\n returnsValue: true,\n apply({ key, el, mods, rx }) {\n if (key) {\n key = modifyCasing(key, mods, 'kebab')\n }\n\n const callback = () => {\n observer.disconnect()\n\n const classes = key\n ? { [key]: rx() as boolean }\n : (rx() as Record)\n\n for (const k in classes) {\n const classNames = k.split(/\\s+/).filter((cn) => cn.length > 0)\n if (classes[k]) {\n for (const name of classNames) {\n if (!el.classList.contains(name)) {\n el.classList.add(name)\n }\n }\n } else {\n for (const name of classNames) {\n if (el.classList.contains(name)) {\n el.classList.remove(name)\n }\n }\n }\n }\n\n observer.observe(el, { attributeFilter: ['class'] })\n }\n\n const observer = new MutationObserver(callback)\n const cleanup = effect(callback)\n\n return () => {\n observer.disconnect()\n cleanup()\n\n const classes = key\n ? { [key]: rx() as boolean }\n : (rx() as Record)\n\n for (const k in classes) {\n const classNames = k.split(/\\s+/).filter((cn) => cn.length > 0)\n for (const name of classNames) {\n el.classList.remove(name)\n }\n }\n }\n },\n})\n", "// Icon: streamline-ultimate:wifi-signal-2\n// Slug: Creates a computed signal.\n// Description: Creates a signal that is computed based on an expression.\n\nimport { attribute } from '@engine'\nimport { computed, mergePaths, mergePatch } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\nimport { updateLeaves } from '@utils/paths'\n\nattribute({\n name: 'computed',\n requirement: {\n value: 'must',\n },\n returnsValue: true,\n apply({ key, mods, rx, error }) {\n if (key) {\n mergePaths([[modifyCasing(key, mods), computed(rx)]])\n } else {\n const patch = Object.assign({}, rx() as Record any>)\n updateLeaves(patch, (old) => {\n if (typeof old === 'function') {\n return computed(old)\n } else {\n throw error('ComputedExpectedFunction')\n }\n })\n mergePatch(patch)\n }\n },\n})\n", "// Icon: oui:security-signal\n// Slug: Executes an expression when signals change.\n// Description: Executes an expression on page load and whenever any signals in the expression change.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nattribute({\n name: 'effect',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply: ({ rx }) => effect(rx),\n})\n", "// Icon: streamline:signal-loading-remix\n// Slug: Creates an indicator for whether an SSE request is in flight.\n// Description: Creates a signal and sets its value to `true` while an SSE request request is in flight, otherwise `false`.\n\nimport { attribute } from '@engine'\nimport { DATASTAR_FETCH_EVENT } from '@engine/consts'\nimport { mergePaths } from '@engine/signals'\nimport type { DatastarFetchEvent } from '@engine/types'\nimport { FINISHED, STARTED } from '@plugins/actions/fetch'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'indicator',\n requirement: 'exclusive',\n apply({ el, key, mods, value }) {\n const signalName = key != null ? modifyCasing(key, mods) : value\n\n mergePaths([[signalName, false]])\n\n const watcher = ((event: CustomEvent) => {\n const { type, el: elt } = event.detail\n if (elt !== el) {\n return\n }\n switch (type) {\n case STARTED:\n mergePaths([[signalName, true]])\n break\n case FINISHED:\n mergePaths([[signalName, false]])\n break\n }\n }) as EventListener\n document.addEventListener(DATASTAR_FETCH_EVENT, watcher)\n return () => {\n mergePaths([[signalName, false]])\n document.removeEventListener(DATASTAR_FETCH_EVENT, watcher)\n }\n },\n})\n", "// Icon: si:json-fill\n// Slug: Outputs a JSON stringified version of signals.\n// Description: Sets the text content of an element to a reactive JSON stringified version of signals.\n\nimport { attribute } from '@engine'\nimport { effect, filtered } from '@engine/signals'\nimport type { SignalFilterOptions } from '@engine/types'\nimport { jsStrToObject } from '@utils/text'\n\nattribute({\n name: 'json-signals',\n requirement: {\n key: 'denied',\n },\n apply({ el, value, mods }) {\n const spaces = mods.has('terse') ? 0 : 2\n let filters: SignalFilterOptions = {}\n if (value) {\n filters = jsStrToObject(value)\n }\n\n const callback = () => {\n observer.disconnect()\n el.textContent = JSON.stringify(filtered(filters), null, spaces)\n observer.observe(el, {\n childList: true,\n characterData: true,\n subtree: true,\n })\n }\n const observer = new MutationObserver(callback)\n const cleanup = effect(callback)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "export const tagToMs = (args: Set) => {\n if (!args || args.size <= 0) return 0\n for (const arg of args) {\n if (arg.endsWith('ms')) {\n return +arg.replace('ms', '')\n }\n if (arg.endsWith('s')) {\n return +arg.replace('s', '') * 1000\n }\n try {\n return Number.parseFloat(arg)\n } catch (_) {}\n }\n return 0\n}\n\nexport const tagHas = (\n tags: Set,\n tag: string,\n defaultValue = false,\n) => {\n if (!tags) return defaultValue\n return tags.has(tag.toLowerCase())\n}\n\nexport const tagFirst = (tags?: Set, defaultValue = ''): string => {\n if (tags && tags.size > 0) {\n for (const tag of tags) {\n return tag\n }\n }\n return defaultValue\n}\n", "import type { EventCallbackHandler, Modifiers } from '@engine/types'\nimport { tagHas, tagToMs } from '@utils/tags'\n\nexport const delay = (\n callback: EventCallbackHandler,\n wait: number,\n): EventCallbackHandler => {\n return (...args: any[]) => {\n setTimeout(() => {\n callback(...args)\n }, wait)\n }\n}\n\nexport const debounce = (\n callback: EventCallbackHandler,\n wait: number,\n leading = false,\n trailing = true,\n): EventCallbackHandler => {\n let timer = 0\n return (...args: any[]) => {\n timer && clearTimeout(timer)\n\n if (leading && !timer) {\n callback(...args)\n }\n\n timer = setTimeout(() => {\n if (trailing) {\n callback(...args)\n }\n timer && clearTimeout(timer)\n timer = 0\n }, wait)\n }\n}\n\nexport const throttle = (\n callback: EventCallbackHandler,\n wait: number,\n leading = true,\n trailing = false,\n): EventCallbackHandler => {\n let waiting = false\n\n return (...args: any[]) => {\n if (waiting) return\n\n if (leading) {\n callback(...args)\n }\n\n waiting = true\n setTimeout(() => {\n if (trailing) {\n callback(...args)\n }\n waiting = false\n }, wait)\n }\n}\n\nexport const modifyTiming = (\n callback: EventCallbackHandler,\n mods: Modifiers,\n): EventCallbackHandler => {\n const delayArgs = mods.get('delay')\n if (delayArgs) {\n const wait = tagToMs(delayArgs)\n callback = delay(callback, wait)\n }\n\n const debounceArgs = mods.get('debounce')\n if (debounceArgs) {\n const wait = tagToMs(debounceArgs)\n const leading = tagHas(debounceArgs, 'leading', false)\n const trailing = !tagHas(debounceArgs, 'notrailing', false)\n callback = debounce(callback, wait, leading, trailing)\n }\n\n const throttleArgs = mods.get('throttle')\n if (throttleArgs) {\n const wait = tagToMs(throttleArgs)\n const leading = !tagHas(throttleArgs, 'noleading', false)\n const trailing = tagHas(throttleArgs, 'trailing', false)\n callback = throttle(callback, wait, leading, trailing)\n }\n\n return callback\n}\n", "import type { EventCallbackHandler, Modifiers } from '@engine/types'\n\nexport const supportsViewTransitions = !!document.startViewTransition\n\nexport const modifyViewTransition = (\n callback: EventCallbackHandler,\n mods: Modifiers,\n): EventCallbackHandler => {\n if (mods.has('viewtransition') && supportsViewTransitions) {\n const cb = callback // I hate javascript\n callback = (...args: any[]) =>\n document.startViewTransition(() => cb(...args))\n }\n\n return callback\n}\n", "// Icon: material-symbols:mail\n// Slug: Attaches an event listener to an element.\n// Description: Attaches an event listener to an element, executing an expression whenever the event is triggered.\n\nimport { attribute } from '@engine'\nimport {\n DATASTAR_FETCH_EVENT,\n DATASTAR_SIGNAL_PATCH_EVENT,\n} from '@engine/consts'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\nimport { modifyTiming } from '@utils/timing'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nattribute({\n name: 'on',\n requirement: 'must',\n argNames: ['evt'],\n apply({ el, key, mods, rx }) {\n let target: Element | Window | Document = el\n if (mods.has('window')) target = window\n let callback = (evt?: Event) => {\n if (evt) {\n if (mods.has('prevent')) {\n evt.preventDefault()\n }\n if (mods.has('stop')) {\n evt.stopPropagation()\n }\n }\n beginBatch()\n rx(evt)\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n callback = modifyTiming(callback, mods)\n const evtListOpts: AddEventListenerOptions = {\n capture: mods.has('capture'),\n passive: mods.has('passive'),\n once: mods.has('once'),\n }\n if (mods.has('outside')) {\n target = document\n const cb = callback\n callback = (evt?: Event) => {\n if (!el.contains(evt?.target as HTMLElement)) {\n cb(evt)\n }\n }\n }\n const eventName = modifyCasing(key, mods, 'kebab')\n // Listen for Datastar events on the document\n if (\n eventName === DATASTAR_FETCH_EVENT ||\n eventName === DATASTAR_SIGNAL_PATCH_EVENT\n ) {\n target = document\n }\n // Prevent default on form submit events\n if (el instanceof HTMLFormElement && eventName === 'submit') {\n const cb = callback\n callback = (evt?: Event) => {\n evt?.preventDefault()\n cb(evt)\n }\n }\n target.addEventListener(eventName, callback, evtListOpts)\n return () => {\n target.removeEventListener(eventName, callback)\n }\n },\n})\n", "// Icon: mdi-light:vector-intersection\n// Slug: Runs an expression on intersection.\n// Description: Runs an expression when the element intersects with the viewport.\n\nimport { attribute } from '@engine'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport type { HTMLOrSVG } from '@engine/types'\nimport { modifyTiming } from '@utils/timing'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nconst once = new WeakSet()\n\nattribute({\n name: 'on-intersect',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply({ el, mods, rx }) {\n let callback = () => {\n beginBatch()\n rx()\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n callback = modifyTiming(callback, mods)\n const options = { threshold: 0 }\n if (mods.has('full')) {\n options.threshold = 1\n } else if (mods.has('half')) {\n options.threshold = 0.5\n }\n let observer: IntersectionObserver | null = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n callback()\n if (observer && once.has(el)) {\n observer.disconnect()\n }\n }\n }\n },\n options,\n )\n observer.observe(el)\n if (mods.has('once')) {\n once.add(el)\n }\n return () => {\n if (!mods.has('once')) {\n once.delete(el)\n }\n if (observer) {\n observer.disconnect()\n observer = null\n }\n }\n },\n})\n", "// Icon: material-symbols:timer-outline\n// Slug: Runs an expression at a regular interval.\n// Description: Runs an expression at a regular interval.\n\nimport { attribute } from '@engine'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport { tagHas, tagToMs } from '@utils/tags'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nattribute({\n name: 'on-interval',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply({ mods, rx }) {\n let callback = () => {\n beginBatch()\n rx()\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n let duration = 1000\n const durationArgs = mods.get('duration')\n if (durationArgs) {\n duration = tagToMs(durationArgs)\n const leading = tagHas(durationArgs, 'leading', false)\n if (leading) {\n callback()\n }\n }\n const intervalId = setInterval(callback, duration)\n return () => {\n clearInterval(intervalId)\n }\n },\n})\n", "// Icon: material-symbols:timer-play-outline\n// Slug: Runs an expression when loaded into the DOM.\n// Description: Runs an expression when the element is loaded into the DOM.\n\nimport { attribute } from '@engine'\nimport { beginBatch, endBatch } from '@engine/signals'\nimport { tagToMs } from '@utils/tags'\nimport { delay } from '@utils/timing'\nimport { modifyViewTransition } from '@utils/view-transitions'\n\nattribute({\n name: 'init',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n apply({ rx, mods }) {\n let callback = () => {\n beginBatch()\n rx()\n endBatch()\n }\n callback = modifyViewTransition(callback, mods)\n let wait = 0\n const delayArgs = mods.get('delay')\n if (delayArgs) {\n wait = tagToMs(delayArgs)\n if (wait > 0) {\n callback = delay(callback, wait)\n }\n }\n callback()\n },\n})\n", "// Icon: material-symbols:change-circle-outline\n// Slug: Runs an expression when signals are patched.\n// Description: Runs an expression whenever one or more signals are patched.\n\nimport { attribute } from '@engine'\nimport { DATASTAR_SIGNAL_PATCH_EVENT } from '@engine/consts'\nimport { beginBatch, endBatch, filtered } from '@engine/signals'\nimport type { JSONPatch, SignalFilterOptions } from '@engine/types'\nimport { isEmpty } from '@utils/paths'\nimport { jsStrToObject } from '@utils/text'\nimport { modifyTiming } from '@utils/timing'\n\nattribute({\n name: 'on-signal-patch',\n requirement: {\n value: 'must',\n },\n argNames: ['patch'],\n returnsValue: true,\n apply({ el, key, mods, rx, error }) {\n if (!!key && key !== 'filter') {\n throw error('KeyNotAllowed')\n }\n\n // Look for data-on-signal-patch-filter data attribute\n const filtersRaw = el.getAttribute('data-on-signal-patch-filter')\n let filters: SignalFilterOptions = {}\n if (filtersRaw) {\n filters = jsStrToObject(filtersRaw)\n }\n\n const callback: EventListener = modifyTiming(\n (evt: CustomEvent) => {\n const watched = filtered(filters, evt.detail)\n if (!isEmpty(watched)) {\n beginBatch()\n rx(watched)\n endBatch()\n }\n },\n mods,\n )\n\n document.addEventListener(DATASTAR_SIGNAL_PATCH_EVENT, callback)\n return () => {\n document.removeEventListener(DATASTAR_SIGNAL_PATCH_EVENT, callback)\n }\n },\n})\n", "// Icon: mdi:cursor-pointer\n// Slug: Creates a reference to an element.\n// Description: Creates a new signal that is a reference to the element on which the data attribute is placed.\n\nimport { attribute } from '@engine'\nimport { mergePaths } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'ref',\n requirement: 'exclusive',\n apply({ el, key, mods, value }) {\n const signalName = key != null ? modifyCasing(key, mods) : value\n mergePaths([[signalName, el]])\n },\n})\n", "// Icon: streamline:interface-edit-view-eye-eyeball-open-view\n// Slug: Shows or hides an element.\n// Description: Shows or hides an element based on whether an expression evaluates to `true` or `false`.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nconst NONE = 'none'\nconst DISPLAY = 'display'\n\nattribute({\n name: 'show',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n returnsValue: true,\n apply({ el, rx }) {\n const update = () => {\n observer.disconnect()\n const shouldShow = rx()\n if (shouldShow) {\n if (el.style.display === NONE) el.style.removeProperty(DISPLAY)\n } else {\n el.style.setProperty(DISPLAY, NONE)\n }\n observer.observe(el, { attributeFilter: ['style'] })\n }\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "// Icon: streamline:wifi-signal-full-remix\n// Slug: Patches signals into the existing signals.\n// Description: Patches (adds, updates or removes) one or more signals into the existing signals.\n\nimport { attribute } from '@engine'\nimport { mergePatch, mergePaths } from '@engine/signals'\nimport { modifyCasing } from '@utils/text'\n\nattribute({\n name: 'signals',\n returnsValue: true,\n apply({ key, mods, rx }) {\n const ifMissing = mods.has('ifmissing')\n\n if (key) {\n key = modifyCasing(key, mods)\n mergePaths([[key, rx?.()]], { ifMissing })\n } else {\n const patch = Object.assign({}, rx?.() as Record)\n mergePatch(patch, { ifMissing })\n }\n },\n})\n", "// Icon: material-symbols:format-paint-outline\n// Slug: Sets inline styles on an element based on an expression.\n// Description: Sets CSS styles on an element using either key-based or object syntax, and keeps them in sync with reactive signals.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\nimport { kebab } from '@utils/text'\n\nattribute({\n name: 'style',\n requirement: {\n value: 'must',\n },\n returnsValue: true,\n apply({ key, el, rx }) {\n const { style } = el\n const initialStyles = new Map()\n\n const apply = (prop: string, value: any) => {\n const initial = initialStyles.get(prop)\n if (!value && value !== 0) {\n initial !== undefined &&\n (initial\n ? style.setProperty(prop, initial)\n : style.removeProperty(prop))\n } else {\n initial === undefined &&\n initialStyles.set(prop, style.getPropertyValue(prop))\n style.setProperty(prop, String(value))\n }\n }\n\n const update = () => {\n observer.disconnect()\n\n if (key) {\n apply(key, rx())\n } else {\n const styles = rx() as Record\n\n for (const [prop, initial] of initialStyles) {\n prop in styles ||\n (initial\n ? style.setProperty(prop, initial)\n : style.removeProperty(prop))\n }\n\n for (const prop in styles) {\n apply(kebab(prop), styles[prop])\n }\n }\n\n observer.observe(el, { attributeFilter: ['style'] })\n }\n\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n for (const [prop, initial] of initialStyles) {\n initial ? style.setProperty(prop, initial) : style.removeProperty(prop)\n }\n }\n },\n})\n", "// Icon: icon-park-outline:text\n// Slug: Binds the text content of an element.\n// Description: Binds the text content of an element to an expression.\n\nimport { attribute } from '@engine'\nimport { effect } from '@engine/signals'\n\nattribute({\n name: 'text',\n requirement: {\n key: 'denied',\n value: 'must',\n },\n returnsValue: true,\n apply({ el, rx }) {\n const update = () => {\n observer.disconnect()\n el.textContent = `${rx()}`\n observer.observe(el, {\n childList: true,\n characterData: true,\n subtree: true,\n })\n }\n\n const observer = new MutationObserver(update)\n const cleanup = effect(update)\n\n return () => {\n observer.disconnect()\n cleanup()\n }\n },\n})\n", "// Icon: material-symbols:cloud-download\n// Slug: Patches elements into the DOM.\n// Description: Patches elements into the DOM.\n\nimport { watcher } from '@engine'\nimport type { WatcherContext } from '@engine/types'\nimport { morph } from '@engine/morph'\nimport { supportsViewTransitions } from '@utils/view-transitions'\n\ntype PatchElementsMode =\n | 'remove'\n | 'outer'\n | 'inner'\n | 'replace'\n | 'prepend'\n | 'append'\n | 'before'\n | 'after'\n\ntype PatchElementsArgs = {\n elements: string\n mode: PatchElementsMode\n selector: string\n useViewTransition: boolean\n}\n\nwatcher({\n name: 'datastar-patch-elements',\n apply(\n ctx,\n { elements = '', selector = '', mode = 'outer', useViewTransition },\n ) {\n switch (mode) {\n case 'remove':\n case 'outer':\n case 'inner':\n case 'replace':\n case 'prepend':\n case 'append':\n case 'before':\n case 'after':\n break\n default:\n throw ctx.error('PatchElementsInvalidMode', { mode })\n }\n\n if (!selector && mode !== 'outer' && mode !== 'replace') {\n throw ctx.error('PatchElementsExpectedSelector')\n }\n\n const args2: PatchElementsArgs = {\n mode,\n selector,\n elements,\n useViewTransition: useViewTransition?.trim() === 'true',\n }\n\n if (supportsViewTransitions && useViewTransition) {\n document.startViewTransition(() => onPatchElements(ctx, args2))\n } else {\n onPatchElements(ctx, args2)\n }\n },\n})\n\nconst onPatchElements = (\n { error }: WatcherContext,\n { elements, selector, mode }: PatchElementsArgs,\n) => {\n const elementsWithSvgsRemoved = elements.replace(\n /]*>|>)([\\s\\S]*?)<\\/svg>/gim,\n '',\n )\n const hasHtml = /<\\/html>/.test(elementsWithSvgsRemoved)\n const hasHead = /<\\/head>/.test(elementsWithSvgsRemoved)\n const hasBody = /<\\/body>/.test(elementsWithSvgsRemoved)\n\n const newDocument = new DOMParser().parseFromString(\n hasHtml || hasHead || hasBody\n ? elements\n : ``,\n 'text/html',\n )\n\n let newContent = document.createDocumentFragment()\n if (hasHtml) {\n newContent.appendChild(newDocument.documentElement)\n } else if (hasHead && hasBody) {\n newContent.appendChild(newDocument.head)\n newContent.appendChild(newDocument.body)\n } else if (hasHead) {\n newContent.appendChild(newDocument.head)\n } else if (hasBody) {\n newContent.appendChild(newDocument.body)\n } else {\n newContent = newDocument.querySelector('template')!.content\n }\n\n if (!selector && (mode === 'outer' || mode === 'replace')) {\n for (const child of newContent.children) {\n let target: Element\n if (child instanceof HTMLHtmlElement) {\n target = document.documentElement\n } else if (child instanceof HTMLBodyElement) {\n target = document.body\n } else if (child instanceof HTMLHeadElement) {\n target = document.head\n } else {\n target = document.getElementById(child.id)!\n if (!target) {\n console.warn(error('PatchElementsNoTargetsFound'), {\n element: { id: child.id },\n })\n continue\n }\n }\n\n applyToTargets(mode as PatchElementsMode, child, [target])\n }\n } else {\n const targets = document.querySelectorAll(selector)\n if (!targets.length) {\n console.warn(error('PatchElementsNoTargetsFound'), { selector })\n return\n }\n\n applyToTargets(mode as PatchElementsMode, newContent, targets)\n }\n}\n\nconst scripts = new WeakSet()\nfor (const script of document.querySelectorAll('script')) {\n scripts.add(script)\n}\n\nconst execute = (target: Element): void => {\n const elScripts =\n target instanceof HTMLScriptElement\n ? [target]\n : target.querySelectorAll('script')\n for (const old of elScripts) {\n if (!scripts.has(old)) {\n const script = document.createElement('script')\n for (const { name, value } of old.attributes) {\n script.setAttribute(name, value)\n }\n script.text = old.text\n old.replaceWith(script)\n scripts.add(script)\n }\n }\n}\n\nconst applyPatchMode = (\n targets: Iterable,\n element: DocumentFragment | Element,\n action: string,\n) => {\n for (const target of targets) {\n const cloned = element.cloneNode(true) as Element\n execute(cloned)\n // @ts-expect-error\n target[action](cloned)\n }\n}\n\nconst applyToTargets = (\n mode: PatchElementsMode,\n element: DocumentFragment | Element,\n targets: Iterable,\n) => {\n switch (mode) {\n case 'remove':\n for (const target of targets) {\n target.remove()\n }\n break\n case 'outer':\n case 'inner':\n for (const target of targets) {\n morph(target, element.cloneNode(true) as Element, mode)\n execute(target)\n }\n break\n case 'replace':\n applyPatchMode(targets, element, 'replaceWith')\n break\n case 'prepend':\n case 'append':\n case 'before':\n case 'after':\n applyPatchMode(targets, element, mode)\n }\n}\n", "// Icon: material-symbols:settings-input-antenna\n// Slug: Patches signals.\n// Description: Patches signals.\n\nimport { watcher } from '@engine'\nimport { mergePatch } from '@engine/signals'\nimport { jsStrToObject } from '@utils/text'\n\nwatcher({\n name: 'datastar-patch-signals',\n apply({ error }, { signals, onlyIfMissing }) {\n if (signals) {\n const ifMissing = onlyIfMissing?.trim() === 'true'\n mergePatch(jsStrToObject(signals), { ifMissing })\n } else {\n throw error('PatchSignalsExpectedSignals')\n }\n },\n})\n"], + "mappings": "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", + "names": ["lol", "DSP", "DSS", "DATASTAR_FETCH_EVENT", "DATASTAR_SIGNAL_PATCH_EVENT", "kebab", "str", "snake", "str", "kebab", "jsStrToObject", "raw", "caseFns", "str", "x", "modifyCasing", "mods", "defaultCase", "c", "aliasify", "name", "hasOwn", "isPojo", "obj", "isEmpty", "prop", "hasOwn", "updateLeaves", "fn", "key", "val", "pathToObj", "paths", "result", "path", "value", "keys", "lastKey", "acc", "currentPatch", "queuedEffects", "batchDepth", "notifyIndex", "queuedEffectsLength", "prevSub", "activeSub", "version", "beginBatch", "endBatch", "flush", "dispatch", "startPeeking", "sub", "stopPeeking", "signal", "initialValue", "signalOper", "value_", "flags_", "computedSymbol", "computed", "getter", "c", "computedOper", "effect", "fn", "e", "fn_", "link", "effectOper", "run", "update", "updateComputed", "updateSignal", "startTracking", "oldValue", "endTracking", "s", "value", "notify", "flags", "subs", "subs_", "sub_", "checkDirty", "deps_", "dep", "dep_", "depFlags", "nextDep_", "propagate", "currentValue", "shallowPropagate", "unlink", "prevDep", "depsTail_", "nextDep", "version_", "subsTail_", "newLink", "prevDep_", "prevSub_", "nextSub_", "toRemove", "next", "stack", "top", "isValidLink", "subSubs", "nextSub", "prev_", "checkDepth", "dirty", "firstSub", "hasMultipleSubs", "checkLink", "getPath", "path", "result", "root", "split", "hasOwn", "deep", "prefix", "isArr", "isPojo", "deepObj", "key", "keys", "_", "prop", "newValue", "diff", "patch", "i", "detail", "pathToObj", "DATASTAR_SIGNAL_PATCH_EVENT", "mergePatch", "ifMissing", "mergeInner", "mergePaths", "paths", "options", "target", "targetParent", "toRegExp", "val", "filtered", "include", "exclude", "obj", "includeRe", "excludeRe", "node", "isHTMLOrSVG", "el", "url", "error", "ctx", "reason", "metadata", "e", "r", "snake", "q", "c", "actionPlugins", "attributePlugins", "watcherPlugins", "actions", "_", "prop", "removals", "queuedAttributes", "queuedAttributeNames", "attribute", "plugin", "apply", "action", "DATASTAR_FETCH_EVENT", "evt", "watcher", "cleanupEls", "els", "el", "cleanups", "cleanup", "aliasedIgnore", "aliasify", "aliasedIgnoreAttr", "shouldIgnore", "applyEls", "onlyNew", "key", "applyAttributePlugin", "observe", "mutations", "target", "type", "attributeName", "addedNodes", "removedNodes", "node", "isHTMLOrSVG", "value", "mutationObserver", "root", "attrKey", "rawKey", "namePart", "rawModifiers", "pluginName", "keyReq", "valueReq", "cachedRx", "args", "genRx", "rawMod", "label", "mod", "returnsValue", "argNames", "expr", "statementRe", "statements", "lastIdx", "last", "escaped", "escapeRe", "DSP", "DSS", "counter", "match", "k", "v", "signalName", "acc", "part", "varName", "fn", "name", "err", "ctxIdMap", "ctxPersistentIds", "oldIdTagNameMap", "duplicateIds", "ctxPantry", "aliasedIgnoreMorph", "aliasify", "aliasedIgnoreMorphAttr", "morph", "oldElt", "newContent", "mode", "isHTMLOrSVG", "normalizedElt", "oldIdElements", "id", "tagName", "newIdElements", "parent", "populateIdMapWithTree", "morphChildren", "oldParent", "newParent", "insertionPoint", "endPoint", "newChild", "bestMatch", "findBestMatch", "cursor", "tempNode", "removeNode", "morphNode", "movedChild", "current", "idSet", "moveBefore", "newEmptyChild", "newClonedChild", "node", "startPoint", "nextSibling", "siblingSoftMatchCount", "displaceMatchCount", "nodeMatchCount", "isSoftMatch", "isIdSetMatch", "oldSet", "newSet", "oldNode", "newNode", "aliasedPreserveAttr", "type", "newElt", "preserveAttrs", "name", "value", "i", "root", "elements", "elt", "action", "_", "fn", "startPeeking", "stopPeeking", "action", "_", "value", "filter", "startPeeking", "masked", "filtered", "updateLeaves", "mergePatch", "stopPeeking", "action", "_", "filter", "startPeeking", "masked", "filtered", "updateLeaves", "oldValue", "mergePatch", "stopPeeking", "fetchAbortControllers", "createHttpMethod", "name", "method", "action", "el", "evt", "error", "url", "selector", "userHeaders", "contentType", "include", "exclude", "openWhenHidden", "retryInterval", "retryScaler", "retryMaxWaitMs", "retryMaxCount", "requestCancellation", "controller", "isDisabled", "oldController", "observer", "mutations", "mutation", "removed", "cleanupFn", "initialHeaders", "headers", "req", "response", "dispatchFetch", "ERROR", "type", "argsRawLines", "line", "i", "v", "argsRaw", "k", "isWrongContent", "RETRYING", "urlInstance", "queryParams", "res", "filtered", "formEl", "formData", "submitter", "preventDefault", "multipart", "formParams", "key", "value", "STARTED", "fetchEventSource", "e", "FINISHED", "RETRIES_FAILED", "DATASTAR_FETCH_EVENT", "err", "getBytes", "stream", "onChunk", "reader", "result", "getLines", "onLine", "buffer", "position", "fieldLength", "discardTrailingNewline", "arr", "concat", "bufLength", "lineStart", "lineEnd", "getMessages", "onId", "onRetry", "onMessage", "message", "newMessage", "decoder", "field", "valueOffset", "retry", "a", "b", "input", "inputSignal", "inputHeaders", "inputOnOpen", "onmessage", "onclose", "onerror", "inputFetch", "overrides", "rest", "resolve", "reject", "curRequestController", "onVisibilityChange", "create", "retryTimer", "dispose", "fetch", "onopen", "retries", "baseRetryInterval", "dispatchNonSSE", "dispatchType", "argNames", "n", "kebab", "o", "ct", "script", "scriptAttributesHeader", "id", "interval", "innerErr", "attribute", "el", "key", "rx", "syncAttr", "val", "update", "observer", "obj", "attributeFilter", "cleanup", "effect", "dataURIRegex", "empty", "aliasedBind", "aliasify", "attribute", "el", "key", "mods", "value", "error", "signalName", "modifyCasing", "get", "type", "set", "syncSignal", "files", "signalFiles", "f", "resolve", "reader", "match", "mergePaths", "typeMap", "option", "initialValue", "getPath", "path", "signalNameKebab", "inputs", "paths", "i", "input", "signalValue", "cleanup", "effect", "attribute", "key", "el", "mods", "rx", "modifyCasing", "callback", "observer", "classes", "k", "classNames", "cn", "name", "cleanup", "effect", "attribute", "key", "mods", "rx", "error", "mergePaths", "modifyCasing", "computed", "patch", "updateLeaves", "old", "mergePatch", "attribute", "rx", "effect", "attribute", "el", "key", "mods", "value", "signalName", "modifyCasing", "mergePaths", "watcher", "event", "type", "elt", "STARTED", "FINISHED", "DATASTAR_FETCH_EVENT", "attribute", "el", "value", "mods", "spaces", "filters", "jsStrToObject", "callback", "observer", "filtered", "cleanup", "effect", "tagToMs", "args", "arg", "tagHas", "tags", "tag", "defaultValue", "delay", "callback", "wait", "args", "debounce", "leading", "trailing", "timer", "throttle", "waiting", "modifyTiming", "mods", "delayArgs", "tagToMs", "debounceArgs", "tagHas", "throttleArgs", "supportsViewTransitions", "modifyViewTransition", "callback", "mods", "cb", "args", "attribute", "el", "key", "mods", "rx", "target", "callback", "evt", "beginBatch", "endBatch", "modifyViewTransition", "modifyTiming", "evtListOpts", "cb", "eventName", "modifyCasing", "DATASTAR_FETCH_EVENT", "DATASTAR_SIGNAL_PATCH_EVENT", "once", "attribute", "el", "mods", "rx", "callback", "beginBatch", "endBatch", "modifyViewTransition", "modifyTiming", "options", "observer", "entries", "entry", "attribute", "mods", "rx", "callback", "beginBatch", "endBatch", "modifyViewTransition", "duration", "durationArgs", "tagToMs", "tagHas", "intervalId", "attribute", "rx", "mods", "callback", "beginBatch", "endBatch", "modifyViewTransition", "wait", "delayArgs", "tagToMs", "delay", "attribute", "el", "key", "mods", "rx", "error", "filtersRaw", "filters", "jsStrToObject", "callback", "modifyTiming", "evt", "watched", "filtered", "isEmpty", "beginBatch", "endBatch", "DATASTAR_SIGNAL_PATCH_EVENT", "attribute", "el", "key", "mods", "value", "signalName", "modifyCasing", "mergePaths", "NONE", "DISPLAY", "attribute", "el", "rx", "update", "observer", "cleanup", "effect", "attribute", "key", "mods", "rx", "ifMissing", "modifyCasing", "mergePaths", "patch", "mergePatch", "attribute", "key", "el", "rx", "style", "initialStyles", "apply", "prop", "value", "initial", "update", "observer", "styles", "kebab", "cleanup", "effect", "attribute", "el", "rx", "update", "observer", "cleanup", "effect", "watcher", "ctx", "elements", "selector", "mode", "useViewTransition", "args2", "supportsViewTransitions", "onPatchElements", "error", "elementsWithSvgsRemoved", "hasHtml", "hasHead", "hasBody", "newDocument", "newContent", "child", "target", "applyToTargets", "targets", "scripts", "script", "execute", "elScripts", "old", "name", "value", "applyPatchMode", "element", "action", "cloned", "morph", "watcher", "error", "signals", "onlyIfMissing", "ifMissing", "mergePatch", "jsStrToObject"] +} diff --git a/experiments/simple/frontend/index.html b/experiments/simple/frontend/index.html new file mode 100644 index 0000000..77cc9d3 --- /dev/null +++ b/experiments/simple/frontend/index.html @@ -0,0 +1,24 @@ + + + + + + + Echo Example + + + + + + + +

The CRUD Example

+ + +
+
+
+ + + + \ No newline at end of file diff --git a/experiments/simple/frontend/pico.blue.css b/experiments/simple/frontend/pico.blue.css new file mode 100644 index 0000000..e76f23b --- /dev/null +++ b/experiments/simple/frontend/pico.blue.css @@ -0,0 +1,2808 @@ +@charset "UTF-8"; +/*! + * Pico CSS ✨ v2.0.6 (https://picocss.com) + * Copyright 2019-2024 - Licensed under MIT + */ +/** + * Styles + */ + +@view-transition { + navigation: auto; +} + + +:root { + --pico-font-family-emoji: "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; + --pico-font-family-sans-serif: system-ui, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, Helvetica, Arial, "Helvetica Neue", sans-serif, var(--pico-font-family-emoji); + --pico-font-family-monospace: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace, var(--pico-font-family-emoji); + --pico-font-family: var(--pico-font-family-sans-serif); + --pico-line-height: 1.5; + --pico-font-weight: 400; + --pico-font-size: 100%; + --pico-text-underline-offset: 0.1rem; + --pico-border-radius: 0.25rem; + --pico-border-width: 0.0625rem; + --pico-outline-width: 0.125rem; + --pico-transition: 0.2s ease-in-out; + --pico-spacing: 1rem; + --pico-typography-spacing-vertical: 1rem; + --pico-block-spacing-vertical: var(--pico-spacing); + --pico-block-spacing-horizontal: var(--pico-spacing); + --pico-grid-column-gap: var(--pico-spacing); + --pico-grid-row-gap: var(--pico-spacing); + --pico-form-element-spacing-vertical: 0.75rem; + --pico-form-element-spacing-horizontal: 1rem; + --pico-group-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-group-box-shadow-focus-with-button: 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); + --pico-group-box-shadow-focus-with-input: 0 0 0 0.0625rem var(--pico-form-element-border-color); + --pico-modal-overlay-backdrop-filter: blur(0.375rem); + --pico-nav-element-spacing-vertical: 1rem; + --pico-nav-element-spacing-horizontal: 0.5rem; + --pico-nav-link-spacing-vertical: 0.5rem; + --pico-nav-link-spacing-horizontal: 0.5rem; + --pico-nav-breadcrumb-divider: ">"; + --pico-icon-checkbox: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-minus: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(255, 255, 255)' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='5' y1='12' x2='19' y2='12'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-date: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-time: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cpolyline points='12 6 12 12 16 14'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-close: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(136, 145, 164)' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E"); + --pico-icon-loading: url("data:image/svg+xml,%3Csvg fill='none' height='24' width='24' viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg' %3E%3Cstyle%3E g %7B animation: rotate 2s linear infinite; transform-origin: center center; %7D circle %7B stroke-dasharray: 75,100; stroke-dashoffset: -5; animation: dash 1.5s ease-in-out infinite; stroke-linecap: round; %7D @keyframes rotate %7B 0%25 %7B transform: rotate(0deg); %7D 100%25 %7B transform: rotate(360deg); %7D %7D @keyframes dash %7B 0%25 %7B stroke-dasharray: 1,100; stroke-dashoffset: 0; %7D 50%25 %7B stroke-dasharray: 44.5,100; stroke-dashoffset: -17.5; %7D 100%25 %7B stroke-dasharray: 44.5,100; stroke-dashoffset: -62; %7D %7D %3C/style%3E%3Cg%3E%3Ccircle cx='12' cy='12' r='10' fill='none' stroke='rgb(136, 145, 164)' stroke-width='4' /%3E%3C/g%3E%3C/svg%3E"); +} +@media (min-width: 576px) { + :root { + --pico-font-size: 106.25%; + } +} +@media (min-width: 768px) { + :root { + --pico-font-size: 112.5%; + } +} +@media (min-width: 1024px) { + :root { + --pico-font-size: 118.75%; + } +} +@media (min-width: 1280px) { + :root { + --pico-font-size: 125%; + } +} +@media (min-width: 1536px) { + :root { + --pico-font-size: 131.25%; + } +} + +a { + --pico-text-decoration: underline; +} +a.secondary, a.contrast { + --pico-text-decoration: underline; +} + +small { + --pico-font-size: 0.875em; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + --pico-font-weight: 700; +} + +h1 { + --pico-font-size: 2rem; + --pico-line-height: 1.125; + --pico-typography-spacing-top: 3rem; +} + +h2 { + --pico-font-size: 1.75rem; + --pico-line-height: 1.15; + --pico-typography-spacing-top: 2.625rem; +} + +h3 { + --pico-font-size: 1.5rem; + --pico-line-height: 1.175; + --pico-typography-spacing-top: 2.25rem; +} + +h4 { + --pico-font-size: 1.25rem; + --pico-line-height: 1.2; + --pico-typography-spacing-top: 1.874rem; +} + +h5 { + --pico-font-size: 1.125rem; + --pico-line-height: 1.225; + --pico-typography-spacing-top: 1.6875rem; +} + +h6 { + --pico-font-size: 1rem; + --pico-line-height: 1.25; + --pico-typography-spacing-top: 1.5rem; +} + +thead th, +thead td, +tfoot th, +tfoot td { + --pico-font-weight: 600; + --pico-border-width: 0.1875rem; +} + +pre, +code, +kbd, +samp { + --pico-font-family: var(--pico-font-family-monospace); +} + +kbd { + --pico-font-weight: bolder; +} + +input:not([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]), +:where(select, textarea) { + --pico-outline-width: 0.0625rem; +} + +[type=search] { + --pico-border-radius: 5rem; +} + +[type=checkbox], +[type=radio] { + --pico-border-width: 0.125rem; +} + +[type=checkbox][role=switch] { + --pico-border-width: 0.1875rem; +} + +details.dropdown summary:not([role=button]) { + --pico-outline-width: 0.0625rem; +} + +nav details.dropdown summary:focus-visible { + --pico-outline-width: 0.125rem; +} + +[role=search] { + --pico-border-radius: 5rem; +} + +[role=search]:has(button.secondary:focus, +[type=submit].secondary:focus, +[type=button].secondary:focus, +[role=button].secondary:focus), +[role=group]:has(button.secondary:focus, +[type=submit].secondary:focus, +[type=button].secondary:focus, +[role=button].secondary:focus) { + --pico-group-box-shadow-focus-with-button: 0 0 0 var(--pico-outline-width) var(--pico-secondary-focus); +} +[role=search]:has(button.contrast:focus, +[type=submit].contrast:focus, +[type=button].contrast:focus, +[role=button].contrast:focus), +[role=group]:has(button.contrast:focus, +[type=submit].contrast:focus, +[type=button].contrast:focus, +[role=button].contrast:focus) { + --pico-group-box-shadow-focus-with-button: 0 0 0 var(--pico-outline-width) var(--pico-contrast-focus); +} +[role=search] button, +[role=search] [type=submit], +[role=search] [type=button], +[role=search] [role=button], +[role=group] button, +[role=group] [type=submit], +[role=group] [type=button], +[role=group] [role=button] { + --pico-form-element-spacing-horizontal: 2rem; +} + +details summary[role=button]:not(.outline)::after { + filter: brightness(0) invert(1); +} + +[aria-busy=true]:not(input, select, textarea):is(button, [type=submit], [type=button], [type=reset], [role=button]):not(.outline)::before { + filter: brightness(0) invert(1); +} + +/** + * Color schemes + */ +[data-theme=light], +:root:not([data-theme=dark]) { + --pico-background-color: #fff; + --pico-color: #373c44; + --pico-text-selection-color: rgba(116, 139, 248, 0.25); + --pico-muted-color: #646b79; + --pico-muted-border-color: #e7eaf0; + --pico-primary: #2060df; + --pico-primary-background: #2060df; + --pico-primary-border: var(--pico-primary-background); + --pico-primary-underline: rgba(32, 96, 223, 0.5); + --pico-primary-hover: #184eb8; + --pico-primary-hover-background: #1d59d0; + --pico-primary-hover-border: var(--pico-primary-hover-background); + --pico-primary-hover-underline: var(--pico-primary-hover); + --pico-primary-focus: rgba(116, 139, 248, 0.5); + --pico-primary-inverse: #fff; + --pico-secondary: #5d6b89; + --pico-secondary-background: #525f7a; + --pico-secondary-border: var(--pico-secondary-background); + --pico-secondary-underline: rgba(93, 107, 137, 0.5); + --pico-secondary-hover: #48536b; + --pico-secondary-hover-background: #48536b; + --pico-secondary-hover-border: var(--pico-secondary-hover-background); + --pico-secondary-hover-underline: var(--pico-secondary-hover); + --pico-secondary-focus: rgba(93, 107, 137, 0.25); + --pico-secondary-inverse: #fff; + --pico-contrast: #181c25; + --pico-contrast-background: #181c25; + --pico-contrast-border: var(--pico-contrast-background); + --pico-contrast-underline: rgba(24, 28, 37, 0.5); + --pico-contrast-hover: #000; + --pico-contrast-hover-background: #000; + --pico-contrast-hover-border: var(--pico-contrast-hover-background); + --pico-contrast-hover-underline: var(--pico-secondary-hover); + --pico-contrast-focus: rgba(93, 107, 137, 0.25); + --pico-contrast-inverse: #fff; + --pico-box-shadow: 0.0145rem 0.029rem 0.174rem rgba(129, 145, 181, 0.01698), 0.0335rem 0.067rem 0.402rem rgba(129, 145, 181, 0.024), 0.0625rem 0.125rem 0.75rem rgba(129, 145, 181, 0.03), 0.1125rem 0.225rem 1.35rem rgba(129, 145, 181, 0.036), 0.2085rem 0.417rem 2.502rem rgba(129, 145, 181, 0.04302), 0.5rem 1rem 6rem rgba(129, 145, 181, 0.06), 0 0 0 0.0625rem rgba(129, 145, 181, 0.015); + --pico-h1-color: #2d3138; + --pico-h2-color: #373c44; + --pico-h3-color: #424751; + --pico-h4-color: #4d535e; + --pico-h5-color: #5c6370; + --pico-h6-color: #646b79; + --pico-mark-background-color: #fde7c0; + --pico-mark-color: #0f1114; + --pico-ins-color: #1d6a54; + --pico-del-color: #883935; + --pico-blockquote-border-color: var(--pico-muted-border-color); + --pico-blockquote-footer-color: var(--pico-muted-color); + --pico-button-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-table-border-color: var(--pico-muted-border-color); + --pico-table-row-stripped-background-color: rgba(111, 120, 135, 0.0375); + --pico-code-background-color: #f3f5f7; + --pico-code-color: #646b79; + --pico-code-kbd-background-color: var(--pico-color); + --pico-code-kbd-color: var(--pico-background-color); + --pico-form-element-background-color: #fbfcfc; + --pico-form-element-selected-background-color: #dfe3eb; + --pico-form-element-border-color: #cfd5e2; + --pico-form-element-color: #23262c; + --pico-form-element-placeholder-color: var(--pico-muted-color); + --pico-form-element-active-background-color: #fff; + --pico-form-element-active-border-color: var(--pico-primary-border); + --pico-form-element-focus-color: var(--pico-primary-border); + --pico-form-element-disabled-opacity: 0.5; + --pico-form-element-invalid-border-color: #b86a6b; + --pico-form-element-invalid-active-border-color: #c84f48; + --pico-form-element-invalid-focus-color: var(--pico-form-element-invalid-active-border-color); + --pico-form-element-valid-border-color: #4c9b8a; + --pico-form-element-valid-active-border-color: #279977; + --pico-form-element-valid-focus-color: var(--pico-form-element-valid-active-border-color); + --pico-switch-background-color: #bfc7d9; + --pico-switch-checked-background-color: var(--pico-primary-background); + --pico-switch-color: #fff; + --pico-switch-thumb-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-range-border-color: #dfe3eb; + --pico-range-active-border-color: #bfc7d9; + --pico-range-thumb-border-color: var(--pico-background-color); + --pico-range-thumb-color: var(--pico-secondary-background); + --pico-range-thumb-active-color: var(--pico-primary-background); + --pico-accordion-border-color: var(--pico-muted-border-color); + --pico-accordion-active-summary-color: var(--pico-primary-hover); + --pico-accordion-close-summary-color: var(--pico-color); + --pico-accordion-open-summary-color: var(--pico-muted-color); + --pico-card-background-color: var(--pico-background-color); + --pico-card-border-color: var(--pico-muted-border-color); + --pico-card-box-shadow: var(--pico-box-shadow); + --pico-card-sectioning-background-color: #fbfcfc; + --pico-dropdown-background-color: #fff; + --pico-dropdown-border-color: #eff1f4; + --pico-dropdown-box-shadow: var(--pico-box-shadow); + --pico-dropdown-color: var(--pico-color); + --pico-dropdown-hover-background-color: #eff1f4; + --pico-loading-spinner-opacity: 0.5; + --pico-modal-overlay-background-color: rgba(232, 234, 237, 0.75); + --pico-progress-background-color: #dfe3eb; + --pico-progress-color: var(--pico-primary-background); + --pico-tooltip-background-color: var(--pico-contrast-background); + --pico-tooltip-color: var(--pico-contrast-inverse); + --pico-icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(76, 155, 138)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(200, 79, 72)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); + color-scheme: light; +} +[data-theme=light] input:is([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]), +:root:not([data-theme=dark]) input:is([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]) { + --pico-form-element-focus-color: var(--pico-primary-focus); +} + +@media only screen and (prefers-color-scheme: dark) { + :root:not([data-theme]) { + --pico-background-color: #13171f; + --pico-color: #c2c7d0; + --pico-text-selection-color: rgba(137, 153, 249, 0.1875); + --pico-muted-color: #7b8495; + --pico-muted-border-color: #202632; + --pico-primary: #8999f9; + --pico-primary-background: #2060df; + --pico-primary-border: var(--pico-primary-background); + --pico-primary-underline: rgba(137, 153, 249, 0.5); + --pico-primary-hover: #aeb5fb; + --pico-primary-hover-background: #3c71f7; + --pico-primary-hover-border: var(--pico-primary-hover-background); + --pico-primary-hover-underline: var(--pico-primary-hover); + --pico-primary-focus: rgba(137, 153, 249, 0.375); + --pico-primary-inverse: #fff; + --pico-secondary: #969eaf; + --pico-secondary-background: #525f7a; + --pico-secondary-border: var(--pico-secondary-background); + --pico-secondary-underline: rgba(150, 158, 175, 0.5); + --pico-secondary-hover: #b3b9c5; + --pico-secondary-hover-background: #5d6b89; + --pico-secondary-hover-border: var(--pico-secondary-hover-background); + --pico-secondary-hover-underline: var(--pico-secondary-hover); + --pico-secondary-focus: rgba(144, 158, 190, 0.25); + --pico-secondary-inverse: #fff; + --pico-contrast: #dfe3eb; + --pico-contrast-background: #eff1f4; + --pico-contrast-border: var(--pico-contrast-background); + --pico-contrast-underline: rgba(223, 227, 235, 0.5); + --pico-contrast-hover: #fff; + --pico-contrast-hover-background: #fff; + --pico-contrast-hover-border: var(--pico-contrast-hover-background); + --pico-contrast-hover-underline: var(--pico-contrast-hover); + --pico-contrast-focus: rgba(207, 213, 226, 0.25); + --pico-contrast-inverse: #000; + --pico-box-shadow: 0.0145rem 0.029rem 0.174rem rgba(7, 9, 12, 0.01698), 0.0335rem 0.067rem 0.402rem rgba(7, 9, 12, 0.024), 0.0625rem 0.125rem 0.75rem rgba(7, 9, 12, 0.03), 0.1125rem 0.225rem 1.35rem rgba(7, 9, 12, 0.036), 0.2085rem 0.417rem 2.502rem rgba(7, 9, 12, 0.04302), 0.5rem 1rem 6rem rgba(7, 9, 12, 0.06), 0 0 0 0.0625rem rgba(7, 9, 12, 0.015); + --pico-h1-color: #f0f1f3; + --pico-h2-color: #e0e3e7; + --pico-h3-color: #c2c7d0; + --pico-h4-color: #b3b9c5; + --pico-h5-color: #a4acba; + --pico-h6-color: #8891a4; + --pico-mark-background-color: #014063; + --pico-mark-color: #fff; + --pico-ins-color: #62af9a; + --pico-del-color: #ce7e7b; + --pico-blockquote-border-color: var(--pico-muted-border-color); + --pico-blockquote-footer-color: var(--pico-muted-color); + --pico-button-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-table-border-color: var(--pico-muted-border-color); + --pico-table-row-stripped-background-color: rgba(111, 120, 135, 0.0375); + --pico-code-background-color: #1a1f28; + --pico-code-color: #8891a4; + --pico-code-kbd-background-color: var(--pico-color); + --pico-code-kbd-color: var(--pico-background-color); + --pico-form-element-background-color: #1c212c; + --pico-form-element-selected-background-color: #2a3140; + --pico-form-element-border-color: #2a3140; + --pico-form-element-color: #e0e3e7; + --pico-form-element-placeholder-color: #8891a4; + --pico-form-element-active-background-color: #1a1f28; + --pico-form-element-active-border-color: var(--pico-primary-border); + --pico-form-element-focus-color: var(--pico-primary-border); + --pico-form-element-disabled-opacity: 0.5; + --pico-form-element-invalid-border-color: #964a50; + --pico-form-element-invalid-active-border-color: #b7403b; + --pico-form-element-invalid-focus-color: var(--pico-form-element-invalid-active-border-color); + --pico-form-element-valid-border-color: #2a7b6f; + --pico-form-element-valid-active-border-color: #16896a; + --pico-form-element-valid-focus-color: var(--pico-form-element-valid-active-border-color); + --pico-switch-background-color: #333c4e; + --pico-switch-checked-background-color: var(--pico-primary-background); + --pico-switch-color: #fff; + --pico-switch-thumb-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-range-border-color: #202632; + --pico-range-active-border-color: #2a3140; + --pico-range-thumb-border-color: var(--pico-background-color); + --pico-range-thumb-color: var(--pico-secondary-background); + --pico-range-thumb-active-color: var(--pico-primary-background); + --pico-accordion-border-color: var(--pico-muted-border-color); + --pico-accordion-active-summary-color: var(--pico-primary-hover); + --pico-accordion-close-summary-color: var(--pico-color); + --pico-accordion-open-summary-color: var(--pico-muted-color); + --pico-card-background-color: #181c25; + --pico-card-border-color: var(--pico-card-background-color); + --pico-card-box-shadow: var(--pico-box-shadow); + --pico-card-sectioning-background-color: #1a1f28; + --pico-dropdown-background-color: #181c25; + --pico-dropdown-border-color: #202632; + --pico-dropdown-box-shadow: var(--pico-box-shadow); + --pico-dropdown-color: var(--pico-color); + --pico-dropdown-hover-background-color: #202632; + --pico-loading-spinner-opacity: 0.5; + --pico-modal-overlay-background-color: rgba(8, 9, 10, 0.75); + --pico-progress-background-color: #202632; + --pico-progress-color: var(--pico-primary-background); + --pico-tooltip-background-color: var(--pico-contrast-background); + --pico-tooltip-color: var(--pico-contrast-inverse); + --pico-icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(42, 123, 111)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(150, 74, 80)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); + color-scheme: dark; + } + :root:not([data-theme]) input:is([type=submit], + [type=button], + [type=reset], + [type=checkbox], + [type=radio], + [type=file]) { + --pico-form-element-focus-color: var(--pico-primary-focus); + } + :root:not([data-theme]) details summary[role=button].contrast:not(.outline)::after { + filter: brightness(0); + } + :root:not([data-theme]) [aria-busy=true]:not(input, select, textarea).contrast:is(button, + [type=submit], + [type=button], + [type=reset], + [role=button]):not(.outline)::before { + filter: brightness(0); + } +} +[data-theme=dark] { + --pico-background-color: #13171f; + --pico-color: #c2c7d0; + --pico-text-selection-color: rgba(137, 153, 249, 0.1875); + --pico-muted-color: #7b8495; + --pico-muted-border-color: #202632; + --pico-primary: #8999f9; + --pico-primary-background: #2060df; + --pico-primary-border: var(--pico-primary-background); + --pico-primary-underline: rgba(137, 153, 249, 0.5); + --pico-primary-hover: #aeb5fb; + --pico-primary-hover-background: #3c71f7; + --pico-primary-hover-border: var(--pico-primary-hover-background); + --pico-primary-hover-underline: var(--pico-primary-hover); + --pico-primary-focus: rgba(137, 153, 249, 0.375); + --pico-primary-inverse: #fff; + --pico-secondary: #969eaf; + --pico-secondary-background: #525f7a; + --pico-secondary-border: var(--pico-secondary-background); + --pico-secondary-underline: rgba(150, 158, 175, 0.5); + --pico-secondary-hover: #b3b9c5; + --pico-secondary-hover-background: #5d6b89; + --pico-secondary-hover-border: var(--pico-secondary-hover-background); + --pico-secondary-hover-underline: var(--pico-secondary-hover); + --pico-secondary-focus: rgba(144, 158, 190, 0.25); + --pico-secondary-inverse: #fff; + --pico-contrast: #dfe3eb; + --pico-contrast-background: #eff1f4; + --pico-contrast-border: var(--pico-contrast-background); + --pico-contrast-underline: rgba(223, 227, 235, 0.5); + --pico-contrast-hover: #fff; + --pico-contrast-hover-background: #fff; + --pico-contrast-hover-border: var(--pico-contrast-hover-background); + --pico-contrast-hover-underline: var(--pico-contrast-hover); + --pico-contrast-focus: rgba(207, 213, 226, 0.25); + --pico-contrast-inverse: #000; + --pico-box-shadow: 0.0145rem 0.029rem 0.174rem rgba(7, 9, 12, 0.01698), 0.0335rem 0.067rem 0.402rem rgba(7, 9, 12, 0.024), 0.0625rem 0.125rem 0.75rem rgba(7, 9, 12, 0.03), 0.1125rem 0.225rem 1.35rem rgba(7, 9, 12, 0.036), 0.2085rem 0.417rem 2.502rem rgba(7, 9, 12, 0.04302), 0.5rem 1rem 6rem rgba(7, 9, 12, 0.06), 0 0 0 0.0625rem rgba(7, 9, 12, 0.015); + --pico-h1-color: #f0f1f3; + --pico-h2-color: #e0e3e7; + --pico-h3-color: #c2c7d0; + --pico-h4-color: #b3b9c5; + --pico-h5-color: #a4acba; + --pico-h6-color: #8891a4; + --pico-mark-background-color: #014063; + --pico-mark-color: #fff; + --pico-ins-color: #62af9a; + --pico-del-color: #ce7e7b; + --pico-blockquote-border-color: var(--pico-muted-border-color); + --pico-blockquote-footer-color: var(--pico-muted-color); + --pico-button-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-button-hover-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-table-border-color: var(--pico-muted-border-color); + --pico-table-row-stripped-background-color: rgba(111, 120, 135, 0.0375); + --pico-code-background-color: #1a1f28; + --pico-code-color: #8891a4; + --pico-code-kbd-background-color: var(--pico-color); + --pico-code-kbd-color: var(--pico-background-color); + --pico-form-element-background-color: #1c212c; + --pico-form-element-selected-background-color: #2a3140; + --pico-form-element-border-color: #2a3140; + --pico-form-element-color: #e0e3e7; + --pico-form-element-placeholder-color: #8891a4; + --pico-form-element-active-background-color: #1a1f28; + --pico-form-element-active-border-color: var(--pico-primary-border); + --pico-form-element-focus-color: var(--pico-primary-border); + --pico-form-element-disabled-opacity: 0.5; + --pico-form-element-invalid-border-color: #964a50; + --pico-form-element-invalid-active-border-color: #b7403b; + --pico-form-element-invalid-focus-color: var(--pico-form-element-invalid-active-border-color); + --pico-form-element-valid-border-color: #2a7b6f; + --pico-form-element-valid-active-border-color: #16896a; + --pico-form-element-valid-focus-color: var(--pico-form-element-valid-active-border-color); + --pico-switch-background-color: #333c4e; + --pico-switch-checked-background-color: var(--pico-primary-background); + --pico-switch-color: #fff; + --pico-switch-thumb-box-shadow: 0 0 0 rgba(0, 0, 0, 0); + --pico-range-border-color: #202632; + --pico-range-active-border-color: #2a3140; + --pico-range-thumb-border-color: var(--pico-background-color); + --pico-range-thumb-color: var(--pico-secondary-background); + --pico-range-thumb-active-color: var(--pico-primary-background); + --pico-accordion-border-color: var(--pico-muted-border-color); + --pico-accordion-active-summary-color: var(--pico-primary-hover); + --pico-accordion-close-summary-color: var(--pico-color); + --pico-accordion-open-summary-color: var(--pico-muted-color); + --pico-card-background-color: #181c25; + --pico-card-border-color: var(--pico-card-background-color); + --pico-card-box-shadow: var(--pico-box-shadow); + --pico-card-sectioning-background-color: #1a1f28; + --pico-dropdown-background-color: #181c25; + --pico-dropdown-border-color: #202632; + --pico-dropdown-box-shadow: var(--pico-box-shadow); + --pico-dropdown-color: var(--pico-color); + --pico-dropdown-hover-background-color: #202632; + --pico-loading-spinner-opacity: 0.5; + --pico-modal-overlay-background-color: rgba(8, 9, 10, 0.75); + --pico-progress-background-color: #202632; + --pico-progress-color: var(--pico-primary-background); + --pico-tooltip-background-color: var(--pico-contrast-background); + --pico-tooltip-color: var(--pico-contrast-inverse); + --pico-icon-valid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(42, 123, 111)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'%3E%3C/polyline%3E%3C/svg%3E"); + --pico-icon-invalid: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='rgb(150, 74, 80)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12.01' y2='16'%3E%3C/line%3E%3C/svg%3E"); + color-scheme: dark; +} +[data-theme=dark] input:is([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[type=file]) { + --pico-form-element-focus-color: var(--pico-primary-focus); +} +[data-theme=dark] details summary[role=button].contrast:not(.outline)::after { + filter: brightness(0); +} +[data-theme=dark] [aria-busy=true]:not(input, select, textarea).contrast:is(button, +[type=submit], +[type=button], +[type=reset], +[role=button]):not(.outline)::before { + filter: brightness(0); +} + +progress, +[type=checkbox], +[type=radio], +[type=range] { + accent-color: var(--pico-primary); +} + +/** + * Document + * Content-box & Responsive typography + */ +*, +*::before, +*::after { + box-sizing: border-box; + background-repeat: no-repeat; +} + +::before, +::after { + text-decoration: inherit; + vertical-align: inherit; +} + +:where(:root) { + -webkit-tap-highlight-color: transparent; + -webkit-text-size-adjust: 100%; + -moz-text-size-adjust: 100%; + text-size-adjust: 100%; + background-color: var(--pico-background-color); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + font-size: var(--pico-font-size); + line-height: var(--pico-line-height); + font-family: var(--pico-font-family); + text-underline-offset: var(--pico-text-underline-offset); + text-rendering: optimizeLegibility; + overflow-wrap: break-word; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; +} + +/** + * Landmarks + */ +body { + width: 100%; + margin: 0; +} + +main { + display: block; +} + +body > header, +body > main, +body > footer { + padding-block: var(--pico-block-spacing-vertical); +} + +/** + * Section + */ +section { + margin-bottom: var(--pico-block-spacing-vertical); +} + +/** + * Container + */ +.container, +.container-fluid { + width: 100%; + margin-right: auto; + margin-left: auto; + padding-right: var(--pico-spacing); + padding-left: var(--pico-spacing); +} + +@media (min-width: 576px) { + .container { + max-width: 510px; + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 768px) { + .container { + max-width: 700px; + } +} +@media (min-width: 1024px) { + .container { + max-width: 950px; + } +} +@media (min-width: 1280px) { + .container { + max-width: 1200px; + } +} +@media (min-width: 1536px) { + .container { + max-width: 1450px; + } +} + +/** + * Grid + * Minimal grid system with auto-layout columns + */ +.grid { + grid-column-gap: var(--pico-grid-column-gap); + grid-row-gap: var(--pico-grid-row-gap); + display: grid; + grid-template-columns: 1fr; +} +@media (min-width: 768px) { + .grid { + grid-template-columns: repeat(auto-fit, minmax(0%, 1fr)); + } +} +.grid > * { + min-width: 0; +} + +/** + * Overflow auto + */ +.overflow-auto { + overflow: auto; +} + +/** + * Typography + */ +b, +strong { + font-weight: bolder; +} + +sub, +sup { + position: relative; + font-size: 0.75em; + line-height: 0; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +address, +blockquote, +dl, +ol, +p, +pre, +table, +ul { + margin-top: 0; + margin-bottom: var(--pico-typography-spacing-vertical); + color: var(--pico-color); + font-style: normal; + font-weight: var(--pico-font-weight); +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin-top: 0; + margin-bottom: var(--pico-typography-spacing-vertical); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + font-size: var(--pico-font-size); + line-height: var(--pico-line-height); + font-family: var(--pico-font-family); +} + +h1 { + --pico-color: var(--pico-h1-color); +} + +h2 { + --pico-color: var(--pico-h2-color); +} + +h3 { + --pico-color: var(--pico-h3-color); +} + +h4 { + --pico-color: var(--pico-h4-color); +} + +h5 { + --pico-color: var(--pico-h5-color); +} + +h6 { + --pico-color: var(--pico-h6-color); +} + +:where(article, address, blockquote, dl, figure, form, ol, p, pre, table, ul) ~ :is(h1, h2, h3, h4, h5, h6) { + margin-top: var(--pico-typography-spacing-top); +} + +p { + margin-bottom: var(--pico-typography-spacing-vertical); +} + +hgroup { + margin-bottom: var(--pico-typography-spacing-vertical); +} +hgroup > * { + margin-top: 0; + margin-bottom: 0; +} +hgroup > *:not(:first-child):last-child { + --pico-color: var(--pico-muted-color); + --pico-font-weight: unset; + font-size: 1rem; +} + +:where(ol, ul) li { + margin-bottom: calc(var(--pico-typography-spacing-vertical) * 0.25); +} + +:where(dl, ol, ul) :where(dl, ol, ul) { + margin: 0; + margin-top: calc(var(--pico-typography-spacing-vertical) * 0.25); +} + +ul li { + list-style: square; +} + +mark { + padding: 0.125rem 0.25rem; + background-color: var(--pico-mark-background-color); + color: var(--pico-mark-color); + vertical-align: baseline; +} + +blockquote { + display: block; + margin: var(--pico-typography-spacing-vertical) 0; + padding: var(--pico-spacing); + border-right: none; + border-left: 0.25rem solid var(--pico-blockquote-border-color); + border-inline-start: 0.25rem solid var(--pico-blockquote-border-color); + border-inline-end: none; +} +blockquote footer { + margin-top: calc(var(--pico-typography-spacing-vertical) * 0.5); + color: var(--pico-blockquote-footer-color); +} + +abbr[title] { + border-bottom: 1px dotted; + text-decoration: none; + cursor: help; +} + +ins { + color: var(--pico-ins-color); + text-decoration: none; +} + +del { + color: var(--pico-del-color); +} + +::-moz-selection { + background-color: var(--pico-text-selection-color); +} + +::selection { + background-color: var(--pico-text-selection-color); +} + +/** + * Link + */ +:where(a:not([role=button])), +[role=link] { + --pico-color: var(--pico-primary); + --pico-background-color: transparent; + --pico-underline: var(--pico-primary-underline); + outline: none; + background-color: var(--pico-background-color); + color: var(--pico-color); + -webkit-text-decoration: var(--pico-text-decoration); + text-decoration: var(--pico-text-decoration); + text-decoration-color: var(--pico-underline); + text-underline-offset: 0.125em; + transition: background-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition), -webkit-text-decoration var(--pico-transition); + transition: background-color var(--pico-transition), color var(--pico-transition), text-decoration var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), color var(--pico-transition), text-decoration var(--pico-transition), box-shadow var(--pico-transition), -webkit-text-decoration var(--pico-transition); +} +:where(a:not([role=button])):is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[role=link]:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-primary-hover); + --pico-underline: var(--pico-primary-hover-underline); + --pico-text-decoration: underline; +} +:where(a:not([role=button])):focus-visible, +[role=link]:focus-visible { + box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); +} +:where(a:not([role=button])).secondary, +[role=link].secondary { + --pico-color: var(--pico-secondary); + --pico-underline: var(--pico-secondary-underline); +} +:where(a:not([role=button])).secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[role=link].secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-secondary-hover); + --pico-underline: var(--pico-secondary-hover-underline); +} +:where(a:not([role=button])).contrast, +[role=link].contrast { + --pico-color: var(--pico-contrast); + --pico-underline: var(--pico-contrast-underline); +} +:where(a:not([role=button])).contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[role=link].contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-contrast-hover); + --pico-underline: var(--pico-contrast-hover-underline); +} + +a[role=button] { + display: inline-block; +} + +/** + * Button + */ +button { + margin: 0; + overflow: visible; + font-family: inherit; + text-transform: none; +} + +button, +[type=submit], +[type=reset], +[type=button] { + -webkit-appearance: button; +} + +button, +[type=submit], +[type=reset], +[type=button], +[type=file]::file-selector-button, +[role=button] { + --pico-background-color: var(--pico-primary-background); + --pico-border-color: var(--pico-primary-border); + --pico-color: var(--pico-primary-inverse); + --pico-box-shadow: var(--pico-button-box-shadow, 0 0 0 rgba(0, 0, 0, 0)); + padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal); + border: var(--pico-border-width) solid var(--pico-border-color); + border-radius: var(--pico-border-radius); + outline: none; + background-color: var(--pico-background-color); + box-shadow: var(--pico-box-shadow); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + font-size: 1rem; + line-height: var(--pico-line-height); + text-align: center; + text-decoration: none; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + transition: background-color var(--pico-transition), border-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition); +} +button:is([aria-current]:not([aria-current=false])), button:is(:hover, :active, :focus), +[type=submit]:is([aria-current]:not([aria-current=false])), +[type=submit]:is(:hover, :active, :focus), +[type=reset]:is([aria-current]:not([aria-current=false])), +[type=reset]:is(:hover, :active, :focus), +[type=button]:is([aria-current]:not([aria-current=false])), +[type=button]:is(:hover, :active, :focus), +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])), +[type=file]::file-selector-button:is(:hover, :active, :focus), +[role=button]:is([aria-current]:not([aria-current=false])), +[role=button]:is(:hover, :active, :focus) { + --pico-background-color: var(--pico-primary-hover-background); + --pico-border-color: var(--pico-primary-hover-border); + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)); + --pico-color: var(--pico-primary-inverse); +} +button:focus, button:is([aria-current]:not([aria-current=false])):focus, +[type=submit]:focus, +[type=submit]:is([aria-current]:not([aria-current=false])):focus, +[type=reset]:focus, +[type=reset]:is([aria-current]:not([aria-current=false])):focus, +[type=button]:focus, +[type=button]:is([aria-current]:not([aria-current=false])):focus, +[type=file]::file-selector-button:focus, +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])):focus, +[role=button]:focus, +[role=button]:is([aria-current]:not([aria-current=false])):focus { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); +} + +[type=submit], +[type=reset], +[type=button] { + margin-bottom: var(--pico-spacing); +} + +:is(button, [type=submit], [type=button], [role=button]).secondary, +[type=reset], +[type=file]::file-selector-button { + --pico-background-color: var(--pico-secondary-background); + --pico-border-color: var(--pico-secondary-border); + --pico-color: var(--pico-secondary-inverse); + cursor: pointer; +} +:is(button, [type=submit], [type=button], [role=button]).secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=reset]:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-background-color: var(--pico-secondary-hover-background); + --pico-border-color: var(--pico-secondary-hover-border); + --pico-color: var(--pico-secondary-inverse); +} +:is(button, [type=submit], [type=button], [role=button]).secondary:focus, :is(button, [type=submit], [type=button], [role=button]).secondary:is([aria-current]:not([aria-current=false])):focus, +[type=reset]:focus, +[type=reset]:is([aria-current]:not([aria-current=false])):focus, +[type=file]::file-selector-button:focus, +[type=file]::file-selector-button:is([aria-current]:not([aria-current=false])):focus { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-secondary-focus); +} + +:is(button, [type=submit], [type=button], [role=button]).contrast { + --pico-background-color: var(--pico-contrast-background); + --pico-border-color: var(--pico-contrast-border); + --pico-color: var(--pico-contrast-inverse); +} +:is(button, [type=submit], [type=button], [role=button]).contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-background-color: var(--pico-contrast-hover-background); + --pico-border-color: var(--pico-contrast-hover-border); + --pico-color: var(--pico-contrast-inverse); +} +:is(button, [type=submit], [type=button], [role=button]).contrast:focus, :is(button, [type=submit], [type=button], [role=button]).contrast:is([aria-current]:not([aria-current=false])):focus { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-contrast-focus); +} + +:is(button, [type=submit], [type=button], [role=button]).outline, +[type=reset].outline { + --pico-background-color: transparent; + --pico-color: var(--pico-primary); + --pico-border-color: var(--pico-primary); +} +:is(button, [type=submit], [type=button], [role=button]).outline:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=reset].outline:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-background-color: transparent; + --pico-color: var(--pico-primary-hover); + --pico-border-color: var(--pico-primary-hover); +} + +:is(button, [type=submit], [type=button], [role=button]).outline.secondary, +[type=reset].outline { + --pico-color: var(--pico-secondary); + --pico-border-color: var(--pico-secondary); +} +:is(button, [type=submit], [type=button], [role=button]).outline.secondary:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), +[type=reset].outline:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-secondary-hover); + --pico-border-color: var(--pico-secondary-hover); +} + +:is(button, [type=submit], [type=button], [role=button]).outline.contrast { + --pico-color: var(--pico-contrast); + --pico-border-color: var(--pico-contrast); +} +:is(button, [type=submit], [type=button], [role=button]).outline.contrast:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + --pico-color: var(--pico-contrast-hover); + --pico-border-color: var(--pico-contrast-hover); +} + +:where(button, [type=submit], [type=reset], [type=button], [role=button])[disabled], +:where(fieldset[disabled]) :is(button, [type=submit], [type=button], [type=reset], [role=button]) { + opacity: 0.5; + pointer-events: none; +} + +/** + * Table + */ +:where(table) { + width: 100%; + border-collapse: collapse; + border-spacing: 0; + text-indent: 0; +} + +th, +td { + padding: calc(var(--pico-spacing) / 2) var(--pico-spacing); + border-bottom: var(--pico-border-width) solid var(--pico-table-border-color); + background-color: var(--pico-background-color); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + text-align: left; + text-align: start; +} + +tfoot th, +tfoot td { + border-top: var(--pico-border-width) solid var(--pico-table-border-color); + border-bottom: 0; +} + +table.striped tbody tr:nth-child(odd) th, +table.striped tbody tr:nth-child(odd) td { + background-color: var(--pico-table-row-stripped-background-color); +} + +/** + * Embedded content + */ +:where(audio, canvas, iframe, img, svg, video) { + vertical-align: middle; +} + +audio, +video { + display: inline-block; +} + +audio:not([controls]) { + display: none; + height: 0; +} + +:where(iframe) { + border-style: none; +} + +img { + max-width: 100%; + height: auto; + border-style: none; +} + +:where(svg:not([fill])) { + fill: currentColor; +} + +svg:not(:root) { + overflow: hidden; +} + +/** + * Code + */ +pre, +code, +kbd, +samp { + font-size: 0.875em; + font-family: var(--pico-font-family); +} + +pre code { + font-size: inherit; + font-family: inherit; +} + +pre { + -ms-overflow-style: scrollbar; + overflow: auto; +} + +pre, +code, +kbd { + border-radius: var(--pico-border-radius); + background: var(--pico-code-background-color); + color: var(--pico-code-color); + font-weight: var(--pico-font-weight); + line-height: initial; +} + +code, +kbd { + display: inline-block; + padding: 0.375rem; +} + +pre { + display: block; + margin-bottom: var(--pico-spacing); + overflow-x: auto; +} +pre > code { + display: block; + padding: var(--pico-spacing); + background: none; + line-height: var(--pico-line-height); +} + +kbd { + background-color: var(--pico-code-kbd-background-color); + color: var(--pico-code-kbd-color); + vertical-align: baseline; +} + +/** + * Figure + */ +figure { + display: block; + margin: 0; + padding: 0; +} +figure figcaption { + padding: calc(var(--pico-spacing) * 0.5) 0; + color: var(--pico-muted-color); +} + +/** + * Miscs + */ +hr { + height: 0; + margin: var(--pico-typography-spacing-vertical) 0; + border: 0; + border-top: 1px solid var(--pico-muted-border-color); + color: inherit; +} + +[hidden], +template { + display: none !important; +} + +canvas { + display: inline-block; +} + +/** + * Basics form elements + */ +input, +optgroup, +select, +textarea { + margin: 0; + font-size: 1rem; + line-height: var(--pico-line-height); + font-family: inherit; + letter-spacing: inherit; +} + +input { + overflow: visible; +} + +select { + text-transform: none; +} + +legend { + max-width: 100%; + padding: 0; + color: inherit; + white-space: normal; +} + +textarea { + overflow: auto; +} + +[type=checkbox], +[type=radio] { + padding: 0; +} + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +[type=search] { + -webkit-appearance: textfield; + outline-offset: -2px; +} + +[type=search]::-webkit-search-decoration { + -webkit-appearance: none; +} + +::-webkit-file-upload-button { + -webkit-appearance: button; + font: inherit; +} + +::-moz-focus-inner { + padding: 0; + border-style: none; +} + +:-moz-focusring { + outline: none; +} + +:-moz-ui-invalid { + box-shadow: none; +} + +::-ms-expand { + display: none; +} + +[type=file], +[type=range] { + padding: 0; + border-width: 0; +} + +input:not([type=checkbox], [type=radio], [type=range]) { + height: calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2); +} + +fieldset { + width: 100%; + margin: 0; + margin-bottom: var(--pico-spacing); + padding: 0; + border: 0; +} + +label, +fieldset legend { + display: block; + margin-bottom: calc(var(--pico-spacing) * 0.375); + color: var(--pico-color); + font-weight: var(--pico-form-label-font-weight, var(--pico-font-weight)); +} + +fieldset legend { + margin-bottom: calc(var(--pico-spacing) * 0.5); +} + +input:not([type=checkbox], [type=radio]), +button[type=submit], +select, +textarea { + width: 100%; +} + +input:not([type=checkbox], [type=radio], [type=range], [type=file]), +select, +textarea { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal); +} + +input, +select, +textarea { + --pico-background-color: var(--pico-form-element-background-color); + --pico-border-color: var(--pico-form-element-border-color); + --pico-color: var(--pico-form-element-color); + --pico-box-shadow: none; + border: var(--pico-border-width) solid var(--pico-border-color); + border-radius: var(--pico-border-radius); + outline: none; + background-color: var(--pico-background-color); + box-shadow: var(--pico-box-shadow); + color: var(--pico-color); + font-weight: var(--pico-font-weight); + transition: background-color var(--pico-transition), border-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition); +} + +input:not([type=submit], +[type=button], +[type=reset], +[type=checkbox], +[type=radio], +[readonly]):is(:active, :focus), +:where(select, textarea):not([readonly]):is(:active, :focus) { + --pico-background-color: var(--pico-form-element-active-background-color); +} + +input:not([type=submit], [type=button], [type=reset], [role=switch], [readonly]):is(:active, :focus), +:where(select, textarea):not([readonly]):is(:active, :focus) { + --pico-border-color: var(--pico-form-element-active-border-color); +} + +input:not([type=submit], +[type=button], +[type=reset], +[type=range], +[type=file], +[readonly]):focus, +:where(select, textarea):not([readonly]):focus { + --pico-box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-focus-color); +} + +input:not([type=submit], [type=button], [type=reset])[disabled], +select[disabled], +textarea[disabled], +label[aria-disabled=true], +:where(fieldset[disabled]) :is(input:not([type=submit], [type=button], [type=reset]), select, textarea) { + opacity: var(--pico-form-element-disabled-opacity); + pointer-events: none; +} + +label[aria-disabled=true] input[disabled] { + opacity: 1; +} + +:where(input, select, textarea):not([type=checkbox], +[type=radio], +[type=date], +[type=datetime-local], +[type=month], +[type=time], +[type=week], +[type=range])[aria-invalid] { + padding-right: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem) !important; + padding-left: var(--pico-form-element-spacing-horizontal); + padding-inline-start: var(--pico-form-element-spacing-horizontal) !important; + padding-inline-end: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem) !important; + background-position: center right 0.75rem; + background-size: 1rem auto; + background-repeat: no-repeat; +} +:where(input, select, textarea):not([type=checkbox], +[type=radio], +[type=date], +[type=datetime-local], +[type=month], +[type=time], +[type=week], +[type=range])[aria-invalid=false]:not(select) { + background-image: var(--pico-icon-valid); +} +:where(input, select, textarea):not([type=checkbox], +[type=radio], +[type=date], +[type=datetime-local], +[type=month], +[type=time], +[type=week], +[type=range])[aria-invalid=true]:not(select) { + background-image: var(--pico-icon-invalid); +} +:where(input, select, textarea)[aria-invalid=false] { + --pico-border-color: var(--pico-form-element-valid-border-color); +} +:where(input, select, textarea)[aria-invalid=false]:is(:active, :focus) { + --pico-border-color: var(--pico-form-element-valid-active-border-color) !important; +} +:where(input, select, textarea)[aria-invalid=false]:is(:active, :focus):not([type=checkbox], [type=radio]) { + --pico-box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-valid-focus-color) !important; +} +:where(input, select, textarea)[aria-invalid=true] { + --pico-border-color: var(--pico-form-element-invalid-border-color); +} +:where(input, select, textarea)[aria-invalid=true]:is(:active, :focus) { + --pico-border-color: var(--pico-form-element-invalid-active-border-color) !important; +} +:where(input, select, textarea)[aria-invalid=true]:is(:active, :focus):not([type=checkbox], [type=radio]) { + --pico-box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-invalid-focus-color) !important; +} + +[dir=rtl] :where(input, select, textarea):not([type=checkbox], [type=radio]):is([aria-invalid], [aria-invalid=true], [aria-invalid=false]) { + background-position: center left 0.75rem; +} + +input::placeholder, +input::-webkit-input-placeholder, +textarea::placeholder, +textarea::-webkit-input-placeholder, +select:invalid { + color: var(--pico-form-element-placeholder-color); + opacity: 1; +} + +input:not([type=checkbox], [type=radio]), +select, +textarea { + margin-bottom: var(--pico-spacing); +} + +select::-ms-expand { + border: 0; + background-color: transparent; +} +select:not([multiple], [size]) { + padding-right: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem); + padding-left: var(--pico-form-element-spacing-horizontal); + padding-inline-start: var(--pico-form-element-spacing-horizontal); + padding-inline-end: calc(var(--pico-form-element-spacing-horizontal) + 1.5rem); + background-image: var(--pico-icon-chevron); + background-position: center right 0.75rem; + background-size: 1rem auto; + background-repeat: no-repeat; +} +select[multiple] option:checked { + background: var(--pico-form-element-selected-background-color); + color: var(--pico-form-element-color); +} + +[dir=rtl] select:not([multiple], [size]) { + background-position: center left 0.75rem; +} + +textarea { + display: block; + resize: vertical; +} +textarea[aria-invalid] { + --pico-icon-height: calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2); + background-position: top right 0.75rem !important; + background-size: 1rem var(--pico-icon-height) !important; +} + +:where(input, select, textarea, fieldset, .grid) + small { + display: block; + width: 100%; + margin-top: calc(var(--pico-spacing) * -0.75); + margin-bottom: var(--pico-spacing); + color: var(--pico-muted-color); +} +:where(input, select, textarea, fieldset, .grid)[aria-invalid=false] + small { + color: var(--pico-ins-color); +} +:where(input, select, textarea, fieldset, .grid)[aria-invalid=true] + small { + color: var(--pico-del-color); +} + +label > :where(input, select, textarea) { + margin-top: calc(var(--pico-spacing) * 0.25); +} + +/** + * Checkboxes, Radios and Switches + */ +label:has([type=checkbox], [type=radio]) { + width: -moz-fit-content; + width: fit-content; + cursor: pointer; +} + +[type=checkbox], +[type=radio] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: 1.25em; + height: 1.25em; + margin-top: -0.125em; + margin-inline-end: 0.5em; + border-width: var(--pico-border-width); + vertical-align: middle; + cursor: pointer; +} +[type=checkbox]::-ms-check, +[type=radio]::-ms-check { + display: none; +} +[type=checkbox]:checked, [type=checkbox]:checked:active, [type=checkbox]:checked:focus, +[type=radio]:checked, +[type=radio]:checked:active, +[type=radio]:checked:focus { + --pico-background-color: var(--pico-primary-background); + --pico-border-color: var(--pico-primary-border); + background-image: var(--pico-icon-checkbox); + background-position: center; + background-size: 0.75em auto; + background-repeat: no-repeat; +} +[type=checkbox] ~ label, +[type=radio] ~ label { + display: inline-block; + margin-bottom: 0; + cursor: pointer; +} +[type=checkbox] ~ label:not(:last-of-type), +[type=radio] ~ label:not(:last-of-type) { + margin-inline-end: 1em; +} + +[type=checkbox]:indeterminate { + --pico-background-color: var(--pico-primary-background); + --pico-border-color: var(--pico-primary-border); + background-image: var(--pico-icon-minus); + background-position: center; + background-size: 0.75em auto; + background-repeat: no-repeat; +} + +[type=radio] { + border-radius: 50%; +} +[type=radio]:checked, [type=radio]:checked:active, [type=radio]:checked:focus { + --pico-background-color: var(--pico-primary-inverse); + border-width: 0.35em; + background-image: none; +} + +[type=checkbox][role=switch] { + --pico-background-color: var(--pico-switch-background-color); + --pico-color: var(--pico-switch-color); + width: 2.25em; + height: 1.25em; + border: var(--pico-border-width) solid var(--pico-border-color); + border-radius: 1.25em; + background-color: var(--pico-background-color); + line-height: 1.25em; +} +[type=checkbox][role=switch]:not([aria-invalid]) { + --pico-border-color: var(--pico-switch-background-color); +} +[type=checkbox][role=switch]:before { + display: block; + aspect-ratio: 1; + height: 100%; + border-radius: 50%; + background-color: var(--pico-color); + box-shadow: var(--pico-switch-thumb-box-shadow); + content: ""; + transition: margin 0.1s ease-in-out; +} +[type=checkbox][role=switch]:focus { + --pico-background-color: var(--pico-switch-background-color); + --pico-border-color: var(--pico-switch-background-color); +} +[type=checkbox][role=switch]:checked { + --pico-background-color: var(--pico-switch-checked-background-color); + --pico-border-color: var(--pico-switch-checked-background-color); + background-image: none; +} +[type=checkbox][role=switch]:checked::before { + margin-inline-start: calc(2.25em - 1.25em); +} +[type=checkbox][role=switch][disabled] { + --pico-background-color: var(--pico-border-color); +} + +[type=checkbox][aria-invalid=false]:checked, [type=checkbox][aria-invalid=false]:checked:active, [type=checkbox][aria-invalid=false]:checked:focus, +[type=checkbox][role=switch][aria-invalid=false]:checked, +[type=checkbox][role=switch][aria-invalid=false]:checked:active, +[type=checkbox][role=switch][aria-invalid=false]:checked:focus { + --pico-background-color: var(--pico-form-element-valid-border-color); +} +[type=checkbox]:checked[aria-invalid=true], [type=checkbox]:checked:active[aria-invalid=true], [type=checkbox]:checked:focus[aria-invalid=true], +[type=checkbox][role=switch]:checked[aria-invalid=true], +[type=checkbox][role=switch]:checked:active[aria-invalid=true], +[type=checkbox][role=switch]:checked:focus[aria-invalid=true] { + --pico-background-color: var(--pico-form-element-invalid-border-color); +} + +[type=checkbox][aria-invalid=false]:checked, [type=checkbox][aria-invalid=false]:checked:active, [type=checkbox][aria-invalid=false]:checked:focus, +[type=radio][aria-invalid=false]:checked, +[type=radio][aria-invalid=false]:checked:active, +[type=radio][aria-invalid=false]:checked:focus, +[type=checkbox][role=switch][aria-invalid=false]:checked, +[type=checkbox][role=switch][aria-invalid=false]:checked:active, +[type=checkbox][role=switch][aria-invalid=false]:checked:focus { + --pico-border-color: var(--pico-form-element-valid-border-color); +} +[type=checkbox]:checked[aria-invalid=true], [type=checkbox]:checked:active[aria-invalid=true], [type=checkbox]:checked:focus[aria-invalid=true], +[type=radio]:checked[aria-invalid=true], +[type=radio]:checked:active[aria-invalid=true], +[type=radio]:checked:focus[aria-invalid=true], +[type=checkbox][role=switch]:checked[aria-invalid=true], +[type=checkbox][role=switch]:checked:active[aria-invalid=true], +[type=checkbox][role=switch]:checked:focus[aria-invalid=true] { + --pico-border-color: var(--pico-form-element-invalid-border-color); +} + +/** + * Input type color + */ +[type=color]::-webkit-color-swatch-wrapper { + padding: 0; +} +[type=color]::-moz-focus-inner { + padding: 0; +} +[type=color]::-webkit-color-swatch { + border: 0; + border-radius: calc(var(--pico-border-radius) * 0.5); +} +[type=color]::-moz-color-swatch { + border: 0; + border-radius: calc(var(--pico-border-radius) * 0.5); +} + +/** + * Input type datetime + */ +input:not([type=checkbox], [type=radio], [type=range], [type=file]):is([type=date], [type=datetime-local], [type=month], [type=time], [type=week]) { + --pico-icon-position: 0.75rem; + --pico-icon-width: 1rem; + padding-right: calc(var(--pico-icon-width) + var(--pico-icon-position)); + background-image: var(--pico-icon-date); + background-position: center right var(--pico-icon-position); + background-size: var(--pico-icon-width) auto; + background-repeat: no-repeat; +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=time] { + background-image: var(--pico-icon-time); +} + +[type=date]::-webkit-calendar-picker-indicator, +[type=datetime-local]::-webkit-calendar-picker-indicator, +[type=month]::-webkit-calendar-picker-indicator, +[type=time]::-webkit-calendar-picker-indicator, +[type=week]::-webkit-calendar-picker-indicator { + width: var(--pico-icon-width); + margin-right: calc(var(--pico-icon-width) * -1); + margin-left: var(--pico-icon-position); + opacity: 0; +} + +@-moz-document url-prefix() { + [type=date], + [type=datetime-local], + [type=month], + [type=time], + [type=week] { + padding-right: var(--pico-form-element-spacing-horizontal) !important; + background-image: none !important; + } +} +[dir=rtl] :is([type=date], [type=datetime-local], [type=month], [type=time], [type=week]) { + text-align: right; +} + +/** + * Input type file + */ +[type=file] { + --pico-color: var(--pico-muted-color); + margin-left: calc(var(--pico-outline-width) * -1); + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) 0; + padding-left: var(--pico-outline-width); + border: 0; + border-radius: 0; + background: none; +} +[type=file]::file-selector-button { + margin-right: calc(var(--pico-spacing) / 2); + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) var(--pico-form-element-spacing-horizontal); +} +[type=file]:is(:hover, :active, :focus)::file-selector-button { + --pico-background-color: var(--pico-secondary-hover-background); + --pico-border-color: var(--pico-secondary-hover-border); +} +[type=file]:focus::file-selector-button { + --pico-box-shadow: var(--pico-button-hover-box-shadow, 0 0 0 rgba(0, 0, 0, 0)), 0 0 0 var(--pico-outline-width) var(--pico-secondary-focus); +} + +/** + * Input type range + */ +[type=range] { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: 100%; + height: 1.25rem; + background: none; +} +[type=range]::-webkit-slider-runnable-track { + width: 100%; + height: 0.375rem; + border-radius: var(--pico-border-radius); + background-color: var(--pico-range-border-color); + -webkit-transition: background-color var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), box-shadow var(--pico-transition); +} +[type=range]::-moz-range-track { + width: 100%; + height: 0.375rem; + border-radius: var(--pico-border-radius); + background-color: var(--pico-range-border-color); + -moz-transition: background-color var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), box-shadow var(--pico-transition); +} +[type=range]::-ms-track { + width: 100%; + height: 0.375rem; + border-radius: var(--pico-border-radius); + background-color: var(--pico-range-border-color); + -ms-transition: background-color var(--pico-transition), box-shadow var(--pico-transition); + transition: background-color var(--pico-transition), box-shadow var(--pico-transition); +} +[type=range]::-webkit-slider-thumb { + -webkit-appearance: none; + width: 1.25rem; + height: 1.25rem; + margin-top: -0.4375rem; + border: 2px solid var(--pico-range-thumb-border-color); + border-radius: 50%; + background-color: var(--pico-range-thumb-color); + cursor: pointer; + -webkit-transition: background-color var(--pico-transition), transform var(--pico-transition); + transition: background-color var(--pico-transition), transform var(--pico-transition); +} +[type=range]::-moz-range-thumb { + -webkit-appearance: none; + width: 1.25rem; + height: 1.25rem; + margin-top: -0.4375rem; + border: 2px solid var(--pico-range-thumb-border-color); + border-radius: 50%; + background-color: var(--pico-range-thumb-color); + cursor: pointer; + -moz-transition: background-color var(--pico-transition), transform var(--pico-transition); + transition: background-color var(--pico-transition), transform var(--pico-transition); +} +[type=range]::-ms-thumb { + -webkit-appearance: none; + width: 1.25rem; + height: 1.25rem; + margin-top: -0.4375rem; + border: 2px solid var(--pico-range-thumb-border-color); + border-radius: 50%; + background-color: var(--pico-range-thumb-color); + cursor: pointer; + -ms-transition: background-color var(--pico-transition), transform var(--pico-transition); + transition: background-color var(--pico-transition), transform var(--pico-transition); +} +[type=range]:active, [type=range]:focus-within { + --pico-range-border-color: var(--pico-range-active-border-color); + --pico-range-thumb-color: var(--pico-range-thumb-active-color); +} +[type=range]:active::-webkit-slider-thumb { + transform: scale(1.25); +} +[type=range]:active::-moz-range-thumb { + transform: scale(1.25); +} +[type=range]:active::-ms-thumb { + transform: scale(1.25); +} + +/** + * Input type search + */ +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search] { + padding-inline-start: calc(var(--pico-form-element-spacing-horizontal) + 1.75rem); + background-image: var(--pico-icon-search); + background-position: center left calc(var(--pico-form-element-spacing-horizontal) + 0.125rem); + background-size: 1rem auto; + background-repeat: no-repeat; +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid] { + padding-inline-start: calc(var(--pico-form-element-spacing-horizontal) + 1.75rem) !important; + background-position: center left 1.125rem, center right 0.75rem; +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid=false] { + background-image: var(--pico-icon-search), var(--pico-icon-valid); +} +input:not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid=true] { + background-image: var(--pico-icon-search), var(--pico-icon-invalid); +} + +[dir=rtl] :where(input):not([type=checkbox], [type=radio], [type=range], [type=file])[type=search] { + background-position: center right 1.125rem; +} +[dir=rtl] :where(input):not([type=checkbox], [type=radio], [type=range], [type=file])[type=search][aria-invalid] { + background-position: center right 1.125rem, center left 0.75rem; +} + +/** + * Accordion (
) + */ +details { + display: block; + margin-bottom: var(--pico-spacing); +} +details summary { + line-height: 1rem; + list-style-type: none; + cursor: pointer; + transition: color var(--pico-transition); +} +details summary:not([role]) { + color: var(--pico-accordion-close-summary-color); +} +details summary::-webkit-details-marker { + display: none; +} +details summary::marker { + display: none; +} +details summary::-moz-list-bullet { + list-style-type: none; +} +details summary::after { + display: block; + width: 1rem; + height: 1rem; + margin-inline-start: calc(var(--pico-spacing, 1rem) * 0.5); + float: right; + transform: rotate(-90deg); + background-image: var(--pico-icon-chevron); + background-position: right center; + background-size: 1rem auto; + background-repeat: no-repeat; + content: ""; + transition: transform var(--pico-transition); +} +details summary:focus { + outline: none; +} +details summary:focus:not([role]) { + color: var(--pico-accordion-active-summary-color); +} +details summary:focus-visible:not([role]) { + outline: var(--pico-outline-width) solid var(--pico-primary-focus); + outline-offset: calc(var(--pico-spacing, 1rem) * 0.5); + color: var(--pico-primary); +} +details summary[role=button] { + width: 100%; + text-align: left; +} +details summary[role=button]::after { + height: calc(1rem * var(--pico-line-height, 1.5)); +} +details[open] > summary { + margin-bottom: var(--pico-spacing); +} +details[open] > summary:not([role]):not(:focus) { + color: var(--pico-accordion-open-summary-color); +} +details[open] > summary::after { + transform: rotate(0); +} + +[dir=rtl] details summary { + text-align: right; +} +[dir=rtl] details summary::after { + float: left; + background-position: left center; +} + +/** + * Card (
) + */ +article { + margin-bottom: var(--pico-block-spacing-vertical); + padding: var(--pico-block-spacing-vertical) var(--pico-block-spacing-horizontal); + border-radius: var(--pico-border-radius); + background: var(--pico-card-background-color); + box-shadow: var(--pico-card-box-shadow); +} +article > header, +article > footer { + margin-right: calc(var(--pico-block-spacing-horizontal) * -1); + margin-left: calc(var(--pico-block-spacing-horizontal) * -1); + padding: calc(var(--pico-block-spacing-vertical) * 0.66) var(--pico-block-spacing-horizontal); + background-color: var(--pico-card-sectioning-background-color); +} +article > header { + margin-top: calc(var(--pico-block-spacing-vertical) * -1); + margin-bottom: var(--pico-block-spacing-vertical); + border-bottom: var(--pico-border-width) solid var(--pico-card-border-color); + border-top-right-radius: var(--pico-border-radius); + border-top-left-radius: var(--pico-border-radius); +} +article > footer { + margin-top: var(--pico-block-spacing-vertical); + margin-bottom: calc(var(--pico-block-spacing-vertical) * -1); + border-top: var(--pico-border-width) solid var(--pico-card-border-color); + border-bottom-right-radius: var(--pico-border-radius); + border-bottom-left-radius: var(--pico-border-radius); +} + +/** + * Dropdown (details.dropdown) + */ +details.dropdown { + position: relative; + border-bottom: none; +} +details.dropdown summary::after, +details.dropdown > button::after, +details.dropdown > a::after { + display: block; + width: 1rem; + height: calc(1rem * var(--pico-line-height, 1.5)); + margin-inline-start: 0.25rem; + float: right; + transform: rotate(0deg) translateX(0.2rem); + background-image: var(--pico-icon-chevron); + background-position: right center; + background-size: 1rem auto; + background-repeat: no-repeat; + content: ""; +} + +nav details.dropdown { + margin-bottom: 0; +} + +details.dropdown summary:not([role]) { + height: calc(1rem * var(--pico-line-height) + var(--pico-form-element-spacing-vertical) * 2 + var(--pico-border-width) * 2); + padding: var(--pico-form-element-spacing-vertical) var(--pico-form-element-spacing-horizontal); + border: var(--pico-border-width) solid var(--pico-form-element-border-color); + border-radius: var(--pico-border-radius); + background-color: var(--pico-form-element-background-color); + color: var(--pico-form-element-placeholder-color); + line-height: inherit; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + transition: background-color var(--pico-transition), border-color var(--pico-transition), color var(--pico-transition), box-shadow var(--pico-transition); +} +details.dropdown summary:not([role]):active, details.dropdown summary:not([role]):focus { + border-color: var(--pico-form-element-active-border-color); + background-color: var(--pico-form-element-active-background-color); +} +details.dropdown summary:not([role]):focus { + box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-form-element-focus-color); +} +details.dropdown summary:not([role]):focus-visible { + outline: none; +} +details.dropdown summary:not([role])[aria-invalid=false] { + --pico-form-element-border-color: var(--pico-form-element-valid-border-color); + --pico-form-element-active-border-color: var(--pico-form-element-valid-focus-color); + --pico-form-element-focus-color: var(--pico-form-element-valid-focus-color); +} +details.dropdown summary:not([role])[aria-invalid=true] { + --pico-form-element-border-color: var(--pico-form-element-invalid-border-color); + --pico-form-element-active-border-color: var(--pico-form-element-invalid-focus-color); + --pico-form-element-focus-color: var(--pico-form-element-invalid-focus-color); +} + +nav details.dropdown { + display: inline; + margin: calc(var(--pico-nav-element-spacing-vertical) * -1) 0; +} +nav details.dropdown summary::after { + transform: rotate(0deg) translateX(0rem); +} +nav details.dropdown summary:not([role]) { + height: calc(1rem * var(--pico-line-height) + var(--pico-nav-link-spacing-vertical) * 2); + padding: calc(var(--pico-nav-link-spacing-vertical) - var(--pico-border-width) * 2) var(--pico-nav-link-spacing-horizontal); +} +nav details.dropdown summary:not([role]):focus-visible { + box-shadow: 0 0 0 var(--pico-outline-width) var(--pico-primary-focus); +} + +details.dropdown summary + ul { + display: flex; + z-index: 99; + position: absolute; + left: 0; + flex-direction: column; + width: 100%; + min-width: -moz-fit-content; + min-width: fit-content; + margin: 0; + margin-top: var(--pico-outline-width); + padding: 0; + border: var(--pico-border-width) solid var(--pico-dropdown-border-color); + border-radius: var(--pico-border-radius); + background-color: var(--pico-dropdown-background-color); + box-shadow: var(--pico-dropdown-box-shadow); + color: var(--pico-dropdown-color); + white-space: nowrap; + opacity: 0; + transition: opacity var(--pico-transition), transform 0s ease-in-out 1s; +} +details.dropdown summary + ul[dir=rtl] { + right: 0; + left: auto; +} +details.dropdown summary + ul li { + width: 100%; + margin-bottom: 0; + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) var(--pico-form-element-spacing-horizontal); + list-style: none; +} +details.dropdown summary + ul li:first-of-type { + margin-top: calc(var(--pico-form-element-spacing-vertical) * 0.5); +} +details.dropdown summary + ul li:last-of-type { + margin-bottom: calc(var(--pico-form-element-spacing-vertical) * 0.5); +} +details.dropdown summary + ul li a { + display: block; + margin: calc(var(--pico-form-element-spacing-vertical) * -0.5) calc(var(--pico-form-element-spacing-horizontal) * -1); + padding: calc(var(--pico-form-element-spacing-vertical) * 0.5) var(--pico-form-element-spacing-horizontal); + overflow: hidden; + border-radius: 0; + color: var(--pico-dropdown-color); + text-decoration: none; + text-overflow: ellipsis; +} +details.dropdown summary + ul li a:hover, details.dropdown summary + ul li a:focus, details.dropdown summary + ul li a:active, details.dropdown summary + ul li a:focus-visible, details.dropdown summary + ul li a[aria-current]:not([aria-current=false]) { + background-color: var(--pico-dropdown-hover-background-color); +} +details.dropdown summary + ul li label { + width: 100%; +} +details.dropdown summary + ul li:has(label):hover { + background-color: var(--pico-dropdown-hover-background-color); +} + +details.dropdown[open] summary { + margin-bottom: 0; +} + +details.dropdown[open] summary + ul { + transform: scaleY(1); + opacity: 1; + transition: opacity var(--pico-transition), transform 0s ease-in-out 0s; +} + +details.dropdown[open] summary::before { + display: block; + z-index: 1; + position: fixed; + width: 100vw; + height: 100vh; + inset: 0; + background: none; + content: ""; + cursor: default; +} + +label > details.dropdown { + margin-top: calc(var(--pico-spacing) * 0.25); +} + +/** + * Group ([role="group"], [role="search"]) + */ +[role=search], +[role=group] { + display: inline-flex; + position: relative; + width: 100%; + margin-bottom: var(--pico-spacing); + border-radius: var(--pico-border-radius); + box-shadow: var(--pico-group-box-shadow, 0 0 0 rgba(0, 0, 0, 0)); + vertical-align: middle; + transition: box-shadow var(--pico-transition); +} +[role=search] > *, +[role=search] input:not([type=checkbox], [type=radio]), +[role=search] select, +[role=group] > *, +[role=group] input:not([type=checkbox], [type=radio]), +[role=group] select { + position: relative; + flex: 1 1 auto; + margin-bottom: 0; +} +[role=search] > *:not(:first-child), +[role=search] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=search] select:not(:first-child), +[role=group] > *:not(:first-child), +[role=group] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=group] select:not(:first-child) { + margin-left: 0; + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +[role=search] > *:not(:last-child), +[role=search] input:not([type=checkbox], [type=radio]):not(:last-child), +[role=search] select:not(:last-child), +[role=group] > *:not(:last-child), +[role=group] input:not([type=checkbox], [type=radio]):not(:last-child), +[role=group] select:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +[role=search] > *:focus, +[role=search] input:not([type=checkbox], [type=radio]):focus, +[role=search] select:focus, +[role=group] > *:focus, +[role=group] input:not([type=checkbox], [type=radio]):focus, +[role=group] select:focus { + z-index: 2; +} +[role=search] button:not(:first-child), +[role=search] [type=submit]:not(:first-child), +[role=search] [type=reset]:not(:first-child), +[role=search] [type=button]:not(:first-child), +[role=search] [role=button]:not(:first-child), +[role=search] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=search] select:not(:first-child), +[role=group] button:not(:first-child), +[role=group] [type=submit]:not(:first-child), +[role=group] [type=reset]:not(:first-child), +[role=group] [type=button]:not(:first-child), +[role=group] [role=button]:not(:first-child), +[role=group] input:not([type=checkbox], [type=radio]):not(:first-child), +[role=group] select:not(:first-child) { + margin-left: calc(var(--pico-border-width) * -1); +} +[role=search] button, +[role=search] [type=submit], +[role=search] [type=reset], +[role=search] [type=button], +[role=search] [role=button], +[role=group] button, +[role=group] [type=submit], +[role=group] [type=reset], +[role=group] [type=button], +[role=group] [role=button] { + width: auto; +} +@supports selector(:has(*)) { + [role=search]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus), + [role=group]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) { + --pico-group-box-shadow: var(--pico-group-box-shadow-focus-with-button); + } + [role=search]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) input:not([type=checkbox], [type=radio]), + [role=search]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) select, + [role=group]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) input:not([type=checkbox], [type=radio]), + [role=group]:has(button:focus, [type=submit]:focus, [type=button]:focus, [role=button]:focus) select { + border-color: transparent; + } + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus), + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) { + --pico-group-box-shadow: var(--pico-group-box-shadow-focus-with-input); + } + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) button, + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=submit], + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=button], + [role=search]:has(input:not([type=submit], [type=button]):focus, select:focus) [role=button], + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) button, + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=submit], + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) [type=button], + [role=group]:has(input:not([type=submit], [type=button]):focus, select:focus) [role=button] { + --pico-button-box-shadow: 0 0 0 var(--pico-border-width) var(--pico-primary-border); + --pico-button-hover-box-shadow: 0 0 0 var(--pico-border-width) var(--pico-primary-hover-border); + } + [role=search] button:focus, + [role=search] [type=submit]:focus, + [role=search] [type=reset]:focus, + [role=search] [type=button]:focus, + [role=search] [role=button]:focus, + [role=group] button:focus, + [role=group] [type=submit]:focus, + [role=group] [type=reset]:focus, + [role=group] [type=button]:focus, + [role=group] [role=button]:focus { + box-shadow: none; + } +} + +[role=search] > *:first-child { + border-top-left-radius: 5rem; + border-bottom-left-radius: 5rem; +} +[role=search] > *:last-child { + border-top-right-radius: 5rem; + border-bottom-right-radius: 5rem; +} + +/** + * Loading ([aria-busy=true]) + */ +[aria-busy=true]:not(input, select, textarea, html) { + white-space: nowrap; +} +[aria-busy=true]:not(input, select, textarea, html)::before { + display: inline-block; + width: 1em; + height: 1em; + background-image: var(--pico-icon-loading); + background-size: 1em auto; + background-repeat: no-repeat; + content: ""; + vertical-align: -0.125em; +} +[aria-busy=true]:not(input, select, textarea, html):not(:empty)::before { + margin-inline-end: calc(var(--pico-spacing) * 0.5); +} +[aria-busy=true]:not(input, select, textarea, html):empty { + text-align: center; +} + +button[aria-busy=true], +[type=submit][aria-busy=true], +[type=button][aria-busy=true], +[type=reset][aria-busy=true], +[role=button][aria-busy=true], +a[aria-busy=true] { + pointer-events: none; +} + +/** + * Modal () + */ +:root { + --pico-scrollbar-width: 0px; +} + +dialog { + display: flex; + z-index: 999; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + align-items: center; + justify-content: center; + width: inherit; + min-width: 100%; + height: inherit; + min-height: 100%; + padding: 0; + border: 0; + -webkit-backdrop-filter: var(--pico-modal-overlay-backdrop-filter); + backdrop-filter: var(--pico-modal-overlay-backdrop-filter); + background-color: var(--pico-modal-overlay-background-color); + color: var(--pico-color); +} +dialog article { + width: 100%; + max-height: calc(100vh - var(--pico-spacing) * 2); + margin: var(--pico-spacing); + overflow: auto; +} +@media (min-width: 576px) { + dialog article { + max-width: 510px; + } +} +@media (min-width: 768px) { + dialog article { + max-width: 700px; + } +} +dialog article > header > * { + margin-bottom: 0; +} +dialog article > header .close, dialog article > header :is(a, button)[rel=prev] { + margin: 0; + margin-left: var(--pico-spacing); + padding: 0; + float: right; +} +dialog article > footer { + text-align: right; +} +dialog article > footer button, +dialog article > footer [role=button] { + margin-bottom: 0; +} +dialog article > footer button:not(:first-of-type), +dialog article > footer [role=button]:not(:first-of-type) { + margin-left: calc(var(--pico-spacing) * 0.5); +} +dialog article .close, dialog article :is(a, button)[rel=prev] { + display: block; + width: 1rem; + height: 1rem; + margin-top: calc(var(--pico-spacing) * -1); + margin-bottom: var(--pico-spacing); + margin-left: auto; + border: none; + background-image: var(--pico-icon-close); + background-position: center; + background-size: auto 1rem; + background-repeat: no-repeat; + background-color: transparent; + opacity: 0.5; + transition: opacity var(--pico-transition); +} +dialog article .close:is([aria-current]:not([aria-current=false]), :hover, :active, :focus), dialog article :is(a, button)[rel=prev]:is([aria-current]:not([aria-current=false]), :hover, :active, :focus) { + opacity: 1; +} +dialog:not([open]), dialog[open=false] { + display: none; +} + +.modal-is-open { + padding-right: var(--pico-scrollbar-width, 0px); + overflow: hidden; + pointer-events: none; + touch-action: none; +} +.modal-is-open dialog { + pointer-events: auto; + touch-action: auto; +} + +:where(.modal-is-opening, .modal-is-closing) dialog, +:where(.modal-is-opening, .modal-is-closing) dialog > article { + animation-duration: 0.2s; + animation-timing-function: ease-in-out; + animation-fill-mode: both; +} +:where(.modal-is-opening, .modal-is-closing) dialog { + animation-duration: 0.8s; + animation-name: modal-overlay; +} +:where(.modal-is-opening, .modal-is-closing) dialog > article { + animation-delay: 0.2s; + animation-name: modal; +} + +.modal-is-closing dialog, +.modal-is-closing dialog > article { + animation-delay: 0s; + animation-direction: reverse; +} + +@keyframes modal-overlay { + from { + -webkit-backdrop-filter: none; + backdrop-filter: none; + background-color: transparent; + } +} +@keyframes modal { + from { + transform: translateY(-100%); + opacity: 0; + } +} +/** + * Nav + */ +:where(nav li)::before { + float: left; + content: "​"; +} + +nav, +nav ul { + display: flex; +} + +nav { + justify-content: space-between; + overflow: visible; +} +nav ol, +nav ul { + align-items: center; + margin-bottom: 0; + padding: 0; + list-style: none; +} +nav ol:first-of-type, +nav ul:first-of-type { + margin-left: calc(var(--pico-nav-element-spacing-horizontal) * -1); +} +nav ol:last-of-type, +nav ul:last-of-type { + margin-right: calc(var(--pico-nav-element-spacing-horizontal) * -1); +} +nav li { + display: inline-block; + margin: 0; + padding: var(--pico-nav-element-spacing-vertical) var(--pico-nav-element-spacing-horizontal); +} +nav li :where(a, [role=link]) { + display: inline-block; + margin: calc(var(--pico-nav-link-spacing-vertical) * -1) calc(var(--pico-nav-link-spacing-horizontal) * -1); + padding: var(--pico-nav-link-spacing-vertical) var(--pico-nav-link-spacing-horizontal); + border-radius: var(--pico-border-radius); +} +nav li :where(a, [role=link]):not(:hover) { + text-decoration: none; +} +nav li button, +nav li [role=button], +nav li [type=button], +nav li input:not([type=checkbox], [type=radio], [type=range], [type=file]), +nav li select { + height: auto; + margin-right: inherit; + margin-bottom: 0; + margin-left: inherit; + padding: calc(var(--pico-nav-link-spacing-vertical) - var(--pico-border-width) * 2) var(--pico-nav-link-spacing-horizontal); +} +nav[aria-label=breadcrumb] { + align-items: center; + justify-content: start; +} +nav[aria-label=breadcrumb] ul li:not(:first-child) { + margin-inline-start: var(--pico-nav-link-spacing-horizontal); +} +nav[aria-label=breadcrumb] ul li a { + margin: calc(var(--pico-nav-link-spacing-vertical) * -1) 0; + margin-inline-start: calc(var(--pico-nav-link-spacing-horizontal) * -1); +} +nav[aria-label=breadcrumb] ul li:not(:last-child)::after { + display: inline-block; + position: absolute; + width: calc(var(--pico-nav-link-spacing-horizontal) * 4); + margin: 0 calc(var(--pico-nav-link-spacing-horizontal) * -1); + content: var(--pico-nav-breadcrumb-divider); + color: var(--pico-muted-color); + text-align: center; + text-decoration: none; + white-space: nowrap; +} +nav[aria-label=breadcrumb] a[aria-current]:not([aria-current=false]) { + background-color: transparent; + color: inherit; + text-decoration: none; + pointer-events: none; +} + +aside nav, +aside ol, +aside ul, +aside li { + display: block; +} +aside li { + padding: calc(var(--pico-nav-element-spacing-vertical) * 0.5) var(--pico-nav-element-spacing-horizontal); +} +aside li a { + display: block; +} +aside li [role=button] { + margin: inherit; +} + +[dir=rtl] nav[aria-label=breadcrumb] ul li:not(:last-child) ::after { + content: "\\"; +} + +/** + * Progress + */ +progress { + display: inline-block; + vertical-align: baseline; +} + +progress { + -webkit-appearance: none; + -moz-appearance: none; + display: inline-block; + appearance: none; + width: 100%; + height: 0.5rem; + margin-bottom: calc(var(--pico-spacing) * 0.5); + overflow: hidden; + border: 0; + border-radius: var(--pico-border-radius); + background-color: var(--pico-progress-background-color); + color: var(--pico-progress-color); +} +progress::-webkit-progress-bar { + border-radius: var(--pico-border-radius); + background: none; +} +progress[value]::-webkit-progress-value { + background-color: var(--pico-progress-color); + -webkit-transition: inline-size var(--pico-transition); + transition: inline-size var(--pico-transition); +} +progress::-moz-progress-bar { + background-color: var(--pico-progress-color); +} +@media (prefers-reduced-motion: no-preference) { + progress:indeterminate { + background: var(--pico-progress-background-color) linear-gradient(to right, var(--pico-progress-color) 30%, var(--pico-progress-background-color) 30%) top left/150% 150% no-repeat; + animation: progress-indeterminate 1s linear infinite; + } + progress:indeterminate[value]::-webkit-progress-value { + background-color: transparent; + } + progress:indeterminate::-moz-progress-bar { + background-color: transparent; + } +} + +@media (prefers-reduced-motion: no-preference) { + [dir=rtl] progress:indeterminate { + animation-direction: reverse; + } +} + +@keyframes progress-indeterminate { + 0% { + background-position: 200% 0; + } + 100% { + background-position: -200% 0; + } +} +/** + * Tooltip ([data-tooltip]) + */ +[data-tooltip] { + position: relative; +} +[data-tooltip]:not(a, button, input) { + border-bottom: 1px dotted; + text-decoration: none; + cursor: help; +} +[data-tooltip][data-placement=top]::before, [data-tooltip][data-placement=top]::after, [data-tooltip]::before, [data-tooltip]::after { + display: block; + z-index: 99; + position: absolute; + bottom: 100%; + left: 50%; + padding: 0.25rem 0.5rem; + overflow: hidden; + transform: translate(-50%, -0.25rem); + border-radius: var(--pico-border-radius); + background: var(--pico-tooltip-background-color); + content: attr(data-tooltip); + color: var(--pico-tooltip-color); + font-style: normal; + font-weight: var(--pico-font-weight); + font-size: 0.875rem; + text-decoration: none; + text-overflow: ellipsis; + white-space: nowrap; + opacity: 0; + pointer-events: none; +} +[data-tooltip][data-placement=top]::after, [data-tooltip]::after { + padding: 0; + transform: translate(-50%, 0rem); + border-top: 0.3rem solid; + border-right: 0.3rem solid transparent; + border-left: 0.3rem solid transparent; + border-radius: 0; + background-color: transparent; + content: ""; + color: var(--pico-tooltip-background-color); +} +[data-tooltip][data-placement=bottom]::before, [data-tooltip][data-placement=bottom]::after { + top: 100%; + bottom: auto; + transform: translate(-50%, 0.25rem); +} +[data-tooltip][data-placement=bottom]:after { + transform: translate(-50%, -0.3rem); + border: 0.3rem solid transparent; + border-bottom: 0.3rem solid; +} +[data-tooltip][data-placement=left]::before, [data-tooltip][data-placement=left]::after { + top: 50%; + right: 100%; + bottom: auto; + left: auto; + transform: translate(-0.25rem, -50%); +} +[data-tooltip][data-placement=left]:after { + transform: translate(0.3rem, -50%); + border: 0.3rem solid transparent; + border-left: 0.3rem solid; +} +[data-tooltip][data-placement=right]::before, [data-tooltip][data-placement=right]::after { + top: 50%; + right: auto; + bottom: auto; + left: 100%; + transform: translate(0.25rem, -50%); +} +[data-tooltip][data-placement=right]:after { + transform: translate(-0.3rem, -50%); + border: 0.3rem solid transparent; + border-right: 0.3rem solid; +} +[data-tooltip]:focus::before, [data-tooltip]:focus::after, [data-tooltip]:hover::before, [data-tooltip]:hover::after { + opacity: 1; +} +@media (hover: hover) and (pointer: fine) { + [data-tooltip]:focus::before, [data-tooltip]:focus::after, [data-tooltip]:hover::before, [data-tooltip]:hover::after { + --pico-tooltip-slide-to: translate(-50%, -0.25rem); + transform: translate(-50%, 0.75rem); + animation-duration: 0.2s; + animation-fill-mode: forwards; + animation-name: tooltip-slide; + opacity: 0; + } + [data-tooltip]:focus::after, [data-tooltip]:hover::after { + --pico-tooltip-caret-slide-to: translate(-50%, 0rem); + transform: translate(-50%, -0.25rem); + animation-name: tooltip-caret-slide; + } + [data-tooltip][data-placement=bottom]:focus::before, [data-tooltip][data-placement=bottom]:focus::after, [data-tooltip][data-placement=bottom]:hover::before, [data-tooltip][data-placement=bottom]:hover::after { + --pico-tooltip-slide-to: translate(-50%, 0.25rem); + transform: translate(-50%, -0.75rem); + animation-name: tooltip-slide; + } + [data-tooltip][data-placement=bottom]:focus::after, [data-tooltip][data-placement=bottom]:hover::after { + --pico-tooltip-caret-slide-to: translate(-50%, -0.3rem); + transform: translate(-50%, -0.5rem); + animation-name: tooltip-caret-slide; + } + [data-tooltip][data-placement=left]:focus::before, [data-tooltip][data-placement=left]:focus::after, [data-tooltip][data-placement=left]:hover::before, [data-tooltip][data-placement=left]:hover::after { + --pico-tooltip-slide-to: translate(-0.25rem, -50%); + transform: translate(0.75rem, -50%); + animation-name: tooltip-slide; + } + [data-tooltip][data-placement=left]:focus::after, [data-tooltip][data-placement=left]:hover::after { + --pico-tooltip-caret-slide-to: translate(0.3rem, -50%); + transform: translate(0.05rem, -50%); + animation-name: tooltip-caret-slide; + } + [data-tooltip][data-placement=right]:focus::before, [data-tooltip][data-placement=right]:focus::after, [data-tooltip][data-placement=right]:hover::before, [data-tooltip][data-placement=right]:hover::after { + --pico-tooltip-slide-to: translate(0.25rem, -50%); + transform: translate(-0.75rem, -50%); + animation-name: tooltip-slide; + } + [data-tooltip][data-placement=right]:focus::after, [data-tooltip][data-placement=right]:hover::after { + --pico-tooltip-caret-slide-to: translate(-0.3rem, -50%); + transform: translate(-0.05rem, -50%); + animation-name: tooltip-caret-slide; + } +} +@keyframes tooltip-slide { + to { + transform: var(--pico-tooltip-slide-to); + opacity: 1; + } +} +@keyframes tooltip-caret-slide { + 50% { + opacity: 0; + } + to { + transform: var(--pico-tooltip-caret-slide-to); + opacity: 1; + } +} + +/** + * Accessibility & User interaction + */ +[aria-controls] { + cursor: pointer; +} + +[aria-disabled=true], +[disabled] { + cursor: not-allowed; +} + +[aria-hidden=false][hidden] { + display: initial; +} + +[aria-hidden=false][hidden]:not(:focus) { + clip: rect(0, 0, 0, 0); + position: absolute; +} + +a, +area, +button, +input, +label, +select, +summary, +textarea, +[tabindex] { + -ms-touch-action: manipulation; +} + +[dir=rtl] { + direction: rtl; +} + +/** + * Reduce Motion Features + */ +@media (prefers-reduced-motion: reduce) { + *:not([aria-busy=true]), + :not([aria-busy=true])::before, + :not([aria-busy=true])::after { + background-attachment: initial !important; + animation-duration: 1ms !important; + animation-delay: -1ms !important; + animation-iteration-count: 1 !important; + scroll-behavior: auto !important; + transition-delay: 0s !important; + transition-duration: 0s !important; + } +} \ No newline at end of file diff --git a/experiments/simple/go.mod b/experiments/simple/go.mod new file mode 100644 index 0000000..1b7b871 --- /dev/null +++ b/experiments/simple/go.mod @@ -0,0 +1,3 @@ +module simple + +go 1.25.0 diff --git a/experiments/simple/main.go b/experiments/simple/main.go new file mode 100644 index 0000000..6943207 --- /dev/null +++ b/experiments/simple/main.go @@ -0,0 +1,150 @@ +package main + +import ( + "html/template" + "io" + "log" + "net/http" +) + +// RequestData holds all the information we want to display about a request +type RequestData struct { + Method string + URL string + Protocol string + Scheme string + Host string + Path string + RawQuery string + QueryParams map[string][]string + Headers map[string][]string + Body string + HasQuery bool +} + +// collectRequestData extracts all relevant information from the HTTP request +func collectRequestData(r *http.Request) (*RequestData, error) { + body, err := io.ReadAll(r.Body) + if err != nil { + return nil, err + } + defer r.Body.Close() + + bodyString := string(body) + if len(bodyString) == 0 { + bodyString = "(empty)" + } + + data := &RequestData{ + Method: r.Method, + URL: r.URL.String(), + Protocol: r.Proto, + Scheme: r.URL.Scheme, + Host: r.Host, + Path: r.URL.Path, + RawQuery: r.URL.RawQuery, + QueryParams: r.URL.Query(), + Headers: r.Header, + Body: bodyString, + HasQuery: len(r.URL.Query()) > 0, + } + + return data, nil +} + +const echoTemplate = ` +
+
+

Request Echo

+ +
+

Request Line

+

Method:{{.Method}}

+

URL:{{.URL}}

+

Protocol:{{.Protocol}}

+
+ +
+

URL Components

+

Scheme:{{.Scheme}}

+

Host:{{.Host}}

+

Path:{{.Path}}

+

RawQuery:{{.RawQuery}}

+
+ +
+

Query Parameters

+ {{if .HasQuery}} + {{range $key, $values := .QueryParams}} + {{range $values}} +

{{$key}}:{{.}}

+ {{end}} + {{end}} + {{else}} +

No query parameters

+ {{end}} +
+ +
+

Headers

+ + + + + + {{range $name, $values := .Headers}} + + + + + {{end}} +
HeaderValue
{{$name}}{{range $i, $v := $values}}{{if $i}}, {{end}}{{$v}}{{end}}
+
+ +
+

Body

+
{{.Body}}
+
+
+
+` + +var tmpl *template.Template + +func init() { + var err error + tmpl, err = template.New("echo").Parse(echoTemplate) + if err != nil { + log.Fatal("Error parsing template:", err) + } +} + +func echoHandler(w http.ResponseWriter, r *http.Request) { + data, err := collectRequestData(r) + if err != nil { + http.Error(w, "Error reading request body", http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "text/html; charset=utf-8") + + err = tmpl.Execute(w, data) + if err != nil { + log.Printf("Error executing template: %v", err) + http.Error(w, "Error rendering response", http.StatusInternalServerError) + } +} + +func main() { + http.HandleFunc("/echo", echoHandler) + + fs := http.FileServer(http.Dir("./frontend")) + http.Handle("/", fs) + + log.Println("Starting server on http://localhost:8080") + log.Println("Echo endpoint available at http://localhost:8080/echo") + + if err := http.ListenAndServe(":8080", nil); err != nil { + log.Fatal(err) + } +}