summaryrefslogtreecommitdiff
path: root/static
diff options
context:
space:
mode:
authorlost+skunk <[email protected]>2024-08-13 15:59:52 +0300
committerlost+skunk <[email protected]>2024-08-13 15:59:52 +0300
commit1537da9b16dfda1ecb2730b5d1de3b9005397618 (patch)
tree0cce5db0cb6393d369b7f8207d495645510276f2 /static
parent4db018fb7f01669cb5e4c1da4b56ccfe3dbadd6f (diff)
downloadskunky-art-1537da9b16dfda1ecb2730b5d1de3b9005397618.tar.gz
skunky-art-1537da9b16dfda1ecb2730b5d1de3b9005397618.tar.bz2
skunky-art-1537da9b16dfda1ecb2730b5d1de3b9005397618.zip
темплейты в бинарнике и улучшенная система кеша
Diffstat (limited to 'static')
-rw-r--r--static/css/skunky.css204
-rw-r--r--static/html/about.htm49
-rw-r--r--static/html/daily.htm13
-rw-r--r--static/html/deviantion.htm44
-rw-r--r--static/html/gruser.htm81
-rw-r--r--static/html/head.htm24
-rw-r--r--static/html/header.htm14
-rw-r--r--static/html/index.htm22
-rw-r--r--static/html/search.htm16
-rw-r--r--static/images/logo.pngbin0 -> 408075 bytes
-rw-r--r--static/templates-noembed.go148
-rw-r--r--static/templates.go16
12 files changed, 631 insertions, 0 deletions
diff --git a/static/css/skunky.css b/static/css/skunky.css
new file mode 100644
index 0000000..bdc894c
--- /dev/null
+++ b/static/css/skunky.css
@@ -0,0 +1,204 @@
+/* TAGS */
+html {
+ font-family: Ubuntu;
+ background-color:black;
+ color: rgb(234, 216, 216);
+}
+a {
+ text-decoration: none;
+ color: cadetblue;
+}
+a:hover {
+ color: #d0ff00;
+ transition: 400ms;
+}
+header h1 {
+ padding-right: 0.2%;
+ padding-left: 0.2%;
+}
+header form {
+ align-self: center;
+}
+header {
+ display: flex;
+}
+form {
+ font-size: 0;
+ border: solid #164e3e 1px;
+ max-width: fit-content;
+}
+form input, button, select {
+ background-color: #134134;
+ padding: 5px;
+ color: whitesmoke;
+ border: 0;
+}
+input:focus {
+ outline: none;
+}
+
+/* BLOCKS */
+.content {
+ align-items: center;
+ border-radius: 3px;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+}
+.block {
+ max-width: 20%;
+ height: 0%;
+ padding: 4px;
+ border-radius: 2px;
+ border: 3px solid #091f19;
+ word-break: break-all;
+ background-color: #091f19;
+ margin-left: 5px;
+ margin-top: 5px;
+ text-align: center;
+}
+.block:hover {
+ border: 3px solid #4d27d6;
+ transition: 400ms;
+}
+.block img, .plates .user-plate img {
+ width: 100%;
+}
+.block p {
+ word-break: break-all;
+}
+
+/* MESSAGES */
+.msg {
+ background-color: #091f19;
+ color: whitesmoke;
+ width: fit-content;
+ max-width: 90%;
+ padding: 4px;
+ border-radius: 2px;
+ margin-top: 6px;
+ text-wrap: pretty;
+ transition: 350ms;
+}
+.msg:hover {
+ background-color: #134134;
+}
+.reply {
+ border-radius: 0px 2px 2px 0px;
+ border-left: #258268 solid;
+ margin-left: 40px;
+}
+
+/* FOLDER & PLATES */
+.folders, .plates {
+ display: flex;
+ flex-wrap: wrap;
+}
+.folder-item {
+ background-color: #060820;
+ border: 3px solid #060820;
+ width: 10%
+}
+.admins .user-plate {
+ width: 5%;
+ background-color: #011522;
+}
+.plates .user-plate {
+ margin-left: 1%;
+ margin-bottom: 1%;
+ background-color: #091f19;
+ padding: 3px;
+ word-break: break-all;
+ text-align: center;
+ max-width: 15%;
+}
+
+/* USER/GROUP BACKGROUNDS */
+.ubg {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+}
+.ubg img {
+ width: 20%;
+}
+
+/* COLORS */
+.nsfw, .about-false {
+ color: red;
+}
+.about-true {
+ color: green;
+}
+.author {
+ color: seagreen;
+}
+.dd {
+ color: rgb(160, 0, 147);
+}
+
+/* SCREEN OPTIMISATIONS */
+@media (orientation: portrait) {
+ * {
+ font-size: 120%
+ }
+
+ ul {
+ font-size: 80%
+ }
+
+ center form {
+ font-size: 60%
+ }
+
+ header form {
+ font-size: 60%;
+ max-width: unset;
+ border: 0;
+ }
+ header, center {
+ text-align: center;
+ display: block;
+ clear: both;
+ font-size: 200%;
+ }
+
+ .content {
+ margin: auto;
+ display: inherit;
+ scale: 100%;
+ }
+ .block {
+ margin-top: 10%;
+ max-width: 200%;
+ }
+ .folder-item {
+ width: 25%
+ }
+ .folders {
+ display: flexbox;
+ justify-content: center
+ }
+ figure img {
+ width: 10%
+ }
+ figure a img {
+ width: 100%
+ }
+ .msg {
+ font-size: 60%;
+ max-width: 80%
+ }
+}
+
+@media (max-width: 1462px) and (orientation: landscape) {
+ .block {
+ max-width: 30%;
+ }
+}
+
+@media (min-width: 788px) and (max-width: 884px) {
+ .block {
+ max-width: 35%;
+ }
+} \ No newline at end of file
diff --git a/static/html/about.htm b/static/html/about.htm
new file mode 100644
index 0000000..d2278d6
--- /dev/null
+++ b/static/html/about.htm
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+ {{template "head" .}}
+ <main>
+ {{template "header" .}}
+ <p>
+ SkunkyArt is an alternative frontend for deviantart.com, written in Go.
+ </p>
+ <h3><a href="https://go.kde.org/matrix/#/#skunkyart:ebloid.ru" target="_blank">Room in Matrix</a></h3>
+ <b>Instance settings:</b>
+ <ul>
+ <li><b>NSFW</b>: <span class="about-{{.Templates.About.Nsfw}}">{{if .Templates.About.Nsfw}}YES{{else}}NO{{end}}</span></li>
+ <li><b>Proxyfing</b>: <span class="about-{{.Templates.About.Proxy}}">{{if .Templates.About.Proxy}}YES{{else}}NO{{end}}</span></li>
+ </ul>
+ <details>
+ <summary><b>Instances:</b></summary>
+ <ul>
+ {{range .Templates.About.Instances}}
+ <li><u><b>{{.Title}}</b></u>:
+ <ul>
+ <li><b>Country</b>: {{.Country}}</li>
+ <li><b>URLs</b>: </li>
+ <ul>
+ {{if ne .Urls.I2P ""}}
+ <li><b>I2P</b>: <a href="{{.Urls.I2P}}">Yes</a></li>
+ {{end}}
+ {{if ne .Urls.Ygg ""}}
+ <li><b>Ygg</b>: <a href="{{.Urls.Ygg}}">Yes</a></li>
+ {{end}}
+ {{if ne .Urls.Tor ""}}
+ <li><b>Tor</b>: <a href="{{.Urls.Tor}}">Yes</a></li>
+ {{end}}
+ {{if ne .Urls.Clearnet ""}}
+ <li><b>Clearnet</b>: <a href="{{.Urls.Clearnet}}">{{.Urls.Clearnet}}</a></li>
+ {{end}}
+ </ul>
+ <li><b>Settings</b>: </li>
+ <ul>
+ <li><b>NSFW</b>: <span class="about-{{.Settings.Nsfw}}">{{if .Settings.Nsfw}}YES{{else}}NO{{end}}</span></li>
+ <li><b>Proxyfing</b>: <span class="about-{{.Settings.Proxy}}">{{if .Settings.Proxy}}YES{{else}}NO{{end}}</span></li>
+ </ul>
+ </ul>
+ </li>
+ {{end}}
+ </ul>
+ </details>
+ <p>Copyright <a href="https://go.kde.org/matrix/#/@softpigeones:ebloid.ru" target="_blank">lost+skunk</a>, X11. <a href="https://git.macaw.me/skunky/skunkyart/src/tag/v1.3.1" target="_blank">SkunkyArt v1.3.1</a></p>
+ </main>
+</html> \ No newline at end of file
diff --git a/static/html/daily.htm b/static/html/daily.htm
new file mode 100644
index 0000000..b3b6044
--- /dev/null
+++ b/static/html/daily.htm
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+ {{template "head" . }}
+ <main>
+ {{template "header" . }}
+ {{if ne .Templates.DDStrips ""}}
+ <h2 id="strips"><a href="#strips">#</a> Strips</h2>
+ {{.Templates.DDStrips}}
+ {{end}}
+ <h2 id="content"><a href="#content">#</a> Content</h2>
+ {{.Templates.SomeList}}
+ </main>
+</html> \ No newline at end of file
diff --git a/static/html/deviantion.htm b/static/html/deviantion.htm
new file mode 100644
index 0000000..f357dd7
--- /dev/null
+++ b/static/html/deviantion.htm
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+ {{template "head" . }}
+ <main>
+ {{template "header" . }}
+ <figure>
+ <img src="{{.BasePath}}media/emojitar/{{.Templates.Deviation.Post.Deviation.Author.Username}}?type=a" width="30px">
+ <span><strong><a href="{{.BasePath}}group_user?type=about&q={{.Templates.Deviation.Post.Deviation.Author.Username}}">{{.Templates.Deviation.Post.Deviation.Author.Username}}</a></strong> — {{if (.Templates.Deviation.Post.Deviation.DD)}}
+ <span class="dd" title="Daily Deviation!"><b>{{.Templates.Deviation.Post.Deviation.Title}}</b></span>
+ {{else}}{{.Templates.Deviation.Post.Deviation.Title}}{{end}}
+ {{if (ne .Templates.Deviation.Post.Deviation.License "none")}}<mark title="License">{{.Templates.Deviation.Post.Deviation.License}}</mark>{{end}} {{if (.Templates.Deviation.Post.Deviation.AI)}}[🤖]{{end}}
+ {{if (.Templates.Deviation.Post.Deviation.NSFW)}}[<span class="nsfw">NSFW</span>]{{end}}
+ </span>
+ <br>
+ {{if (ne .Templates.Deviation.Post.IMG "")}}
+ <a href="{{.Templates.Deviation.Post.IMG}}" title="open/download image"><img src="{{.Templates.Deviation.Post.IMG}}" width="50%"></a>
+ <br>
+ {{end}}
+ {{if (ne .Templates.Deviation.Tags "")}}
+ {{.Templates.Deviation.Tags}}<br>
+ {{end}}
+ <span>Published: <strong>{{.Templates.Deviation.StringTime}}</strong>; Views: <strong>{{.Templates.Deviation.Post.Deviation.Stats.Views}}</strong>; Favourites: <strong>{{.Templates.Deviation.Post.Deviation.Stats.Favourites}}</strong>; Downloads: <strong>{{.Templates.Deviation.Post.Deviation.Stats.Downloads}}</strong>
+ <br><a target="_blank" href="https://www.deviantart.com/{{.Templates.Deviation.Post.Deviation.Author.Username}}/art/art-{{.Templates.Deviation.Post.Deviation.ID}}">Redirect to original</a>
+ </span>
+ {{if (ne .Templates.Deviation.Post.Description "")}}
+ <figcaption>
+ <details>
+ <summary>Description</summary>
+ {{.Templates.Deviation.Post.Description}}
+ </details>
+ </figcaption>
+ {{end}}
+ {{if ne .Templates.Deviation.Related ""}}
+ <details>
+ <summary>Related content</summary>
+ {{.Templates.Deviation.Related}}
+ </details>
+ {{end}}
+ {{if (ne .Templates.Deviation.Comments "")}}
+ {{.Templates.Deviation.Comments}}
+ {{end}}
+ </figure>
+ </main>
+</html> \ No newline at end of file
diff --git a/static/html/gruser.htm b/static/html/gruser.htm
new file mode 100644
index 0000000..c8227ef
--- /dev/null
+++ b/static/html/gruser.htm
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+ {{template "head" . }}
+ <main>
+ <header>
+ <h1><a href="{{.BasePath}}">HOME</a> | <a href="{{.BasePath}}dd">DD</a>
+ | <a href="group_user?q={{.Templates.GroupUser.GR.Owner.Username}}&type={{if eq .Type 'a'}}gallery">Gallery{{else}}about">About{{end}}</a>
+ | <a href="group_user?q={{.Templates.GroupUser.GR.Owner.Username}}&type=gallery&atom=true">RSS</a></h1>
+ <form method="get" action="{{.BasePath}}search">
+ <input type="gallery" name="q" placeholder="Search for ..." autocomplete="off" autocapitalize="none" spellcheck="false">
+ <input type="hidden" name="usr" value="{{.Templates.GroupUser.GR.Owner.Username}}">
+ <select name="type">
+ <option value="gallery">Gallery</option>
+ <option value="all">All</option>
+ <option value="tag">Tag</option>
+ <option value="r">Groups</option>
+ </select>
+ <button type="submit">Search!</button>
+ </form> <h1>| {{.Templates.GroupUser.GR.Owner.Username}}</h1>
+ </header>
+ {{if eq .Type 'a'}}
+ {{if ne .Templates.GroupUser.About.BG ""}}
+ <a href="{{.Templates.GroupUser.About.BGMeta.Url}}" class="ubg"><img title="{{if ne .Templates.GroupUser.GR.Owner.Username .Templates.GroupUser.About.BGMeta.Author.Username}}
+ {{.Templates.GroupUser.About.BGMeta.Author.Username}} - {{end}}{{.Templates.GroupUser.About.BGMeta.Title}}" src="{{.Templates.GroupUser.About.BG}}"></a>
+ {{end}}
+
+ <img src="{{.BasePath}}media/emojitar/{{.Templates.GroupUser.GR.Owner.Username}}?type=a" width="30px" height="30px"> <b>{{.Templates.GroupUser.GR.Owner.Username}}</b>
+ {{if (eq .Templates.GroupUser.About.A.Gender "male")}}
+ ♂️
+ {{end}}
+ {{if (eq .Templates.GroupUser.About.A.Gender "female")}}
+ ♀️
+ {{end}}
+ [<span title="UID">{{.Templates.GroupUser.GR.Gruser.ID}}</span>]
+ [<span title="Registration date">{{.Templates.GroupUser.CreationDate}}</span>]
+ {{if ne .Templates.GroupUser.GR.Extra.Tag ""}}
+ <i title="User's Tag">"{{.Templates.GroupUser.GR.Extra.Tag}}"</i>{{end}} {{if ne .Templates.GroupUser.About.A.Country ""}}
+ (<b>{{.Templates.GroupUser.About.A.Country}}</b>)
+ {{end}}
+
+ {{if .Templates.GroupUser.Group}}
+ <h3 id="stats"><a href="#stats">#</a> Statistics</h3>
+ <p>Watchers: <b>{{.Templates.GroupUser.GR.Extra.Stats.Watchers}}</b>; Pageviews: <b>{{.Templates.GroupUser.GR.Extra.Stats.Pageviews}}</b></b>
+ {{else}}
+ <h3 id="stats"><a href="#stats">#</a> Statistics</h3>
+ <p>Favourites: <b>{{.Templates.GroupUser.GR.Extra.Stats.Favourites}}</b>; Deviations: <b>{{.Templates.GroupUser.GR.Extra.Stats.Deviations}}</b>; Watchers: <b>{{.Templates.GroupUser.GR.Extra.Stats.Watchers}}</b>
+ <p>Watching: <b>{{.Templates.GroupUser.GR.Extra.Stats.Watching}}</b>; Pageviews: <b>{{.Templates.GroupUser.GR.Extra.Stats.Pageviews}}</b>; Comments Made: <b>{{.Templates.GroupUser.GR.Extra.Stats.CommentsMade}}</b>; Friends: <b>{{.Templates.GroupUser.GR.Extra.Stats.Friends}}</b></p>
+ {{end}}
+
+ {{if ne .Templates.GroupUser.Admins ""}}
+ <h3 id="admins"><a href="#admins">#</a> Group admins</h3>
+ <div class="plates admins">
+ {{.Templates.GroupUser.Admins}}
+ </div>
+ {{end}}
+
+ {{if ne .Templates.GroupUser.About.Interests ""}}
+ <h3 id="interests"><a href="#interests">#</a> Interests</h3>
+ {{.Templates.GroupUser.About.Interests}}
+ {{end}}
+
+ {{if ne .Templates.GroupUser.About.Social ""}}
+ <h3 id="social"><a href="#social">#</a> Social Links</h3>
+ {{.Templates.GroupUser.About.Social}}
+ {{end}}
+
+ {{if ne .Templates.GroupUser.About.DescriptionFormatted ""}}
+ <h3 id="about"><a href="#about">#</a> About me</h3>
+ {{.Templates.GroupUser.About.DescriptionFormatted}}
+ {{end}}
+ {{if ne .Templates.GroupUser.About.Comments ""}}
+ <br>
+ <h3 id="comments"><a href="#comments">#</a> Comments</h3>
+ {{.Templates.GroupUser.About.Comments}}
+ {{end}}
+ {{else}}
+ {{.Templates.GroupUser.Gallery.Folders}}
+ {{.Templates.GroupUser.Gallery.List}}
+ {{end}}
+ </main>
+</html>
diff --git a/static/html/head.htm b/static/html/head.htm
new file mode 100644
index 0000000..f7f6b91
--- /dev/null
+++ b/static/html/head.htm
@@ -0,0 +1,24 @@
+{{define "head"}}
+<head>
+ <title>SkunkyArt |
+ {{if eq .Endpoint "search"}}
+ "{{.QueryRaw}}"
+ {{else if eq .Endpoint "post"}}
+ {{.Templates.Deviation.Post.Deviation.Author.Username}} — {{.Templates.Deviation.Post.Deviation.Title}}
+ {{else if eq .Type 'a'}}
+ {{if .Templates.GroupUser.GR.Owner.Username}}
+ {{.Templates.GroupUser.GR.Owner.Username}}
+ {{else}}
+ gallery of {{.Templates.GroupUser.GR.Owner.Username}}
+ {{end}}
+ {{else}}
+ {{.Endpoint}}
+ {{end}}
+ </title>
+
+ <base href="{{.BasePath}}">
+ <meta name="referrer" content="no-referrer" />
+ <link rel="stylesheet" href="{{.BasePath}}stylesheet">
+ <link rel="icon" type="image/x-icon" href="{{.BasePath}}favicon.ico">
+</head>
+{{end}} \ No newline at end of file
diff --git a/static/html/header.htm b/static/html/header.htm
new file mode 100644
index 0000000..f8537a3
--- /dev/null
+++ b/static/html/header.htm
@@ -0,0 +1,14 @@
+{{define "header"}}
+<header>
+ <h1><a href="">HOME</a> | <a href="dd">DD</a> {{if eq .Endpoint "dd"}}| <a href="{{.Endpoint}}?atom=true">RSS</a>{{end}}</h1>
+ <form method="get" action="search">
+ <input type="text" name="q" placeholder="Search for ..." autocomplete="off" autocapitalize="none" spellcheck="false" value="{{.QueryRaw}}">
+ <select name="type">
+ <option value="all">All</option>
+ <option value="tag">Tag</option>
+ <option value="r">Groups</option>
+ </select>
+ <button type="submit">Search!</button>
+ </form>
+</header>
+{{end}} \ No newline at end of file
diff --git a/static/html/index.htm b/static/html/index.htm
new file mode 100644
index 0000000..78f1d8a
--- /dev/null
+++ b/static/html/index.htm
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>SkunkyArt</title>
+ <link rel="stylesheet" href="stylesheet"/>
+ <link rel="icon" type="image/x-icon" href="favicon.ico">
+ </head>
+ <main>
+ <center>
+ <form method="get" action="search">
+ <input type="text" name="q" placeholder="Search for ..." autocomplete="off" autocapitalize="none" spellcheck="false">
+ <select name="type">
+ <option value="all">All</option>
+ <option value="tag">Tag</option>
+ <option value="r">Groups</option>
+ </select>
+ <button type="submit">Search!</button>
+ </form>
+ <h1><a href="dd">Daily Deviations</a> | <a href="about">About</a> | <a href="https://git.macaw.me/skunky/SkunkyArt" target="_blank">Source Code</a></h1>
+ </center>
+ </main>
+</html> \ No newline at end of file
diff --git a/static/html/search.htm b/static/html/search.htm
new file mode 100644
index 0000000..74bbd38
--- /dev/null
+++ b/static/html/search.htm
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+ {{template "head" . }}
+ <main>
+ {{template "header" . }}
+
+ {{if ne .Templates.Search.List ""}}
+ {{if ne .Templates.Search.Content.Total 0}}
+ <h1>Results by request '{{.QueryRaw}}': {{.Templates.Search.Content.Total}}</h1>
+ {{end}}
+ {{.Templates.Search.List}}
+ {{else}}
+ <p>No results :(</p>
+ {{end}}
+ </main>
+</html> \ No newline at end of file
diff --git a/static/images/logo.png b/static/images/logo.png
new file mode 100644
index 0000000..e895de7
--- /dev/null
+++ b/static/images/logo.png
Binary files differ
diff --git a/static/templates-noembed.go b/static/templates-noembed.go
new file mode 100644
index 0000000..7a3c541
--- /dev/null
+++ b/static/templates-noembed.go
@@ -0,0 +1,148 @@
+//go:build !embed
+// +build !embed
+
+package static
+
+import (
+ "bytes"
+ "io/fs"
+ "os"
+ "strings"
+ "time"
+)
+
+var Templates FS
+
+type file struct {
+ path string
+ name string
+ content []byte
+}
+
+var templateNames = []string{}
+var templates = make(map[string][]file)
+var StaticPath string
+
+func CopyTemplatesToMemory() {
+ baseDir, err := os.ReadDir(StaticPath)
+ try(err)
+
+ for _, c := range baseDir {
+ if c.IsDir() {
+ templateNames = append(templateNames, c.Name())
+
+ var filePath strings.Builder
+ filePath.WriteString(StaticPath)
+ filePath.WriteString("/")
+ filePath.WriteString(c.Name())
+
+ dir, err := os.ReadDir(filePath.String())
+ try(err)
+
+ filePath.WriteString("/")
+ for _, cd := range dir {
+ f, err := os.ReadFile(filePath.String() + cd.Name())
+ try(err)
+ templates[c.Name()] = append(templates[c.Name()], file{
+ content: f,
+ name: cd.Name(),
+ path: c.Name() + "/" + cd.Name(),
+ })
+ }
+ }
+ }
+}
+
+type FS struct{}
+
+func (FS) Open(name string) (fs.File, error) {
+ for i, l := 0, len(templateNames); i < l; i++ {
+ for _, x := range templates[templateNames[i]] {
+ if x.content != nil && name == x.path {
+ return &File{
+ name: x.path,
+ content: bytes.NewBuffer(x.content),
+ }, nil
+ }
+ }
+ }
+ return nil, &fs.PathError{}
+}
+
+func (FS) Glob(pattern string) ([]string, error) {
+ trimmed := strings.Split(pattern, "/")
+ var matches = []string{}
+ for x, s := range templates {
+ for i, l := 0, len(s); i < l && trimmed[0] == x; i++ {
+ s := s[i]
+ matches = append(matches, s.path)
+ }
+ }
+ if len(matches) != 0 {
+ return matches, nil
+ }
+ return nil, &fs.PathError{}
+}
+
+func try(err error) {
+ if err != nil {
+ println(err.Error())
+ os.Exit(1)
+ }
+}
+
+/* сделано на основе https://github.com/psanford/memfs; требуется для корректной работы templates.ParseFS */
+type fileInfo struct {
+ name string
+}
+
+func (fi fileInfo) Name() string {
+ return fi.name
+}
+
+func (fi fileInfo) Size() int64 {
+ return 4096
+}
+
+func (fileInfo) Mode() fs.FileMode {
+ return 0
+}
+
+func (fileInfo) ModTime() time.Time {
+ return time.Time{}
+}
+
+func (fileInfo) IsDir() bool {
+ return false
+}
+
+func (fileInfo) Sys() interface{} {
+ return nil
+}
+
+type File struct {
+ name string
+ content *bytes.Buffer
+ closed bool
+}
+
+func (f *File) Stat() (fs.FileInfo, error) {
+ return fileInfo{
+ name: f.name,
+ }, nil
+}
+
+func (f *File) Read(b []byte) (int, error) {
+ if f.closed {
+ return 0, fs.ErrClosed
+ }
+ return f.content.Read(b)
+}
+
+func (f *File) Close() error {
+ if f.closed {
+ return fs.ErrClosed
+ }
+ f.closed = true
+ return nil
+}
diff --git a/static/templates.go b/static/templates.go
new file mode 100644
index 0000000..28a057a
--- /dev/null
+++ b/static/templates.go
@@ -0,0 +1,16 @@
+//go:build embed
+// +build embed
+
+package static
+
+import "embed"
+
+//go:embed *
+var Templates embed.FS
+var Enabled bool = true
+
+var StaticPath string
+
+func CopyTemplatesToMemory() {
+ _ = StaticPath
+}