summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--default.nix2
-rw-r--r--go.mod8
-rw-r--r--go.sum12
-rw-r--r--roseh.moe.go370
-rw-r--r--static/styles.css12
-rw-r--r--templates/cmd-index.html.template4
-rw-r--r--templates/games/index.html.template6
-rw-r--r--templates/games/rms.html.template4
-rw-r--r--templates/index.html.template6
-rw-r--r--templates/login.html.template6
-rw-r--r--templates/mart/girl.html.template15
-rw-r--r--templates/mart/index.html.template14
-rw-r--r--templates/mart/set.html.template13
-rw-r--r--templates/note.html.template4
-rw-r--r--templates/outline.html.template4
-rw-r--r--templates/pkg-index.html.template4
-rw-r--r--templates/wormhole-success.html.template6
-rw-r--r--templates/wormhole.html.template4
18 files changed, 31 insertions, 463 deletions
diff --git a/default.nix b/default.nix
index 5f1c55c..5fcf54b 100644
--- a/default.nix
+++ b/default.nix
@@ -16,5 +16,5 @@ pkgs.buildGoModule rec {
# remember to bump this hash when your dependencies change.
# vendorHash = pkgs.lib.fakeHash;
- vendorHash = "sha256-TPaZ5FzBJ/t+kuJPRZCYU0A4RL4ksg0J+5jzddkGWJI=";
+ vendorHash = "sha256-NGersrCh0dQfMqf31Pq0dDCcx7ywokjmSaHaJCW6+Zo=";
}
diff --git a/go.mod b/go.mod
index 607feb7..b8e9c15 100644
--- a/go.mod
+++ b/go.mod
@@ -1,14 +1,12 @@
module roseh.moe/pkg/roseh.moe
-go 1.25.0
+go 1.25
require (
- github.com/mattn/go-sqlite3 v1.14.50
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
- golang.org/x/image v0.45.0
- golang.org/x/term v0.45.0
+ golang.org/x/term v0.39.0
roseh.moe/pkg/oae2 v0.3.0
roseh.moe/pkg/wordlist v1.0.2
)
-require golang.org/x/sys v0.47.0 // indirect
+require golang.org/x/sys v0.40.0 // indirect
diff --git a/go.sum b/go.sum
index 03e29d8..789a5a3 100644
--- a/go.sum
+++ b/go.sum
@@ -1,13 +1,9 @@
-github.com/mattn/go-sqlite3 v1.14.50 h1:dmdFvo1XG4MPzA4IkAmE9upVz/Nj31uRoM5+jC8hYbY=
-github.com/mattn/go-sqlite3 v1.14.50/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
-golang.org/x/image v0.45.0 h1:FMb1nTbH5H9vF55SriQHgFw5GnNL9Jg6L25BwXKzhB0=
-golang.org/x/image v0.45.0/go.mod h1:n62x/7RqlwXDvGsSU4u6IUTUf6KghUZ9Bt7cG/T9Fx4=
-golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
-golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
-golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
-golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
+golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
+golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
+golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
roseh.moe/pkg/oae2 v0.3.0 h1:VR1Fqg8Qg2axaqZC9lSd87giuOOgvRXvL9zEXjc7nLQ=
roseh.moe/pkg/oae2 v0.3.0/go.mod h1:SZ5K2nvKreVdhHVNxujxcZLOnjhVi+qPi2XkB18dR8g=
roseh.moe/pkg/wordlist v1.0.2 h1:riB2RqCU5zXfCQjaPHYTXV/688FV9/Bp6Hnb0IAkP9c=
diff --git a/roseh.moe.go b/roseh.moe.go
index d9a948b..206679b 100644
--- a/roseh.moe.go
+++ b/roseh.moe.go
@@ -2,7 +2,6 @@ package main
import (
"archive/tar"
- "archive/zip"
"cmp"
"compress/gzip"
"crypto/hkdf"
@@ -11,7 +10,6 @@ import (
"crypto/sha1"
"crypto/sha256"
"crypto/subtle"
- "database/sql"
"embed"
"encoding/base64"
"encoding/binary"
@@ -20,8 +18,6 @@ import (
"flag"
"fmt"
"html/template"
- "image"
- "image/jpeg"
"io"
"io/fs"
"log"
@@ -30,16 +26,13 @@ import (
"net/http/httputil"
"net/url"
"os"
- "path/filepath"
"slices"
"strconv"
"strings"
"sync"
"time"
- _ "github.com/mattn/go-sqlite3"
"github.com/skip2/go-qrcode"
- "golang.org/x/image/draw"
"roseh.moe/pkg/oae2"
"roseh.moe/pkg/roseh.moe/internal/pwhash"
"roseh.moe/pkg/wordlist"
@@ -55,8 +48,6 @@ var (
holeTempDir = flag.String("hole-temp-dir", "hole", "directory to store temporary files for the wormhole")
codeDir = flag.String("code-dir", "code", "directory to serve git repos")
nezuko = flag.String("nezuko", "nezuko", "nezuko partition")
- martDir = flag.String("mart-dir", "/mnt/nezuko/downloads/[metart.com] Photosets - 1999 to 2023", "met art data directory")
- martDB = flag.String("mart-db", "/mnt/nezuko/files/met-art.sqlite", "met art index")
serverStartTime = time.Now()
)
@@ -914,297 +905,6 @@ func (h *nezukoHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.srv.ServeHTTP(w, r)
}
-var (
- //go:embed templates/mart/index.html.template
- metArtIndexString string
- metArtIndexTemplate = template.Must(outlinedTemplate(metArtIndexString))
-)
-
-type metArtIndexTemplateArgsGirl struct {
- Name string
- URL string
- CoverID int64
-}
-
-type metArtIndexTemplateArgs struct {
- Girls []metArtIndexTemplateArgsGirl
-}
-
-type metArtIndexHandler struct {
- s *stmts
-}
-
-func (h *metArtIndexHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- if !stupidCache(w, r) {
- return
- }
- rows, err := h.s.listGirls.Query()
- if err != nil {
- log.Printf("Warning: list girls: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- var girls []metArtIndexTemplateArgsGirl
- for rows.Next() {
- var girl metArtIndexTemplateArgsGirl
- if err := rows.Scan(&girl.Name, &girl.CoverID); err != nil {
- log.Printf("Warning: list girls: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- girl.URL = strings.ReplaceAll(girl.Name, " ", "-")
- girls = append(girls, girl)
- }
- if err := rows.Err(); err != nil {
- log.Printf("Warning: list girls: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- if err := metArtIndexTemplate.Execute(w, metArtIndexTemplateArgs{girls}); err != nil {
- log.Printf("Warning: mart index: %s", err)
- }
-}
-
-type metArtPhotoHandler struct {
- s *stmts
-}
-
-func (h *metArtPhotoHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- if !stupidCache(w, r) {
- return
- }
- id, err := strconv.ParseInt(strings.TrimSuffix(r.PathValue("photo"), ".jpeg"), 10, 64)
- if err != nil {
- notFound(w, r)
- return
- }
- var path, filename string
- if err := h.s.findPhoto.QueryRow(id).Scan(&path, &filename); err != nil {
- if err == sql.ErrNoRows {
- notFound(w, r)
- return
- }
- log.Printf("Warning: find photo: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- archive, err := zip.OpenReader(filepath.Join(*martDir, path))
- if err != nil {
- log.Printf("Warning: open archive: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- defer archive.Close()
- f, err := archive.Open(filename)
- if err != nil {
- log.Printf("Warning: open archive file: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- defer f.Close()
- w.Header().Set("Content-Type", "image/jpeg")
- if stat, err := f.Stat(); err == nil {
- w.Header().Set("Content-Length", strconv.FormatInt(stat.Size(), 10))
- }
- if _, err := io.Copy(w, f); err != nil {
- log.Printf("Warning: met art image: %s", err)
- }
-}
-
-var (
- //go:embed templates/mart/girl.html.template
- metArtGirlString string
- metArtGirlTemplate = template.Must(outlinedTemplate(metArtGirlString))
-)
-
-type metArtGirlTemplateArgsSet struct {
- URL string
- CoverID int64
- Name string
-}
-
-type metArtGirlTemplateArgs struct {
- Name string
- URL string
- Sets []metArtGirlTemplateArgsSet
-}
-
-type metArtGirlHandler struct {
- s *stmts
-}
-
-func (h *metArtGirlHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- if !stupidCache(w, r) {
- return
- }
- name := strings.ReplaceAll(r.PathValue("girl"), "-", " ")
- rows, err := h.s.listSetsForGirl.Query(name)
- if err != nil {
- log.Printf("Warning: list sets: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- var sets []metArtGirlTemplateArgsSet
- for rows.Next() {
- var id, coverID int64
- var name string
- if err := rows.Scan(&id, &coverID, &name); err != nil {
- log.Printf("Warning: list sets: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- sets = append(sets, metArtGirlTemplateArgsSet{
- Name: name,
- URL: fmt.Sprintf("%d-%s", id, strings.ReplaceAll(name, " ", "-")),
- CoverID: coverID,
- })
- }
- if err := rows.Err(); err != nil {
- log.Printf("Warning: list sets: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- if len(sets) == 0 {
- notFound(w, r)
- return
- }
- if err := metArtGirlTemplate.Execute(w, metArtGirlTemplateArgs{Name: name, URL: r.PathValue("girl"), Sets: sets}); err != nil {
- log.Printf("Warning: mart girl: %s", err)
- }
-}
-
-type metArtGirlPreviewHandler struct {
- s *stmts
-}
-
-func (h *metArtGirlPreviewHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- if !stupidCache(w, r) {
- return
- }
- id, err := strconv.ParseInt(strings.TrimSuffix(r.PathValue("photo"), ".jpeg"), 10, 64)
- if err != nil {
- notFound(w, r)
- return
- }
- var path, filename string
- if err := h.s.findPhoto.QueryRow(id).Scan(&path, &filename); err != nil {
- if err == sql.ErrNoRows {
- notFound(w, r)
- return
- }
- log.Printf("Warning: find photo: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- archive, err := zip.OpenReader(filepath.Join(*martDir, path))
- if err != nil {
- log.Printf("Warning: open archive: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- defer archive.Close()
- f, err := archive.Open(filename)
- if err != nil {
- log.Printf("Warning: open archive file: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- defer f.Close()
- fullSize, _, err := image.Decode(f)
- if err != nil {
- log.Printf("Warning: open preview photo: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- resized := image.NewRGBA(image.Rect(0, 0, 250, fullSize.Bounds().Dy()*250/fullSize.Bounds().Dx()))
- draw.ApproxBiLinear.Scale(resized, resized.Bounds(), fullSize, fullSize.Bounds(), draw.Src, nil)
- w.Header().Set("Content-Type", "image/jpeg")
- if err := jpeg.Encode(w, resized, &jpeg.Options{Quality: 50}); err != nil {
- log.Printf("Warning: met art preview image: %s", err)
- }
-}
-
-var (
- //go:embed templates/mart/set.html.template
- metArtSetString string
- metArtSetTemplate = template.Must(outlinedTemplate(metArtSetString))
-)
-
-type metArtSetTemplateArgs struct {
- Name string
- Photos []int64
-}
-
-type metArtSetHandler struct {
- s *stmts
-}
-
-func (h *metArtSetHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- if !stupidCache(w, r) {
- return
- }
- setID, _, _ := strings.Cut(r.PathValue("set"), "-")
- id, err := strconv.ParseInt(setID, 10, 64)
- if err != nil {
- notFound(w, r)
- return
- }
- wg := new(sync.WaitGroup)
- var setName string
- var setErr error
- wg.Go(func() {
- setErr = h.s.setName.QueryRow(id).Scan(&setName)
- })
- var photos []int64
- var photosErr error
- wg.Go(func() {
- rows, err := h.s.listPhotosForSet.Query(id)
- if err != nil {
- photosErr = err
- return
- }
- for rows.Next() {
- var photoID int64
- if err := rows.Scan(&photoID); err != nil {
- photosErr = err
- return
- }
- photos = append(photos, photoID)
- }
- if err := rows.Err(); err != nil {
- photosErr = err
- return
- }
- })
- wg.Wait()
- if err := setErr; err != nil {
- log.Printf("Error: find set name: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- if err := photosErr; err != nil {
- log.Printf("Warning: list set photos: %s", err)
- http.Error(w, "internal error", http.StatusInternalServerError)
- return
- }
- if len(photos) == 0 {
- notFound(w, r)
- return
- }
- if err := metArtSetTemplate.Execute(w, metArtSetTemplateArgs{Name: setName, Photos: photos}); err != nil {
- log.Printf("Warning: mart set: %s", err)
- }
-}
-
-func stupidCache(w http.ResponseWriter, r *http.Request) bool {
- w.Header().Set("Last-Modified", "Mon, 01 Jan 1990 00:00:00 GMT")
- if _, ok := r.Header["If-Modified-Since"]; ok {
- w.WriteHeader(http.StatusNotModified)
- return false
- }
- return true
-}
-
type jellyfinReverseProxy struct {
proxy httputil.ReverseProxy
}
@@ -1217,56 +917,6 @@ func (p *jellyfinReverseProxy) ServeHTTP(w http.ResponseWriter, r *http.Request)
p.proxy.ServeHTTP(w, r)
}
-type stmts struct {
- listGirls *sql.Stmt
- findPhoto *sql.Stmt
- girlName *sql.Stmt
- listSetsForGirl *sql.Stmt
- setName *sql.Stmt
- listPhotosForSet *sql.Stmt
-}
-
-func prepareStatements(db *sql.DB) (*stmts, error) {
- s := new(stmts)
- var err error
- s.listGirls, err = db.Prepare(`
- SELECT
- girls.name,
- (
- SELECT cover_photo_id
- FROM sets
- WHERE sets.girl_id = girls.girl_id
- ORDER BY date ASC, sets.name ASC LIMIT 1
- )
- FROM girls
- ORDER BY substr(girls.name, instr(girls.name, ' ')+1), girls.name
- `)
- if err != nil {
- return nil, err
- }
- s.findPhoto, err = db.Prepare("SELECT path, filename FROM photos JOIN sets USING (set_id) WHERE photo_id = ?")
- if err != nil {
- return nil, err
- }
- s.girlName, err = db.Prepare("SELECT name FROM girls WHERE girl_id = ?")
- if err != nil {
- return nil, err
- }
- s.listSetsForGirl, err = db.Prepare("SELECT set_id, cover_photo_id, sets.name FROM girls JOIN sets USING (girl_id) WHERE girls.name = ? ORDER BY date ASC, sets.name ASC")
- if err != nil {
- return nil, err
- }
- s.setName, err = db.Prepare("SELECT name FROM sets WHERE set_id = ?")
- if err != nil {
- return nil, err
- }
- s.listPhotosForSet, err = db.Prepare("SELECT photo_id FROM sets JOIN photos USING (set_id) WHERE set_id = ? AND idx IS NOT NULL ORDER BY idx ASC")
- if err != nil {
- return nil, err
- }
- return s, nil
-}
-
func main() {
flag.Parse()
@@ -1274,15 +924,6 @@ func main() {
log.Fatal(err)
}
- db, err := sql.Open("sqlite3", *martDB)
- if err != nil {
- log.Fatal(err)
- }
- stmts, err := prepareStatements(db)
- if err != nil {
- log.Fatal(err)
- }
-
go func() {
for range time.NewTicker(2 * time.Hour).C {
if err := cleanHole(); err != nil {
@@ -1293,7 +934,7 @@ func main() {
mux := http.NewServeMux()
mux.HandleFunc("GET /{$}", index)
- mux.HandleFunc("GET /games/{$}", gamesIndex)
+ mux.HandleFunc("GET /games/", gamesIndex)
mux.HandleFunc("GET /games/pong", pong)
mux.HandleFunc("GET /games/rms", stallmanShooter)
mux.HandleFunc("GET /qr.png", qrHandler)
@@ -1304,17 +945,12 @@ func main() {
mux.HandleFunc("POST /login", login)
mux.HandleFunc("GET /notepad", notepad)
mux.HandleFunc("POST /notepad", autosave)
- mux.HandleFunc("GET /cmd/{$}", cmdIndex)
+ mux.HandleFunc("GET /cmd/", cmdIndex)
mux.HandleFunc("GET /cmd/{cmd}", cmd)
- mux.HandleFunc("GET /pkg/{$}", pkgIndex)
+ mux.HandleFunc("GET /pkg/", pkgIndex)
mux.HandleFunc("GET /pkg/{pkg}", pkg)
mux.Handle("GET /code/", http.StripPrefix("/code/", http.FileServer(http.Dir(*codeDir))))
mux.Handle("GET /nezuko/", &nezukoHandler{http.StripPrefix("/nezuko/", http.FileServer(http.Dir(*nezuko)))})
- mux.Handle("GET /mart/{$}", &metArtIndexHandler{stmts})
- mux.Handle("GET /mart/{girl}/{$}", &metArtGirlHandler{stmts})
- mux.Handle("GET /mart/{girl}/{set}", &metArtSetHandler{stmts})
- mux.Handle("GET /mart/photos/{photo}", &metArtPhotoHandler{stmts})
- mux.Handle("GET /mart/photos/preview/{photo}", &metArtGirlPreviewHandler{stmts})
mux.HandleFunc("GET /static/", static)
mux.HandleFunc("GET /favicon.ico", favicon)
apiMux := http.NewServeMux()
diff --git a/static/styles.css b/static/styles.css
index 969095f..0f56527 100644
--- a/static/styles.css
+++ b/static/styles.css
@@ -139,15 +139,3 @@ img.inline {
margin-right: 5px;
filter: drop-shadow(2px -1px 3px grey);
}
-
-figure {
- display: inline-block;
- text-align: center;
-}
-
-.fullwidth figure img {
- max-width: 100vw;
- max-height: 100vh;
- width: auto;
- height: auto;
-}
diff --git a/templates/cmd-index.html.template b/templates/cmd-index.html.template
index e239ef0..16b89b0 100644
--- a/templates/cmd-index.html.template
+++ b/templates/cmd-index.html.template
@@ -1,8 +1,8 @@
-{{- define "head"}}
+{{define "head" -}}
<title>Commands</title>
{{- end}}
-{{- define "body"}}
+{{define "body" -}}
<section>
<p>Command index</p>
<ul>
diff --git a/templates/games/index.html.template b/templates/games/index.html.template
index f25c080..f235bd1 100644
--- a/templates/games/index.html.template
+++ b/templates/games/index.html.template
@@ -1,8 +1,6 @@
-{{- define "head"}}
- <title>Games</title>
-{{- end}}
+{{define "head"}}<title>Games</title>{{end}}
-{{- define "body"}}
+{{define "body" -}}
<section>
<ul>
<li><a href="/games/pong">Pong</a> (warning: loud)</li>
diff --git a/templates/games/rms.html.template b/templates/games/rms.html.template
index d6efdad..9f396fe 100644
--- a/templates/games/rms.html.template
+++ b/templates/games/rms.html.template
@@ -1,9 +1,9 @@
-{{- define "head"}}
+{{define "head" -}}
<title>RMS shooter</title>
<script src="/static/games/rms/rms.js" defer></script>
{{- end}}
-{{- define "body"}}
+{{define "body" -}}
<img id="sprite-sheet" src="/static/games/rms/sprite-sheet.webp" hidden>
<section>
diff --git a/templates/index.html.template b/templates/index.html.template
index 009083b..fcb74b6 100644
--- a/templates/index.html.template
+++ b/templates/index.html.template
@@ -1,8 +1,6 @@
-{{- define "head"}}
- <title>roseh.moe</title>
-{{- end}}
+{{define "head"}}<title>roseh.moe</title>{{end}}
-{{- define "body"}}
+{{define "body" -}}
<div style="background-image:url(/static/index/stars.webp);background-repeat:repeat;height:500px;display:flex">
<h1 style="margin:auto">roseh.moe</h1>
</div>
diff --git a/templates/login.html.template b/templates/login.html.template
index 49f392b..ce46bd1 100644
--- a/templates/login.html.template
+++ b/templates/login.html.template
@@ -1,8 +1,6 @@
-{{- define "head"}}
- <title>Login</title>
-{{- end}}
+{{define "head"}}<title>Login</title>{{end}}
-{{- define "body"}}
+{{define "body" -}}
<section>
{{- if .Error}}
<p class="login-error"><img class="inline" src="/static/angry.webp">Incorrect password</p>
diff --git a/templates/mart/girl.html.template b/templates/mart/girl.html.template
deleted file mode 100644
index bc82e4f..0000000
--- a/templates/mart/girl.html.template
+++ /dev/null
@@ -1,15 +0,0 @@
-{{- define "head"}}
- <title>{{.Name}}</title>
-{{- end}}
-
-{{- define "body"}}
- {{$girlURL := .URL}}
- {{- range .Sets}}
- <figure>
- <a href="/mart/{{$girlURL}}/{{.URL}}">
- <img src="/mart/photos/preview/{{.CoverID}}.jpeg">
- </a>
- <figcaption>{{.Name}}</figcaption>
- </figure>
- {{- end}}
-{{- end}}
diff --git a/templates/mart/index.html.template b/templates/mart/index.html.template
deleted file mode 100644
index 17365c1..0000000
--- a/templates/mart/index.html.template
+++ /dev/null
@@ -1,14 +0,0 @@
-{{- define "head"}}
- <title>Met Art Babes</title>
-{{- end}}
-
-{{- define "body"}}
- {{- range .Girls}}
- <figure>
- <a href="/mart/{{.URL}}/">
- <img src="/mart/photos/preview/{{.CoverID}}.jpeg">
- </a>
- <figcaption>{{.Name}}</figcaption>
- </figure>
- {{- end}}
-{{- end}}
diff --git a/templates/mart/set.html.template b/templates/mart/set.html.template
deleted file mode 100644
index dbe0f22..0000000
--- a/templates/mart/set.html.template
+++ /dev/null
@@ -1,13 +0,0 @@
-{{- define "head"}}
- <title>{{.Name}}</title>
-{{- end}}
-
-{{- define "body"}}
- <div class="fullwidth">
- {{- range .Photos}}
- <figure>
- <img src="/mart/photos/{{.}}.jpeg">
- </figure>
- {{- end}}
- </div>
-{{- end}}
diff --git a/templates/note.html.template b/templates/note.html.template
index cc9255e..ff72bdf 100644
--- a/templates/note.html.template
+++ b/templates/note.html.template
@@ -1,11 +1,11 @@
-{{- define "head"}}
+{{define "head" -}}
<script src="/static/htmx.min.js"></script>
<title>Notepad</title>
<meta name="viewport" content="interactive-widget=resizes-content"> <!-- https://stackoverflow.com/q/76026292 -->
{{- end}}
-{{- define "body"}}
+{{define "body" -}}
<form id="form" method="post">
<div class="save-indicator-container">
{{block "saveIndicator" ""}}<span id="save-indicator">{{.}}</span>{{end}}
diff --git a/templates/outline.html.template b/templates/outline.html.template
index 67dfa6d..6ef1fe0 100644
--- a/templates/outline.html.template
+++ b/templates/outline.html.template
@@ -4,9 +4,9 @@
<link rel="icon" href="/favicon.ico">
<link rel="stylesheet" href="/static/styles.css">
- {{- template "head" .}}
+ {{template "head" .}}
</head>
<body>
- {{- template "body" .}}
+ {{template "body" .}}
</body>
</html>
diff --git a/templates/pkg-index.html.template b/templates/pkg-index.html.template
index ae26686..fc88ed4 100644
--- a/templates/pkg-index.html.template
+++ b/templates/pkg-index.html.template
@@ -1,8 +1,8 @@
-{{- define "head"}}
+{{define "head" -}}
<title>Packages</title>
{{- end}}
-{{- define "body"}}
+{{define "body" -}}
<section>
<p>Package index</p>
<ul>
diff --git a/templates/wormhole-success.html.template b/templates/wormhole-success.html.template
index 89f9cf2..dbb997e 100644
--- a/templates/wormhole-success.html.template
+++ b/templates/wormhole-success.html.template
@@ -1,8 +1,6 @@
-{{- define "head"}}
- <title>Uploaded!</title>
-{{- end}}
+{{define "head"}}<title>Uploaded!</title>{{end}}
-{{- define "body"}}
+{{define "body" -}}
<div style="display:flex;flex-direction:column;align-items:center;font-size:50px">
<p><a href="{{.URL}}">{{.URL}}</a></p>
<img src="{{.QR}}" alt="QR code for {{.URL}}" width="500px">
diff --git a/templates/wormhole.html.template b/templates/wormhole.html.template
index e773bc0..9c770c1 100644
--- a/templates/wormhole.html.template
+++ b/templates/wormhole.html.template
@@ -1,8 +1,8 @@
-{{- define "head"}}
+{{define "head" -}}
<title>Wormhole</title>
{{- end}}
-{{- define "body"}}
+{{define "body" -}}
<form
method="post"
enctype="multipart/form-data"