New structure and embedding ok
- commit
- b1ebd301f7ef87cd55f96ca7add691d1a074d3f7
- author
- bnema · · 2023-09-12 17:30 UTC
- parent
- 69d1ee6
- signature
- unsigned
this diff is incomplete: 2 files are too large to show. the totals above count everything; clone the repository to read the rest.
M .gitignore +1 -0
| @@ -7,3 +7,4 @@ logs/error.log | |||
| 7 | 7 | logs/http.log | |
| 8 | 8 | logs/docker.log | |
| 9 | 9 | gordon.yml | |
| 10 | + | bun.lockb | |
| @@ -7,3 +7,4 @@ logs/error.log | |||||
| 7 | logs/http.log | 7 | logs/http.log | ||
| 8 | logs/docker.log | 8 | logs/docker.log | ||
| 9 | gordon.yml | 9 | gordon.yml | ||
| 10 | + | bun.lockb | |||
A cmd/main.go +10 -0
| @@ -0,0 +1,10 @@ | |||
| 1 | + | package main | |
| 2 | + | ||
| 3 | + | import ( | |
| 4 | + | "github.com/bnema/gordon/internal/app" | |
| 5 | + | ) | |
| 6 | + | ||
| 7 | + | func main() { | |
| 8 | + | a := app.NewApp() | |
| 9 | + | a.Start() | |
| 10 | + | } | |
| @@ -0,0 +1,10 @@ | |||||
| 1 | + | package main | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "github.com/bnema/gordon/internal/app" | |||
| 5 | + | ) | |||
| 6 | + | ||||
| 7 | + | func main() { | |||
| 8 | + | a := app.NewApp() | |||
| 9 | + | a.Start() | |||
| 10 | + | } | |||
A go.mod +21 -0
| @@ -0,0 +1,21 @@ | |||
| 1 | + | module github.com/bnema/gordon | |
| 2 | + | ||
| 3 | + | go 1.21.1 | |
| 4 | + | ||
| 5 | + | require ( | |
| 6 | + | github.com/PuerkitoBio/goquery v1.8.1 | |
| 7 | + | github.com/labstack/echo/v4 v4.11.1 | |
| 8 | + | ) | |
| 9 | + | ||
| 10 | + | require ( | |
| 11 | + | github.com/andybalholm/cascadia v1.3.1 // indirect | |
| 12 | + | github.com/labstack/gommon v0.4.0 // indirect | |
| 13 | + | github.com/mattn/go-colorable v0.1.13 // indirect | |
| 14 | + | github.com/mattn/go-isatty v0.0.19 // indirect | |
| 15 | + | github.com/valyala/bytebufferpool v1.0.0 // indirect | |
| 16 | + | github.com/valyala/fasttemplate v1.2.2 // indirect | |
| 17 | + | golang.org/x/crypto v0.11.0 // indirect | |
| 18 | + | golang.org/x/net v0.12.0 // indirect | |
| 19 | + | golang.org/x/sys v0.10.0 // indirect | |
| 20 | + | golang.org/x/text v0.11.0 // indirect | |
| 21 | + | ) | |
| @@ -0,0 +1,21 @@ | |||||
| 1 | + | module github.com/bnema/gordon | |||
| 2 | + | ||||
| 3 | + | go 1.21.1 | |||
| 4 | + | ||||
| 5 | + | require ( | |||
| 6 | + | github.com/PuerkitoBio/goquery v1.8.1 | |||
| 7 | + | github.com/labstack/echo/v4 v4.11.1 | |||
| 8 | + | ) | |||
| 9 | + | ||||
| 10 | + | require ( | |||
| 11 | + | github.com/andybalholm/cascadia v1.3.1 // indirect | |||
| 12 | + | github.com/labstack/gommon v0.4.0 // indirect | |||
| 13 | + | github.com/mattn/go-colorable v0.1.13 // indirect | |||
| 14 | + | github.com/mattn/go-isatty v0.0.19 // indirect | |||
| 15 | + | github.com/valyala/bytebufferpool v1.0.0 // indirect | |||
| 16 | + | github.com/valyala/fasttemplate v1.2.2 // indirect | |||
| 17 | + | golang.org/x/crypto v0.11.0 // indirect | |||
| 18 | + | golang.org/x/net v0.12.0 // indirect | |||
| 19 | + | golang.org/x/sys v0.10.0 // indirect | |||
| 20 | + | golang.org/x/text v0.11.0 // indirect | |||
| 21 | + | ) | |||
A go.sum +77 -0 generated file: collapsed
A internal/app/app.go +61 -0
| @@ -0,0 +1,61 @@ | |||
| 1 | + | package app | |
| 2 | + | ||
| 3 | + | import ( | |
| 4 | + | "fmt" | |
| 5 | + | "io/fs" | |
| 6 | + | ||
| 7 | + | "github.com/bnema/gordon/internal/gotemplate" | |
| 8 | + | "github.com/bnema/gordon/internal/webui" | |
| 9 | + | ) | |
| 10 | + | ||
| 11 | + | const ( | |
| 12 | + | BuildVersion = "0.0.2" | |
| 13 | + | BuildDir = "tmp" | |
| 14 | + | ) | |
| 15 | + | ||
| 16 | + | type App struct { | |
| 17 | + | TemplateFS fs.FS | |
| 18 | + | PublicFS fs.FS | |
| 19 | + | BuildVersion string | |
| 20 | + | BuildDir string | |
| 21 | + | } | |
| 22 | + | ||
| 23 | + | func (*App) GetTemplateFS() fs.FS { | |
| 24 | + | return gotemplate.TemplateFS | |
| 25 | + | } | |
| 26 | + | ||
| 27 | + | func (*App) GetPublicFS() fs.FS { | |
| 28 | + | return webui.PublicFS | |
| 29 | + | } | |
| 30 | + | ||
| 31 | + | func (*App) GetBuildVersion() string { | |
| 32 | + | return BuildVersion | |
| 33 | + | } | |
| 34 | + | ||
| 35 | + | func (*App) GetBuildDir() string { | |
| 36 | + | return BuildDir | |
| 37 | + | } | |
| 38 | + | ||
| 39 | + | func NewApp() *App { | |
| 40 | + | return &App{ | |
| 41 | + | TemplateFS: gotemplate.TemplateFS, | |
| 42 | + | PublicFS: webui.PublicFS, | |
| 43 | + | BuildVersion: BuildVersion, | |
| 44 | + | BuildDir: BuildDir, | |
| 45 | + | } | |
| 46 | + | } | |
| 47 | + | ||
| 48 | + | func (a *App) Start() { | |
| 49 | + | fmt.Println("Starting app") | |
| 50 | + | ||
| 51 | + | // LS in the template directory | |
| 52 | + | entries, err := fs.ReadDir(a.TemplateFS, ".") // List the root directory | |
| 53 | + | if err != nil { | |
| 54 | + | fmt.Println("Error reading directory:", err) | |
| 55 | + | return | |
| 56 | + | } | |
| 57 | + | ||
| 58 | + | for _, entry := range entries { | |
| 59 | + | fmt.Println(entry.Name()) | |
| 60 | + | } | |
| 61 | + | } | |
| @@ -0,0 +1,61 @@ | |||||
| 1 | + | package app | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "fmt" | |||
| 5 | + | "io/fs" | |||
| 6 | + | ||||
| 7 | + | "github.com/bnema/gordon/internal/gotemplate" | |||
| 8 | + | "github.com/bnema/gordon/internal/webui" | |||
| 9 | + | ) | |||
| 10 | + | ||||
| 11 | + | const ( | |||
| 12 | + | BuildVersion = "0.0.2" | |||
| 13 | + | BuildDir = "tmp" | |||
| 14 | + | ) | |||
| 15 | + | ||||
| 16 | + | type App struct { | |||
| 17 | + | TemplateFS fs.FS | |||
| 18 | + | PublicFS fs.FS | |||
| 19 | + | BuildVersion string | |||
| 20 | + | BuildDir string | |||
| 21 | + | } | |||
| 22 | + | ||||
| 23 | + | func (*App) GetTemplateFS() fs.FS { | |||
| 24 | + | return gotemplate.TemplateFS | |||
| 25 | + | } | |||
| 26 | + | ||||
| 27 | + | func (*App) GetPublicFS() fs.FS { | |||
| 28 | + | return webui.PublicFS | |||
| 29 | + | } | |||
| 30 | + | ||||
| 31 | + | func (*App) GetBuildVersion() string { | |||
| 32 | + | return BuildVersion | |||
| 33 | + | } | |||
| 34 | + | ||||
| 35 | + | func (*App) GetBuildDir() string { | |||
| 36 | + | return BuildDir | |||
| 37 | + | } | |||
| 38 | + | ||||
| 39 | + | func NewApp() *App { | |||
| 40 | + | return &App{ | |||
| 41 | + | TemplateFS: gotemplate.TemplateFS, | |||
| 42 | + | PublicFS: webui.PublicFS, | |||
| 43 | + | BuildVersion: BuildVersion, | |||
| 44 | + | BuildDir: BuildDir, | |||
| 45 | + | } | |||
| 46 | + | } | |||
| 47 | + | ||||
| 48 | + | func (a *App) Start() { | |||
| 49 | + | fmt.Println("Starting app") | |||
| 50 | + | ||||
| 51 | + | // LS in the template directory | |||
| 52 | + | entries, err := fs.ReadDir(a.TemplateFS, ".") // List the root directory | |||
| 53 | + | if err != nil { | |||
| 54 | + | fmt.Println("Error reading directory:", err) | |||
| 55 | + | return | |||
| 56 | + | } | |||
| 57 | + | ||||
| 58 | + | for _, entry := range entries { | |||
| 59 | + | fmt.Println(entry.Name()) | |||
| 60 | + | } | |||
| 61 | + | } | |||
A internal/gotemplate/embed.go +13 -0
| @@ -0,0 +1,13 @@ | |||
| 1 | + | package gotemplate | |
| 2 | + | ||
| 3 | + | import ( | |
| 4 | + | "embed" | |
| 5 | + | ||
| 6 | + | "github.com/labstack/echo/v4" | |
| 7 | + | ) | |
| 8 | + | ||
| 9 | + | // Embedding templates directories | |
| 10 | + | ||
| 11 | + | //go:embed models/* | |
| 12 | + | var template embed.FS | |
| 13 | + | var TemplateFS = echo.MustSubFS(template, "models") | |
| @@ -0,0 +1,13 @@ | |||||
| 1 | + | package gotemplate | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "embed" | |||
| 5 | + | ||||
| 6 | + | "github.com/labstack/echo/v4" | |||
| 7 | + | ) | |||
| 8 | + | ||||
| 9 | + | // Embedding templates directories | |||
| 10 | + | ||||
| 11 | + | //go:embed models/* | |||
| 12 | + | var template embed.FS | |||
| 13 | + | var TemplateFS = echo.MustSubFS(template, "models") | |||
A internal/gotemplate/models/html/admin/dashboard.gohtml +9 -0
| @@ -0,0 +1,9 @@ | |||
| 1 | + | <div id="dashboard"> | |
| 2 | + | <h1 | |
| 3 | + | class="text-5xl fw100 animate-bounce-alt animate-count-infinite animate-duration-1s" | |
| 4 | + | > | |
| 5 | + | Hello World from dashboard.html | |
| 6 | + | </h1> | |
| 7 | + | <!-- We load Chart.js here to avoid loading it in every page end when all the rest is loaded --> | |
| 8 | + | <script src="libs/chart.js"></script> | |
| 9 | + | </div> | |
| @@ -0,0 +1,9 @@ | |||||
| 1 | + | <div id="dashboard"> | |||
| 2 | + | <h1 | |||
| 3 | + | class="text-5xl fw100 animate-bounce-alt animate-count-infinite animate-duration-1s" | |||
| 4 | + | > | |||
| 5 | + | Hello World from dashboard.html | |||
| 6 | + | </h1> | |||
| 7 | + | <!-- We load Chart.js here to avoid loading it in every page end when all the rest is loaded --> | |||
| 8 | + | <script src="libs/chart.js"></script> | |||
| 9 | + | </div> | |||
A internal/gotemplate/models/html/admin/index.gohtml +124 -0
| @@ -0,0 +1,124 @@ | |||
| 1 | + | <!-- @format --> | |
| 2 | + | ||
| 3 | + | <!DOCTYPE html> | |
| 4 | + | <html lang="en"> | |
| 5 | + | <head> | |
| 6 | + | <meta charset="UTF-8" /> | |
| 7 | + | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| 8 | + | <title>{{ .header.meta.title }}</title> | |
| 9 | + | <meta name="description" content="{{ .Header.Meta.Description }}" /> | |
| 10 | + | <meta name="keywords" content="{{ .Header.Meta.Keywords }}" /> | |
| 11 | + | <!-- Custom CSS + Tailwind --> | |
| 12 | + | <link rel="stylesheet" href="/assets/css/tailwind.css" /> | |
| 13 | + | <!-- Iconoir --> | |
| 14 | + | <link rel="stylesheet" href="/libs/iconoir.css" /> | |
| 15 | + | <!-- Alpine --> | |
| 16 | + | <script src="/libs/alpine.min.js"></script> | |
| 17 | + | <!-- HTMX min js --> | |
| 18 | + | <script src="/libs/htmx.min.js"></script> | |
| 19 | + | <!-- HTMX SSE --> | |
| 20 | + | <script src="/libs/htmx-sse.js"></script> | |
| 21 | + | <!-- Custom JS from assets/js --> | |
| 22 | + | <script src="assets/js/custom.js"></script> | |
| 23 | + | </head> | |
| 24 | + | <body class="IBMPlexSans bg-zinc-200 md:p-8 flex"> | |
| 25 | + | <!-- Left Menu --> | |
| 26 | + | <div class="w-1/5 flex flex-col space-evenly"> | |
| 27 | + | <!-- Logo --> | |
| 28 | + | <div id="logo-mascot-leftnav" class="flex justify-center p-4"> | |
| 29 | + | <div class="circle-shadow flex justify-center w-100"> | |
| 30 | + | <img | |
| 31 | + | src="/assets/imgs/gordon-mascot-hq-trsp.png" | |
| 32 | + | alt="logo" | |
| 33 | + | class="sm:h-24 h-32 xl:h-48" | |
| 34 | + | /> | |
| 35 | + | </div> | |
| 36 | + | </div> | |
| 37 | + | <!-- Site Name + Version --> | |
| 38 | + | <div | |
| 39 | + | class="p-4 flex flex-col bg-gordonmascot-lblue rounded-lg shadow space-y-4" | |
| 40 | + | > | |
| 41 | + | <div class="w-full flex justify-center"> | |
| 42 | + | <h1 | |
| 43 | + | class="gordon-title text-2xl lg:text-4xl xl:text-5xl text-gordonmascot-hblue tracking-tighter" | |
| 44 | + | > | |
| 45 | + | Gordon | |
| 46 | + | </h1> | |
| 47 | + | <span class="gordon-v-subtitle text-gordonmascot-mblue text-sm" | |
| 48 | + | >v0.0.1</span | |
| 49 | + | > | |
| 50 | + | </div> | |
| 51 | + | <!--(Navigation) --> | |
| 52 | + | <div id="menu-leftnav" class="w-full"> | |
| 53 | + | <ul | |
| 54 | + | class="flex flex-col md:space-y-6 md:py-8 font-semibold text-gray-100 text-lg md:text-2xl md:pl-4" | |
| 55 | + | > | |
| 56 | + | <li class="flex items-center"> | |
| 57 | + | <i class="iconoir-dashboard-speed mr-2 md:text-3xl"></i> | |
| 58 | + | <a href="index.html">Dashboard</a> | |
| 59 | + | </li> | |
| 60 | + | <li class="flex items-center"> | |
| 61 | + | <i class="iconoir-server mr-2 md:text-3xl"></i> | |
| 62 | + | <a href="#manager">Manager</a> | |
| 63 | + | </li> | |
| 64 | + | <li class="flex items-center"> | |
| 65 | + | <i class="iconoir-community mr-2 md:text-3xl"></i> | |
| 66 | + | <a href="#users">Users</a> | |
| 67 | + | </li> | |
| 68 | + | <li class="flex items-center"> | |
| 69 | + | <i class="iconoir-database-settings mr-2 md:text-3xl"></i> | |
| 70 | + | <a href="#gordon-settings">Settings</a> | |
| 71 | + | </li> | |
| 72 | + | </ul> | |
| 73 | + | </div> | |
| 74 | + | ||
| 75 | + | <div class="w-full h-24 bg-gordonmascot-mblue rounded-lg"></div> | |
| 76 | + | <!-- Mock menu item --> | |
| 77 | + | </div> | |
| 78 | + | </div> | |
| 79 | + | ||
| 80 | + | <!-- Main Content including the navbar --> | |
| 81 | + | <div class="flex-1 flex flex-col md:pt-10 space-y-4 ml-4"> | |
| 82 | + | <!-- Search Nav within the main content --> | |
| 83 | + | <div class="mb-4 flex justify-end"> | |
| 84 | + | <div class="w-72 h-10 bg-gray-300 rounded-lg"> | |
| 85 | + | <!-- Search input with iconir search --> | |
| 86 | + | <div class="flex justify-between items-center h-full px-2"> | |
| 87 | + | <input | |
| 88 | + | type="text" | |
| 89 | + | class="w-full h-full bg-transparent outline-none" | |
| 90 | + | placeholder="Search" | |
| 91 | + | /> | |
| 92 | + | <i class="iconoir-search"></i> | |
| 93 | + | </div> | |
| 94 | + | </div> | |
| 95 | + | <!-- Mock search or other element --> | |
| 96 | + | </div> | |
| 97 | + | ||
| 98 | + | <!-- Cards section --> | |
| 99 | + | <div class="flex space-x-4 flex-grow"> | |
| 100 | + | <!-- Main Card on the Left --> | |
| 101 | + | <div class="w-4/6 bg-white p-4 rounded-md shadow mb-4"> | |
| 102 | + | <div class="w-full rounded-sm bg-gray-300"></div> | |
| 103 | + | <!-- Mock main card --> | |
| 104 | + | </div> | |
| 105 | + | ||
| 106 | + | <!-- Two Cards on the Right --> | |
| 107 | + | <div class="w-2/6 flex flex-col flex-justify-start"> | |
| 108 | + | <div class="bg-white p-4 rounded-md shadow mb-4"> | |
| 109 | + | <div class="w-full h-44 rounded-sm bg-gray-300"></div> | |
| 110 | + | <!-- Mock card --> | |
| 111 | + | </div> | |
| 112 | + | <div class="bg-white p-4 rounded-md shadow mb-4"> | |
| 113 | + | <div class="w-full h-44 rounded-sm bg-gray-300"></div> | |
| 114 | + | <!-- Mock card --> | |
| 115 | + | </div> | |
| 116 | + | <div class="bg-white p-4 rounded-md shadow mb-4"> | |
| 117 | + | <div class="w-full h-44 rounded-sm bg-gray-300"></div> | |
| 118 | + | <!-- Mock card --> | |
| 119 | + | </div> | |
| 120 | + | </div> | |
| 121 | + | </div> | |
| 122 | + | </div> | |
| 123 | + | </body> | |
| 124 | + | </html> | |
| @@ -0,0 +1,124 @@ | |||||
| 1 | + | <!-- @format --> | |||
| 2 | + | ||||
| 3 | + | <!DOCTYPE html> | |||
| 4 | + | <html lang="en"> | |||
| 5 | + | <head> | |||
| 6 | + | <meta charset="UTF-8" /> | |||
| 7 | + | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |||
| 8 | + | <title>{{ .header.meta.title }}</title> | |||
| 9 | + | <meta name="description" content="{{ .Header.Meta.Description }}" /> | |||
| 10 | + | <meta name="keywords" content="{{ .Header.Meta.Keywords }}" /> | |||
| 11 | + | <!-- Custom CSS + Tailwind --> | |||
| 12 | + | <link rel="stylesheet" href="/assets/css/tailwind.css" /> | |||
| 13 | + | <!-- Iconoir --> | |||
| 14 | + | <link rel="stylesheet" href="/libs/iconoir.css" /> | |||
| 15 | + | <!-- Alpine --> | |||
| 16 | + | <script src="/libs/alpine.min.js"></script> | |||
| 17 | + | <!-- HTMX min js --> | |||
| 18 | + | <script src="/libs/htmx.min.js"></script> | |||
| 19 | + | <!-- HTMX SSE --> | |||
| 20 | + | <script src="/libs/htmx-sse.js"></script> | |||
| 21 | + | <!-- Custom JS from assets/js --> | |||
| 22 | + | <script src="assets/js/custom.js"></script> | |||
| 23 | + | </head> | |||
| 24 | + | <body class="IBMPlexSans bg-zinc-200 md:p-8 flex"> | |||
| 25 | + | <!-- Left Menu --> | |||
| 26 | + | <div class="w-1/5 flex flex-col space-evenly"> | |||
| 27 | + | <!-- Logo --> | |||
| 28 | + | <div id="logo-mascot-leftnav" class="flex justify-center p-4"> | |||
| 29 | + | <div class="circle-shadow flex justify-center w-100"> | |||
| 30 | + | <img | |||
| 31 | + | src="/assets/imgs/gordon-mascot-hq-trsp.png" | |||
| 32 | + | alt="logo" | |||
| 33 | + | class="sm:h-24 h-32 xl:h-48" | |||
| 34 | + | /> | |||
| 35 | + | </div> | |||
| 36 | + | </div> | |||
| 37 | + | <!-- Site Name + Version --> | |||
| 38 | + | <div | |||
| 39 | + | class="p-4 flex flex-col bg-gordonmascot-lblue rounded-lg shadow space-y-4" | |||
| 40 | + | > | |||
| 41 | + | <div class="w-full flex justify-center"> | |||
| 42 | + | <h1 | |||
| 43 | + | class="gordon-title text-2xl lg:text-4xl xl:text-5xl text-gordonmascot-hblue tracking-tighter" | |||
| 44 | + | > | |||
| 45 | + | Gordon | |||
| 46 | + | </h1> | |||
| 47 | + | <span class="gordon-v-subtitle text-gordonmascot-mblue text-sm" | |||
| 48 | + | >v0.0.1</span | |||
| 49 | + | > | |||
| 50 | + | </div> | |||
| 51 | + | <!--(Navigation) --> | |||
| 52 | + | <div id="menu-leftnav" class="w-full"> | |||
| 53 | + | <ul | |||
| 54 | + | class="flex flex-col md:space-y-6 md:py-8 font-semibold text-gray-100 text-lg md:text-2xl md:pl-4" | |||
| 55 | + | > | |||
| 56 | + | <li class="flex items-center"> | |||
| 57 | + | <i class="iconoir-dashboard-speed mr-2 md:text-3xl"></i> | |||
| 58 | + | <a href="index.html">Dashboard</a> | |||
| 59 | + | </li> | |||
| 60 | + | <li class="flex items-center"> | |||
| 61 | + | <i class="iconoir-server mr-2 md:text-3xl"></i> | |||
| 62 | + | <a href="#manager">Manager</a> | |||
| 63 | + | </li> | |||
| 64 | + | <li class="flex items-center"> | |||
| 65 | + | <i class="iconoir-community mr-2 md:text-3xl"></i> | |||
| 66 | + | <a href="#users">Users</a> | |||
| 67 | + | </li> | |||
| 68 | + | <li class="flex items-center"> | |||
| 69 | + | <i class="iconoir-database-settings mr-2 md:text-3xl"></i> | |||
| 70 | + | <a href="#gordon-settings">Settings</a> | |||
| 71 | + | </li> | |||
| 72 | + | </ul> | |||
| 73 | + | </div> | |||
| 74 | + | ||||
| 75 | + | <div class="w-full h-24 bg-gordonmascot-mblue rounded-lg"></div> | |||
| 76 | + | <!-- Mock menu item --> | |||
| 77 | + | </div> | |||
| 78 | + | </div> | |||
| 79 | + | ||||
| 80 | + | <!-- Main Content including the navbar --> | |||
| 81 | + | <div class="flex-1 flex flex-col md:pt-10 space-y-4 ml-4"> | |||
| 82 | + | <!-- Search Nav within the main content --> | |||
| 83 | + | <div class="mb-4 flex justify-end"> | |||
| 84 | + | <div class="w-72 h-10 bg-gray-300 rounded-lg"> | |||
| 85 | + | <!-- Search input with iconir search --> | |||
| 86 | + | <div class="flex justify-between items-center h-full px-2"> | |||
| 87 | + | <input | |||
| 88 | + | type="text" | |||
| 89 | + | class="w-full h-full bg-transparent outline-none" | |||
| 90 | + | placeholder="Search" | |||
| 91 | + | /> | |||
| 92 | + | <i class="iconoir-search"></i> | |||
| 93 | + | </div> | |||
| 94 | + | </div> | |||
| 95 | + | <!-- Mock search or other element --> | |||
| 96 | + | </div> | |||
| 97 | + | ||||
| 98 | + | <!-- Cards section --> | |||
| 99 | + | <div class="flex space-x-4 flex-grow"> | |||
| 100 | + | <!-- Main Card on the Left --> | |||
| 101 | + | <div class="w-4/6 bg-white p-4 rounded-md shadow mb-4"> | |||
| 102 | + | <div class="w-full rounded-sm bg-gray-300"></div> | |||
| 103 | + | <!-- Mock main card --> | |||
| 104 | + | </div> | |||
| 105 | + | ||||
| 106 | + | <!-- Two Cards on the Right --> | |||
| 107 | + | <div class="w-2/6 flex flex-col flex-justify-start"> | |||
| 108 | + | <div class="bg-white p-4 rounded-md shadow mb-4"> | |||
| 109 | + | <div class="w-full h-44 rounded-sm bg-gray-300"></div> | |||
| 110 | + | <!-- Mock card --> | |||
| 111 | + | </div> | |||
| 112 | + | <div class="bg-white p-4 rounded-md shadow mb-4"> | |||
| 113 | + | <div class="w-full h-44 rounded-sm bg-gray-300"></div> | |||
| 114 | + | <!-- Mock card --> | |||
| 115 | + | </div> | |||
| 116 | + | <div class="bg-white p-4 rounded-md shadow mb-4"> | |||
| 117 | + | <div class="w-full h-44 rounded-sm bg-gray-300"></div> | |||
| 118 | + | <!-- Mock card --> | |||
| 119 | + | </div> | |||
| 120 | + | </div> | |||
| 121 | + | </div> | |||
| 122 | + | </div> | |||
| 123 | + | </body> | |||
| 124 | + | </html> | |||
A internal/gotemplate/models/html/admin/install.gohtml +137 -0
| @@ -0,0 +1,137 @@ | |||
| 1 | + | <!DOCTYPE html> | |
| 2 | + | <html lang="en"> | |
| 3 | + | <head> | |
| 4 | + | <meta charset="UTF-8" /> | |
| 5 | + | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| 6 | + | <title>{{ .header.meta.title }}</title> | |
| 7 | + | <meta name="description" content="{{ .Header.Meta.Description }}" /> | |
| 8 | + | <meta name="keywords" content="{{ .Header.Meta.Keywords }}" /> | |
| 9 | + | <!-- Custom CSS + Tailwind --> | |
| 10 | + | <link rel="stylesheet" href="/assets/css/tailwind.css" /> | |
| 11 | + | <!-- Iconoir --> | |
| 12 | + | <link rel="stylesheet" href="/libs/iconoir.css" /> | |
| 13 | + | <!-- Alpine --> | |
| 14 | + | <script src="/libs/alpine.min.js"></script> | |
| 15 | + | <!-- HTMX min js --> | |
| 16 | + | <script src="/libs/htmx.min.js"></script> | |
| 17 | + | <!-- HTMX SSE --> | |
| 18 | + | <script src="/libs/htmx-sse.js"></script> | |
| 19 | + | <!-- Custom JS from assets/js --> | |
| 20 | + | <script src="/assets/js/custom.js"></script> | |
| 21 | + | </head> | |
| 22 | + | ||
| 23 | + | <body | |
| 24 | + | class="IBMPlexSans bg-zinc-200 md:p-8 flex flex-col items-center" | |
| 25 | + | hx-boost="true" | |
| 26 | + | > | |
| 27 | + | <!-- Logo and Title --> | |
| 28 | + | <div | |
| 29 | + | id="logo-mascot" | |
| 30 | + | class="flex flex-col justify-center items-center p-4 mb-4" | |
| 31 | + | > | |
| 32 | + | <div class="circle-shadow flex justify-center w-100"> | |
| 33 | + | <img | |
| 34 | + | src="/assets/imgs/gordon-mascot-hq-trsp.png" | |
| 35 | + | alt="logo" | |
| 36 | + | class="sm:h-24 h-32 xl:h-48" | |
| 37 | + | /> | |
| 38 | + | </div> | |
| 39 | + | <div class="flex justify-center mt-4"> | |
| 40 | + | <h1 | |
| 41 | + | class="gordon-title text-2xl lg:text-4xl xl:text-5xl text-gordonmascot-hblue tracking-tighter" | |
| 42 | + | > | |
| 43 | + | Gordon | |
| 44 | + | </h1> | |
| 45 | + | <span class="gordon-v-subtitle text-gordonmascot-mblue text-sm ml-2" | |
| 46 | + | >v0.0.1</span | |
| 47 | + | > | |
| 48 | + | </div> | |
| 49 | + | </div> | |
| 50 | + | ||
| 51 | + | <!-- Main Content --> | |
| 52 | + | <div class="bg-white p-4 rounded-md shadow mb-4 w-2/3"> | |
| 53 | + | <!-- Install Traefik --> | |
| 54 | + | <div id="install-traefik"> | |
| 55 | + | <div class="flex flex-col items-center"> | |
| 56 | + | <h2 class="text-2xl font-semibold text-gray-800"> | |
| 57 | + | 1 - Install Traefik | |
| 58 | + | </h2> | |
| 59 | + | <!-- Dual view left : install procedure / right : SSE log installation --> | |
| 60 | + | <div class="flex flex-col md:flex-row justify-items-center w-full"> | |
| 61 | + | <!-- Left --> | |
| 62 | + | <div class="w-full md:w-1/2 p-4"> | |
| 63 | + | <form | |
| 64 | + | id="install-traefik-form" | |
| 65 | + | action="/admin/install/traefik" | |
| 66 | + | method="POST" | |
| 67 | + | hx-post="/admin/install/traefik" | |
| 68 | + | hx-swap="outerHTML" | |
| 69 | + | > | |
| 70 | + | <h2 class="">1.1 - Set your top domain name</h2> | |
| 71 | + | <input | |
| 72 | + | type="text" | |
| 73 | + | name="topdomain" | |
| 74 | + | id="topdomain" | |
| 75 | + | class="w-full py-2 px-4 my-2 border border-gray-300 rounded-md" | |
| 76 | + | placeholder="example.com" | |
| 77 | + | /> | |
| 78 | + | <h2>1.2 - Set your admin email (a reachable one)</h2> | |
| 79 | + | <input | |
| 80 | + | type="text" | |
| 81 | + | name="adminemail" | |
| 82 | + | id="adminemail" | |
| 83 | + | class="w-full p-2 border border-gray-300 rounded-md" | |
| 84 | + | placeholder="admin@example.com" | |
| 85 | + | /> | |
| 86 | + | <button | |
| 87 | + | type="submit" | |
| 88 | + | class="w-full p-2 bg-gordonmascot-hblue text-slate-100 rounded-md mt-4" | |
| 89 | + | > | |
| 90 | + | Save & Install Traefik | |
| 91 | + | </button> | |
| 92 | + | </form> | |
| 93 | + | </div> | |
| 94 | + | <!-- Right --> | |
| 95 | + | <div class="w-full md:w-1/2 p-4 text-slate-100"> | |
| 96 | + | <div | |
| 97 | + | class="flex flex-col items-center bg-gordonmascot-hblue rounded-md" | |
| 98 | + | > | |
| 99 | + | <div class="w-full h-64 overflow-y-scroll-auto p-4"> | |
| 100 | + | <div | |
| 101 | + | class="flex flex-col space-y-2" | |
| 102 | + | hx-ext="sse" | |
| 103 | + | sse-connect="/admin/install/traefik/sse" | |
| 104 | + | > | |
| 105 | + | <!-- One item --> | |
| 106 | + | <div class="flex flex-row items-center"> | |
| 107 | + | <span class="">[INFO]</span> | |
| 108 | + | <span class="">Traefik installed</span> | |
| 109 | + | </div> | |
| 110 | + | <!-- One item --> | |
| 111 | + | <div class="flex flex-row items-center"> | |
| 112 | + | <span class="">[INFO]</span> | |
| 113 | + | <span class="ml-2">Traefik started</span> | |
| 114 | + | </div> | |
| 115 | + | <!-- One item --> | |
| 116 | + | <div class="flex flex-row items-center"> | |
| 117 | + | <span class="">[INFO]</span> | |
| 118 | + | <span class="ml-2" | |
| 119 | + | >Traefik configuration file created</span | |
| 120 | + | > | |
| 121 | + | </div> | |
| 122 | + | <!-- One item --> | |
| 123 | + | <div class="flex flex-row items-center"> | |
| 124 | + | <span class="">[INFO]</span> | |
| 125 | + | <span class="">Traefik configuration file updated</span> | |
| 126 | + | </div> | |
| 127 | + | </div> | |
| 128 | + | </div> | |
| 129 | + | </div> | |
| 130 | + | </div> | |
| 131 | + | </div> | |
| 132 | + | </div> | |
| 133 | + | </div> | |
| 134 | + | <!-- End Install Traefik --> | |
| 135 | + | </div> | |
| 136 | + | </body> | |
| 137 | + | </html> | |
| @@ -0,0 +1,137 @@ | |||||
| 1 | + | <!DOCTYPE html> | |||
| 2 | + | <html lang="en"> | |||
| 3 | + | <head> | |||
| 4 | + | <meta charset="UTF-8" /> | |||
| 5 | + | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |||
| 6 | + | <title>{{ .header.meta.title }}</title> | |||
| 7 | + | <meta name="description" content="{{ .Header.Meta.Description }}" /> | |||
| 8 | + | <meta name="keywords" content="{{ .Header.Meta.Keywords }}" /> | |||
| 9 | + | <!-- Custom CSS + Tailwind --> | |||
| 10 | + | <link rel="stylesheet" href="/assets/css/tailwind.css" /> | |||
| 11 | + | <!-- Iconoir --> | |||
| 12 | + | <link rel="stylesheet" href="/libs/iconoir.css" /> | |||
| 13 | + | <!-- Alpine --> | |||
| 14 | + | <script src="/libs/alpine.min.js"></script> | |||
| 15 | + | <!-- HTMX min js --> | |||
| 16 | + | <script src="/libs/htmx.min.js"></script> | |||
| 17 | + | <!-- HTMX SSE --> | |||
| 18 | + | <script src="/libs/htmx-sse.js"></script> | |||
| 19 | + | <!-- Custom JS from assets/js --> | |||
| 20 | + | <script src="/assets/js/custom.js"></script> | |||
| 21 | + | </head> | |||
| 22 | + | ||||
| 23 | + | <body | |||
| 24 | + | class="IBMPlexSans bg-zinc-200 md:p-8 flex flex-col items-center" | |||
| 25 | + | hx-boost="true" | |||
| 26 | + | > | |||
| 27 | + | <!-- Logo and Title --> | |||
| 28 | + | <div | |||
| 29 | + | id="logo-mascot" | |||
| 30 | + | class="flex flex-col justify-center items-center p-4 mb-4" | |||
| 31 | + | > | |||
| 32 | + | <div class="circle-shadow flex justify-center w-100"> | |||
| 33 | + | <img | |||
| 34 | + | src="/assets/imgs/gordon-mascot-hq-trsp.png" | |||
| 35 | + | alt="logo" | |||
| 36 | + | class="sm:h-24 h-32 xl:h-48" | |||
| 37 | + | /> | |||
| 38 | + | </div> | |||
| 39 | + | <div class="flex justify-center mt-4"> | |||
| 40 | + | <h1 | |||
| 41 | + | class="gordon-title text-2xl lg:text-4xl xl:text-5xl text-gordonmascot-hblue tracking-tighter" | |||
| 42 | + | > | |||
| 43 | + | Gordon | |||
| 44 | + | </h1> | |||
| 45 | + | <span class="gordon-v-subtitle text-gordonmascot-mblue text-sm ml-2" | |||
| 46 | + | >v0.0.1</span | |||
| 47 | + | > | |||
| 48 | + | </div> | |||
| 49 | + | </div> | |||
| 50 | + | ||||
| 51 | + | <!-- Main Content --> | |||
| 52 | + | <div class="bg-white p-4 rounded-md shadow mb-4 w-2/3"> | |||
| 53 | + | <!-- Install Traefik --> | |||
| 54 | + | <div id="install-traefik"> | |||
| 55 | + | <div class="flex flex-col items-center"> | |||
| 56 | + | <h2 class="text-2xl font-semibold text-gray-800"> | |||
| 57 | + | 1 - Install Traefik | |||
| 58 | + | </h2> | |||
| 59 | + | <!-- Dual view left : install procedure / right : SSE log installation --> | |||
| 60 | + | <div class="flex flex-col md:flex-row justify-items-center w-full"> | |||
| 61 | + | <!-- Left --> | |||
| 62 | + | <div class="w-full md:w-1/2 p-4"> | |||
| 63 | + | <form | |||
| 64 | + | id="install-traefik-form" | |||
| 65 | + | action="/admin/install/traefik" | |||
| 66 | + | method="POST" | |||
| 67 | + | hx-post="/admin/install/traefik" | |||
| 68 | + | hx-swap="outerHTML" | |||
| 69 | + | > | |||
| 70 | + | <h2 class="">1.1 - Set your top domain name</h2> | |||
| 71 | + | <input | |||
| 72 | + | type="text" | |||
| 73 | + | name="topdomain" | |||
| 74 | + | id="topdomain" | |||
| 75 | + | class="w-full py-2 px-4 my-2 border border-gray-300 rounded-md" | |||
| 76 | + | placeholder="example.com" | |||
| 77 | + | /> | |||
| 78 | + | <h2>1.2 - Set your admin email (a reachable one)</h2> | |||
| 79 | + | <input | |||
| 80 | + | type="text" | |||
| 81 | + | name="adminemail" | |||
| 82 | + | id="adminemail" | |||
| 83 | + | class="w-full p-2 border border-gray-300 rounded-md" | |||
| 84 | + | placeholder="admin@example.com" | |||
| 85 | + | /> | |||
| 86 | + | <button | |||
| 87 | + | type="submit" | |||
| 88 | + | class="w-full p-2 bg-gordonmascot-hblue text-slate-100 rounded-md mt-4" | |||
| 89 | + | > | |||
| 90 | + | Save & Install Traefik | |||
| 91 | + | </button> | |||
| 92 | + | </form> | |||
| 93 | + | </div> | |||
| 94 | + | <!-- Right --> | |||
| 95 | + | <div class="w-full md:w-1/2 p-4 text-slate-100"> | |||
| 96 | + | <div | |||
| 97 | + | class="flex flex-col items-center bg-gordonmascot-hblue rounded-md" | |||
| 98 | + | > | |||
| 99 | + | <div class="w-full h-64 overflow-y-scroll-auto p-4"> | |||
| 100 | + | <div | |||
| 101 | + | class="flex flex-col space-y-2" | |||
| 102 | + | hx-ext="sse" | |||
| 103 | + | sse-connect="/admin/install/traefik/sse" | |||
| 104 | + | > | |||
| 105 | + | <!-- One item --> | |||
| 106 | + | <div class="flex flex-row items-center"> | |||
| 107 | + | <span class="">[INFO]</span> | |||
| 108 | + | <span class="">Traefik installed</span> | |||
| 109 | + | </div> | |||
| 110 | + | <!-- One item --> | |||
| 111 | + | <div class="flex flex-row items-center"> | |||
| 112 | + | <span class="">[INFO]</span> | |||
| 113 | + | <span class="ml-2">Traefik started</span> | |||
| 114 | + | </div> | |||
| 115 | + | <!-- One item --> | |||
| 116 | + | <div class="flex flex-row items-center"> | |||
| 117 | + | <span class="">[INFO]</span> | |||
| 118 | + | <span class="ml-2" | |||
| 119 | + | >Traefik configuration file created</span | |||
| 120 | + | > | |||
| 121 | + | </div> | |||
| 122 | + | <!-- One item --> | |||
| 123 | + | <div class="flex flex-row items-center"> | |||
| 124 | + | <span class="">[INFO]</span> | |||
| 125 | + | <span class="">Traefik configuration file updated</span> | |||
| 126 | + | </div> | |||
| 127 | + | </div> | |||
| 128 | + | </div> | |||
| 129 | + | </div> | |||
| 130 | + | </div> | |||
| 131 | + | </div> | |||
| 132 | + | </div> | |||
| 133 | + | </div> | |||
| 134 | + | <!-- End Install Traefik --> | |||
| 135 | + | </div> | |||
| 136 | + | </body> | |||
| 137 | + | </html> | |||
A internal/gotemplate/models/html/admin/manager.gohtml +0 -0
no textual change.
A internal/gotemplate/models/html/admin/user.gohtml +0 -0
no textual change.
A internal/gotemplate/models/html/fragments/components.gohtml +33 -0
| @@ -0,0 +1,33 @@ | |||
| 1 | + | <!-- @format --> | |
| 2 | + | ||
| 3 | + | <div id="header"> | |
| 4 | + | <h1 | |
| 5 | + | class="text-5xl fw100 animate-bounce-alt animate-count-infinite animate-duration-1s" | |
| 6 | + | > | |
| 7 | + | {{ .body.header.helloworld }} | |
| 8 | + | </h1> | |
| 9 | + | </div> | |
| 10 | + | ||
| 11 | + | <div id="hello"> | |
| 12 | + | <h1 | |
| 13 | + | class="text-5xl fw100 animate-bounce-alt animate-count-infinite animate-duration-1s" | |
| 14 | + | > | |
| 15 | + | {{ .body.div.hello }} | |
| 16 | + | </h1> | |
| 17 | + | </div> | |
| 18 | + | <div | |
| 19 | + | id="header" | |
| 20 | + | hx-get="/htmx" | |
| 21 | + | hx-headers='{"HX-Fragment": "header"}' | |
| 22 | + | hx-trigger="load" | |
| 23 | + | hx-swap="outerHTML" | |
| 24 | + | ></div> | |
| 25 | + | ||
| 26 | + | <!-- App Fragment --> | |
| 27 | + | <div | |
| 28 | + | id="app" | |
| 29 | + | hx-get="/htmx" | |
| 30 | + | hx-headers='{"HX-Fragment": "hello"}' | |
| 31 | + | hx-trigger="load" | |
| 32 | + | hx-swap="outerHTML" | |
| 33 | + | ></div> | |
| @@ -0,0 +1,33 @@ | |||||
| 1 | + | <!-- @format --> | |||
| 2 | + | ||||
| 3 | + | <div id="header"> | |||
| 4 | + | <h1 | |||
| 5 | + | class="text-5xl fw100 animate-bounce-alt animate-count-infinite animate-duration-1s" | |||
| 6 | + | > | |||
| 7 | + | {{ .body.header.helloworld }} | |||
| 8 | + | </h1> | |||
| 9 | + | </div> | |||
| 10 | + | ||||
| 11 | + | <div id="hello"> | |||
| 12 | + | <h1 | |||
| 13 | + | class="text-5xl fw100 animate-bounce-alt animate-count-infinite animate-duration-1s" | |||
| 14 | + | > | |||
| 15 | + | {{ .body.div.hello }} | |||
| 16 | + | </h1> | |||
| 17 | + | </div> | |||
| 18 | + | <div | |||
| 19 | + | id="header" | |||
| 20 | + | hx-get="/htmx" | |||
| 21 | + | hx-headers='{"HX-Fragment": "header"}' | |||
| 22 | + | hx-trigger="load" | |||
| 23 | + | hx-swap="outerHTML" | |||
| 24 | + | ></div> | |||
| 25 | + | ||||
| 26 | + | <!-- App Fragment --> | |||
| 27 | + | <div | |||
| 28 | + | id="app" | |||
| 29 | + | hx-get="/htmx" | |||
| 30 | + | hx-headers='{"HX-Fragment": "hello"}' | |||
| 31 | + | hx-trigger="load" | |||
| 32 | + | hx-swap="outerHTML" | |||
| 33 | + | ></div> | |||
A internal/gotemplate/models/html/strings.yml +23 -0
| @@ -0,0 +1,23 @@ | |||
| 1 | + | en: | |
| 2 | + | header: | |
| 3 | + | meta: | |
| 4 | + | title: Gordon - Admin Dashboard | |
| 5 | + | description: Admin dashboard for Gordon | |
| 6 | + | keywords: gordon, admin, dashboard | |
| 7 | + | body: | |
| 8 | + | header: | |
| 9 | + | helloworld: Hello World! | |
| 10 | + | div: | |
| 11 | + | hello: Hello component loaded from a template! | |
| 12 | + | ||
| 13 | + | fr: | |
| 14 | + | header: | |
| 15 | + | meta: | |
| 16 | + | title: Gordon - Tableau de bord administrateur | |
| 17 | + | description: Tableau de bord administrateur pour Gordon | |
| 18 | + | keywords: gordon, admin, dashboard | |
| 19 | + | body: | |
| 20 | + | header: | |
| 21 | + | helloworld: Bonjour le monde! | |
| 22 | + | div: | |
| 23 | + | hello: Composant de salut chargé à partir d'un modèle! | |
| @@ -0,0 +1,23 @@ | |||||
| 1 | + | en: | |||
| 2 | + | header: | |||
| 3 | + | meta: | |||
| 4 | + | title: Gordon - Admin Dashboard | |||
| 5 | + | description: Admin dashboard for Gordon | |||
| 6 | + | keywords: gordon, admin, dashboard | |||
| 7 | + | body: | |||
| 8 | + | header: | |||
| 9 | + | helloworld: Hello World! | |||
| 10 | + | div: | |||
| 11 | + | hello: Hello component loaded from a template! | |||
| 12 | + | ||||
| 13 | + | fr: | |||
| 14 | + | header: | |||
| 15 | + | meta: | |||
| 16 | + | title: Gordon - Tableau de bord administrateur | |||
| 17 | + | description: Tableau de bord administrateur pour Gordon | |||
| 18 | + | keywords: gordon, admin, dashboard | |||
| 19 | + | body: | |||
| 20 | + | header: | |||
| 21 | + | helloworld: Bonjour le monde! | |||
| 22 | + | div: | |||
| 23 | + | hello: Composant de salut chargé à partir d'un modèle! | |||
A internal/gotemplate/models/txt/test.txt +0 -0
no textual change.
A internal/httpserve/handler/adminroutes.go +5 -0
| @@ -0,0 +1,5 @@ | |||
| 1 | + | package handlers | |
| 2 | + | ||
| 3 | + | import () | |
| 4 | + | ||
| 5 | + | ||
| @@ -0,0 +1,5 @@ | |||||
| 1 | + | package handlers | |||
| 2 | + | ||||
| 3 | + | import () | |||
| 4 | + | ||||
| 5 | + | ||||
A internal/httpserve/handler/htmx.go +0 -0
no textual change.
A internal/httpserve/handler/static.go +0 -0
no textual change.
A internal/httpserve/middleware/detectcolorscheme.go +0 -0
no textual change.
A internal/httpserve/middleware/detectlang.go +0 -0
no textual change.
A internal/httpserve/middleware/secure.go +0 -0
no textual change.
A internal/httpserve/middleware/tmp/build-errors.log +1 -0
| @@ -0,0 +1,1 @@ | |||
| 1 | + | exit status 1⏎̸ | |
| @@ -0,0 +1,1 @@ | |||||
| 1 | + | exit status 1⏎̸ | |||
A internal/httpserve/router.go +0 -0
no textual change.
A internal/webui/embed.go +14 -0
| @@ -0,0 +1,14 @@ | |||
| 1 | + | package webui | |
| 2 | + | ||
| 3 | + | import ( | |
| 4 | + | "embed" | |
| 5 | + | ||
| 6 | + | "github.com/labstack/echo/v4" | |
| 7 | + | ) | |
| 8 | + | ||
| 9 | + | // Embedding the public directory | |
| 10 | + | // | |
| 11 | + | //go:embed public/* | |
| 12 | + | var public embed.FS | |
| 13 | + | ||
| 14 | + | var PublicFS = echo.MustSubFS(public, "internal/webui/public") | |
| @@ -0,0 +1,14 @@ | |||||
| 1 | + | package webui | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "embed" | |||
| 5 | + | ||||
| 6 | + | "github.com/labstack/echo/v4" | |||
| 7 | + | ) | |||
| 8 | + | ||||
| 9 | + | // Embedding the public directory | |||
| 10 | + | // | |||
| 11 | + | //go:embed public/* | |||
| 12 | + | var public embed.FS | |||
| 13 | + | ||||
| 14 | + | var PublicFS = echo.MustSubFS(public, "internal/webui/public") | |||
A internal/webui/public/404.gohtml +12 -0
| @@ -0,0 +1,12 @@ | |||
| 1 | + | <!DOCTYPE html> | |
| 2 | + | <html lang="en"> | |
| 3 | + | <head> | |
| 4 | + | <meta charset="UTF-8" /> | |
| 5 | + | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| 6 | + | <title>Error 404</title> | |
| 7 | + | </head> | |
| 8 | + | <body> | |
| 9 | + | <h1>Error 404</h1> | |
| 10 | + | <p>Page not found</p> | |
| 11 | + | </body> | |
| 12 | + | </html> | |
| @@ -0,0 +1,12 @@ | |||||
| 1 | + | <!DOCTYPE html> | |||
| 2 | + | <html lang="en"> | |||
| 3 | + | <head> | |||
| 4 | + | <meta charset="UTF-8" /> | |||
| 5 | + | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |||
| 6 | + | <title>Error 404</title> | |||
| 7 | + | </head> | |||
| 8 | + | <body> | |||
| 9 | + | <h1>Error 404</h1> | |||
| 10 | + | <p>Page not found</p> | |||
| 11 | + | </body> | |||
| 12 | + | </html> | |||
A internal/webui/public/500.gohtml +12 -0
| @@ -0,0 +1,12 @@ | |||
| 1 | + | <!DOCTYPE html> | |
| 2 | + | <html lang="en"> | |
| 3 | + | <head> | |
| 4 | + | <meta charset="UTF-8" /> | |
| 5 | + | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| 6 | + | <title>Error 500</title> | |
| 7 | + | </head> | |
| 8 | + | <body> | |
| 9 | + | <h1>500 Internal Server Error</h1> | |
| 10 | + | <p>Something went really wrong o/</p> | |
| 11 | + | </body> | |
| 12 | + | </html> | |
| @@ -0,0 +1,12 @@ | |||||
| 1 | + | <!DOCTYPE html> | |||
| 2 | + | <html lang="en"> | |||
| 3 | + | <head> | |||
| 4 | + | <meta charset="UTF-8" /> | |||
| 5 | + | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |||
| 6 | + | <title>Error 500</title> | |||
| 7 | + | </head> | |||
| 8 | + | <body> | |||
| 9 | + | <h1>500 Internal Server Error</h1> | |||
| 10 | + | <p>Something went really wrong o/</p> | |||
| 11 | + | </body> | |||
| 12 | + | </html> | |||
A internal/webui/public/android-chrome-192x192.png +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/android-chrome-512x512.png +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/apple-touch-icon.png +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/assets/css/custom.css +116 -0
| @@ -0,0 +1,116 @@ | |||
| 1 | + | /** | |
| 2 | + | * Path: internal/ui/public/assets/css/custom.css | |
| 3 | + | * | |
| 4 | + | * @format | |
| 5 | + | */ | |
| 6 | + | ||
| 7 | + | /* Embeded path : assets/css/cutsom.css */ | |
| 8 | + | ||
| 9 | + | @tailwind base; | |
| 10 | + | @tailwind components; | |
| 11 | + | @tailwind utilities; | |
| 12 | + | ||
| 13 | + | /* Import IBM Plex Fonts */ | |
| 14 | + | @font-face { | |
| 15 | + | font-family: "IBMPlexSans-Bold"; | |
| 16 | + | src: url("/assets/fonts/IBMPlex/IBMPlexSans-Bold.woff2") format("woff2"); | |
| 17 | + | font-weight: bold; | |
| 18 | + | font-style: normal; | |
| 19 | + | } | |
| 20 | + | ||
| 21 | + | @font-face { | |
| 22 | + | font-family: "IBMPlexSans-Regular"; | |
| 23 | + | src: url("/assets/fonts/IBMPlex/IBMPlexSans-Regular.woff2") format("woff2"); | |
| 24 | + | font-weight: normal; | |
| 25 | + | font-style: normal; | |
| 26 | + | } | |
| 27 | + | ||
| 28 | + | /* Import Jetbrains Mono Nerd Font */ | |
| 29 | + | @font-face { | |
| 30 | + | font-family: "JetBrainsMono-Nerd-Font-Regular"; | |
| 31 | + | src: url("/assets/fonts/JetBrainsMonoNerd/JetBrainsMonoNerdFontMono-Regular.woff2") | |
| 32 | + | format("woff2"); | |
| 33 | + | font-weight: normal; | |
| 34 | + | font-style: normal; | |
| 35 | + | } | |
| 36 | + | ||
| 37 | + | @font-face { | |
| 38 | + | font-family: "LilitaOne-Regular"; | |
| 39 | + | src: url("/assets/fonts/LilitaOne/LilitaOne-Regular.ttf") format("truetype"); | |
| 40 | + | font-weight: normal; | |
| 41 | + | font-style: normal; | |
| 42 | + | } | |
| 43 | + | ||
| 44 | + | .fade-me-out.htmx-swapping { | |
| 45 | + | opacity: 0; | |
| 46 | + | transition: opacity 1s ease-out; | |
| 47 | + | } | |
| 48 | + | ||
| 49 | + | /* View transition */ | |
| 50 | + | @keyframes fade-in { | |
| 51 | + | from { | |
| 52 | + | opacity: 0; | |
| 53 | + | } | |
| 54 | + | } | |
| 55 | + | ||
| 56 | + | @keyframes fade-out { | |
| 57 | + | to { | |
| 58 | + | opacity: 0; | |
| 59 | + | } | |
| 60 | + | } | |
| 61 | + | ||
| 62 | + | @keyframes slide-from-right { | |
| 63 | + | from { | |
| 64 | + | transform: translateX(90px); | |
| 65 | + | } | |
| 66 | + | } | |
| 67 | + | ||
| 68 | + | @keyframes slide-to-left { | |
| 69 | + | to { | |
| 70 | + | transform: translateX(-90px); | |
| 71 | + | } | |
| 72 | + | } | |
| 73 | + | ||
| 74 | + | .slide-it { | |
| 75 | + | view-transition-name: slide-it; | |
| 76 | + | } | |
| 77 | + | ||
| 78 | + | ::view-transition-old(slide-it) { | |
| 79 | + | animation: 180ms cubic-bezier(0.4, 0, 1, 1) both fade-out, | |
| 80 | + | 600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left; | |
| 81 | + | } | |
| 82 | + | ::view-transition-new(slide-it) { | |
| 83 | + | animation: 420ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in, | |
| 84 | + | 600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right; | |
| 85 | + | } | |
| 86 | + | ||
| 87 | + | .gordon-title { | |
| 88 | + | font-family: "LilitaOne-Regular", sans-serif; | |
| 89 | + | ||
| 90 | + | } | |
| 91 | + | ||
| 92 | + | .IBMPlexSans { | |
| 93 | + | font-family: "IBMPlexSans-Regular", sans-serif; | |
| 94 | + | } | |
| 95 | + | ||
| 96 | + | .circle-shadow { | |
| 97 | + | width: 100%; | |
| 98 | + | position: relative; | |
| 99 | + | } | |
| 100 | + | ||
| 101 | + | .circle-shadow::after { | |
| 102 | + | position: absolute; | |
| 103 | + | width: 50%; | |
| 104 | + | height: 0.4rem; | |
| 105 | + | margin: auto; | |
| 106 | + | background: rgba(0, 0, 0, 0.1); | |
| 107 | + | border-radius: 50%; | |
| 108 | + | z-index: -1; | |
| 109 | + | bottom: 2%; | |
| 110 | + | content: ""; | |
| 111 | + | box-shadow: 0 0 1px 0.3rem rgba(0, 0, 0, 0.1); | |
| 112 | + | } | |
| 113 | + | ||
| 114 | + | .iconoir { | |
| 115 | + | margin-right: 8px; | |
| 116 | + | } | |
| @@ -0,0 +1,116 @@ | |||||
| 1 | + | /** | |||
| 2 | + | * Path: internal/ui/public/assets/css/custom.css | |||
| 3 | + | * | |||
| 4 | + | * @format | |||
| 5 | + | */ | |||
| 6 | + | ||||
| 7 | + | /* Embeded path : assets/css/cutsom.css */ | |||
| 8 | + | ||||
| 9 | + | @tailwind base; | |||
| 10 | + | @tailwind components; | |||
| 11 | + | @tailwind utilities; | |||
| 12 | + | ||||
| 13 | + | /* Import IBM Plex Fonts */ | |||
| 14 | + | @font-face { | |||
| 15 | + | font-family: "IBMPlexSans-Bold"; | |||
| 16 | + | src: url("/assets/fonts/IBMPlex/IBMPlexSans-Bold.woff2") format("woff2"); | |||
| 17 | + | font-weight: bold; | |||
| 18 | + | font-style: normal; | |||
| 19 | + | } | |||
| 20 | + | ||||
| 21 | + | @font-face { | |||
| 22 | + | font-family: "IBMPlexSans-Regular"; | |||
| 23 | + | src: url("/assets/fonts/IBMPlex/IBMPlexSans-Regular.woff2") format("woff2"); | |||
| 24 | + | font-weight: normal; | |||
| 25 | + | font-style: normal; | |||
| 26 | + | } | |||
| 27 | + | ||||
| 28 | + | /* Import Jetbrains Mono Nerd Font */ | |||
| 29 | + | @font-face { | |||
| 30 | + | font-family: "JetBrainsMono-Nerd-Font-Regular"; | |||
| 31 | + | src: url("/assets/fonts/JetBrainsMonoNerd/JetBrainsMonoNerdFontMono-Regular.woff2") | |||
| 32 | + | format("woff2"); | |||
| 33 | + | font-weight: normal; | |||
| 34 | + | font-style: normal; | |||
| 35 | + | } | |||
| 36 | + | ||||
| 37 | + | @font-face { | |||
| 38 | + | font-family: "LilitaOne-Regular"; | |||
| 39 | + | src: url("/assets/fonts/LilitaOne/LilitaOne-Regular.ttf") format("truetype"); | |||
| 40 | + | font-weight: normal; | |||
| 41 | + | font-style: normal; | |||
| 42 | + | } | |||
| 43 | + | ||||
| 44 | + | .fade-me-out.htmx-swapping { | |||
| 45 | + | opacity: 0; | |||
| 46 | + | transition: opacity 1s ease-out; | |||
| 47 | + | } | |||
| 48 | + | ||||
| 49 | + | /* View transition */ | |||
| 50 | + | @keyframes fade-in { | |||
| 51 | + | from { | |||
| 52 | + | opacity: 0; | |||
| 53 | + | } | |||
| 54 | + | } | |||
| 55 | + | ||||
| 56 | + | @keyframes fade-out { | |||
| 57 | + | to { | |||
| 58 | + | opacity: 0; | |||
| 59 | + | } | |||
| 60 | + | } | |||
| 61 | + | ||||
| 62 | + | @keyframes slide-from-right { | |||
| 63 | + | from { | |||
| 64 | + | transform: translateX(90px); | |||
| 65 | + | } | |||
| 66 | + | } | |||
| 67 | + | ||||
| 68 | + | @keyframes slide-to-left { | |||
| 69 | + | to { | |||
| 70 | + | transform: translateX(-90px); | |||
| 71 | + | } | |||
| 72 | + | } | |||
| 73 | + | ||||
| 74 | + | .slide-it { | |||
| 75 | + | view-transition-name: slide-it; | |||
| 76 | + | } | |||
| 77 | + | ||||
| 78 | + | ::view-transition-old(slide-it) { | |||
| 79 | + | animation: 180ms cubic-bezier(0.4, 0, 1, 1) both fade-out, | |||
| 80 | + | 600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left; | |||
| 81 | + | } | |||
| 82 | + | ::view-transition-new(slide-it) { | |||
| 83 | + | animation: 420ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in, | |||
| 84 | + | 600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right; | |||
| 85 | + | } | |||
| 86 | + | ||||
| 87 | + | .gordon-title { | |||
| 88 | + | font-family: "LilitaOne-Regular", sans-serif; | |||
| 89 | + | ||||
| 90 | + | } | |||
| 91 | + | ||||
| 92 | + | .IBMPlexSans { | |||
| 93 | + | font-family: "IBMPlexSans-Regular", sans-serif; | |||
| 94 | + | } | |||
| 95 | + | ||||
| 96 | + | .circle-shadow { | |||
| 97 | + | width: 100%; | |||
| 98 | + | position: relative; | |||
| 99 | + | } | |||
| 100 | + | ||||
| 101 | + | .circle-shadow::after { | |||
| 102 | + | position: absolute; | |||
| 103 | + | width: 50%; | |||
| 104 | + | height: 0.4rem; | |||
| 105 | + | margin: auto; | |||
| 106 | + | background: rgba(0, 0, 0, 0.1); | |||
| 107 | + | border-radius: 50%; | |||
| 108 | + | z-index: -1; | |||
| 109 | + | bottom: 2%; | |||
| 110 | + | content: ""; | |||
| 111 | + | box-shadow: 0 0 1px 0.3rem rgba(0, 0, 0, 0.1); | |||
| 112 | + | } | |||
| 113 | + | ||||
| 114 | + | .iconoir { | |||
| 115 | + | margin-right: 8px; | |||
| 116 | + | } | |||
A internal/webui/public/assets/css/tailwind.css +1046 -0
| @@ -0,0 +1,1046 @@ | |||
| 1 | + | /** | |
| 2 | + | * Path: internal/ui/public/assets/css/custom.css | |
| 3 | + | * | |
| 4 | + | * @format | |
| 5 | + | */ | |
| 6 | + | ||
| 7 | + | /* Embeded path : assets/css/cutsom.css */ | |
| 8 | + | ||
| 9 | + | /*! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com | |
| 10 | + | */ | |
| 11 | + | ||
| 12 | + | /* | |
| 13 | + | 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) | |
| 14 | + | 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) | |
| 15 | + | */ | |
| 16 | + | ||
| 17 | + | *, | |
| 18 | + | ::before, | |
| 19 | + | ::after { | |
| 20 | + | box-sizing: border-box; | |
| 21 | + | /* 1 */ | |
| 22 | + | border-width: 0; | |
| 23 | + | /* 2 */ | |
| 24 | + | border-style: solid; | |
| 25 | + | /* 2 */ | |
| 26 | + | border-color: #e5e7eb; | |
| 27 | + | /* 2 */ | |
| 28 | + | } | |
| 29 | + | ||
| 30 | + | ::before, | |
| 31 | + | ::after { | |
| 32 | + | --tw-content: ''; | |
| 33 | + | } | |
| 34 | + | ||
| 35 | + | /* | |
| 36 | + | 1. Use a consistent sensible line-height in all browsers. | |
| 37 | + | 2. Prevent adjustments of font size after orientation changes in iOS. | |
| 38 | + | 3. Use a more readable tab size. | |
| 39 | + | 4. Use the user's configured `sans` font-family by default. | |
| 40 | + | 5. Use the user's configured `sans` font-feature-settings by default. | |
| 41 | + | 6. Use the user's configured `sans` font-variation-settings by default. | |
| 42 | + | */ | |
| 43 | + | ||
| 44 | + | html { | |
| 45 | + | line-height: 1.5; | |
| 46 | + | /* 1 */ | |
| 47 | + | -webkit-text-size-adjust: 100%; | |
| 48 | + | /* 2 */ | |
| 49 | + | -moz-tab-size: 4; | |
| 50 | + | /* 3 */ | |
| 51 | + | -o-tab-size: 4; | |
| 52 | + | tab-size: 4; | |
| 53 | + | /* 3 */ | |
| 54 | + | font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; | |
| 55 | + | /* 4 */ | |
| 56 | + | font-feature-settings: normal; | |
| 57 | + | /* 5 */ | |
| 58 | + | font-variation-settings: normal; | |
| 59 | + | /* 6 */ | |
| 60 | + | } | |
| 61 | + | ||
| 62 | + | /* | |
| 63 | + | 1. Remove the margin in all browsers. | |
| 64 | + | 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. | |
| 65 | + | */ | |
| 66 | + | ||
| 67 | + | body { | |
| 68 | + | margin: 0; | |
| 69 | + | /* 1 */ | |
| 70 | + | line-height: inherit; | |
| 71 | + | /* 2 */ | |
| 72 | + | } | |
| 73 | + | ||
| 74 | + | /* | |
| 75 | + | 1. Add the correct height in Firefox. | |
| 76 | + | 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) | |
| 77 | + | 3. Ensure horizontal rules are visible by default. | |
| 78 | + | */ | |
| 79 | + | ||
| 80 | + | hr { | |
| 81 | + | height: 0; | |
| 82 | + | /* 1 */ | |
| 83 | + | color: inherit; | |
| 84 | + | /* 2 */ | |
| 85 | + | border-top-width: 1px; | |
| 86 | + | /* 3 */ | |
| 87 | + | } | |
| 88 | + | ||
| 89 | + | /* | |
| 90 | + | Add the correct text decoration in Chrome, Edge, and Safari. | |
| 91 | + | */ | |
| 92 | + | ||
| 93 | + | abbr:where([title]) { | |
| 94 | + | -webkit-text-decoration: underline dotted; | |
| 95 | + | text-decoration: underline dotted; | |
| 96 | + | } | |
| 97 | + | ||
| 98 | + | /* | |
| 99 | + | Remove the default font size and weight for headings. | |
| 100 | + | */ | |
| 101 | + | ||
| 102 | + | h1, | |
| 103 | + | h2, | |
| 104 | + | h3, | |
| 105 | + | h4, | |
| 106 | + | h5, | |
| 107 | + | h6 { | |
| 108 | + | font-size: inherit; | |
| 109 | + | font-weight: inherit; | |
| 110 | + | } | |
| 111 | + | ||
| 112 | + | /* | |
| 113 | + | Reset links to optimize for opt-in styling instead of opt-out. | |
| 114 | + | */ | |
| 115 | + | ||
| 116 | + | a { | |
| 117 | + | color: inherit; | |
| 118 | + | text-decoration: inherit; | |
| 119 | + | } | |
| 120 | + | ||
| 121 | + | /* | |
| 122 | + | Add the correct font weight in Edge and Safari. | |
| 123 | + | */ | |
| 124 | + | ||
| 125 | + | b, | |
| 126 | + | strong { | |
| 127 | + | font-weight: bolder; | |
| 128 | + | } | |
| 129 | + | ||
| 130 | + | /* | |
| 131 | + | 1. Use the user's configured `mono` font family by default. | |
| 132 | + | 2. Correct the odd `em` font sizing in all browsers. | |
| 133 | + | */ | |
| 134 | + | ||
| 135 | + | code, | |
| 136 | + | kbd, | |
| 137 | + | samp, | |
| 138 | + | pre { | |
| 139 | + | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | |
| 140 | + | /* 1 */ | |
| 141 | + | font-size: 1em; | |
| 142 | + | /* 2 */ | |
| 143 | + | } | |
| 144 | + | ||
| 145 | + | /* | |
| 146 | + | Add the correct font size in all browsers. | |
| 147 | + | */ | |
| 148 | + | ||
| 149 | + | small { | |
| 150 | + | font-size: 80%; | |
| 151 | + | } | |
| 152 | + | ||
| 153 | + | /* | |
| 154 | + | Prevent `sub` and `sup` elements from affecting the line height in all browsers. | |
| 155 | + | */ | |
| 156 | + | ||
| 157 | + | sub, | |
| 158 | + | sup { | |
| 159 | + | font-size: 75%; | |
| 160 | + | line-height: 0; | |
| 161 | + | position: relative; | |
| 162 | + | vertical-align: baseline; | |
| 163 | + | } | |
| 164 | + | ||
| 165 | + | sub { | |
| 166 | + | bottom: -0.25em; | |
| 167 | + | } | |
| 168 | + | ||
| 169 | + | sup { | |
| 170 | + | top: -0.5em; | |
| 171 | + | } | |
| 172 | + | ||
| 173 | + | /* | |
| 174 | + | 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) | |
| 175 | + | 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) | |
| 176 | + | 3. Remove gaps between table borders by default. | |
| 177 | + | */ | |
| 178 | + | ||
| 179 | + | table { | |
| 180 | + | text-indent: 0; | |
| 181 | + | /* 1 */ | |
| 182 | + | border-color: inherit; | |
| 183 | + | /* 2 */ | |
| 184 | + | border-collapse: collapse; | |
| 185 | + | /* 3 */ | |
| 186 | + | } | |
| 187 | + | ||
| 188 | + | /* | |
| 189 | + | 1. Change the font styles in all browsers. | |
| 190 | + | 2. Remove the margin in Firefox and Safari. | |
| 191 | + | 3. Remove default padding in all browsers. | |
| 192 | + | */ | |
| 193 | + | ||
| 194 | + | button, | |
| 195 | + | input, | |
| 196 | + | optgroup, | |
| 197 | + | select, | |
| 198 | + | textarea { | |
| 199 | + | font-family: inherit; | |
| 200 | + | /* 1 */ | |
| 201 | + | font-feature-settings: inherit; | |
| 202 | + | /* 1 */ | |
| 203 | + | font-variation-settings: inherit; | |
| 204 | + | /* 1 */ | |
| 205 | + | font-size: 100%; | |
| 206 | + | /* 1 */ | |
| 207 | + | font-weight: inherit; | |
| 208 | + | /* 1 */ | |
| 209 | + | line-height: inherit; | |
| 210 | + | /* 1 */ | |
| 211 | + | color: inherit; | |
| 212 | + | /* 1 */ | |
| 213 | + | margin: 0; | |
| 214 | + | /* 2 */ | |
| 215 | + | padding: 0; | |
| 216 | + | /* 3 */ | |
| 217 | + | } | |
| 218 | + | ||
| 219 | + | /* | |
| 220 | + | Remove the inheritance of text transform in Edge and Firefox. | |
| 221 | + | */ | |
| 222 | + | ||
| 223 | + | button, | |
| 224 | + | select { | |
| 225 | + | text-transform: none; | |
| 226 | + | } | |
| 227 | + | ||
| 228 | + | /* | |
| 229 | + | 1. Correct the inability to style clickable types in iOS and Safari. | |
| 230 | + | 2. Remove default button styles. | |
| 231 | + | */ | |
| 232 | + | ||
| 233 | + | button, | |
| 234 | + | [type='button'], | |
| 235 | + | [type='reset'], | |
| 236 | + | [type='submit'] { | |
| 237 | + | -webkit-appearance: button; | |
| 238 | + | /* 1 */ | |
| 239 | + | background-color: transparent; | |
| 240 | + | /* 2 */ | |
| 241 | + | background-image: none; | |
| 242 | + | /* 2 */ | |
| 243 | + | } | |
| 244 | + | ||
| 245 | + | /* | |
| 246 | + | Use the modern Firefox focus style for all focusable elements. | |
| 247 | + | */ | |
| 248 | + | ||
| 249 | + | :-moz-focusring { | |
| 250 | + | outline: auto; | |
| 251 | + | } | |
| 252 | + | ||
| 253 | + | /* | |
| 254 | + | Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) | |
| 255 | + | */ | |
| 256 | + | ||
| 257 | + | :-moz-ui-invalid { | |
| 258 | + | box-shadow: none; | |
| 259 | + | } | |
| 260 | + | ||
| 261 | + | /* | |
| 262 | + | Add the correct vertical alignment in Chrome and Firefox. | |
| 263 | + | */ | |
| 264 | + | ||
| 265 | + | progress { | |
| 266 | + | vertical-align: baseline; | |
| 267 | + | } | |
| 268 | + | ||
| 269 | + | /* | |
| 270 | + | Correct the cursor style of increment and decrement buttons in Safari. | |
| 271 | + | */ | |
| 272 | + | ||
| 273 | + | ::-webkit-inner-spin-button, | |
| 274 | + | ::-webkit-outer-spin-button { | |
| 275 | + | height: auto; | |
| 276 | + | } | |
| 277 | + | ||
| 278 | + | /* | |
| 279 | + | 1. Correct the odd appearance in Chrome and Safari. | |
| 280 | + | 2. Correct the outline style in Safari. | |
| 281 | + | */ | |
| 282 | + | ||
| 283 | + | [type='search'] { | |
| 284 | + | -webkit-appearance: textfield; | |
| 285 | + | /* 1 */ | |
| 286 | + | outline-offset: -2px; | |
| 287 | + | /* 2 */ | |
| 288 | + | } | |
| 289 | + | ||
| 290 | + | /* | |
| 291 | + | Remove the inner padding in Chrome and Safari on macOS. | |
| 292 | + | */ | |
| 293 | + | ||
| 294 | + | ::-webkit-search-decoration { | |
| 295 | + | -webkit-appearance: none; | |
| 296 | + | } | |
| 297 | + | ||
| 298 | + | /* | |
| 299 | + | 1. Correct the inability to style clickable types in iOS and Safari. | |
| 300 | + | 2. Change font properties to `inherit` in Safari. | |
| 301 | + | */ | |
| 302 | + | ||
| 303 | + | ::-webkit-file-upload-button { | |
| 304 | + | -webkit-appearance: button; | |
| 305 | + | /* 1 */ | |
| 306 | + | font: inherit; | |
| 307 | + | /* 2 */ | |
| 308 | + | } | |
| 309 | + | ||
| 310 | + | /* | |
| 311 | + | Add the correct display in Chrome and Safari. | |
| 312 | + | */ | |
| 313 | + | ||
| 314 | + | summary { | |
| 315 | + | display: list-item; | |
| 316 | + | } | |
| 317 | + | ||
| 318 | + | /* | |
| 319 | + | Removes the default spacing and border for appropriate elements. | |
| 320 | + | */ | |
| 321 | + | ||
| 322 | + | blockquote, | |
| 323 | + | dl, | |
| 324 | + | dd, | |
| 325 | + | h1, | |
| 326 | + | h2, | |
| 327 | + | h3, | |
| 328 | + | h4, | |
| 329 | + | h5, | |
| 330 | + | h6, | |
| 331 | + | hr, | |
| 332 | + | figure, | |
| 333 | + | p, | |
| 334 | + | pre { | |
| 335 | + | margin: 0; | |
| 336 | + | } | |
| 337 | + | ||
| 338 | + | fieldset { | |
| 339 | + | margin: 0; | |
| 340 | + | padding: 0; | |
| 341 | + | } | |
| 342 | + | ||
| 343 | + | legend { | |
| 344 | + | padding: 0; | |
| 345 | + | } | |
| 346 | + | ||
| 347 | + | ol, | |
| 348 | + | ul, | |
| 349 | + | menu { | |
| 350 | + | list-style: none; | |
| 351 | + | margin: 0; | |
| 352 | + | padding: 0; | |
| 353 | + | } | |
| 354 | + | ||
| 355 | + | /* | |
| 356 | + | Reset default styling for dialogs. | |
| 357 | + | */ | |
| 358 | + | ||
| 359 | + | dialog { | |
| 360 | + | padding: 0; | |
| 361 | + | } | |
| 362 | + | ||
| 363 | + | /* | |
| 364 | + | Prevent resizing textareas horizontally by default. | |
| 365 | + | */ | |
| 366 | + | ||
| 367 | + | textarea { | |
| 368 | + | resize: vertical; | |
| 369 | + | } | |
| 370 | + | ||
| 371 | + | /* | |
| 372 | + | 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) | |
| 373 | + | 2. Set the default placeholder color to the user's configured gray 400 color. | |
| 374 | + | */ | |
| 375 | + | ||
| 376 | + | input::-moz-placeholder, textarea::-moz-placeholder { | |
| 377 | + | opacity: 1; | |
| 378 | + | /* 1 */ | |
| 379 | + | color: #9ca3af; | |
| 380 | + | /* 2 */ | |
| 381 | + | } | |
| 382 | + | ||
| 383 | + | input::placeholder, | |
| 384 | + | textarea::placeholder { | |
| 385 | + | opacity: 1; | |
| 386 | + | /* 1 */ | |
| 387 | + | color: #9ca3af; | |
| 388 | + | /* 2 */ | |
| 389 | + | } | |
| 390 | + | ||
| 391 | + | /* | |
| 392 | + | Set the default cursor for buttons. | |
| 393 | + | */ | |
| 394 | + | ||
| 395 | + | button, | |
| 396 | + | [role="button"] { | |
| 397 | + | cursor: pointer; | |
| 398 | + | } | |
| 399 | + | ||
| 400 | + | /* | |
| 401 | + | Make sure disabled buttons don't get the pointer cursor. | |
| 402 | + | */ | |
| 403 | + | ||
| 404 | + | :disabled { | |
| 405 | + | cursor: default; | |
| 406 | + | } | |
| 407 | + | ||
| 408 | + | /* | |
| 409 | + | 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) | |
| 410 | + | 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) | |
| 411 | + | This can trigger a poorly considered lint error in some tools but is included by design. | |
| 412 | + | */ | |
| 413 | + | ||
| 414 | + | img, | |
| 415 | + | svg, | |
| 416 | + | video, | |
| 417 | + | canvas, | |
| 418 | + | audio, | |
| 419 | + | iframe, | |
| 420 | + | embed, | |
| 421 | + | object { | |
| 422 | + | display: block; | |
| 423 | + | /* 1 */ | |
| 424 | + | vertical-align: middle; | |
| 425 | + | /* 2 */ | |
| 426 | + | } | |
| 427 | + | ||
| 428 | + | /* | |
| 429 | + | Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) | |
| 430 | + | */ | |
| 431 | + | ||
| 432 | + | img, | |
| 433 | + | video { | |
| 434 | + | max-width: 100%; | |
| 435 | + | height: auto; | |
| 436 | + | } | |
| 437 | + | ||
| 438 | + | /* Make elements with the HTML hidden attribute stay hidden by default */ | |
| 439 | + | ||
| 440 | + | [hidden] { | |
| 441 | + | display: none; | |
| 442 | + | } | |
| 443 | + | ||
| 444 | + | *, ::before, ::after { | |
| 445 | + | --tw-border-spacing-x: 0; | |
| 446 | + | --tw-border-spacing-y: 0; | |
| 447 | + | --tw-translate-x: 0; | |
| 448 | + | --tw-translate-y: 0; | |
| 449 | + | --tw-rotate: 0; | |
| 450 | + | --tw-skew-x: 0; | |
| 451 | + | --tw-skew-y: 0; | |
| 452 | + | --tw-scale-x: 1; | |
| 453 | + | --tw-scale-y: 1; | |
| 454 | + | --tw-pan-x: ; | |
| 455 | + | --tw-pan-y: ; | |
| 456 | + | --tw-pinch-zoom: ; | |
| 457 | + | --tw-scroll-snap-strictness: proximity; | |
| 458 | + | --tw-gradient-from-position: ; | |
| 459 | + | --tw-gradient-via-position: ; | |
| 460 | + | --tw-gradient-to-position: ; | |
| 461 | + | --tw-ordinal: ; | |
| 462 | + | --tw-slashed-zero: ; | |
| 463 | + | --tw-numeric-figure: ; | |
| 464 | + | --tw-numeric-spacing: ; | |
| 465 | + | --tw-numeric-fraction: ; | |
| 466 | + | --tw-ring-inset: ; | |
| 467 | + | --tw-ring-offset-width: 0px; | |
| 468 | + | --tw-ring-offset-color: #fff; | |
| 469 | + | --tw-ring-color: rgb(59 130 246 / 0.5); | |
| 470 | + | --tw-ring-offset-shadow: 0 0 #0000; | |
| 471 | + | --tw-ring-shadow: 0 0 #0000; | |
| 472 | + | --tw-shadow: 0 0 #0000; | |
| 473 | + | --tw-shadow-colored: 0 0 #0000; | |
| 474 | + | --tw-blur: ; | |
| 475 | + | --tw-brightness: ; | |
| 476 | + | --tw-contrast: ; | |
| 477 | + | --tw-grayscale: ; | |
| 478 | + | --tw-hue-rotate: ; | |
| 479 | + | --tw-invert: ; | |
| 480 | + | --tw-saturate: ; | |
| 481 | + | --tw-sepia: ; | |
| 482 | + | --tw-drop-shadow: ; | |
| 483 | + | --tw-backdrop-blur: ; | |
| 484 | + | --tw-backdrop-brightness: ; | |
| 485 | + | --tw-backdrop-contrast: ; | |
| 486 | + | --tw-backdrop-grayscale: ; | |
| 487 | + | --tw-backdrop-hue-rotate: ; | |
| 488 | + | --tw-backdrop-invert: ; | |
| 489 | + | --tw-backdrop-opacity: ; | |
| 490 | + | --tw-backdrop-saturate: ; | |
| 491 | + | --tw-backdrop-sepia: ; | |
| 492 | + | } | |
| 493 | + | ||
| 494 | + | ::backdrop { | |
| 495 | + | --tw-border-spacing-x: 0; | |
| 496 | + | --tw-border-spacing-y: 0; | |
| 497 | + | --tw-translate-x: 0; | |
| 498 | + | --tw-translate-y: 0; | |
| 499 | + | --tw-rotate: 0; | |
| 500 | + | --tw-skew-x: 0; | |
| 501 | + | --tw-skew-y: 0; | |
| 502 | + | --tw-scale-x: 1; | |
| 503 | + | --tw-scale-y: 1; | |
| 504 | + | --tw-pan-x: ; | |
| 505 | + | --tw-pan-y: ; | |
| 506 | + | --tw-pinch-zoom: ; | |
| 507 | + | --tw-scroll-snap-strictness: proximity; | |
| 508 | + | --tw-gradient-from-position: ; | |
| 509 | + | --tw-gradient-via-position: ; | |
| 510 | + | --tw-gradient-to-position: ; | |
| 511 | + | --tw-ordinal: ; | |
| 512 | + | --tw-slashed-zero: ; | |
| 513 | + | --tw-numeric-figure: ; | |
| 514 | + | --tw-numeric-spacing: ; | |
| 515 | + | --tw-numeric-fraction: ; | |
| 516 | + | --tw-ring-inset: ; | |
| 517 | + | --tw-ring-offset-width: 0px; | |
| 518 | + | --tw-ring-offset-color: #fff; | |
| 519 | + | --tw-ring-color: rgb(59 130 246 / 0.5); | |
| 520 | + | --tw-ring-offset-shadow: 0 0 #0000; | |
| 521 | + | --tw-ring-shadow: 0 0 #0000; | |
| 522 | + | --tw-shadow: 0 0 #0000; | |
| 523 | + | --tw-shadow-colored: 0 0 #0000; | |
| 524 | + | --tw-blur: ; | |
| 525 | + | --tw-brightness: ; | |
| 526 | + | --tw-contrast: ; | |
| 527 | + | --tw-grayscale: ; | |
| 528 | + | --tw-hue-rotate: ; | |
| 529 | + | --tw-invert: ; | |
| 530 | + | --tw-saturate: ; | |
| 531 | + | --tw-sepia: ; | |
| 532 | + | --tw-drop-shadow: ; | |
| 533 | + | --tw-backdrop-blur: ; | |
| 534 | + | --tw-backdrop-brightness: ; | |
| 535 | + | --tw-backdrop-contrast: ; | |
| 536 | + | --tw-backdrop-grayscale: ; | |
| 537 | + | --tw-backdrop-hue-rotate: ; | |
| 538 | + | --tw-backdrop-invert: ; | |
| 539 | + | --tw-backdrop-opacity: ; | |
| 540 | + | --tw-backdrop-saturate: ; | |
| 541 | + | --tw-backdrop-sepia: ; | |
| 542 | + | } | |
| 543 | + | ||
| 544 | + | .my-2 { | |
| 545 | + | margin-top: 0.5rem; | |
| 546 | + | margin-bottom: 0.5rem; | |
| 547 | + | } | |
| 548 | + | ||
| 549 | + | .mb-4 { | |
| 550 | + | margin-bottom: 1rem; | |
| 551 | + | } | |
| 552 | + | ||
| 553 | + | .ml-2 { | |
| 554 | + | margin-left: 0.5rem; | |
| 555 | + | } | |
| 556 | + | ||
| 557 | + | .ml-4 { | |
| 558 | + | margin-left: 1rem; | |
| 559 | + | } | |
| 560 | + | ||
| 561 | + | .mr-2 { | |
| 562 | + | margin-right: 0.5rem; | |
| 563 | + | } | |
| 564 | + | ||
| 565 | + | .mt-4 { | |
| 566 | + | margin-top: 1rem; | |
| 567 | + | } | |
| 568 | + | ||
| 569 | + | .flex { | |
| 570 | + | display: flex; | |
| 571 | + | } | |
| 572 | + | ||
| 573 | + | .h-10 { | |
| 574 | + | height: 2.5rem; | |
| 575 | + | } | |
| 576 | + | ||
| 577 | + | .h-24 { | |
| 578 | + | height: 6rem; | |
| 579 | + | } | |
| 580 | + | ||
| 581 | + | .h-32 { | |
| 582 | + | height: 8rem; | |
| 583 | + | } | |
| 584 | + | ||
| 585 | + | .h-44 { | |
| 586 | + | height: 11rem; | |
| 587 | + | } | |
| 588 | + | ||
| 589 | + | .h-64 { | |
| 590 | + | height: 16rem; | |
| 591 | + | } | |
| 592 | + | ||
| 593 | + | .h-full { | |
| 594 | + | height: 100%; | |
| 595 | + | } | |
| 596 | + | ||
| 597 | + | .w-1\/5 { | |
| 598 | + | width: 20%; | |
| 599 | + | } | |
| 600 | + | ||
| 601 | + | .w-2\/6 { | |
| 602 | + | width: 33.333333%; | |
| 603 | + | } | |
| 604 | + | ||
| 605 | + | .w-4\/6 { | |
| 606 | + | width: 66.666667%; | |
| 607 | + | } | |
| 608 | + | ||
| 609 | + | .w-72 { | |
| 610 | + | width: 18rem; | |
| 611 | + | } | |
| 612 | + | ||
| 613 | + | .w-full { | |
| 614 | + | width: 100%; | |
| 615 | + | } | |
| 616 | + | ||
| 617 | + | .w-2\/3 { | |
| 618 | + | width: 66.666667%; | |
| 619 | + | } | |
| 620 | + | ||
| 621 | + | .w-screen { | |
| 622 | + | width: 100vw; | |
| 623 | + | } | |
| 624 | + | ||
| 625 | + | .w-96 { | |
| 626 | + | width: 24rem; | |
| 627 | + | } | |
| 628 | + | ||
| 629 | + | .flex-1 { | |
| 630 | + | flex: 1 1 0%; | |
| 631 | + | } | |
| 632 | + | ||
| 633 | + | .flex-grow { | |
| 634 | + | flex-grow: 1; | |
| 635 | + | } | |
| 636 | + | ||
| 637 | + | .flex-row { | |
| 638 | + | flex-direction: row; | |
| 639 | + | } | |
| 640 | + | ||
| 641 | + | .flex-col { | |
| 642 | + | flex-direction: column; | |
| 643 | + | } | |
| 644 | + | ||
| 645 | + | .items-center { | |
| 646 | + | align-items: center; | |
| 647 | + | } | |
| 648 | + | ||
| 649 | + | .justify-end { | |
| 650 | + | justify-content: flex-end; | |
| 651 | + | } | |
| 652 | + | ||
| 653 | + | .justify-center { | |
| 654 | + | justify-content: center; | |
| 655 | + | } | |
| 656 | + | ||
| 657 | + | .justify-between { | |
| 658 | + | justify-content: space-between; | |
| 659 | + | } | |
| 660 | + | ||
| 661 | + | .justify-items-center { | |
| 662 | + | justify-items: center; | |
| 663 | + | } | |
| 664 | + | ||
| 665 | + | .space-x-4 > :not([hidden]) ~ :not([hidden]) { | |
| 666 | + | --tw-space-x-reverse: 0; | |
| 667 | + | margin-right: calc(1rem * var(--tw-space-x-reverse)); | |
| 668 | + | margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); | |
| 669 | + | } | |
| 670 | + | ||
| 671 | + | .space-y-2 > :not([hidden]) ~ :not([hidden]) { | |
| 672 | + | --tw-space-y-reverse: 0; | |
| 673 | + | margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); | |
| 674 | + | margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); | |
| 675 | + | } | |
| 676 | + | ||
| 677 | + | .space-y-4 > :not([hidden]) ~ :not([hidden]) { | |
| 678 | + | --tw-space-y-reverse: 0; | |
| 679 | + | margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); | |
| 680 | + | margin-bottom: calc(1rem * var(--tw-space-y-reverse)); | |
| 681 | + | } | |
| 682 | + | ||
| 683 | + | .space-x-3 > :not([hidden]) ~ :not([hidden]) { | |
| 684 | + | --tw-space-x-reverse: 0; | |
| 685 | + | margin-right: calc(0.75rem * var(--tw-space-x-reverse)); | |
| 686 | + | margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))); | |
| 687 | + | } | |
| 688 | + | ||
| 689 | + | .space-y-3 > :not([hidden]) ~ :not([hidden]) { | |
| 690 | + | --tw-space-y-reverse: 0; | |
| 691 | + | margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); | |
| 692 | + | margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); | |
| 693 | + | } | |
| 694 | + | ||
| 695 | + | .overflow-y-scroll { | |
| 696 | + | overflow-y: scroll; | |
| 697 | + | } | |
| 698 | + | ||
| 699 | + | .rounded-lg { | |
| 700 | + | border-radius: 0.5rem; | |
| 701 | + | } | |
| 702 | + | ||
| 703 | + | .rounded-md { | |
| 704 | + | border-radius: 0.375rem; | |
| 705 | + | } | |
| 706 | + | ||
| 707 | + | .rounded-sm { | |
| 708 | + | border-radius: 0.125rem; | |
| 709 | + | } | |
| 710 | + | ||
| 711 | + | .border { | |
| 712 | + | border-width: 1px; | |
| 713 | + | } | |
| 714 | + | ||
| 715 | + | .border-gray-300 { | |
| 716 | + | --tw-border-opacity: 1; | |
| 717 | + | border-color: rgb(209 213 219 / var(--tw-border-opacity)); | |
| 718 | + | } | |
| 719 | + | ||
| 720 | + | .bg-gordonmascot-lblue { | |
| 721 | + | --tw-bg-opacity: 1; | |
| 722 | + | background-color: rgb(0 123 192 / var(--tw-bg-opacity)); | |
| 723 | + | } | |
| 724 | + | ||
| 725 | + | .bg-gordonmascot-mblue { | |
| 726 | + | --tw-bg-opacity: 1; | |
| 727 | + | background-color: rgb(0 82 147 / var(--tw-bg-opacity)); | |
| 728 | + | } | |
| 729 | + | ||
| 730 | + | .bg-gray-300 { | |
| 731 | + | --tw-bg-opacity: 1; | |
| 732 | + | background-color: rgb(209 213 219 / var(--tw-bg-opacity)); | |
| 733 | + | } | |
| 734 | + | ||
| 735 | + | .bg-transparent { | |
| 736 | + | background-color: transparent; | |
| 737 | + | } | |
| 738 | + | ||
| 739 | + | .bg-white { | |
| 740 | + | --tw-bg-opacity: 1; | |
| 741 | + | background-color: rgb(255 255 255 / var(--tw-bg-opacity)); | |
| 742 | + | } | |
| 743 | + | ||
| 744 | + | .bg-zinc-200 { | |
| 745 | + | --tw-bg-opacity: 1; | |
| 746 | + | background-color: rgb(228 228 231 / var(--tw-bg-opacity)); | |
| 747 | + | } | |
| 748 | + | ||
| 749 | + | .bg-gordonmascot-hblue { | |
| 750 | + | --tw-bg-opacity: 1; | |
| 751 | + | background-color: rgb(1 30 92 / var(--tw-bg-opacity)); | |
| 752 | + | } | |
| 753 | + | ||
| 754 | + | .bg-zinc-400 { | |
| 755 | + | --tw-bg-opacity: 1; | |
| 756 | + | background-color: rgb(161 161 170 / var(--tw-bg-opacity)); | |
| 757 | + | } | |
| 758 | + | ||
| 759 | + | .p-4 { | |
| 760 | + | padding: 1rem; | |
| 761 | + | } | |
| 762 | + | ||
| 763 | + | .p-2 { | |
| 764 | + | padding: 0.5rem; | |
| 765 | + | } | |
| 766 | + | ||
| 767 | + | .px-2 { | |
| 768 | + | padding-left: 0.5rem; | |
| 769 | + | padding-right: 0.5rem; | |
| 770 | + | } | |
| 771 | + | ||
| 772 | + | .px-6 { | |
| 773 | + | padding-left: 1.5rem; | |
| 774 | + | padding-right: 1.5rem; | |
| 775 | + | } | |
| 776 | + | ||
| 777 | + | .py-2 { | |
| 778 | + | padding-top: 0.5rem; | |
| 779 | + | padding-bottom: 0.5rem; | |
| 780 | + | } | |
| 781 | + | ||
| 782 | + | .px-4 { | |
| 783 | + | padding-left: 1rem; | |
| 784 | + | padding-right: 1rem; | |
| 785 | + | } | |
| 786 | + | ||
| 787 | + | .text-2xl { | |
| 788 | + | font-size: 1.5rem; | |
| 789 | + | line-height: 2rem; | |
| 790 | + | } | |
| 791 | + | ||
| 792 | + | .text-5xl { | |
| 793 | + | font-size: 3rem; | |
| 794 | + | line-height: 1; | |
| 795 | + | } | |
| 796 | + | ||
| 797 | + | .text-lg { | |
| 798 | + | font-size: 1.125rem; | |
| 799 | + | line-height: 1.75rem; | |
| 800 | + | } | |
| 801 | + | ||
| 802 | + | .text-sm { | |
| 803 | + | font-size: 0.875rem; | |
| 804 | + | line-height: 1.25rem; | |
| 805 | + | } | |
| 806 | + | ||
| 807 | + | .text-xl { | |
| 808 | + | font-size: 1.25rem; | |
| 809 | + | line-height: 1.75rem; | |
| 810 | + | } | |
| 811 | + | ||
| 812 | + | .font-semibold { | |
| 813 | + | font-weight: 600; | |
| 814 | + | } | |
| 815 | + | ||
| 816 | + | .tracking-tighter { | |
| 817 | + | letter-spacing: -0.05em; | |
| 818 | + | } | |
| 819 | + | ||
| 820 | + | .text-gordonmascot-hblue { | |
| 821 | + | --tw-text-opacity: 1; | |
| 822 | + | color: rgb(1 30 92 / var(--tw-text-opacity)); | |
| 823 | + | } | |
| 824 | + | ||
| 825 | + | .text-gordonmascot-mblue { | |
| 826 | + | --tw-text-opacity: 1; | |
| 827 | + | color: rgb(0 82 147 / var(--tw-text-opacity)); | |
| 828 | + | } | |
| 829 | + | ||
| 830 | + | .text-gray-100 { | |
| 831 | + | --tw-text-opacity: 1; | |
| 832 | + | color: rgb(243 244 246 / var(--tw-text-opacity)); | |
| 833 | + | } | |
| 834 | + | ||
| 835 | + | .text-gray-800 { | |
| 836 | + | --tw-text-opacity: 1; | |
| 837 | + | color: rgb(31 41 55 / var(--tw-text-opacity)); | |
| 838 | + | } | |
| 839 | + | ||
| 840 | + | .text-slate-400 { | |
| 841 | + | --tw-text-opacity: 1; | |
| 842 | + | color: rgb(148 163 184 / var(--tw-text-opacity)); | |
| 843 | + | } | |
| 844 | + | ||
| 845 | + | .text-slate-100 { | |
| 846 | + | --tw-text-opacity: 1; | |
| 847 | + | color: rgb(241 245 249 / var(--tw-text-opacity)); | |
| 848 | + | } | |
| 849 | + | ||
| 850 | + | .shadow { | |
| 851 | + | --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); | |
| 852 | + | --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); | |
| 853 | + | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); | |
| 854 | + | } | |
| 855 | + | ||
| 856 | + | .outline-none { | |
| 857 | + | outline: 2px solid transparent; | |
| 858 | + | outline-offset: 2px; | |
| 859 | + | } | |
| 860 | + | ||
| 861 | + | /* Import IBM Plex Fonts */ | |
| 862 | + | ||
| 863 | + | @font-face { | |
| 864 | + | font-family: "IBMPlexSans-Bold"; | |
| 865 | + | ||
| 866 | + | src: url("/assets/fonts/IBMPlex/IBMPlexSans-Bold.woff2") format("woff2"); | |
| 867 | + | ||
| 868 | + | font-weight: bold; | |
| 869 | + | ||
| 870 | + | font-style: normal; | |
| 871 | + | } | |
| 872 | + | ||
| 873 | + | @font-face { | |
| 874 | + | font-family: "IBMPlexSans-Regular"; | |
| 875 | + | ||
| 876 | + | src: url("/assets/fonts/IBMPlex/IBMPlexSans-Regular.woff2") format("woff2"); | |
| 877 | + | ||
| 878 | + | font-weight: normal; | |
| 879 | + | ||
| 880 | + | font-style: normal; | |
| 881 | + | } | |
| 882 | + | ||
| 883 | + | /* Import Jetbrains Mono Nerd Font */ | |
| 884 | + | ||
| 885 | + | @font-face { | |
| 886 | + | font-family: "JetBrainsMono-Nerd-Font-Regular"; | |
| 887 | + | ||
| 888 | + | src: url("/assets/fonts/JetBrainsMonoNerd/JetBrainsMonoNerdFontMono-Regular.woff2") | |
| 889 | + | format("woff2"); | |
| 890 | + | ||
| 891 | + | font-weight: normal; | |
| 892 | + | ||
| 893 | + | font-style: normal; | |
| 894 | + | } | |
| 895 | + | ||
| 896 | + | @font-face { | |
| 897 | + | font-family: "LilitaOne-Regular"; | |
| 898 | + | ||
| 899 | + | src: url("/assets/fonts/LilitaOne/LilitaOne-Regular.ttf") format("truetype"); | |
| 900 | + | ||
| 901 | + | font-weight: normal; | |
| 902 | + | ||
| 903 | + | font-style: normal; | |
| 904 | + | } | |
| 905 | + | ||
| 906 | + | .fade-me-out.htmx-swapping { | |
| 907 | + | opacity: 0; | |
| 908 | + | transition: opacity 1s ease-out; | |
| 909 | + | } | |
| 910 | + | ||
| 911 | + | /* View transition */ | |
| 912 | + | ||
| 913 | + | @keyframes fade-in { | |
| 914 | + | from { | |
| 915 | + | opacity: 0; | |
| 916 | + | } | |
| 917 | + | } | |
| 918 | + | ||
| 919 | + | @keyframes fade-out { | |
| 920 | + | to { | |
| 921 | + | opacity: 0; | |
| 922 | + | } | |
| 923 | + | } | |
| 924 | + | ||
| 925 | + | @keyframes slide-from-right { | |
| 926 | + | from { | |
| 927 | + | transform: translateX(90px); | |
| 928 | + | } | |
| 929 | + | } | |
| 930 | + | ||
| 931 | + | @keyframes slide-to-left { | |
| 932 | + | to { | |
| 933 | + | transform: translateX(-90px); | |
| 934 | + | } | |
| 935 | + | } | |
| 936 | + | ||
| 937 | + | .slide-it { | |
| 938 | + | view-transition-name: slide-it; | |
| 939 | + | } | |
| 940 | + | ||
| 941 | + | ::view-transition-old(slide-it) { | |
| 942 | + | animation: 180ms cubic-bezier(0.4, 0, 1, 1) both fade-out, | |
| 943 | + | 600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left; | |
| 944 | + | } | |
| 945 | + | ||
| 946 | + | ::view-transition-new(slide-it) { | |
| 947 | + | animation: 420ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in, | |
| 948 | + | 600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right; | |
| 949 | + | } | |
| 950 | + | ||
| 951 | + | .gordon-title { | |
| 952 | + | font-family: "LilitaOne-Regular", sans-serif; | |
| 953 | + | } | |
| 954 | + | ||
| 955 | + | .IBMPlexSans { | |
| 956 | + | font-family: "IBMPlexSans-Regular", sans-serif; | |
| 957 | + | } | |
| 958 | + | ||
| 959 | + | .circle-shadow { | |
| 960 | + | width: 100%; | |
| 961 | + | position: relative; | |
| 962 | + | } | |
| 963 | + | ||
| 964 | + | .circle-shadow::after { | |
| 965 | + | position: absolute; | |
| 966 | + | width: 50%; | |
| 967 | + | height: 0.4rem; | |
| 968 | + | margin: auto; | |
| 969 | + | background: rgba(0, 0, 0, 0.1); | |
| 970 | + | border-radius: 50%; | |
| 971 | + | z-index: -1; | |
| 972 | + | bottom: 2%; | |
| 973 | + | content: ""; | |
| 974 | + | box-shadow: 0 0 1px 0.3rem rgba(0, 0, 0, 0.1); | |
| 975 | + | } | |
| 976 | + | ||
| 977 | + | .iconoir { | |
| 978 | + | margin-right: 8px; | |
| 979 | + | } | |
| 980 | + | ||
| 981 | + | @media (min-width: 640px) { | |
| 982 | + | .sm\:h-24 { | |
| 983 | + | height: 6rem; | |
| 984 | + | } | |
| 985 | + | } | |
| 986 | + | ||
| 987 | + | @media (min-width: 768px) { | |
| 988 | + | .md\:w-1\/2 { | |
| 989 | + | width: 50%; | |
| 990 | + | } | |
| 991 | + | ||
| 992 | + | .md\:flex-row { | |
| 993 | + | flex-direction: row; | |
| 994 | + | } | |
| 995 | + | ||
| 996 | + | .md\:space-y-6 > :not([hidden]) ~ :not([hidden]) { | |
| 997 | + | --tw-space-y-reverse: 0; | |
| 998 | + | margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); | |
| 999 | + | margin-bottom: calc(1.5rem * var(--tw-space-y-reverse)); | |
| 1000 | + | } | |
| 1001 | + | ||
| 1002 | + | .md\:p-8 { | |
| 1003 | + | padding: 2rem; | |
| 1004 | + | } | |
| 1005 | + | ||
| 1006 | + | .md\:py-8 { | |
| 1007 | + | padding-top: 2rem; | |
| 1008 | + | padding-bottom: 2rem; | |
| 1009 | + | } | |
| 1010 | + | ||
| 1011 | + | .md\:pl-4 { | |
| 1012 | + | padding-left: 1rem; | |
| 1013 | + | } | |
| 1014 | + | ||
| 1015 | + | .md\:pt-10 { | |
| 1016 | + | padding-top: 2.5rem; | |
| 1017 | + | } | |
| 1018 | + | ||
| 1019 | + | .md\:text-2xl { | |
| 1020 | + | font-size: 1.5rem; | |
| 1021 | + | line-height: 2rem; | |
| 1022 | + | } | |
| 1023 | + | ||
| 1024 | + | .md\:text-3xl { | |
| 1025 | + | font-size: 1.875rem; | |
| 1026 | + | line-height: 2.25rem; | |
| 1027 | + | } | |
| 1028 | + | } | |
| 1029 | + | ||
| 1030 | + | @media (min-width: 1024px) { | |
| 1031 | + | .lg\:text-4xl { | |
| 1032 | + | font-size: 2.25rem; | |
| 1033 | + | line-height: 2.5rem; | |
| 1034 | + | } | |
| 1035 | + | } | |
| 1036 | + | ||
| 1037 | + | @media (min-width: 1280px) { | |
| 1038 | + | .xl\:h-48 { | |
| 1039 | + | height: 12rem; | |
| 1040 | + | } | |
| 1041 | + | ||
| 1042 | + | .xl\:text-5xl { | |
| 1043 | + | font-size: 3rem; | |
| 1044 | + | line-height: 1; | |
| 1045 | + | } | |
| 1046 | + | } | |
| @@ -0,0 +1,1046 @@ | |||||
| 1 | + | /** | |||
| 2 | + | * Path: internal/ui/public/assets/css/custom.css | |||
| 3 | + | * | |||
| 4 | + | * @format | |||
| 5 | + | */ | |||
| 6 | + | ||||
| 7 | + | /* Embeded path : assets/css/cutsom.css */ | |||
| 8 | + | ||||
| 9 | + | /*! tailwindcss v3.3.3 | MIT License | https://tailwindcss.com | |||
| 10 | + | */ | |||
| 11 | + | ||||
| 12 | + | /* | |||
| 13 | + | 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) | |||
| 14 | + | 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) | |||
| 15 | + | */ | |||
| 16 | + | ||||
| 17 | + | *, | |||
| 18 | + | ::before, | |||
| 19 | + | ::after { | |||
| 20 | + | box-sizing: border-box; | |||
| 21 | + | /* 1 */ | |||
| 22 | + | border-width: 0; | |||
| 23 | + | /* 2 */ | |||
| 24 | + | border-style: solid; | |||
| 25 | + | /* 2 */ | |||
| 26 | + | border-color: #e5e7eb; | |||
| 27 | + | /* 2 */ | |||
| 28 | + | } | |||
| 29 | + | ||||
| 30 | + | ::before, | |||
| 31 | + | ::after { | |||
| 32 | + | --tw-content: ''; | |||
| 33 | + | } | |||
| 34 | + | ||||
| 35 | + | /* | |||
| 36 | + | 1. Use a consistent sensible line-height in all browsers. | |||
| 37 | + | 2. Prevent adjustments of font size after orientation changes in iOS. | |||
| 38 | + | 3. Use a more readable tab size. | |||
| 39 | + | 4. Use the user's configured `sans` font-family by default. | |||
| 40 | + | 5. Use the user's configured `sans` font-feature-settings by default. | |||
| 41 | + | 6. Use the user's configured `sans` font-variation-settings by default. | |||
| 42 | + | */ | |||
| 43 | + | ||||
| 44 | + | html { | |||
| 45 | + | line-height: 1.5; | |||
| 46 | + | /* 1 */ | |||
| 47 | + | -webkit-text-size-adjust: 100%; | |||
| 48 | + | /* 2 */ | |||
| 49 | + | -moz-tab-size: 4; | |||
| 50 | + | /* 3 */ | |||
| 51 | + | -o-tab-size: 4; | |||
| 52 | + | tab-size: 4; | |||
| 53 | + | /* 3 */ | |||
| 54 | + | font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; | |||
| 55 | + | /* 4 */ | |||
| 56 | + | font-feature-settings: normal; | |||
| 57 | + | /* 5 */ | |||
| 58 | + | font-variation-settings: normal; | |||
| 59 | + | /* 6 */ | |||
| 60 | + | } | |||
| 61 | + | ||||
| 62 | + | /* | |||
| 63 | + | 1. Remove the margin in all browsers. | |||
| 64 | + | 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. | |||
| 65 | + | */ | |||
| 66 | + | ||||
| 67 | + | body { | |||
| 68 | + | margin: 0; | |||
| 69 | + | /* 1 */ | |||
| 70 | + | line-height: inherit; | |||
| 71 | + | /* 2 */ | |||
| 72 | + | } | |||
| 73 | + | ||||
| 74 | + | /* | |||
| 75 | + | 1. Add the correct height in Firefox. | |||
| 76 | + | 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) | |||
| 77 | + | 3. Ensure horizontal rules are visible by default. | |||
| 78 | + | */ | |||
| 79 | + | ||||
| 80 | + | hr { | |||
| 81 | + | height: 0; | |||
| 82 | + | /* 1 */ | |||
| 83 | + | color: inherit; | |||
| 84 | + | /* 2 */ | |||
| 85 | + | border-top-width: 1px; | |||
| 86 | + | /* 3 */ | |||
| 87 | + | } | |||
| 88 | + | ||||
| 89 | + | /* | |||
| 90 | + | Add the correct text decoration in Chrome, Edge, and Safari. | |||
| 91 | + | */ | |||
| 92 | + | ||||
| 93 | + | abbr:where([title]) { | |||
| 94 | + | -webkit-text-decoration: underline dotted; | |||
| 95 | + | text-decoration: underline dotted; | |||
| 96 | + | } | |||
| 97 | + | ||||
| 98 | + | /* | |||
| 99 | + | Remove the default font size and weight for headings. | |||
| 100 | + | */ | |||
| 101 | + | ||||
| 102 | + | h1, | |||
| 103 | + | h2, | |||
| 104 | + | h3, | |||
| 105 | + | h4, | |||
| 106 | + | h5, | |||
| 107 | + | h6 { | |||
| 108 | + | font-size: inherit; | |||
| 109 | + | font-weight: inherit; | |||
| 110 | + | } | |||
| 111 | + | ||||
| 112 | + | /* | |||
| 113 | + | Reset links to optimize for opt-in styling instead of opt-out. | |||
| 114 | + | */ | |||
| 115 | + | ||||
| 116 | + | a { | |||
| 117 | + | color: inherit; | |||
| 118 | + | text-decoration: inherit; | |||
| 119 | + | } | |||
| 120 | + | ||||
| 121 | + | /* | |||
| 122 | + | Add the correct font weight in Edge and Safari. | |||
| 123 | + | */ | |||
| 124 | + | ||||
| 125 | + | b, | |||
| 126 | + | strong { | |||
| 127 | + | font-weight: bolder; | |||
| 128 | + | } | |||
| 129 | + | ||||
| 130 | + | /* | |||
| 131 | + | 1. Use the user's configured `mono` font family by default. | |||
| 132 | + | 2. Correct the odd `em` font sizing in all browsers. | |||
| 133 | + | */ | |||
| 134 | + | ||||
| 135 | + | code, | |||
| 136 | + | kbd, | |||
| 137 | + | samp, | |||
| 138 | + | pre { | |||
| 139 | + | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; | |||
| 140 | + | /* 1 */ | |||
| 141 | + | font-size: 1em; | |||
| 142 | + | /* 2 */ | |||
| 143 | + | } | |||
| 144 | + | ||||
| 145 | + | /* | |||
| 146 | + | Add the correct font size in all browsers. | |||
| 147 | + | */ | |||
| 148 | + | ||||
| 149 | + | small { | |||
| 150 | + | font-size: 80%; | |||
| 151 | + | } | |||
| 152 | + | ||||
| 153 | + | /* | |||
| 154 | + | Prevent `sub` and `sup` elements from affecting the line height in all browsers. | |||
| 155 | + | */ | |||
| 156 | + | ||||
| 157 | + | sub, | |||
| 158 | + | sup { | |||
| 159 | + | font-size: 75%; | |||
| 160 | + | line-height: 0; | |||
| 161 | + | position: relative; | |||
| 162 | + | vertical-align: baseline; | |||
| 163 | + | } | |||
| 164 | + | ||||
| 165 | + | sub { | |||
| 166 | + | bottom: -0.25em; | |||
| 167 | + | } | |||
| 168 | + | ||||
| 169 | + | sup { | |||
| 170 | + | top: -0.5em; | |||
| 171 | + | } | |||
| 172 | + | ||||
| 173 | + | /* | |||
| 174 | + | 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) | |||
| 175 | + | 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) | |||
| 176 | + | 3. Remove gaps between table borders by default. | |||
| 177 | + | */ | |||
| 178 | + | ||||
| 179 | + | table { | |||
| 180 | + | text-indent: 0; | |||
| 181 | + | /* 1 */ | |||
| 182 | + | border-color: inherit; | |||
| 183 | + | /* 2 */ | |||
| 184 | + | border-collapse: collapse; | |||
| 185 | + | /* 3 */ | |||
| 186 | + | } | |||
| 187 | + | ||||
| 188 | + | /* | |||
| 189 | + | 1. Change the font styles in all browsers. | |||
| 190 | + | 2. Remove the margin in Firefox and Safari. | |||
| 191 | + | 3. Remove default padding in all browsers. | |||
| 192 | + | */ | |||
| 193 | + | ||||
| 194 | + | button, | |||
| 195 | + | input, | |||
| 196 | + | optgroup, | |||
| 197 | + | select, | |||
| 198 | + | textarea { | |||
| 199 | + | font-family: inherit; | |||
| 200 | + | /* 1 */ | |||
| 201 | + | font-feature-settings: inherit; | |||
| 202 | + | /* 1 */ | |||
| 203 | + | font-variation-settings: inherit; | |||
| 204 | + | /* 1 */ | |||
| 205 | + | font-size: 100%; | |||
| 206 | + | /* 1 */ | |||
| 207 | + | font-weight: inherit; | |||
| 208 | + | /* 1 */ | |||
| 209 | + | line-height: inherit; | |||
| 210 | + | /* 1 */ | |||
| 211 | + | color: inherit; | |||
| 212 | + | /* 1 */ | |||
| 213 | + | margin: 0; | |||
| 214 | + | /* 2 */ | |||
| 215 | + | padding: 0; | |||
| 216 | + | /* 3 */ | |||
| 217 | + | } | |||
| 218 | + | ||||
| 219 | + | /* | |||
| 220 | + | Remove the inheritance of text transform in Edge and Firefox. | |||
| 221 | + | */ | |||
| 222 | + | ||||
| 223 | + | button, | |||
| 224 | + | select { | |||
| 225 | + | text-transform: none; | |||
| 226 | + | } | |||
| 227 | + | ||||
| 228 | + | /* | |||
| 229 | + | 1. Correct the inability to style clickable types in iOS and Safari. | |||
| 230 | + | 2. Remove default button styles. | |||
| 231 | + | */ | |||
| 232 | + | ||||
| 233 | + | button, | |||
| 234 | + | [type='button'], | |||
| 235 | + | [type='reset'], | |||
| 236 | + | [type='submit'] { | |||
| 237 | + | -webkit-appearance: button; | |||
| 238 | + | /* 1 */ | |||
| 239 | + | background-color: transparent; | |||
| 240 | + | /* 2 */ | |||
| 241 | + | background-image: none; | |||
| 242 | + | /* 2 */ | |||
| 243 | + | } | |||
| 244 | + | ||||
| 245 | + | /* | |||
| 246 | + | Use the modern Firefox focus style for all focusable elements. | |||
| 247 | + | */ | |||
| 248 | + | ||||
| 249 | + | :-moz-focusring { | |||
| 250 | + | outline: auto; | |||
| 251 | + | } | |||
| 252 | + | ||||
| 253 | + | /* | |||
| 254 | + | Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) | |||
| 255 | + | */ | |||
| 256 | + | ||||
| 257 | + | :-moz-ui-invalid { | |||
| 258 | + | box-shadow: none; | |||
| 259 | + | } | |||
| 260 | + | ||||
| 261 | + | /* | |||
| 262 | + | Add the correct vertical alignment in Chrome and Firefox. | |||
| 263 | + | */ | |||
| 264 | + | ||||
| 265 | + | progress { | |||
| 266 | + | vertical-align: baseline; | |||
| 267 | + | } | |||
| 268 | + | ||||
| 269 | + | /* | |||
| 270 | + | Correct the cursor style of increment and decrement buttons in Safari. | |||
| 271 | + | */ | |||
| 272 | + | ||||
| 273 | + | ::-webkit-inner-spin-button, | |||
| 274 | + | ::-webkit-outer-spin-button { | |||
| 275 | + | height: auto; | |||
| 276 | + | } | |||
| 277 | + | ||||
| 278 | + | /* | |||
| 279 | + | 1. Correct the odd appearance in Chrome and Safari. | |||
| 280 | + | 2. Correct the outline style in Safari. | |||
| 281 | + | */ | |||
| 282 | + | ||||
| 283 | + | [type='search'] { | |||
| 284 | + | -webkit-appearance: textfield; | |||
| 285 | + | /* 1 */ | |||
| 286 | + | outline-offset: -2px; | |||
| 287 | + | /* 2 */ | |||
| 288 | + | } | |||
| 289 | + | ||||
| 290 | + | /* | |||
| 291 | + | Remove the inner padding in Chrome and Safari on macOS. | |||
| 292 | + | */ | |||
| 293 | + | ||||
| 294 | + | ::-webkit-search-decoration { | |||
| 295 | + | -webkit-appearance: none; | |||
| 296 | + | } | |||
| 297 | + | ||||
| 298 | + | /* | |||
| 299 | + | 1. Correct the inability to style clickable types in iOS and Safari. | |||
| 300 | + | 2. Change font properties to `inherit` in Safari. | |||
| 301 | + | */ | |||
| 302 | + | ||||
| 303 | + | ::-webkit-file-upload-button { | |||
| 304 | + | -webkit-appearance: button; | |||
| 305 | + | /* 1 */ | |||
| 306 | + | font: inherit; | |||
| 307 | + | /* 2 */ | |||
| 308 | + | } | |||
| 309 | + | ||||
| 310 | + | /* | |||
| 311 | + | Add the correct display in Chrome and Safari. | |||
| 312 | + | */ | |||
| 313 | + | ||||
| 314 | + | summary { | |||
| 315 | + | display: list-item; | |||
| 316 | + | } | |||
| 317 | + | ||||
| 318 | + | /* | |||
| 319 | + | Removes the default spacing and border for appropriate elements. | |||
| 320 | + | */ | |||
| 321 | + | ||||
| 322 | + | blockquote, | |||
| 323 | + | dl, | |||
| 324 | + | dd, | |||
| 325 | + | h1, | |||
| 326 | + | h2, | |||
| 327 | + | h3, | |||
| 328 | + | h4, | |||
| 329 | + | h5, | |||
| 330 | + | h6, | |||
| 331 | + | hr, | |||
| 332 | + | figure, | |||
| 333 | + | p, | |||
| 334 | + | pre { | |||
| 335 | + | margin: 0; | |||
| 336 | + | } | |||
| 337 | + | ||||
| 338 | + | fieldset { | |||
| 339 | + | margin: 0; | |||
| 340 | + | padding: 0; | |||
| 341 | + | } | |||
| 342 | + | ||||
| 343 | + | legend { | |||
| 344 | + | padding: 0; | |||
| 345 | + | } | |||
| 346 | + | ||||
| 347 | + | ol, | |||
| 348 | + | ul, | |||
| 349 | + | menu { | |||
| 350 | + | list-style: none; | |||
| 351 | + | margin: 0; | |||
| 352 | + | padding: 0; | |||
| 353 | + | } | |||
| 354 | + | ||||
| 355 | + | /* | |||
| 356 | + | Reset default styling for dialogs. | |||
| 357 | + | */ | |||
| 358 | + | ||||
| 359 | + | dialog { | |||
| 360 | + | padding: 0; | |||
| 361 | + | } | |||
| 362 | + | ||||
| 363 | + | /* | |||
| 364 | + | Prevent resizing textareas horizontally by default. | |||
| 365 | + | */ | |||
| 366 | + | ||||
| 367 | + | textarea { | |||
| 368 | + | resize: vertical; | |||
| 369 | + | } | |||
| 370 | + | ||||
| 371 | + | /* | |||
| 372 | + | 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) | |||
| 373 | + | 2. Set the default placeholder color to the user's configured gray 400 color. | |||
| 374 | + | */ | |||
| 375 | + | ||||
| 376 | + | input::-moz-placeholder, textarea::-moz-placeholder { | |||
| 377 | + | opacity: 1; | |||
| 378 | + | /* 1 */ | |||
| 379 | + | color: #9ca3af; | |||
| 380 | + | /* 2 */ | |||
| 381 | + | } | |||
| 382 | + | ||||
| 383 | + | input::placeholder, | |||
| 384 | + | textarea::placeholder { | |||
| 385 | + | opacity: 1; | |||
| 386 | + | /* 1 */ | |||
| 387 | + | color: #9ca3af; | |||
| 388 | + | /* 2 */ | |||
| 389 | + | } | |||
| 390 | + | ||||
| 391 | + | /* | |||
| 392 | + | Set the default cursor for buttons. | |||
| 393 | + | */ | |||
| 394 | + | ||||
| 395 | + | button, | |||
| 396 | + | [role="button"] { | |||
| 397 | + | cursor: pointer; | |||
| 398 | + | } | |||
| 399 | + | ||||
| 400 | + | /* | |||
| 401 | + | Make sure disabled buttons don't get the pointer cursor. | |||
| 402 | + | */ | |||
| 403 | + | ||||
| 404 | + | :disabled { | |||
| 405 | + | cursor: default; | |||
| 406 | + | } | |||
| 407 | + | ||||
| 408 | + | /* | |||
| 409 | + | 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) | |||
| 410 | + | 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) | |||
| 411 | + | This can trigger a poorly considered lint error in some tools but is included by design. | |||
| 412 | + | */ | |||
| 413 | + | ||||
| 414 | + | img, | |||
| 415 | + | svg, | |||
| 416 | + | video, | |||
| 417 | + | canvas, | |||
| 418 | + | audio, | |||
| 419 | + | iframe, | |||
| 420 | + | embed, | |||
| 421 | + | object { | |||
| 422 | + | display: block; | |||
| 423 | + | /* 1 */ | |||
| 424 | + | vertical-align: middle; | |||
| 425 | + | /* 2 */ | |||
| 426 | + | } | |||
| 427 | + | ||||
| 428 | + | /* | |||
| 429 | + | Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) | |||
| 430 | + | */ | |||
| 431 | + | ||||
| 432 | + | img, | |||
| 433 | + | video { | |||
| 434 | + | max-width: 100%; | |||
| 435 | + | height: auto; | |||
| 436 | + | } | |||
| 437 | + | ||||
| 438 | + | /* Make elements with the HTML hidden attribute stay hidden by default */ | |||
| 439 | + | ||||
| 440 | + | [hidden] { | |||
| 441 | + | display: none; | |||
| 442 | + | } | |||
| 443 | + | ||||
| 444 | + | *, ::before, ::after { | |||
| 445 | + | --tw-border-spacing-x: 0; | |||
| 446 | + | --tw-border-spacing-y: 0; | |||
| 447 | + | --tw-translate-x: 0; | |||
| 448 | + | --tw-translate-y: 0; | |||
| 449 | + | --tw-rotate: 0; | |||
| 450 | + | --tw-skew-x: 0; | |||
| 451 | + | --tw-skew-y: 0; | |||
| 452 | + | --tw-scale-x: 1; | |||
| 453 | + | --tw-scale-y: 1; | |||
| 454 | + | --tw-pan-x: ; | |||
| 455 | + | --tw-pan-y: ; | |||
| 456 | + | --tw-pinch-zoom: ; | |||
| 457 | + | --tw-scroll-snap-strictness: proximity; | |||
| 458 | + | --tw-gradient-from-position: ; | |||
| 459 | + | --tw-gradient-via-position: ; | |||
| 460 | + | --tw-gradient-to-position: ; | |||
| 461 | + | --tw-ordinal: ; | |||
| 462 | + | --tw-slashed-zero: ; | |||
| 463 | + | --tw-numeric-figure: ; | |||
| 464 | + | --tw-numeric-spacing: ; | |||
| 465 | + | --tw-numeric-fraction: ; | |||
| 466 | + | --tw-ring-inset: ; | |||
| 467 | + | --tw-ring-offset-width: 0px; | |||
| 468 | + | --tw-ring-offset-color: #fff; | |||
| 469 | + | --tw-ring-color: rgb(59 130 246 / 0.5); | |||
| 470 | + | --tw-ring-offset-shadow: 0 0 #0000; | |||
| 471 | + | --tw-ring-shadow: 0 0 #0000; | |||
| 472 | + | --tw-shadow: 0 0 #0000; | |||
| 473 | + | --tw-shadow-colored: 0 0 #0000; | |||
| 474 | + | --tw-blur: ; | |||
| 475 | + | --tw-brightness: ; | |||
| 476 | + | --tw-contrast: ; | |||
| 477 | + | --tw-grayscale: ; | |||
| 478 | + | --tw-hue-rotate: ; | |||
| 479 | + | --tw-invert: ; | |||
| 480 | + | --tw-saturate: ; | |||
| 481 | + | --tw-sepia: ; | |||
| 482 | + | --tw-drop-shadow: ; | |||
| 483 | + | --tw-backdrop-blur: ; | |||
| 484 | + | --tw-backdrop-brightness: ; | |||
| 485 | + | --tw-backdrop-contrast: ; | |||
| 486 | + | --tw-backdrop-grayscale: ; | |||
| 487 | + | --tw-backdrop-hue-rotate: ; | |||
| 488 | + | --tw-backdrop-invert: ; | |||
| 489 | + | --tw-backdrop-opacity: ; | |||
| 490 | + | --tw-backdrop-saturate: ; | |||
| 491 | + | --tw-backdrop-sepia: ; | |||
| 492 | + | } | |||
| 493 | + | ||||
| 494 | + | ::backdrop { | |||
| 495 | + | --tw-border-spacing-x: 0; | |||
| 496 | + | --tw-border-spacing-y: 0; | |||
| 497 | + | --tw-translate-x: 0; | |||
| 498 | + | --tw-translate-y: 0; | |||
| 499 | + | --tw-rotate: 0; | |||
| 500 | + | --tw-skew-x: 0; | |||
| 501 | + | --tw-skew-y: 0; | |||
| 502 | + | --tw-scale-x: 1; | |||
| 503 | + | --tw-scale-y: 1; | |||
| 504 | + | --tw-pan-x: ; | |||
| 505 | + | --tw-pan-y: ; | |||
| 506 | + | --tw-pinch-zoom: ; | |||
| 507 | + | --tw-scroll-snap-strictness: proximity; | |||
| 508 | + | --tw-gradient-from-position: ; | |||
| 509 | + | --tw-gradient-via-position: ; | |||
| 510 | + | --tw-gradient-to-position: ; | |||
| 511 | + | --tw-ordinal: ; | |||
| 512 | + | --tw-slashed-zero: ; | |||
| 513 | + | --tw-numeric-figure: ; | |||
| 514 | + | --tw-numeric-spacing: ; | |||
| 515 | + | --tw-numeric-fraction: ; | |||
| 516 | + | --tw-ring-inset: ; | |||
| 517 | + | --tw-ring-offset-width: 0px; | |||
| 518 | + | --tw-ring-offset-color: #fff; | |||
| 519 | + | --tw-ring-color: rgb(59 130 246 / 0.5); | |||
| 520 | + | --tw-ring-offset-shadow: 0 0 #0000; | |||
| 521 | + | --tw-ring-shadow: 0 0 #0000; | |||
| 522 | + | --tw-shadow: 0 0 #0000; | |||
| 523 | + | --tw-shadow-colored: 0 0 #0000; | |||
| 524 | + | --tw-blur: ; | |||
| 525 | + | --tw-brightness: ; | |||
| 526 | + | --tw-contrast: ; | |||
| 527 | + | --tw-grayscale: ; | |||
| 528 | + | --tw-hue-rotate: ; | |||
| 529 | + | --tw-invert: ; | |||
| 530 | + | --tw-saturate: ; | |||
| 531 | + | --tw-sepia: ; | |||
| 532 | + | --tw-drop-shadow: ; | |||
| 533 | + | --tw-backdrop-blur: ; | |||
| 534 | + | --tw-backdrop-brightness: ; | |||
| 535 | + | --tw-backdrop-contrast: ; | |||
| 536 | + | --tw-backdrop-grayscale: ; | |||
| 537 | + | --tw-backdrop-hue-rotate: ; | |||
| 538 | + | --tw-backdrop-invert: ; | |||
| 539 | + | --tw-backdrop-opacity: ; | |||
| 540 | + | --tw-backdrop-saturate: ; | |||
| 541 | + | --tw-backdrop-sepia: ; | |||
| 542 | + | } | |||
| 543 | + | ||||
| 544 | + | .my-2 { | |||
| 545 | + | margin-top: 0.5rem; | |||
| 546 | + | margin-bottom: 0.5rem; | |||
| 547 | + | } | |||
| 548 | + | ||||
| 549 | + | .mb-4 { | |||
| 550 | + | margin-bottom: 1rem; | |||
| 551 | + | } | |||
| 552 | + | ||||
| 553 | + | .ml-2 { | |||
| 554 | + | margin-left: 0.5rem; | |||
| 555 | + | } | |||
| 556 | + | ||||
| 557 | + | .ml-4 { | |||
| 558 | + | margin-left: 1rem; | |||
| 559 | + | } | |||
| 560 | + | ||||
| 561 | + | .mr-2 { | |||
| 562 | + | margin-right: 0.5rem; | |||
| 563 | + | } | |||
| 564 | + | ||||
| 565 | + | .mt-4 { | |||
| 566 | + | margin-top: 1rem; | |||
| 567 | + | } | |||
| 568 | + | ||||
| 569 | + | .flex { | |||
| 570 | + | display: flex; | |||
| 571 | + | } | |||
| 572 | + | ||||
| 573 | + | .h-10 { | |||
| 574 | + | height: 2.5rem; | |||
| 575 | + | } | |||
| 576 | + | ||||
| 577 | + | .h-24 { | |||
| 578 | + | height: 6rem; | |||
| 579 | + | } | |||
| 580 | + | ||||
| 581 | + | .h-32 { | |||
| 582 | + | height: 8rem; | |||
| 583 | + | } | |||
| 584 | + | ||||
| 585 | + | .h-44 { | |||
| 586 | + | height: 11rem; | |||
| 587 | + | } | |||
| 588 | + | ||||
| 589 | + | .h-64 { | |||
| 590 | + | height: 16rem; | |||
| 591 | + | } | |||
| 592 | + | ||||
| 593 | + | .h-full { | |||
| 594 | + | height: 100%; | |||
| 595 | + | } | |||
| 596 | + | ||||
| 597 | + | .w-1\/5 { | |||
| 598 | + | width: 20%; | |||
| 599 | + | } | |||
| 600 | + | ||||
| 601 | + | .w-2\/6 { | |||
| 602 | + | width: 33.333333%; | |||
| 603 | + | } | |||
| 604 | + | ||||
| 605 | + | .w-4\/6 { | |||
| 606 | + | width: 66.666667%; | |||
| 607 | + | } | |||
| 608 | + | ||||
| 609 | + | .w-72 { | |||
| 610 | + | width: 18rem; | |||
| 611 | + | } | |||
| 612 | + | ||||
| 613 | + | .w-full { | |||
| 614 | + | width: 100%; | |||
| 615 | + | } | |||
| 616 | + | ||||
| 617 | + | .w-2\/3 { | |||
| 618 | + | width: 66.666667%; | |||
| 619 | + | } | |||
| 620 | + | ||||
| 621 | + | .w-screen { | |||
| 622 | + | width: 100vw; | |||
| 623 | + | } | |||
| 624 | + | ||||
| 625 | + | .w-96 { | |||
| 626 | + | width: 24rem; | |||
| 627 | + | } | |||
| 628 | + | ||||
| 629 | + | .flex-1 { | |||
| 630 | + | flex: 1 1 0%; | |||
| 631 | + | } | |||
| 632 | + | ||||
| 633 | + | .flex-grow { | |||
| 634 | + | flex-grow: 1; | |||
| 635 | + | } | |||
| 636 | + | ||||
| 637 | + | .flex-row { | |||
| 638 | + | flex-direction: row; | |||
| 639 | + | } | |||
| 640 | + | ||||
| 641 | + | .flex-col { | |||
| 642 | + | flex-direction: column; | |||
| 643 | + | } | |||
| 644 | + | ||||
| 645 | + | .items-center { | |||
| 646 | + | align-items: center; | |||
| 647 | + | } | |||
| 648 | + | ||||
| 649 | + | .justify-end { | |||
| 650 | + | justify-content: flex-end; | |||
| 651 | + | } | |||
| 652 | + | ||||
| 653 | + | .justify-center { | |||
| 654 | + | justify-content: center; | |||
| 655 | + | } | |||
| 656 | + | ||||
| 657 | + | .justify-between { | |||
| 658 | + | justify-content: space-between; | |||
| 659 | + | } | |||
| 660 | + | ||||
| 661 | + | .justify-items-center { | |||
| 662 | + | justify-items: center; | |||
| 663 | + | } | |||
| 664 | + | ||||
| 665 | + | .space-x-4 > :not([hidden]) ~ :not([hidden]) { | |||
| 666 | + | --tw-space-x-reverse: 0; | |||
| 667 | + | margin-right: calc(1rem * var(--tw-space-x-reverse)); | |||
| 668 | + | margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse))); | |||
| 669 | + | } | |||
| 670 | + | ||||
| 671 | + | .space-y-2 > :not([hidden]) ~ :not([hidden]) { | |||
| 672 | + | --tw-space-y-reverse: 0; | |||
| 673 | + | margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse))); | |||
| 674 | + | margin-bottom: calc(0.5rem * var(--tw-space-y-reverse)); | |||
| 675 | + | } | |||
| 676 | + | ||||
| 677 | + | .space-y-4 > :not([hidden]) ~ :not([hidden]) { | |||
| 678 | + | --tw-space-y-reverse: 0; | |||
| 679 | + | margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse))); | |||
| 680 | + | margin-bottom: calc(1rem * var(--tw-space-y-reverse)); | |||
| 681 | + | } | |||
| 682 | + | ||||
| 683 | + | .space-x-3 > :not([hidden]) ~ :not([hidden]) { | |||
| 684 | + | --tw-space-x-reverse: 0; | |||
| 685 | + | margin-right: calc(0.75rem * var(--tw-space-x-reverse)); | |||
| 686 | + | margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse))); | |||
| 687 | + | } | |||
| 688 | + | ||||
| 689 | + | .space-y-3 > :not([hidden]) ~ :not([hidden]) { | |||
| 690 | + | --tw-space-y-reverse: 0; | |||
| 691 | + | margin-top: calc(0.75rem * calc(1 - var(--tw-space-y-reverse))); | |||
| 692 | + | margin-bottom: calc(0.75rem * var(--tw-space-y-reverse)); | |||
| 693 | + | } | |||
| 694 | + | ||||
| 695 | + | .overflow-y-scroll { | |||
| 696 | + | overflow-y: scroll; | |||
| 697 | + | } | |||
| 698 | + | ||||
| 699 | + | .rounded-lg { | |||
| 700 | + | border-radius: 0.5rem; | |||
| 701 | + | } | |||
| 702 | + | ||||
| 703 | + | .rounded-md { | |||
| 704 | + | border-radius: 0.375rem; | |||
| 705 | + | } | |||
| 706 | + | ||||
| 707 | + | .rounded-sm { | |||
| 708 | + | border-radius: 0.125rem; | |||
| 709 | + | } | |||
| 710 | + | ||||
| 711 | + | .border { | |||
| 712 | + | border-width: 1px; | |||
| 713 | + | } | |||
| 714 | + | ||||
| 715 | + | .border-gray-300 { | |||
| 716 | + | --tw-border-opacity: 1; | |||
| 717 | + | border-color: rgb(209 213 219 / var(--tw-border-opacity)); | |||
| 718 | + | } | |||
| 719 | + | ||||
| 720 | + | .bg-gordonmascot-lblue { | |||
| 721 | + | --tw-bg-opacity: 1; | |||
| 722 | + | background-color: rgb(0 123 192 / var(--tw-bg-opacity)); | |||
| 723 | + | } | |||
| 724 | + | ||||
| 725 | + | .bg-gordonmascot-mblue { | |||
| 726 | + | --tw-bg-opacity: 1; | |||
| 727 | + | background-color: rgb(0 82 147 / var(--tw-bg-opacity)); | |||
| 728 | + | } | |||
| 729 | + | ||||
| 730 | + | .bg-gray-300 { | |||
| 731 | + | --tw-bg-opacity: 1; | |||
| 732 | + | background-color: rgb(209 213 219 / var(--tw-bg-opacity)); | |||
| 733 | + | } | |||
| 734 | + | ||||
| 735 | + | .bg-transparent { | |||
| 736 | + | background-color: transparent; | |||
| 737 | + | } | |||
| 738 | + | ||||
| 739 | + | .bg-white { | |||
| 740 | + | --tw-bg-opacity: 1; | |||
| 741 | + | background-color: rgb(255 255 255 / var(--tw-bg-opacity)); | |||
| 742 | + | } | |||
| 743 | + | ||||
| 744 | + | .bg-zinc-200 { | |||
| 745 | + | --tw-bg-opacity: 1; | |||
| 746 | + | background-color: rgb(228 228 231 / var(--tw-bg-opacity)); | |||
| 747 | + | } | |||
| 748 | + | ||||
| 749 | + | .bg-gordonmascot-hblue { | |||
| 750 | + | --tw-bg-opacity: 1; | |||
| 751 | + | background-color: rgb(1 30 92 / var(--tw-bg-opacity)); | |||
| 752 | + | } | |||
| 753 | + | ||||
| 754 | + | .bg-zinc-400 { | |||
| 755 | + | --tw-bg-opacity: 1; | |||
| 756 | + | background-color: rgb(161 161 170 / var(--tw-bg-opacity)); | |||
| 757 | + | } | |||
| 758 | + | ||||
| 759 | + | .p-4 { | |||
| 760 | + | padding: 1rem; | |||
| 761 | + | } | |||
| 762 | + | ||||
| 763 | + | .p-2 { | |||
| 764 | + | padding: 0.5rem; | |||
| 765 | + | } | |||
| 766 | + | ||||
| 767 | + | .px-2 { | |||
| 768 | + | padding-left: 0.5rem; | |||
| 769 | + | padding-right: 0.5rem; | |||
| 770 | + | } | |||
| 771 | + | ||||
| 772 | + | .px-6 { | |||
| 773 | + | padding-left: 1.5rem; | |||
| 774 | + | padding-right: 1.5rem; | |||
| 775 | + | } | |||
| 776 | + | ||||
| 777 | + | .py-2 { | |||
| 778 | + | padding-top: 0.5rem; | |||
| 779 | + | padding-bottom: 0.5rem; | |||
| 780 | + | } | |||
| 781 | + | ||||
| 782 | + | .px-4 { | |||
| 783 | + | padding-left: 1rem; | |||
| 784 | + | padding-right: 1rem; | |||
| 785 | + | } | |||
| 786 | + | ||||
| 787 | + | .text-2xl { | |||
| 788 | + | font-size: 1.5rem; | |||
| 789 | + | line-height: 2rem; | |||
| 790 | + | } | |||
| 791 | + | ||||
| 792 | + | .text-5xl { | |||
| 793 | + | font-size: 3rem; | |||
| 794 | + | line-height: 1; | |||
| 795 | + | } | |||
| 796 | + | ||||
| 797 | + | .text-lg { | |||
| 798 | + | font-size: 1.125rem; | |||
| 799 | + | line-height: 1.75rem; | |||
| 800 | + | } | |||
| 801 | + | ||||
| 802 | + | .text-sm { | |||
| 803 | + | font-size: 0.875rem; | |||
| 804 | + | line-height: 1.25rem; | |||
| 805 | + | } | |||
| 806 | + | ||||
| 807 | + | .text-xl { | |||
| 808 | + | font-size: 1.25rem; | |||
| 809 | + | line-height: 1.75rem; | |||
| 810 | + | } | |||
| 811 | + | ||||
| 812 | + | .font-semibold { | |||
| 813 | + | font-weight: 600; | |||
| 814 | + | } | |||
| 815 | + | ||||
| 816 | + | .tracking-tighter { | |||
| 817 | + | letter-spacing: -0.05em; | |||
| 818 | + | } | |||
| 819 | + | ||||
| 820 | + | .text-gordonmascot-hblue { | |||
| 821 | + | --tw-text-opacity: 1; | |||
| 822 | + | color: rgb(1 30 92 / var(--tw-text-opacity)); | |||
| 823 | + | } | |||
| 824 | + | ||||
| 825 | + | .text-gordonmascot-mblue { | |||
| 826 | + | --tw-text-opacity: 1; | |||
| 827 | + | color: rgb(0 82 147 / var(--tw-text-opacity)); | |||
| 828 | + | } | |||
| 829 | + | ||||
| 830 | + | .text-gray-100 { | |||
| 831 | + | --tw-text-opacity: 1; | |||
| 832 | + | color: rgb(243 244 246 / var(--tw-text-opacity)); | |||
| 833 | + | } | |||
| 834 | + | ||||
| 835 | + | .text-gray-800 { | |||
| 836 | + | --tw-text-opacity: 1; | |||
| 837 | + | color: rgb(31 41 55 / var(--tw-text-opacity)); | |||
| 838 | + | } | |||
| 839 | + | ||||
| 840 | + | .text-slate-400 { | |||
| 841 | + | --tw-text-opacity: 1; | |||
| 842 | + | color: rgb(148 163 184 / var(--tw-text-opacity)); | |||
| 843 | + | } | |||
| 844 | + | ||||
| 845 | + | .text-slate-100 { | |||
| 846 | + | --tw-text-opacity: 1; | |||
| 847 | + | color: rgb(241 245 249 / var(--tw-text-opacity)); | |||
| 848 | + | } | |||
| 849 | + | ||||
| 850 | + | .shadow { | |||
| 851 | + | --tw-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1); | |||
| 852 | + | --tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color); | |||
| 853 | + | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); | |||
| 854 | + | } | |||
| 855 | + | ||||
| 856 | + | .outline-none { | |||
| 857 | + | outline: 2px solid transparent; | |||
| 858 | + | outline-offset: 2px; | |||
| 859 | + | } | |||
| 860 | + | ||||
| 861 | + | /* Import IBM Plex Fonts */ | |||
| 862 | + | ||||
| 863 | + | @font-face { | |||
| 864 | + | font-family: "IBMPlexSans-Bold"; | |||
| 865 | + | ||||
| 866 | + | src: url("/assets/fonts/IBMPlex/IBMPlexSans-Bold.woff2") format("woff2"); | |||
| 867 | + | ||||
| 868 | + | font-weight: bold; | |||
| 869 | + | ||||
| 870 | + | font-style: normal; | |||
| 871 | + | } | |||
| 872 | + | ||||
| 873 | + | @font-face { | |||
| 874 | + | font-family: "IBMPlexSans-Regular"; | |||
| 875 | + | ||||
| 876 | + | src: url("/assets/fonts/IBMPlex/IBMPlexSans-Regular.woff2") format("woff2"); | |||
| 877 | + | ||||
| 878 | + | font-weight: normal; | |||
| 879 | + | ||||
| 880 | + | font-style: normal; | |||
| 881 | + | } | |||
| 882 | + | ||||
| 883 | + | /* Import Jetbrains Mono Nerd Font */ | |||
| 884 | + | ||||
| 885 | + | @font-face { | |||
| 886 | + | font-family: "JetBrainsMono-Nerd-Font-Regular"; | |||
| 887 | + | ||||
| 888 | + | src: url("/assets/fonts/JetBrainsMonoNerd/JetBrainsMonoNerdFontMono-Regular.woff2") | |||
| 889 | + | format("woff2"); | |||
| 890 | + | ||||
| 891 | + | font-weight: normal; | |||
| 892 | + | ||||
| 893 | + | font-style: normal; | |||
| 894 | + | } | |||
| 895 | + | ||||
| 896 | + | @font-face { | |||
| 897 | + | font-family: "LilitaOne-Regular"; | |||
| 898 | + | ||||
| 899 | + | src: url("/assets/fonts/LilitaOne/LilitaOne-Regular.ttf") format("truetype"); | |||
| 900 | + | ||||
| 901 | + | font-weight: normal; | |||
| 902 | + | ||||
| 903 | + | font-style: normal; | |||
| 904 | + | } | |||
| 905 | + | ||||
| 906 | + | .fade-me-out.htmx-swapping { | |||
| 907 | + | opacity: 0; | |||
| 908 | + | transition: opacity 1s ease-out; | |||
| 909 | + | } | |||
| 910 | + | ||||
| 911 | + | /* View transition */ | |||
| 912 | + | ||||
| 913 | + | @keyframes fade-in { | |||
| 914 | + | from { | |||
| 915 | + | opacity: 0; | |||
| 916 | + | } | |||
| 917 | + | } | |||
| 918 | + | ||||
| 919 | + | @keyframes fade-out { | |||
| 920 | + | to { | |||
| 921 | + | opacity: 0; | |||
| 922 | + | } | |||
| 923 | + | } | |||
| 924 | + | ||||
| 925 | + | @keyframes slide-from-right { | |||
| 926 | + | from { | |||
| 927 | + | transform: translateX(90px); | |||
| 928 | + | } | |||
| 929 | + | } | |||
| 930 | + | ||||
| 931 | + | @keyframes slide-to-left { | |||
| 932 | + | to { | |||
| 933 | + | transform: translateX(-90px); | |||
| 934 | + | } | |||
| 935 | + | } | |||
| 936 | + | ||||
| 937 | + | .slide-it { | |||
| 938 | + | view-transition-name: slide-it; | |||
| 939 | + | } | |||
| 940 | + | ||||
| 941 | + | ::view-transition-old(slide-it) { | |||
| 942 | + | animation: 180ms cubic-bezier(0.4, 0, 1, 1) both fade-out, | |||
| 943 | + | 600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-to-left; | |||
| 944 | + | } | |||
| 945 | + | ||||
| 946 | + | ::view-transition-new(slide-it) { | |||
| 947 | + | animation: 420ms cubic-bezier(0, 0, 0.2, 1) 90ms both fade-in, | |||
| 948 | + | 600ms cubic-bezier(0.4, 0, 0.2, 1) both slide-from-right; | |||
| 949 | + | } | |||
| 950 | + | ||||
| 951 | + | .gordon-title { | |||
| 952 | + | font-family: "LilitaOne-Regular", sans-serif; | |||
| 953 | + | } | |||
| 954 | + | ||||
| 955 | + | .IBMPlexSans { | |||
| 956 | + | font-family: "IBMPlexSans-Regular", sans-serif; | |||
| 957 | + | } | |||
| 958 | + | ||||
| 959 | + | .circle-shadow { | |||
| 960 | + | width: 100%; | |||
| 961 | + | position: relative; | |||
| 962 | + | } | |||
| 963 | + | ||||
| 964 | + | .circle-shadow::after { | |||
| 965 | + | position: absolute; | |||
| 966 | + | width: 50%; | |||
| 967 | + | height: 0.4rem; | |||
| 968 | + | margin: auto; | |||
| 969 | + | background: rgba(0, 0, 0, 0.1); | |||
| 970 | + | border-radius: 50%; | |||
| 971 | + | z-index: -1; | |||
| 972 | + | bottom: 2%; | |||
| 973 | + | content: ""; | |||
| 974 | + | box-shadow: 0 0 1px 0.3rem rgba(0, 0, 0, 0.1); | |||
| 975 | + | } | |||
| 976 | + | ||||
| 977 | + | .iconoir { | |||
| 978 | + | margin-right: 8px; | |||
| 979 | + | } | |||
| 980 | + | ||||
| 981 | + | @media (min-width: 640px) { | |||
| 982 | + | .sm\:h-24 { | |||
| 983 | + | height: 6rem; | |||
| 984 | + | } | |||
| 985 | + | } | |||
| 986 | + | ||||
| 987 | + | @media (min-width: 768px) { | |||
| 988 | + | .md\:w-1\/2 { | |||
| 989 | + | width: 50%; | |||
| 990 | + | } | |||
| 991 | + | ||||
| 992 | + | .md\:flex-row { | |||
| 993 | + | flex-direction: row; | |||
| 994 | + | } | |||
| 995 | + | ||||
| 996 | + | .md\:space-y-6 > :not([hidden]) ~ :not([hidden]) { | |||
| 997 | + | --tw-space-y-reverse: 0; | |||
| 998 | + | margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse))); | |||
| 999 | + | margin-bottom: calc(1.5rem * var(--tw-space-y-reverse)); | |||
| 1000 | + | } | |||
| 1001 | + | ||||
| 1002 | + | .md\:p-8 { | |||
| 1003 | + | padding: 2rem; | |||
| 1004 | + | } | |||
| 1005 | + | ||||
| 1006 | + | .md\:py-8 { | |||
| 1007 | + | padding-top: 2rem; | |||
| 1008 | + | padding-bottom: 2rem; | |||
| 1009 | + | } | |||
| 1010 | + | ||||
| 1011 | + | .md\:pl-4 { | |||
| 1012 | + | padding-left: 1rem; | |||
| 1013 | + | } | |||
| 1014 | + | ||||
| 1015 | + | .md\:pt-10 { | |||
| 1016 | + | padding-top: 2.5rem; | |||
| 1017 | + | } | |||
| 1018 | + | ||||
| 1019 | + | .md\:text-2xl { | |||
| 1020 | + | font-size: 1.5rem; | |||
| 1021 | + | line-height: 2rem; | |||
| 1022 | + | } | |||
| 1023 | + | ||||
| 1024 | + | .md\:text-3xl { | |||
| 1025 | + | font-size: 1.875rem; | |||
| 1026 | + | line-height: 2.25rem; | |||
| 1027 | + | } | |||
| 1028 | + | } | |||
| 1029 | + | ||||
| 1030 | + | @media (min-width: 1024px) { | |||
| 1031 | + | .lg\:text-4xl { | |||
| 1032 | + | font-size: 2.25rem; | |||
| 1033 | + | line-height: 2.5rem; | |||
| 1034 | + | } | |||
| 1035 | + | } | |||
| 1036 | + | ||||
| 1037 | + | @media (min-width: 1280px) { | |||
| 1038 | + | .xl\:h-48 { | |||
| 1039 | + | height: 12rem; | |||
| 1040 | + | } | |||
| 1041 | + | ||||
| 1042 | + | .xl\:text-5xl { | |||
| 1043 | + | font-size: 3rem; | |||
| 1044 | + | line-height: 1; | |||
| 1045 | + | } | |||
| 1046 | + | } | |||
A internal/webui/public/assets/fonts/IBMPlex/IBMPlexSans-Bold.woff2 +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/assets/fonts/IBMPlex/IBMPlexSans-Light.woff2 +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/assets/fonts/IBMPlex/IBMPlexSans-Medium.woff2 +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/assets/fonts/IBMPlex/IBMPlexSans-Regular.woff2 +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/assets/fonts/IBMPlex/IBMPlexSans-Thin.woff2 +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/assets/fonts/JetBrainsMonoNerd/JetBrainsMonoNerdFont-Bold.woff2 +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/assets/fonts/JetBrainsMonoNerd/JetBrainsMonoNerdFont-Regular.woff2 +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/assets/fonts/JetBrainsMonoNerd/JetBrainsMonoNerdFontMono-Regular.ttf +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/assets/fonts/LilitaOne/LilitaOne-Regular.ttf +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/assets/fonts/LilitaOne/LilitaOne-Regular.woff2 +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/assets/imgs/gordon-mascot-hq-trsp.png +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/assets/imgs/gordon-mascot-mq-trsp.png +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/assets/imgs/gordon-mascot.png +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/favicon-16x16.png +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/favicon-32x32.png +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/favicon.ico +0 -0 binary file: no text diff
binary file: no text diff
A internal/webui/public/libs/alpine.min.js +5 -0 generated file: collapsed
A internal/webui/public/libs/chart.js +20 -0 too large to show in the browser
too large to show in the browser view raw
A internal/webui/public/libs/htmx-sse.js +322 -0
| @@ -0,0 +1,322 @@ | |||
| 1 | + | /* | |
| 2 | + | Server Sent Events Extension | |
| 3 | + | ============================ | |
| 4 | + | This extension adds support for Server Sent Events to htmx. See /www/extensions/sse.md for usage instructions. | |
| 5 | + | ||
| 6 | + | */ | |
| 7 | + | ||
| 8 | + | (function(){ | |
| 9 | + | ||
| 10 | + | /** @type {import("../htmx").HtmxInternalApi} */ | |
| 11 | + | var api; | |
| 12 | + | ||
| 13 | + | htmx.defineExtension("sse", { | |
| 14 | + | ||
| 15 | + | /** | |
| 16 | + | * Init saves the provided reference to the internal HTMX API. | |
| 17 | + | * | |
| 18 | + | * @param {import("../htmx").HtmxInternalApi} api | |
| 19 | + | * @returns void | |
| 20 | + | */ | |
| 21 | + | init: function(apiRef) { | |
| 22 | + | // store a reference to the internal API. | |
| 23 | + | api = apiRef; | |
| 24 | + | ||
| 25 | + | // set a function in the public API for creating new EventSource objects | |
| 26 | + | if (htmx.createEventSource == undefined) { | |
| 27 | + | htmx.createEventSource = createEventSource; | |
| 28 | + | } | |
| 29 | + | }, | |
| 30 | + | ||
| 31 | + | /** | |
| 32 | + | * onEvent handles all events passed to this extension. | |
| 33 | + | * | |
| 34 | + | * @param {string} name | |
| 35 | + | * @param {Event} evt | |
| 36 | + | * @returns void | |
| 37 | + | */ | |
| 38 | + | onEvent: function(name, evt) { | |
| 39 | + | ||
| 40 | + | switch (name) { | |
| 41 | + | ||
| 42 | + | // Try to remove remove an EventSource when elements are removed | |
| 43 | + | case "htmx:beforeCleanupElement": | |
| 44 | + | var internalData = api.getInternalData(evt.target) | |
| 45 | + | if (internalData.sseEventSource) { | |
| 46 | + | internalData.sseEventSource.close(); | |
| 47 | + | } | |
| 48 | + | return; | |
| 49 | + | ||
| 50 | + | // Try to create EventSources when elements are processed | |
| 51 | + | case "htmx:afterProcessNode": | |
| 52 | + | createEventSourceOnElement(evt.target); | |
| 53 | + | } | |
| 54 | + | } | |
| 55 | + | }); | |
| 56 | + | ||
| 57 | + | /////////////////////////////////////////////// | |
| 58 | + | // HELPER FUNCTIONS | |
| 59 | + | /////////////////////////////////////////////// | |
| 60 | + | ||
| 61 | + | ||
| 62 | + | /** | |
| 63 | + | * createEventSource is the default method for creating new EventSource objects. | |
| 64 | + | * it is hoisted into htmx.config.createEventSource to be overridden by the user, if needed. | |
| 65 | + | * | |
| 66 | + | * @param {string} url | |
| 67 | + | * @returns EventSource | |
| 68 | + | */ | |
| 69 | + | function createEventSource(url) { | |
| 70 | + | return new EventSource(url, {withCredentials:true}); | |
| 71 | + | } | |
| 72 | + | ||
| 73 | + | function splitOnWhitespace(trigger) { | |
| 74 | + | return trigger.trim().split(/\s+/); | |
| 75 | + | } | |
| 76 | + | ||
| 77 | + | function getLegacySSEURL(elt) { | |
| 78 | + | var legacySSEValue = api.getAttributeValue(elt, "hx-sse"); | |
| 79 | + | if (legacySSEValue) { | |
| 80 | + | var values = splitOnWhitespace(legacySSEValue); | |
| 81 | + | for (var i = 0; i < values.length; i++) { | |
| 82 | + | var value = values[i].split(/:(.+)/); | |
| 83 | + | if (value[0] === "connect") { | |
| 84 | + | return value[1]; | |
| 85 | + | } | |
| 86 | + | } | |
| 87 | + | } | |
| 88 | + | } | |
| 89 | + | ||
| 90 | + | function getLegacySSESwaps(elt) { | |
| 91 | + | var legacySSEValue = api.getAttributeValue(elt, "hx-sse"); | |
| 92 | + | var returnArr = []; | |
| 93 | + | if (legacySSEValue) { | |
| 94 | + | var values = splitOnWhitespace(legacySSEValue); | |
| 95 | + | for (var i = 0; i < values.length; i++) { | |
| 96 | + | var value = values[i].split(/:(.+)/); | |
| 97 | + | if (value[0] === "swap") { | |
| 98 | + | returnArr.push(value[1]); | |
| 99 | + | } | |
| 100 | + | } | |
| 101 | + | } | |
| 102 | + | return returnArr; | |
| 103 | + | } | |
| 104 | + | ||
| 105 | + | /** | |
| 106 | + | * createEventSourceOnElement creates a new EventSource connection on the provided element. | |
| 107 | + | * If a usable EventSource already exists, then it is returned. If not, then a new EventSource | |
| 108 | + | * is created and stored in the element's internalData. | |
| 109 | + | * @param {HTMLElement} elt | |
| 110 | + | * @param {number} retryCount | |
| 111 | + | * @returns {EventSource | null} | |
| 112 | + | */ | |
| 113 | + | function createEventSourceOnElement(elt, retryCount) { | |
| 114 | + | ||
| 115 | + | if (elt == null) { | |
| 116 | + | return null; | |
| 117 | + | } | |
| 118 | + | ||
| 119 | + | var internalData = api.getInternalData(elt); | |
| 120 | + | ||
| 121 | + | // get URL from element's attribute | |
| 122 | + | var sseURL = api.getAttributeValue(elt, "sse-connect"); | |
| 123 | + | ||
| 124 | + | ||
| 125 | + | if (sseURL == undefined) { | |
| 126 | + | var legacyURL = getLegacySSEURL(elt) | |
| 127 | + | if (legacyURL) { | |
| 128 | + | sseURL = legacyURL; | |
| 129 | + | } else { | |
| 130 | + | return null; | |
| 131 | + | } | |
| 132 | + | } | |
| 133 | + | ||
| 134 | + | // Connect to the EventSource | |
| 135 | + | var source = htmx.createEventSource(sseURL); | |
| 136 | + | internalData.sseEventSource = source; | |
| 137 | + | ||
| 138 | + | // Create event handlers | |
| 139 | + | source.onerror = function (err) { | |
| 140 | + | ||
| 141 | + | // Log an error event | |
| 142 | + | api.triggerErrorEvent(elt, "htmx:sseError", {error:err, source:source}); | |
| 143 | + | ||
| 144 | + | // If parent no longer exists in the document, then clean up this EventSource | |
| 145 | + | if (maybeCloseSSESource(elt)) { | |
| 146 | + | return; | |
| 147 | + | } | |
| 148 | + | ||
| 149 | + | // Otherwise, try to reconnect the EventSource | |
| 150 | + | if (source.readyState === EventSource.CLOSED) { | |
| 151 | + | retryCount = retryCount || 0; | |
| 152 | + | var timeout = Math.random() * (2 ^ retryCount) * 500; | |
| 153 | + | window.setTimeout(function() { | |
| 154 | + | createEventSourceOnElement(elt, Math.min(7, retryCount+1)); | |
| 155 | + | }, timeout); | |
| 156 | + | } | |
| 157 | + | }; | |
| 158 | + | ||
| 159 | + | source.onopen = function (evt) { | |
| 160 | + | api.triggerEvent(elt, "htmx:sseOpen", {source: source}); | |
| 161 | + | } | |
| 162 | + | ||
| 163 | + | // Add message handlers for every `sse-swap` attribute | |
| 164 | + | queryAttributeOnThisOrChildren(elt, "sse-swap").forEach(function(child) { | |
| 165 | + | ||
| 166 | + | var sseSwapAttr = api.getAttributeValue(child, "sse-swap"); | |
| 167 | + | if (sseSwapAttr) { | |
| 168 | + | var sseEventNames = sseSwapAttr.split(","); | |
| 169 | + | } else { | |
| 170 | + | var sseEventNames = getLegacySSESwaps(child); | |
| 171 | + | } | |
| 172 | + | ||
| 173 | + | for (var i = 0 ; i < sseEventNames.length ; i++) { | |
| 174 | + | var sseEventName = sseEventNames[i].trim(); | |
| 175 | + | var listener = function(event) { | |
| 176 | + | ||
| 177 | + | // If the parent is missing then close SSE and remove listener | |
| 178 | + | if (maybeCloseSSESource(elt)) { | |
| 179 | + | source.removeEventListener(sseEventName, listener); | |
| 180 | + | return; | |
| 181 | + | } | |
| 182 | + | ||
| 183 | + | // swap the response into the DOM and trigger a notification | |
| 184 | + | swap(child, event.data); | |
| 185 | + | api.triggerEvent(elt, "htmx:sseMessage", event); | |
| 186 | + | }; | |
| 187 | + | ||
| 188 | + | // Register the new listener | |
| 189 | + | api.getInternalData(elt).sseEventListener = listener; | |
| 190 | + | source.addEventListener(sseEventName, listener); | |
| 191 | + | } | |
| 192 | + | }); | |
| 193 | + | ||
| 194 | + | // Add message handlers for every `hx-trigger="sse:*"` attribute | |
| 195 | + | queryAttributeOnThisOrChildren(elt, "hx-trigger").forEach(function(child) { | |
| 196 | + | ||
| 197 | + | var sseEventName = api.getAttributeValue(child, "hx-trigger"); | |
| 198 | + | if (sseEventName == null) { | |
| 199 | + | return; | |
| 200 | + | } | |
| 201 | + | ||
| 202 | + | // Only process hx-triggers for events with the "sse:" prefix | |
| 203 | + | if (sseEventName.slice(0, 4) != "sse:") { | |
| 204 | + | return; | |
| 205 | + | } | |
| 206 | + | ||
| 207 | + | var listener = function(event) { | |
| 208 | + | ||
| 209 | + | // If parent is missing, then close SSE and remove listener | |
| 210 | + | if (maybeCloseSSESource(elt)) { | |
| 211 | + | source.removeEventListener(sseEventName, listener); | |
| 212 | + | return; | |
| 213 | + | } | |
| 214 | + | ||
| 215 | + | // Trigger events to be handled by the rest of htmx | |
| 216 | + | htmx.trigger(child, sseEventName, event); | |
| 217 | + | htmx.trigger(child, "htmx:sseMessage", event); | |
| 218 | + | } | |
| 219 | + | ||
| 220 | + | // Register the new listener | |
| 221 | + | api.getInternalData(elt).sseEventListener = listener; | |
| 222 | + | source.addEventListener(sseEventName.slice(4), listener); | |
| 223 | + | }); | |
| 224 | + | } | |
| 225 | + | ||
| 226 | + | /** | |
| 227 | + | * maybeCloseSSESource confirms that the parent element still exists. | |
| 228 | + | * If not, then any associated SSE source is closed and the function returns true. | |
| 229 | + | * | |
| 230 | + | * @param {HTMLElement} elt | |
| 231 | + | * @returns boolean | |
| 232 | + | */ | |
| 233 | + | function maybeCloseSSESource(elt) { | |
| 234 | + | if (!api.bodyContains(elt)) { | |
| 235 | + | var source = api.getInternalData(elt).sseEventSource; | |
| 236 | + | if (source != undefined) { | |
| 237 | + | source.close(); | |
| 238 | + | // source = null | |
| 239 | + | return true; | |
| 240 | + | } | |
| 241 | + | } | |
| 242 | + | return false; | |
| 243 | + | } | |
| 244 | + | ||
| 245 | + | /** | |
| 246 | + | * queryAttributeOnThisOrChildren returns all nodes that contain the requested attributeName, INCLUDING THE PROVIDED ROOT ELEMENT. | |
| 247 | + | * | |
| 248 | + | * @param {HTMLElement} elt | |
| 249 | + | * @param {string} attributeName | |
| 250 | + | */ | |
| 251 | + | function queryAttributeOnThisOrChildren(elt, attributeName) { | |
| 252 | + | ||
| 253 | + | var result = []; | |
| 254 | + | ||
| 255 | + | // If the parent element also contains the requested attribute, then add it to the results too. | |
| 256 | + | if (api.hasAttribute(elt, attributeName) || api.hasAttribute(elt, "hx-sse")) { | |
| 257 | + | result.push(elt); | |
| 258 | + | } | |
| 259 | + | ||
| 260 | + | // Search all child nodes that match the requested attribute | |
| 261 | + | elt.querySelectorAll("[" + attributeName + "], [data-" + attributeName + "], [hx-sse], [data-hx-sse]").forEach(function(node) { | |
| 262 | + | result.push(node); | |
| 263 | + | }); | |
| 264 | + | ||
| 265 | + | return result; | |
| 266 | + | } | |
| 267 | + | ||
| 268 | + | /** | |
| 269 | + | * @param {HTMLElement} elt | |
| 270 | + | * @param {string} content | |
| 271 | + | */ | |
| 272 | + | function swap(elt, content) { | |
| 273 | + | ||
| 274 | + | api.withExtensions(elt, function(extension) { | |
| 275 | + | content = extension.transformResponse(content, null, elt); | |
| 276 | + | }); | |
| 277 | + | ||
| 278 | + | var swapSpec = api.getSwapSpecification(elt); | |
| 279 | + | var target = api.getTarget(elt); | |
| 280 | + | var settleInfo = api.makeSettleInfo(elt); | |
| 281 | + | ||
| 282 | + | api.selectAndSwap(swapSpec.swapStyle, target, elt, content, settleInfo); | |
| 283 | + | ||
| 284 | + | settleInfo.elts.forEach(function (elt) { | |
| 285 | + | if (elt.classList) { | |
| 286 | + | elt.classList.add(htmx.config.settlingClass); | |
| 287 | + | } | |
| 288 | + | api.triggerEvent(elt, 'htmx:beforeSettle'); | |
| 289 | + | }); | |
| 290 | + | ||
| 291 | + | // Handle settle tasks (with delay if requested) | |
| 292 | + | if (swapSpec.settleDelay > 0) { | |
| 293 | + | setTimeout(doSettle(settleInfo), swapSpec.settleDelay); | |
| 294 | + | } else { | |
| 295 | + | doSettle(settleInfo)(); | |
| 296 | + | } | |
| 297 | + | } | |
| 298 | + | ||
| 299 | + | /** | |
| 300 | + | * doSettle mirrors much of the functionality in htmx that | |
| 301 | + | * settles elements after their content has been swapped. | |
| 302 | + | * TODO: this should be published by htmx, and not duplicated here | |
| 303 | + | * @param {import("../htmx").HtmxSettleInfo} settleInfo | |
| 304 | + | * @returns () => void | |
| 305 | + | */ | |
| 306 | + | function doSettle(settleInfo) { | |
| 307 | + | ||
| 308 | + | return function() { | |
| 309 | + | settleInfo.tasks.forEach(function (task) { | |
| 310 | + | task.call(); | |
| 311 | + | }); | |
| 312 | + | ||
| 313 | + | settleInfo.elts.forEach(function (elt) { | |
| 314 | + | if (elt.classList) { | |
| 315 | + | elt.classList.remove(htmx.config.settlingClass); | |
| 316 | + | } | |
| 317 | + | api.triggerEvent(elt, 'htmx:afterSettle'); | |
| 318 | + | }); | |
| 319 | + | } | |
| 320 | + | } | |
| 321 | + | ||
| 322 | + | })();⏎̸ | |
| @@ -0,0 +1,322 @@ | |||||
| 1 | + | /* | |||
| 2 | + | Server Sent Events Extension | |||
| 3 | + | ============================ | |||
| 4 | + | This extension adds support for Server Sent Events to htmx. See /www/extensions/sse.md for usage instructions. | |||
| 5 | + | ||||
| 6 | + | */ | |||
| 7 | + | ||||
| 8 | + | (function(){ | |||
| 9 | + | ||||
| 10 | + | /** @type {import("../htmx").HtmxInternalApi} */ | |||
| 11 | + | var api; | |||
| 12 | + | ||||
| 13 | + | htmx.defineExtension("sse", { | |||
| 14 | + | ||||
| 15 | + | /** | |||
| 16 | + | * Init saves the provided reference to the internal HTMX API. | |||
| 17 | + | * | |||
| 18 | + | * @param {import("../htmx").HtmxInternalApi} api | |||
| 19 | + | * @returns void | |||
| 20 | + | */ | |||
| 21 | + | init: function(apiRef) { | |||
| 22 | + | // store a reference to the internal API. | |||
| 23 | + | api = apiRef; | |||
| 24 | + | ||||
| 25 | + | // set a function in the public API for creating new EventSource objects | |||
| 26 | + | if (htmx.createEventSource == undefined) { | |||
| 27 | + | htmx.createEventSource = createEventSource; | |||
| 28 | + | } | |||
| 29 | + | }, | |||
| 30 | + | ||||
| 31 | + | /** | |||
| 32 | + | * onEvent handles all events passed to this extension. | |||
| 33 | + | * | |||
| 34 | + | * @param {string} name | |||
| 35 | + | * @param {Event} evt | |||
| 36 | + | * @returns void | |||
| 37 | + | */ | |||
| 38 | + | onEvent: function(name, evt) { | |||
| 39 | + | ||||
| 40 | + | switch (name) { | |||
| 41 | + | ||||
| 42 | + | // Try to remove remove an EventSource when elements are removed | |||
| 43 | + | case "htmx:beforeCleanupElement": | |||
| 44 | + | var internalData = api.getInternalData(evt.target) | |||
| 45 | + | if (internalData.sseEventSource) { | |||
| 46 | + | internalData.sseEventSource.close(); | |||
| 47 | + | } | |||
| 48 | + | return; | |||
| 49 | + | ||||
| 50 | + | // Try to create EventSources when elements are processed | |||
| 51 | + | case "htmx:afterProcessNode": | |||
| 52 | + | createEventSourceOnElement(evt.target); | |||
| 53 | + | } | |||
| 54 | + | } | |||
| 55 | + | }); | |||
| 56 | + | ||||
| 57 | + | /////////////////////////////////////////////// | |||
| 58 | + | // HELPER FUNCTIONS | |||
| 59 | + | /////////////////////////////////////////////// | |||
| 60 | + | ||||
| 61 | + | ||||
| 62 | + | /** | |||
| 63 | + | * createEventSource is the default method for creating new EventSource objects. | |||
| 64 | + | * it is hoisted into htmx.config.createEventSource to be overridden by the user, if needed. | |||
| 65 | + | * | |||
| 66 | + | * @param {string} url | |||
| 67 | + | * @returns EventSource | |||
| 68 | + | */ | |||
| 69 | + | function createEventSource(url) { | |||
| 70 | + | return new EventSource(url, {withCredentials:true}); | |||
| 71 | + | } | |||
| 72 | + | ||||
| 73 | + | function splitOnWhitespace(trigger) { | |||
| 74 | + | return trigger.trim().split(/\s+/); | |||
| 75 | + | } | |||
| 76 | + | ||||
| 77 | + | function getLegacySSEURL(elt) { | |||
| 78 | + | var legacySSEValue = api.getAttributeValue(elt, "hx-sse"); | |||
| 79 | + | if (legacySSEValue) { | |||
| 80 | + | var values = splitOnWhitespace(legacySSEValue); | |||
| 81 | + | for (var i = 0; i < values.length; i++) { | |||
| 82 | + | var value = values[i].split(/:(.+)/); | |||
| 83 | + | if (value[0] === "connect") { | |||
| 84 | + | return value[1]; | |||
| 85 | + | } | |||
| 86 | + | } | |||
| 87 | + | } | |||
| 88 | + | } | |||
| 89 | + | ||||
| 90 | + | function getLegacySSESwaps(elt) { | |||
| 91 | + | var legacySSEValue = api.getAttributeValue(elt, "hx-sse"); | |||
| 92 | + | var returnArr = []; | |||
| 93 | + | if (legacySSEValue) { | |||
| 94 | + | var values = splitOnWhitespace(legacySSEValue); | |||
| 95 | + | for (var i = 0; i < values.length; i++) { | |||
| 96 | + | var value = values[i].split(/:(.+)/); | |||
| 97 | + | if (value[0] === "swap") { | |||
| 98 | + | returnArr.push(value[1]); | |||
| 99 | + | } | |||
| 100 | + | } | |||
| 101 | + | } | |||
| 102 | + | return returnArr; | |||
| 103 | + | } | |||
| 104 | + | ||||
| 105 | + | /** | |||
| 106 | + | * createEventSourceOnElement creates a new EventSource connection on the provided element. | |||
| 107 | + | * If a usable EventSource already exists, then it is returned. If not, then a new EventSource | |||
| 108 | + | * is created and stored in the element's internalData. | |||
| 109 | + | * @param {HTMLElement} elt | |||
| 110 | + | * @param {number} retryCount | |||
| 111 | + | * @returns {EventSource | null} | |||
| 112 | + | */ | |||
| 113 | + | function createEventSourceOnElement(elt, retryCount) { | |||
| 114 | + | ||||
| 115 | + | if (elt == null) { | |||
| 116 | + | return null; | |||
| 117 | + | } | |||
| 118 | + | ||||
| 119 | + | var internalData = api.getInternalData(elt); | |||
| 120 | + | ||||
| 121 | + | // get URL from element's attribute | |||
| 122 | + | var sseURL = api.getAttributeValue(elt, "sse-connect"); | |||
| 123 | + | ||||
| 124 | + | ||||
| 125 | + | if (sseURL == undefined) { | |||
| 126 | + | var legacyURL = getLegacySSEURL(elt) | |||
| 127 | + | if (legacyURL) { | |||
| 128 | + | sseURL = legacyURL; | |||
| 129 | + | } else { | |||
| 130 | + | return null; | |||
| 131 | + | } | |||
| 132 | + | } | |||
| 133 | + | ||||
| 134 | + | // Connect to the EventSource | |||
| 135 | + | var source = htmx.createEventSource(sseURL); | |||
| 136 | + | internalData.sseEventSource = source; | |||
| 137 | + | ||||
| 138 | + | // Create event handlers | |||
| 139 | + | source.onerror = function (err) { | |||
| 140 | + | ||||
| 141 | + | // Log an error event | |||
| 142 | + | api.triggerErrorEvent(elt, "htmx:sseError", {error:err, source:source}); | |||
| 143 | + | ||||
| 144 | + | // If parent no longer exists in the document, then clean up this EventSource | |||
| 145 | + | if (maybeCloseSSESource(elt)) { | |||
| 146 | + | return; | |||
| 147 | + | } | |||
| 148 | + | ||||
| 149 | + | // Otherwise, try to reconnect the EventSource | |||
| 150 | + | if (source.readyState === EventSource.CLOSED) { | |||
| 151 | + | retryCount = retryCount || 0; | |||
| 152 | + | var timeout = Math.random() * (2 ^ retryCount) * 500; | |||
| 153 | + | window.setTimeout(function() { | |||
| 154 | + | createEventSourceOnElement(elt, Math.min(7, retryCount+1)); | |||
| 155 | + | }, timeout); | |||
| 156 | + | } | |||
| 157 | + | }; | |||
| 158 | + | ||||
| 159 | + | source.onopen = function (evt) { | |||
| 160 | + | api.triggerEvent(elt, "htmx:sseOpen", {source: source}); | |||
| 161 | + | } | |||
| 162 | + | ||||
| 163 | + | // Add message handlers for every `sse-swap` attribute | |||
| 164 | + | queryAttributeOnThisOrChildren(elt, "sse-swap").forEach(function(child) { | |||
| 165 | + | ||||
| 166 | + | var sseSwapAttr = api.getAttributeValue(child, "sse-swap"); | |||
| 167 | + | if (sseSwapAttr) { | |||
| 168 | + | var sseEventNames = sseSwapAttr.split(","); | |||
| 169 | + | } else { | |||
| 170 | + | var sseEventNames = getLegacySSESwaps(child); | |||
| 171 | + | } | |||
| 172 | + | ||||
| 173 | + | for (var i = 0 ; i < sseEventNames.length ; i++) { | |||
| 174 | + | var sseEventName = sseEventNames[i].trim(); | |||
| 175 | + | var listener = function(event) { | |||
| 176 | + | ||||
| 177 | + | // If the parent is missing then close SSE and remove listener | |||
| 178 | + | if (maybeCloseSSESource(elt)) { | |||
| 179 | + | source.removeEventListener(sseEventName, listener); | |||
| 180 | + | return; | |||
| 181 | + | } | |||
| 182 | + | ||||
| 183 | + | // swap the response into the DOM and trigger a notification | |||
| 184 | + | swap(child, event.data); | |||
| 185 | + | api.triggerEvent(elt, "htmx:sseMessage", event); | |||
| 186 | + | }; | |||
| 187 | + | ||||
| 188 | + | // Register the new listener | |||
| 189 | + | api.getInternalData(elt).sseEventListener = listener; | |||
| 190 | + | source.addEventListener(sseEventName, listener); | |||
| 191 | + | } | |||
| 192 | + | }); | |||
| 193 | + | ||||
| 194 | + | // Add message handlers for every `hx-trigger="sse:*"` attribute | |||
| 195 | + | queryAttributeOnThisOrChildren(elt, "hx-trigger").forEach(function(child) { | |||
| 196 | + | ||||
| 197 | + | var sseEventName = api.getAttributeValue(child, "hx-trigger"); | |||
| 198 | + | if (sseEventName == null) { | |||
| 199 | + | return; | |||
| 200 | + | } | |||
| 201 | + | ||||
| 202 | + | // Only process hx-triggers for events with the "sse:" prefix | |||
| 203 | + | if (sseEventName.slice(0, 4) != "sse:") { | |||
| 204 | + | return; | |||
| 205 | + | } | |||
| 206 | + | ||||
| 207 | + | var listener = function(event) { | |||
| 208 | + | ||||
| 209 | + | // If parent is missing, then close SSE and remove listener | |||
| 210 | + | if (maybeCloseSSESource(elt)) { | |||
| 211 | + | source.removeEventListener(sseEventName, listener); | |||
| 212 | + | return; | |||
| 213 | + | } | |||
| 214 | + | ||||
| 215 | + | // Trigger events to be handled by the rest of htmx | |||
| 216 | + | htmx.trigger(child, sseEventName, event); | |||
| 217 | + | htmx.trigger(child, "htmx:sseMessage", event); | |||
| 218 | + | } | |||
| 219 | + | ||||
| 220 | + | // Register the new listener | |||
| 221 | + | api.getInternalData(elt).sseEventListener = listener; | |||
| 222 | + | source.addEventListener(sseEventName.slice(4), listener); | |||
| 223 | + | }); | |||
| 224 | + | } | |||
| 225 | + | ||||
| 226 | + | /** | |||
| 227 | + | * maybeCloseSSESource confirms that the parent element still exists. | |||
| 228 | + | * If not, then any associated SSE source is closed and the function returns true. | |||
| 229 | + | * | |||
| 230 | + | * @param {HTMLElement} elt | |||
| 231 | + | * @returns boolean | |||
| 232 | + | */ | |||
| 233 | + | function maybeCloseSSESource(elt) { | |||
| 234 | + | if (!api.bodyContains(elt)) { | |||
| 235 | + | var source = api.getInternalData(elt).sseEventSource; | |||
| 236 | + | if (source != undefined) { | |||
| 237 | + | source.close(); | |||
| 238 | + | // source = null | |||
| 239 | + | return true; | |||
| 240 | + | } | |||
| 241 | + | } | |||
| 242 | + | return false; | |||
| 243 | + | } | |||
| 244 | + | ||||
| 245 | + | /** | |||
| 246 | + | * queryAttributeOnThisOrChildren returns all nodes that contain the requested attributeName, INCLUDING THE PROVIDED ROOT ELEMENT. | |||
| 247 | + | * | |||
| 248 | + | * @param {HTMLElement} elt | |||
| 249 | + | * @param {string} attributeName | |||
| 250 | + | */ | |||
| 251 | + | function queryAttributeOnThisOrChildren(elt, attributeName) { | |||
| 252 | + | ||||
| 253 | + | var result = []; | |||
| 254 | + | ||||
| 255 | + | // If the parent element also contains the requested attribute, then add it to the results too. | |||
| 256 | + | if (api.hasAttribute(elt, attributeName) || api.hasAttribute(elt, "hx-sse")) { | |||
| 257 | + | result.push(elt); | |||
| 258 | + | } | |||
| 259 | + | ||||
| 260 | + | // Search all child nodes that match the requested attribute | |||
| 261 | + | elt.querySelectorAll("[" + attributeName + "], [data-" + attributeName + "], [hx-sse], [data-hx-sse]").forEach(function(node) { | |||
| 262 | + | result.push(node); | |||
| 263 | + | }); | |||
| 264 | + | ||||
| 265 | + | return result; | |||
| 266 | + | } | |||
| 267 | + | ||||
| 268 | + | /** | |||
| 269 | + | * @param {HTMLElement} elt | |||
| 270 | + | * @param {string} content | |||
| 271 | + | */ | |||
| 272 | + | function swap(elt, content) { | |||
| 273 | + | ||||
| 274 | + | api.withExtensions(elt, function(extension) { | |||
| 275 | + | content = extension.transformResponse(content, null, elt); | |||
| 276 | + | }); | |||
| 277 | + | ||||
| 278 | + | var swapSpec = api.getSwapSpecification(elt); | |||
| 279 | + | var target = api.getTarget(elt); | |||
| 280 | + | var settleInfo = api.makeSettleInfo(elt); | |||
| 281 | + | ||||
| 282 | + | api.selectAndSwap(swapSpec.swapStyle, target, elt, content, settleInfo); | |||
| 283 | + | ||||
| 284 | + | settleInfo.elts.forEach(function (elt) { | |||
| 285 | + | if (elt.classList) { | |||
| 286 | + | elt.classList.add(htmx.config.settlingClass); | |||
| 287 | + | } | |||
| 288 | + | api.triggerEvent(elt, 'htmx:beforeSettle'); | |||
| 289 | + | }); | |||
| 290 | + | ||||
| 291 | + | // Handle settle tasks (with delay if requested) | |||
| 292 | + | if (swapSpec.settleDelay > 0) { | |||
| 293 | + | setTimeout(doSettle(settleInfo), swapSpec.settleDelay); | |||
| 294 | + | } else { | |||
| 295 | + | doSettle(settleInfo)(); | |||
| 296 | + | } | |||
| 297 | + | } | |||
| 298 | + | ||||
| 299 | + | /** | |||
| 300 | + | * doSettle mirrors much of the functionality in htmx that | |||
| 301 | + | * settles elements after their content has been swapped. | |||
| 302 | + | * TODO: this should be published by htmx, and not duplicated here | |||
| 303 | + | * @param {import("../htmx").HtmxSettleInfo} settleInfo | |||
| 304 | + | * @returns () => void | |||
| 305 | + | */ | |||
| 306 | + | function doSettle(settleInfo) { | |||
| 307 | + | ||||
| 308 | + | return function() { | |||
| 309 | + | settleInfo.tasks.forEach(function (task) { | |||
| 310 | + | task.call(); | |||
| 311 | + | }); | |||
| 312 | + | ||||
| 313 | + | settleInfo.elts.forEach(function (elt) { | |||
| 314 | + | if (elt.classList) { | |||
| 315 | + | elt.classList.remove(htmx.config.settlingClass); | |||
| 316 | + | } | |||
| 317 | + | api.triggerEvent(elt, 'htmx:afterSettle'); | |||
| 318 | + | }); | |||
| 319 | + | } | |||
| 320 | + | } | |||
| 321 | + | ||||
| 322 | + | })();⏎̸ | |||
A internal/webui/public/libs/htmx.min.js +1 -0
| @@ -0,0 +1,1 @@ | |||
| 1 | + | (function(e,t){if(typeof define==="function"&&define.amd){define([],t)}else if(typeof module==="object"&&module.exports){module.exports=t()}else{e.htmx=e.htmx||t()}})(typeof self!=="undefined"?self:this,function(){return function(){"use strict";var G={onLoad:t,process:Nt,on:le,off:ue,trigger:oe,ajax:xr,find:b,findAll:f,closest:d,values:function(e,t){var r=er(e,t||"post");return r.values},remove:U,addClass:B,removeClass:n,toggleClass:V,takeClass:j,defineExtension:Rr,removeExtension:Or,logAll:X,logNone:F,logger:null,config:{historyEnabled:true,historyCacheSize:10,refreshOnHistoryMiss:false,defaultSwapStyle:"innerHTML",defaultSwapDelay:0,defaultSettleDelay:20,includeIndicatorStyles:true,indicatorClass:"htmx-indicator",requestClass:"htmx-request",addedClass:"htmx-added",settlingClass:"htmx-settling",swappingClass:"htmx-swapping",allowEval:true,allowScriptTags:true,inlineScriptNonce:"",attributesToSettle:["class","style","width","height"],withCredentials:false,timeout:0,wsReconnectDelay:"full-jitter",wsBinaryType:"blob",disableSelector:"[hx-disable], [data-hx-disable]",useTemplateFragments:false,scrollBehavior:"smooth",defaultFocusScroll:false,getCacheBusterParam:false,globalViewTransitions:false,methodsThatUseUrlParams:["get"],selfRequestsOnly:false},parseInterval:v,_:e,createEventSource:function(e){return new EventSource(e,{withCredentials:true})},createWebSocket:function(e){var t=new WebSocket(e,[]);t.binaryType=G.config.wsBinaryType;return t},version:"1.9.5"};var C={addTriggerHandler:bt,bodyContains:re,canAccessLocalStorage:M,findThisElement:he,filterValues:ar,hasAttribute:o,getAttributeValue:Z,getClosestAttributeValue:Y,getClosestMatch:c,getExpressionVars:gr,getHeaders:ir,getInputValues:er,getInternalData:ee,getSwapSpecification:sr,getTriggerSpecs:Ge,getTarget:de,makeFragment:l,mergeObjects:ne,makeSettleInfo:S,oobSwap:me,querySelectorExt:ie,selectAndSwap:De,settleImmediately:Wt,shouldCancel:Qe,triggerEvent:oe,triggerErrorEvent:ae,withExtensions:w};var R=["get","post","put","delete","patch"];var O=R.map(function(e){return"[hx-"+e+"], [data-hx-"+e+"]"}).join(", ");function v(e){if(e==undefined){return undefined}if(e.slice(-2)=="ms"){return parseFloat(e.slice(0,-2))||undefined}if(e.slice(-1)=="s"){return parseFloat(e.slice(0,-1))*1e3||undefined}if(e.slice(-1)=="m"){return parseFloat(e.slice(0,-1))*1e3*60||undefined}return parseFloat(e)||undefined}function J(e,t){return e.getAttribute&&e.getAttribute(t)}function o(e,t){return e.hasAttribute&&(e.hasAttribute(t)||e.hasAttribute("data-"+t))}function Z(e,t){return J(e,t)||J(e,"data-"+t)}function u(e){return e.parentElement}function K(){return document}function c(e,t){while(e&&!t(e)){e=u(e)}return e?e:null}function T(e,t,r){var n=Z(t,r);var i=Z(t,"hx-disinherit");if(e!==t&&i&&(i==="*"||i.split(" ").indexOf(r)>=0)){return"unset"}else{return n}}function Y(t,r){var n=null;c(t,function(e){return n=T(t,e,r)});if(n!=="unset"){return n}}function h(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return r&&r.call(e,t)}function q(e){var t=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i;var r=t.exec(e);if(r){return r[1].toLowerCase()}else{return""}}function i(e,t){var r=new DOMParser;var n=r.parseFromString(e,"text/html");var i=n.body;while(t>0){t--;i=i.firstChild}if(i==null){i=K().createDocumentFragment()}return i}function H(e){return e.match(/<body/)}function l(e){var t=!H(e);if(G.config.useTemplateFragments&&t){var r=i("<body><template>"+e+"</template></body>",0);return r.querySelector("template").content}else{var n=q(e);switch(n){case"thead":case"tbody":case"tfoot":case"colgroup":case"caption":return i("<table>"+e+"</table>",1);case"col":return i("<table><colgroup>"+e+"</colgroup></table>",2);case"tr":return i("<table><tbody>"+e+"</tbody></table>",2);case"td":case"th":return i("<table><tbody><tr>"+e+"</tr></tbody></table>",3);case"script":return i("<div>"+e+"</div>",1);default:return i(e,0)}}}function Q(e){if(e){e()}}function L(e,t){return Object.prototype.toString.call(e)==="[object "+t+"]"}function A(e){return L(e,"Function")}function N(e){return L(e,"Object")}function ee(e){var t="htmx-internal-data";var r=e[t];if(!r){r=e[t]={}}return r}function I(e){var t=[];if(e){for(var r=0;r<e.length;r++){t.push(e[r])}}return t}function te(e,t){if(e){for(var r=0;r<e.length;r++){t(e[r])}}}function P(e){var t=e.getBoundingClientRect();var r=t.top;var n=t.bottom;return r<window.innerHeight&&n>=0}function re(e){if(e.getRootNode&&e.getRootNode()instanceof window.ShadowRoot){return K().body.contains(e.getRootNode().host)}else{return K().body.contains(e)}}function k(e){return e.trim().split(/\s+/)}function ne(e,t){for(var r in t){if(t.hasOwnProperty(r)){e[r]=t[r]}}return e}function y(e){try{return JSON.parse(e)}catch(e){x(e);return null}}function M(){var e="htmx:localStorageTest";try{localStorage.setItem(e,e);localStorage.removeItem(e);return true}catch(e){return false}}function D(t){try{var e=new URL(t);if(e){t=e.pathname+e.search}if(!t.match("^/$")){t=t.replace(/\/+$/,"")}return t}catch(e){return t}}function e(e){return hr(K().body,function(){return eval(e)})}function t(t){var e=G.on("htmx:load",function(e){t(e.detail.elt)});return e}function X(){G.logger=function(e,t,r){if(console){console.log(t,e,r)}}}function F(){G.logger=null}function b(e,t){if(t){return e.querySelector(t)}else{return b(K(),e)}}function f(e,t){if(t){return e.querySelectorAll(t)}else{return f(K(),e)}}function U(e,t){e=s(e);if(t){setTimeout(function(){U(e);e=null},t)}else{e.parentElement.removeChild(e)}}function B(e,t,r){e=s(e);if(r){setTimeout(function(){B(e,t);e=null},r)}else{e.classList&&e.classList.add(t)}}function n(e,t,r){e=s(e);if(r){setTimeout(function(){n(e,t);e=null},r)}else{if(e.classList){e.classList.remove(t);if(e.classList.length===0){e.removeAttribute("class")}}}}function V(e,t){e=s(e);e.classList.toggle(t)}function j(e,t){e=s(e);te(e.parentElement.children,function(e){n(e,t)});B(e,t)}function d(e,t){e=s(e);if(e.closest){return e.closest(t)}else{do{if(e==null||h(e,t)){return e}}while(e=e&&u(e));return null}}function r(e){var t=e.trim();if(t.startsWith("<")&&t.endsWith("/>")){return t.substring(1,t.length-2)}else{return t}}function W(e,t){if(t.indexOf("closest ")===0){return[d(e,r(t.substr(8)))]}else if(t.indexOf("find ")===0){return[b(e,r(t.substr(5)))]}else if(t.indexOf("next ")===0){return[_(e,r(t.substr(5)))]}else if(t.indexOf("previous ")===0){return[z(e,r(t.substr(9)))]}else if(t==="document"){return[document]}else if(t==="window"){return[window]}else if(t==="body"){return[document.body]}else{return K().querySelectorAll(r(t))}}var _=function(e,t){var r=K().querySelectorAll(t);for(var n=0;n<r.length;n++){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_PRECEDING){return i}}};var z=function(e,t){var r=K().querySelectorAll(t);for(var n=r.length-1;n>=0;n--){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_FOLLOWING){return i}}};function ie(e,t){if(t){return W(e,t)[0]}else{return W(K().body,e)[0]}}function s(e){if(L(e,"String")){return b(e)}else{return e}}function $(e,t,r){if(A(t)){return{target:K().body,event:e,listener:t}}else{return{target:s(e),event:t,listener:r}}}function le(t,r,n){Hr(function(){var e=$(t,r,n);e.target.addEventListener(e.event,e.listener)});var e=A(r);return e?r:n}function ue(t,r,n){Hr(function(){var e=$(t,r,n);e.target.removeEventListener(e.event,e.listener)});return A(r)?r:n}var fe=K().createElement("output");function ce(e,t){var r=Y(e,t);if(r){if(r==="this"){return[he(e,t)]}else{var n=W(e,r);if(n.length===0){x('The selector "'+r+'" on '+t+" returned no matches!");return[fe]}else{return n}}}}function he(e,t){return c(e,function(e){return Z(e,t)!=null})}function de(e){var t=Y(e,"hx-target");if(t){if(t==="this"){return he(e,"hx-target")}else{return ie(e,t)}}else{var r=ee(e);if(r.boosted){return K().body}else{return e}}}function ve(e){var t=G.config.attributesToSettle;for(var r=0;r<t.length;r++){if(e===t[r]){return true}}return false}function ge(t,r){te(t.attributes,function(e){if(!r.hasAttribute(e.name)&&ve(e.name)){t.removeAttribute(e.name)}});te(r.attributes,function(e){if(ve(e.name)){t.setAttribute(e.name,e.value)}})}function pe(e,t){var r=Tr(t);for(var n=0;n<r.length;n++){var i=r[n];try{if(i.isInlineSwap(e)){return true}}catch(e){x(e)}}return e==="outerHTML"}function me(e,i,a){var t="#"+J(i,"id");var o="outerHTML";if(e==="true"){}else if(e.indexOf(":")>0){o=e.substr(0,e.indexOf(":"));t=e.substr(e.indexOf(":")+1,e.length)}else{o=e}var r=K().querySelectorAll(t);if(r){te(r,function(e){var t;var r=i.cloneNode(true);t=K().createDocumentFragment();t.appendChild(r);if(!pe(o,e)){t=r}var n={shouldSwap:true,target:e,fragment:t};if(!oe(e,"htmx:oobBeforeSwap",n))return;e=n.target;if(n["shouldSwap"]){ke(o,e,e,t,a)}te(a.elts,function(e){oe(e,"htmx:oobAfterSwap",n)})});i.parentNode.removeChild(i)}else{i.parentNode.removeChild(i);ae(K().body,"htmx:oobErrorNoTarget",{content:i})}return e}function xe(e,t,r){var n=Y(e,"hx-select-oob");if(n){var i=n.split(",");for(let e=0;e<i.length;e++){var a=i[e].split(":",2);var o=a[0].trim();if(o.indexOf("#")===0){o=o.substring(1)}var s=a[1]||"true";var l=t.querySelector("#"+o);if(l){me(s,l,r)}}}te(f(t,"[hx-swap-oob], [data-hx-swap-oob]"),function(e){var t=Z(e,"hx-swap-oob");if(t!=null){me(t,e,r)}})}function ye(e){te(f(e,"[hx-preserve], [data-hx-preserve]"),function(e){var t=Z(e,"id");var r=K().getElementById(t);if(r!=null){e.parentNode.replaceChild(r,e)}})}function be(o,e,s){te(e.querySelectorAll("[id]"),function(e){var t=J(e,"id");if(t&&t.length>0){var r=t.replace("'","\\'");var n=e.tagName.replace(":","\\:");var i=o.querySelector(n+"[id='"+r+"']");if(i&&i!==o){var a=e.cloneNode();ge(e,i);s.tasks.push(function(){ge(e,a)})}}})}function we(e){return function(){n(e,G.config.addedClass);Nt(e);St(e);Se(e);oe(e,"htmx:load")}}function Se(e){var t="[autofocus]";var r=h(e,t)?e:e.querySelector(t);if(r!=null){r.focus()}}function a(e,t,r,n){be(e,r,n);while(r.childNodes.length>0){var i=r.firstChild;B(i,G.config.addedClass);e.insertBefore(i,t);if(i.nodeType!==Node.TEXT_NODE&&i.nodeType!==Node.COMMENT_NODE){n.tasks.push(we(i))}}}function Ee(e,t){var r=0;while(r<e.length){t=(t<<5)-t+e.charCodeAt(r++)|0}return t}function Ce(e){var t=0;if(e.attributes){for(var r=0;r<e.attributes.length;r++){var n=e.attributes[r];if(n.value){t=Ee(n.name,t);t=Ee(n.value,t)}}}return t}function Re(t){var r=ee(t);if(r.onHandlers){for(let e=0;e<r.onHandlers.length;e++){const n=r.onHandlers[e];t.removeEventListener(n.event,n.listener)}delete r.onHandlers}}function Oe(e){var t=ee(e);if(t.timeout){clearTimeout(t.timeout)}if(t.webSocket){t.webSocket.close()}if(t.sseEventSource){t.sseEventSource.close()}if(t.listenerInfos){te(t.listenerInfos,function(e){if(e.on){e.on.removeEventListener(e.trigger,e.listener)}})}if(t.initHash){t.initHash=null}Re(e)}function g(e){oe(e,"htmx:beforeCleanupElement");Oe(e);if(e.children){te(e.children,function(e){g(e)})}}function Te(t,e,r){if(t.tagName==="BODY"){return Ie(t,e,r)}else{var n;var i=t.previousSibling;a(u(t),t,e,r);if(i==null){n=u(t).firstChild}else{n=i.nextSibling}ee(t).replacedWith=n;r.elts=r.elts.filter(function(e){return e!=t});while(n&&n!==t){if(n.nodeType===Node.ELEMENT_NODE){r.elts.push(n)}n=n.nextElementSibling}g(t);u(t).removeChild(t)}}function qe(e,t,r){return a(e,e.firstChild,t,r)}function He(e,t,r){return a(u(e),e,t,r)}function Le(e,t,r){return a(e,null,t,r)}function Ae(e,t,r){return a(u(e),e.nextSibling,t,r)}function Ne(e,t,r){g(e);return u(e).removeChild(e)}function Ie(e,t,r){var n=e.firstChild;a(e,n,t,r);if(n){while(n.nextSibling){g(n.nextSibling);e.removeChild(n.nextSibling)}g(n);e.removeChild(n)}}function Pe(e,t,r){var n=r||Y(e,"hx-select");if(n){var i=K().createDocumentFragment();te(t.querySelectorAll(n),function(e){i.appendChild(e)});t=i}return t}function ke(e,t,r,n,i){switch(e){case"none":return;case"outerHTML":Te(r,n,i);return;case"afterbegin":qe(r,n,i);return;case"beforebegin":He(r,n,i);return;case"beforeend":Le(r,n,i);return;case"afterend":Ae(r,n,i);return;case"delete":Ne(r,n,i);return;default:var a=Tr(t);for(var o=0;o<a.length;o++){var s=a[o];try{var l=s.handleSwap(e,r,n,i);if(l){if(typeof l.length!=="undefined"){for(var u=0;u<l.length;u++){var f=l[u];if(f.nodeType!==Node.TEXT_NODE&&f.nodeType!==Node.COMMENT_NODE){i.tasks.push(we(f))}}}return}}catch(e){x(e)}}if(e==="innerHTML"){Ie(r,n,i)}else{ke(G.config.defaultSwapStyle,t,r,n,i)}}}function Me(e){if(e.indexOf("<title")>-1){var t=e.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");var r=t.match(/<title(\s[^>]*>|>)([\s\S]*?)<\/title>/im);if(r){return r[2]}}}function De(e,t,r,n,i,a){i.title=Me(n);var o=l(n);if(o){xe(r,o,i);o=Pe(r,o,a);ye(o);return ke(e,r,t,o,i)}}function Xe(e,t,r){var n=e.getResponseHeader(t);if(n.indexOf("{")===0){var i=y(n);for(var a in i){if(i.hasOwnProperty(a)){var o=i[a];if(!N(o)){o={value:o}}oe(r,a,o)}}}else{var s=n.split(",");for(var l=0;l<s.length;l++){oe(r,s[l].trim(),[])}}}var Fe=/\s/;var p=/[\s,]/;var Ue=/[_$a-zA-Z]/;var Be=/[_$a-zA-Z0-9]/;var Ve=['"',"'","/"];var je=/[^\s]/;function We(e){var t=[];var r=0;while(r<e.length){if(Ue.exec(e.charAt(r))){var n=r;while(Be.exec(e.charAt(r+1))){r++}t.push(e.substr(n,r-n+1))}else if(Ve.indexOf(e.charAt(r))!==-1){var i=e.charAt(r);var n=r;r++;while(r<e.length&&e.charAt(r)!==i){if(e.charAt(r)==="\\"){r++}r++}t.push(e.substr(n,r-n+1))}else{var a=e.charAt(r);t.push(a)}r++}return t}function _e(e,t,r){return Ue.exec(e.charAt(0))&&e!=="true"&&e!=="false"&&e!=="this"&&e!==r&&t!=="."}function ze(e,t,r){if(t[0]==="["){t.shift();var n=1;var i=" return (function("+r+"){ return (";var a=null;while(t.length>0){var o=t[0];if(o==="]"){n--;if(n===0){if(a===null){i=i+"true"}t.shift();i+=")})";try{var s=hr(e,function(){return Function(i)()},function(){return true});s.source=i;return s}catch(e){ae(K().body,"htmx:syntax:error",{error:e,source:i});return null}}}else if(o==="["){n++}if(_e(o,a,r)){i+="(("+r+"."+o+") ? ("+r+"."+o+") : (window."+o+"))"}else{i=i+o}a=t.shift()}}}function m(e,t){var r="";while(e.length>0&&!e[0].match(t)){r+=e.shift()}return r}var $e="input, textarea, select";function Ge(e){var t=Z(e,"hx-trigger");var r=[];if(t){var n=We(t);do{m(n,je);var i=n.length;var a=m(n,/[,\[\s]/);if(a!==""){if(a==="every"){var o={trigger:"every"};m(n,je);o.pollInterval=v(m(n,/[,\[\s]/));m(n,je);var s=ze(e,n,"event");if(s){o.eventFilter=s}r.push(o)}else if(a.indexOf("sse:")===0){r.push({trigger:"sse",sseEvent:a.substr(4)})}else{var l={trigger:a};var s=ze(e,n,"event");if(s){l.eventFilter=s}while(n.length>0&&n[0]!==","){m(n,je);var u=n.shift();if(u==="changed"){l.changed=true}else if(u==="once"){l.once=true}else if(u==="consume"){l.consume=true}else if(u==="delay"&&n[0]===":"){n.shift();l.delay=v(m(n,p))}else if(u==="from"&&n[0]===":"){n.shift();var f=m(n,p);if(f==="closest"||f==="find"||f==="next"||f==="previous"){n.shift();f+=" "+m(n,p)}l.from=f}else if(u==="target"&&n[0]===":"){n.shift();l.target=m(n,p)}else if(u==="throttle"&&n[0]===":"){n.shift();l.throttle=v(m(n,p))}else if(u==="queue"&&n[0]===":"){n.shift();l.queue=m(n,p)}else if((u==="root"||u==="threshold")&&n[0]===":"){n.shift();l[u]=m(n,p)}else{ae(e,"htmx:syntax:error",{token:n.shift()})}}r.push(l)}}if(n.length===i){ae(e,"htmx:syntax:error",{token:n.shift()})}m(n,je)}while(n[0]===","&&n.shift())}if(r.length>0){return r}else if(h(e,"form")){return[{trigger:"submit"}]}else if(h(e,'input[type="button"], input[type="submit"]')){return[{trigger:"click"}]}else if(h(e,$e)){return[{trigger:"change"}]}else{return[{trigger:"click"}]}}function Je(e){ee(e).cancelled=true}function Ze(e,t,r){var n=ee(e);n.timeout=setTimeout(function(){if(re(e)&&n.cancelled!==true){if(!tt(r,e,Pt("hx:poll:trigger",{triggerSpec:r,target:e}))){t(e)}Ze(e,t,r)}},r.pollInterval)}function Ke(e){return location.hostname===e.hostname&&J(e,"href")&&J(e,"href").indexOf("#")!==0}function Ye(t,r,e){if(t.tagName==="A"&&Ke(t)&&(t.target===""||t.target==="_self")||t.tagName==="FORM"){r.boosted=true;var n,i;if(t.tagName==="A"){n="get";i=t.href}else{var a=J(t,"method");n=a?a.toLowerCase():"get";if(n==="get"){}i=J(t,"action")}e.forEach(function(e){rt(t,function(e,t){if(d(e,G.config.disableSelector)){g(e);return}se(n,i,e,t)},r,e,true)})}}function Qe(e,t){if(e.type==="submit"||e.type==="click"){if(t.tagName==="FORM"){return true}if(h(t,'input[type="submit"], button')&&d(t,"form")!==null){return true}if(t.tagName==="A"&&t.href&&(t.getAttribute("href")==="#"||t.getAttribute("href").indexOf("#")!==0)){return true}}return false}function et(e,t){return ee(e).boosted&&e.tagName==="A"&&t.type==="click"&&(t.ctrlKey||t.metaKey)}function tt(e,t,r){var n=e.eventFilter;if(n){try{return n.call(t,r)!==true}catch(e){ae(K().body,"htmx:eventFilter:error",{error:e,source:n.source});return true}}return false}function rt(a,o,e,s,l){var u=ee(a);var t;if(s.from){t=W(a,s.from)}else{t=[a]}if(s.changed){t.forEach(function(e){var t=ee(e);t.lastValue=e.value})}te(t,function(n){var i=function(e){if(!re(a)){n.removeEventListener(s.trigger,i);return}if(et(a,e)){return}if(l||Qe(e,a)){e.preventDefault()}if(tt(s,a,e)){return}var t=ee(e);t.triggerSpec=s;if(t.handledFor==null){t.handledFor=[]}if(t.handledFor.indexOf(a)<0){t.handledFor.push(a);if(s.consume){e.stopPropagation()}if(s.target&&e.target){if(!h(e.target,s.target)){return}}if(s.once){if(u.triggeredOnce){return}else{u.triggeredOnce=true}}if(s.changed){var r=ee(n);if(r.lastValue===n.value){return}r.lastValue=n.value}if(u.delayed){clearTimeout(u.delayed)}if(u.throttle){return}if(s.throttle){if(!u.throttle){o(a,e);u.throttle=setTimeout(function(){u.throttle=null},s.throttle)}}else if(s.delay){u.delayed=setTimeout(function(){o(a,e)},s.delay)}else{oe(a,"htmx:trigger");o(a,e)}}};if(e.listenerInfos==null){e.listenerInfos=[]}e.listenerInfos.push({trigger:s.trigger,listener:i,on:n});n.addEventListener(s.trigger,i)})}var nt=false;var it=null;function at(){if(!it){it=function(){nt=true};window.addEventListener("scroll",it);setInterval(function(){if(nt){nt=false;te(K().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"),function(e){ot(e)})}},200)}}function ot(t){if(!o(t,"data-hx-revealed")&&P(t)){t.setAttribute("data-hx-revealed","true");var e=ee(t);if(e.initHash){oe(t,"revealed")}else{t.addEventListener("htmx:afterProcessNode",function(e){oe(t,"revealed")},{once:true})}}}function st(e,t,r){var n=k(r);for(var i=0;i<n.length;i++){var a=n[i].split(/:(.+)/);if(a[0]==="connect"){lt(e,a[1],0)}if(a[0]==="send"){ft(e)}}}function lt(s,r,n){if(!re(s)){return}if(r.indexOf("/")==0){var e=location.hostname+(location.port?":"+location.port:"");if(location.protocol=="https:"){r="wss://"+e+r}else if(location.protocol=="http:"){r="ws://"+e+r}}var t=G.createWebSocket(r);t.onerror=function(e){ae(s,"htmx:wsError",{error:e,socket:t});ut(s)};t.onclose=function(e){if([1006,1012,1013].indexOf(e.code)>=0){var t=ct(n);setTimeout(function(){lt(s,r,n+1)},t)}};t.onopen=function(e){n=0};ee(s).webSocket=t;t.addEventListener("message",function(e){if(ut(s)){return}var t=e.data;w(s,function(e){t=e.transformResponse(t,null,s)});var r=S(s);var n=l(t);var i=I(n.children);for(var a=0;a<i.length;a++){var o=i[a];me(Z(o,"hx-swap-oob")||"true",o,r)}Wt(r.tasks)})}function ut(e){if(!re(e)){ee(e).webSocket.close();return true}}function ft(u){var f=c(u,function(e){return ee(e).webSocket!=null});if(f){u.addEventListener(Ge(u)[0].trigger,function(e){var t=ee(f).webSocket;var r=ir(u,f);var n=er(u,"post");var i=n.errors;var a=n.values;var o=gr(u);var s=ne(a,o);var l=ar(s,u);l["HEADERS"]=r;if(i&&i.length>0){oe(u,"htmx:validation:halted",i);return}t.send(JSON.stringify(l));if(Qe(e,u)){e.preventDefault()}})}else{ae(u,"htmx:noWebSocketSourceError")}}function ct(e){var t=G.config.wsReconnectDelay;if(typeof t==="function"){return t(e)}if(t==="full-jitter"){var r=Math.min(e,6);var n=1e3*Math.pow(2,r);return n*Math.random()}x('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"')}function ht(e,t,r){var n=k(r);for(var i=0;i<n.length;i++){var a=n[i].split(/:(.+)/);if(a[0]==="connect"){dt(e,a[1])}if(a[0]==="swap"){vt(e,a[1])}}}function dt(t,e){var r=G.createEventSource(e);r.onerror=function(e){ae(t,"htmx:sseError",{error:e,source:r});pt(t)};ee(t).sseEventSource=r}function vt(a,o){var s=c(a,mt);if(s){var l=ee(s).sseEventSource;var u=function(e){if(pt(s)){return}if(!re(a)){l.removeEventListener(o,u);return}var t=e.data;w(a,function(e){t=e.transformResponse(t,null,a)});var r=sr(a);var n=de(a);var i=S(a);De(r.swapStyle,n,a,t,i);Wt(i.tasks);oe(a,"htmx:sseMessage",e)};ee(a).sseListener=u;l.addEventListener(o,u)}else{ae(a,"htmx:noSSESourceError")}}function gt(e,t,r){var n=c(e,mt);if(n){var i=ee(n).sseEventSource;var a=function(){if(!pt(n)){if(re(e)){t(e)}else{i.removeEventListener(r,a)}}};ee(e).sseListener=a;i.addEventListener(r,a)}else{ae(e,"htmx:noSSESourceError")}}function pt(e){if(!re(e)){ee(e).sseEventSource.close();return true}}function mt(e){return ee(e).sseEventSource!=null}function xt(e,t,r,n){var i=function(){if(!r.loaded){r.loaded=true;t(e)}};if(n){setTimeout(i,n)}else{i()}}function yt(t,i,e){var a=false;te(R,function(r){if(o(t,"hx-"+r)){var n=Z(t,"hx-"+r);a=true;i.path=n;i.verb=r;e.forEach(function(e){bt(t,e,i,function(e,t){if(d(e,G.config.disableSelector)){g(e);return}se(r,n,e,t)})})}});return a}function bt(n,e,t,r){if(e.sseEvent){gt(n,r,e.sseEvent)}else if(e.trigger==="revealed"){at();rt(n,r,t,e);ot(n)}else if(e.trigger==="intersect"){var i={};if(e.root){i.root=ie(n,e.root)}if(e.threshold){i.threshold=parseFloat(e.threshold)}var a=new IntersectionObserver(function(e){for(var t=0;t<e.length;t++){var r=e[t];if(r.isIntersecting){oe(n,"intersect");break}}},i);a.observe(n);rt(n,r,t,e)}else if(e.trigger==="load"){if(!tt(e,n,Pt("load",{elt:n}))){xt(n,r,t,e.delay)}}else if(e.pollInterval){t.polling=true;Ze(n,r,e)}else{rt(n,r,t,e)}}function wt(e){if(G.config.allowScriptTags&&(e.type==="text/javascript"||e.type==="module"||e.type==="")){var t=K().createElement("script");te(e.attributes,function(e){t.setAttribute(e.name,e.value)});t.textContent=e.textContent;t.async=false;if(G.config.inlineScriptNonce){t.nonce=G.config.inlineScriptNonce}var r=e.parentElement;try{r.insertBefore(t,e)}catch(e){x(e)}finally{if(e.parentElement){e.parentElement.removeChild(e)}}}}function St(e){if(h(e,"script")){wt(e)}te(f(e,"script"),function(e){wt(e)})}function Et(){return document.querySelector("[hx-boost], [data-hx-boost]")}function Ct(e){if(!document.evaluate)return[];let t=null;const r=[];const n=document.evaluate('//*[@*[ starts-with(name(), "hx-on:") or starts-with(name(), "data-hx-on:") ]]',e);while(t=n.iterateNext())r.push(t);return r}function Rt(e){if(e.querySelectorAll){var t=Et()?", a":"";var r=e.querySelectorAll(O+t+", form, [type='submit'], [hx-sse], [data-hx-sse], [hx-ws],"+" [data-hx-ws], [hx-ext], [data-hx-ext], [hx-trigger], [data-hx-trigger], [hx-on], [data-hx-on]");return r}else{return[]}}function Ot(e){var n=s("#"+J(e,"form"))||d(e,"form");if(!n){return}var t=function(e){var t=d(e.target,"button, input[type='submit']");if(t!==null){var r=ee(n);r.lastButtonClicked=t}};e.addEventListener("click",t);e.addEventListener("focusin",t);e.addEventListener("focusout",function(e){var t=ee(n);t.lastButtonClicked=null})}function Tt(e){var t=We(e);var r=0;for(let e=0;e<t.length;e++){const n=t[e];if(n==="{"){r++}else if(n==="}"){r--}}return r}function qt(t,e,r){var n=ee(t);n.onHandlers=[];var i;var a=function(e){return hr(t,function(){if(!i){i=new Function("event",r)}i.call(t,e)})};t.addEventListener(e,a);n.onHandlers.push({event:e,listener:a})}function Ht(e){var t=Z(e,"hx-on");if(t){var r={};var n=t.split("\n");var i=null;var a=0;while(n.length>0){var o=n.shift();var s=o.match(/^\s*([a-zA-Z:\-]+:)(.*)/);if(a===0&&s){o.split(":");i=s[1].slice(0,-1);r[i]=s[2]}else{r[i]+=o}a+=Tt(o)}for(var l in r){qt(e,l,r[l])}}}function Lt(t){Re(t);for(var e=0;e<t.attributes.length;e++){var r=t.attributes[e].name;var n=t.attributes[e].value;if(r.startsWith("hx-on:")||r.startsWith("data-hx-on:")){let e=r.slice(r.indexOf(":")+1);if(e.startsWith(":"))e="htmx"+e;qt(t,e,n)}}}function At(t){if(d(t,G.config.disableSelector)){g(t);return}var r=ee(t);if(r.initHash!==Ce(t)){Oe(t);r.initHash=Ce(t);Ht(t);oe(t,"htmx:beforeProcessNode");if(t.value){r.lastValue=t.value}var e=Ge(t);var n=yt(t,r,e);if(!n){if(Y(t,"hx-boost")==="true"){Ye(t,r,e)}else if(o(t,"hx-trigger")){e.forEach(function(e){bt(t,e,r,function(){})})}}if(t.tagName==="FORM"||J(t,"type")==="submit"&&o(t,"form")){Ot(t)}var i=Z(t,"hx-sse");if(i){ht(t,r,i)}var a=Z(t,"hx-ws");if(a){st(t,r,a)}oe(t,"htmx:afterProcessNode")}}function Nt(e){e=s(e);if(d(e,G.config.disableSelector)){g(e);return}At(e);te(Rt(e),function(e){At(e)});te(Ct(e),Lt)}function It(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}function Pt(e,t){var r;if(window.CustomEvent&&typeof window.CustomEvent==="function"){r=new CustomEvent(e,{bubbles:true,cancelable:true,detail:t})}else{r=K().createEvent("CustomEvent");r.initCustomEvent(e,true,true,t)}return r}function ae(e,t,r){oe(e,t,ne({error:t},r))}function kt(e){return e==="htmx:afterProcessNode"}function w(e,t){te(Tr(e),function(e){try{t(e)}catch(e){x(e)}})}function x(e){if(console.error){console.error(e)}else if(console.log){console.log("ERROR: ",e)}}function oe(e,t,r){e=s(e);if(r==null){r={}}r["elt"]=e;var n=Pt(t,r);if(G.logger&&!kt(t)){G.logger(e,t,r)}if(r.error){x(r.error);oe(e,"htmx:error",{errorInfo:r})}var i=e.dispatchEvent(n);var a=It(t);if(i&&a!==t){var o=Pt(a,n.detail);i=i&&e.dispatchEvent(o)}w(e,function(e){i=i&&e.onEvent(t,n)!==false});return i}var Mt=location.pathname+location.search;function Dt(){var e=K().querySelector("[hx-history-elt],[data-hx-history-elt]");return e||K().body}function Xt(e,t,r,n){if(!M()){return}e=D(e);var i=y(localStorage.getItem("htmx-history-cache"))||[];for(var a=0;a<i.length;a++){if(i[a].url===e){i.splice(a,1);break}}var o={url:e,content:t,title:r,scroll:n};oe(K().body,"htmx:historyItemCreated",{item:o,cache:i});i.push(o);while(i.length>G.config.historyCacheSize){i.shift()}while(i.length>0){try{localStorage.setItem("htmx-history-cache",JSON.stringify(i));break}catch(e){ae(K().body,"htmx:historyCacheError",{cause:e,cache:i});i.shift()}}}function Ft(e){if(!M()){return null}e=D(e);var t=y(localStorage.getItem("htmx-history-cache"))||[];for(var r=0;r<t.length;r++){if(t[r].url===e){return t[r]}}return null}function Ut(e){var t=G.config.requestClass;var r=e.cloneNode(true);te(f(r,"."+t),function(e){n(e,t)});return r.innerHTML}function Bt(){var e=Dt();var t=Mt||location.pathname+location.search;var r=K().querySelector('[hx-history="false" i],[data-hx-history="false" i]');if(!r){oe(K().body,"htmx:beforeHistorySave",{path:t,historyElt:e});Xt(t,Ut(e),K().title,window.scrollY)}if(G.config.historyEnabled)history.replaceState({htmx:true},K().title,window.location.href)}function Vt(e){if(G.config.getCacheBusterParam){e=e.replace(/org\.htmx\.cache-buster=[^&]*&?/,"");if(e.endsWith("&")||e.endsWith("?")){e=e.slice(0,-1)}}if(G.config.historyEnabled){history.pushState({htmx:true},"",e)}Mt=e}function jt(e){if(G.config.historyEnabled)history.replaceState({htmx:true},"",e);Mt=e}function Wt(e){te(e,function(e){e.call()})}function _t(a){var e=new XMLHttpRequest;var o={path:a,xhr:e};oe(K().body,"htmx:historyCacheMiss",o);e.open("GET",a,true);e.setRequestHeader("HX-History-Restore-Request","true");e.onload=function(){if(this.status>=200&&this.status<400){oe(K().body,"htmx:historyCacheMissLoad",o);var e=l(this.response);e=e.querySelector("[hx-history-elt],[data-hx-history-elt]")||e;var t=Dt();var r=S(t);var n=Me(this.response);if(n){var i=b("title");if(i){i.innerHTML=n}else{window.document.title=n}}Ie(t,e,r);Wt(r.tasks);Mt=a;oe(K().body,"htmx:historyRestore",{path:a,cacheMiss:true,serverResponse:this.response})}else{ae(K().body,"htmx:historyCacheMissLoadError",o)}};e.send()}function zt(e){Bt();e=e||location.pathname+location.search;var t=Ft(e);if(t){var r=l(t.content);var n=Dt();var i=S(n);Ie(n,r,i);Wt(i.tasks);document.title=t.title;setTimeout(function(){window.scrollTo(0,t.scroll)},0);Mt=e;oe(K().body,"htmx:historyRestore",{path:e,item:t})}else{if(G.config.refreshOnHistoryMiss){window.location.reload(true)}else{_t(e)}}}function $t(e){var t=ce(e,"hx-indicator");if(t==null){t=[e]}te(t,function(e){var t=ee(e);t.requestCount=(t.requestCount||0)+1;e.classList["add"].call(e.classList,G.config.requestClass)});return t}function Gt(e){te(e,function(e){var t=ee(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.classList["remove"].call(e.classList,G.config.requestClass)}})}function Jt(e,t){for(var r=0;r<e.length;r++){var n=e[r];if(n.isSameNode(t)){return true}}return false}function Zt(e){if(e.name===""||e.name==null||e.disabled){return false}if(e.type==="button"||e.type==="submit"||e.tagName==="image"||e.tagName==="reset"||e.tagName==="file"){return false}if(e.type==="checkbox"||e.type==="radio"){return e.checked}return true}function Kt(e,t,r){if(e!=null&&t!=null){var n=r[e];if(n===undefined){r[e]=t}else if(Array.isArray(n)){if(Array.isArray(t)){r[e]=n.concat(t)}else{n.push(t)}}else{if(Array.isArray(t)){r[e]=[n].concat(t)}else{r[e]=[n,t]}}}}function Yt(t,r,n,e,i){if(e==null||Jt(t,e)){return}else{t.push(e)}if(Zt(e)){var a=J(e,"name");var o=e.value;if(e.multiple){o=I(e.querySelectorAll("option:checked")).map(function(e){return e.value})}if(e.files){o=I(e.files)}Kt(a,o,r);if(i){Qt(e,n)}}if(h(e,"form")){var s=e.elements;te(s,function(e){Yt(t,r,n,e,i)})}}function Qt(e,t){if(e.willValidate){oe(e,"htmx:validation:validate");if(!e.checkValidity()){t.push({elt:e,message:e.validationMessage,validity:e.validity});oe(e,"htmx:validation:failed",{message:e.validationMessage,validity:e.validity})}}}function er(e,t){var r=[];var n={};var i={};var a=[];var o=ee(e);var s=h(e,"form")&&e.noValidate!==true||Z(e,"hx-validate")==="true";if(o.lastButtonClicked){s=s&&o.lastButtonClicked.formNoValidate!==true}if(t!=="get"){Yt(r,i,a,d(e,"form"),s)}Yt(r,n,a,e,s);if(o.lastButtonClicked||e.tagName==="BUTTON"||e.tagName==="INPUT"&&J(e,"type")==="submit"){var l=o.lastButtonClicked||e;var u=J(l,"name");Kt(u,l.value,i)}var f=ce(e,"hx-include");te(f,function(e){Yt(r,n,a,e,s);if(!h(e,"form")){te(e.querySelectorAll($e),function(e){Yt(r,n,a,e,s)})}});n=ne(n,i);return{errors:a,values:n}}function tr(e,t,r){if(e!==""){e+="&"}if(String(r)==="[object Object]"){r=JSON.stringify(r)}var n=encodeURIComponent(r);e+=encodeURIComponent(t)+"="+n;return e}function rr(e){var t="";for(var r in e){if(e.hasOwnProperty(r)){var n=e[r];if(Array.isArray(n)){te(n,function(e){t=tr(t,r,e)})}else{t=tr(t,r,n)}}}return t}function nr(e){var t=new FormData;for(var r in e){if(e.hasOwnProperty(r)){var n=e[r];if(Array.isArray(n)){te(n,function(e){t.append(r,e)})}else{t.append(r,n)}}}return t}function ir(e,t,r){var n={"HX-Request":"true","HX-Trigger":J(e,"id"),"HX-Trigger-Name":J(e,"name"),"HX-Target":Z(t,"id"),"HX-Current-URL":K().location.href};cr(e,"hx-headers",false,n);if(r!==undefined){n["HX-Prompt"]=r}if(ee(e).boosted){n["HX-Boosted"]="true"}return n}function ar(t,e){var r=Y(e,"hx-params");if(r){if(r==="none"){return{}}else if(r==="*"){return t}else if(r.indexOf("not ")===0){te(r.substr(4).split(","),function(e){e=e.trim();delete t[e]});return t}else{var n={};te(r.split(","),function(e){e=e.trim();n[e]=t[e]});return n}}else{return t}}function or(e){return J(e,"href")&&J(e,"href").indexOf("#")>=0}function sr(e,t){var r=t?t:Y(e,"hx-swap");var n={swapStyle:ee(e).boosted?"innerHTML":G.config.defaultSwapStyle,swapDelay:G.config.defaultSwapDelay,settleDelay:G.config.defaultSettleDelay};if(ee(e).boosted&&!or(e)){n["show"]="top"}if(r){var i=k(r);if(i.length>0){n["swapStyle"]=i[0];for(var a=1;a<i.length;a++){var o=i[a];if(o.indexOf("swap:")===0){n["swapDelay"]=v(o.substr(5))}if(o.indexOf("settle:")===0){n["settleDelay"]=v(o.substr(7))}if(o.indexOf("transition:")===0){n["transition"]=o.substr(11)==="true"}if(o.indexOf("scroll:")===0){var s=o.substr(7);var l=s.split(":");var u=l.pop();var f=l.length>0?l.join(":"):null;n["scroll"]=u;n["scrollTarget"]=f}if(o.indexOf("show:")===0){var c=o.substr(5);var l=c.split(":");var h=l.pop();var f=l.length>0?l.join(":"):null;n["show"]=h;n["showTarget"]=f}if(o.indexOf("focus-scroll:")===0){var d=o.substr("focus-scroll:".length);n["focusScroll"]=d=="true"}}}}return n}function lr(e){return Y(e,"hx-encoding")==="multipart/form-data"||h(e,"form")&&J(e,"enctype")==="multipart/form-data"}function ur(t,r,n){var i=null;w(r,function(e){if(i==null){i=e.encodeParameters(t,n,r)}});if(i!=null){return i}else{if(lr(r)){return nr(n)}else{return rr(n)}}}function S(e){return{tasks:[],elts:[e]}}function fr(e,t){var r=e[0];var n=e[e.length-1];if(t.scroll){var i=null;if(t.scrollTarget){i=ie(r,t.scrollTarget)}if(t.scroll==="top"&&(r||i)){i=i||r;i.scrollTop=0}if(t.scroll==="bottom"&&(n||i)){i=i||n;i.scrollTop=i.scrollHeight}}if(t.show){var i=null;if(t.showTarget){var a=t.showTarget;if(t.showTarget==="window"){a="body"}i=ie(r,a)}if(t.show==="top"&&(r||i)){i=i||r;i.scrollIntoView({block:"start",behavior:G.config.scrollBehavior})}if(t.show==="bottom"&&(n||i)){i=i||n;i.scrollIntoView({block:"end",behavior:G.config.scrollBehavior})}}}function cr(e,t,r,n){if(n==null){n={}}if(e==null){return n}var i=Z(e,t);if(i){var a=i.trim();var o=r;if(a==="unset"){return null}if(a.indexOf("javascript:")===0){a=a.substr(11);o=true}else if(a.indexOf("js:")===0){a=a.substr(3);o=true}if(a.indexOf("{")!==0){a="{"+a+"}"}var s;if(o){s=hr(e,function(){return Function("return ("+a+")")()},{})}else{s=y(a)}for(var l in s){if(s.hasOwnProperty(l)){if(n[l]==null){n[l]=s[l]}}}}return cr(u(e),t,r,n)}function hr(e,t,r){if(G.config.allowEval){return t()}else{ae(e,"htmx:evalDisallowedError");return r}}function dr(e,t){return cr(e,"hx-vars",true,t)}function vr(e,t){return cr(e,"hx-vals",false,t)}function gr(e){return ne(dr(e),vr(e))}function pr(t,r,n){if(n!==null){try{t.setRequestHeader(r,n)}catch(e){t.setRequestHeader(r,encodeURIComponent(n));t.setRequestHeader(r+"-URI-AutoEncoded","true")}}}function mr(t){if(t.responseURL&&typeof URL!=="undefined"){try{var e=new URL(t.responseURL);return e.pathname+e.search}catch(e){ae(K().body,"htmx:badResponseUrl",{url:t.responseURL})}}}function E(e,t){return e.getAllResponseHeaders().match(t)}function xr(e,t,r){e=e.toLowerCase();if(r){if(r instanceof Element||L(r,"String")){return se(e,t,null,null,{targetOverride:s(r),returnPromise:true})}else{return se(e,t,s(r.source),r.event,{handler:r.handler,headers:r.headers,values:r.values,targetOverride:s(r.target),swapOverride:r.swap,returnPromise:true})}}else{return se(e,t,null,null,{returnPromise:true})}}function yr(e){var t=[];while(e){t.push(e);e=e.parentElement}return t}function br(e,t,r){var n=new URL(t,document.location.href);var i=document.location.origin;var a=i===n.origin;if(G.config.selfRequestsOnly){if(!a){return false}}return oe(e,"htmx:validateUrl",ne({url:n,sameHost:a},r))}function se(e,t,n,r,i,M){var a=null;var o=null;i=i!=null?i:{};if(i.returnPromise&&typeof Promise!=="undefined"){var s=new Promise(function(e,t){a=e;o=t})}if(n==null){n=K().body}var D=i.handler||Sr;if(!re(n)){return}var l=i.targetOverride||de(n);if(l==null||l==fe){ae(n,"htmx:targetError",{target:Z(n,"hx-target")});return}if(!M){var X=function(){return se(e,t,n,r,i,true)};var F={target:l,elt:n,path:t,verb:e,triggeringEvent:r,etc:i,issueRequest:X};if(oe(n,"htmx:confirm",F)===false){return}}var u=n;var f=ee(n);var c=Y(n,"hx-sync");var h=null;var d=false;if(c){var v=c.split(":");var g=v[0].trim();if(g==="this"){u=he(n,"hx-sync")}else{u=ie(n,g)}c=(v[1]||"drop").trim();f=ee(u);if(c==="drop"&&f.xhr&&f.abortable!==true){return}else if(c==="abort"){if(f.xhr){return}else{d=true}}else if(c==="replace"){oe(u,"htmx:abort")}else if(c.indexOf("queue")===0){var U=c.split(" ");h=(U[1]||"last").trim()}}if(f.xhr){if(f.abortable){oe(u,"htmx:abort")}else{if(h==null){if(r){var p=ee(r);if(p&&p.triggerSpec&&p.triggerSpec.queue){h=p.triggerSpec.queue}}if(h==null){h="last"}}if(f.queuedRequests==null){f.queuedRequests=[]}if(h==="first"&&f.queuedRequests.length===0){f.queuedRequests.push(function(){se(e,t,n,r,i)})}else if(h==="all"){f.queuedRequests.push(function(){se(e,t,n,r,i)})}else if(h==="last"){f.queuedRequests=[];f.queuedRequests.push(function(){se(e,t,n,r,i)})}return}}var m=new XMLHttpRequest;f.xhr=m;f.abortable=d;var x=function(){f.xhr=null;f.abortable=false;if(f.queuedRequests!=null&&f.queuedRequests.length>0){var e=f.queuedRequests.shift();e()}};var y=Y(n,"hx-prompt");if(y){var b=prompt(y);if(b===null||!oe(n,"htmx:prompt",{prompt:b,target:l})){Q(a);x();return s}}var w=Y(n,"hx-confirm");if(w){if(!confirm(w)){Q(a);x();return s}}var S=ir(n,l,b);if(i.headers){S=ne(S,i.headers)}var E=er(n,e);var C=E.errors;var R=E.values;if(i.values){R=ne(R,i.values)}var B=gr(n);var O=ne(R,B);var T=ar(O,n);if(e!=="get"&&!lr(n)){S["Content-Type"]="application/x-www-form-urlencoded"}if(G.config.getCacheBusterParam&&e==="get"){T["org.htmx.cache-buster"]=J(l,"id")||"true"}if(t==null||t===""){t=K().location.href}var q=cr(n,"hx-request");var V=ee(n).boosted;var H=G.config.methodsThatUseUrlParams.indexOf(e)>=0;var L={boosted:V,useUrlParams:H,parameters:T,unfilteredParameters:O,headers:S,target:l,verb:e,errors:C,withCredentials:i.credentials||q.credentials||G.config.withCredentials,timeout:i.timeout||q.timeout||G.config.timeout,path:t,triggeringEvent:r};if(!oe(n,"htmx:configRequest",L)){Q(a);x();return s}t=L.path;e=L.verb;S=L.headers;T=L.parameters;C=L.errors;H=L.useUrlParams;if(C&&C.length>0){oe(n,"htmx:validation:halted",L);Q(a);x();return s}var j=t.split("#");var W=j[0];var A=j[1];var N=t;if(H){N=W;var _=Object.keys(T).length!==0;if(_){if(N.indexOf("?")<0){N+="?"}else{N+="&"}N+=rr(T);if(A){N+="#"+A}}}if(!br(n,N,L)){ae(n,"htmx:invalidPath",L);return}m.open(e.toUpperCase(),N,true);m.overrideMimeType("text/html");m.withCredentials=L.withCredentials;m.timeout=L.timeout;if(q.noHeaders){}else{for(var I in S){if(S.hasOwnProperty(I)){var z=S[I];pr(m,I,z)}}}var P={xhr:m,target:l,requestConfig:L,etc:i,boosted:V,pathInfo:{requestPath:t,finalRequestPath:N,anchor:A}};m.onload=function(){try{var e=yr(n);P.pathInfo.responsePath=mr(m);D(n,P);Gt(k);oe(n,"htmx:afterRequest",P);oe(n,"htmx:afterOnLoad",P);if(!re(n)){var t=null;while(e.length>0&&t==null){var r=e.shift();if(re(r)){t=r}}if(t){oe(t,"htmx:afterRequest",P);oe(t,"htmx:afterOnLoad",P)}}Q(a);x()}catch(e){ae(n,"htmx:onLoadError",ne({error:e},P));throw e}};m.onerror=function(){Gt(k);ae(n,"htmx:afterRequest",P);ae(n,"htmx:sendError",P);Q(o);x()};m.onabort=function(){Gt(k);ae(n,"htmx:afterRequest",P);ae(n,"htmx:sendAbort",P);Q(o);x()};m.ontimeout=function(){Gt(k);ae(n,"htmx:afterRequest",P);ae(n,"htmx:timeout",P);Q(o);x()};if(!oe(n,"htmx:beforeRequest",P)){Q(a);x();return s}var k=$t(n);te(["loadstart","loadend","progress","abort"],function(t){te([m,m.upload],function(e){e.addEventListener(t,function(e){oe(n,"htmx:xhr:"+t,{lengthComputable:e.lengthComputable,loaded:e.loaded,total:e.total})})})});oe(n,"htmx:beforeSend",P);var $=H?null:ur(m,n,T);m.send($);return s}function wr(e,t){var r=t.xhr;var n=null;var i=null;if(E(r,/HX-Push:/i)){n=r.getResponseHeader("HX-Push");i="push"}else if(E(r,/HX-Push-Url:/i)){n=r.getResponseHeader("HX-Push-Url");i="push"}else if(E(r,/HX-Replace-Url:/i)){n=r.getResponseHeader("HX-Replace-Url");i="replace"}if(n){if(n==="false"){return{}}else{return{type:i,path:n}}}var a=t.pathInfo.finalRequestPath;var o=t.pathInfo.responsePath;var s=Y(e,"hx-push-url");var l=Y(e,"hx-replace-url");var u=ee(e).boosted;var f=null;var c=null;if(s){f="push";c=s}else if(l){f="replace";c=l}else if(u){f="push";c=o||a}if(c){if(c==="false"){return{}}if(c==="true"){c=o||a}if(t.pathInfo.anchor&&c.indexOf("#")===-1){c=c+"#"+t.pathInfo.anchor}return{type:f,path:c}}else{return{}}}function Sr(l,u){var f=u.xhr;var c=u.target;var e=u.etc;if(!oe(l,"htmx:beforeOnLoad",u))return;if(E(f,/HX-Trigger:/i)){Xe(f,"HX-Trigger",l)}if(E(f,/HX-Location:/i)){Bt();var t=f.getResponseHeader("HX-Location");var h;if(t.indexOf("{")===0){h=y(t);t=h["path"];delete h["path"]}xr("GET",t,h).then(function(){Vt(t)});return}if(E(f,/HX-Redirect:/i)){location.href=f.getResponseHeader("HX-Redirect");return}if(E(f,/HX-Refresh:/i)){if("true"===f.getResponseHeader("HX-Refresh")){location.reload();return}}if(E(f,/HX-Retarget:/i)){u.target=K().querySelector(f.getResponseHeader("HX-Retarget"))}var d=wr(l,u);var r=f.status>=200&&f.status<400&&f.status!==204;var v=f.response;var n=f.status>=400;var i=ne({shouldSwap:r,serverResponse:v,isError:n},u);if(!oe(c,"htmx:beforeSwap",i))return;c=i.target;v=i.serverResponse;n=i.isError;u.target=c;u.failed=n;u.successful=!n;if(i.shouldSwap){if(f.status===286){Je(l)}w(l,function(e){v=e.transformResponse(v,f,l)});if(d.type){Bt()}var a=e.swapOverride;if(E(f,/HX-Reswap:/i)){a=f.getResponseHeader("HX-Reswap")}var h=sr(l,a);c.classList.add(G.config.swappingClass);var g=null;var p=null;var o=function(){try{var e=document.activeElement;var t={};try{t={elt:e,start:e?e.selectionStart:null,end:e?e.selectionEnd:null}}catch(e){}var r;if(E(f,/HX-Reselect:/i)){r=f.getResponseHeader("HX-Reselect")}var n=S(c);De(h.swapStyle,c,l,v,n,r);if(t.elt&&!re(t.elt)&&J(t.elt,"id")){var i=document.getElementById(J(t.elt,"id"));var a={preventScroll:h.focusScroll!==undefined?!h.focusScroll:!G.config.defaultFocusScroll};if(i){if(t.start&&i.setSelectionRange){try{i.setSelectionRange(t.start,t.end)}catch(e){}}i.focus(a)}}c.classList.remove(G.config.swappingClass);te(n.elts,function(e){if(e.classList){e.classList.add(G.config.settlingClass)}oe(e,"htmx:afterSwap",u)});if(E(f,/HX-Trigger-After-Swap:/i)){var o=l;if(!re(l)){o=K().body}Xe(f,"HX-Trigger-After-Swap",o)}var s=function(){te(n.tasks,function(e){e.call()});te(n.elts,function(e){if(e.classList){e.classList.remove(G.config.settlingClass)}oe(e,"htmx:afterSettle",u)});if(d.type){if(d.type==="push"){Vt(d.path);oe(K().body,"htmx:pushedIntoHistory",{path:d.path})}else{jt(d.path);oe(K().body,"htmx:replacedInHistory",{path:d.path})}}if(u.pathInfo.anchor){var e=b("#"+u.pathInfo.anchor);if(e){e.scrollIntoView({block:"start",behavior:"auto"})}}if(n.title){var t=b("title");if(t){t.innerHTML=n.title}else{window.document.title=n.title}}fr(n.elts,h);if(E(f,/HX-Trigger-After-Settle:/i)){var r=l;if(!re(l)){r=K().body}Xe(f,"HX-Trigger-After-Settle",r)}Q(g)};if(h.settleDelay>0){setTimeout(s,h.settleDelay)}else{s()}}catch(e){ae(l,"htmx:swapError",u);Q(p);throw e}};var s=G.config.globalViewTransitions;if(h.hasOwnProperty("transition")){s=h.transition}if(s&&oe(l,"htmx:beforeTransition",u)&&typeof Promise!=="undefined"&&document.startViewTransition){var m=new Promise(function(e,t){g=e;p=t});var x=o;o=function(){document.startViewTransition(function(){x();return m})}}if(h.swapDelay>0){setTimeout(o,h.swapDelay)}else{o()}}if(n){ae(l,"htmx:responseError",ne({error:"Response Status Error Code "+f.status+" from "+u.pathInfo.requestPath},u))}}var Er={};function Cr(){return{init:function(e){return null},onEvent:function(e,t){return true},transformResponse:function(e,t,r){return e},isInlineSwap:function(e){return false},handleSwap:function(e,t,r,n){return false},encodeParameters:function(e,t,r){return null}}}function Rr(e,t){if(t.init){t.init(C)}Er[e]=ne(Cr(),t)}function Or(e){delete Er[e]}function Tr(e,r,n){if(e==undefined){return r}if(r==undefined){r=[]}if(n==undefined){n=[]}var t=Z(e,"hx-ext");if(t){te(t.split(","),function(e){e=e.replace(/ /g,"");if(e.slice(0,7)=="ignore:"){n.push(e.slice(7));return}if(n.indexOf(e)<0){var t=Er[e];if(t&&r.indexOf(t)<0){r.push(t)}}})}return Tr(u(e),r,n)}var qr=false;K().addEventListener("DOMContentLoaded",function(){qr=true});function Hr(e){if(qr||K().readyState==="complete"){e()}else{K().addEventListener("DOMContentLoaded",e)}}function Lr(){if(G.config.includeIndicatorStyles!==false){K().head.insertAdjacentHTML("beforeend","<style> ."+G.config.indicatorClass+"{opacity:0;transition: opacity 200ms ease-in;} ."+G.config.requestClass+" ."+G.config.indicatorClass+"{opacity:1} ."+G.config.requestClass+"."+G.config.indicatorClass+"{opacity:1} </style>")}}function Ar(){var e=K().querySelector('meta[name="htmx-config"]');if(e){return y(e.content)}else{return null}}function Nr(){var e=Ar();if(e){G.config=ne(G.config,e)}}Hr(function(){Nr();Lr();var e=K().body;Nt(e);var t=K().querySelectorAll("[hx-trigger='restored'],[data-hx-trigger='restored']");e.addEventListener("htmx:abort",function(e){var t=e.target;var r=ee(t);if(r&&r.xhr){r.xhr.abort()}});var r=window.onpopstate;window.onpopstate=function(e){if(e.state&&e.state.htmx){zt();te(t,function(e){oe(e,"htmx:restored",{document:K(),triggerEvent:oe})})}else{if(r){r(e)}}};setTimeout(function(){oe(e,"htmx:load",{});e=null},0)});return G}()});⏎̸ | |
| @@ -0,0 +1,1 @@ | |||||
| 1 | + | (function(e,t){if(typeof define==="function"&&define.amd){define([],t)}else if(typeof module==="object"&&module.exports){module.exports=t()}else{e.htmx=e.htmx||t()}})(typeof self!=="undefined"?self:this,function(){return function(){"use strict";var G={onLoad:t,process:Nt,on:le,off:ue,trigger:oe,ajax:xr,find:b,findAll:f,closest:d,values:function(e,t){var r=er(e,t||"post");return r.values},remove:U,addClass:B,removeClass:n,toggleClass:V,takeClass:j,defineExtension:Rr,removeExtension:Or,logAll:X,logNone:F,logger:null,config:{historyEnabled:true,historyCacheSize:10,refreshOnHistoryMiss:false,defaultSwapStyle:"innerHTML",defaultSwapDelay:0,defaultSettleDelay:20,includeIndicatorStyles:true,indicatorClass:"htmx-indicator",requestClass:"htmx-request",addedClass:"htmx-added",settlingClass:"htmx-settling",swappingClass:"htmx-swapping",allowEval:true,allowScriptTags:true,inlineScriptNonce:"",attributesToSettle:["class","style","width","height"],withCredentials:false,timeout:0,wsReconnectDelay:"full-jitter",wsBinaryType:"blob",disableSelector:"[hx-disable], [data-hx-disable]",useTemplateFragments:false,scrollBehavior:"smooth",defaultFocusScroll:false,getCacheBusterParam:false,globalViewTransitions:false,methodsThatUseUrlParams:["get"],selfRequestsOnly:false},parseInterval:v,_:e,createEventSource:function(e){return new EventSource(e,{withCredentials:true})},createWebSocket:function(e){var t=new WebSocket(e,[]);t.binaryType=G.config.wsBinaryType;return t},version:"1.9.5"};var C={addTriggerHandler:bt,bodyContains:re,canAccessLocalStorage:M,findThisElement:he,filterValues:ar,hasAttribute:o,getAttributeValue:Z,getClosestAttributeValue:Y,getClosestMatch:c,getExpressionVars:gr,getHeaders:ir,getInputValues:er,getInternalData:ee,getSwapSpecification:sr,getTriggerSpecs:Ge,getTarget:de,makeFragment:l,mergeObjects:ne,makeSettleInfo:S,oobSwap:me,querySelectorExt:ie,selectAndSwap:De,settleImmediately:Wt,shouldCancel:Qe,triggerEvent:oe,triggerErrorEvent:ae,withExtensions:w};var R=["get","post","put","delete","patch"];var O=R.map(function(e){return"[hx-"+e+"], [data-hx-"+e+"]"}).join(", ");function v(e){if(e==undefined){return undefined}if(e.slice(-2)=="ms"){return parseFloat(e.slice(0,-2))||undefined}if(e.slice(-1)=="s"){return parseFloat(e.slice(0,-1))*1e3||undefined}if(e.slice(-1)=="m"){return parseFloat(e.slice(0,-1))*1e3*60||undefined}return parseFloat(e)||undefined}function J(e,t){return e.getAttribute&&e.getAttribute(t)}function o(e,t){return e.hasAttribute&&(e.hasAttribute(t)||e.hasAttribute("data-"+t))}function Z(e,t){return J(e,t)||J(e,"data-"+t)}function u(e){return e.parentElement}function K(){return document}function c(e,t){while(e&&!t(e)){e=u(e)}return e?e:null}function T(e,t,r){var n=Z(t,r);var i=Z(t,"hx-disinherit");if(e!==t&&i&&(i==="*"||i.split(" ").indexOf(r)>=0)){return"unset"}else{return n}}function Y(t,r){var n=null;c(t,function(e){return n=T(t,e,r)});if(n!=="unset"){return n}}function h(e,t){var r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector;return r&&r.call(e,t)}function q(e){var t=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i;var r=t.exec(e);if(r){return r[1].toLowerCase()}else{return""}}function i(e,t){var r=new DOMParser;var n=r.parseFromString(e,"text/html");var i=n.body;while(t>0){t--;i=i.firstChild}if(i==null){i=K().createDocumentFragment()}return i}function H(e){return e.match(/<body/)}function l(e){var t=!H(e);if(G.config.useTemplateFragments&&t){var r=i("<body><template>"+e+"</template></body>",0);return r.querySelector("template").content}else{var n=q(e);switch(n){case"thead":case"tbody":case"tfoot":case"colgroup":case"caption":return i("<table>"+e+"</table>",1);case"col":return i("<table><colgroup>"+e+"</colgroup></table>",2);case"tr":return i("<table><tbody>"+e+"</tbody></table>",2);case"td":case"th":return i("<table><tbody><tr>"+e+"</tr></tbody></table>",3);case"script":return i("<div>"+e+"</div>",1);default:return i(e,0)}}}function Q(e){if(e){e()}}function L(e,t){return Object.prototype.toString.call(e)==="[object "+t+"]"}function A(e){return L(e,"Function")}function N(e){return L(e,"Object")}function ee(e){var t="htmx-internal-data";var r=e[t];if(!r){r=e[t]={}}return r}function I(e){var t=[];if(e){for(var r=0;r<e.length;r++){t.push(e[r])}}return t}function te(e,t){if(e){for(var r=0;r<e.length;r++){t(e[r])}}}function P(e){var t=e.getBoundingClientRect();var r=t.top;var n=t.bottom;return r<window.innerHeight&&n>=0}function re(e){if(e.getRootNode&&e.getRootNode()instanceof window.ShadowRoot){return K().body.contains(e.getRootNode().host)}else{return K().body.contains(e)}}function k(e){return e.trim().split(/\s+/)}function ne(e,t){for(var r in t){if(t.hasOwnProperty(r)){e[r]=t[r]}}return e}function y(e){try{return JSON.parse(e)}catch(e){x(e);return null}}function M(){var e="htmx:localStorageTest";try{localStorage.setItem(e,e);localStorage.removeItem(e);return true}catch(e){return false}}function D(t){try{var e=new URL(t);if(e){t=e.pathname+e.search}if(!t.match("^/$")){t=t.replace(/\/+$/,"")}return t}catch(e){return t}}function e(e){return hr(K().body,function(){return eval(e)})}function t(t){var e=G.on("htmx:load",function(e){t(e.detail.elt)});return e}function X(){G.logger=function(e,t,r){if(console){console.log(t,e,r)}}}function F(){G.logger=null}function b(e,t){if(t){return e.querySelector(t)}else{return b(K(),e)}}function f(e,t){if(t){return e.querySelectorAll(t)}else{return f(K(),e)}}function U(e,t){e=s(e);if(t){setTimeout(function(){U(e);e=null},t)}else{e.parentElement.removeChild(e)}}function B(e,t,r){e=s(e);if(r){setTimeout(function(){B(e,t);e=null},r)}else{e.classList&&e.classList.add(t)}}function n(e,t,r){e=s(e);if(r){setTimeout(function(){n(e,t);e=null},r)}else{if(e.classList){e.classList.remove(t);if(e.classList.length===0){e.removeAttribute("class")}}}}function V(e,t){e=s(e);e.classList.toggle(t)}function j(e,t){e=s(e);te(e.parentElement.children,function(e){n(e,t)});B(e,t)}function d(e,t){e=s(e);if(e.closest){return e.closest(t)}else{do{if(e==null||h(e,t)){return e}}while(e=e&&u(e));return null}}function r(e){var t=e.trim();if(t.startsWith("<")&&t.endsWith("/>")){return t.substring(1,t.length-2)}else{return t}}function W(e,t){if(t.indexOf("closest ")===0){return[d(e,r(t.substr(8)))]}else if(t.indexOf("find ")===0){return[b(e,r(t.substr(5)))]}else if(t.indexOf("next ")===0){return[_(e,r(t.substr(5)))]}else if(t.indexOf("previous ")===0){return[z(e,r(t.substr(9)))]}else if(t==="document"){return[document]}else if(t==="window"){return[window]}else if(t==="body"){return[document.body]}else{return K().querySelectorAll(r(t))}}var _=function(e,t){var r=K().querySelectorAll(t);for(var n=0;n<r.length;n++){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_PRECEDING){return i}}};var z=function(e,t){var r=K().querySelectorAll(t);for(var n=r.length-1;n>=0;n--){var i=r[n];if(i.compareDocumentPosition(e)===Node.DOCUMENT_POSITION_FOLLOWING){return i}}};function ie(e,t){if(t){return W(e,t)[0]}else{return W(K().body,e)[0]}}function s(e){if(L(e,"String")){return b(e)}else{return e}}function $(e,t,r){if(A(t)){return{target:K().body,event:e,listener:t}}else{return{target:s(e),event:t,listener:r}}}function le(t,r,n){Hr(function(){var e=$(t,r,n);e.target.addEventListener(e.event,e.listener)});var e=A(r);return e?r:n}function ue(t,r,n){Hr(function(){var e=$(t,r,n);e.target.removeEventListener(e.event,e.listener)});return A(r)?r:n}var fe=K().createElement("output");function ce(e,t){var r=Y(e,t);if(r){if(r==="this"){return[he(e,t)]}else{var n=W(e,r);if(n.length===0){x('The selector "'+r+'" on '+t+" returned no matches!");return[fe]}else{return n}}}}function he(e,t){return c(e,function(e){return Z(e,t)!=null})}function de(e){var t=Y(e,"hx-target");if(t){if(t==="this"){return he(e,"hx-target")}else{return ie(e,t)}}else{var r=ee(e);if(r.boosted){return K().body}else{return e}}}function ve(e){var t=G.config.attributesToSettle;for(var r=0;r<t.length;r++){if(e===t[r]){return true}}return false}function ge(t,r){te(t.attributes,function(e){if(!r.hasAttribute(e.name)&&ve(e.name)){t.removeAttribute(e.name)}});te(r.attributes,function(e){if(ve(e.name)){t.setAttribute(e.name,e.value)}})}function pe(e,t){var r=Tr(t);for(var n=0;n<r.length;n++){var i=r[n];try{if(i.isInlineSwap(e)){return true}}catch(e){x(e)}}return e==="outerHTML"}function me(e,i,a){var t="#"+J(i,"id");var o="outerHTML";if(e==="true"){}else if(e.indexOf(":")>0){o=e.substr(0,e.indexOf(":"));t=e.substr(e.indexOf(":")+1,e.length)}else{o=e}var r=K().querySelectorAll(t);if(r){te(r,function(e){var t;var r=i.cloneNode(true);t=K().createDocumentFragment();t.appendChild(r);if(!pe(o,e)){t=r}var n={shouldSwap:true,target:e,fragment:t};if(!oe(e,"htmx:oobBeforeSwap",n))return;e=n.target;if(n["shouldSwap"]){ke(o,e,e,t,a)}te(a.elts,function(e){oe(e,"htmx:oobAfterSwap",n)})});i.parentNode.removeChild(i)}else{i.parentNode.removeChild(i);ae(K().body,"htmx:oobErrorNoTarget",{content:i})}return e}function xe(e,t,r){var n=Y(e,"hx-select-oob");if(n){var i=n.split(",");for(let e=0;e<i.length;e++){var a=i[e].split(":",2);var o=a[0].trim();if(o.indexOf("#")===0){o=o.substring(1)}var s=a[1]||"true";var l=t.querySelector("#"+o);if(l){me(s,l,r)}}}te(f(t,"[hx-swap-oob], [data-hx-swap-oob]"),function(e){var t=Z(e,"hx-swap-oob");if(t!=null){me(t,e,r)}})}function ye(e){te(f(e,"[hx-preserve], [data-hx-preserve]"),function(e){var t=Z(e,"id");var r=K().getElementById(t);if(r!=null){e.parentNode.replaceChild(r,e)}})}function be(o,e,s){te(e.querySelectorAll("[id]"),function(e){var t=J(e,"id");if(t&&t.length>0){var r=t.replace("'","\\'");var n=e.tagName.replace(":","\\:");var i=o.querySelector(n+"[id='"+r+"']");if(i&&i!==o){var a=e.cloneNode();ge(e,i);s.tasks.push(function(){ge(e,a)})}}})}function we(e){return function(){n(e,G.config.addedClass);Nt(e);St(e);Se(e);oe(e,"htmx:load")}}function Se(e){var t="[autofocus]";var r=h(e,t)?e:e.querySelector(t);if(r!=null){r.focus()}}function a(e,t,r,n){be(e,r,n);while(r.childNodes.length>0){var i=r.firstChild;B(i,G.config.addedClass);e.insertBefore(i,t);if(i.nodeType!==Node.TEXT_NODE&&i.nodeType!==Node.COMMENT_NODE){n.tasks.push(we(i))}}}function Ee(e,t){var r=0;while(r<e.length){t=(t<<5)-t+e.charCodeAt(r++)|0}return t}function Ce(e){var t=0;if(e.attributes){for(var r=0;r<e.attributes.length;r++){var n=e.attributes[r];if(n.value){t=Ee(n.name,t);t=Ee(n.value,t)}}}return t}function Re(t){var r=ee(t);if(r.onHandlers){for(let e=0;e<r.onHandlers.length;e++){const n=r.onHandlers[e];t.removeEventListener(n.event,n.listener)}delete r.onHandlers}}function Oe(e){var t=ee(e);if(t.timeout){clearTimeout(t.timeout)}if(t.webSocket){t.webSocket.close()}if(t.sseEventSource){t.sseEventSource.close()}if(t.listenerInfos){te(t.listenerInfos,function(e){if(e.on){e.on.removeEventListener(e.trigger,e.listener)}})}if(t.initHash){t.initHash=null}Re(e)}function g(e){oe(e,"htmx:beforeCleanupElement");Oe(e);if(e.children){te(e.children,function(e){g(e)})}}function Te(t,e,r){if(t.tagName==="BODY"){return Ie(t,e,r)}else{var n;var i=t.previousSibling;a(u(t),t,e,r);if(i==null){n=u(t).firstChild}else{n=i.nextSibling}ee(t).replacedWith=n;r.elts=r.elts.filter(function(e){return e!=t});while(n&&n!==t){if(n.nodeType===Node.ELEMENT_NODE){r.elts.push(n)}n=n.nextElementSibling}g(t);u(t).removeChild(t)}}function qe(e,t,r){return a(e,e.firstChild,t,r)}function He(e,t,r){return a(u(e),e,t,r)}function Le(e,t,r){return a(e,null,t,r)}function Ae(e,t,r){return a(u(e),e.nextSibling,t,r)}function Ne(e,t,r){g(e);return u(e).removeChild(e)}function Ie(e,t,r){var n=e.firstChild;a(e,n,t,r);if(n){while(n.nextSibling){g(n.nextSibling);e.removeChild(n.nextSibling)}g(n);e.removeChild(n)}}function Pe(e,t,r){var n=r||Y(e,"hx-select");if(n){var i=K().createDocumentFragment();te(t.querySelectorAll(n),function(e){i.appendChild(e)});t=i}return t}function ke(e,t,r,n,i){switch(e){case"none":return;case"outerHTML":Te(r,n,i);return;case"afterbegin":qe(r,n,i);return;case"beforebegin":He(r,n,i);return;case"beforeend":Le(r,n,i);return;case"afterend":Ae(r,n,i);return;case"delete":Ne(r,n,i);return;default:var a=Tr(t);for(var o=0;o<a.length;o++){var s=a[o];try{var l=s.handleSwap(e,r,n,i);if(l){if(typeof l.length!=="undefined"){for(var u=0;u<l.length;u++){var f=l[u];if(f.nodeType!==Node.TEXT_NODE&&f.nodeType!==Node.COMMENT_NODE){i.tasks.push(we(f))}}}return}}catch(e){x(e)}}if(e==="innerHTML"){Ie(r,n,i)}else{ke(G.config.defaultSwapStyle,t,r,n,i)}}}function Me(e){if(e.indexOf("<title")>-1){var t=e.replace(/<svg(\s[^>]*>|>)([\s\S]*?)<\/svg>/gim,"");var r=t.match(/<title(\s[^>]*>|>)([\s\S]*?)<\/title>/im);if(r){return r[2]}}}function De(e,t,r,n,i,a){i.title=Me(n);var o=l(n);if(o){xe(r,o,i);o=Pe(r,o,a);ye(o);return ke(e,r,t,o,i)}}function Xe(e,t,r){var n=e.getResponseHeader(t);if(n.indexOf("{")===0){var i=y(n);for(var a in i){if(i.hasOwnProperty(a)){var o=i[a];if(!N(o)){o={value:o}}oe(r,a,o)}}}else{var s=n.split(",");for(var l=0;l<s.length;l++){oe(r,s[l].trim(),[])}}}var Fe=/\s/;var p=/[\s,]/;var Ue=/[_$a-zA-Z]/;var Be=/[_$a-zA-Z0-9]/;var Ve=['"',"'","/"];var je=/[^\s]/;function We(e){var t=[];var r=0;while(r<e.length){if(Ue.exec(e.charAt(r))){var n=r;while(Be.exec(e.charAt(r+1))){r++}t.push(e.substr(n,r-n+1))}else if(Ve.indexOf(e.charAt(r))!==-1){var i=e.charAt(r);var n=r;r++;while(r<e.length&&e.charAt(r)!==i){if(e.charAt(r)==="\\"){r++}r++}t.push(e.substr(n,r-n+1))}else{var a=e.charAt(r);t.push(a)}r++}return t}function _e(e,t,r){return Ue.exec(e.charAt(0))&&e!=="true"&&e!=="false"&&e!=="this"&&e!==r&&t!=="."}function ze(e,t,r){if(t[0]==="["){t.shift();var n=1;var i=" return (function("+r+"){ return (";var a=null;while(t.length>0){var o=t[0];if(o==="]"){n--;if(n===0){if(a===null){i=i+"true"}t.shift();i+=")})";try{var s=hr(e,function(){return Function(i)()},function(){return true});s.source=i;return s}catch(e){ae(K().body,"htmx:syntax:error",{error:e,source:i});return null}}}else if(o==="["){n++}if(_e(o,a,r)){i+="(("+r+"."+o+") ? ("+r+"."+o+") : (window."+o+"))"}else{i=i+o}a=t.shift()}}}function m(e,t){var r="";while(e.length>0&&!e[0].match(t)){r+=e.shift()}return r}var $e="input, textarea, select";function Ge(e){var t=Z(e,"hx-trigger");var r=[];if(t){var n=We(t);do{m(n,je);var i=n.length;var a=m(n,/[,\[\s]/);if(a!==""){if(a==="every"){var o={trigger:"every"};m(n,je);o.pollInterval=v(m(n,/[,\[\s]/));m(n,je);var s=ze(e,n,"event");if(s){o.eventFilter=s}r.push(o)}else if(a.indexOf("sse:")===0){r.push({trigger:"sse",sseEvent:a.substr(4)})}else{var l={trigger:a};var s=ze(e,n,"event");if(s){l.eventFilter=s}while(n.length>0&&n[0]!==","){m(n,je);var u=n.shift();if(u==="changed"){l.changed=true}else if(u==="once"){l.once=true}else if(u==="consume"){l.consume=true}else if(u==="delay"&&n[0]===":"){n.shift();l.delay=v(m(n,p))}else if(u==="from"&&n[0]===":"){n.shift();var f=m(n,p);if(f==="closest"||f==="find"||f==="next"||f==="previous"){n.shift();f+=" "+m(n,p)}l.from=f}else if(u==="target"&&n[0]===":"){n.shift();l.target=m(n,p)}else if(u==="throttle"&&n[0]===":"){n.shift();l.throttle=v(m(n,p))}else if(u==="queue"&&n[0]===":"){n.shift();l.queue=m(n,p)}else if((u==="root"||u==="threshold")&&n[0]===":"){n.shift();l[u]=m(n,p)}else{ae(e,"htmx:syntax:error",{token:n.shift()})}}r.push(l)}}if(n.length===i){ae(e,"htmx:syntax:error",{token:n.shift()})}m(n,je)}while(n[0]===","&&n.shift())}if(r.length>0){return r}else if(h(e,"form")){return[{trigger:"submit"}]}else if(h(e,'input[type="button"], input[type="submit"]')){return[{trigger:"click"}]}else if(h(e,$e)){return[{trigger:"change"}]}else{return[{trigger:"click"}]}}function Je(e){ee(e).cancelled=true}function Ze(e,t,r){var n=ee(e);n.timeout=setTimeout(function(){if(re(e)&&n.cancelled!==true){if(!tt(r,e,Pt("hx:poll:trigger",{triggerSpec:r,target:e}))){t(e)}Ze(e,t,r)}},r.pollInterval)}function Ke(e){return location.hostname===e.hostname&&J(e,"href")&&J(e,"href").indexOf("#")!==0}function Ye(t,r,e){if(t.tagName==="A"&&Ke(t)&&(t.target===""||t.target==="_self")||t.tagName==="FORM"){r.boosted=true;var n,i;if(t.tagName==="A"){n="get";i=t.href}else{var a=J(t,"method");n=a?a.toLowerCase():"get";if(n==="get"){}i=J(t,"action")}e.forEach(function(e){rt(t,function(e,t){if(d(e,G.config.disableSelector)){g(e);return}se(n,i,e,t)},r,e,true)})}}function Qe(e,t){if(e.type==="submit"||e.type==="click"){if(t.tagName==="FORM"){return true}if(h(t,'input[type="submit"], button')&&d(t,"form")!==null){return true}if(t.tagName==="A"&&t.href&&(t.getAttribute("href")==="#"||t.getAttribute("href").indexOf("#")!==0)){return true}}return false}function et(e,t){return ee(e).boosted&&e.tagName==="A"&&t.type==="click"&&(t.ctrlKey||t.metaKey)}function tt(e,t,r){var n=e.eventFilter;if(n){try{return n.call(t,r)!==true}catch(e){ae(K().body,"htmx:eventFilter:error",{error:e,source:n.source});return true}}return false}function rt(a,o,e,s,l){var u=ee(a);var t;if(s.from){t=W(a,s.from)}else{t=[a]}if(s.changed){t.forEach(function(e){var t=ee(e);t.lastValue=e.value})}te(t,function(n){var i=function(e){if(!re(a)){n.removeEventListener(s.trigger,i);return}if(et(a,e)){return}if(l||Qe(e,a)){e.preventDefault()}if(tt(s,a,e)){return}var t=ee(e);t.triggerSpec=s;if(t.handledFor==null){t.handledFor=[]}if(t.handledFor.indexOf(a)<0){t.handledFor.push(a);if(s.consume){e.stopPropagation()}if(s.target&&e.target){if(!h(e.target,s.target)){return}}if(s.once){if(u.triggeredOnce){return}else{u.triggeredOnce=true}}if(s.changed){var r=ee(n);if(r.lastValue===n.value){return}r.lastValue=n.value}if(u.delayed){clearTimeout(u.delayed)}if(u.throttle){return}if(s.throttle){if(!u.throttle){o(a,e);u.throttle=setTimeout(function(){u.throttle=null},s.throttle)}}else if(s.delay){u.delayed=setTimeout(function(){o(a,e)},s.delay)}else{oe(a,"htmx:trigger");o(a,e)}}};if(e.listenerInfos==null){e.listenerInfos=[]}e.listenerInfos.push({trigger:s.trigger,listener:i,on:n});n.addEventListener(s.trigger,i)})}var nt=false;var it=null;function at(){if(!it){it=function(){nt=true};window.addEventListener("scroll",it);setInterval(function(){if(nt){nt=false;te(K().querySelectorAll("[hx-trigger='revealed'],[data-hx-trigger='revealed']"),function(e){ot(e)})}},200)}}function ot(t){if(!o(t,"data-hx-revealed")&&P(t)){t.setAttribute("data-hx-revealed","true");var e=ee(t);if(e.initHash){oe(t,"revealed")}else{t.addEventListener("htmx:afterProcessNode",function(e){oe(t,"revealed")},{once:true})}}}function st(e,t,r){var n=k(r);for(var i=0;i<n.length;i++){var a=n[i].split(/:(.+)/);if(a[0]==="connect"){lt(e,a[1],0)}if(a[0]==="send"){ft(e)}}}function lt(s,r,n){if(!re(s)){return}if(r.indexOf("/")==0){var e=location.hostname+(location.port?":"+location.port:"");if(location.protocol=="https:"){r="wss://"+e+r}else if(location.protocol=="http:"){r="ws://"+e+r}}var t=G.createWebSocket(r);t.onerror=function(e){ae(s,"htmx:wsError",{error:e,socket:t});ut(s)};t.onclose=function(e){if([1006,1012,1013].indexOf(e.code)>=0){var t=ct(n);setTimeout(function(){lt(s,r,n+1)},t)}};t.onopen=function(e){n=0};ee(s).webSocket=t;t.addEventListener("message",function(e){if(ut(s)){return}var t=e.data;w(s,function(e){t=e.transformResponse(t,null,s)});var r=S(s);var n=l(t);var i=I(n.children);for(var a=0;a<i.length;a++){var o=i[a];me(Z(o,"hx-swap-oob")||"true",o,r)}Wt(r.tasks)})}function ut(e){if(!re(e)){ee(e).webSocket.close();return true}}function ft(u){var f=c(u,function(e){return ee(e).webSocket!=null});if(f){u.addEventListener(Ge(u)[0].trigger,function(e){var t=ee(f).webSocket;var r=ir(u,f);var n=er(u,"post");var i=n.errors;var a=n.values;var o=gr(u);var s=ne(a,o);var l=ar(s,u);l["HEADERS"]=r;if(i&&i.length>0){oe(u,"htmx:validation:halted",i);return}t.send(JSON.stringify(l));if(Qe(e,u)){e.preventDefault()}})}else{ae(u,"htmx:noWebSocketSourceError")}}function ct(e){var t=G.config.wsReconnectDelay;if(typeof t==="function"){return t(e)}if(t==="full-jitter"){var r=Math.min(e,6);var n=1e3*Math.pow(2,r);return n*Math.random()}x('htmx.config.wsReconnectDelay must either be a function or the string "full-jitter"')}function ht(e,t,r){var n=k(r);for(var i=0;i<n.length;i++){var a=n[i].split(/:(.+)/);if(a[0]==="connect"){dt(e,a[1])}if(a[0]==="swap"){vt(e,a[1])}}}function dt(t,e){var r=G.createEventSource(e);r.onerror=function(e){ae(t,"htmx:sseError",{error:e,source:r});pt(t)};ee(t).sseEventSource=r}function vt(a,o){var s=c(a,mt);if(s){var l=ee(s).sseEventSource;var u=function(e){if(pt(s)){return}if(!re(a)){l.removeEventListener(o,u);return}var t=e.data;w(a,function(e){t=e.transformResponse(t,null,a)});var r=sr(a);var n=de(a);var i=S(a);De(r.swapStyle,n,a,t,i);Wt(i.tasks);oe(a,"htmx:sseMessage",e)};ee(a).sseListener=u;l.addEventListener(o,u)}else{ae(a,"htmx:noSSESourceError")}}function gt(e,t,r){var n=c(e,mt);if(n){var i=ee(n).sseEventSource;var a=function(){if(!pt(n)){if(re(e)){t(e)}else{i.removeEventListener(r,a)}}};ee(e).sseListener=a;i.addEventListener(r,a)}else{ae(e,"htmx:noSSESourceError")}}function pt(e){if(!re(e)){ee(e).sseEventSource.close();return true}}function mt(e){return ee(e).sseEventSource!=null}function xt(e,t,r,n){var i=function(){if(!r.loaded){r.loaded=true;t(e)}};if(n){setTimeout(i,n)}else{i()}}function yt(t,i,e){var a=false;te(R,function(r){if(o(t,"hx-"+r)){var n=Z(t,"hx-"+r);a=true;i.path=n;i.verb=r;e.forEach(function(e){bt(t,e,i,function(e,t){if(d(e,G.config.disableSelector)){g(e);return}se(r,n,e,t)})})}});return a}function bt(n,e,t,r){if(e.sseEvent){gt(n,r,e.sseEvent)}else if(e.trigger==="revealed"){at();rt(n,r,t,e);ot(n)}else if(e.trigger==="intersect"){var i={};if(e.root){i.root=ie(n,e.root)}if(e.threshold){i.threshold=parseFloat(e.threshold)}var a=new IntersectionObserver(function(e){for(var t=0;t<e.length;t++){var r=e[t];if(r.isIntersecting){oe(n,"intersect");break}}},i);a.observe(n);rt(n,r,t,e)}else if(e.trigger==="load"){if(!tt(e,n,Pt("load",{elt:n}))){xt(n,r,t,e.delay)}}else if(e.pollInterval){t.polling=true;Ze(n,r,e)}else{rt(n,r,t,e)}}function wt(e){if(G.config.allowScriptTags&&(e.type==="text/javascript"||e.type==="module"||e.type==="")){var t=K().createElement("script");te(e.attributes,function(e){t.setAttribute(e.name,e.value)});t.textContent=e.textContent;t.async=false;if(G.config.inlineScriptNonce){t.nonce=G.config.inlineScriptNonce}var r=e.parentElement;try{r.insertBefore(t,e)}catch(e){x(e)}finally{if(e.parentElement){e.parentElement.removeChild(e)}}}}function St(e){if(h(e,"script")){wt(e)}te(f(e,"script"),function(e){wt(e)})}function Et(){return document.querySelector("[hx-boost], [data-hx-boost]")}function Ct(e){if(!document.evaluate)return[];let t=null;const r=[];const n=document.evaluate('//*[@*[ starts-with(name(), "hx-on:") or starts-with(name(), "data-hx-on:") ]]',e);while(t=n.iterateNext())r.push(t);return r}function Rt(e){if(e.querySelectorAll){var t=Et()?", a":"";var r=e.querySelectorAll(O+t+", form, [type='submit'], [hx-sse], [data-hx-sse], [hx-ws],"+" [data-hx-ws], [hx-ext], [data-hx-ext], [hx-trigger], [data-hx-trigger], [hx-on], [data-hx-on]");return r}else{return[]}}function Ot(e){var n=s("#"+J(e,"form"))||d(e,"form");if(!n){return}var t=function(e){var t=d(e.target,"button, input[type='submit']");if(t!==null){var r=ee(n);r.lastButtonClicked=t}};e.addEventListener("click",t);e.addEventListener("focusin",t);e.addEventListener("focusout",function(e){var t=ee(n);t.lastButtonClicked=null})}function Tt(e){var t=We(e);var r=0;for(let e=0;e<t.length;e++){const n=t[e];if(n==="{"){r++}else if(n==="}"){r--}}return r}function qt(t,e,r){var n=ee(t);n.onHandlers=[];var i;var a=function(e){return hr(t,function(){if(!i){i=new Function("event",r)}i.call(t,e)})};t.addEventListener(e,a);n.onHandlers.push({event:e,listener:a})}function Ht(e){var t=Z(e,"hx-on");if(t){var r={};var n=t.split("\n");var i=null;var a=0;while(n.length>0){var o=n.shift();var s=o.match(/^\s*([a-zA-Z:\-]+:)(.*)/);if(a===0&&s){o.split(":");i=s[1].slice(0,-1);r[i]=s[2]}else{r[i]+=o}a+=Tt(o)}for(var l in r){qt(e,l,r[l])}}}function Lt(t){Re(t);for(var e=0;e<t.attributes.length;e++){var r=t.attributes[e].name;var n=t.attributes[e].value;if(r.startsWith("hx-on:")||r.startsWith("data-hx-on:")){let e=r.slice(r.indexOf(":")+1);if(e.startsWith(":"))e="htmx"+e;qt(t,e,n)}}}function At(t){if(d(t,G.config.disableSelector)){g(t);return}var r=ee(t);if(r.initHash!==Ce(t)){Oe(t);r.initHash=Ce(t);Ht(t);oe(t,"htmx:beforeProcessNode");if(t.value){r.lastValue=t.value}var e=Ge(t);var n=yt(t,r,e);if(!n){if(Y(t,"hx-boost")==="true"){Ye(t,r,e)}else if(o(t,"hx-trigger")){e.forEach(function(e){bt(t,e,r,function(){})})}}if(t.tagName==="FORM"||J(t,"type")==="submit"&&o(t,"form")){Ot(t)}var i=Z(t,"hx-sse");if(i){ht(t,r,i)}var a=Z(t,"hx-ws");if(a){st(t,r,a)}oe(t,"htmx:afterProcessNode")}}function Nt(e){e=s(e);if(d(e,G.config.disableSelector)){g(e);return}At(e);te(Rt(e),function(e){At(e)});te(Ct(e),Lt)}function It(e){return e.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()}function Pt(e,t){var r;if(window.CustomEvent&&typeof window.CustomEvent==="function"){r=new CustomEvent(e,{bubbles:true,cancelable:true,detail:t})}else{r=K().createEvent("CustomEvent");r.initCustomEvent(e,true,true,t)}return r}function ae(e,t,r){oe(e,t,ne({error:t},r))}function kt(e){return e==="htmx:afterProcessNode"}function w(e,t){te(Tr(e),function(e){try{t(e)}catch(e){x(e)}})}function x(e){if(console.error){console.error(e)}else if(console.log){console.log("ERROR: ",e)}}function oe(e,t,r){e=s(e);if(r==null){r={}}r["elt"]=e;var n=Pt(t,r);if(G.logger&&!kt(t)){G.logger(e,t,r)}if(r.error){x(r.error);oe(e,"htmx:error",{errorInfo:r})}var i=e.dispatchEvent(n);var a=It(t);if(i&&a!==t){var o=Pt(a,n.detail);i=i&&e.dispatchEvent(o)}w(e,function(e){i=i&&e.onEvent(t,n)!==false});return i}var Mt=location.pathname+location.search;function Dt(){var e=K().querySelector("[hx-history-elt],[data-hx-history-elt]");return e||K().body}function Xt(e,t,r,n){if(!M()){return}e=D(e);var i=y(localStorage.getItem("htmx-history-cache"))||[];for(var a=0;a<i.length;a++){if(i[a].url===e){i.splice(a,1);break}}var o={url:e,content:t,title:r,scroll:n};oe(K().body,"htmx:historyItemCreated",{item:o,cache:i});i.push(o);while(i.length>G.config.historyCacheSize){i.shift()}while(i.length>0){try{localStorage.setItem("htmx-history-cache",JSON.stringify(i));break}catch(e){ae(K().body,"htmx:historyCacheError",{cause:e,cache:i});i.shift()}}}function Ft(e){if(!M()){return null}e=D(e);var t=y(localStorage.getItem("htmx-history-cache"))||[];for(var r=0;r<t.length;r++){if(t[r].url===e){return t[r]}}return null}function Ut(e){var t=G.config.requestClass;var r=e.cloneNode(true);te(f(r,"."+t),function(e){n(e,t)});return r.innerHTML}function Bt(){var e=Dt();var t=Mt||location.pathname+location.search;var r=K().querySelector('[hx-history="false" i],[data-hx-history="false" i]');if(!r){oe(K().body,"htmx:beforeHistorySave",{path:t,historyElt:e});Xt(t,Ut(e),K().title,window.scrollY)}if(G.config.historyEnabled)history.replaceState({htmx:true},K().title,window.location.href)}function Vt(e){if(G.config.getCacheBusterParam){e=e.replace(/org\.htmx\.cache-buster=[^&]*&?/,"");if(e.endsWith("&")||e.endsWith("?")){e=e.slice(0,-1)}}if(G.config.historyEnabled){history.pushState({htmx:true},"",e)}Mt=e}function jt(e){if(G.config.historyEnabled)history.replaceState({htmx:true},"",e);Mt=e}function Wt(e){te(e,function(e){e.call()})}function _t(a){var e=new XMLHttpRequest;var o={path:a,xhr:e};oe(K().body,"htmx:historyCacheMiss",o);e.open("GET",a,true);e.setRequestHeader("HX-History-Restore-Request","true");e.onload=function(){if(this.status>=200&&this.status<400){oe(K().body,"htmx:historyCacheMissLoad",o);var e=l(this.response);e=e.querySelector("[hx-history-elt],[data-hx-history-elt]")||e;var t=Dt();var r=S(t);var n=Me(this.response);if(n){var i=b("title");if(i){i.innerHTML=n}else{window.document.title=n}}Ie(t,e,r);Wt(r.tasks);Mt=a;oe(K().body,"htmx:historyRestore",{path:a,cacheMiss:true,serverResponse:this.response})}else{ae(K().body,"htmx:historyCacheMissLoadError",o)}};e.send()}function zt(e){Bt();e=e||location.pathname+location.search;var t=Ft(e);if(t){var r=l(t.content);var n=Dt();var i=S(n);Ie(n,r,i);Wt(i.tasks);document.title=t.title;setTimeout(function(){window.scrollTo(0,t.scroll)},0);Mt=e;oe(K().body,"htmx:historyRestore",{path:e,item:t})}else{if(G.config.refreshOnHistoryMiss){window.location.reload(true)}else{_t(e)}}}function $t(e){var t=ce(e,"hx-indicator");if(t==null){t=[e]}te(t,function(e){var t=ee(e);t.requestCount=(t.requestCount||0)+1;e.classList["add"].call(e.classList,G.config.requestClass)});return t}function Gt(e){te(e,function(e){var t=ee(e);t.requestCount=(t.requestCount||0)-1;if(t.requestCount===0){e.classList["remove"].call(e.classList,G.config.requestClass)}})}function Jt(e,t){for(var r=0;r<e.length;r++){var n=e[r];if(n.isSameNode(t)){return true}}return false}function Zt(e){if(e.name===""||e.name==null||e.disabled){return false}if(e.type==="button"||e.type==="submit"||e.tagName==="image"||e.tagName==="reset"||e.tagName==="file"){return false}if(e.type==="checkbox"||e.type==="radio"){return e.checked}return true}function Kt(e,t,r){if(e!=null&&t!=null){var n=r[e];if(n===undefined){r[e]=t}else if(Array.isArray(n)){if(Array.isArray(t)){r[e]=n.concat(t)}else{n.push(t)}}else{if(Array.isArray(t)){r[e]=[n].concat(t)}else{r[e]=[n,t]}}}}function Yt(t,r,n,e,i){if(e==null||Jt(t,e)){return}else{t.push(e)}if(Zt(e)){var a=J(e,"name");var o=e.value;if(e.multiple){o=I(e.querySelectorAll("option:checked")).map(function(e){return e.value})}if(e.files){o=I(e.files)}Kt(a,o,r);if(i){Qt(e,n)}}if(h(e,"form")){var s=e.elements;te(s,function(e){Yt(t,r,n,e,i)})}}function Qt(e,t){if(e.willValidate){oe(e,"htmx:validation:validate");if(!e.checkValidity()){t.push({elt:e,message:e.validationMessage,validity:e.validity});oe(e,"htmx:validation:failed",{message:e.validationMessage,validity:e.validity})}}}function er(e,t){var r=[];var n={};var i={};var a=[];var o=ee(e);var s=h(e,"form")&&e.noValidate!==true||Z(e,"hx-validate")==="true";if(o.lastButtonClicked){s=s&&o.lastButtonClicked.formNoValidate!==true}if(t!=="get"){Yt(r,i,a,d(e,"form"),s)}Yt(r,n,a,e,s);if(o.lastButtonClicked||e.tagName==="BUTTON"||e.tagName==="INPUT"&&J(e,"type")==="submit"){var l=o.lastButtonClicked||e;var u=J(l,"name");Kt(u,l.value,i)}var f=ce(e,"hx-include");te(f,function(e){Yt(r,n,a,e,s);if(!h(e,"form")){te(e.querySelectorAll($e),function(e){Yt(r,n,a,e,s)})}});n=ne(n,i);return{errors:a,values:n}}function tr(e,t,r){if(e!==""){e+="&"}if(String(r)==="[object Object]"){r=JSON.stringify(r)}var n=encodeURIComponent(r);e+=encodeURIComponent(t)+"="+n;return e}function rr(e){var t="";for(var r in e){if(e.hasOwnProperty(r)){var n=e[r];if(Array.isArray(n)){te(n,function(e){t=tr(t,r,e)})}else{t=tr(t,r,n)}}}return t}function nr(e){var t=new FormData;for(var r in e){if(e.hasOwnProperty(r)){var n=e[r];if(Array.isArray(n)){te(n,function(e){t.append(r,e)})}else{t.append(r,n)}}}return t}function ir(e,t,r){var n={"HX-Request":"true","HX-Trigger":J(e,"id"),"HX-Trigger-Name":J(e,"name"),"HX-Target":Z(t,"id"),"HX-Current-URL":K().location.href};cr(e,"hx-headers",false,n);if(r!==undefined){n["HX-Prompt"]=r}if(ee(e).boosted){n["HX-Boosted"]="true"}return n}function ar(t,e){var r=Y(e,"hx-params");if(r){if(r==="none"){return{}}else if(r==="*"){return t}else if(r.indexOf("not ")===0){te(r.substr(4).split(","),function(e){e=e.trim();delete t[e]});return t}else{var n={};te(r.split(","),function(e){e=e.trim();n[e]=t[e]});return n}}else{return t}}function or(e){return J(e,"href")&&J(e,"href").indexOf("#")>=0}function sr(e,t){var r=t?t:Y(e,"hx-swap");var n={swapStyle:ee(e).boosted?"innerHTML":G.config.defaultSwapStyle,swapDelay:G.config.defaultSwapDelay,settleDelay:G.config.defaultSettleDelay};if(ee(e).boosted&&!or(e)){n["show"]="top"}if(r){var i=k(r);if(i.length>0){n["swapStyle"]=i[0];for(var a=1;a<i.length;a++){var o=i[a];if(o.indexOf("swap:")===0){n["swapDelay"]=v(o.substr(5))}if(o.indexOf("settle:")===0){n["settleDelay"]=v(o.substr(7))}if(o.indexOf("transition:")===0){n["transition"]=o.substr(11)==="true"}if(o.indexOf("scroll:")===0){var s=o.substr(7);var l=s.split(":");var u=l.pop();var f=l.length>0?l.join(":"):null;n["scroll"]=u;n["scrollTarget"]=f}if(o.indexOf("show:")===0){var c=o.substr(5);var l=c.split(":");var h=l.pop();var f=l.length>0?l.join(":"):null;n["show"]=h;n["showTarget"]=f}if(o.indexOf("focus-scroll:")===0){var d=o.substr("focus-scroll:".length);n["focusScroll"]=d=="true"}}}}return n}function lr(e){return Y(e,"hx-encoding")==="multipart/form-data"||h(e,"form")&&J(e,"enctype")==="multipart/form-data"}function ur(t,r,n){var i=null;w(r,function(e){if(i==null){i=e.encodeParameters(t,n,r)}});if(i!=null){return i}else{if(lr(r)){return nr(n)}else{return rr(n)}}}function S(e){return{tasks:[],elts:[e]}}function fr(e,t){var r=e[0];var n=e[e.length-1];if(t.scroll){var i=null;if(t.scrollTarget){i=ie(r,t.scrollTarget)}if(t.scroll==="top"&&(r||i)){i=i||r;i.scrollTop=0}if(t.scroll==="bottom"&&(n||i)){i=i||n;i.scrollTop=i.scrollHeight}}if(t.show){var i=null;if(t.showTarget){var a=t.showTarget;if(t.showTarget==="window"){a="body"}i=ie(r,a)}if(t.show==="top"&&(r||i)){i=i||r;i.scrollIntoView({block:"start",behavior:G.config.scrollBehavior})}if(t.show==="bottom"&&(n||i)){i=i||n;i.scrollIntoView({block:"end",behavior:G.config.scrollBehavior})}}}function cr(e,t,r,n){if(n==null){n={}}if(e==null){return n}var i=Z(e,t);if(i){var a=i.trim();var o=r;if(a==="unset"){return null}if(a.indexOf("javascript:")===0){a=a.substr(11);o=true}else if(a.indexOf("js:")===0){a=a.substr(3);o=true}if(a.indexOf("{")!==0){a="{"+a+"}"}var s;if(o){s=hr(e,function(){return Function("return ("+a+")")()},{})}else{s=y(a)}for(var l in s){if(s.hasOwnProperty(l)){if(n[l]==null){n[l]=s[l]}}}}return cr(u(e),t,r,n)}function hr(e,t,r){if(G.config.allowEval){return t()}else{ae(e,"htmx:evalDisallowedError");return r}}function dr(e,t){return cr(e,"hx-vars",true,t)}function vr(e,t){return cr(e,"hx-vals",false,t)}function gr(e){return ne(dr(e),vr(e))}function pr(t,r,n){if(n!==null){try{t.setRequestHeader(r,n)}catch(e){t.setRequestHeader(r,encodeURIComponent(n));t.setRequestHeader(r+"-URI-AutoEncoded","true")}}}function mr(t){if(t.responseURL&&typeof URL!=="undefined"){try{var e=new URL(t.responseURL);return e.pathname+e.search}catch(e){ae(K().body,"htmx:badResponseUrl",{url:t.responseURL})}}}function E(e,t){return e.getAllResponseHeaders().match(t)}function xr(e,t,r){e=e.toLowerCase();if(r){if(r instanceof Element||L(r,"String")){return se(e,t,null,null,{targetOverride:s(r),returnPromise:true})}else{return se(e,t,s(r.source),r.event,{handler:r.handler,headers:r.headers,values:r.values,targetOverride:s(r.target),swapOverride:r.swap,returnPromise:true})}}else{return se(e,t,null,null,{returnPromise:true})}}function yr(e){var t=[];while(e){t.push(e);e=e.parentElement}return t}function br(e,t,r){var n=new URL(t,document.location.href);var i=document.location.origin;var a=i===n.origin;if(G.config.selfRequestsOnly){if(!a){return false}}return oe(e,"htmx:validateUrl",ne({url:n,sameHost:a},r))}function se(e,t,n,r,i,M){var a=null;var o=null;i=i!=null?i:{};if(i.returnPromise&&typeof Promise!=="undefined"){var s=new Promise(function(e,t){a=e;o=t})}if(n==null){n=K().body}var D=i.handler||Sr;if(!re(n)){return}var l=i.targetOverride||de(n);if(l==null||l==fe){ae(n,"htmx:targetError",{target:Z(n,"hx-target")});return}if(!M){var X=function(){return se(e,t,n,r,i,true)};var F={target:l,elt:n,path:t,verb:e,triggeringEvent:r,etc:i,issueRequest:X};if(oe(n,"htmx:confirm",F)===false){return}}var u=n;var f=ee(n);var c=Y(n,"hx-sync");var h=null;var d=false;if(c){var v=c.split(":");var g=v[0].trim();if(g==="this"){u=he(n,"hx-sync")}else{u=ie(n,g)}c=(v[1]||"drop").trim();f=ee(u);if(c==="drop"&&f.xhr&&f.abortable!==true){return}else if(c==="abort"){if(f.xhr){return}else{d=true}}else if(c==="replace"){oe(u,"htmx:abort")}else if(c.indexOf("queue")===0){var U=c.split(" ");h=(U[1]||"last").trim()}}if(f.xhr){if(f.abortable){oe(u,"htmx:abort")}else{if(h==null){if(r){var p=ee(r);if(p&&p.triggerSpec&&p.triggerSpec.queue){h=p.triggerSpec.queue}}if(h==null){h="last"}}if(f.queuedRequests==null){f.queuedRequests=[]}if(h==="first"&&f.queuedRequests.length===0){f.queuedRequests.push(function(){se(e,t,n,r,i)})}else if(h==="all"){f.queuedRequests.push(function(){se(e,t,n,r,i)})}else if(h==="last"){f.queuedRequests=[];f.queuedRequests.push(function(){se(e,t,n,r,i)})}return}}var m=new XMLHttpRequest;f.xhr=m;f.abortable=d;var x=function(){f.xhr=null;f.abortable=false;if(f.queuedRequests!=null&&f.queuedRequests.length>0){var e=f.queuedRequests.shift();e()}};var y=Y(n,"hx-prompt");if(y){var b=prompt(y);if(b===null||!oe(n,"htmx:prompt",{prompt:b,target:l})){Q(a);x();return s}}var w=Y(n,"hx-confirm");if(w){if(!confirm(w)){Q(a);x();return s}}var S=ir(n,l,b);if(i.headers){S=ne(S,i.headers)}var E=er(n,e);var C=E.errors;var R=E.values;if(i.values){R=ne(R,i.values)}var B=gr(n);var O=ne(R,B);var T=ar(O,n);if(e!=="get"&&!lr(n)){S["Content-Type"]="application/x-www-form-urlencoded"}if(G.config.getCacheBusterParam&&e==="get"){T["org.htmx.cache-buster"]=J(l,"id")||"true"}if(t==null||t===""){t=K().location.href}var q=cr(n,"hx-request");var V=ee(n).boosted;var H=G.config.methodsThatUseUrlParams.indexOf(e)>=0;var L={boosted:V,useUrlParams:H,parameters:T,unfilteredParameters:O,headers:S,target:l,verb:e,errors:C,withCredentials:i.credentials||q.credentials||G.config.withCredentials,timeout:i.timeout||q.timeout||G.config.timeout,path:t,triggeringEvent:r};if(!oe(n,"htmx:configRequest",L)){Q(a);x();return s}t=L.path;e=L.verb;S=L.headers;T=L.parameters;C=L.errors;H=L.useUrlParams;if(C&&C.length>0){oe(n,"htmx:validation:halted",L);Q(a);x();return s}var j=t.split("#");var W=j[0];var A=j[1];var N=t;if(H){N=W;var _=Object.keys(T).length!==0;if(_){if(N.indexOf("?")<0){N+="?"}else{N+="&"}N+=rr(T);if(A){N+="#"+A}}}if(!br(n,N,L)){ae(n,"htmx:invalidPath",L);return}m.open(e.toUpperCase(),N,true);m.overrideMimeType("text/html");m.withCredentials=L.withCredentials;m.timeout=L.timeout;if(q.noHeaders){}else{for(var I in S){if(S.hasOwnProperty(I)){var z=S[I];pr(m,I,z)}}}var P={xhr:m,target:l,requestConfig:L,etc:i,boosted:V,pathInfo:{requestPath:t,finalRequestPath:N,anchor:A}};m.onload=function(){try{var e=yr(n);P.pathInfo.responsePath=mr(m);D(n,P);Gt(k);oe(n,"htmx:afterRequest",P);oe(n,"htmx:afterOnLoad",P);if(!re(n)){var t=null;while(e.length>0&&t==null){var r=e.shift();if(re(r)){t=r}}if(t){oe(t,"htmx:afterRequest",P);oe(t,"htmx:afterOnLoad",P)}}Q(a);x()}catch(e){ae(n,"htmx:onLoadError",ne({error:e},P));throw e}};m.onerror=function(){Gt(k);ae(n,"htmx:afterRequest",P);ae(n,"htmx:sendError",P);Q(o);x()};m.onabort=function(){Gt(k);ae(n,"htmx:afterRequest",P);ae(n,"htmx:sendAbort",P);Q(o);x()};m.ontimeout=function(){Gt(k);ae(n,"htmx:afterRequest",P);ae(n,"htmx:timeout",P);Q(o);x()};if(!oe(n,"htmx:beforeRequest",P)){Q(a);x();return s}var k=$t(n);te(["loadstart","loadend","progress","abort"],function(t){te([m,m.upload],function(e){e.addEventListener(t,function(e){oe(n,"htmx:xhr:"+t,{lengthComputable:e.lengthComputable,loaded:e.loaded,total:e.total})})})});oe(n,"htmx:beforeSend",P);var $=H?null:ur(m,n,T);m.send($);return s}function wr(e,t){var r=t.xhr;var n=null;var i=null;if(E(r,/HX-Push:/i)){n=r.getResponseHeader("HX-Push");i="push"}else if(E(r,/HX-Push-Url:/i)){n=r.getResponseHeader("HX-Push-Url");i="push"}else if(E(r,/HX-Replace-Url:/i)){n=r.getResponseHeader("HX-Replace-Url");i="replace"}if(n){if(n==="false"){return{}}else{return{type:i,path:n}}}var a=t.pathInfo.finalRequestPath;var o=t.pathInfo.responsePath;var s=Y(e,"hx-push-url");var l=Y(e,"hx-replace-url");var u=ee(e).boosted;var f=null;var c=null;if(s){f="push";c=s}else if(l){f="replace";c=l}else if(u){f="push";c=o||a}if(c){if(c==="false"){return{}}if(c==="true"){c=o||a}if(t.pathInfo.anchor&&c.indexOf("#")===-1){c=c+"#"+t.pathInfo.anchor}return{type:f,path:c}}else{return{}}}function Sr(l,u){var f=u.xhr;var c=u.target;var e=u.etc;if(!oe(l,"htmx:beforeOnLoad",u))return;if(E(f,/HX-Trigger:/i)){Xe(f,"HX-Trigger",l)}if(E(f,/HX-Location:/i)){Bt();var t=f.getResponseHeader("HX-Location");var h;if(t.indexOf("{")===0){h=y(t);t=h["path"];delete h["path"]}xr("GET",t,h).then(function(){Vt(t)});return}if(E(f,/HX-Redirect:/i)){location.href=f.getResponseHeader("HX-Redirect");return}if(E(f,/HX-Refresh:/i)){if("true"===f.getResponseHeader("HX-Refresh")){location.reload();return}}if(E(f,/HX-Retarget:/i)){u.target=K().querySelector(f.getResponseHeader("HX-Retarget"))}var d=wr(l,u);var r=f.status>=200&&f.status<400&&f.status!==204;var v=f.response;var n=f.status>=400;var i=ne({shouldSwap:r,serverResponse:v,isError:n},u);if(!oe(c,"htmx:beforeSwap",i))return;c=i.target;v=i.serverResponse;n=i.isError;u.target=c;u.failed=n;u.successful=!n;if(i.shouldSwap){if(f.status===286){Je(l)}w(l,function(e){v=e.transformResponse(v,f,l)});if(d.type){Bt()}var a=e.swapOverride;if(E(f,/HX-Reswap:/i)){a=f.getResponseHeader("HX-Reswap")}var h=sr(l,a);c.classList.add(G.config.swappingClass);var g=null;var p=null;var o=function(){try{var e=document.activeElement;var t={};try{t={elt:e,start:e?e.selectionStart:null,end:e?e.selectionEnd:null}}catch(e){}var r;if(E(f,/HX-Reselect:/i)){r=f.getResponseHeader("HX-Reselect")}var n=S(c);De(h.swapStyle,c,l,v,n,r);if(t.elt&&!re(t.elt)&&J(t.elt,"id")){var i=document.getElementById(J(t.elt,"id"));var a={preventScroll:h.focusScroll!==undefined?!h.focusScroll:!G.config.defaultFocusScroll};if(i){if(t.start&&i.setSelectionRange){try{i.setSelectionRange(t.start,t.end)}catch(e){}}i.focus(a)}}c.classList.remove(G.config.swappingClass);te(n.elts,function(e){if(e.classList){e.classList.add(G.config.settlingClass)}oe(e,"htmx:afterSwap",u)});if(E(f,/HX-Trigger-After-Swap:/i)){var o=l;if(!re(l)){o=K().body}Xe(f,"HX-Trigger-After-Swap",o)}var s=function(){te(n.tasks,function(e){e.call()});te(n.elts,function(e){if(e.classList){e.classList.remove(G.config.settlingClass)}oe(e,"htmx:afterSettle",u)});if(d.type){if(d.type==="push"){Vt(d.path);oe(K().body,"htmx:pushedIntoHistory",{path:d.path})}else{jt(d.path);oe(K().body,"htmx:replacedInHistory",{path:d.path})}}if(u.pathInfo.anchor){var e=b("#"+u.pathInfo.anchor);if(e){e.scrollIntoView({block:"start",behavior:"auto"})}}if(n.title){var t=b("title");if(t){t.innerHTML=n.title}else{window.document.title=n.title}}fr(n.elts,h);if(E(f,/HX-Trigger-After-Settle:/i)){var r=l;if(!re(l)){r=K().body}Xe(f,"HX-Trigger-After-Settle",r)}Q(g)};if(h.settleDelay>0){setTimeout(s,h.settleDelay)}else{s()}}catch(e){ae(l,"htmx:swapError",u);Q(p);throw e}};var s=G.config.globalViewTransitions;if(h.hasOwnProperty("transition")){s=h.transition}if(s&&oe(l,"htmx:beforeTransition",u)&&typeof Promise!=="undefined"&&document.startViewTransition){var m=new Promise(function(e,t){g=e;p=t});var x=o;o=function(){document.startViewTransition(function(){x();return m})}}if(h.swapDelay>0){setTimeout(o,h.swapDelay)}else{o()}}if(n){ae(l,"htmx:responseError",ne({error:"Response Status Error Code "+f.status+" from "+u.pathInfo.requestPath},u))}}var Er={};function Cr(){return{init:function(e){return null},onEvent:function(e,t){return true},transformResponse:function(e,t,r){return e},isInlineSwap:function(e){return false},handleSwap:function(e,t,r,n){return false},encodeParameters:function(e,t,r){return null}}}function Rr(e,t){if(t.init){t.init(C)}Er[e]=ne(Cr(),t)}function Or(e){delete Er[e]}function Tr(e,r,n){if(e==undefined){return r}if(r==undefined){r=[]}if(n==undefined){n=[]}var t=Z(e,"hx-ext");if(t){te(t.split(","),function(e){e=e.replace(/ /g,"");if(e.slice(0,7)=="ignore:"){n.push(e.slice(7));return}if(n.indexOf(e)<0){var t=Er[e];if(t&&r.indexOf(t)<0){r.push(t)}}})}return Tr(u(e),r,n)}var qr=false;K().addEventListener("DOMContentLoaded",function(){qr=true});function Hr(e){if(qr||K().readyState==="complete"){e()}else{K().addEventListener("DOMContentLoaded",e)}}function Lr(){if(G.config.includeIndicatorStyles!==false){K().head.insertAdjacentHTML("beforeend","<style> ."+G.config.indicatorClass+"{opacity:0;transition: opacity 200ms ease-in;} ."+G.config.requestClass+" ."+G.config.indicatorClass+"{opacity:1} ."+G.config.requestClass+"."+G.config.indicatorClass+"{opacity:1} </style>")}}function Ar(){var e=K().querySelector('meta[name="htmx-config"]');if(e){return y(e.content)}else{return null}}function Nr(){var e=Ar();if(e){G.config=ne(G.config,e)}}Hr(function(){Nr();Lr();var e=K().body;Nt(e);var t=K().querySelectorAll("[hx-trigger='restored'],[data-hx-trigger='restored']");e.addEventListener("htmx:abort",function(e){var t=e.target;var r=ee(t);if(r&&r.xhr){r.xhr.abort()}});var r=window.onpopstate;window.onpopstate=function(e){if(e.state&&e.state.htmx){zt();te(t,function(e){oe(e,"htmx:restored",{document:K(),triggerEvent:oe})})}else{if(r){r(e)}}};setTimeout(function(){oe(e,"htmx:load",{});e=null},0)});return G}()});⏎̸ | |||
A internal/webui/public/libs/iconoir.css +22 -0 too large to show in the browser
too large to show in the browser view raw
A internal/webui/public/site.webmanifest +1 -0
| @@ -0,0 +1,1 @@ | |||
| 1 | + | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}⏎̸ | |
| @@ -0,0 +1,1 @@ | |||||
| 1 | + | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}⏎̸ | |||
D package-lock.json +0 -991 generated file: collapsed
A pkg/utils/htmx/htmlfragments.go +42 -0
| @@ -0,0 +1,42 @@ | |||
| 1 | + | package htmx | |
| 2 | + | ||
| 3 | + | import ( | |
| 4 | + | "bytes" | |
| 5 | + | ||
| 6 | + | "github.com/PuerkitoBio/goquery" | |
| 7 | + | ||
| 8 | + | ) | |
| 9 | + | ||
| 10 | + | // GetHTMLFragmentByID returns the HTML fragment with the specified id | |
| 11 | + | func GetHTMLFragmentByID(id string, data interface{}, a *app.App, ac *app.Config) (string, error) { | |
| 12 | + | // 1. Render the template | |
| 13 | + | renderer, err := templating.GetHTMLRenderer("components.gohtml", ac.GetTemplateFS(), a) | |
| 14 | + | if err != nil { | |
| 15 | + | return "", err | |
| 16 | + | } | |
| 17 | + | ||
| 18 | + | renderedHTML, err := renderer.Render(data, a) | |
| 19 | + | if err != nil { | |
| 20 | + | return "", err | |
| 21 | + | } | |
| 22 | + | ||
| 23 | + | // 2. Parse the rendered HTML with goquery | |
| 24 | + | doc, err := goquery.NewDocumentFromReader(bytes.NewReader([]byte(renderedHTML))) | |
| 25 | + | if err != nil { | |
| 26 | + | return "", err | |
| 27 | + | } | |
| 28 | + | ||
| 29 | + | // 3. Find the div with the specified id | |
| 30 | + | fragmentContent, err := doc.Find("#" + id).Html() | |
| 31 | + | if err != nil { | |
| 32 | + | return "", err | |
| 33 | + | } | |
| 34 | + | ||
| 35 | + | if fragmentcontent == "" { | |
| 36 | + | return "", err | |
| 37 | + | } | |
| 38 | + | ||
| 39 | + | return fragmentContent, nil | |
| 40 | + | } | |
| 41 | + | ||
| 42 | + | ||
| @@ -0,0 +1,42 @@ | |||||
| 1 | + | package htmx | |||
| 2 | + | ||||
| 3 | + | import ( | |||
| 4 | + | "bytes" | |||
| 5 | + | ||||
| 6 | + | "github.com/PuerkitoBio/goquery" | |||
| 7 | + | ||||
| 8 | + | ) | |||
| 9 | + | ||||
| 10 | + | // GetHTMLFragmentByID returns the HTML fragment with the specified id | |||
| 11 | + | func GetHTMLFragmentByID(id string, data interface{}, a *app.App, ac *app.Config) (string, error) { | |||
| 12 | + | // 1. Render the template | |||
| 13 | + | renderer, err := templating.GetHTMLRenderer("components.gohtml", ac.GetTemplateFS(), a) | |||
| 14 | + | if err != nil { | |||
| 15 | + | return "", err | |||
| 16 | + | } | |||
| 17 | + | ||||
| 18 | + | renderedHTML, err := renderer.Render(data, a) | |||
| 19 | + | if err != nil { | |||
| 20 | + | return "", err | |||
| 21 | + | } | |||
| 22 | + | ||||
| 23 | + | // 2. Parse the rendered HTML with goquery | |||
| 24 | + | doc, err := goquery.NewDocumentFromReader(bytes.NewReader([]byte(renderedHTML))) | |||
| 25 | + | if err != nil { | |||
| 26 | + | return "", err | |||
| 27 | + | } | |||
| 28 | + | ||||
| 29 | + | // 3. Find the div with the specified id | |||
| 30 | + | fragmentContent, err := doc.Find("#" + id).Html() | |||
| 31 | + | if err != nil { | |||
| 32 | + | return "", err | |||
| 33 | + | } | |||
| 34 | + | ||||
| 35 | + | if fragmentcontent == "" { | |||
| 36 | + | return "", err | |||
| 37 | + | } | |||
| 38 | + | ||||
| 39 | + | return fragmentContent, nil | |||
| 40 | + | } | |||
| 41 | + | ||||
| 42 | + | ||||