From 3088330067c8f45b82df215bd73307b5df206d10 Mon Sep 17 00:00:00 2001 From: xoy Date: Fri, 28 Feb 2025 23:34:15 +0100 Subject: [PATCH] [Finalize app] --- .gitignore | 1 + generate.go | 4 +- go.mod | 19 ++++++++ go.sum | 50 ++++++++++++++++++++ main.go | 53 +++++++++++++++++++-- misc.go | 28 +++++++++++ static/css/colors.css | 28 +++++++++++ static/css/index.css | 40 ++++++++++++++++ static/css/main.css | 86 ++++++++++++++++++++++++++++++++++ static/css/rendertypes.css | 31 ++++++++++++ static/media/hilbertcurve.gif | Bin 0 -> 26046 bytes static/media/snakerender.png | Bin 0 -> 4289 bytes templatetypes.go | 10 ++++ views/index.html | 16 ++++++- views/partials/base-top.html | 5 ++ views/rendertypes.html | 14 ++++++ 16 files changed, 377 insertions(+), 8 deletions(-) create mode 100644 .gitignore create mode 100644 misc.go create mode 100644 static/css/rendertypes.css create mode 100644 static/media/hilbertcurve.gif create mode 100644 static/media/snakerender.png create mode 100644 templatetypes.go create mode 100644 views/rendertypes.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6a3e68d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +**/.DS_Store \ No newline at end of file diff --git a/generate.go b/generate.go index 6a7bdfa..05afa18 100644 --- a/generate.go +++ b/generate.go @@ -13,8 +13,8 @@ import ( ) func SnakeGenerateByteImagePart(data []byte, startX, startY, stopX, stopY, xLen, yLen int, img *image.RGBA) { - for x := startX; x < stopX; x++ { - for y := startY; y < stopY; y++ { + for y := startY; y < stopY; y++ { + for x := startX; x < stopX; x++ { B := byte(0) diff --git a/go.mod b/go.mod index a9a0845..cbb084f 100644 --- a/go.mod +++ b/go.mod @@ -10,16 +10,35 @@ require ( require ( github.com/andybalholm/brotli v1.1.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gofiber/template v1.8.3 // indirect github.com/gofiber/utils v1.1.0 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect github.com/klauspost/compress v1.17.9 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/rivo/uniseg v0.2.0 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.19.0 // indirect + github.com/subosito/gotenv v1.6.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.51.0 // indirect github.com/valyala/tcplisten v1.0.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.9.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.22.0 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 3de7ffc..9f51ac2 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,11 @@ github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +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/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI= github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw= github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc= @@ -12,8 +16,12 @@ github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM= github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0= 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/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= 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= @@ -21,23 +29,65 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= 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/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +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/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= +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/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +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/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA= github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g= github.com/valyala/tcplisten v1.0.0 h1:rBHj/Xf+E1tRGZyWIWwJDiRY0zc1Js+CV5DqwacVSA8= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ= golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8= 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.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +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= diff --git a/main.go b/main.go index bf71dc2..f15a172 100644 --- a/main.go +++ b/main.go @@ -1,27 +1,62 @@ package main import ( + "flag" "fmt" "io" "log" "github.com/gofiber/fiber/v2" "github.com/gofiber/template/html/v2" + "github.com/spf13/pflag" + "github.com/spf13/viper" ) func main() { + viper.SetEnvPrefix("BI") + viper.AutomaticEnv() + + flag.Int("MAX_FILE_SIZE", 1073741824, "Max file size in bytes") + flag.Parse() + + err := viper.BindPFlags(pflag.CommandLine) + if err != nil { + fmt.Println(err) + return + } + + maxFileSize := viper.GetInt("MAX_FILE_SIZE") + engine := html.New("views", ".html") app := fiber.New(fiber.Config{ Views: engine, - BodyLimit: 10 * 1024 * 1024 * 1024, // 1GiB + BodyLimit: maxFileSize, }) + maxFileSizeString := fileSizeToString(maxFileSize) + + nav := []NavItem{ + NewNavItem("/", "Generator"), + NewNavItem("/rendertypes", "Rendertypes"), + } + app.Static("/", "static") app.Get("/", func(c *fiber.Ctx) error { return c.Render("index", fiber.Map{ - "Stylenames": []string{"colors", "main", "index"}, + "Stylenames": []string{"colors", "main", "index"}, + "NavItems": nav, + "ActivePage": "/", + "MaxFileSize": maxFileSizeString, + }) + }) + + app.Get("/rendertypes", func(c *fiber.Ctx) error { + return c.Render("rendertypes", fiber.Map{ + "Stylenames": []string{"colors", "main", "rendertypes"}, + "NavItems": nav, + "ActivePage": "/rendertypes", }) }) @@ -40,13 +75,23 @@ func main() { return err } - img, err := HilbertCurveGenerateByteImage(data) + renderType := c.FormValue("rendertype", "snake") + + var img []byte + + switch renderType { + case "snake": + img, err = SnakeGenerateByteImage(data) + default: + img, err = HilbertCurveGenerateByteImage(data) + } + if err != nil { return err } c.Type("bmp") - c.Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", file.Filename+".bmp")) + c.Set("Content-Disposition", fmt.Sprintf("filename=\"%s\"", file.Filename+".bmp")) //attachment; return c.Send(img) }) diff --git a/misc.go b/misc.go new file mode 100644 index 0000000..e361c11 --- /dev/null +++ b/misc.go @@ -0,0 +1,28 @@ +package main + +import "fmt" + +func fileSizeToString(fileSize int) string { + binarySizes := []string{ + "B", + "kiB", + "MiB", + "GiB", + "TiB", + "PiB", + "EiB", + "ZiB", + "YiB", + "RiB", + "QiB", + } + + smallerNumber := float64(fileSize) + size := 0 + binarySizesCount := len(binarySizes) + for smallerNumber >= 1024 || size >= binarySizesCount { + smallerNumber /= 1024 + size++ + } + return fmt.Sprintf("%.2f %v", smallerNumber, binarySizes[size]) +} diff --git a/static/css/colors.css b/static/css/colors.css index e69de29..da728b2 100644 --- a/static/css/colors.css +++ b/static/css/colors.css @@ -0,0 +1,28 @@ +:root { + --fg: #e8e6e3; + --fg-inactive: #999999; + --bg: #181a1b; + --bg-light: black; + --bg-border: #888888; + --accent: #a9daef; + --danger: #e16363; + --invalid: #d73030; + --contrast: white; + --link: #6f6fff; + --link-visited: #bb88e9; +} + +@media (prefers-color-scheme: light) { + :root { + --fg: #071419; + --fg-inactive: #4d636c; + --bg: #e0ecff; + --bg-light: #bcc5d5; + --bg-border: #888888; + --accent: #333333; + --danger: #be0000; + --contrast: black; + --link: #0000ee; + --link-visited: #551a8b; + } +} \ No newline at end of file diff --git a/static/css/index.css b/static/css/index.css index e69de29..3692fdf 100644 --- a/static/css/index.css +++ b/static/css/index.css @@ -0,0 +1,40 @@ +main { + display: flex; + flex-direction: column; + justify-content: center; +} + +form { + display: grid; + grid-template-columns: max-content; + gap: 5px; + margin: auto; +} + +form > div.form-content { + display: grid; + grid-template-columns: max-content max-content; + grid-template-rows: max-content; + align-items: baseline; + gap: 10px; +} + +form > div.form-content > div.radio-container { + display: grid; + grid-template-columns: max-content max-content; + grid-template-rows: max-content; + align-items: baseline; + gap: 10px; +} + +form > div.form-content > div.radio-container > *, form > button[type="submit"], form > div.form-content > input[type="file"] { + cursor: pointer; +} + +form > :is(button[type="submit"], div.form-content) { + font-size: 1.5em; +} + +form > div.form-content > p.maxfilesize { + text-align: right; +} \ No newline at end of file diff --git a/static/css/main.css b/static/css/main.css index e69de29..6e5d0b7 100644 --- a/static/css/main.css +++ b/static/css/main.css @@ -0,0 +1,86 @@ +* { + box-sizing: border-box; + } + + html, body { + width: 100%; + height: 100%; + margin: 0; + padding: 0; + font-family: monospace; + + color: var(--fg); + background-color: var(--bg); + } + + a { + color: var(--link); + text-decoration: none; + font-weight: bold; + } + + a:visited { + color: var(--link-visited); + } + + header, footer { + background-color: var(--bg-light); + height: 150px; + } + + footer { + height: 50px; + } + + header { + display: flex; + flex-direction: column; + justify-content: space-around; + } + + header > h1 { + padding: 0; + margin: 0; + text-align: center; + font-size: 4.5em; + } + + :is(header, footer) > nav { + display: flex; + justify-content: center; + gap: 20px; + font-size: 1.5em; + } + + footer > nav { + height: 100%; + flex-direction: column; + } + + footer > nav > a { + margin: auto; + } + + :is(header, footer) > nav > a::before { + content: '< '; + } + + :is(header, footer) > nav > a::after { + content: ' >'; + } + + :is(header, footer) > nav > a:is(:hover, .active)::before { + content: '\00a0>'; + } + + :is(header, footer) > nav > a:is(:hover, .active)::after { + content: '<\00a0'; + } + + :is(header, footer) > nav > a:visited { + color: var(--link); + } + + main { + min-height: calc(100vh - 200px); + } \ No newline at end of file diff --git a/static/css/rendertypes.css b/static/css/rendertypes.css new file mode 100644 index 0000000..fef9e9e --- /dev/null +++ b/static/css/rendertypes.css @@ -0,0 +1,31 @@ +main { + display: flex; + flex-direction: row; + flex-wrap: wrap; + gap: 10px; + align-items: center; + justify-content: center; +} + +div.rendertype-container { + display: flex; + flex-direction: column; + gap: 10px; + align-items: center; +} + +div.rendertype-container > div.rendertype-img { + width: 250px; + height: 250px; + background-color: white; + background-position: center; + background-size: contain; +} + +div.rendertype-container > div.rendertype-img.snake { + background-image: url(/media/snakerender.png); +} + +div.rendertype-container > div.rendertype-img.hilbertcurve { + background-image: url(/media/hilbertcurve.gif); +} \ No newline at end of file diff --git a/static/media/hilbertcurve.gif b/static/media/hilbertcurve.gif new file mode 100644 index 0000000000000000000000000000000000000000..94f2167223573182406d9bbd7bc2718a68dd078c GIT binary patch literal 26046 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⛼>9NCbuf4z3I5DK%1|rq zH(P%k_Lhk#6pBVdlevXZG>ck!Zf(;16kpulzPm{y427$w)oMX}@ba1h@!`zWK=4?{ zRTU53Nqmjc4xM*Ak(k)PV!5B}J-}|73z7T8QL#NdL$7kh6=4lhmVA$|9nKQELNUK7 zxrN2WacDVroJ$%U{VEf?*1>^d8ZA0Uj3QxtOKQbdWmS7VIrotO(O-xK!f~DGmB}Uj0j6{AU3^hyeNq?>X7oZolqy zitb>R1NP5JxD{o>S|*pYATFJ|G{rrdL|ohTGBAlZ4UTi4Wr z6vkqCFpSCTy^`zICCX?5fiPH?T5H-!+{+ft*dGAlfN3@{&_IFBM(A3>%lZO=*VSIl zgyC>#$M4y_#ECz<6^)ieEGti*?ex=tyg4s%Ck^1tSK7ybU@1-2PkN*p5@d1uxk=5# z<%oZPXJYep6ZiGYaxumPGEbzquk?$l8#QdL3nQR0)r|M?MSuE~QhTTLtM|z@B zp?j-!3uwbfER+AK)7k0PhVmk<6RI6Q|`9)EI)E6>>m zACL+N-~q!eE+*!-L&9Jh3=Ku+4eIFA0=^hDzml0W1rH+p#W^tu5aT=vU0F_@5g?Hu zgu=KPPx`y3=Rksgl9X`m{T35EGc%LI$;`|InTqIoVbkNbHX?y=UF8mt6Brl>$a$6q yMkLe4k8k9B*I7VtU~4{u233OQ|DLan=Ih8Ahh-Ou8Q|{+Xphf+?~0ufXa5CEKqkBZ literal 0 HcmV?d00001 diff --git a/templatetypes.go b/templatetypes.go new file mode 100644 index 0000000..c660e0a --- /dev/null +++ b/templatetypes.go @@ -0,0 +1,10 @@ +package main + +type NavItem struct { + Destination string + Caption string +} + +func NewNavItem(destination, caption string) NavItem { + return NavItem{destination, caption} +} diff --git a/views/index.html b/views/index.html index a3a25d6..66e2a68 100644 --- a/views/index.html +++ b/views/index.html @@ -1,8 +1,20 @@ {{template "partials/base-top" .}}
- - +
+ +
+ +

Max filesize: {{ .MaxFileSize }}

+
+ +
+ + + + +
+
diff --git a/views/partials/base-top.html b/views/partials/base-top.html index 87d2e11..ec04bf5 100644 --- a/views/partials/base-top.html +++ b/views/partials/base-top.html @@ -11,5 +11,10 @@

BinaryImage

+
\ No newline at end of file diff --git a/views/rendertypes.html b/views/rendertypes.html new file mode 100644 index 0000000..05bfb4f --- /dev/null +++ b/views/rendertypes.html @@ -0,0 +1,14 @@ +{{template "partials/base-top" .}} + +
+
+

Hilbert Curve

+
+ +
+
+

Snake

+
+ + +{{template "partials/base-bottom" .}} \ No newline at end of file