+ 404 +
++ Page not found +
++ This page doesn't exist +
+ + + Go Home + +diff --git a/.air.toml b/.air.toml new file mode 100644 index 0000000..1be4367 --- /dev/null +++ b/.air.toml @@ -0,0 +1,52 @@ +root = "." +tmp_dir = "tmp" + +[build] +pre_cmd = [""] +bin = "./tmp/main" +cmd = "go build -o ./tmp/main ." +include_dir = [] +include_ext = ["go"] +include_file = [""] +exclude_dir = [ + "bin", + "dist", + "assets", + "tmp", + "vendor", + "node_modules", + "bin", + "tests", + "vendor", +] +exclude_file = [] +exclude_regex = ["_test\\.go", "_templ\\.go"] +exclude_unchanged = false +follow_symlink = false +log = "build-errors-air.log" +full_bin = "" +delay = 100 +poll = false +rerun = false +rerun_delay = 500 +poll_interval = 500 +kill_delay = "0s" +send_interrupt = false +stop_on_error = true + +[color] +app = "" +build = "yellow" +main = "magenta" +runner = "green" +watcher = "cyan" + +[log] +time = false + +[misc] +clean_on_exit = false + +[screen] +clear_on_rebuild = false +keep_scroll = true diff --git a/.air_proxy.toml b/.air_proxy.toml new file mode 100644 index 0000000..aafd4ef --- /dev/null +++ b/.air_proxy.toml @@ -0,0 +1,41 @@ +root = "." +tmp_dir = "tmp" + +[build] +pre_cmd = [""] +bin = "true" +cmd = "echo 'running proxy one' && templ generate --notify-proxy --proxybind='localhost' --proxyport='8080'" +include_dir = ["assets"] +include_ext = [""] +include_file = ["js,css"] +exclude_file = [] +exclude_regex = ["_test\\.go", "_templ\\.go"] +exclude_unchanged = false +follow_symlink = false +log = "build-errors-air.log" +full_bin = "" +delay = 100 +poll = false +rerun = false +rerun_delay = 500 +poll_interval = 500 +kill_delay = "0s" +send_interrupt = false +stop_on_error = true + +[color] +app = "" +build = "yellow" +main = "magenta" +runner = "green" +watcher = "cyan" + +[log] +time = false + +[misc] +clean_on_exit = true + +[screen] +clear_on_rebuild = true +keep_scroll = true diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..dfe833c --- /dev/null +++ b/.dockerignore @@ -0,0 +1,33 @@ +# Auto-generated .dockerignore file. +# See https://gowebly.org for more information. + +# Ignore folders. +.git/ +.github/ +.vscode/ +.idea/ +node_modules/ +bin/ +dist/ +dist-ssr/ +tmp/ +tests/ + +# Ignore files. +LICENSE +.DS_Store +.dockerignore +.gitignore +.postcssrc +Dockerfile +**/*.templ +**/*_test.go +package.json +*-lock.json +*.lockb +*.config.* +*.yml +*.yaml +*.toml +*.md +*.out diff --git a/.gitignore b/.gitignore index 6f6f5e6..a94a31d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,22 +1,57 @@ -# If you prefer the allow list template instead of the deny list, see community template: -# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore -# -# Binaries for programs and plugins +# Auto-generated .gitignore file. +# See https://gowebly.org for more information. + +# macOS files. +.DS_Store + +# IDE files. +.idea/ +.vscode/ + +# Go workflow files. +go.work + +# Environment files. +.env + +# Generated folders. +bin/ +dist-ssr/ +dist/ + +# Node modules. +node_modules/ + +# Vendor folders. +vendor/ + +# Temp folders. +.parcel-cache/ +tmp/ + +# Logs. +logs/ +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +# Ignore by extensions. *.exe *.exe~ *.dll *.so +.*_templ.go *.dylib - -# Test binary, built with `go test -c` +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +*.local +*.lockb *.test - -# Output of the go coverage tool, specifically when used with LiteIDE +*.tmp *.out - -# Dependency directories (remove the comment below to include it) -# vendor/ - -# Go workspace file -go.work -go.work.sum diff --git a/.postcssrc b/.postcssrc new file mode 100644 index 0000000..0985cb2 --- /dev/null +++ b/.postcssrc @@ -0,0 +1,5 @@ +{ + "plugins": { + "tailwindcss": {} + } +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..874dcb7 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,8 @@ +# Auto-generated .gitignore file. +# See https://gowebly.org for more information. + +# Ignore static files. +static/ + +# Ignore templates. +templates/ diff --git a/README.md b/README.md index 78a0e8b..fa6875e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # trivia-chase + Trivial Pursuit inspired game using HTMX and Go. diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..5b078db --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,122 @@ +version: '3' + +dotenv: [.env] + +tasks: + default: + desc: Display all available tasks. + cmds: + - task: list + + list: + desc: List all tasks. + cmds: + - task -l + + install: + desc: Initialize the project. + cmds: + - task: install:bun + - task: install:modules + - task: install:tools + - task: install:golint + + gen: + desc: Generate Templ and TailwindCSS files. + cmds: + - bun run fmt + - bun run build + - task: generate-templ + + generate-templ: + desc: Generate Templ files. + cmds: + - templ generate + + dev: + desc: Run the dev server. + cmds: + - task --parallel dev:templ dev:air dev:assets dev:sync_assets + + dev:assets: + desc: Run TailwindCSS And Esbuild build in watch mode. + cmds: + - bun run dev + + dev:air: + desc: Run the dev server with air. + cmds: + - air -c .air.toml + + dev:templ: + desc: Run the dev server with templ. + cmds: + - templ generate --watch --proxy="http://localhost:8080" --open-browser=false + + dev:sync_assets: air -c .air_proxy.toml + + build: + desc: Build production Go binary and assets. + cmds: + - task: gen + - go build -o bin/app ./main.go + - chmod +x bin/app + + dev-caddy: + desc: Run Caddy server For WildCard SubDomain For Local Development. + cmds: + - caddy run --config ./scripts/Caddyfile.dev + + run: + desc: Run the Go binary. + cmds: + - ./bin/app + + install:bun: + desc: Install dependencies. + cmds: + - bun install + + install:golint: + desc: Install golint. + cmds: + - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.55.2 + + install:modules: + desc: Download Go modules. + cmds: + - go mod download + + install:tools: + desc: Install tools. + cmds: + - awk -F'"' '/_/ {print $2}' tools.go | xargs -tI % go install % + + tidy: + desc: Tidy go.sum. + cmds: + - go mod tidy + + nil-away: nilaway -exclude-pkgs="github.com/labstack/echo,github.com/a-h/templ,github.com/cosmtrek/air,github.com/nedpals/supabase-go,github.com/apple/pkl-go" ./... + + lint: + desc: Uses golangci-lint + cmds: + - golangci-lint run + + fmt: + desc: Reformat code + cmds: + - bun run fmt + - go fmt ./... + + check: + desc: Run all checks. + cmds: + - task: fmt + - task: tidy + - task: lint + - task: nil-away + - task: vuln + - task: sql-check-files + - task: sql-check-structure diff --git a/assets/scripts.js b/assets/scripts.js new file mode 100644 index 0000000..3ccdfc4 --- /dev/null +++ b/assets/scripts.js @@ -0,0 +1,8 @@ +import 'htmx.org' +import Alpine from 'alpinejs' + +// Add Alpine instance to window object. +window.Alpine = Alpine + +// Start Alpine. +Alpine.start() diff --git a/assets/styles.scss b/assets/styles.scss new file mode 100644 index 0000000..b5c61c9 --- /dev/null +++ b/assets/styles.scss @@ -0,0 +1,3 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/cmd/main.go b/cmd/main.go new file mode 100644 index 0000000..c1db506 --- /dev/null +++ b/cmd/main.go @@ -0,0 +1,18 @@ +package cmd + +import ( + "net/http" + + "github.com/a-h/templ" + "github.com/sammyshear/trivia-chase/views/pages" +) + +func App() { + mux := http.NewServeMux() + indexPage := pages.Home() + + mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) + mux.Handle("/", templ.Handler(indexPage)) + + http.ListenAndServe(":3000", mux) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..84fd014 --- /dev/null +++ b/go.mod @@ -0,0 +1,48 @@ +module github.com/sammyshear/trivia-chase + +go 1.22.5 + +require ( + github.com/air-verse/air v1.52.3 + github.com/jdudmesh/gomon v0.6.3 +) + +require ( + dario.cat/mergo v1.0.0 // indirect + github.com/a-h/templ v0.2.747 // indirect + github.com/bep/godartsass v1.2.0 // indirect + github.com/bep/godartsass/v2 v2.0.0 // indirect + github.com/bep/golibsass v1.1.1 // indirect + github.com/bwmarrin/snowflake v0.3.0 // indirect + github.com/cli/safeexec v1.0.1 // indirect + github.com/creack/pty v1.1.21 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/go-sql-driver/mysql v1.8.1 // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/gohugoio/hugo v0.123.3 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/jdudmesh/gomon-ipc v0.1.1 // indirect + github.com/jmoiron/sqlx v1.3.5 // indirect + github.com/lib/pq v1.10.9 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-sqlite3 v1.14.22 // indirect + github.com/mitchellh/hashstructure v1.1.0 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.1.1 // indirect + github.com/r3labs/sse/v2 v2.10.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/stretchr/testify v1.9.0 // indirect + github.com/tdewolff/parse/v2 v2.7.12 // indirect + golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/tools v0.23.0 // indirect + google.golang.org/protobuf v1.33.0 // indirect + gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..8c02d99 --- /dev/null +++ b/go.sum @@ -0,0 +1,296 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69 h1:+tu3HOoMXB7RXEINRVIpxJCT+KdYiI7LAEAUrOw3dIU= +github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69/go.mod h1:L1AbZdiDllfyYH5l5OkAaZtk7VkWe89bPJFmnDBNHxg= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/a-h/templ v0.2.648 h1:A1ggHGIE7AONOHrFaDTM8SrqgqHL6fWgWCijQ21Zy9I= +github.com/a-h/templ v0.2.648/go.mod h1:SA7mtYwVEajbIXFRh3vKdYm/4FYyLQAtPH1+KxzGPA8= +github.com/a-h/templ v0.2.747 h1:D0dQ2lxC3W7Dxl6fxQ/1zZHBQslSkTSvl5FxP/CfdKg= +github.com/a-h/templ v0.2.747/go.mod h1:69ObQIbrcuwPCU32ohNaWce3Cb7qM5GMiqN1K+2yop4= +github.com/air-verse/air v1.52.3 h1:BkFIIk4v21hsViWzV9z7hvuLjhI+yXt4Xa16M1mb+4o= +github.com/air-verse/air v1.52.3/go.mod h1:1xd2oyYArpkaeJ0IXNYj+GYLwdfPfID+cAh7cu6XTlI= +github.com/alecthomas/chroma/v2 v2.12.0 h1:Wh8qLEgMMsN7mgyG8/qIpegky2Hvzr4By6gEF7cmWgw= +github.com/alecthomas/chroma/v2 v2.12.0/go.mod h1:4TQu7gdfuPjSh76j78ietmqh9LiurGF0EpseFXdKMBw= +github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c h1:651/eoCRnQ7YtSjAnSzRucrJz+3iGEFt+ysraELS81M= +github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/bep/clocks v0.5.0 h1:hhvKVGLPQWRVsBP/UB7ErrHYIO42gINVbvqxvYTPVps= +github.com/bep/clocks v0.5.0/go.mod h1:SUq3q+OOq41y2lRQqH5fsOoxN8GbxSiT6jvoVVLCVhU= +github.com/bep/debounce v1.2.0 h1:wXds8Kq8qRfwAOpAxHrJDbCXgC5aHSzgQb/0gKsHQqo= +github.com/bep/debounce v1.2.0/go.mod h1:H8yggRPQKLUhUoqrJC1bO2xNya7vanpDl7xR3ISbCJ0= +github.com/bep/gitmap v1.1.2 h1:zk04w1qc1COTZPPYWDQHvns3y1afOsdRfraFQ3qI840= +github.com/bep/gitmap v1.1.2/go.mod h1:g9VRETxFUXNWzMiuxOwcudo6DfZkW9jOsOW0Ft4kYaY= +github.com/bep/goat v0.5.0 h1:S8jLXHCVy/EHIoCY+btKkmcxcXFd34a0Q63/0D4TKeA= +github.com/bep/goat v0.5.0/go.mod h1:Md9x7gRxiWKs85yHlVTvHQw9rg86Bm+Y4SuYE8CTH7c= +github.com/bep/godartsass v1.2.0 h1:E2VvQrxAHAFwbjyOIExAMmogTItSKodoKuijNrGm5yU= +github.com/bep/godartsass v1.2.0/go.mod h1:6LvK9RftsXMxGfsA0LDV12AGc4Jylnu6NgHL+Q5/pE8= +github.com/bep/godartsass/v2 v2.0.0 h1:Ruht+BpBWkpmW+yAM2dkp7RSSeN0VLaTobyW0CiSP3Y= +github.com/bep/godartsass/v2 v2.0.0/go.mod h1:AcP8QgC+OwOXEq6im0WgDRYK7scDsmZCEW62o1prQLo= +github.com/bep/golibsass v1.1.1 h1:xkaet75ygImMYjM+FnHIT3xJn7H0xBA9UxSOJjk8Khw= +github.com/bep/golibsass v1.1.1/go.mod h1:DL87K8Un/+pWUS75ggYv41bliGiolxzDKWJAq3eJ1MA= +github.com/bep/gowebp v0.3.0 h1:MhmMrcf88pUY7/PsEhMgEP0T6fDUnRTMpN8OclDrbrY= +github.com/bep/gowebp v0.3.0/go.mod h1:ZhFodwdiFp8ehGJpF4LdPl6unxZm9lLFjxD3z2h2AgI= +github.com/bep/lazycache v0.4.0 h1:X8yVyWNVupPd4e1jV7efi3zb7ZV/qcjKQgIQ5aPbkYI= +github.com/bep/lazycache v0.4.0/go.mod h1:NmRm7Dexh3pmR1EignYR8PjO2cWybFQ68+QgY3VMCSc= +github.com/bep/logg v0.4.0 h1:luAo5mO4ZkhA5M1iDVDqDqnBBnlHjmtZF6VAyTp+nCQ= +github.com/bep/logg v0.4.0/go.mod h1:Ccp9yP3wbR1mm++Kpxet91hAZBEQgmWgFgnXX3GkIV0= +github.com/bep/overlayfs v0.9.1 h1:SL54SV8A3zRkmQ+83Jj4TLE88jadHd5d1L4NpfmqJJs= +github.com/bep/overlayfs v0.9.1/go.mod h1:aYY9W7aXQsGcA7V9x/pzeR8LjEgIxbtisZm8Q7zPz40= +github.com/bep/tmc v0.5.1 h1:CsQnSC6MsomH64gw0cT5f+EwQDcvZz4AazKunFwTpuI= +github.com/bep/tmc v0.5.1/go.mod h1:tGYHN8fS85aJPhDLgXETVKp+PR382OvFi2+q2GkGsq0= +github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0= +github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME= +github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= +github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q= +github.com/cli/safeexec v1.0.1 h1:e/C79PbXF4yYTN/wauC4tviMxEV13BwljGj0N9j+N00= +github.com/cli/safeexec v1.0.1/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= +github.com/creack/pty v1.1.21/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/disintegration/gift v1.2.1 h1:Y005a1X4Z7Uc+0gLpSAsKhWi4qLtsdEcMIbbdvdZ6pc= +github.com/disintegration/gift v1.2.1/go.mod h1:Jh2i7f7Q2BM7Ezno3PhfezbR1xpUg9dUg3/RlKGr4HI= +github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq0= +github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanw/esbuild v0.20.1 h1:ueyMIL19umCcJTSxiBH/QmPipgGt8hEDM24pdfowgEc= +github.com/evanw/esbuild v0.20.1/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= +github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/getkin/kin-openapi v0.123.0 h1:zIik0mRwFNLyvtXK274Q6ut+dPh6nlxBp0x7mNrPhs8= +github.com/getkin/kin-openapi v0.123.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= +github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= +github.com/go-openapi/swag v0.22.8 h1:/9RjDSQ0vbFR+NyjGMkFTsA1IA0fmhKSThmfGZjicbw= +github.com/go-openapi/swag v0.22.8/go.mod h1:6QT22icPLEqAM/z/TChgb4WAveCHF92+2gF0CNjHpPI= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/gobuffalo/flect v1.0.2 h1:eqjPGSo2WmjgY2XlpGwo2NXgL3RucAKo4k4qQMNA5sA= +github.com/gobuffalo/flect v1.0.2/go.mod h1:A5msMlrHtLqh9umBSnvabjsMrCcCpAyzglnDvkbYKHs= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gohugoio/go-i18n/v2 v2.1.3-0.20230805085216-e63c13218d0e h1:QArsSubW7eDh8APMXkByjQWvuljwPGAGQpJEFn0F0wY= +github.com/gohugoio/go-i18n/v2 v2.1.3-0.20230805085216-e63c13218d0e/go.mod h1:3Ltoo9Banwq0gOtcOwxuHG6omk+AwsQPADyw2vQYOJQ= +github.com/gohugoio/hugo v0.123.3 h1:a96Kex2xrqmrSYAYJ8MKzsKCVvCUPjW3+YyXtsEXRmE= +github.com/gohugoio/hugo v0.123.3/go.mod h1:7AHCGAy5MIFEhnvQMG5DfpVGpgrXfkoZ4z6y0zwQHLQ= +github.com/gohugoio/hugo-goldmark-extensions/passthrough v0.1.0 h1:oFQ3f1M3Ook6amHmbqVu/uBRrQ6yjMDFkIv4HQr0f1Y= +github.com/gohugoio/hugo-goldmark-extensions/passthrough v0.1.0/go.mod h1:g9CCh+Ci2IMbPUrVJuXbBTrA+rIIx5+hDQ4EXYaQDoM= +github.com/gohugoio/locales v0.14.0 h1:Q0gpsZwfv7ATHMbcTNepFd59H7GoykzWJIxi113XGDc= +github.com/gohugoio/locales v0.14.0/go.mod h1:ip8cCAv/cnmVLzzXtiTpPwgJ4xhKZranqNqtoIu0b/4= +github.com/gohugoio/localescompressed v1.0.1 h1:KTYMi8fCWYLswFyJAeOtuk/EkXR/KPTHHNN9OS+RTxo= +github.com/gohugoio/localescompressed v1.0.1/go.mod h1:jBF6q8D7a0vaEmcWPNcAjUZLJaIVNiwvM3WlmTvooB0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hairyhenderson/go-codeowners v0.4.0 h1:Wx/tRXb07sCyHeC8mXfio710Iu35uAy5KYiBdLHdv4Q= +github.com/hairyhenderson/go-codeowners v0.4.0/go.mod h1:iJgZeCt+W/GzXo5uchFCqvVHZY2T4TAIpvuVlKVkLxc= +github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= +github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/invopop/yaml v0.2.0 h1:7zky/qH+O0DwAyoobXUqvVBwgBFRxKoQ/3FjcVpjTMY= +github.com/invopop/yaml v0.2.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= +github.com/jdkato/prose v1.2.1 h1:Fp3UnJmLVISmlc57BgKUzdjr0lOtjqTZicL3PaYy6cU= +github.com/jdkato/prose v1.2.1/go.mod h1:AiRHgVagnEx2JbQRQowVBKjG0bcs/vtkGCH1dYAL1rA= +github.com/jdudmesh/gomon v0.6.3 h1:fPZCTCTqEeR1Zcip98TctBkj5IZZougfaSCMOpBPVJk= +github.com/jdudmesh/gomon v0.6.3/go.mod h1:ERKhsYNokNjH+uEr0U7b2lT/7R/0TLbqugkcjivOBk8= +github.com/jdudmesh/gomon-ipc v0.1.1 h1:8tn4VC2NIg68R1YQWTpcyYKS8Qy06yRhbPwqEEYwfA4= +github.com/jdudmesh/gomon-ipc v0.1.1/go.mod h1:INgfPXgKrSumNtUA1v2Ao0jWTz2Wie9lgvgLLWzpM5w= +github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= +github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kyokomi/emoji/v2 v2.2.12 h1:sSVA5nH9ebR3Zji1o31wu3yOwD1zKXQA2z0zUyeit60= +github.com/kyokomi/emoji/v2 v2.2.12/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/makeworld-the-better-one/dither/v2 v2.4.0 h1:Az/dYXiTcwcRSe59Hzw4RI1rSnAZns+1msaCXetrMFE= +github.com/makeworld-the-better-one/dither/v2 v2.4.0/go.mod h1:VBtN8DXO7SNtyGmLiGA7IsFeKrBkQPze1/iAeM95arc= +github.com/marekm4/color-extractor v1.2.1 h1:3Zb2tQsn6bITZ8MBVhc33Qn1k5/SEuZ18mrXGUqIwn0= +github.com/marekm4/color-extractor v1.2.1/go.mod h1:90VjmiHI6M8ez9eYUaXLdcKnS+BAOp7w+NpwBdkJmpA= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mitchellh/hashstructure v1.1.0 h1:P6P1hdjqAAknpY/M1CGipelZgp+4y9ja9kmUZPXP+H0= +github.com/mitchellh/hashstructure v1.1.0/go.mod h1:xUDAozZz0Wmdiufv0uyhnHkUTN6/6d8ulp4AwfLKrmA= +github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c h1:cqn374mizHuIWj+OSJCajGr/phAmuMug9qIX3l9CflE= +github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/muesli/smartcrop v0.3.0 h1:JTlSkmxWg/oQ1TcLDoypuirdE8Y/jzNirQeLkxpA6Oc= +github.com/muesli/smartcrop v0.3.0/go.mod h1:i2fCI/UorTfgEpPPLWiFBv4pye+YAG78RwcQLUkocpI= +github.com/niklasfasching/go-org v1.7.0 h1:vyMdcMWWTe/XmANk19F4k8XGBYg0GQ/gJGMimOjGMek= +github.com/niklasfasching/go-org v1.7.0/go.mod h1:WuVm4d45oePiE0eX25GqTDQIt/qPW1T9DGkRscqLW5o= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= +github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= +github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= +github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0= +github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd h1:CmH9+J6ZSsIjUK3dcGsnCnO41eRBOnY12zwkn5qVwgc= +github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= +github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo= +github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tdewolff/minify/v2 v2.20.17 h1:zGqEDhspr3XjSrQI/56vw9IdAhLAaKTLXWnDBsxNVt8= +github.com/tdewolff/minify/v2 v2.20.17/go.mod h1:ulkFoeAVWMLEyjuDz1ZIWOA31g5aWOawCFRp9R/MudM= +github.com/tdewolff/parse/v2 v2.7.12 h1:tgavkHc2ZDEQVKy1oWxwIyh5bP4F5fEh/JmBwPP/3LQ= +github.com/tdewolff/parse/v2 v2.7.12/go.mod h1:3FbJWZp3XT9OWVN3Hmfp0p/a08v4h8J9W1aghka0soA= +github.com/tdewolff/test v1.0.11-0.20231101010635-f1265d231d52/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= +github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03u/dMQK9g+Iw9ewps4mCl1nB8Sscbo= +github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8= +github.com/yuin/goldmark v1.7.0 h1:EfOIvIMZIzHdB/R/zVrikYLPPwJlfMcNczJFMs1m6sA= +github.com/yuin/goldmark v1.7.0/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E= +github.com/yuin/goldmark-emoji v1.0.2 h1:c/RgTShNgHTtc6xdz2KKI74jJr6rWi7FPgnP9GAsO5s= +github.com/yuin/goldmark-emoji v1.0.2/go.mod h1:RhP/RWpexdp+KHs7ghKnifRoIs/Bq4nDS7tRbCkOwKY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw= +golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= +golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8= +golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y= +gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/main.go b/main.go new file mode 100644 index 0000000..27fdd54 --- /dev/null +++ b/main.go @@ -0,0 +1,7 @@ +package main + +import "github.com/sammyshear/trivia-chase/cmd" + +func main() { + cmd.App() +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..638bf21 --- /dev/null +++ b/package.json @@ -0,0 +1,35 @@ +{ + "name": "trivia-chase", + "version": "0.1.0", + "license": "MIT", + "source": [ + "./assets/scripts.js", + "./assets/styles.scss" + ], + "targets": { + "default": { + "distDir": "./static" + } + }, + "scripts": { + "fmt": "prettier --write .", + "build": "esbuild assets/scripts.js --bundle --minify --outdir=static/ && tailwindcss -i ./assets/styles.scss -o ./static/styles.css --minify", + "js:watch": "esbuild assets/scripts.js --bundle --outdir=static/ --watch=forever", + "tailwindcss:watch": "tailwindcss -i ./assets/styles.scss -o ./static/styles.css --watch", + "dev": "npm run js:watch & npm run tailwindcss:watch" + }, + "dependencies": { + "@tailwindcss/forms": "^0.5.7", + "@tailwindcss/typography": "latest", + "alpinejs": "latest", + "esbuild": "^0.20.2", + "htmx.org": "latest", + "tailwindcss": "^3.4.3" + }, + "devDependencies": { + "@iconify-json/bi": "^1.1.23", + "@iconify-json/material-symbols": "^1.1.73", + "@iconify/tailwind": "^0.1.4", + "prettier": "latest" + } +} diff --git a/prettier.config.js b/prettier.config.js new file mode 100644 index 0000000..9b88e80 --- /dev/null +++ b/prettier.config.js @@ -0,0 +1,14 @@ +/** @type {import('prettier').Config} */ +module.exports = { + trailingComma: 'es5', + tabWidth: 2, + semi: false, + singleQuote: true, + + overrides: [ + { + files: '.postcssrc', + options: { parser: 'json' }, + }, + ], +} diff --git a/static/scripts.js b/static/scripts.js new file mode 100644 index 0000000..48fd8ca --- /dev/null +++ b/static/scripts.js @@ -0,0 +1,6789 @@ +"use strict"; +(() => { + // node_modules/htmx.org/dist/htmx.esm.js + var htmx2 = function() { + "use strict"; + const htmx = { + // Tsc madness here, assigning the functions directly results in an invalid TypeScript output, but reassigning is fine + /* Event processing */ + /** @type {typeof onLoadHelper} */ + onLoad: null, + /** @type {typeof processNode} */ + process: null, + /** @type {typeof addEventListenerImpl} */ + on: null, + /** @type {typeof removeEventListenerImpl} */ + off: null, + /** @type {typeof triggerEvent} */ + trigger: null, + /** @type {typeof ajaxHelper} */ + ajax: null, + /* DOM querying helpers */ + /** @type {typeof find} */ + find: null, + /** @type {typeof findAll} */ + findAll: null, + /** @type {typeof closest} */ + closest: null, + /** + * Returns the input values that would resolve for a given element via the htmx value resolution mechanism + * + * @see https://htmx.org/api/#values + * + * @param {Element} elt the element to resolve values on + * @param {HttpVerb} type the request type (e.g. **get** or **post**) non-GET's will include the enclosing form of the element. Defaults to **post** + * @returns {Object} + */ + values: function(elt, type) { + const inputValues = getInputValues(elt, type || "post"); + return inputValues.values; + }, + /* DOM manipulation helpers */ + /** @type {typeof removeElement} */ + remove: null, + /** @type {typeof addClassToElement} */ + addClass: null, + /** @type {typeof removeClassFromElement} */ + removeClass: null, + /** @type {typeof toggleClassOnElement} */ + toggleClass: null, + /** @type {typeof takeClassForElement} */ + takeClass: null, + /** @type {typeof swap} */ + swap: null, + /* Extension entrypoints */ + /** @type {typeof defineExtension} */ + defineExtension: null, + /** @type {typeof removeExtension} */ + removeExtension: null, + /* Debugging */ + /** @type {typeof logAll} */ + logAll: null, + /** @type {typeof logNone} */ + logNone: null, + /* Debugging */ + /** + * The logger htmx uses to log with + * + * @see https://htmx.org/api/#logger + */ + logger: null, + /** + * A property holding the configuration htmx uses at runtime. + * + * Note that using a [meta tag](https://htmx.org/docs/#config) is the preferred mechanism for setting these properties. + * + * @see https://htmx.org/api/#config + */ + config: { + /** + * Whether to use history. + * @type boolean + * @default true + */ + historyEnabled: true, + /** + * The number of pages to keep in **localStorage** for history support. + * @type number + * @default 10 + */ + historyCacheSize: 10, + /** + * @type boolean + * @default false + */ + refreshOnHistoryMiss: false, + /** + * The default swap style to use if **[hx-swap](https://htmx.org/attributes/hx-swap)** is omitted. + * @type HtmxSwapStyle + * @default 'innerHTML' + */ + defaultSwapStyle: "innerHTML", + /** + * The default delay between receiving a response from the server and doing the swap. + * @type number + * @default 0 + */ + defaultSwapDelay: 0, + /** + * The default delay between completing the content swap and settling attributes. + * @type number + * @default 20 + */ + defaultSettleDelay: 20, + /** + * If true, htmx will inject a small amount of CSS into the page to make indicators invisible unless the **htmx-indicator** class is present. + * @type boolean + * @default true + */ + includeIndicatorStyles: true, + /** + * The class to place on indicators when a request is in flight. + * @type string + * @default 'htmx-indicator' + */ + indicatorClass: "htmx-indicator", + /** + * The class to place on triggering elements when a request is in flight. + * @type string + * @default 'htmx-request' + */ + requestClass: "htmx-request", + /** + * The class to temporarily place on elements that htmx has added to the DOM. + * @type string + * @default 'htmx-added' + */ + addedClass: "htmx-added", + /** + * The class to place on target elements when htmx is in the settling phase. + * @type string + * @default 'htmx-settling' + */ + settlingClass: "htmx-settling", + /** + * The class to place on target elements when htmx is in the swapping phase. + * @type string + * @default 'htmx-swapping' + */ + swappingClass: "htmx-swapping", + /** + * Allows the use of eval-like functionality in htmx, to enable **hx-vars**, trigger conditions & script tag evaluation. Can be set to **false** for CSP compatibility. + * @type boolean + * @default true + */ + allowEval: true, + /** + * If set to false, disables the interpretation of script tags. + * @type boolean + * @default true + */ + allowScriptTags: true, + /** + * If set, the nonce will be added to inline scripts. + * @type string + * @default '' + */ + inlineScriptNonce: "", + /** + * If set, the nonce will be added to inline styles. + * @type string + * @default '' + */ + inlineStyleNonce: "", + /** + * The attributes to settle during the settling phase. + * @type string[] + * @default ['class', 'style', 'width', 'height'] + */ + attributesToSettle: ["class", "style", "width", "height"], + /** + * Allow cross-site Access-Control requests using credentials such as cookies, authorization headers or TLS client certificates. + * @type boolean + * @default false + */ + withCredentials: false, + /** + * @type number + * @default 0 + */ + timeout: 0, + /** + * The default implementation of **getWebSocketReconnectDelay** for reconnecting after unexpected connection loss by the event code **Abnormal Closure**, **Service Restart** or **Try Again Later**. + * @type {'full-jitter' | ((retryCount:number) => number)} + * @default "full-jitter" + */ + wsReconnectDelay: "full-jitter", + /** + * The type of binary data being received over the WebSocket connection + * @type BinaryType + * @default 'blob' + */ + wsBinaryType: "blob", + /** + * @type string + * @default '[hx-disable], [data-hx-disable]' + */ + disableSelector: "[hx-disable], [data-hx-disable]", + /** + * @type {'auto' | 'instant' | 'smooth'} + * @default 'smooth' + */ + scrollBehavior: "instant", + /** + * If the focused element should be scrolled into view. + * @type boolean + * @default false + */ + defaultFocusScroll: false, + /** + * If set to true htmx will include a cache-busting parameter in GET requests to avoid caching partial responses by the browser + * @type boolean + * @default false + */ + getCacheBusterParam: false, + /** + * If set to true, htmx will use the View Transition API when swapping in new content. + * @type boolean + * @default false + */ + globalViewTransitions: false, + /** + * htmx will format requests with these methods by encoding their parameters in the URL, not the request body + * @type {(HttpVerb)[]} + * @default ['get', 'delete'] + */ + methodsThatUseUrlParams: ["get", "delete"], + /** + * If set to true, disables htmx-based requests to non-origin hosts. + * @type boolean + * @default false + */ + selfRequestsOnly: true, + /** + * If set to true htmx will not update the title of the document when a title tag is found in new content + * @type boolean + * @default false + */ + ignoreTitle: false, + /** + * Whether the target of a boosted element is scrolled into the viewport. + * @type boolean + * @default true + */ + scrollIntoViewOnBoost: true, + /** + * The cache to store evaluated trigger specifications into. + * You may define a simple object to use a never-clearing cache, or implement your own system using a [proxy object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Proxy) + * @type {Object|null} + * @default null + */ + triggerSpecsCache: null, + /** @type boolean */ + disableInheritance: false, + /** @type HtmxResponseHandlingConfig[] */ + responseHandling: [ + { code: "204", swap: false }, + { code: "[23]..", swap: true }, + { code: "[45]..", swap: false, error: true } + ], + /** + * Whether to process OOB swaps on elements that are nested within the main response element. + * @type boolean + * @default true + */ + allowNestedOobSwaps: true + }, + /** @type {typeof parseInterval} */ + parseInterval: null, + /** @type {typeof internalEval} */ + _: null, + version: "2.0.1" + }; + htmx.onLoad = onLoadHelper; + htmx.process = processNode; + htmx.on = addEventListenerImpl; + htmx.off = removeEventListenerImpl; + htmx.trigger = triggerEvent; + htmx.ajax = ajaxHelper; + htmx.find = find; + htmx.findAll = findAll; + htmx.closest = closest; + htmx.remove = removeElement; + htmx.addClass = addClassToElement; + htmx.removeClass = removeClassFromElement; + htmx.toggleClass = toggleClassOnElement; + htmx.takeClass = takeClassForElement; + htmx.swap = swap; + htmx.defineExtension = defineExtension; + htmx.removeExtension = removeExtension; + htmx.logAll = logAll; + htmx.logNone = logNone; + htmx.parseInterval = parseInterval; + htmx._ = internalEval; + const internalAPI = { + addTriggerHandler, + bodyContains, + canAccessLocalStorage, + findThisElement, + filterValues, + swap, + hasAttribute, + getAttributeValue, + getClosestAttributeValue, + getClosestMatch, + getExpressionVars, + getHeaders, + getInputValues, + getInternalData, + getSwapSpecification, + getTriggerSpecs, + getTarget, + makeFragment, + mergeObjects, + makeSettleInfo, + oobSwap, + querySelectorExt, + settleImmediately, + shouldCancel, + triggerEvent, + triggerErrorEvent, + withExtensions + }; + const VERBS = ["get", "post", "put", "delete", "patch"]; + const VERB_SELECTOR = VERBS.map(function(verb) { + return "[hx-" + verb + "], [data-hx-" + verb + "]"; + }).join(", "); + const HEAD_TAG_REGEX = makeTagRegEx("head"); + function makeTagRegEx(tag, global = false) { + return new RegExp( + `<${tag}(\\s[^>]*>|>)([\\s\\S]*?)<\\/${tag}>`, + global ? "gim" : "im" + ); + } + function parseInterval(str2) { + if (str2 == void 0) { + return void 0; + } + let interval = NaN; + if (str2.slice(-2) == "ms") { + interval = parseFloat(str2.slice(0, -2)); + } else if (str2.slice(-1) == "s") { + interval = parseFloat(str2.slice(0, -1)) * 1e3; + } else if (str2.slice(-1) == "m") { + interval = parseFloat(str2.slice(0, -1)) * 1e3 * 60; + } else { + interval = parseFloat(str2); + } + return isNaN(interval) ? void 0 : interval; + } + function getRawAttribute(elt, name) { + return elt instanceof Element && elt.getAttribute(name); + } + function hasAttribute(elt, qualifiedName) { + return !!elt.hasAttribute && (elt.hasAttribute(qualifiedName) || elt.hasAttribute("data-" + qualifiedName)); + } + function getAttributeValue(elt, qualifiedName) { + return getRawAttribute(elt, qualifiedName) || getRawAttribute(elt, "data-" + qualifiedName); + } + function parentElt(elt) { + const parent = elt.parentElement; + if (!parent && elt.parentNode instanceof ShadowRoot) + return elt.parentNode; + return parent; + } + function getDocument() { + return document; + } + function getRootNode(elt, global) { + return elt.getRootNode ? elt.getRootNode({ composed: global }) : getDocument(); + } + function getClosestMatch(elt, condition) { + while (elt && !condition(elt)) { + elt = parentElt(elt); + } + return elt || null; + } + function getAttributeValueWithDisinheritance(initialElement, ancestor, attributeName) { + const attributeValue = getAttributeValue(ancestor, attributeName); + const disinherit = getAttributeValue(ancestor, "hx-disinherit"); + var inherit = getAttributeValue(ancestor, "hx-inherit"); + if (initialElement !== ancestor) { + if (htmx.config.disableInheritance) { + if (inherit && (inherit === "*" || inherit.split(" ").indexOf(attributeName) >= 0)) { + return attributeValue; + } else { + return null; + } + } + if (disinherit && (disinherit === "*" || disinherit.split(" ").indexOf(attributeName) >= 0)) { + return "unset"; + } + } + return attributeValue; + } + function getClosestAttributeValue(elt, attributeName) { + let closestAttr = null; + getClosestMatch(elt, function(e) { + return !!(closestAttr = getAttributeValueWithDisinheritance(elt, asElement(e), attributeName)); + }); + if (closestAttr !== "unset") { + return closestAttr; + } + } + function matches(elt, selector) { + const matchesFunction = elt instanceof Element && (elt.matches || elt.matchesSelector || elt.msMatchesSelector || elt.mozMatchesSelector || elt.webkitMatchesSelector || elt.oMatchesSelector); + return !!matchesFunction && matchesFunction.call(elt, selector); + } + function getStartTag(str2) { + const tagMatcher = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i; + const match = tagMatcher.exec(str2); + if (match) { + return match[1].toLowerCase(); + } else { + return ""; + } + } + function parseHTML(resp) { + const parser = new DOMParser(); + return parser.parseFromString(resp, "text/html"); + } + function takeChildrenFor(fragment, elt) { + while (elt.childNodes.length > 0) { + fragment.append(elt.childNodes[0]); + } + } + function duplicateScript(script) { + const newScript = getDocument().createElement("script"); + forEach(script.attributes, function(attr) { + newScript.setAttribute(attr.name, attr.value); + }); + newScript.textContent = script.textContent; + newScript.async = false; + if (htmx.config.inlineScriptNonce) { + newScript.nonce = htmx.config.inlineScriptNonce; + } + return newScript; + } + function isJavaScriptScriptNode(script) { + return script.matches("script") && (script.type === "text/javascript" || script.type === "module" || script.type === ""); + } + function normalizeScriptTags(fragment) { + Array.from(fragment.querySelectorAll("script")).forEach( + /** @param {HTMLScriptElement} script */ + (script) => { + if (isJavaScriptScriptNode(script)) { + const newScript = duplicateScript(script); + const parent = script.parentNode; + try { + parent.insertBefore(newScript, script); + } catch (e) { + logError(e); + } finally { + script.remove(); + } + } + } + ); + } + function makeFragment(response) { + const responseWithNoHead = response.replace(HEAD_TAG_REGEX, ""); + const startTag = getStartTag(responseWithNoHead); + let fragment; + if (startTag === "html") { + fragment = /** @type DocumentFragmentWithTitle */ + new DocumentFragment(); + const doc = parseHTML(response); + takeChildrenFor(fragment, doc.body); + fragment.title = doc.title; + } else if (startTag === "body") { + fragment = /** @type DocumentFragmentWithTitle */ + new DocumentFragment(); + const doc = parseHTML(responseWithNoHead); + takeChildrenFor(fragment, doc.body); + fragment.title = doc.title; + } else { + const doc = parseHTML('
' + responseWithNoHead + ""); + fragment = /** @type DocumentFragmentWithTitle */ + doc.querySelector("template").content; + fragment.title = doc.title; + var titleElement = fragment.querySelector("title"); + if (titleElement && titleElement.parentNode === fragment) { + titleElement.remove(); + fragment.title = titleElement.innerText; + } + } + if (fragment) { + if (htmx.config.allowScriptTags) { + normalizeScriptTags(fragment); + } else { + fragment.querySelectorAll("script").forEach((script) => script.remove()); + } + } + return fragment; + } + function maybeCall(func) { + if (func) { + func(); + } + } + function isType(o, type) { + return Object.prototype.toString.call(o) === "[object " + type + "]"; + } + function isFunction(o) { + return typeof o === "function"; + } + function isRawObject(o) { + return isType(o, "Object"); + } + function getInternalData(elt) { + const dataProp = "htmx-internal-data"; + let data2 = elt[dataProp]; + if (!data2) { + data2 = elt[dataProp] = {}; + } + return data2; + } + function toArray(arr) { + const returnArr = []; + if (arr) { + for (let i = 0; i < arr.length; i++) { + returnArr.push(arr[i]); + } + } + return returnArr; + } + function forEach(arr, func) { + if (arr) { + for (let i = 0; i < arr.length; i++) { + func(arr[i]); + } + } + } + function isScrolledIntoView(el) { + const rect = el.getBoundingClientRect(); + const elemTop = rect.top; + const elemBottom = rect.bottom; + return elemTop < window.innerHeight && elemBottom >= 0; + } + function bodyContains(elt) { + const rootNode = elt.getRootNode && elt.getRootNode(); + if (rootNode && rootNode instanceof window.ShadowRoot) { + return getDocument().body.contains(rootNode.host); + } else { + return getDocument().body.contains(elt); + } + } + function splitOnWhitespace(trigger2) { + return trigger2.trim().split(/\s+/); + } + function mergeObjects(obj1, obj2) { + for (const key in obj2) { + if (obj2.hasOwnProperty(key)) { + obj1[key] = obj2[key]; + } + } + return obj1; + } + function parseJSON(jString) { + try { + return JSON.parse(jString); + } catch (error2) { + logError(error2); + return null; + } + } + function canAccessLocalStorage() { + const test = "htmx:localStorageTest"; + try { + localStorage.setItem(test, test); + localStorage.removeItem(test); + return true; + } catch (e) { + return false; + } + } + function normalizePath(path) { + try { + const url = new URL(path); + if (url) { + path = url.pathname + url.search; + } + if (!/^\/$/.test(path)) { + path = path.replace(/\/+$/, ""); + } + return path; + } catch (e) { + return path; + } + } + function internalEval(str) { + return maybeEval(getDocument().body, function() { + return eval(str); + }); + } + function onLoadHelper(callback) { + const value = htmx.on( + "htmx:load", + /** @param {CustomEvent} evt */ + function(evt) { + callback(evt.detail.elt); + } + ); + return value; + } + function logAll() { + htmx.logger = function(elt, event, data2) { + if (console) { + console.log(event, elt, data2); + } + }; + } + function logNone() { + htmx.logger = null; + } + function find(eltOrSelector, selector) { + if (typeof eltOrSelector !== "string") { + return eltOrSelector.querySelector(selector); + } else { + return find(getDocument(), eltOrSelector); + } + } + function findAll(eltOrSelector, selector) { + if (typeof eltOrSelector !== "string") { + return eltOrSelector.querySelectorAll(selector); + } else { + return findAll(getDocument(), eltOrSelector); + } + } + function getWindow() { + return window; + } + function removeElement(elt, delay) { + elt = resolveTarget(elt); + if (delay) { + getWindow().setTimeout(function() { + removeElement(elt); + elt = null; + }, delay); + } else { + parentElt(elt).removeChild(elt); + } + } + function asElement(elt) { + return elt instanceof Element ? elt : null; + } + function asHtmlElement(elt) { + return elt instanceof HTMLElement ? elt : null; + } + function asString(value) { + return typeof value === "string" ? value : null; + } + function asParentNode(elt) { + return elt instanceof Element || elt instanceof Document || elt instanceof DocumentFragment ? elt : null; + } + function addClassToElement(elt, clazz, delay) { + elt = asElement(resolveTarget(elt)); + if (!elt) { + return; + } + if (delay) { + getWindow().setTimeout(function() { + addClassToElement(elt, clazz); + elt = null; + }, delay); + } else { + elt.classList && elt.classList.add(clazz); + } + } + function removeClassFromElement(node, clazz, delay) { + let elt = asElement(resolveTarget(node)); + if (!elt) { + return; + } + if (delay) { + getWindow().setTimeout(function() { + removeClassFromElement(elt, clazz); + elt = null; + }, delay); + } else { + if (elt.classList) { + elt.classList.remove(clazz); + if (elt.classList.length === 0) { + elt.removeAttribute("class"); + } + } + } + } + function toggleClassOnElement(elt, clazz) { + elt = resolveTarget(elt); + elt.classList.toggle(clazz); + } + function takeClassForElement(elt, clazz) { + elt = resolveTarget(elt); + forEach(elt.parentElement.children, function(child) { + removeClassFromElement(child, clazz); + }); + addClassToElement(asElement(elt), clazz); + } + function closest(elt, selector) { + elt = asElement(resolveTarget(elt)); + if (elt && elt.closest) { + return elt.closest(selector); + } else { + do { + if (elt == null || matches(elt, selector)) { + return elt; + } + } while (elt = elt && asElement(parentElt(elt))); + return null; + } + } + function startsWith(str2, prefix2) { + return str2.substring(0, prefix2.length) === prefix2; + } + function endsWith(str2, suffix) { + return str2.substring(str2.length - suffix.length) === suffix; + } + function normalizeSelector(selector) { + const trimmedSelector = selector.trim(); + if (startsWith(trimmedSelector, "<") && endsWith(trimmedSelector, "/>")) { + return trimmedSelector.substring(1, trimmedSelector.length - 2); + } else { + return trimmedSelector; + } + } + function querySelectorAllExt(elt, selector, global) { + elt = resolveTarget(elt); + if (selector.indexOf("closest ") === 0) { + return [closest(asElement(elt), normalizeSelector(selector.substr(8)))]; + } else if (selector.indexOf("find ") === 0) { + return [find(asParentNode(elt), normalizeSelector(selector.substr(5)))]; + } else if (selector === "next") { + return [asElement(elt).nextElementSibling]; + } else if (selector.indexOf("next ") === 0) { + return [scanForwardQuery(elt, normalizeSelector(selector.substr(5)), !!global)]; + } else if (selector === "previous") { + return [asElement(elt).previousElementSibling]; + } else if (selector.indexOf("previous ") === 0) { + return [scanBackwardsQuery(elt, normalizeSelector(selector.substr(9)), !!global)]; + } else if (selector === "document") { + return [document]; + } else if (selector === "window") { + return [window]; + } else if (selector === "body") { + return [document.body]; + } else if (selector === "root") { + return [getRootNode(elt, !!global)]; + } else if (selector.indexOf("global ") === 0) { + return querySelectorAllExt(elt, selector.slice(7), true); + } else { + return toArray(asParentNode(getRootNode(elt, !!global)).querySelectorAll(normalizeSelector(selector))); + } + } + var scanForwardQuery = function(start2, match, global) { + const results = asParentNode(getRootNode(start2, global)).querySelectorAll(match); + for (let i = 0; i < results.length; i++) { + const elt = results[i]; + if (elt.compareDocumentPosition(start2) === Node.DOCUMENT_POSITION_PRECEDING) { + return elt; + } + } + }; + var scanBackwardsQuery = function(start2, match, global) { + const results = asParentNode(getRootNode(start2, global)).querySelectorAll(match); + for (let i = results.length - 1; i >= 0; i--) { + const elt = results[i]; + if (elt.compareDocumentPosition(start2) === Node.DOCUMENT_POSITION_FOLLOWING) { + return elt; + } + } + }; + function querySelectorExt(eltOrSelector, selector) { + if (typeof eltOrSelector !== "string") { + return querySelectorAllExt(eltOrSelector, selector)[0]; + } else { + return querySelectorAllExt(getDocument().body, eltOrSelector)[0]; + } + } + function resolveTarget(eltOrSelector, context) { + if (typeof eltOrSelector === "string") { + return find(asParentNode(context) || document, eltOrSelector); + } else { + return eltOrSelector; + } + } + function processEventArgs(arg1, arg2, arg3) { + if (isFunction(arg2)) { + return { + target: getDocument().body, + event: asString(arg1), + listener: arg2 + }; + } else { + return { + target: resolveTarget(arg1), + event: asString(arg2), + listener: arg3 + }; + } + } + function addEventListenerImpl(arg1, arg2, arg3) { + ready(function() { + const eventArgs = processEventArgs(arg1, arg2, arg3); + eventArgs.target.addEventListener(eventArgs.event, eventArgs.listener); + }); + const b = isFunction(arg2); + return b ? arg2 : arg3; + } + function removeEventListenerImpl(arg1, arg2, arg3) { + ready(function() { + const eventArgs = processEventArgs(arg1, arg2, arg3); + eventArgs.target.removeEventListener(eventArgs.event, eventArgs.listener); + }); + return isFunction(arg2) ? arg2 : arg3; + } + const DUMMY_ELT = getDocument().createElement("output"); + function findAttributeTargets(elt, attrName) { + const attrTarget = getClosestAttributeValue(elt, attrName); + if (attrTarget) { + if (attrTarget === "this") { + return [findThisElement(elt, attrName)]; + } else { + const result = querySelectorAllExt(elt, attrTarget); + if (result.length === 0) { + logError('The selector "' + attrTarget + '" on ' + attrName + " returned no matches!"); + return [DUMMY_ELT]; + } else { + return result; + } + } + } + } + function findThisElement(elt, attribute) { + return asElement(getClosestMatch(elt, function(elt2) { + return getAttributeValue(asElement(elt2), attribute) != null; + })); + } + function getTarget(elt) { + const targetStr = getClosestAttributeValue(elt, "hx-target"); + if (targetStr) { + if (targetStr === "this") { + return findThisElement(elt, "hx-target"); + } else { + return querySelectorExt(elt, targetStr); + } + } else { + const data2 = getInternalData(elt); + if (data2.boosted) { + return getDocument().body; + } else { + return elt; + } + } + } + function shouldSettleAttribute(name) { + const attributesToSettle = htmx.config.attributesToSettle; + for (let i = 0; i < attributesToSettle.length; i++) { + if (name === attributesToSettle[i]) { + return true; + } + } + return false; + } + function cloneAttributes(mergeTo, mergeFrom) { + forEach(mergeTo.attributes, function(attr) { + if (!mergeFrom.hasAttribute(attr.name) && shouldSettleAttribute(attr.name)) { + mergeTo.removeAttribute(attr.name); + } + }); + forEach(mergeFrom.attributes, function(attr) { + if (shouldSettleAttribute(attr.name)) { + mergeTo.setAttribute(attr.name, attr.value); + } + }); + } + function isInlineSwap(swapStyle, target) { + const extensions2 = getExtensions(target); + for (let i = 0; i < extensions2.length; i++) { + const extension = extensions2[i]; + try { + if (extension.isInlineSwap(swapStyle)) { + return true; + } + } catch (e) { + logError(e); + } + } + return swapStyle === "outerHTML"; + } + function oobSwap(oobValue, oobElement, settleInfo) { + let selector = "#" + getRawAttribute(oobElement, "id"); + let swapStyle = "outerHTML"; + if (oobValue === "true") { + } else if (oobValue.indexOf(":") > 0) { + swapStyle = oobValue.substr(0, oobValue.indexOf(":")); + selector = oobValue.substr(oobValue.indexOf(":") + 1, oobValue.length); + } else { + swapStyle = oobValue; + } + const targets = getDocument().querySelectorAll(selector); + if (targets) { + forEach( + targets, + function(target) { + let fragment; + const oobElementClone = oobElement.cloneNode(true); + fragment = getDocument().createDocumentFragment(); + fragment.appendChild(oobElementClone); + if (!isInlineSwap(swapStyle, target)) { + fragment = asParentNode(oobElementClone); + } + const beforeSwapDetails = { shouldSwap: true, target, fragment }; + if (!triggerEvent(target, "htmx:oobBeforeSwap", beforeSwapDetails)) + return; + target = beforeSwapDetails.target; + if (beforeSwapDetails.shouldSwap) { + swapWithStyle(swapStyle, target, target, fragment, settleInfo); + } + forEach(settleInfo.elts, function(elt) { + triggerEvent(elt, "htmx:oobAfterSwap", beforeSwapDetails); + }); + } + ); + oobElement.parentNode.removeChild(oobElement); + } else { + oobElement.parentNode.removeChild(oobElement); + triggerErrorEvent(getDocument().body, "htmx:oobErrorNoTarget", { content: oobElement }); + } + return oobValue; + } + function handlePreservedElements(fragment) { + forEach(findAll(fragment, "[hx-preserve], [data-hx-preserve]"), function(preservedElt) { + const id = getAttributeValue(preservedElt, "id"); + const oldElt = getDocument().getElementById(id); + if (oldElt != null) { + preservedElt.parentNode.replaceChild(oldElt, preservedElt); + } + }); + } + function handleAttributes(parentNode, fragment, settleInfo) { + forEach(fragment.querySelectorAll("[id]"), function(newNode) { + const id = getRawAttribute(newNode, "id"); + if (id && id.length > 0) { + const normalizedId = id.replace("'", "\\'"); + const normalizedTag = newNode.tagName.replace(":", "\\:"); + const parentElt2 = asParentNode(parentNode); + const oldNode = parentElt2 && parentElt2.querySelector(normalizedTag + "[id='" + normalizedId + "']"); + if (oldNode && oldNode !== parentElt2) { + const newAttributes = newNode.cloneNode(); + cloneAttributes(newNode, oldNode); + settleInfo.tasks.push(function() { + cloneAttributes(newNode, newAttributes); + }); + } + } + }); + } + function makeAjaxLoadTask(child) { + return function() { + removeClassFromElement(child, htmx.config.addedClass); + processNode(asElement(child)); + processFocus(asParentNode(child)); + triggerEvent(child, "htmx:load"); + }; + } + function processFocus(child) { + const autofocus = "[autofocus]"; + const autoFocusedElt = asHtmlElement(matches(child, autofocus) ? child : child.querySelector(autofocus)); + if (autoFocusedElt != null) { + autoFocusedElt.focus(); + } + } + function insertNodesBefore(parentNode, insertBefore, fragment, settleInfo) { + handleAttributes(parentNode, fragment, settleInfo); + while (fragment.childNodes.length > 0) { + const child = fragment.firstChild; + addClassToElement(asElement(child), htmx.config.addedClass); + parentNode.insertBefore(child, insertBefore); + if (child.nodeType !== Node.TEXT_NODE && child.nodeType !== Node.COMMENT_NODE) { + settleInfo.tasks.push(makeAjaxLoadTask(child)); + } + } + } + function stringHash(string, hash) { + let char = 0; + while (char < string.length) { + hash = (hash << 5) - hash + string.charCodeAt(char++) | 0; + } + return hash; + } + function attributeHash(elt) { + let hash = 0; + if (elt.attributes) { + for (let i = 0; i < elt.attributes.length; i++) { + const attribute = elt.attributes[i]; + if (attribute.value) { + hash = stringHash(attribute.name, hash); + hash = stringHash(attribute.value, hash); + } + } + } + return hash; + } + function deInitOnHandlers(elt) { + const internalData = getInternalData(elt); + if (internalData.onHandlers) { + for (let i = 0; i < internalData.onHandlers.length; i++) { + const handlerInfo = internalData.onHandlers[i]; + removeEventListenerImpl(elt, handlerInfo.event, handlerInfo.listener); + } + delete internalData.onHandlers; + } + } + function deInitNode(element) { + const internalData = getInternalData(element); + if (internalData.timeout) { + clearTimeout(internalData.timeout); + } + if (internalData.listenerInfos) { + forEach(internalData.listenerInfos, function(info) { + if (info.on) { + removeEventListenerImpl(info.on, info.trigger, info.listener); + } + }); + } + deInitOnHandlers(element); + forEach(Object.keys(internalData), function(key) { + delete internalData[key]; + }); + } + function cleanUpElement(element) { + triggerEvent(element, "htmx:beforeCleanupElement"); + deInitNode(element); + if (element.children) { + forEach(element.children, function(child) { + cleanUpElement(child); + }); + } + } + function swapOuterHTML(target, fragment, settleInfo) { + if (target instanceof Element && target.tagName === "BODY") { + return swapInnerHTML(target, fragment, settleInfo); + } + let newElt; + const eltBeforeNewContent = target.previousSibling; + insertNodesBefore(parentElt(target), target, fragment, settleInfo); + if (eltBeforeNewContent == null) { + newElt = parentElt(target).firstChild; + } else { + newElt = eltBeforeNewContent.nextSibling; + } + settleInfo.elts = settleInfo.elts.filter(function(e) { + return e !== target; + }); + while (newElt && newElt !== target) { + if (newElt instanceof Element) { + settleInfo.elts.push(newElt); + newElt = newElt.nextElementSibling; + } else { + newElt = null; + } + } + cleanUpElement(target); + if (target instanceof Element) { + target.remove(); + } else { + target.parentNode.removeChild(target); + } + } + function swapAfterBegin(target, fragment, settleInfo) { + return insertNodesBefore(target, target.firstChild, fragment, settleInfo); + } + function swapBeforeBegin(target, fragment, settleInfo) { + return insertNodesBefore(parentElt(target), target, fragment, settleInfo); + } + function swapBeforeEnd(target, fragment, settleInfo) { + return insertNodesBefore(target, null, fragment, settleInfo); + } + function swapAfterEnd(target, fragment, settleInfo) { + return insertNodesBefore(parentElt(target), target.nextSibling, fragment, settleInfo); + } + function swapDelete(target) { + cleanUpElement(target); + return parentElt(target).removeChild(target); + } + function swapInnerHTML(target, fragment, settleInfo) { + const firstChild = target.firstChild; + insertNodesBefore(target, firstChild, fragment, settleInfo); + if (firstChild) { + while (firstChild.nextSibling) { + cleanUpElement(firstChild.nextSibling); + target.removeChild(firstChild.nextSibling); + } + cleanUpElement(firstChild); + target.removeChild(firstChild); + } + } + function swapWithStyle(swapStyle, elt, target, fragment, settleInfo) { + switch (swapStyle) { + case "none": + return; + case "outerHTML": + swapOuterHTML(target, fragment, settleInfo); + return; + case "afterbegin": + swapAfterBegin(target, fragment, settleInfo); + return; + case "beforebegin": + swapBeforeBegin(target, fragment, settleInfo); + return; + case "beforeend": + swapBeforeEnd(target, fragment, settleInfo); + return; + case "afterend": + swapAfterEnd(target, fragment, settleInfo); + return; + case "delete": + swapDelete(target); + return; + default: + var extensions2 = getExtensions(elt); + for (let i = 0; i < extensions2.length; i++) { + const ext = extensions2[i]; + try { + const newElements = ext.handleSwap(swapStyle, target, fragment, settleInfo); + if (newElements) { + if (typeof newElements.length !== "undefined") { + for (let j = 0; j < newElements.length; j++) { + const child = newElements[j]; + if (child.nodeType !== Node.TEXT_NODE && child.nodeType !== Node.COMMENT_NODE) { + settleInfo.tasks.push(makeAjaxLoadTask(child)); + } + } + } + return; + } + } catch (e) { + logError(e); + } + } + if (swapStyle === "innerHTML") { + swapInnerHTML(target, fragment, settleInfo); + } else { + swapWithStyle(htmx.config.defaultSwapStyle, elt, target, fragment, settleInfo); + } + } + } + function findAndSwapOobElements(fragment, settleInfo) { + forEach(findAll(fragment, "[hx-swap-oob], [data-hx-swap-oob]"), function(oobElement) { + if (htmx.config.allowNestedOobSwaps || oobElement.parentElement === null) { + const oobValue = getAttributeValue(oobElement, "hx-swap-oob"); + if (oobValue != null) { + oobSwap(oobValue, oobElement, settleInfo); + } + } else { + oobElement.removeAttribute("hx-swap-oob"); + oobElement.removeAttribute("data-hx-swap-oob"); + } + }); + } + function swap(target, content, swapSpec, swapOptions) { + if (!swapOptions) { + swapOptions = {}; + } + target = resolveTarget(target); + const activeElt = document.activeElement; + let selectionInfo = {}; + try { + selectionInfo = { + elt: activeElt, + // @ts-ignore + start: activeElt ? activeElt.selectionStart : null, + // @ts-ignore + end: activeElt ? activeElt.selectionEnd : null + }; + } catch (e) { + } + const settleInfo = makeSettleInfo(target); + if (swapSpec.swapStyle === "textContent") { + target.textContent = content; + } else { + let fragment = makeFragment(content); + settleInfo.title = fragment.title; + if (swapOptions.selectOOB) { + const oobSelectValues = swapOptions.selectOOB.split(","); + for (let i = 0; i < oobSelectValues.length; i++) { + const oobSelectValue = oobSelectValues[i].split(":", 2); + let id = oobSelectValue[0].trim(); + if (id.indexOf("#") === 0) { + id = id.substring(1); + } + const oobValue = oobSelectValue[1] || "true"; + const oobElement = fragment.querySelector("#" + id); + if (oobElement) { + oobSwap(oobValue, oobElement, settleInfo); + } + } + } + findAndSwapOobElements(fragment, settleInfo); + forEach( + findAll(fragment, "template"), + /** @param {HTMLTemplateElement} template */ + function(template) { + findAndSwapOobElements(template.content, settleInfo); + if (template.content.childElementCount === 0 && template.content.textContent.trim() === "") { + template.remove(); + } + } + ); + if (swapOptions.select) { + const newFragment = getDocument().createDocumentFragment(); + forEach(fragment.querySelectorAll(swapOptions.select), function(node) { + newFragment.appendChild(node); + }); + fragment = newFragment; + } + handlePreservedElements(fragment); + swapWithStyle(swapSpec.swapStyle, swapOptions.contextElement, target, fragment, settleInfo); + } + if (selectionInfo.elt && !bodyContains(selectionInfo.elt) && getRawAttribute(selectionInfo.elt, "id")) { + const newActiveElt = document.getElementById(getRawAttribute(selectionInfo.elt, "id")); + const focusOptions = { preventScroll: swapSpec.focusScroll !== void 0 ? !swapSpec.focusScroll : !htmx.config.defaultFocusScroll }; + if (newActiveElt) { + if (selectionInfo.start && newActiveElt.setSelectionRange) { + try { + newActiveElt.setSelectionRange(selectionInfo.start, selectionInfo.end); + } catch (e) { + } + } + newActiveElt.focus(focusOptions); + } + } + target.classList.remove(htmx.config.swappingClass); + forEach(settleInfo.elts, function(elt) { + if (elt.classList) { + elt.classList.add(htmx.config.settlingClass); + } + triggerEvent(elt, "htmx:afterSwap", swapOptions.eventInfo); + }); + if (swapOptions.afterSwapCallback) { + swapOptions.afterSwapCallback(); + } + if (!swapSpec.ignoreTitle) { + handleTitle(settleInfo.title); + } + const doSettle = function() { + forEach(settleInfo.tasks, function(task) { + task.call(); + }); + forEach(settleInfo.elts, function(elt) { + if (elt.classList) { + elt.classList.remove(htmx.config.settlingClass); + } + triggerEvent(elt, "htmx:afterSettle", swapOptions.eventInfo); + }); + if (swapOptions.anchor) { + const anchorTarget = asElement(resolveTarget("#" + swapOptions.anchor)); + if (anchorTarget) { + anchorTarget.scrollIntoView({ block: "start", behavior: "auto" }); + } + } + updateScrollState(settleInfo.elts, swapSpec); + if (swapOptions.afterSettleCallback) { + swapOptions.afterSettleCallback(); + } + }; + if (swapSpec.settleDelay > 0) { + getWindow().setTimeout(doSettle, swapSpec.settleDelay); + } else { + doSettle(); + } + } + function handleTriggerHeader(xhr, header, elt) { + const triggerBody = xhr.getResponseHeader(header); + if (triggerBody.indexOf("{") === 0) { + const triggers = parseJSON(triggerBody); + for (const eventName in triggers) { + if (triggers.hasOwnProperty(eventName)) { + let detail = triggers[eventName]; + if (!isRawObject(detail)) { + detail = { value: detail }; + } + triggerEvent(elt, eventName, detail); + } + } + } else { + const eventNames = triggerBody.split(","); + for (let i = 0; i < eventNames.length; i++) { + triggerEvent(elt, eventNames[i].trim(), []); + } + } + } + const WHITESPACE = /\s/; + const WHITESPACE_OR_COMMA = /[\s,]/; + const SYMBOL_START = /[_$a-zA-Z]/; + const SYMBOL_CONT = /[_$a-zA-Z0-9]/; + const STRINGISH_START = ['"', "'", "/"]; + const NOT_WHITESPACE = /[^\s]/; + const COMBINED_SELECTOR_START = /[{(]/; + const COMBINED_SELECTOR_END = /[})]/; + function tokenizeString(str2) { + const tokens = []; + let position = 0; + while (position < str2.length) { + if (SYMBOL_START.exec(str2.charAt(position))) { + var startPosition = position; + while (SYMBOL_CONT.exec(str2.charAt(position + 1))) { + position++; + } + tokens.push(str2.substr(startPosition, position - startPosition + 1)); + } else if (STRINGISH_START.indexOf(str2.charAt(position)) !== -1) { + const startChar = str2.charAt(position); + var startPosition = position; + position++; + while (position < str2.length && str2.charAt(position) !== startChar) { + if (str2.charAt(position) === "\\") { + position++; + } + position++; + } + tokens.push(str2.substr(startPosition, position - startPosition + 1)); + } else { + const symbol = str2.charAt(position); + tokens.push(symbol); + } + position++; + } + return tokens; + } + function isPossibleRelativeReference(token, last, paramName) { + return SYMBOL_START.exec(token.charAt(0)) && token !== "true" && token !== "false" && token !== "this" && token !== paramName && last !== "."; + } + function maybeGenerateConditional(elt, tokens, paramName) { + if (tokens[0] === "[") { + tokens.shift(); + let bracketCount = 1; + let conditionalSource = " return (function(" + paramName + "){ return ("; + let last = null; + while (tokens.length > 0) { + const token = tokens[0]; + if (token === "]") { + bracketCount--; + if (bracketCount === 0) { + if (last === null) { + conditionalSource = conditionalSource + "true"; + } + tokens.shift(); + conditionalSource += ")})"; + try { + const conditionFunction = maybeEval( + elt, + function() { + return Function(conditionalSource)(); + }, + function() { + return true; + } + ); + conditionFunction.source = conditionalSource; + return conditionFunction; + } catch (e) { + triggerErrorEvent(getDocument().body, "htmx:syntax:error", { error: e, source: conditionalSource }); + return null; + } + } + } else if (token === "[") { + bracketCount++; + } + if (isPossibleRelativeReference(token, last, paramName)) { + conditionalSource += "((" + paramName + "." + token + ") ? (" + paramName + "." + token + ") : (window." + token + "))"; + } else { + conditionalSource = conditionalSource + token; + } + last = tokens.shift(); + } + } + } + function consumeUntil(tokens, match) { + let result = ""; + while (tokens.length > 0 && !match.test(tokens[0])) { + result += tokens.shift(); + } + return result; + } + function consumeCSSSelector(tokens) { + let result; + if (tokens.length > 0 && COMBINED_SELECTOR_START.test(tokens[0])) { + tokens.shift(); + result = consumeUntil(tokens, COMBINED_SELECTOR_END).trim(); + tokens.shift(); + } else { + result = consumeUntil(tokens, WHITESPACE_OR_COMMA); + } + return result; + } + const INPUT_SELECTOR = "input, textarea, select"; + function parseAndCacheTrigger(elt, explicitTrigger, cache) { + const triggerSpecs = []; + const tokens = tokenizeString(explicitTrigger); + do { + consumeUntil(tokens, NOT_WHITESPACE); + const initialLength = tokens.length; + const trigger2 = consumeUntil(tokens, /[,\[\s]/); + if (trigger2 !== "") { + if (trigger2 === "every") { + const every = { trigger: "every" }; + consumeUntil(tokens, NOT_WHITESPACE); + every.pollInterval = parseInterval(consumeUntil(tokens, /[,\[\s]/)); + consumeUntil(tokens, NOT_WHITESPACE); + var eventFilter = maybeGenerateConditional(elt, tokens, "event"); + if (eventFilter) { + every.eventFilter = eventFilter; + } + triggerSpecs.push(every); + } else { + const triggerSpec = { trigger: trigger2 }; + var eventFilter = maybeGenerateConditional(elt, tokens, "event"); + if (eventFilter) { + triggerSpec.eventFilter = eventFilter; + } + while (tokens.length > 0 && tokens[0] !== ",") { + consumeUntil(tokens, NOT_WHITESPACE); + const token = tokens.shift(); + if (token === "changed") { + triggerSpec.changed = true; + } else if (token === "once") { + triggerSpec.once = true; + } else if (token === "consume") { + triggerSpec.consume = true; + } else if (token === "delay" && tokens[0] === ":") { + tokens.shift(); + triggerSpec.delay = parseInterval(consumeUntil(tokens, WHITESPACE_OR_COMMA)); + } else if (token === "from" && tokens[0] === ":") { + tokens.shift(); + if (COMBINED_SELECTOR_START.test(tokens[0])) { + var from_arg = consumeCSSSelector(tokens); + } else { + var from_arg = consumeUntil(tokens, WHITESPACE_OR_COMMA); + if (from_arg === "closest" || from_arg === "find" || from_arg === "next" || from_arg === "previous") { + tokens.shift(); + const selector = consumeCSSSelector(tokens); + if (selector.length > 0) { + from_arg += " " + selector; + } + } + } + triggerSpec.from = from_arg; + } else if (token === "target" && tokens[0] === ":") { + tokens.shift(); + triggerSpec.target = consumeCSSSelector(tokens); + } else if (token === "throttle" && tokens[0] === ":") { + tokens.shift(); + triggerSpec.throttle = parseInterval(consumeUntil(tokens, WHITESPACE_OR_COMMA)); + } else if (token === "queue" && tokens[0] === ":") { + tokens.shift(); + triggerSpec.queue = consumeUntil(tokens, WHITESPACE_OR_COMMA); + } else if (token === "root" && tokens[0] === ":") { + tokens.shift(); + triggerSpec[token] = consumeCSSSelector(tokens); + } else if (token === "threshold" && tokens[0] === ":") { + tokens.shift(); + triggerSpec[token] = consumeUntil(tokens, WHITESPACE_OR_COMMA); + } else { + triggerErrorEvent(elt, "htmx:syntax:error", { token: tokens.shift() }); + } + } + triggerSpecs.push(triggerSpec); + } + } + if (tokens.length === initialLength) { + triggerErrorEvent(elt, "htmx:syntax:error", { token: tokens.shift() }); + } + consumeUntil(tokens, NOT_WHITESPACE); + } while (tokens[0] === "," && tokens.shift()); + if (cache) { + cache[explicitTrigger] = triggerSpecs; + } + return triggerSpecs; + } + function getTriggerSpecs(elt) { + const explicitTrigger = getAttributeValue(elt, "hx-trigger"); + let triggerSpecs = []; + if (explicitTrigger) { + const cache = htmx.config.triggerSpecsCache; + triggerSpecs = cache && cache[explicitTrigger] || parseAndCacheTrigger(elt, explicitTrigger, cache); + } + if (triggerSpecs.length > 0) { + return triggerSpecs; + } else if (matches(elt, "form")) { + return [{ trigger: "submit" }]; + } else if (matches(elt, 'input[type="button"], input[type="submit"]')) { + return [{ trigger: "click" }]; + } else if (matches(elt, INPUT_SELECTOR)) { + return [{ trigger: "change" }]; + } else { + return [{ trigger: "click" }]; + } + } + function cancelPolling(elt) { + getInternalData(elt).cancelled = true; + } + function processPolling(elt, handler4, spec) { + const nodeData = getInternalData(elt); + nodeData.timeout = getWindow().setTimeout(function() { + if (bodyContains(elt) && nodeData.cancelled !== true) { + if (!maybeFilterEvent(spec, elt, makeEvent("hx:poll:trigger", { + triggerSpec: spec, + target: elt + }))) { + handler4(elt); + } + processPolling(elt, handler4, spec); + } + }, spec.pollInterval); + } + function isLocalLink(elt) { + return location.hostname === elt.hostname && getRawAttribute(elt, "href") && getRawAttribute(elt, "href").indexOf("#") !== 0; + } + function eltIsDisabled(elt) { + return closest(elt, htmx.config.disableSelector); + } + function boostElement(elt, nodeData, triggerSpecs) { + if (elt instanceof HTMLAnchorElement && isLocalLink(elt) && (elt.target === "" || elt.target === "_self") || elt.tagName === "FORM") { + nodeData.boosted = true; + let verb, path; + if (elt.tagName === "A") { + verb = "get"; + path = getRawAttribute(elt, "href"); + } else { + const rawAttribute = getRawAttribute(elt, "method"); + verb = rawAttribute ? rawAttribute.toLowerCase() : "get"; + if (verb === "get") { + } + path = getRawAttribute(elt, "action"); + } + triggerSpecs.forEach(function(triggerSpec) { + addEventListener(elt, function(node, evt) { + const elt2 = asElement(node); + if (eltIsDisabled(elt2)) { + cleanUpElement(elt2); + return; + } + issueAjaxRequest(verb, path, elt2, evt); + }, nodeData, triggerSpec, true); + }); + } + } + function shouldCancel(evt, node) { + const elt = asElement(node); + if (!elt) { + return false; + } + if (evt.type === "submit" || evt.type === "click") { + if (elt.tagName === "FORM") { + return true; + } + if (matches(elt, 'input[type="submit"], button') && closest(elt, "form") !== null) { + return true; + } + if (elt instanceof HTMLAnchorElement && elt.href && (elt.getAttribute("href") === "#" || elt.getAttribute("href").indexOf("#") !== 0)) { + return true; + } + } + return false; + } + function ignoreBoostedAnchorCtrlClick(elt, evt) { + return getInternalData(elt).boosted && elt instanceof HTMLAnchorElement && evt.type === "click" && // @ts-ignore this will resolve to undefined for events that don't define those properties, which is fine + (evt.ctrlKey || evt.metaKey); + } + function maybeFilterEvent(triggerSpec, elt, evt) { + const eventFilter = triggerSpec.eventFilter; + if (eventFilter) { + try { + return eventFilter.call(elt, evt) !== true; + } catch (e) { + const source = eventFilter.source; + triggerErrorEvent(getDocument().body, "htmx:eventFilter:error", { error: e, source }); + return true; + } + } + return false; + } + function addEventListener(elt, handler4, nodeData, triggerSpec, explicitCancel) { + const elementData = getInternalData(elt); + let eltsToListenOn; + if (triggerSpec.from) { + eltsToListenOn = querySelectorAllExt(elt, triggerSpec.from); + } else { + eltsToListenOn = [elt]; + } + if (triggerSpec.changed) { + eltsToListenOn.forEach(function(eltToListenOn) { + const eltToListenOnData = getInternalData(eltToListenOn); + eltToListenOnData.lastValue = eltToListenOn.value; + }); + } + forEach(eltsToListenOn, function(eltToListenOn) { + const eventListener = function(evt) { + if (!bodyContains(elt)) { + eltToListenOn.removeEventListener(triggerSpec.trigger, eventListener); + return; + } + if (ignoreBoostedAnchorCtrlClick(elt, evt)) { + return; + } + if (explicitCancel || shouldCancel(evt, elt)) { + evt.preventDefault(); + } + if (maybeFilterEvent(triggerSpec, elt, evt)) { + return; + } + const eventData = getInternalData(evt); + eventData.triggerSpec = triggerSpec; + if (eventData.handledFor == null) { + eventData.handledFor = []; + } + if (eventData.handledFor.indexOf(elt) < 0) { + eventData.handledFor.push(elt); + if (triggerSpec.consume) { + evt.stopPropagation(); + } + if (triggerSpec.target && evt.target) { + if (!matches(asElement(evt.target), triggerSpec.target)) { + return; + } + } + if (triggerSpec.once) { + if (elementData.triggeredOnce) { + return; + } else { + elementData.triggeredOnce = true; + } + } + if (triggerSpec.changed) { + const eltToListenOnData = getInternalData(eltToListenOn); + const value = eltToListenOn.value; + if (eltToListenOnData.lastValue === value) { + return; + } + eltToListenOnData.lastValue = value; + } + if (elementData.delayed) { + clearTimeout(elementData.delayed); + } + if (elementData.throttle) { + return; + } + if (triggerSpec.throttle > 0) { + if (!elementData.throttle) { + handler4(elt, evt); + elementData.throttle = getWindow().setTimeout(function() { + elementData.throttle = null; + }, triggerSpec.throttle); + } + } else if (triggerSpec.delay > 0) { + elementData.delayed = getWindow().setTimeout(function() { + handler4(elt, evt); + }, triggerSpec.delay); + } else { + triggerEvent(elt, "htmx:trigger"); + handler4(elt, evt); + } + } + }; + if (nodeData.listenerInfos == null) { + nodeData.listenerInfos = []; + } + nodeData.listenerInfos.push({ + trigger: triggerSpec.trigger, + listener: eventListener, + on: eltToListenOn + }); + eltToListenOn.addEventListener(triggerSpec.trigger, eventListener); + }); + } + let windowIsScrolling = false; + let scrollHandler = null; + function initScrollHandler() { + if (!scrollHandler) { + scrollHandler = function() { + windowIsScrolling = true; + }; + window.addEventListener("scroll", scrollHandler); + setInterval(function() { + if (windowIsScrolling) { + windowIsScrolling = false; + forEach(getDocument().querySelectorAll("[hx-trigger*='revealed'],[data-hx-trigger*='revealed']"), function(elt) { + maybeReveal(elt); + }); + } + }, 200); + } + } + function maybeReveal(elt) { + if (!hasAttribute(elt, "data-hx-revealed") && isScrolledIntoView(elt)) { + elt.setAttribute("data-hx-revealed", "true"); + const nodeData = getInternalData(elt); + if (nodeData.initHash) { + triggerEvent(elt, "revealed"); + } else { + elt.addEventListener("htmx:afterProcessNode", function() { + triggerEvent(elt, "revealed"); + }, { once: true }); + } + } + } + function loadImmediately(elt, handler4, nodeData, delay) { + const load = function() { + if (!nodeData.loaded) { + nodeData.loaded = true; + handler4(elt); + } + }; + if (delay > 0) { + getWindow().setTimeout(load, delay); + } else { + load(); + } + } + function processVerbs(elt, nodeData, triggerSpecs) { + let explicitAction = false; + forEach(VERBS, function(verb) { + if (hasAttribute(elt, "hx-" + verb)) { + const path = getAttributeValue(elt, "hx-" + verb); + explicitAction = true; + nodeData.path = path; + nodeData.verb = verb; + triggerSpecs.forEach(function(triggerSpec) { + addTriggerHandler(elt, triggerSpec, nodeData, function(node, evt) { + const elt2 = asElement(node); + if (closest(elt2, htmx.config.disableSelector)) { + cleanUpElement(elt2); + return; + } + issueAjaxRequest(verb, path, elt2, evt); + }); + }); + } + }); + return explicitAction; + } + function addTriggerHandler(elt, triggerSpec, nodeData, handler4) { + if (triggerSpec.trigger === "revealed") { + initScrollHandler(); + addEventListener(elt, handler4, nodeData, triggerSpec); + maybeReveal(asElement(elt)); + } else if (triggerSpec.trigger === "intersect") { + const observerOptions = {}; + if (triggerSpec.root) { + observerOptions.root = querySelectorExt(elt, triggerSpec.root); + } + if (triggerSpec.threshold) { + observerOptions.threshold = parseFloat(triggerSpec.threshold); + } + const observer2 = new IntersectionObserver(function(entries) { + for (let i = 0; i < entries.length; i++) { + const entry = entries[i]; + if (entry.isIntersecting) { + triggerEvent(elt, "intersect"); + break; + } + } + }, observerOptions); + observer2.observe(asElement(elt)); + addEventListener(asElement(elt), handler4, nodeData, triggerSpec); + } else if (triggerSpec.trigger === "load") { + if (!maybeFilterEvent(triggerSpec, elt, makeEvent("load", { elt }))) { + loadImmediately(asElement(elt), handler4, nodeData, triggerSpec.delay); + } + } else if (triggerSpec.pollInterval > 0) { + nodeData.polling = true; + processPolling(asElement(elt), handler4, triggerSpec); + } else { + addEventListener(elt, handler4, nodeData, triggerSpec); + } + } + function shouldProcessHxOn(node) { + const elt = asElement(node); + if (!elt) { + return false; + } + const attributes = elt.attributes; + for (let j = 0; j < attributes.length; j++) { + const attrName = attributes[j].name; + if (startsWith(attrName, "hx-on:") || startsWith(attrName, "data-hx-on:") || startsWith(attrName, "hx-on-") || startsWith(attrName, "data-hx-on-")) { + return true; + } + } + return false; + } + const HX_ON_QUERY = new XPathEvaluator().createExpression('.//*[@*[ starts-with(name(), "hx-on:") or starts-with(name(), "data-hx-on:") or starts-with(name(), "hx-on-") or starts-with(name(), "data-hx-on-") ]]'); + function processHXOnRoot(elt, elements) { + if (shouldProcessHxOn(elt)) { + elements.push(asElement(elt)); + } + const iter = HX_ON_QUERY.evaluate(elt); + let node = null; + while (node = iter.iterateNext()) + elements.push(asElement(node)); + } + function findHxOnWildcardElements(elt) { + const elements = []; + if (elt instanceof DocumentFragment) { + for (const child of elt.childNodes) { + processHXOnRoot(child, elements); + } + } else { + processHXOnRoot(elt, elements); + } + return elements; + } + function findElementsToProcess(elt) { + if (elt.querySelectorAll) { + const boostedSelector = ", [hx-boost] a, [data-hx-boost] a, a[hx-boost], a[data-hx-boost]"; + const extensionSelectors = []; + for (const e in extensions) { + const extension = extensions[e]; + if (extension.getSelectors) { + var selectors = extension.getSelectors(); + if (selectors) { + extensionSelectors.push(selectors); + } + } + } + const results = elt.querySelectorAll(VERB_SELECTOR + boostedSelector + ", form, [type='submit'], [hx-ext], [data-hx-ext], [hx-trigger], [data-hx-trigger]" + extensionSelectors.flat().map((s) => ", " + s).join("")); + return results; + } else { + return []; + } + } + function maybeSetLastButtonClicked(evt) { + const elt = ( + /** @type {HTMLButtonElement|HTMLInputElement} */ + closest(asElement(evt.target), "button, input[type='submit']") + ); + const internalData = getRelatedFormData(evt); + if (internalData) { + internalData.lastButtonClicked = elt; + } + } + function maybeUnsetLastButtonClicked(evt) { + const internalData = getRelatedFormData(evt); + if (internalData) { + internalData.lastButtonClicked = null; + } + } + function getRelatedFormData(evt) { + const elt = closest(asElement(evt.target), "button, input[type='submit']"); + if (!elt) { + return; + } + const form = resolveTarget("#" + getRawAttribute(elt, "form"), elt.getRootNode()) || closest(elt, "form"); + if (!form) { + return; + } + return getInternalData(form); + } + function initButtonTracking(elt) { + elt.addEventListener("click", maybeSetLastButtonClicked); + elt.addEventListener("focusin", maybeSetLastButtonClicked); + elt.addEventListener("focusout", maybeUnsetLastButtonClicked); + } + function addHxOnEventHandler(elt, eventName, code) { + const nodeData = getInternalData(elt); + if (!Array.isArray(nodeData.onHandlers)) { + nodeData.onHandlers = []; + } + let func; + const listener = function(e) { + maybeEval(elt, function() { + if (eltIsDisabled(elt)) { + return; + } + if (!func) { + func = new Function("event", code); + } + func.call(elt, e); + }); + }; + elt.addEventListener(eventName, listener); + nodeData.onHandlers.push({ event: eventName, listener }); + } + function processHxOnWildcard(elt) { + deInitOnHandlers(elt); + for (let i = 0; i < elt.attributes.length; i++) { + const name = elt.attributes[i].name; + const value = elt.attributes[i].value; + if (startsWith(name, "hx-on") || startsWith(name, "data-hx-on")) { + const afterOnPosition = name.indexOf("-on") + 3; + const nextChar = name.slice(afterOnPosition, afterOnPosition + 1); + if (nextChar === "-" || nextChar === ":") { + let eventName = name.slice(afterOnPosition + 1); + if (startsWith(eventName, ":")) { + eventName = "htmx" + eventName; + } else if (startsWith(eventName, "-")) { + eventName = "htmx:" + eventName.slice(1); + } else if (startsWith(eventName, "htmx-")) { + eventName = "htmx:" + eventName.slice(5); + } + addHxOnEventHandler(elt, eventName, value); + } + } + } + } + function initNode(elt) { + if (closest(elt, htmx.config.disableSelector)) { + cleanUpElement(elt); + return; + } + const nodeData = getInternalData(elt); + if (nodeData.initHash !== attributeHash(elt)) { + deInitNode(elt); + nodeData.initHash = attributeHash(elt); + triggerEvent(elt, "htmx:beforeProcessNode"); + if (elt.value) { + nodeData.lastValue = elt.value; + } + const triggerSpecs = getTriggerSpecs(elt); + const hasExplicitHttpAction = processVerbs(elt, nodeData, triggerSpecs); + if (!hasExplicitHttpAction) { + if (getClosestAttributeValue(elt, "hx-boost") === "true") { + boostElement(elt, nodeData, triggerSpecs); + } else if (hasAttribute(elt, "hx-trigger")) { + triggerSpecs.forEach(function(triggerSpec) { + addTriggerHandler(elt, triggerSpec, nodeData, function() { + }); + }); + } + } + if (elt.tagName === "FORM" || getRawAttribute(elt, "type") === "submit" && hasAttribute(elt, "form")) { + initButtonTracking(elt); + } + triggerEvent(elt, "htmx:afterProcessNode"); + } + } + function processNode(elt) { + elt = resolveTarget(elt); + if (closest(elt, htmx.config.disableSelector)) { + cleanUpElement(elt); + return; + } + initNode(elt); + forEach(findElementsToProcess(elt), function(child) { + initNode(child); + }); + forEach(findHxOnWildcardElements(elt), processHxOnWildcard); + } + function kebabEventName(str2) { + return str2.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(); + } + function makeEvent(eventName, detail) { + let evt; + if (window.CustomEvent && typeof window.CustomEvent === "function") { + evt = new CustomEvent(eventName, { bubbles: true, cancelable: true, composed: true, detail }); + } else { + evt = getDocument().createEvent("CustomEvent"); + evt.initCustomEvent(eventName, true, true, detail); + } + return evt; + } + function triggerErrorEvent(elt, eventName, detail) { + triggerEvent(elt, eventName, mergeObjects({ error: eventName }, detail)); + } + function ignoreEventForLogging(eventName) { + return eventName === "htmx:afterProcessNode"; + } + function withExtensions(elt, toDo) { + forEach(getExtensions(elt), function(extension) { + try { + toDo(extension); + } catch (e) { + logError(e); + } + }); + } + function logError(msg) { + if (console.error) { + console.error(msg); + } else if (console.log) { + console.log("ERROR: ", msg); + } + } + function triggerEvent(elt, eventName, detail) { + elt = resolveTarget(elt); + if (detail == null) { + detail = {}; + } + detail.elt = elt; + const event = makeEvent(eventName, detail); + if (htmx.logger && !ignoreEventForLogging(eventName)) { + htmx.logger(elt, eventName, detail); + } + if (detail.error) { + logError(detail.error); + triggerEvent(elt, "htmx:error", { errorInfo: detail }); + } + let eventResult = elt.dispatchEvent(event); + const kebabName = kebabEventName(eventName); + if (eventResult && kebabName !== eventName) { + const kebabedEvent = makeEvent(kebabName, event.detail); + eventResult = eventResult && elt.dispatchEvent(kebabedEvent); + } + withExtensions(asElement(elt), function(extension) { + eventResult = eventResult && (extension.onEvent(eventName, event) !== false && !event.defaultPrevented); + }); + return eventResult; + } + let currentPathForHistory = location.pathname + location.search; + function getHistoryElement() { + const historyElt = getDocument().querySelector("[hx-history-elt],[data-hx-history-elt]"); + return historyElt || getDocument().body; + } + function saveToHistoryCache(url, rootElt) { + if (!canAccessLocalStorage()) { + return; + } + const innerHTML = cleanInnerHtmlForHistory(rootElt); + const title = getDocument().title; + const scroll = window.scrollY; + if (htmx.config.historyCacheSize <= 0) { + localStorage.removeItem("htmx-history-cache"); + return; + } + url = normalizePath(url); + const historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || []; + for (let i = 0; i < historyCache.length; i++) { + if (historyCache[i].url === url) { + historyCache.splice(i, 1); + break; + } + } + const newHistoryItem = { url, content: innerHTML, title, scroll }; + triggerEvent(getDocument().body, "htmx:historyItemCreated", { item: newHistoryItem, cache: historyCache }); + historyCache.push(newHistoryItem); + while (historyCache.length > htmx.config.historyCacheSize) { + historyCache.shift(); + } + while (historyCache.length > 0) { + try { + localStorage.setItem("htmx-history-cache", JSON.stringify(historyCache)); + break; + } catch (e) { + triggerErrorEvent(getDocument().body, "htmx:historyCacheError", { cause: e, cache: historyCache }); + historyCache.shift(); + } + } + } + function getCachedHistory(url) { + if (!canAccessLocalStorage()) { + return null; + } + url = normalizePath(url); + const historyCache = parseJSON(localStorage.getItem("htmx-history-cache")) || []; + for (let i = 0; i < historyCache.length; i++) { + if (historyCache[i].url === url) { + return historyCache[i]; + } + } + return null; + } + function cleanInnerHtmlForHistory(elt) { + const className = htmx.config.requestClass; + const clone2 = ( + /** @type Element */ + elt.cloneNode(true) + ); + forEach(findAll(clone2, "." + className), function(child) { + removeClassFromElement(child, className); + }); + return clone2.innerHTML; + } + function saveCurrentPageToHistory() { + const elt = getHistoryElement(); + const path = currentPathForHistory || location.pathname + location.search; + let disableHistoryCache; + try { + disableHistoryCache = getDocument().querySelector('[hx-history="false" i],[data-hx-history="false" i]'); + } catch (e) { + disableHistoryCache = getDocument().querySelector('[hx-history="false"],[data-hx-history="false"]'); + } + if (!disableHistoryCache) { + triggerEvent(getDocument().body, "htmx:beforeHistorySave", { path, historyElt: elt }); + saveToHistoryCache(path, elt); + } + if (htmx.config.historyEnabled) + history.replaceState({ htmx: true }, getDocument().title, window.location.href); + } + function pushUrlIntoHistory(path) { + if (htmx.config.getCacheBusterParam) { + path = path.replace(/org\.htmx\.cache-buster=[^&]*&?/, ""); + if (endsWith(path, "&") || endsWith(path, "?")) { + path = path.slice(0, -1); + } + } + if (htmx.config.historyEnabled) { + history.pushState({ htmx: true }, "", path); + } + currentPathForHistory = path; + } + function replaceUrlInHistory(path) { + if (htmx.config.historyEnabled) + history.replaceState({ htmx: true }, "", path); + currentPathForHistory = path; + } + function settleImmediately(tasks) { + forEach(tasks, function(task) { + task.call(void 0); + }); + } + function loadHistoryFromServer(path) { + const request = new XMLHttpRequest(); + const details = { path, xhr: request }; + triggerEvent(getDocument().body, "htmx:historyCacheMiss", details); + request.open("GET", path, true); + request.setRequestHeader("HX-Request", "true"); + request.setRequestHeader("HX-History-Restore-Request", "true"); + request.setRequestHeader("HX-Current-URL", getDocument().location.href); + request.onload = function() { + if (this.status >= 200 && this.status < 400) { + triggerEvent(getDocument().body, "htmx:historyCacheMissLoad", details); + const fragment = makeFragment(this.response); + const content = fragment.querySelector("[hx-history-elt],[data-hx-history-elt]") || fragment; + const historyElement = getHistoryElement(); + const settleInfo = makeSettleInfo(historyElement); + handleTitle(fragment.title); + swapInnerHTML(historyElement, content, settleInfo); + settleImmediately(settleInfo.tasks); + currentPathForHistory = path; + triggerEvent(getDocument().body, "htmx:historyRestore", { path, cacheMiss: true, serverResponse: this.response }); + } else { + triggerErrorEvent(getDocument().body, "htmx:historyCacheMissLoadError", details); + } + }; + request.send(); + } + function restoreHistory(path) { + saveCurrentPageToHistory(); + path = path || location.pathname + location.search; + const cached = getCachedHistory(path); + if (cached) { + const fragment = makeFragment(cached.content); + const historyElement = getHistoryElement(); + const settleInfo = makeSettleInfo(historyElement); + handleTitle(fragment.title); + swapInnerHTML(historyElement, fragment, settleInfo); + settleImmediately(settleInfo.tasks); + getWindow().setTimeout(function() { + window.scrollTo(0, cached.scroll); + }, 0); + currentPathForHistory = path; + triggerEvent(getDocument().body, "htmx:historyRestore", { path, item: cached }); + } else { + if (htmx.config.refreshOnHistoryMiss) { + window.location.reload(true); + } else { + loadHistoryFromServer(path); + } + } + } + function addRequestIndicatorClasses(elt) { + let indicators = ( + /** @type Element[] */ + findAttributeTargets(elt, "hx-indicator") + ); + if (indicators == null) { + indicators = [elt]; + } + forEach(indicators, function(ic) { + const internalData = getInternalData(ic); + internalData.requestCount = (internalData.requestCount || 0) + 1; + ic.classList.add.call(ic.classList, htmx.config.requestClass); + }); + return indicators; + } + function disableElements(elt) { + let disabledElts = ( + /** @type Element[] */ + findAttributeTargets(elt, "hx-disabled-elt") + ); + if (disabledElts == null) { + disabledElts = []; + } + forEach(disabledElts, function(disabledElement) { + const internalData = getInternalData(disabledElement); + internalData.requestCount = (internalData.requestCount || 0) + 1; + disabledElement.setAttribute("disabled", ""); + }); + return disabledElts; + } + function removeRequestIndicators(indicators, disabled) { + forEach(indicators, function(ic) { + const internalData = getInternalData(ic); + internalData.requestCount = (internalData.requestCount || 0) - 1; + if (internalData.requestCount === 0) { + ic.classList.remove.call(ic.classList, htmx.config.requestClass); + } + }); + forEach(disabled, function(disabledElement) { + const internalData = getInternalData(disabledElement); + internalData.requestCount = (internalData.requestCount || 0) - 1; + if (internalData.requestCount === 0) { + disabledElement.removeAttribute("disabled"); + } + }); + } + function haveSeenNode(processed, elt) { + for (let i = 0; i < processed.length; i++) { + const node = processed[i]; + if (node.isSameNode(elt)) { + return true; + } + } + return false; + } + function shouldInclude(element) { + const elt = ( + /** @type {HTMLInputElement} */ + element + ); + if (elt.name === "" || elt.name == null || elt.disabled || closest(elt, "fieldset[disabled]")) { + return false; + } + if (elt.type === "button" || elt.type === "submit" || elt.tagName === "image" || elt.tagName === "reset" || elt.tagName === "file") { + return false; + } + if (elt.type === "checkbox" || elt.type === "radio") { + return elt.checked; + } + return true; + } + function addValueToFormData(name, value, formData) { + if (name != null && value != null) { + if (Array.isArray(value)) { + value.forEach(function(v) { + formData.append(name, v); + }); + } else { + formData.append(name, value); + } + } + } + function removeValueFromFormData(name, value, formData) { + if (name != null && value != null) { + let values = formData.getAll(name); + if (Array.isArray(value)) { + values = values.filter((v) => value.indexOf(v) < 0); + } else { + values = values.filter((v) => v !== value); + } + formData.delete(name); + forEach(values, (v) => formData.append(name, v)); + } + } + function processInputValue(processed, formData, errors, elt, validate) { + if (elt == null || haveSeenNode(processed, elt)) { + return; + } else { + processed.push(elt); + } + if (shouldInclude(elt)) { + const name = getRawAttribute(elt, "name"); + let value = elt.value; + if (elt instanceof HTMLSelectElement && elt.multiple) { + value = toArray(elt.querySelectorAll("option:checked")).map(function(e) { + return ( + /** @type HTMLOptionElement */ + e.value + ); + }); + } + if (elt instanceof HTMLInputElement && elt.files) { + value = toArray(elt.files); + } + addValueToFormData(name, value, formData); + if (validate) { + validateElement(elt, errors); + } + } + if (elt instanceof HTMLFormElement) { + forEach(elt.elements, function(input) { + if (processed.indexOf(input) >= 0) { + removeValueFromFormData(input.name, input.value, formData); + } else { + processed.push(input); + } + if (validate) { + validateElement(input, errors); + } + }); + new FormData(elt).forEach(function(value, name) { + if (value instanceof File && value.name === "") { + return; + } + addValueToFormData(name, value, formData); + }); + } + } + function validateElement(elt, errors) { + const element = ( + /** @type {HTMLElement & ElementInternals} */ + elt + ); + if (element.willValidate) { + triggerEvent(element, "htmx:validation:validate"); + if (!element.checkValidity()) { + errors.push({ elt: element, message: element.validationMessage, validity: element.validity }); + triggerEvent(element, "htmx:validation:failed", { message: element.validationMessage, validity: element.validity }); + } + } + } + function overrideFormData(receiver, donor) { + for (const key of donor.keys()) { + receiver.delete(key); + donor.getAll(key).forEach(function(value) { + receiver.append(key, value); + }); + } + return receiver; + } + function getInputValues(elt, verb) { + const processed = []; + const formData = new FormData(); + const priorityFormData = new FormData(); + const errors = []; + const internalData = getInternalData(elt); + if (internalData.lastButtonClicked && !bodyContains(internalData.lastButtonClicked)) { + internalData.lastButtonClicked = null; + } + let validate = elt instanceof HTMLFormElement && elt.noValidate !== true || getAttributeValue(elt, "hx-validate") === "true"; + if (internalData.lastButtonClicked) { + validate = validate && internalData.lastButtonClicked.formNoValidate !== true; + } + if (verb !== "get") { + processInputValue(processed, priorityFormData, errors, closest(elt, "form"), validate); + } + processInputValue(processed, formData, errors, elt, validate); + if (internalData.lastButtonClicked || elt.tagName === "BUTTON" || elt.tagName === "INPUT" && getRawAttribute(elt, "type") === "submit") { + const button = internalData.lastButtonClicked || /** @type HTMLInputElement|HTMLButtonElement */ + elt; + const name = getRawAttribute(button, "name"); + addValueToFormData(name, button.value, priorityFormData); + } + const includes = findAttributeTargets(elt, "hx-include"); + forEach(includes, function(node) { + processInputValue(processed, formData, errors, asElement(node), validate); + if (!matches(node, "form")) { + forEach(asParentNode(node).querySelectorAll(INPUT_SELECTOR), function(descendant) { + processInputValue(processed, formData, errors, descendant, validate); + }); + } + }); + overrideFormData(formData, priorityFormData); + return { errors, formData, values: formDataProxy(formData) }; + } + function appendParam(returnStr, name, realValue) { + if (returnStr !== "") { + returnStr += "&"; + } + if (String(realValue) === "[object Object]") { + realValue = JSON.stringify(realValue); + } + const s = encodeURIComponent(realValue); + returnStr += encodeURIComponent(name) + "=" + s; + return returnStr; + } + function urlEncode(values) { + values = formDataFromObject(values); + let returnStr = ""; + values.forEach(function(value, key) { + returnStr = appendParam(returnStr, key, value); + }); + return returnStr; + } + function getHeaders(elt, target, prompt2) { + const headers = { + "HX-Request": "true", + "HX-Trigger": getRawAttribute(elt, "id"), + "HX-Trigger-Name": getRawAttribute(elt, "name"), + "HX-Target": getAttributeValue(target, "id"), + "HX-Current-URL": getDocument().location.href + }; + getValuesForElement(elt, "hx-headers", false, headers); + if (prompt2 !== void 0) { + headers["HX-Prompt"] = prompt2; + } + if (getInternalData(elt).boosted) { + headers["HX-Boosted"] = "true"; + } + return headers; + } + function filterValues(inputValues, elt) { + const paramsValue = getClosestAttributeValue(elt, "hx-params"); + if (paramsValue) { + if (paramsValue === "none") { + return new FormData(); + } else if (paramsValue === "*") { + return inputValues; + } else if (paramsValue.indexOf("not ") === 0) { + forEach(paramsValue.substr(4).split(","), function(name) { + name = name.trim(); + inputValues.delete(name); + }); + return inputValues; + } else { + const newValues = new FormData(); + forEach(paramsValue.split(","), function(name) { + name = name.trim(); + if (inputValues.has(name)) { + inputValues.getAll(name).forEach(function(value) { + newValues.append(name, value); + }); + } + }); + return newValues; + } + } else { + return inputValues; + } + } + function isAnchorLink(elt) { + return !!getRawAttribute(elt, "href") && getRawAttribute(elt, "href").indexOf("#") >= 0; + } + function getSwapSpecification(elt, swapInfoOverride) { + const swapInfo = swapInfoOverride || getClosestAttributeValue(elt, "hx-swap"); + const swapSpec = { + swapStyle: getInternalData(elt).boosted ? "innerHTML" : htmx.config.defaultSwapStyle, + swapDelay: htmx.config.defaultSwapDelay, + settleDelay: htmx.config.defaultSettleDelay + }; + if (htmx.config.scrollIntoViewOnBoost && getInternalData(elt).boosted && !isAnchorLink(elt)) { + swapSpec.show = "top"; + } + if (swapInfo) { + const split = splitOnWhitespace(swapInfo); + if (split.length > 0) { + for (let i = 0; i < split.length; i++) { + const value = split[i]; + if (value.indexOf("swap:") === 0) { + swapSpec.swapDelay = parseInterval(value.substr(5)); + } else if (value.indexOf("settle:") === 0) { + swapSpec.settleDelay = parseInterval(value.substr(7)); + } else if (value.indexOf("transition:") === 0) { + swapSpec.transition = value.substr(11) === "true"; + } else if (value.indexOf("ignoreTitle:") === 0) { + swapSpec.ignoreTitle = value.substr(12) === "true"; + } else if (value.indexOf("scroll:") === 0) { + const scrollSpec = value.substr(7); + var splitSpec = scrollSpec.split(":"); + const scrollVal = splitSpec.pop(); + var selectorVal = splitSpec.length > 0 ? splitSpec.join(":") : null; + swapSpec.scroll = scrollVal; + swapSpec.scrollTarget = selectorVal; + } else if (value.indexOf("show:") === 0) { + const showSpec = value.substr(5); + var splitSpec = showSpec.split(":"); + const showVal = splitSpec.pop(); + var selectorVal = splitSpec.length > 0 ? splitSpec.join(":") : null; + swapSpec.show = showVal; + swapSpec.showTarget = selectorVal; + } else if (value.indexOf("focus-scroll:") === 0) { + const focusScrollVal = value.substr("focus-scroll:".length); + swapSpec.focusScroll = focusScrollVal == "true"; + } else if (i == 0) { + swapSpec.swapStyle = value; + } else { + logError("Unknown modifier in hx-swap: " + value); + } + } + } + } + return swapSpec; + } + function usesFormData(elt) { + return getClosestAttributeValue(elt, "hx-encoding") === "multipart/form-data" || matches(elt, "form") && getRawAttribute(elt, "enctype") === "multipart/form-data"; + } + function encodeParamsForBody(xhr, elt, filteredParameters) { + let encodedParameters = null; + withExtensions(elt, function(extension) { + if (encodedParameters == null) { + encodedParameters = extension.encodeParameters(xhr, filteredParameters, elt); + } + }); + if (encodedParameters != null) { + return encodedParameters; + } else { + if (usesFormData(elt)) { + return overrideFormData(new FormData(), formDataFromObject(filteredParameters)); + } else { + return urlEncode(filteredParameters); + } + } + } + function makeSettleInfo(target) { + return { tasks: [], elts: [target] }; + } + function updateScrollState(content, swapSpec) { + const first = content[0]; + const last = content[content.length - 1]; + if (swapSpec.scroll) { + var target = null; + if (swapSpec.scrollTarget) { + target = asElement(querySelectorExt(first, swapSpec.scrollTarget)); + } + if (swapSpec.scroll === "top" && (first || target)) { + target = target || first; + target.scrollTop = 0; + } + if (swapSpec.scroll === "bottom" && (last || target)) { + target = target || last; + target.scrollTop = target.scrollHeight; + } + } + if (swapSpec.show) { + var target = null; + if (swapSpec.showTarget) { + let targetStr = swapSpec.showTarget; + if (swapSpec.showTarget === "window") { + targetStr = "body"; + } + target = asElement(querySelectorExt(first, targetStr)); + } + if (swapSpec.show === "top" && (first || target)) { + target = target || first; + target.scrollIntoView({ block: "start", behavior: htmx.config.scrollBehavior }); + } + if (swapSpec.show === "bottom" && (last || target)) { + target = target || last; + target.scrollIntoView({ block: "end", behavior: htmx.config.scrollBehavior }); + } + } + } + function getValuesForElement(elt, attr, evalAsDefault, values) { + if (values == null) { + values = {}; + } + if (elt == null) { + return values; + } + const attributeValue = getAttributeValue(elt, attr); + if (attributeValue) { + let str2 = attributeValue.trim(); + let evaluateValue = evalAsDefault; + if (str2 === "unset") { + return null; + } + if (str2.indexOf("javascript:") === 0) { + str2 = str2.substr(11); + evaluateValue = true; + } else if (str2.indexOf("js:") === 0) { + str2 = str2.substr(3); + evaluateValue = true; + } + if (str2.indexOf("{") !== 0) { + str2 = "{" + str2 + "}"; + } + let varsValues; + if (evaluateValue) { + varsValues = maybeEval(elt, function() { + return Function("return (" + str2 + ")")(); + }, {}); + } else { + varsValues = parseJSON(str2); + } + for (const key in varsValues) { + if (varsValues.hasOwnProperty(key)) { + if (values[key] == null) { + values[key] = varsValues[key]; + } + } + } + } + return getValuesForElement(asElement(parentElt(elt)), attr, evalAsDefault, values); + } + function maybeEval(elt, toEval, defaultVal) { + if (htmx.config.allowEval) { + return toEval(); + } else { + triggerErrorEvent(elt, "htmx:evalDisallowedError"); + return defaultVal; + } + } + function getHXVarsForElement(elt, expressionVars) { + return getValuesForElement(elt, "hx-vars", true, expressionVars); + } + function getHXValsForElement(elt, expressionVars) { + return getValuesForElement(elt, "hx-vals", false, expressionVars); + } + function getExpressionVars(elt) { + return mergeObjects(getHXVarsForElement(elt), getHXValsForElement(elt)); + } + function safelySetHeaderValue(xhr, header, headerValue) { + if (headerValue !== null) { + try { + xhr.setRequestHeader(header, headerValue); + } catch (e) { + xhr.setRequestHeader(header, encodeURIComponent(headerValue)); + xhr.setRequestHeader(header + "-URI-AutoEncoded", "true"); + } + } + } + function getPathFromResponse(xhr) { + if (xhr.responseURL && typeof URL !== "undefined") { + try { + const url = new URL(xhr.responseURL); + return url.pathname + url.search; + } catch (e) { + triggerErrorEvent(getDocument().body, "htmx:badResponseUrl", { url: xhr.responseURL }); + } + } + } + function hasHeader(xhr, regexp) { + return regexp.test(xhr.getAllResponseHeaders()); + } + function ajaxHelper(verb, path, context) { + verb = /** @type HttpVerb */ + verb.toLowerCase(); + if (context) { + if (context instanceof Element || typeof context === "string") { + return issueAjaxRequest(verb, path, null, null, { + targetOverride: resolveTarget(context), + returnPromise: true + }); + } else { + return issueAjaxRequest( + verb, + path, + resolveTarget(context.source), + context.event, + { + handler: context.handler, + headers: context.headers, + values: context.values, + targetOverride: resolveTarget(context.target), + swapOverride: context.swap, + select: context.select, + returnPromise: true + } + ); + } + } else { + return issueAjaxRequest(verb, path, null, null, { + returnPromise: true + }); + } + } + function hierarchyForElt(elt) { + const arr = []; + while (elt) { + arr.push(elt); + elt = elt.parentElement; + } + return arr; + } + function verifyPath(elt, path, requestConfig) { + let sameHost; + let url; + if (typeof URL === "function") { + url = new URL(path, document.location.href); + const origin = document.location.origin; + sameHost = origin === url.origin; + } else { + url = path; + sameHost = startsWith(path, document.location.origin); + } + if (htmx.config.selfRequestsOnly) { + if (!sameHost) { + return false; + } + } + return triggerEvent(elt, "htmx:validateUrl", mergeObjects({ url, sameHost }, requestConfig)); + } + function formDataFromObject(obj) { + if (obj instanceof FormData) + return obj; + const formData = new FormData(); + for (const key in obj) { + if (obj.hasOwnProperty(key)) { + if (typeof obj[key].forEach === "function") { + obj[key].forEach(function(v) { + formData.append(key, v); + }); + } else if (typeof obj[key] === "object") { + formData.append(key, JSON.stringify(obj[key])); + } else { + formData.append(key, obj[key]); + } + } + } + return formData; + } + function formDataArrayProxy(formData, name, array) { + return new Proxy(array, { + get: function(target, key) { + if (typeof key === "number") + return target[key]; + if (key === "length") + return target.length; + if (key === "push") { + return function(value) { + target.push(value); + formData.append(name, value); + }; + } + if (typeof target[key] === "function") { + return function() { + target[key].apply(target, arguments); + formData.delete(name); + target.forEach(function(v) { + formData.append(name, v); + }); + }; + } + if (target[key] && target[key].length === 1) { + return target[key][0]; + } else { + return target[key]; + } + }, + set: function(target, index, value) { + target[index] = value; + formData.delete(name); + target.forEach(function(v) { + formData.append(name, v); + }); + return true; + } + }); + } + function formDataProxy(formData) { + return new Proxy(formData, { + get: function(target, name) { + if (typeof name === "symbol") { + return Reflect.get(target, name); + } + if (name === "toJSON") { + return () => Object.fromEntries(formData); + } + if (name in target) { + if (typeof target[name] === "function") { + return function() { + return formData[name].apply(formData, arguments); + }; + } else { + return target[name]; + } + } + const array = formData.getAll(name); + if (array.length === 0) { + return void 0; + } else if (array.length === 1) { + return array[0]; + } else { + return formDataArrayProxy(target, name, array); + } + }, + set: function(target, name, value) { + if (typeof name !== "string") { + return false; + } + target.delete(name); + if (typeof value.forEach === "function") { + value.forEach(function(v) { + target.append(name, v); + }); + } else { + target.append(name, value); + } + return true; + }, + deleteProperty: function(target, name) { + if (typeof name === "string") { + target.delete(name); + } + return true; + }, + // Support Object.assign call from proxy + ownKeys: function(target) { + return Reflect.ownKeys(Object.fromEntries(target)); + }, + getOwnPropertyDescriptor: function(target, prop) { + return Reflect.getOwnPropertyDescriptor(Object.fromEntries(target), prop); + } + }); + } + function issueAjaxRequest(verb, path, elt, event, etc, confirmed) { + let resolve = null; + let reject = null; + etc = etc != null ? etc : {}; + if (etc.returnPromise && typeof Promise !== "undefined") { + var promise = new Promise(function(_resolve, _reject) { + resolve = _resolve; + reject = _reject; + }); + } + if (elt == null) { + elt = getDocument().body; + } + const responseHandler = etc.handler || handleAjaxResponse; + const select = etc.select || null; + if (!bodyContains(elt)) { + maybeCall(resolve); + return promise; + } + const target = etc.targetOverride || asElement(getTarget(elt)); + if (target == null || target == DUMMY_ELT) { + triggerErrorEvent(elt, "htmx:targetError", { target: getAttributeValue(elt, "hx-target") }); + maybeCall(reject); + return promise; + } + let eltData = getInternalData(elt); + const submitter = eltData.lastButtonClicked; + if (submitter) { + const buttonPath = getRawAttribute(submitter, "formaction"); + if (buttonPath != null) { + path = buttonPath; + } + const buttonVerb = getRawAttribute(submitter, "formmethod"); + if (buttonVerb != null) { + if (buttonVerb.toLowerCase() !== "dialog") { + verb = /** @type HttpVerb */ + buttonVerb; + } + } + } + const confirmQuestion = getClosestAttributeValue(elt, "hx-confirm"); + if (confirmed === void 0) { + const issueRequest = function(skipConfirmation) { + return issueAjaxRequest(verb, path, elt, event, etc, !!skipConfirmation); + }; + const confirmDetails = { target, elt, path, verb, triggeringEvent: event, etc, issueRequest, question: confirmQuestion }; + if (triggerEvent(elt, "htmx:confirm", confirmDetails) === false) { + maybeCall(resolve); + return promise; + } + } + let syncElt = elt; + let syncStrategy = getClosestAttributeValue(elt, "hx-sync"); + let queueStrategy = null; + let abortable = false; + if (syncStrategy) { + const syncStrings = syncStrategy.split(":"); + const selector = syncStrings[0].trim(); + if (selector === "this") { + syncElt = findThisElement(elt, "hx-sync"); + } else { + syncElt = asElement(querySelectorExt(elt, selector)); + } + syncStrategy = (syncStrings[1] || "drop").trim(); + eltData = getInternalData(syncElt); + if (syncStrategy === "drop" && eltData.xhr && eltData.abortable !== true) { + maybeCall(resolve); + return promise; + } else if (syncStrategy === "abort") { + if (eltData.xhr) { + maybeCall(resolve); + return promise; + } else { + abortable = true; + } + } else if (syncStrategy === "replace") { + triggerEvent(syncElt, "htmx:abort"); + } else if (syncStrategy.indexOf("queue") === 0) { + const queueStrArray = syncStrategy.split(" "); + queueStrategy = (queueStrArray[1] || "last").trim(); + } + } + if (eltData.xhr) { + if (eltData.abortable) { + triggerEvent(syncElt, "htmx:abort"); + } else { + if (queueStrategy == null) { + if (event) { + const eventData = getInternalData(event); + if (eventData && eventData.triggerSpec && eventData.triggerSpec.queue) { + queueStrategy = eventData.triggerSpec.queue; + } + } + if (queueStrategy == null) { + queueStrategy = "last"; + } + } + if (eltData.queuedRequests == null) { + eltData.queuedRequests = []; + } + if (queueStrategy === "first" && eltData.queuedRequests.length === 0) { + eltData.queuedRequests.push(function() { + issueAjaxRequest(verb, path, elt, event, etc); + }); + } else if (queueStrategy === "all") { + eltData.queuedRequests.push(function() { + issueAjaxRequest(verb, path, elt, event, etc); + }); + } else if (queueStrategy === "last") { + eltData.queuedRequests = []; + eltData.queuedRequests.push(function() { + issueAjaxRequest(verb, path, elt, event, etc); + }); + } + maybeCall(resolve); + return promise; + } + } + const xhr = new XMLHttpRequest(); + eltData.xhr = xhr; + eltData.abortable = abortable; + const endRequestLock = function() { + eltData.xhr = null; + eltData.abortable = false; + if (eltData.queuedRequests != null && eltData.queuedRequests.length > 0) { + const queuedRequest = eltData.queuedRequests.shift(); + queuedRequest(); + } + }; + const promptQuestion = getClosestAttributeValue(elt, "hx-prompt"); + if (promptQuestion) { + var promptResponse = prompt(promptQuestion); + if (promptResponse === null || !triggerEvent(elt, "htmx:prompt", { prompt: promptResponse, target })) { + maybeCall(resolve); + endRequestLock(); + return promise; + } + } + if (confirmQuestion && !confirmed) { + if (!confirm(confirmQuestion)) { + maybeCall(resolve); + endRequestLock(); + return promise; + } + } + let headers = getHeaders(elt, target, promptResponse); + if (verb !== "get" && !usesFormData(elt)) { + headers["Content-Type"] = "application/x-www-form-urlencoded"; + } + if (etc.headers) { + headers = mergeObjects(headers, etc.headers); + } + const results = getInputValues(elt, verb); + let errors = results.errors; + const rawFormData = results.formData; + if (etc.values) { + overrideFormData(rawFormData, formDataFromObject(etc.values)); + } + const expressionVars = formDataFromObject(getExpressionVars(elt)); + const allFormData = overrideFormData(rawFormData, expressionVars); + let filteredFormData = filterValues(allFormData, elt); + if (htmx.config.getCacheBusterParam && verb === "get") { + filteredFormData.set("org.htmx.cache-buster", getRawAttribute(target, "id") || "true"); + } + if (path == null || path === "") { + path = getDocument().location.href; + } + const requestAttrValues = getValuesForElement(elt, "hx-request"); + const eltIsBoosted = getInternalData(elt).boosted; + let useUrlParams = htmx.config.methodsThatUseUrlParams.indexOf(verb) >= 0; + const requestConfig = { + boosted: eltIsBoosted, + useUrlParams, + formData: filteredFormData, + parameters: formDataProxy(filteredFormData), + unfilteredFormData: allFormData, + unfilteredParameters: formDataProxy(allFormData), + headers, + target, + verb, + errors, + withCredentials: etc.credentials || requestAttrValues.credentials || htmx.config.withCredentials, + timeout: etc.timeout || requestAttrValues.timeout || htmx.config.timeout, + path, + triggeringEvent: event + }; + if (!triggerEvent(elt, "htmx:configRequest", requestConfig)) { + maybeCall(resolve); + endRequestLock(); + return promise; + } + path = requestConfig.path; + verb = requestConfig.verb; + headers = requestConfig.headers; + filteredFormData = formDataFromObject(requestConfig.parameters); + errors = requestConfig.errors; + useUrlParams = requestConfig.useUrlParams; + if (errors && errors.length > 0) { + triggerEvent(elt, "htmx:validation:halted", requestConfig); + maybeCall(resolve); + endRequestLock(); + return promise; + } + const splitPath = path.split("#"); + const pathNoAnchor = splitPath[0]; + const anchor = splitPath[1]; + let finalPath = path; + if (useUrlParams) { + finalPath = pathNoAnchor; + const hasValues = !filteredFormData.keys().next().done; + if (hasValues) { + if (finalPath.indexOf("?") < 0) { + finalPath += "?"; + } else { + finalPath += "&"; + } + finalPath += urlEncode(filteredFormData); + if (anchor) { + finalPath += "#" + anchor; + } + } + } + if (!verifyPath(elt, finalPath, requestConfig)) { + triggerErrorEvent(elt, "htmx:invalidPath", requestConfig); + maybeCall(reject); + return promise; + } + xhr.open(verb.toUpperCase(), finalPath, true); + xhr.overrideMimeType("text/html"); + xhr.withCredentials = requestConfig.withCredentials; + xhr.timeout = requestConfig.timeout; + if (requestAttrValues.noHeaders) { + } else { + for (const header in headers) { + if (headers.hasOwnProperty(header)) { + const headerValue = headers[header]; + safelySetHeaderValue(xhr, header, headerValue); + } + } + } + const responseInfo = { + xhr, + target, + requestConfig, + etc, + boosted: eltIsBoosted, + select, + pathInfo: { + requestPath: path, + finalRequestPath: finalPath, + responsePath: null, + anchor + } + }; + xhr.onload = function() { + try { + const hierarchy = hierarchyForElt(elt); + responseInfo.pathInfo.responsePath = getPathFromResponse(xhr); + responseHandler(elt, responseInfo); + removeRequestIndicators(indicators, disableElts); + triggerEvent(elt, "htmx:afterRequest", responseInfo); + triggerEvent(elt, "htmx:afterOnLoad", responseInfo); + if (!bodyContains(elt)) { + let secondaryTriggerElt = null; + while (hierarchy.length > 0 && secondaryTriggerElt == null) { + const parentEltInHierarchy = hierarchy.shift(); + if (bodyContains(parentEltInHierarchy)) { + secondaryTriggerElt = parentEltInHierarchy; + } + } + if (secondaryTriggerElt) { + triggerEvent(secondaryTriggerElt, "htmx:afterRequest", responseInfo); + triggerEvent(secondaryTriggerElt, "htmx:afterOnLoad", responseInfo); + } + } + maybeCall(resolve); + endRequestLock(); + } catch (e) { + triggerErrorEvent(elt, "htmx:onLoadError", mergeObjects({ error: e }, responseInfo)); + throw e; + } + }; + xhr.onerror = function() { + removeRequestIndicators(indicators, disableElts); + triggerErrorEvent(elt, "htmx:afterRequest", responseInfo); + triggerErrorEvent(elt, "htmx:sendError", responseInfo); + maybeCall(reject); + endRequestLock(); + }; + xhr.onabort = function() { + removeRequestIndicators(indicators, disableElts); + triggerErrorEvent(elt, "htmx:afterRequest", responseInfo); + triggerErrorEvent(elt, "htmx:sendAbort", responseInfo); + maybeCall(reject); + endRequestLock(); + }; + xhr.ontimeout = function() { + removeRequestIndicators(indicators, disableElts); + triggerErrorEvent(elt, "htmx:afterRequest", responseInfo); + triggerErrorEvent(elt, "htmx:timeout", responseInfo); + maybeCall(reject); + endRequestLock(); + }; + if (!triggerEvent(elt, "htmx:beforeRequest", responseInfo)) { + maybeCall(resolve); + endRequestLock(); + return promise; + } + var indicators = addRequestIndicatorClasses(elt); + var disableElts = disableElements(elt); + forEach(["loadstart", "loadend", "progress", "abort"], function(eventName) { + forEach([xhr, xhr.upload], function(target2) { + target2.addEventListener(eventName, function(event2) { + triggerEvent(elt, "htmx:xhr:" + eventName, { + lengthComputable: event2.lengthComputable, + loaded: event2.loaded, + total: event2.total + }); + }); + }); + }); + triggerEvent(elt, "htmx:beforeSend", responseInfo); + const params = useUrlParams ? null : encodeParamsForBody(xhr, elt, filteredFormData); + xhr.send(params); + return promise; + } + function determineHistoryUpdates(elt, responseInfo) { + const xhr = responseInfo.xhr; + let pathFromHeaders = null; + let typeFromHeaders = null; + if (hasHeader(xhr, /HX-Push:/i)) { + pathFromHeaders = xhr.getResponseHeader("HX-Push"); + typeFromHeaders = "push"; + } else if (hasHeader(xhr, /HX-Push-Url:/i)) { + pathFromHeaders = xhr.getResponseHeader("HX-Push-Url"); + typeFromHeaders = "push"; + } else if (hasHeader(xhr, /HX-Replace-Url:/i)) { + pathFromHeaders = xhr.getResponseHeader("HX-Replace-Url"); + typeFromHeaders = "replace"; + } + if (pathFromHeaders) { + if (pathFromHeaders === "false") { + return {}; + } else { + return { + type: typeFromHeaders, + path: pathFromHeaders + }; + } + } + const requestPath = responseInfo.pathInfo.finalRequestPath; + const responsePath = responseInfo.pathInfo.responsePath; + const pushUrl = getClosestAttributeValue(elt, "hx-push-url"); + const replaceUrl = getClosestAttributeValue(elt, "hx-replace-url"); + const elementIsBoosted = getInternalData(elt).boosted; + let saveType = null; + let path = null; + if (pushUrl) { + saveType = "push"; + path = pushUrl; + } else if (replaceUrl) { + saveType = "replace"; + path = replaceUrl; + } else if (elementIsBoosted) { + saveType = "push"; + path = responsePath || requestPath; + } + if (path) { + if (path === "false") { + return {}; + } + if (path === "true") { + path = responsePath || requestPath; + } + if (responseInfo.pathInfo.anchor && path.indexOf("#") === -1) { + path = path + "#" + responseInfo.pathInfo.anchor; + } + return { + type: saveType, + path + }; + } else { + return {}; + } + } + function codeMatches(responseHandlingConfig, status) { + var regExp = new RegExp(responseHandlingConfig.code); + return regExp.test(status.toString(10)); + } + function resolveResponseHandling(xhr) { + for (var i = 0; i < htmx.config.responseHandling.length; i++) { + var responseHandlingElement = htmx.config.responseHandling[i]; + if (codeMatches(responseHandlingElement, xhr.status)) { + return responseHandlingElement; + } + } + return { + swap: false + }; + } + function handleTitle(title) { + if (title) { + const titleElt = find("title"); + if (titleElt) { + titleElt.innerHTML = title; + } else { + window.document.title = title; + } + } + } + function handleAjaxResponse(elt, responseInfo) { + const xhr = responseInfo.xhr; + let target = responseInfo.target; + const etc = responseInfo.etc; + const responseInfoSelect = responseInfo.select; + if (!triggerEvent(elt, "htmx:beforeOnLoad", responseInfo)) + return; + if (hasHeader(xhr, /HX-Trigger:/i)) { + handleTriggerHeader(xhr, "HX-Trigger", elt); + } + if (hasHeader(xhr, /HX-Location:/i)) { + saveCurrentPageToHistory(); + let redirectPath = xhr.getResponseHeader("HX-Location"); + var redirectSwapSpec; + if (redirectPath.indexOf("{") === 0) { + redirectSwapSpec = parseJSON(redirectPath); + redirectPath = redirectSwapSpec.path; + delete redirectSwapSpec.path; + } + ajaxHelper("get", redirectPath, redirectSwapSpec).then(function() { + pushUrlIntoHistory(redirectPath); + }); + return; + } + const shouldRefresh = hasHeader(xhr, /HX-Refresh:/i) && xhr.getResponseHeader("HX-Refresh") === "true"; + if (hasHeader(xhr, /HX-Redirect:/i)) { + location.href = xhr.getResponseHeader("HX-Redirect"); + shouldRefresh && location.reload(); + return; + } + if (shouldRefresh) { + location.reload(); + return; + } + if (hasHeader(xhr, /HX-Retarget:/i)) { + if (xhr.getResponseHeader("HX-Retarget") === "this") { + responseInfo.target = elt; + } else { + responseInfo.target = asElement(querySelectorExt(elt, xhr.getResponseHeader("HX-Retarget"))); + } + } + const historyUpdate = determineHistoryUpdates(elt, responseInfo); + const responseHandling = resolveResponseHandling(xhr); + const shouldSwap = responseHandling.swap; + let isError = !!responseHandling.error; + let ignoreTitle = htmx.config.ignoreTitle || responseHandling.ignoreTitle; + let selectOverride = responseHandling.select; + if (responseHandling.target) { + responseInfo.target = asElement(querySelectorExt(elt, responseHandling.target)); + } + var swapOverride = etc.swapOverride; + if (swapOverride == null && responseHandling.swapOverride) { + swapOverride = responseHandling.swapOverride; + } + if (hasHeader(xhr, /HX-Retarget:/i)) { + if (xhr.getResponseHeader("HX-Retarget") === "this") { + responseInfo.target = elt; + } else { + responseInfo.target = asElement(querySelectorExt(elt, xhr.getResponseHeader("HX-Retarget"))); + } + } + if (hasHeader(xhr, /HX-Reswap:/i)) { + swapOverride = xhr.getResponseHeader("HX-Reswap"); + } + var serverResponse = xhr.response; + var beforeSwapDetails = mergeObjects({ + shouldSwap, + serverResponse, + isError, + ignoreTitle, + selectOverride + }, responseInfo); + if (responseHandling.event && !triggerEvent(target, responseHandling.event, beforeSwapDetails)) + return; + if (!triggerEvent(target, "htmx:beforeSwap", beforeSwapDetails)) + return; + target = beforeSwapDetails.target; + serverResponse = beforeSwapDetails.serverResponse; + isError = beforeSwapDetails.isError; + ignoreTitle = beforeSwapDetails.ignoreTitle; + selectOverride = beforeSwapDetails.selectOverride; + responseInfo.target = target; + responseInfo.failed = isError; + responseInfo.successful = !isError; + if (beforeSwapDetails.shouldSwap) { + if (xhr.status === 286) { + cancelPolling(elt); + } + withExtensions(elt, function(extension) { + serverResponse = extension.transformResponse(serverResponse, xhr, elt); + }); + if (historyUpdate.type) { + saveCurrentPageToHistory(); + } + if (hasHeader(xhr, /HX-Reswap:/i)) { + swapOverride = xhr.getResponseHeader("HX-Reswap"); + } + var swapSpec = getSwapSpecification(elt, swapOverride); + if (!swapSpec.hasOwnProperty("ignoreTitle")) { + swapSpec.ignoreTitle = ignoreTitle; + } + target.classList.add(htmx.config.swappingClass); + let settleResolve = null; + let settleReject = null; + if (responseInfoSelect) { + selectOverride = responseInfoSelect; + } + if (hasHeader(xhr, /HX-Reselect:/i)) { + selectOverride = xhr.getResponseHeader("HX-Reselect"); + } + const selectOOB = getClosestAttributeValue(elt, "hx-select-oob"); + const select = getClosestAttributeValue(elt, "hx-select"); + let doSwap = function() { + try { + if (historyUpdate.type) { + triggerEvent(getDocument().body, "htmx:beforeHistoryUpdate", mergeObjects({ history: historyUpdate }, responseInfo)); + if (historyUpdate.type === "push") { + pushUrlIntoHistory(historyUpdate.path); + triggerEvent(getDocument().body, "htmx:pushedIntoHistory", { path: historyUpdate.path }); + } else { + replaceUrlInHistory(historyUpdate.path); + triggerEvent(getDocument().body, "htmx:replacedInHistory", { path: historyUpdate.path }); + } + } + swap(target, serverResponse, swapSpec, { + select: selectOverride || select, + selectOOB, + eventInfo: responseInfo, + anchor: responseInfo.pathInfo.anchor, + contextElement: elt, + afterSwapCallback: function() { + if (hasHeader(xhr, /HX-Trigger-After-Swap:/i)) { + let finalElt = elt; + if (!bodyContains(elt)) { + finalElt = getDocument().body; + } + handleTriggerHeader(xhr, "HX-Trigger-After-Swap", finalElt); + } + }, + afterSettleCallback: function() { + if (hasHeader(xhr, /HX-Trigger-After-Settle:/i)) { + let finalElt = elt; + if (!bodyContains(elt)) { + finalElt = getDocument().body; + } + handleTriggerHeader(xhr, "HX-Trigger-After-Settle", finalElt); + } + maybeCall(settleResolve); + } + }); + } catch (e) { + triggerErrorEvent(elt, "htmx:swapError", responseInfo); + maybeCall(settleReject); + throw e; + } + }; + let shouldTransition = htmx.config.globalViewTransitions; + if (swapSpec.hasOwnProperty("transition")) { + shouldTransition = swapSpec.transition; + } + if (shouldTransition && triggerEvent(elt, "htmx:beforeTransition", responseInfo) && typeof Promise !== "undefined" && // @ts-ignore experimental feature atm + document.startViewTransition) { + const settlePromise = new Promise(function(_resolve, _reject) { + settleResolve = _resolve; + settleReject = _reject; + }); + const innerDoSwap = doSwap; + doSwap = function() { + document.startViewTransition(function() { + innerDoSwap(); + return settlePromise; + }); + }; + } + if (swapSpec.swapDelay > 0) { + getWindow().setTimeout(doSwap, swapSpec.swapDelay); + } else { + doSwap(); + } + } + if (isError) { + triggerErrorEvent(elt, "htmx:responseError", mergeObjects({ error: "Response Status Error Code " + xhr.status + " from " + responseInfo.pathInfo.requestPath }, responseInfo)); + } + } + const extensions = {}; + function extensionBase() { + return { + init: function(api) { + return null; + }, + getSelectors: function() { + return null; + }, + onEvent: function(name, evt) { + return true; + }, + transformResponse: function(text, xhr, elt) { + return text; + }, + isInlineSwap: function(swapStyle) { + return false; + }, + handleSwap: function(swapStyle, target, fragment, settleInfo) { + return false; + }, + encodeParameters: function(xhr, parameters, elt) { + return null; + } + }; + } + function defineExtension(name, extension) { + if (extension.init) { + extension.init(internalAPI); + } + extensions[name] = mergeObjects(extensionBase(), extension); + } + function removeExtension(name) { + delete extensions[name]; + } + function getExtensions(elt, extensionsToReturn, extensionsToIgnore) { + if (extensionsToReturn == void 0) { + extensionsToReturn = []; + } + if (elt == void 0) { + return extensionsToReturn; + } + if (extensionsToIgnore == void 0) { + extensionsToIgnore = []; + } + const extensionsForElement = getAttributeValue(elt, "hx-ext"); + if (extensionsForElement) { + forEach(extensionsForElement.split(","), function(extensionName) { + extensionName = extensionName.replace(/ /g, ""); + if (extensionName.slice(0, 7) == "ignore:") { + extensionsToIgnore.push(extensionName.slice(7)); + return; + } + if (extensionsToIgnore.indexOf(extensionName) < 0) { + const extension = extensions[extensionName]; + if (extension && extensionsToReturn.indexOf(extension) < 0) { + extensionsToReturn.push(extension); + } + } + }); + } + return getExtensions(asElement(parentElt(elt)), extensionsToReturn, extensionsToIgnore); + } + var isReady = false; + getDocument().addEventListener("DOMContentLoaded", function() { + isReady = true; + }); + function ready(fn) { + if (isReady || getDocument().readyState === "complete") { + fn(); + } else { + getDocument().addEventListener("DOMContentLoaded", fn); + } + } + function insertIndicatorStyles() { + if (htmx.config.includeIndicatorStyles !== false) { + const nonceAttribute = htmx.config.inlineStyleNonce ? ` nonce="${htmx.config.inlineStyleNonce}"` : ""; + getDocument().head.insertAdjacentHTML( + "beforeend", + "" + ); + } + } + function getMetaConfig() { + const element = getDocument().querySelector('meta[name="htmx-config"]'); + if (element) { + return parseJSON(element.content); + } else { + return null; + } + } + function mergeMetaConfig() { + const metaConfig = getMetaConfig(); + if (metaConfig) { + htmx.config = mergeObjects(htmx.config, metaConfig); + } + } + ready(function() { + mergeMetaConfig(); + insertIndicatorStyles(); + let body = getDocument().body; + processNode(body); + const restoredElts = getDocument().querySelectorAll( + "[hx-trigger='restored'],[data-hx-trigger='restored']" + ); + body.addEventListener("htmx:abort", function(evt) { + const target = evt.target; + const internalData = getInternalData(target); + if (internalData && internalData.xhr) { + internalData.xhr.abort(); + } + }); + const originalPopstate = window.onpopstate ? window.onpopstate.bind(window) : null; + window.onpopstate = function(event) { + if (event.state && event.state.htmx) { + restoreHistory(); + forEach(restoredElts, function(elt) { + triggerEvent(elt, "htmx:restored", { + document: getDocument(), + triggerEvent + }); + }); + } else { + if (originalPopstate) { + originalPopstate(event); + } + } + }; + getWindow().setTimeout(function() { + triggerEvent(body, "htmx:load", {}); + body = null; + }, 0); + }); + return htmx; + }(); + var htmx_esm_default = htmx2; + + // node_modules/alpinejs/dist/module.esm.js + var flushPending = false; + var flushing = false; + var queue = []; + var lastFlushedIndex = -1; + function scheduler(callback) { + queueJob(callback); + } + function queueJob(job) { + if (!queue.includes(job)) + queue.push(job); + queueFlush(); + } + function dequeueJob(job) { + let index = queue.indexOf(job); + if (index !== -1 && index > lastFlushedIndex) + queue.splice(index, 1); + } + function queueFlush() { + if (!flushing && !flushPending) { + flushPending = true; + queueMicrotask(flushJobs); + } + } + function flushJobs() { + flushPending = false; + flushing = true; + for (let i = 0; i < queue.length; i++) { + queue[i](); + lastFlushedIndex = i; + } + queue.length = 0; + lastFlushedIndex = -1; + flushing = false; + } + var reactive; + var effect; + var release; + var raw; + var shouldSchedule = true; + function disableEffectScheduling(callback) { + shouldSchedule = false; + callback(); + shouldSchedule = true; + } + function setReactivityEngine(engine) { + reactive = engine.reactive; + release = engine.release; + effect = (callback) => engine.effect(callback, { scheduler: (task) => { + if (shouldSchedule) { + scheduler(task); + } else { + task(); + } + } }); + raw = engine.raw; + } + function overrideEffect(override) { + effect = override; + } + function elementBoundEffect(el) { + let cleanup2 = () => { + }; + let wrappedEffect = (callback) => { + let effectReference = effect(callback); + if (!el._x_effects) { + el._x_effects = /* @__PURE__ */ new Set(); + el._x_runEffects = () => { + el._x_effects.forEach((i) => i()); + }; + } + el._x_effects.add(effectReference); + cleanup2 = () => { + if (effectReference === void 0) + return; + el._x_effects.delete(effectReference); + release(effectReference); + }; + return effectReference; + }; + return [wrappedEffect, () => { + cleanup2(); + }]; + } + function watch(getter, callback) { + let firstTime = true; + let oldValue; + let effectReference = effect(() => { + let value = getter(); + JSON.stringify(value); + if (!firstTime) { + queueMicrotask(() => { + callback(value, oldValue); + oldValue = value; + }); + } else { + oldValue = value; + } + firstTime = false; + }); + return () => release(effectReference); + } + var onAttributeAddeds = []; + var onElRemoveds = []; + var onElAddeds = []; + function onElAdded(callback) { + onElAddeds.push(callback); + } + function onElRemoved(el, callback) { + if (typeof callback === "function") { + if (!el._x_cleanups) + el._x_cleanups = []; + el._x_cleanups.push(callback); + } else { + callback = el; + onElRemoveds.push(callback); + } + } + function onAttributesAdded(callback) { + onAttributeAddeds.push(callback); + } + function onAttributeRemoved(el, name, callback) { + if (!el._x_attributeCleanups) + el._x_attributeCleanups = {}; + if (!el._x_attributeCleanups[name]) + el._x_attributeCleanups[name] = []; + el._x_attributeCleanups[name].push(callback); + } + function cleanupAttributes(el, names) { + if (!el._x_attributeCleanups) + return; + Object.entries(el._x_attributeCleanups).forEach(([name, value]) => { + if (names === void 0 || names.includes(name)) { + value.forEach((i) => i()); + delete el._x_attributeCleanups[name]; + } + }); + } + function cleanupElement(el) { + if (el._x_cleanups) { + while (el._x_cleanups.length) + el._x_cleanups.pop()(); + } + } + var observer = new MutationObserver(onMutate); + var currentlyObserving = false; + function startObservingMutations() { + observer.observe(document, { subtree: true, childList: true, attributes: true, attributeOldValue: true }); + currentlyObserving = true; + } + function stopObservingMutations() { + flushObserver(); + observer.disconnect(); + currentlyObserving = false; + } + var queuedMutations = []; + function flushObserver() { + let records = observer.takeRecords(); + queuedMutations.push(() => records.length > 0 && onMutate(records)); + let queueLengthWhenTriggered = queuedMutations.length; + queueMicrotask(() => { + if (queuedMutations.length === queueLengthWhenTriggered) { + while (queuedMutations.length > 0) + queuedMutations.shift()(); + } + }); + } + function mutateDom(callback) { + if (!currentlyObserving) + return callback(); + stopObservingMutations(); + let result = callback(); + startObservingMutations(); + return result; + } + var isCollecting = false; + var deferredMutations = []; + function deferMutations() { + isCollecting = true; + } + function flushAndStopDeferringMutations() { + isCollecting = false; + onMutate(deferredMutations); + deferredMutations = []; + } + function onMutate(mutations) { + if (isCollecting) { + deferredMutations = deferredMutations.concat(mutations); + return; + } + let addedNodes = /* @__PURE__ */ new Set(); + let removedNodes = /* @__PURE__ */ new Set(); + let addedAttributes = /* @__PURE__ */ new Map(); + let removedAttributes = /* @__PURE__ */ new Map(); + for (let i = 0; i < mutations.length; i++) { + if (mutations[i].target._x_ignoreMutationObserver) + continue; + if (mutations[i].type === "childList") { + mutations[i].addedNodes.forEach((node) => node.nodeType === 1 && addedNodes.add(node)); + mutations[i].removedNodes.forEach((node) => node.nodeType === 1 && removedNodes.add(node)); + } + if (mutations[i].type === "attributes") { + let el = mutations[i].target; + let name = mutations[i].attributeName; + let oldValue = mutations[i].oldValue; + let add2 = () => { + if (!addedAttributes.has(el)) + addedAttributes.set(el, []); + addedAttributes.get(el).push({ name, value: el.getAttribute(name) }); + }; + let remove = () => { + if (!removedAttributes.has(el)) + removedAttributes.set(el, []); + removedAttributes.get(el).push(name); + }; + if (el.hasAttribute(name) && oldValue === null) { + add2(); + } else if (el.hasAttribute(name)) { + remove(); + add2(); + } else { + remove(); + } + } + } + removedAttributes.forEach((attrs, el) => { + cleanupAttributes(el, attrs); + }); + addedAttributes.forEach((attrs, el) => { + onAttributeAddeds.forEach((i) => i(el, attrs)); + }); + for (let node of removedNodes) { + if (addedNodes.has(node)) + continue; + onElRemoveds.forEach((i) => i(node)); + } + addedNodes.forEach((node) => { + node._x_ignoreSelf = true; + node._x_ignore = true; + }); + for (let node of addedNodes) { + if (removedNodes.has(node)) + continue; + if (!node.isConnected) + continue; + delete node._x_ignoreSelf; + delete node._x_ignore; + onElAddeds.forEach((i) => i(node)); + node._x_ignore = true; + node._x_ignoreSelf = true; + } + addedNodes.forEach((node) => { + delete node._x_ignoreSelf; + delete node._x_ignore; + }); + addedNodes = null; + removedNodes = null; + addedAttributes = null; + removedAttributes = null; + } + function scope(node) { + return mergeProxies(closestDataStack(node)); + } + function addScopeToNode(node, data2, referenceNode) { + node._x_dataStack = [data2, ...closestDataStack(referenceNode || node)]; + return () => { + node._x_dataStack = node._x_dataStack.filter((i) => i !== data2); + }; + } + function closestDataStack(node) { + if (node._x_dataStack) + return node._x_dataStack; + if (typeof ShadowRoot === "function" && node instanceof ShadowRoot) { + return closestDataStack(node.host); + } + if (!node.parentNode) { + return []; + } + return closestDataStack(node.parentNode); + } + function mergeProxies(objects) { + return new Proxy({ objects }, mergeProxyTrap); + } + var mergeProxyTrap = { + ownKeys({ objects }) { + return Array.from( + new Set(objects.flatMap((i) => Object.keys(i))) + ); + }, + has({ objects }, name) { + if (name == Symbol.unscopables) + return false; + return objects.some( + (obj) => Object.prototype.hasOwnProperty.call(obj, name) || Reflect.has(obj, name) + ); + }, + get({ objects }, name, thisProxy) { + if (name == "toJSON") + return collapseProxies; + return Reflect.get( + objects.find( + (obj) => Reflect.has(obj, name) + ) || {}, + name, + thisProxy + ); + }, + set({ objects }, name, value, thisProxy) { + const target = objects.find( + (obj) => Object.prototype.hasOwnProperty.call(obj, name) + ) || objects[objects.length - 1]; + const descriptor = Object.getOwnPropertyDescriptor(target, name); + if (descriptor?.set && descriptor?.get) + return descriptor.set.call(thisProxy, value) || true; + return Reflect.set(target, name, value); + } + }; + function collapseProxies() { + let keys = Reflect.ownKeys(this); + return keys.reduce((acc, key) => { + acc[key] = Reflect.get(this, key); + return acc; + }, {}); + } + function initInterceptors(data2) { + let isObject2 = (val) => typeof val === "object" && !Array.isArray(val) && val !== null; + let recurse = (obj, basePath = "") => { + Object.entries(Object.getOwnPropertyDescriptors(obj)).forEach(([key, { value, enumerable }]) => { + if (enumerable === false || value === void 0) + return; + if (typeof value === "object" && value !== null && value.__v_skip) + return; + let path = basePath === "" ? key : `${basePath}.${key}`; + if (typeof value === "object" && value !== null && value._x_interceptor) { + obj[key] = value.initialize(data2, path, key); + } else { + if (isObject2(value) && value !== obj && !(value instanceof Element)) { + recurse(value, path); + } + } + }); + }; + return recurse(data2); + } + function interceptor(callback, mutateObj = () => { + }) { + let obj = { + initialValue: void 0, + _x_interceptor: true, + initialize(data2, path, key) { + return callback(this.initialValue, () => get(data2, path), (value) => set(data2, path, value), path, key); + } + }; + mutateObj(obj); + return (initialValue) => { + if (typeof initialValue === "object" && initialValue !== null && initialValue._x_interceptor) { + let initialize = obj.initialize.bind(obj); + obj.initialize = (data2, path, key) => { + let innerValue = initialValue.initialize(data2, path, key); + obj.initialValue = innerValue; + return initialize(data2, path, key); + }; + } else { + obj.initialValue = initialValue; + } + return obj; + }; + } + function get(obj, path) { + return path.split(".").reduce((carry, segment) => carry[segment], obj); + } + function set(obj, path, value) { + if (typeof path === "string") + path = path.split("."); + if (path.length === 1) + obj[path[0]] = value; + else if (path.length === 0) + throw error; + else { + if (obj[path[0]]) + return set(obj[path[0]], path.slice(1), value); + else { + obj[path[0]] = {}; + return set(obj[path[0]], path.slice(1), value); + } + } + } + var magics = {}; + function magic(name, callback) { + magics[name] = callback; + } + function injectMagics(obj, el) { + Object.entries(magics).forEach(([name, callback]) => { + let memoizedUtilities = null; + function getUtilities() { + if (memoizedUtilities) { + return memoizedUtilities; + } else { + let [utilities, cleanup2] = getElementBoundUtilities(el); + memoizedUtilities = { interceptor, ...utilities }; + onElRemoved(el, cleanup2); + return memoizedUtilities; + } + } + Object.defineProperty(obj, `$${name}`, { + get() { + return callback(el, getUtilities()); + }, + enumerable: false + }); + }); + return obj; + } + function tryCatch(el, expression, callback, ...args) { + try { + return callback(...args); + } catch (e) { + handleError(e, el, expression); + } + } + function handleError(error2, el, expression = void 0) { + error2 = Object.assign( + error2 ?? { message: "No error message given." }, + { el, expression } + ); + console.warn(`Alpine Expression Error: ${error2.message} + +${expression ? 'Expression: "' + expression + '"\n\n' : ""}`, el); + setTimeout(() => { + throw error2; + }, 0); + } + var shouldAutoEvaluateFunctions = true; + function dontAutoEvaluateFunctions(callback) { + let cache = shouldAutoEvaluateFunctions; + shouldAutoEvaluateFunctions = false; + let result = callback(); + shouldAutoEvaluateFunctions = cache; + return result; + } + function evaluate(el, expression, extras = {}) { + let result; + evaluateLater(el, expression)((value) => result = value, extras); + return result; + } + function evaluateLater(...args) { + return theEvaluatorFunction(...args); + } + var theEvaluatorFunction = normalEvaluator; + function setEvaluator(newEvaluator) { + theEvaluatorFunction = newEvaluator; + } + function normalEvaluator(el, expression) { + let overriddenMagics = {}; + injectMagics(overriddenMagics, el); + let dataStack = [overriddenMagics, ...closestDataStack(el)]; + let evaluator = typeof expression === "function" ? generateEvaluatorFromFunction(dataStack, expression) : generateEvaluatorFromString(dataStack, expression, el); + return tryCatch.bind(null, el, expression, evaluator); + } + function generateEvaluatorFromFunction(dataStack, func) { + return (receiver = () => { + }, { scope: scope2 = {}, params = [] } = {}) => { + let result = func.apply(mergeProxies([scope2, ...dataStack]), params); + runIfTypeOfFunction(receiver, result); + }; + } + var evaluatorMemo = {}; + function generateFunctionFromString(expression, el) { + if (evaluatorMemo[expression]) { + return evaluatorMemo[expression]; + } + let AsyncFunction = Object.getPrototypeOf(async function() { + }).constructor; + let rightSideSafeExpression = /^[\n\s]*if.*\(.*\)/.test(expression.trim()) || /^(let|const)\s/.test(expression.trim()) ? `(async()=>{ ${expression} })()` : expression; + const safeAsyncFunction = () => { + try { + let func2 = new AsyncFunction( + ["__self", "scope"], + `with (scope) { __self.result = ${rightSideSafeExpression} }; __self.finished = true; return __self.result;` + ); + Object.defineProperty(func2, "name", { + value: `[Alpine] ${expression}` + }); + return func2; + } catch (error2) { + handleError(error2, el, expression); + return Promise.resolve(); + } + }; + let func = safeAsyncFunction(); + evaluatorMemo[expression] = func; + return func; + } + function generateEvaluatorFromString(dataStack, expression, el) { + let func = generateFunctionFromString(expression, el); + return (receiver = () => { + }, { scope: scope2 = {}, params = [] } = {}) => { + func.result = void 0; + func.finished = false; + let completeScope = mergeProxies([scope2, ...dataStack]); + if (typeof func === "function") { + let promise = func(func, completeScope).catch((error2) => handleError(error2, el, expression)); + if (func.finished) { + runIfTypeOfFunction(receiver, func.result, completeScope, params, el); + func.result = void 0; + } else { + promise.then((result) => { + runIfTypeOfFunction(receiver, result, completeScope, params, el); + }).catch((error2) => handleError(error2, el, expression)).finally(() => func.result = void 0); + } + } + }; + } + function runIfTypeOfFunction(receiver, value, scope2, params, el) { + if (shouldAutoEvaluateFunctions && typeof value === "function") { + let result = value.apply(scope2, params); + if (result instanceof Promise) { + result.then((i) => runIfTypeOfFunction(receiver, i, scope2, params)).catch((error2) => handleError(error2, el, value)); + } else { + receiver(result); + } + } else if (typeof value === "object" && value instanceof Promise) { + value.then((i) => receiver(i)); + } else { + receiver(value); + } + } + var prefixAsString = "x-"; + function prefix(subject = "") { + return prefixAsString + subject; + } + function setPrefix(newPrefix) { + prefixAsString = newPrefix; + } + var directiveHandlers = {}; + function directive(name, callback) { + directiveHandlers[name] = callback; + return { + before(directive2) { + if (!directiveHandlers[directive2]) { + console.warn(String.raw`Cannot find directive \`${directive2}\`. \`${name}\` will use the default order of execution`); + return; + } + const pos = directiveOrder.indexOf(directive2); + directiveOrder.splice(pos >= 0 ? pos : directiveOrder.indexOf("DEFAULT"), 0, name); + } + }; + } + function directiveExists(name) { + return Object.keys(directiveHandlers).includes(name); + } + function directives(el, attributes, originalAttributeOverride) { + attributes = Array.from(attributes); + if (el._x_virtualDirectives) { + let vAttributes = Object.entries(el._x_virtualDirectives).map(([name, value]) => ({ name, value })); + let staticAttributes = attributesOnly(vAttributes); + vAttributes = vAttributes.map((attribute) => { + if (staticAttributes.find((attr) => attr.name === attribute.name)) { + return { + name: `x-bind:${attribute.name}`, + value: `"${attribute.value}"` + }; + } + return attribute; + }); + attributes = attributes.concat(vAttributes); + } + let transformedAttributeMap = {}; + let directives2 = attributes.map(toTransformedAttributes((newName, oldName) => transformedAttributeMap[newName] = oldName)).filter(outNonAlpineAttributes).map(toParsedDirectives(transformedAttributeMap, originalAttributeOverride)).sort(byPriority); + return directives2.map((directive2) => { + return getDirectiveHandler(el, directive2); + }); + } + function attributesOnly(attributes) { + return Array.from(attributes).map(toTransformedAttributes()).filter((attr) => !outNonAlpineAttributes(attr)); + } + var isDeferringHandlers = false; + var directiveHandlerStacks = /* @__PURE__ */ new Map(); + var currentHandlerStackKey = Symbol(); + function deferHandlingDirectives(callback) { + isDeferringHandlers = true; + let key = Symbol(); + currentHandlerStackKey = key; + directiveHandlerStacks.set(key, []); + let flushHandlers = () => { + while (directiveHandlerStacks.get(key).length) + directiveHandlerStacks.get(key).shift()(); + directiveHandlerStacks.delete(key); + }; + let stopDeferring = () => { + isDeferringHandlers = false; + flushHandlers(); + }; + callback(flushHandlers); + stopDeferring(); + } + function getElementBoundUtilities(el) { + let cleanups = []; + let cleanup2 = (callback) => cleanups.push(callback); + let [effect3, cleanupEffect] = elementBoundEffect(el); + cleanups.push(cleanupEffect); + let utilities = { + Alpine: alpine_default, + effect: effect3, + cleanup: cleanup2, + evaluateLater: evaluateLater.bind(evaluateLater, el), + evaluate: evaluate.bind(evaluate, el) + }; + let doCleanup = () => cleanups.forEach((i) => i()); + return [utilities, doCleanup]; + } + function getDirectiveHandler(el, directive2) { + let noop = () => { + }; + let handler4 = directiveHandlers[directive2.type] || noop; + let [utilities, cleanup2] = getElementBoundUtilities(el); + onAttributeRemoved(el, directive2.original, cleanup2); + let fullHandler = () => { + if (el._x_ignore || el._x_ignoreSelf) + return; + handler4.inline && handler4.inline(el, directive2, utilities); + handler4 = handler4.bind(handler4, el, directive2, utilities); + isDeferringHandlers ? directiveHandlerStacks.get(currentHandlerStackKey).push(handler4) : handler4(); + }; + fullHandler.runCleanups = cleanup2; + return fullHandler; + } + var startingWith = (subject, replacement) => ({ name, value }) => { + if (name.startsWith(subject)) + name = name.replace(subject, replacement); + return { name, value }; + }; + var into = (i) => i; + function toTransformedAttributes(callback = () => { + }) { + return ({ name, value }) => { + let { name: newName, value: newValue } = attributeTransformers.reduce((carry, transform) => { + return transform(carry); + }, { name, value }); + if (newName !== name) + callback(newName, name); + return { name: newName, value: newValue }; + }; + } + var attributeTransformers = []; + function mapAttributes(callback) { + attributeTransformers.push(callback); + } + function outNonAlpineAttributes({ name }) { + return alpineAttributeRegex().test(name); + } + var alpineAttributeRegex = () => new RegExp(`^${prefixAsString}([^:^.]+)\\b`); + function toParsedDirectives(transformedAttributeMap, originalAttributeOverride) { + return ({ name, value }) => { + let typeMatch = name.match(alpineAttributeRegex()); + let valueMatch = name.match(/:([a-zA-Z0-9\-_:]+)/); + let modifiers = name.match(/\.[^.\]]+(?=[^\]]*$)/g) || []; + let original = originalAttributeOverride || transformedAttributeMap[name] || name; + return { + type: typeMatch ? typeMatch[1] : null, + value: valueMatch ? valueMatch[1] : null, + modifiers: modifiers.map((i) => i.replace(".", "")), + expression: value, + original + }; + }; + } + var DEFAULT = "DEFAULT"; + var directiveOrder = [ + "ignore", + "ref", + "data", + "id", + "anchor", + "bind", + "init", + "for", + "model", + "modelable", + "transition", + "show", + "if", + DEFAULT, + "teleport" + ]; + function byPriority(a, b) { + let typeA = directiveOrder.indexOf(a.type) === -1 ? DEFAULT : a.type; + let typeB = directiveOrder.indexOf(b.type) === -1 ? DEFAULT : b.type; + return directiveOrder.indexOf(typeA) - directiveOrder.indexOf(typeB); + } + function dispatch(el, name, detail = {}) { + el.dispatchEvent( + new CustomEvent(name, { + detail, + bubbles: true, + // Allows events to pass the shadow DOM barrier. + composed: true, + cancelable: true + }) + ); + } + function walk(el, callback) { + if (typeof ShadowRoot === "function" && el instanceof ShadowRoot) { + Array.from(el.children).forEach((el2) => walk(el2, callback)); + return; + } + let skip = false; + callback(el, () => skip = true); + if (skip) + return; + let node = el.firstElementChild; + while (node) { + walk(node, callback, false); + node = node.nextElementSibling; + } + } + function warn(message, ...args) { + console.warn(`Alpine Warning: ${message}`, ...args); + } + var started = false; + function start() { + if (started) + warn("Alpine has already been initialized on this page. Calling Alpine.start() more than once can cause problems."); + started = true; + if (!document.body) + warn("Unable to initialize. Trying to load Alpine before `` is available. Did you forget to add `defer` in Alpine's ` + ++ This page doesn't exist +
+ + + Go Home + +