diff --git a/assets/js/editor-artifact.js b/assets/js/editor-artifact.js
index 990c322b..5cbb87ce 100644
--- a/assets/js/editor-artifact.js
+++ b/assets/js/editor-artifact.js
@@ -10,7 +10,7 @@ import {
youtube as validateYouTube,
number as validateNumber,
} from "./artifact-validate.mjs";
-import { clipValue, getElmById } from "./helper.mjs";
+import { clipValue, getElmById, titleize } from "./helper.mjs";
(() => {
"use strict";
@@ -283,6 +283,15 @@ import { clipValue, getElmById } from "./helper.mjs";
title.value = titleU[0].value;
title.classList.add("is-valid");
});
+ const titleizeBtn = document.getElementById("artifact-editor-titleize");
+ if (titleizeBtn.length === 0) {
+ throw new Error("The titleize button is missing.");
+ }
+ titleizeBtn.addEventListener("click", () => {
+ title.value = titleize(title.value);
+ let event = new Event("keyup");
+ title.dispatchEvent(event);
+ });
const ct = document.getElementById("artifact-editor-credit-text");
if (ct === null) {
diff --git a/assets/js/helper.mjs b/assets/js/helper.mjs
index 4b58bd5d..db5157c6 100644
--- a/assets/js/helper.mjs
+++ b/assets/js/helper.mjs
@@ -3,6 +3,40 @@
* This module provides functions for handling common tasks.
*/
+/**
+ * Titleizes a string of text but keeps common adverbs in lowercase.
+ *
+ * @param {string} text - The input text to be titleized.
+ * @returns {string} - The titleized text.
+ */
+export function titleize(text) {
+ const commonAdverbs = [
+ "a",
+ "an",
+ "and",
+ "as",
+ "but",
+ "for",
+ "if",
+ "of",
+ "or",
+ "so",
+ "the",
+ "to",
+ ];
+ return text
+ .split(" ")
+ .map((word, index) => {
+ // Capitalize the first word and any word not in the common adverbs list
+ if (index === 0 || !commonAdverbs.includes(word.toLowerCase())) {
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
+ }
+ // Keep common adverbs in lowercase
+ return word.toLowerCase();
+ })
+ .join(" ");
+}
+
/**
* Copies the text content of an HTML element to the clipboard.
* @async
diff --git a/go.mod b/go.mod
index 51b0bcdd..763ed1eb 100644
--- a/go.mod
+++ b/go.mod
@@ -3,9 +3,9 @@ module github.com/Defacto2/server
go 1.22.7
require (
- github.com/Defacto2/archive v1.0.2
- github.com/Defacto2/helper v1.1.2
- github.com/Defacto2/magicnumber v1.0.1
+ github.com/Defacto2/archive v1.0.3
+ github.com/Defacto2/helper v1.1.3
+ github.com/Defacto2/magicnumber v1.0.2
github.com/Defacto2/releaser v1.0.4
github.com/caarlos0/env/v11 v11.2.2
github.com/carlmjohnson/versioninfo v0.22.5
@@ -33,11 +33,6 @@ require (
gopkg.in/natefinch/lumberjack.v2 v2.2.1
)
-// replace (
-// github.com/Defacto2/archive => /home/ben/github/archive
-// github.com/Defacto2/helper => /home/ben/github/helper
-// )
-
require (
cloud.google.com/go/auth v0.9.4 // indirect
cloud.google.com/go/auth/oauth2adapt v0.2.4 // indirect
diff --git a/go.sum b/go.sum
index 4be09fd0..c5b6b2b7 100644
--- a/go.sum
+++ b/go.sum
@@ -69,12 +69,12 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/DATA-DOG/go-sqlmock v1.4.1 h1:ThlnYciV1iM/V0OSF/dtkqWb6xo5qITT1TJBG1MRDJM=
github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
-github.com/Defacto2/archive v1.0.2 h1:kibNK3ZFoB87XIeDolxQ6uDbdCnBvDNygJtgngE3prM=
-github.com/Defacto2/archive v1.0.2/go.mod h1:0/aa1BwDOBp4d87R/N33Lcr3+WzELv041wunK8R5A5c=
-github.com/Defacto2/helper v1.1.2 h1:HVJnWI9a0nA7vOcfO3BZTSPGNftNS678wf6daMrjbE0=
-github.com/Defacto2/helper v1.1.2/go.mod h1:IikMmXvNy3uOcLk4/cEi9mb+xcx8AHPsSmVGd8SKpB0=
-github.com/Defacto2/magicnumber v1.0.1 h1:UmiBUrYwTk3NPR1lGaaQ3Js+3YllBRf9XxSKInE3Da4=
-github.com/Defacto2/magicnumber v1.0.1/go.mod h1:SIr4UUO0htkx89FNTdUIpuCbuZqW9uYC5spvWl9bBtk=
+github.com/Defacto2/archive v1.0.3 h1:7iidbFf3yBJ0e2XWsx/uhB4ciWysE5nMejzRCQSgops=
+github.com/Defacto2/archive v1.0.3/go.mod h1:1nM/bBCir4nz1t/HFYnZk9tXc/yaWzJTEu1+CDoGyUE=
+github.com/Defacto2/helper v1.1.3 h1:BS7PqOR31AtXC+BTKM9oL2OE+NLrdLqd8xyBxwAsCps=
+github.com/Defacto2/helper v1.1.3/go.mod h1:IikMmXvNy3uOcLk4/cEi9mb+xcx8AHPsSmVGd8SKpB0=
+github.com/Defacto2/magicnumber v1.0.2 h1:zElw+GCZiS0n4xta6g7WDp9ovx1RZKRYL+q9zj0l4dk=
+github.com/Defacto2/magicnumber v1.0.2/go.mod h1:U64FNRfNyv5tBE6jPU00ortSbrIAVO5V34tZFwaeA3s=
github.com/Defacto2/releaser v1.0.4 h1:dM7epo3Rk+l2NAH4/dMHzo9QCIC6VejhptlhPUtfg3U=
github.com/Defacto2/releaser v1.0.4/go.mod h1:Jt9HqJDl4ol1oKFb2efvO+8d8buFwSYfn/Trh7O3oLw=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
diff --git a/handler/app/dirs.go b/handler/app/dirs.go
index 20ba8de2..4cf12432 100644
--- a/handler/app/dirs.go
+++ b/handler/app/dirs.go
@@ -28,6 +28,7 @@ import (
"github.com/Defacto2/server/handler/readme"
"github.com/Defacto2/server/handler/render"
"github.com/Defacto2/server/handler/sess"
+ "github.com/Defacto2/server/internal/command"
"github.com/Defacto2/server/internal/postgres/models"
"github.com/Defacto2/server/internal/tags"
"github.com/Defacto2/server/model"
@@ -182,18 +183,23 @@ func (dir Dirs) updateMagics(db *sql.DB, logger *zap.SugaredLogger,
}
return data
}
- switch modMagic {
- case
- magicnumber.ARChiveSEA.Title(),
- magicnumber.YoshiLHA.Title(),
- magicnumber.ArchiveRobertJung.Title(),
- magicnumber.PKWAREZipImplode.Title(),
- magicnumber.PKWAREZipReduce.Title(),
- magicnumber.PKWAREZipShrink.Title():
- case magicnumber.PKWAREZip.Title():
+ switch {
+ case redundantArchive(modMagic):
+ case modMagic == magicnumber.PKWAREZip.Title():
if !repackZIP(name) {
return data
}
+ case plainText(modMagic):
+ dirs := command.Dirs{
+ Download: dir.Download,
+ Preview: dir.Preview,
+ Thumbnail: dir.Thumbnail,
+ }
+ if err := dirs.TextImager(logger, name, uid); err != nil {
+ logger.Error(errorWithID(err, "text imager", uid))
+ }
+ data["missingAssets"] = ""
+ return data
default:
return data
}
@@ -211,6 +217,43 @@ func (dir Dirs) updateMagics(db *sql.DB, logger *zap.SugaredLogger,
return data
}
+func redundantArchive(modMagic interface{}) bool {
+ switch modMagic.(type) {
+ case string:
+ default:
+ return false
+ }
+ switch modMagic.(string) {
+ case
+ magicnumber.ARChiveSEA.Title(),
+ magicnumber.YoshiLHA.Title(),
+ magicnumber.ArchiveRobertJung.Title(),
+ magicnumber.PKWAREZipImplode.Title(),
+ magicnumber.PKWAREZipReduce.Title(),
+ magicnumber.PKWAREZipShrink.Title():
+ return true
+ default:
+ return false
+ }
+}
+
+func plainText(modMagic interface{}) bool {
+ switch modMagic.(type) {
+ case string:
+ default:
+ return false
+ }
+ switch modMagic.(string) {
+ case
+ magicnumber.UTF8Text.Title(),
+ magicnumber.ANSIEscapeText.Title(),
+ magicnumber.PlainText.Title():
+ return true
+ default:
+ return false
+ }
+}
+
func (dir Dirs) embed(art *models.File, data map[string]interface{}) (map[string]interface{}, error) {
if art == nil {
return data, nil
diff --git a/handler/app/internal/filerecord/filerecord.go b/handler/app/internal/filerecord/filerecord.go
index 74897f1d..010d6c04 100644
--- a/handler/app/internal/filerecord/filerecord.go
+++ b/handler/app/internal/filerecord/filerecord.go
@@ -119,7 +119,7 @@ func (m ListEntry) Column2(htm string) string {
``
case osTool(ext):
htm += blank
- case m.Texts && !soloText():
+ case m.Texts || soloText():
htm += readmecopy(m.UniqueID, name)
default:
htm += blank
diff --git a/handler/router.go b/handler/router.go
index fca85fdc..92882586 100644
--- a/handler/router.go
+++ b/handler/router.go
@@ -116,6 +116,7 @@ func (c Configuration) embed(e *echo.Echo, public embed.FS) *echo.Echo {
e.FileFS("/osd.xml", "public/text/osd.xml", public)
e.FileFS("/robots.txt", "public/text/robots.txt", public)
e.FileFS("/site.webmanifest", "public/text/site.webmanifest.json", public)
+ e.FileFS("/wdosbox.wasm.js", "public/js/wdosbox.wasm", public) // this is required by `js-dos.js`
return e
}
diff --git a/internal/command/command.go b/internal/command/command.go
index 74f22b23..9add37c5 100644
--- a/internal/command/command.go
+++ b/internal/command/command.go
@@ -3,6 +3,7 @@ package command
import (
"bytes"
+ "context"
"errors"
"fmt"
"io"
@@ -10,28 +11,30 @@ import (
"os/exec"
"path/filepath"
"strings"
+ "time"
"go.uber.org/zap"
)
const (
- pattern = "defacto2-" // prefix for temporary directories
- patternS = "defacto2-server"
- arc = ".arc" // arc file extension
- arj = ".arj" // arj file extension
- bmp = ".bmp" // bmp file extension
- gif = ".gif" // gif file extension
- gzip = ".gz" // gzip file extension
- jpg = ".jpg" // jpg file extension
- jpeg = ".jpeg" // jpeg file extension
- png = ".png" // png file extension
- rar = ".rar" // rar file extension
- tar = ".tar" // tar file extension
- tiff = ".tiff" // tiff file extension
- txt = ".txt" // txt file extension
- webp = ".webp" // webp file extension
- zip = ".zip" // zip file extension
- zip7 = ".7z" // 7zip file extension
+ cmdTimeout = 10 * time.Second
+ pattern = "defacto2-" // prefix for temporary directories
+ patternS = "defacto2-server"
+ arc = ".arc" // arc file extension
+ arj = ".arj" // arj file extension
+ bmp = ".bmp" // bmp file extension
+ gif = ".gif" // gif file extension
+ gzip = ".gz" // gzip file extension
+ jpg = ".jpg" // jpg file extension
+ jpeg = ".jpeg" // jpeg file extension
+ png = ".png" // png file extension
+ rar = ".rar" // rar file extension
+ tar = ".tar" // tar file extension
+ tiff = ".tiff" // tiff file extension
+ txt = ".txt" // txt file extension
+ webp = ".webp" // webp file extension
+ zip = ".zip" // zip file extension
+ zip7 = ".7z" // 7zip file extension
)
var (
@@ -215,7 +218,9 @@ func RunStdOut(name string, arg ...string) ([]byte, error) {
return nil, fmt.Errorf("run output %w", err)
}
var out bytes.Buffer
- cmd := exec.Command(name, arg...)
+ ctx, cancel := context.WithTimeout(context.Background(), cmdTimeout)
+ defer cancel()
+ cmd := exec.CommandContext(ctx, name, arg...)
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
return nil, fmt.Errorf("run output cmd.run %w", err)
@@ -228,7 +233,9 @@ func RunQuiet(name string, arg ...string) error {
if err := LookCmd(name); err != nil {
return fmt.Errorf("run quiet %w", err)
}
- cmd := exec.Command(name, arg...)
+ ctx, cancel := context.WithTimeout(context.Background(), cmdTimeout)
+ defer cancel()
+ cmd := exec.CommandContext(ctx, name, arg...)
if err := cmd.Start(); err != nil {
return fmt.Errorf("run quiet start %w", err)
}
@@ -249,7 +256,9 @@ func run(debug *zap.SugaredLogger, name, wdir string, arg ...string) error {
if err := LookCmd(name); err != nil {
return fmt.Errorf("run %w", err)
}
- cmd := exec.Command(name, arg...)
+ ctx, cancel := context.WithTimeout(context.Background(), cmdTimeout)
+ defer cancel()
+ cmd := exec.CommandContext(ctx, name, arg...)
cmd.Dir = wdir
if debug != nil {
p, err := cmd.CombinedOutput()
diff --git a/internal/command/images.go b/internal/command/images.go
index 7c81cd99..9bc86e1a 100644
--- a/internal/command/images.go
+++ b/internal/command/images.go
@@ -5,6 +5,7 @@ package command
// and other command-line tools.
import (
+ "bufio"
"errors"
"fmt"
"io"
@@ -297,14 +298,85 @@ func (dir Dirs) PictureImager(debug *zap.SugaredLogger, src, unid string) error
return nil
}
+// Write80x29 reads the src text file and writes the first 29 lines of text to the dst file.
+// The text is truncated to 80 characters per line. Empty newlines at the start of the file
+// are ignored.
+//
+// The function is useful for creating a preview of text files in the 80x29 format that
+// can be used by the ANSILOVE command to create a PNG image. 80 columns and 29 rows are
+// works well with a 400x400 pixel thumbnail.
+func Write80x29(src, dst string) error {
+ srcFile, err := os.Open(src)
+ if err != nil {
+ return fmt.Errorf("write 80x29 open %w", err)
+ }
+ defer srcFile.Close()
+ dstFile, err := os.Create(dst)
+ if err != nil {
+ return fmt.Errorf("write 80x29 create %w", err)
+ }
+ defer dstFile.Close()
+
+ scanner := bufio.NewScanner(srcFile)
+ writer := bufio.NewWriter(dstFile)
+ defer writer.Flush()
+
+ const maxColumns, maxRows = 80, 29
+ rowCount := 0
+ skipNL := true
+
+ for scanner.Scan() {
+ line := scanner.Text()
+ if line == "" || line == "\n" || line == "\r" || line == "\r\n" {
+ if skipNL {
+ continue
+ }
+ line = ""
+ }
+ if rowCount >= maxRows {
+ break
+ }
+
+ if len(line) > maxColumns {
+ trimmedLine := line[:maxColumns]
+ line = trimmedLine
+ }
+ _, err := writer.WriteString(line + "\n")
+ if err != nil {
+ return fmt.Errorf("write 80x29 writer string %w", err)
+ }
+ // intentionally skip the first line in a file
+ // as sometimes these contain non-printable characters and control codes.
+ fileLine := rowCount == 0
+ if skipNL && !fileLine {
+ skipNL = false
+ }
+ rowCount++
+ }
+ if err := scanner.Err(); err != nil {
+ return fmt.Errorf("write 80x29 scanner %w", err)
+ }
+ return nil
+}
+
// TextImager converts the src text file and creates a PNG image in the preview directory.
// A webp thumbnail image is also created and copied to the thumbnail directory.
func (dir Dirs) TextImager(debug *zap.SugaredLogger, src, unid string) error {
args := Args{}
args.AnsiMsDos()
- arg := []string{src} // source file
+
+ path, err := helper.MkContent(src)
+ if err != nil {
+ return err
+ }
+ defer os.RemoveAll(path)
+ tmpText := filepath.Join(path, unid+".txt")
+ if err = Write80x29(src, tmpText); err != nil {
+ return fmt.Errorf("dirs text imager %w", err)
+ }
+ arg := []string{tmpText} // source text file
arg = append(arg, args...) // command line arguments
- tmp := BaseNamePath(src) + png // destination
+ tmp := BaseNamePath(src) + png // destination file
arg = append(arg, "-o", tmp)
if err := Run(nil, Ansilove, arg...); err != nil {
return fmt.Errorf("dirs text imager %w", err)
@@ -318,9 +390,20 @@ func (dir Dirs) TextImager(debug *zap.SugaredLogger, src, unid string) error {
func (dir Dirs) TextAmigaImager(debug *zap.SugaredLogger, src, unid string) error {
args := Args{}
args.AnsiMsDos()
- arg := []string{src} // source file
+
+ path, err := helper.MkContent(src)
+ if err != nil {
+ return err
+ }
+ defer os.RemoveAll(path)
+ tmpText := filepath.Join(path, unid+".txt")
+ if err = Write80x29(src, tmpText); err != nil {
+ return fmt.Errorf("dirs text imager %w", err)
+ }
+
+ arg := []string{tmpText} // source text file
arg = append(arg, args...) // command line arguments
- tmp := BaseNamePath(src) + png // destination
+ tmp := BaseNamePath(src) + png // destination file
arg = append(arg, "-o", tmp)
if err := Run(nil, Ansilove, arg...); err != nil {
return fmt.Errorf("dirs ami text imager %w", err)
diff --git a/public/js/editor-artifact.min.js b/public/js/editor-artifact.min.js
index d13f7889..d1dbfc15 100644
--- a/public/js/editor-artifact.min.js
+++ b/public/js/editor-artifact.min.js
@@ -1,2 +1,2 @@
/* editor-artifact.min.js © Defacto2 2024 */
-(()=>{function R(t,i,r){if(t==null)throw new Error("The year input element is null.");if(i==null)throw new Error("The month input element is null.");if(r==null)throw new Error("The day input element is null.");t.classList.remove("is-invalid","is-valid"),i.classList.remove("is-invalid","is-valid"),r.classList.remove("is-invalid","is-valid");let o=parseInt(t.value,10);isNaN(o)?t.value="0":t.value=o;let s=parseInt(i.value,10);isNaN(s)?i.value="0":i.value=s;let a=parseInt(r.value,10);isNaN(a)?r.value="0":r.value=a;let l=0,w=new Date().getFullYear(),g=o>=1980&&o<=w;o>l&&!g&&t.classList.add("is-invalid");let M=s>=1&&s<=12;s>l&&!M&&i.classList.add("is-invalid");let p=a>=1&&a<=31;a>l&&!p&&r.classList.add("is-invalid"),isNaN(o)&&(M||p)&&t.classList.add("is-invalid"),(s==l||isNaN(s))&&p&&i.classList.add("is-invalid")}function fe(t){return he(t,!0)}function ge(t){return he(t,!1)}function he(t,i){if(t==null)throw new Error("The repository URL element is null.");t.classList.remove("is-valid","is-invalid");let r=t.value.trim();if(r.length===0)return;if(i==!0&&r.startsWith("refs/")){t.classList.add("is-invalid");return}if(r.includes("://")){t.classList.add("is-invalid");return}let s=/[^A-Za-z0-9-._/]/g;r=r.replace(s,""),r=r.replaceAll("//","/");let a=/^\//;r=r.replace(a,""),t.value=r;let l=t.getAttribute("maxlength");if(l===null)throw new Error(`The maxlength attribute is required for ${t.id}.`);if(r.length>l){t.classList.add("is-invalid");return}}function B(t){if(t==null)throw new Error("The element of the releaser validator is null.");t.classList.remove("is-valid","is-invalid");let i=t.value.trim().toUpperCase();i=i.replace("+",", "),i=i.replace(/[^ A-ZÀ-ÖØ-Þ0-9\-,&]/g,""),t.value=i;let r=t.getAttribute("minlength"),o=t.getAttribute("maxlength"),s=t.getAttribute("required");if(r===null)throw new Error(`The minlength attribute is required for ${t.id}.`);if(o===null)throw new Error(`The maxlength attribute is required for ${t.id}.`);let a=document.getElementById("artifact-editor-releasers-error");if(a===null)throw new Error("The releasers error element is null.");let l=i.lengtho;if(s!=null&&l){t.classList.add("is-invalid"),t.id==="-1"&&a.classList.add("d-block");return}let w=i.length>0&&(i.lengtho);if(s==null&&w){t.classList.add("is-invalid");return}t.classList.remove("is-invalid"),a.classList.remove("d-block")}function Ee(t){if(t==null)throw new Error("The element of the releaser validator is null.");t.classList.remove("is-valid","is-invalid");let i=t.value.trim();i.length>0&&i.length!=11&&t.classList.add("is-invalid")}function Z(t,i){if(t==null)throw new Error("The element of the number validator is null.");t.classList.remove("is-valid","is-invalid");let r=parseInt(t.value,10);isNaN(r)&&t.classList.add("is-invalid"),(r>i||r<0)&&t.classList.add("is-invalid")}async function T(t){let i=d(t);i.focus(),await navigator.clipboard.writeText(`${i.value}`).then(function(){console.log(`Copied ${be(i.value.length)} to the clipboard`)},function(r){console.error(`could not save any text to the clipboard: ${r}`)})}function d(t){let i=document.getElementById(t);if(i==null)throw new Error(`The ${t} for getElmById() element is null.`);return i}function be(t=0){let s=Math.pow(1e3,2),a=Math.pow(1e3,3);return t>a?`${(Math.round(t*100/a)/100).toFixed(2)} GB`:t>s?`${(Math.round(t*100/s)/100).toFixed(1)} MB`:t>1e3?`${(Math.round(t*100/1e3)/100).toFixed()} kB`:`${Math.round(t).toFixed()} bytes`}(()=>{"use strict";function t(e){return function(){e.forEach(n=>{n.disabled=!0,n.classList.remove("btn-outline-primary"),n.classList.add("btn-light")})}}function i(e){return function(){e.forEach(n=>{n.disabled=!1,n.classList.remove("btn-light"),n.classList.add("btn-outline-primary")})}}let r=document.getElementById("artifact-editor-modal"),o=document.getElementsByName("artifact-editor-dataeditor");r.addEventListener("shown.bs.modal",()=>{t(o)()}),r.addEventListener("hidden.bs.modal",()=>{i(o)()});let s=document.getElementById("asset-editor-modal"),a=document.getElementsByName("artifact-editor-fileeditor");s.addEventListener("shown.bs.modal",()=>{t(a)()}),s.addEventListener("hidden.bs.modal",()=>{i(a)()});let l=document.getElementById("emulate-editor-modal"),w=document.getElementsByName("artifact-editor-emueditor");l.addEventListener("shown.bs.modal",()=>{t(w)()}),l.addEventListener("hidden.bs.modal",()=>{i(w)()});let g=document.getElementById("emulate-run-program");if(g!==null){let e=document.getElementById("emulate-guess-program");if(e===null)throw new Error("The guess program input is missing.");g.addEventListener("input",()=>{if(g.value=g.value.toUpperCase(),g.value!==""){e.disabled=!0;return}e.disabled=!1})}if(d("artifact-editor-key-value")===null)throw new Error("The key value is missing.");let p=d("artifact-editor-key-label");if(p===null)throw new Error("The key label is missing.");if(p.addEventListener("click",()=>T("artifact-editor-key-value")),d("artifact-editor-unique-id-value")===null)throw new Error("The unique id value is missing.");let O=d("artifact-editor-unique-id-label");if(O===null)throw new Error("The unique id label is missing.");if(O.addEventListener("click",()=>T("artifact-editor-unique-id-value")),d("artifact-editor-location-value")===null)throw new Error("The location value is missing.");let _=d("artifact-editor-location-label");if(_===null)throw new Error("The location label is missing.");if(_.addEventListener("click",()=>T("artifact-editor-location-value")),d("artifact-editor-templocation")!==null&&d("artifact-editor-templocation-label").addEventListener("click",()=>T("artifact-editor-templocation")),document.getElementById("artifact-editor-os-label")===null)throw new Error("The operating system label is missing.");let h=document.getElementById("artifact-editor-operating-system");if(h===null)throw new Error("The operating system input is missing.");h.addEventListener("input",C);let E=document.getElementById("artifact-editor-category");if(E===null)throw new Error("The category input is missing.");E.addEventListener("input",U),C(),U();function C(){h.selectedIndex==0&&(h.classList.remove("is-valid"),h.classList.add("is-invalid"))}function U(){E.selectedIndex==0&&(E.classList.remove("is-valid"),E.classList.add("is-invalid"))}let Y=document.getElementsByName("prereset-classifications");if(Y.length===0)throw new Error("The preset classifications are missing.");for(let e=0;e{W.preventDefault(),h.value=v,h.classList.remove("is-invalid"),E.value=q,E.classList.remove("is-invalid"),C(),U()})}let f=document.getElementById("artifact-editor-filename");if(f===null)throw new Error("The filename input is missing.");f.addEventListener("input",e=>{e.target.classList.remove("is-valid"),e.target.classList.remove("is-invalid"),e.target.value.trim().length===0&&e.target.classList.add("is-invalid")});let J=document.getElementById("artifact-editor-filename-reset");if(J===null)throw new Error("The filename reset is missing.");let D=document.getElementsByName("artifact-editor-filename-undo");if(D.length===0)throw new Error("The filename resetter is missing.");J.addEventListener("click",()=>{if(f.classList.remove("is-valid"),D.length===0)throw new Error("The filename resetter is missing.");f.value=D[0].value,f.classList.add("is-valid"),f.classList.remove("is-invalid"),f.value.trim().length===0&&f.classList.add("is-invalid")});let L=document.getElementById("artifact-editor-releaser-1");if(L===null)throw new Error("The releaser 1 input is missing.");L.addEventListener("input",e=>B(e.target));let y=document.getElementById("artifact-editor-releaser-2");if(y===null)throw new Error("The releaser 2 input is missing.");y.addEventListener("input",e=>B(e.target));let K=document.getElementById("artifact-editor-releaser-undo");if(K===null)throw new Error("The releasers reset is missing.");K.addEventListener("click",pe);function pe(){let e=L.getAttribute("data-reset-rel1");if(e===null)throw new Error("data-reset-rel1 attribute is required for artifact-editor-releaser-1.");L.value=e,B(L);let n=y.getAttribute("data-reset-rel2");if(n===null)throw new Error("data-reset-rel2 attribute is required for artifact-editor-releaser-2.");y.value=n,B(y)}let b=document.getElementById("artifact-editor-title");if(b===null)throw new Error("The title input is missing.");b.addEventListener("input",e=>{e.target.classList.remove("is-valid")});let Q=document.getElementById("artifact-editor-title-undo");if(Q===null)throw new Error("The title reset is missing.");let F=document.getElementsByName("artifact-editor-titleundo");if(F.length===0)throw new Error("The title resetter is missing.");Q.addEventListener("click",()=>{if(b.classList.remove("is-valid"),F.length===0)throw new Error("The title resetter is missing.");b.value=F[0].value,b.classList.add("is-valid")});let S=document.getElementById("artifact-editor-credit-text");if(S===null)throw new Error("The creator text input is missing.");S.addEventListener("input",e=>{e.target.classList.remove("is-valid")});let G=document.getElementById("artifact-editor-credit-ill");if(G===null)throw new Error("The creator illustrator input is missing.");G.addEventListener("input",e=>{e.target.classList.remove("is-valid")});let j=document.getElementById("artifact-editor-credit-prog");if(j===null)throw new Error("The creator programmer input is missing.");j.addEventListener("input",e=>{e.target.classList.remove("is-valid")});let z=document.getElementById("artifact-editor-credit-audio");if(z===null)throw new Error("The creator audio input is missing.");z.addEventListener("input",e=>{e.target.classList.remove("is-valid")});let H=document.getElementById("artifact-editor-credits-undo");if(H===null)throw new Error("The creator resetter is missing.");let X=document.getElementById("artifact-editor-credit-undo");if(X===null)throw new Error("The creator reset is missing.");X.addEventListener("click",()=>{if(H.length===0)throw new Error("The creator resetter is missing.");let e=H.value.split(";");if(e.length!=4)throw new Error("The creator resetter values are invalid.");let n=e[0],v=e[1],q=e[2],W=e[3];S.value=n,G.value=v,j.value=q,z.value=W});let I=document.getElementById("artifact-editor-comment");if(I===null)throw new Error("The comment input is missing.");I.addEventListener("input",e=>{e.target.classList.remove("is-valid")});let ee=document.getElementById("artifact-editor-comment-undo");if(ee===null)throw new Error("The comment reset is missing.");let te=document.getElementById("artifact-editor-comment-resetter");if(te===null)throw new Error("The comment resetter is missing.");ee.addEventListener("click",()=>{I.classList.remove("is-valid"),I.value=te.value});let ie=document.getElementById("artifact-editor-virustotal");if(ie===null)throw new Error("The virustotal input is missing.");ie.addEventListener("input",e=>{e.target.classList.remove("is-valid","is-invalid");let n=e.target.value.trim();n.length!=0&&(n.startsWith("https://www.virustotal.com/")||e.target.classList.add("is-invalid"))});let c=document.getElementById("artifact-editor-year");if(c===null)throw new Error("The year input is missing.");c.addEventListener("input",()=>{R(c,u,m)});let u=document.getElementById("artifact-editor-month");if(u===null)throw new Error("The month input is missing.");u.addEventListener("input",()=>{R(c,u,m)});let m=document.getElementById("artifact-editor-day");if(m===null)throw new Error("The day input is missing.");m.addEventListener("input",()=>{R(c,u,m)});let re=document.getElementById("artifact-editor-date-reset");if(re===null)throw new Error("The date reset is missing.");let ne=document.getElementById("artifact-editor-date-resetter");if(ne===null)throw new Error("The date resetter is missing.");re.addEventListener("click",()=>{c.classList.remove("is-invalid","is-valid"),u.classList.remove("is-invalid","is-valid"),m.classList.remove("is-invalid","is-valid");let n=ne.value.split("-");if(n.length!=3)throw new Error("The date resetter values are invalid.");c.value=n[0],u.value=n[1],m.value=n[2]});let se=document.getElementById("artifact-editor-date-lastmod");if(se!==null){let e=document.getElementById("artifact-editor-date-lastmodder");if(e===null)throw new Error("The date last modder input is missing.");se.addEventListener("click",()=>{c.classList.remove("is-invalid","is-valid"),u.classList.remove("is-invalid","is-valid"),m.classList.remove("is-invalid","is-valid");let v=e.value.split("-");if(v.length!=3)throw new Error("The date last modder values are invalid.");c.value=v[0],u.value=v[1],m.value=v[2]})}let ae=document.getElementById("artifact-editor-links-reset");if(ae===null)throw new Error("The links reset is missing.");let x=document.getElementById("artifact-editor-youtube"),oe=document.getElementById("artifact-editor-youtube-reset");if(x===null||oe===null)throw new Error("A YouTube input is missing.");let k=document.getElementById("artifact-editor-demozoo"),le=document.getElementById("artifact-editor-demozoo-reset");if(k===null||le===null)throw new Error("A Demozoo input is missing.");let N=document.getElementById("artifact-editor-pouet"),de=document.getElementById("artifact-editor-pouet-reset");if(N===null||de===null)throw new Error("A Pouet input is missing.");let $=document.getElementById("artifact-editor-16colors"),ce=document.getElementById("artifact-editor-16colors-reset");if($===null||ce===null)throw new Error("A 16colors input is missing.");let A=document.getElementById("artifact-editor-github"),ue=document.getElementById("artifact-editor-github-reset");if(A===null||ue===null)throw new Error("A GitHub input is missing.");let P=document.getElementById("artifact-editor-relations"),me=document.getElementById("artifact-editor-relations-reset");if(P===null||me===null)throw new Error("A relations input is missing.");let V=document.getElementById("artifact-editor-websites"),ve=document.getElementById("artifact-editor-websites-reset");if(V===null||ve===null)throw new Error("A websites input is missing.");ae.addEventListener("click",()=>{x.classList.remove("is-invalid","is-valid"),k.classList.remove("is-invalid","is-valid"),N.classList.remove("is-invalid","is-valid"),$.classList.remove("is-invalid","is-valid"),A.classList.remove("is-invalid","is-valid"),P.classList.remove("is-invalid","is-valid"),V.classList.remove("is-invalid","is-valid"),x.value=oe.value,k.value=le.value,N.value=de.value,$.value=ce.value,A.value=ue.value,P.value=me.value,V.value=ve.value});let Le=45e4,ye=2e5;x.addEventListener("input",e=>Ee(e.target)),k.addEventListener("input",e=>Z(e.target,Le)),N.addEventListener("input",e=>Z(e.target,ye)),$.addEventListener("input",e=>ge(e.target)),A.addEventListener("input",e=>fe(e.target))})();})();
+(()=>{function R(t,i,r){if(t==null)throw new Error("The year input element is null.");if(i==null)throw new Error("The month input element is null.");if(r==null)throw new Error("The day input element is null.");t.classList.remove("is-invalid","is-valid"),i.classList.remove("is-invalid","is-valid"),r.classList.remove("is-invalid","is-valid");let a=parseInt(t.value,10);isNaN(a)?t.value="0":t.value=a;let s=parseInt(i.value,10);isNaN(s)?i.value="0":i.value=s;let o=parseInt(r.value,10);isNaN(o)?r.value="0":r.value=o;let l=0,p=new Date().getFullYear(),h=a>=1980&&a<=p;a>l&&!h&&t.classList.add("is-invalid");let C=s>=1&&s<=12;s>l&&!C&&i.classList.add("is-invalid");let L=o>=1&&o<=31;o>l&&!L&&r.classList.add("is-invalid"),isNaN(a)&&(C||L)&&t.classList.add("is-invalid"),(s==l||isNaN(s))&&L&&i.classList.add("is-invalid")}function ge(t){return Ee(t,!0)}function he(t){return Ee(t,!1)}function Ee(t,i){if(t==null)throw new Error("The repository URL element is null.");t.classList.remove("is-valid","is-invalid");let r=t.value.trim();if(r.length===0)return;if(i==!0&&r.startsWith("refs/")){t.classList.add("is-invalid");return}if(r.includes("://")){t.classList.add("is-invalid");return}let s=/[^A-Za-z0-9-._/]/g;r=r.replace(s,""),r=r.replaceAll("//","/");let o=/^\//;r=r.replace(o,""),t.value=r;let l=t.getAttribute("maxlength");if(l===null)throw new Error(`The maxlength attribute is required for ${t.id}.`);if(r.length>l){t.classList.add("is-invalid");return}}function B(t){if(t==null)throw new Error("The element of the releaser validator is null.");t.classList.remove("is-valid","is-invalid");let i=t.value.trim().toUpperCase();i=i.replace("+",", "),i=i.replace(/[^ A-ZÀ-ÖØ-Þ0-9\-,&]/g,""),t.value=i;let r=t.getAttribute("minlength"),a=t.getAttribute("maxlength"),s=t.getAttribute("required");if(r===null)throw new Error(`The minlength attribute is required for ${t.id}.`);if(a===null)throw new Error(`The maxlength attribute is required for ${t.id}.`);let o=document.getElementById("artifact-editor-releasers-error");if(o===null)throw new Error("The releasers error element is null.");let l=i.lengtha;if(s!=null&&l){t.classList.add("is-invalid"),t.id==="-1"&&o.classList.add("d-block");return}let p=i.length>0&&(i.lengtha);if(s==null&&p){t.classList.add("is-invalid");return}t.classList.remove("is-invalid"),o.classList.remove("d-block")}function we(t){if(t==null)throw new Error("The element of the releaser validator is null.");t.classList.remove("is-valid","is-invalid");let i=t.value.trim();i.length>0&&i.length!=11&&t.classList.add("is-invalid")}function Z(t,i){if(t==null)throw new Error("The element of the number validator is null.");t.classList.remove("is-valid","is-invalid");let r=parseInt(t.value,10);isNaN(r)&&t.classList.add("is-invalid"),(r>i||r<0)&&t.classList.add("is-invalid")}function pe(t){let i=["a","an","and","as","but","for","if","of","or","so","the","to"];return t.split(" ").map((r,a)=>a===0||!i.includes(r.toLowerCase())?r.charAt(0).toUpperCase()+r.slice(1).toLowerCase():r.toLowerCase()).join(" ")}async function T(t){let i=d(t);i.focus(),await navigator.clipboard.writeText(`${i.value}`).then(function(){console.log(`Copied ${Te(i.value.length)} to the clipboard`)},function(r){console.error(`could not save any text to the clipboard: ${r}`)})}function d(t){let i=document.getElementById(t);if(i==null)throw new Error(`The ${t} for getElmById() element is null.`);return i}function Te(t=0){let s=Math.pow(1e3,2),o=Math.pow(1e3,3);return t>o?`${(Math.round(t*100/o)/100).toFixed(2)} GB`:t>s?`${(Math.round(t*100/s)/100).toFixed(1)} MB`:t>1e3?`${(Math.round(t*100/1e3)/100).toFixed()} kB`:`${Math.round(t).toFixed()} bytes`}(()=>{"use strict";function t(e){return function(){e.forEach(n=>{n.disabled=!0,n.classList.remove("btn-outline-primary"),n.classList.add("btn-light")})}}function i(e){return function(){e.forEach(n=>{n.disabled=!1,n.classList.remove("btn-light"),n.classList.add("btn-outline-primary")})}}let r=document.getElementById("artifact-editor-modal"),a=document.getElementsByName("artifact-editor-dataeditor");r.addEventListener("shown.bs.modal",()=>{t(a)()}),r.addEventListener("hidden.bs.modal",()=>{i(a)()});let s=document.getElementById("asset-editor-modal"),o=document.getElementsByName("artifact-editor-fileeditor");s.addEventListener("shown.bs.modal",()=>{t(o)()}),s.addEventListener("hidden.bs.modal",()=>{i(o)()});let l=document.getElementById("emulate-editor-modal"),p=document.getElementsByName("artifact-editor-emueditor");l.addEventListener("shown.bs.modal",()=>{t(p)()}),l.addEventListener("hidden.bs.modal",()=>{i(p)()});let h=document.getElementById("emulate-run-program");if(h!==null){let e=document.getElementById("emulate-guess-program");if(e===null)throw new Error("The guess program input is missing.");h.addEventListener("input",()=>{if(h.value=h.value.toUpperCase(),h.value!==""){e.disabled=!0;return}e.disabled=!1})}if(d("artifact-editor-key-value")===null)throw new Error("The key value is missing.");let L=d("artifact-editor-key-label");if(L===null)throw new Error("The key label is missing.");if(L.addEventListener("click",()=>T("artifact-editor-key-value")),d("artifact-editor-unique-id-value")===null)throw new Error("The unique id value is missing.");let O=d("artifact-editor-unique-id-label");if(O===null)throw new Error("The unique id label is missing.");if(O.addEventListener("click",()=>T("artifact-editor-unique-id-value")),d("artifact-editor-location-value")===null)throw new Error("The location value is missing.");let _=d("artifact-editor-location-label");if(_===null)throw new Error("The location label is missing.");if(_.addEventListener("click",()=>T("artifact-editor-location-value")),d("artifact-editor-templocation")!==null&&d("artifact-editor-templocation-label").addEventListener("click",()=>T("artifact-editor-templocation")),document.getElementById("artifact-editor-os-label")===null)throw new Error("The operating system label is missing.");let E=document.getElementById("artifact-editor-operating-system");if(E===null)throw new Error("The operating system input is missing.");E.addEventListener("input",M);let w=document.getElementById("artifact-editor-category");if(w===null)throw new Error("The category input is missing.");w.addEventListener("input",U),M(),U();function M(){E.selectedIndex==0&&(E.classList.remove("is-valid"),E.classList.add("is-invalid"))}function U(){w.selectedIndex==0&&(w.classList.remove("is-valid"),w.classList.add("is-invalid"))}let Y=document.getElementsByName("prereset-classifications");if(Y.length===0)throw new Error("The preset classifications are missing.");for(let e=0;e{W.preventDefault(),E.value=v,E.classList.remove("is-invalid"),w.value=q,w.classList.remove("is-invalid"),M(),U()})}let f=document.getElementById("artifact-editor-filename");if(f===null)throw new Error("The filename input is missing.");f.addEventListener("input",e=>{e.target.classList.remove("is-valid"),e.target.classList.remove("is-invalid"),e.target.value.trim().length===0&&e.target.classList.add("is-invalid")});let J=document.getElementById("artifact-editor-filename-reset");if(J===null)throw new Error("The filename reset is missing.");let D=document.getElementsByName("artifact-editor-filename-undo");if(D.length===0)throw new Error("The filename resetter is missing.");J.addEventListener("click",()=>{if(f.classList.remove("is-valid"),D.length===0)throw new Error("The filename resetter is missing.");f.value=D[0].value,f.classList.add("is-valid"),f.classList.remove("is-invalid"),f.value.trim().length===0&&f.classList.add("is-invalid")});let y=document.getElementById("artifact-editor-releaser-1");if(y===null)throw new Error("The releaser 1 input is missing.");y.addEventListener("input",e=>B(e.target));let b=document.getElementById("artifact-editor-releaser-2");if(b===null)throw new Error("The releaser 2 input is missing.");b.addEventListener("input",e=>B(e.target));let K=document.getElementById("artifact-editor-releaser-undo");if(K===null)throw new Error("The releasers reset is missing.");K.addEventListener("click",ye);function ye(){let e=y.getAttribute("data-reset-rel1");if(e===null)throw new Error("data-reset-rel1 attribute is required for artifact-editor-releaser-1.");y.value=e,B(y);let n=b.getAttribute("data-reset-rel2");if(n===null)throw new Error("data-reset-rel2 attribute is required for artifact-editor-releaser-2.");b.value=n,B(b)}let g=document.getElementById("artifact-editor-title");if(g===null)throw new Error("The title input is missing.");g.addEventListener("input",e=>{e.target.classList.remove("is-valid")});let Q=document.getElementById("artifact-editor-title-undo");if(Q===null)throw new Error("The title reset is missing.");let z=document.getElementsByName("artifact-editor-titleundo");if(z.length===0)throw new Error("The title resetter is missing.");Q.addEventListener("click",()=>{if(g.classList.remove("is-valid"),z.length===0)throw new Error("The title resetter is missing.");g.value=z[0].value,g.classList.add("is-valid")});let X=document.getElementById("artifact-editor-titleize");if(X.length===0)throw new Error("The titleize button is missing.");X.addEventListener("click",()=>{g.value=pe(g.value);let e=new Event("keyup");g.dispatchEvent(e)});let F=document.getElementById("artifact-editor-credit-text");if(F===null)throw new Error("The creator text input is missing.");F.addEventListener("input",e=>{e.target.classList.remove("is-valid")});let S=document.getElementById("artifact-editor-credit-ill");if(S===null)throw new Error("The creator illustrator input is missing.");S.addEventListener("input",e=>{e.target.classList.remove("is-valid")});let G=document.getElementById("artifact-editor-credit-prog");if(G===null)throw new Error("The creator programmer input is missing.");G.addEventListener("input",e=>{e.target.classList.remove("is-valid")});let j=document.getElementById("artifact-editor-credit-audio");if(j===null)throw new Error("The creator audio input is missing.");j.addEventListener("input",e=>{e.target.classList.remove("is-valid")});let H=document.getElementById("artifact-editor-credits-undo");if(H===null)throw new Error("The creator resetter is missing.");let ee=document.getElementById("artifact-editor-credit-undo");if(ee===null)throw new Error("The creator reset is missing.");ee.addEventListener("click",()=>{if(H.length===0)throw new Error("The creator resetter is missing.");let e=H.value.split(";");if(e.length!=4)throw new Error("The creator resetter values are invalid.");let n=e[0],v=e[1],q=e[2],W=e[3];F.value=n,S.value=v,G.value=q,j.value=W});let I=document.getElementById("artifact-editor-comment");if(I===null)throw new Error("The comment input is missing.");I.addEventListener("input",e=>{e.target.classList.remove("is-valid")});let te=document.getElementById("artifact-editor-comment-undo");if(te===null)throw new Error("The comment reset is missing.");let ie=document.getElementById("artifact-editor-comment-resetter");if(ie===null)throw new Error("The comment resetter is missing.");te.addEventListener("click",()=>{I.classList.remove("is-valid"),I.value=ie.value});let re=document.getElementById("artifact-editor-virustotal");if(re===null)throw new Error("The virustotal input is missing.");re.addEventListener("input",e=>{e.target.classList.remove("is-valid","is-invalid");let n=e.target.value.trim();n.length!=0&&(n.startsWith("https://www.virustotal.com/")||e.target.classList.add("is-invalid"))});let c=document.getElementById("artifact-editor-year");if(c===null)throw new Error("The year input is missing.");c.addEventListener("input",()=>{R(c,u,m)});let u=document.getElementById("artifact-editor-month");if(u===null)throw new Error("The month input is missing.");u.addEventListener("input",()=>{R(c,u,m)});let m=document.getElementById("artifact-editor-day");if(m===null)throw new Error("The day input is missing.");m.addEventListener("input",()=>{R(c,u,m)});let ne=document.getElementById("artifact-editor-date-reset");if(ne===null)throw new Error("The date reset is missing.");let se=document.getElementById("artifact-editor-date-resetter");if(se===null)throw new Error("The date resetter is missing.");ne.addEventListener("click",()=>{c.classList.remove("is-invalid","is-valid"),u.classList.remove("is-invalid","is-valid"),m.classList.remove("is-invalid","is-valid");let n=se.value.split("-");if(n.length!=3)throw new Error("The date resetter values are invalid.");c.value=n[0],u.value=n[1],m.value=n[2]});let ae=document.getElementById("artifact-editor-date-lastmod");if(ae!==null){let e=document.getElementById("artifact-editor-date-lastmodder");if(e===null)throw new Error("The date last modder input is missing.");ae.addEventListener("click",()=>{c.classList.remove("is-invalid","is-valid"),u.classList.remove("is-invalid","is-valid"),m.classList.remove("is-invalid","is-valid");let v=e.value.split("-");if(v.length!=3)throw new Error("The date last modder values are invalid.");c.value=v[0],u.value=v[1],m.value=v[2]})}let oe=document.getElementById("artifact-editor-links-reset");if(oe===null)throw new Error("The links reset is missing.");let x=document.getElementById("artifact-editor-youtube"),le=document.getElementById("artifact-editor-youtube-reset");if(x===null||le===null)throw new Error("A YouTube input is missing.");let k=document.getElementById("artifact-editor-demozoo"),de=document.getElementById("artifact-editor-demozoo-reset");if(k===null||de===null)throw new Error("A Demozoo input is missing.");let N=document.getElementById("artifact-editor-pouet"),ce=document.getElementById("artifact-editor-pouet-reset");if(N===null||ce===null)throw new Error("A Pouet input is missing.");let $=document.getElementById("artifact-editor-16colors"),ue=document.getElementById("artifact-editor-16colors-reset");if($===null||ue===null)throw new Error("A 16colors input is missing.");let A=document.getElementById("artifact-editor-github"),me=document.getElementById("artifact-editor-github-reset");if(A===null||me===null)throw new Error("A GitHub input is missing.");let P=document.getElementById("artifact-editor-relations"),ve=document.getElementById("artifact-editor-relations-reset");if(P===null||ve===null)throw new Error("A relations input is missing.");let V=document.getElementById("artifact-editor-websites"),fe=document.getElementById("artifact-editor-websites-reset");if(V===null||fe===null)throw new Error("A websites input is missing.");oe.addEventListener("click",()=>{x.classList.remove("is-invalid","is-valid"),k.classList.remove("is-invalid","is-valid"),N.classList.remove("is-invalid","is-valid"),$.classList.remove("is-invalid","is-valid"),A.classList.remove("is-invalid","is-valid"),P.classList.remove("is-invalid","is-valid"),V.classList.remove("is-invalid","is-valid"),x.value=le.value,k.value=de.value,N.value=ce.value,$.value=ue.value,A.value=me.value,P.value=ve.value,V.value=fe.value});let be=45e4,Be=2e5;x.addEventListener("input",e=>we(e.target)),k.addEventListener("input",e=>Z(e.target,be)),N.addEventListener("input",e=>Z(e.target,Be)),$.addEventListener("input",e=>he(e.target)),A.addEventListener("input",e=>ge(e.target))})();})();
diff --git a/public/js/editor-assets.min.js b/public/js/editor-assets.min.js
index 748ad5e4..39c85225 100644
--- a/public/js/editor-assets.min.js
+++ b/public/js/editor-assets.min.js
@@ -1,2 +1,2 @@
/* editor-assets.min.js © Defacto2 2024 */
-(()=>{var k=100,L=1024*1024,H=100*L;function f(s,a){if(s==null)throw new Error("The formId value of progress is null.");if(a==null)throw new Error("The elementId value of progress is null.");htmx.on(`#${s}`,"htmx:xhr:progress",function(l){l.target.id==`${s}`&&htmx.find(`#${a}`).setAttribute("value",l.detail.loaded/l.detail.total*k)})}(()=>{"use strict";f("artifact-editor-dl-form","artifact-editor-dl-progress"),f("artifact-editor-preview-form","artifact-editor-preview-progress");let s=document.getElementById("artifact-editor-preview-reset");if(s==null){console.error("the reset preview button is missing");return}let a=document.getElementById("artifact-editor-replace-preview");if(a==null){console.error("the form preview input is missing");return}let l=document.getElementById("artifact-editor-dl-reset");if(l==null){console.error("the reset button is missing");return}let d=document.getElementById("artifact-editor-dl-up");if(d==null){console.error("the artifact file input is missing");return}let h=document.getElementById("artifact-editor-modal");if(h==null){console.error("the data editor modal is missing");return}let m=document.getElementById("asset-editor-modal");if(m==null){console.error("the asset editor modal is missing");return}let w=document.getElementById("emulate-editor-modal");if(w==null){console.error("the emulate editor modal is missing");return}let v=new bootstrap.Modal(h),g=new bootstrap.Modal(m),T=new bootstrap.Modal(w);switch(new URL(window.location.href).hash){case"#data-editor":v.show(),history.replaceState(null,"",window.location.pathname);break;case"#file-editor":g.show(),history.replaceState(null,"",window.location.pathname);break;case"#emulate-editor":T.show(),history.replaceState(null,"",window.location.pathname);break;default:}document.body.addEventListener("htmx:afterRequest",function(e){p(e,"artifact-editor-dl-form","artifact-editor-dl-up","artifact-editor-dl-feedback"),p(e,"artifact-editor-preview-form","artifact-editor-replace-preview","artifact-editor-preview-feedback"),c(e,"artifact-editor-image-delete","artifact-editor-image-feedback"),c(e,"artifact-editor-imagepreview-delete","artifact-editor-image-feedback"),c(e,"artifact-editor-imagethumb-delete","artifact-editor-image-feedback"),c(e,"artifact-editor-image-pixelate","artifact-editor-preview-feedback"),u(e,"artifact-editor-link-delete","artifact-editor-link-feedback"),u(e,"artifact-editor-comp-previewcopy","artifact-editor-comp-feedback"),u(e,"artifact-editor-comp-previewtext","artifact-editor-comp-feedback"),u(e,"artifact-editor-comp-textcopy","artifact-editor-comp-feedback")});function u(e,o,r){if(e.detail.elt===null||e.detail.elt.id!==`${o}`&&e.detail.elt.name!==o)return;let t=document.getElementById(r);if(t===null)throw new Error(`The htmx successful feedback element ${r} is null`);let i="text-danger",n=e.detail.xhr;if(e.detail.successful){t.innerText=`${n.responseText}`,t.classList.remove(i);return}if(e.detail.failed&&e.detail.xhr){t.classList.add(i),t.innerText=`Something on the server is not working, ${n.status} status: ${n.responseText}.`;return}t.classList.add(i),t.innerText="Something with the browser is not working, please try again or refresh the page."}function c(e,o,r){if(e.detail.elt===null||e.detail.elt.id!==`${o}`)return;let t=document.getElementById(r);if(t===null)throw new Error(`The htmx successful feedback element ${r} is null`);let i="text-danger",n="text-success",x=e.detail.xhr;if(e.detail.successful){t.innerText="The delete request was successful, about to refresh the page.",t.classList.remove(i),t.classList.add(n),setTimeout(()=>{location.reload()},500);return}if(e.detail.failed&&e.detail.xhr){t.classList.add(i),t.innerText=`Something on the server is not working, ${x.status} status: ${x.responseText}.`;return}t.classList.add(i),t.innerText="Something with the browser is not working, please try again or refresh the page."}function p(e,o,r,t){if(e.detail.elt===null||e.detail.elt.id!==`${o}`)return;let i=document.getElementById(r);if(i===null)throw new Error(`The htmx successful input element ${r} is null`);let n=document.getElementById(t);if(n===null)throw new Error(`The htmx successful feedback element ${t} is null`);if(e.detail.successful)return E(e,i,n);if(e.detail.failed&&e.detail.xhr)return b(e,i,n);y(i,n)}function E(e,o,r){let t=e.detail.xhr;r.innerText=`${t.responseText}`,r.classList.remove("invalid-feedback"),r.classList.add("valid-feedback"),o.classList.remove("is-invalid"),o.classList.add("is-valid"),setTimeout(()=>{location.reload()},500)}function b(e,o,r){let t=e.detail.xhr;r.innerText=`Something on the server is not working, ${t.status} status: ${t.responseText}.`,r.classList.remove("valid-feedback"),r.classList.add("invalid-feedback"),o.classList.remove("is-valid"),o.classList.add("is-invalid")}function y(e,o){e.classList.remove("is-valid"),e.classList.add("is-invalid"),o.innerText="Something with the browser is not working, please try again or refresh the page.",o.classList.remove("d-none")}l.addEventListener("click",function(){d.value="",d.classList.remove("is-invalid","is-valid")}),s.addEventListener("click",function(){a.value="",a.classList.remove("is-invalid","is-valid")})})();})();
+(()=>{var k=100,L=1024*1024,A=100*L;function f(s,a){if(s==null)throw new Error("The formId value of progress is null.");if(a==null)throw new Error("The elementId value of progress is null.");htmx.on(`#${s}`,"htmx:xhr:progress",function(l){l.target.id==`${s}`&&htmx.find(`#${a}`).setAttribute("value",l.detail.loaded/l.detail.total*k)})}(()=>{"use strict";f("artifact-editor-dl-form","artifact-editor-dl-progress"),f("artifact-editor-preview-form","artifact-editor-preview-progress");let s=document.getElementById("artifact-editor-preview-reset");if(s==null){console.error("the reset preview button is missing");return}let a=document.getElementById("artifact-editor-replace-preview");if(a==null){console.error("the form preview input is missing");return}let l=document.getElementById("artifact-editor-dl-reset");if(l==null){console.error("the reset button is missing");return}let d=document.getElementById("artifact-editor-dl-up");if(d==null){console.error("the artifact file input is missing");return}let h=document.getElementById("artifact-editor-modal");if(h==null){console.error("the data editor modal is missing");return}let m=document.getElementById("asset-editor-modal");if(m==null){console.error("the asset editor modal is missing");return}let w=document.getElementById("emulate-editor-modal");if(w==null){console.error("the emulate editor modal is missing");return}let v=new bootstrap.Modal(h),g=new bootstrap.Modal(m),T=new bootstrap.Modal(w);switch(new URL(window.location.href).hash){case"#data-editor":v.show(),history.replaceState(null,"",window.location.pathname);break;case"#file-editor":g.show(),history.replaceState(null,"",window.location.pathname);break;case"#emulate-editor":T.show(),history.replaceState(null,"",window.location.pathname);break;default:}document.body.addEventListener("htmx:afterRequest",function(e){p(e,"artifact-editor-dl-form","artifact-editor-dl-up","artifact-editor-dl-feedback"),p(e,"artifact-editor-preview-form","artifact-editor-replace-preview","artifact-editor-preview-feedback"),c(e,"artifact-editor-image-delete","artifact-editor-image-feedback"),c(e,"artifact-editor-imagepreview-delete","artifact-editor-image-feedback"),c(e,"artifact-editor-imagethumb-delete","artifact-editor-image-feedback"),c(e,"artifact-editor-image-pixelate","artifact-editor-preview-feedback"),u(e,"artifact-editor-link-delete","artifact-editor-link-feedback"),u(e,"artifact-editor-comp-previewcopy","artifact-editor-comp-feedback"),u(e,"artifact-editor-comp-previewtext","artifact-editor-comp-feedback"),u(e,"artifact-editor-comp-textcopy","artifact-editor-comp-feedback")});function u(e,o,r){if(e.detail.elt===null||e.detail.elt.id!==`${o}`&&e.detail.elt.name!==o)return;let t=document.getElementById(r);if(t===null)throw new Error(`The htmx successful feedback element ${r} is null`);let i="text-danger",n=e.detail.xhr;if(e.detail.successful){t.innerText=`${n.responseText}`,t.classList.remove(i);return}if(e.detail.failed&&e.detail.xhr){t.classList.add(i),t.innerText=`Something on the server is not working, ${n.status} status: ${n.responseText}.`;return}t.classList.add(i),t.innerText="Something with the browser is not working, please try again or refresh the page."}function c(e,o,r){if(e.detail.elt===null||e.detail.elt.id!==`${o}`)return;let t=document.getElementById(r);if(t===null)throw new Error(`The htmx successful feedback element ${r} is null`);let i="text-danger",n="text-success",x=e.detail.xhr;if(e.detail.successful){t.innerText="The delete request was successful, about to refresh the page.",t.classList.remove(i),t.classList.add(n),setTimeout(()=>{location.reload()},500);return}if(e.detail.failed&&e.detail.xhr){t.classList.add(i),t.innerText=`Something on the server is not working, ${x.status} status: ${x.responseText}.`;return}t.classList.add(i),t.innerText="Something with the browser is not working, please try again or refresh the page."}function p(e,o,r,t){if(e.detail.elt===null||e.detail.elt.id!==`${o}`)return;let i=document.getElementById(r);if(i===null)throw new Error(`The htmx successful input element ${r} is null`);let n=document.getElementById(t);if(n===null)throw new Error(`The htmx successful feedback element ${t} is null`);if(e.detail.successful)return E(e,i,n);if(e.detail.failed&&e.detail.xhr)return b(e,i,n);y(i,n)}function E(e,o,r){let t=e.detail.xhr;r.innerText=`${t.responseText}`,r.classList.remove("invalid-feedback"),r.classList.add("valid-feedback"),o.classList.remove("is-invalid"),o.classList.add("is-valid"),setTimeout(()=>{location.reload()},500)}function b(e,o,r){let t=e.detail.xhr;r.innerText=`Something on the server is not working, ${t.status} status: ${t.responseText}.`,r.classList.remove("valid-feedback"),r.classList.add("invalid-feedback"),o.classList.remove("is-valid"),o.classList.add("is-invalid")}function y(e,o){e.classList.remove("is-valid"),e.classList.add("is-invalid"),o.innerText="Something with the browser is not working, please try again or refresh the page.",o.classList.remove("d-none")}l.addEventListener("click",function(){d.value="",d.classList.remove("is-invalid","is-valid")}),s.addEventListener("click",function(){a.value="",a.classList.remove("is-invalid","is-valid")})})();})();
diff --git a/public/js/readme.min.js b/public/js/readme.min.js
index 0757465d..c90277b9 100644
--- a/public/js/readme.min.js
+++ b/public/js/readme.min.js
@@ -1,2 +1,2 @@
/* readme.min.js © Defacto2 2024 */
-(()=>{async function s(t){let a=c(t);a.focus(),await navigator.clipboard.writeText(`${a.textContent}`).then(function(){console.log(`Copied ${x(a.textContent.length)} to the clipboard`);let e=document.getElementById("artifact-copy-readme-body");if(e===null)return;let r=e.textContent;e.textContent="\u2713 Copied",window.setTimeout(()=>{e.textContent=`${r}`},1e3)},function(e){console.error(`could not save any text to the clipboard: ${e}`)})}function c(t){let n=document.getElementById(t);if(n==null)throw new Error(`The ${t} for getElmById() element is null.`);return n}function x(t=0){let r=Math.pow(1e3,2),o=Math.pow(1e3,3);return t>o?`${(Math.round(t*100/o)/100).toFixed(2)} GB`:t>r?`${(Math.round(t*100/r)/100).toFixed(1)} MB`:t>1e3?`${(Math.round(t*100/1e3)/100).toFixed()} kB`:`${Math.round(t).toFixed()} bytes`}(()=>{"use strict";let t="d-none",n=["reader-invert","border","border-black","rounded-1"],a="readmeLatin1",e=c(a),r="readmeCP437",o=c(r),f=document.querySelector('input[name="readme-base"]:checked'),u=document.getElementById("monoFont");u!==null&&u.addEventListener("click",m);function m(){switch(f.id){case"vgaFont":e.classList.add(t),o.classList.remove(t,"font-dos",...n),o.classList.add("font-cascadia-mono");break;case"topazFont":o.classList.add(t),e.classList.remove(t,"font-amiga",...n),e.classList.add("font-cascadia-mono");break;default:throw new Error("no default font found for the readme")}}let i=document.getElementById("topazFont");i!==null&&i.addEventListener("click",p);function p(){o.classList.add(t),e.classList.remove(t,"font-cascadia-mono"),e.classList.add("font-amiga",...n)}let d=document.getElementById("vgaFont");d!==null&&d.addEventListener("click",h);function h(){e.classList.add(t),o.classList.remove(t,"font-cascadia-mono"),o.classList.add("font-dos",...n)}let l=c("artifact-copy-readme-body");typeof navigator.clipboard>"u"?l.classList.add(t):l.addEventListener("click",v);function v(){i!==null&&i.checked?s(a):d!==null&&d.checked?s(r):s(r)}})();})();
+(()=>{async function d(t){let a=c(t);a.focus(),await navigator.clipboard.writeText(`${a.textContent}`).then(function(){console.log(`Copied ${x(a.textContent.length)} to the clipboard`);let e=document.getElementById("artifact-copy-readme-body");if(e===null)return;let r=e.textContent;e.textContent="\u2713 Copied",window.setTimeout(()=>{e.textContent=`${r}`},1e3)},function(e){console.error(`could not save any text to the clipboard: ${e}`)})}function c(t){let n=document.getElementById(t);if(n==null)throw new Error(`The ${t} for getElmById() element is null.`);return n}function x(t=0){let r=Math.pow(1e3,2),o=Math.pow(1e3,3);return t>o?`${(Math.round(t*100/o)/100).toFixed(2)} GB`:t>r?`${(Math.round(t*100/r)/100).toFixed(1)} MB`:t>1e3?`${(Math.round(t*100/1e3)/100).toFixed()} kB`:`${Math.round(t).toFixed()} bytes`}(()=>{"use strict";let t="d-none",n=["reader-invert","border","border-black","rounded-1"],a="readmeLatin1",e=c(a),r="readmeCP437",o=c(r),f=document.querySelector('input[name="readme-base"]:checked'),u=document.getElementById("monoFont");u!==null&&u.addEventListener("click",m);function m(){switch(f.id){case"vgaFont":e.classList.add(t),o.classList.remove(t,"font-dos",...n),o.classList.add("font-cascadia-mono");break;case"topazFont":o.classList.add(t),e.classList.remove(t,"font-amiga",...n),e.classList.add("font-cascadia-mono");break;default:throw new Error("no default font found for the readme")}}let i=document.getElementById("topazFont");i!==null&&i.addEventListener("click",p);function p(){o.classList.add(t),e.classList.remove(t,"font-cascadia-mono"),e.classList.add("font-amiga",...n)}let s=document.getElementById("vgaFont");s!==null&&s.addEventListener("click",h);function h(){e.classList.add(t),o.classList.remove(t,"font-cascadia-mono"),o.classList.add("font-dos",...n)}let l=c("artifact-copy-readme-body");typeof navigator.clipboard>"u"?l.classList.add(t):l.addEventListener("click",v);function v(){i!==null&&i.checked?d(a):s!==null&&s.checked?d(r):d(r)}})();})();
diff --git a/public/js/uploader.min.js b/public/js/uploader.min.js
index b528851b..fa7e624f 100644
--- a/public/js/uploader.min.js
+++ b/public/js/uploader.min.js
@@ -1,2 +1,2 @@
/* uploader.min.js © Defacto2 2024 */
-(()=>{function t(e){let a=document.getElementById(e);if(a==null)throw new Error(`The ${e} for getElmById() element is null.`);return a}function n(e){if(`${e}`=="")return!0;let a=1980,r=new Date().getFullYear();return!(er)}function o(e){return`${e}`==""?!0:!(e<1||e>12)}function ne(e){return`${e}`==""?!0:!(e<1||e>31)}function Se(e,a){if(e=="")return!0;let r=Number(e),s=Number(a);if(!Number.isInteger(s)||s<1)throw new Error(`The ID sanity value is invalid: ${s}`);return Number.isInteger(r)&&r>0&&r<=s}var l="is-invalid",k="d-none",gt=100,xe=1024*1024,He=100*xe;function T(e,a){if(e==null)throw new Error("The elementId value of focusModalById is null.");if(a==null)throw new Error("The submissionId value of focusModalById is null.");let r=document.getElementById(a);if(r==null)throw new Error(`The ${a} element is null.`);let s=t(e);if(s.addEventListener("shown.bs.modal",function(){r.focus()}),bootstrap===void 0)throw new Error("The bootstrap object is undefined.");return new bootstrap.Modal(s,{keyboard:!0})}async function yt(e){if(e==null)throw new Error("The file value of checkSHA is null.");try{let a=await bt(e),r=await fetch(`/uploader/sha384/${a}`,{method:"PATCH",headers:{"Content-Type":"text/plain"},body:a});if(!r.ok)throw new Error(`Hashing is not possible, server response: ${r.status}`);return await r.text()=="true"}catch(a){console.log(`Hashing is not possible: ${a}`)}}async function bt(e){if(e==null)throw new Error("The file value of sha384 is null.");try{let a=await e.arrayBuffer(),r=await crypto.subtle.digest("SHA-384",a);return Array.from(new Uint8Array(r)).map(s=>s.toString(16).padStart(2,"0")).join("")}catch(a){throw new Error(`Could not use arrayBuffer or crypto.subtle: ${a}`)}}function H(e,a){if(e==null)throw new Error("The formId value of progress is null.");if(a==null)throw new Error("The elementId value of progress is null.");htmx.on(`#${e}`,"htmx:xhr:progress",function(r){r.target.id==`${e}`&&htmx.find(`#${a}`).setAttribute("value",r.detail.loaded/r.detail.total*gt)})}function u(e){if(e==null)throw new Error("The file value of checkSize is null.");return e.size>He?`The chosen file is too big at ${Math.round(e.size/xe)}MB, maximum size is ${He/xe}MB.`:""}function Ye(){return ne(this.value)==!1?(this.classList.add(l),!1):(this.classList.remove(l),!0)}function d(){return console.log(`The month value is ${this.value}.`),o(this.value)==!1?(this.classList.add(l),!1):(this.classList.remove(l),!0)}function f(){return n(this.value)==!1?(this.classList.add(l),!1):(this.classList.remove(l),!0)}function p(e,a,r,s){if(e==null)throw new Error("The errors value of checkErrors is null.");if(a==null)throw new Error("The alert value of checkErrors is null.");if(r==null)throw new Error("The fileInput value of checkErrors is null.");if(s==null)throw new Error("The results value of checkErrors is null.");e=e.filter(w=>w!=""),!(e.length<=0)&&(a.innerText=e.join(" "),a.classList.remove(k),r.innerText="",r.classList.add(l),s.classList.add(k))}async function m(e,a,r,s){if(e==null)throw new Error("The file value of checkDuplicate is null.");if(a==null)throw new Error("The alert value of checkDuplicate is null.");if(r==null)throw new Error("The fileInput value of checkDuplicate is null.");if(s==null)throw new Error("The results value of checkDuplicate is null.");await yt(e)!=!1&&(a.innerText=`The chosen file already exists in the database: ${e.name}`,a.classList.remove(k),r.innerText="",r.classList.add(l),s.classList.add(k))}function h(e,a,r){if(e==null)throw new Error("The file1 value of hiddenDetails is null.");if(a==null)throw new Error("The lastMod value of hiddenDetails is null.");if(r==null)throw new Error("The magic value of hiddenDetails is null.");let s=e.lastModified,w=new Date().getTime(),Be=60*60*1e3;w-s=400&&s.classList.remove(Q)}),document.body.addEventListener("htmx:afterRequest",function(S){if(S.detail.elt===null||S.detail.elt.id!==`${e}`)return;if(S.detail.successful)return Vt(r);let ie=S.detail.xhr;if(S.detail.failed&&ie)return ie.status===404?Rt(s,w,a):Nt(s,ie);qt(s)})}function Ce(e,a){e.addEventListener("input",function(){if(!Se(e.value,a)){e.classList.add(ge);return}e.classList.remove(ge)})}function At(e,a){a.innerHTML="",e.innerText="",e.classList.add(Q)}function Vt(e){e.focus()}function Rt(e,a,r){a.innerText=`Production not found on ${r}.`}function qt(e){e.innerText="Something with the browser is not working, please refresh the page.",e.classList.remove(Q)}function Nt(e,a){e.innerText=`Something went wrong, ${a.status} status: ${a.responseText}.`,e.classList.remove(Q)}var Pt="application/x-freearc",Kt="application/x-arj",Gt="application/x-bzip",Ot="application/x-bzip2",Ut="application/gzip",Xt="application/vnd.rar",Zt="application/x-tar",_t="application/zip",Jt="application/x-7z-compressed",Qt="application/x-msdos-program",Wt="image/bmp",er="image/gif",tr="image/jpeg",rr="image/vnd.zbrush.pcx",ar="image/png",sr="image/tiff",ir="image/webp",nr="application/x-csh",or="application/x-chrome-extension",lr="text/x-script.perl",cr="application/x-httpd-php",ur="text/x-script.phyton",dr="text/x-script.rexx",fr="application/x-sh",pr="application/x-shellscript",mr="text/x-script.tcl",hr="text/x-shellscript",vr="text/x-script.zsh";function Lr(){return[nr,or,lr,cr,ur,dr,fr,pr,mr,hr,vr]}function Ae(){return[Qt]}function oe(){return[Pt,Kt,Gt,Ot,Ut,Xt,Zt,_t,Jt]}function Ve(){return["application/octet-stream","application/x-binary","application/x-ms-dos-executable"]}function xr(){return[Wt,er,tr,rr,ar,sr,ir]}function Re(){return["text/plain","text/x-nfo"]}function qe(e){return Lr().includes(e)}function Ne(e){return xr().concat(oe()).includes(e)}function le(e){return Ae().concat(oe(),Ve()).includes(e)}function Pe(e){return Re().concat(oe(),Ae(),Ve()).includes(e)}function Ke(e){return Re().concat(oe()).includes(e)}var gr="uploader-image-form",E="is-invalid",be="d-none",yr=t(gr),q=t("uploader-image-alert"),Y=t("uploader-image-file"),Ge=t("uploader-image-last-modified"),br=t("uploader-image-list-1"),wr=t("uploader-image-list-2"),Oe=t("uploader-image-magic"),W=t("uploader-image-month"),ce=t("uploader-image-releaser-1"),M=t("uploader-image-results"),R=t("uploader-image-year");yr.addEventListener("reset",function(){Ge.value="",Oe.value="",Xe()});Y.addEventListener("change",Tr);ce.addEventListener("input",c);R.addEventListener("input",f);W.addEventListener("input",d);function Ue(e){t(e).addEventListener("click",function(){let r=!0;if(ce.value==""&&(ce.classList.add(E),r=!1),n(R.value)==!1&&(R.classList.add(E),r=!1),o(W.value)==!1&&(W.classList.add(E),r=!1),W.value!=""&&R.value==""&&(R.classList.add(E),r=!1),Y.value==""&&(Y.classList.add(E),r=!1),r==!1)return L(q,M);Xe(),M.innerText="...",M.classList.remove(be)})}async function Tr(){v(Y,q,M);let e=this.files[0],a=[u(e),Er(e)];p(a,q,Y,M),m(e,q,Y,M),h(e,Ge,Oe)}function Er(e){return Ne(e.type)?"":`The chosen file mime type ${e.type} is probably not suitable for an image.`}function Xe(){br.innerHTML="",wr.innerHTML="",M.innerHTML="",M.classList.add(be),q.innerText="",q.classList.add(be),R.classList.remove(E),W.classList.remove(E),ce.classList.remove(E),Y.classList.remove(E)}var kr="uploader-intro-form",b="is-invalid",we="d-none",Mr=t(kr),P=t("uploader-intro-alert"),F=t("uploader-intro-file"),Ze=t("uploader-intro-last-modified"),zr=t("uploader-intro-list-1"),$r=t("uploader-intro-list-2"),_e=t("uploader-intro-magic"),ee=t("uploader-intro-month"),ue=t("uploader-intro-releaser-1"),z=t("uploader-intro-results"),N=t("uploader-intro-year"),Je=t("uploader-intro-youtube");Mr.addEventListener("reset",function(){Ze.value="",_e.value="",We()});F.addEventListener("change",Ir);ue.addEventListener("input",c);N.addEventListener("input",f);ee.addEventListener("input",d);Je.addEventListener("input",Fe);function Qe(e){t(e).addEventListener("click",function(){let r=!0;if(ue.value==""&&(ue.classList.add(b),r=!1),n(N.value)==!1&&(N.classList.add(b),r=!1),o(ee.value)==!1&&(ee.classList.add(b),r=!1),ee.value!=""&&N.value==""&&(N.classList.add(b),r=!1),F.value==""&&(F.classList.add(b),r=!1),r==!1)return L(P,z);We(),z.innerText="...",z.classList.remove(we)})}async function Ir(){v(F,P,z);let e=this.files[0],a=[u(e),Br(e)];p(a,P,F,z),m(e,P,F,z),h(e,Ze,_e)}function Br(e){return le(e.type)?"":`The chosen file mime type ${e.type} is probably not suitable for an intro.`}function We(){zr.innerHTML="",$r.innerHTML="",z.innerHTML="",z.classList.add(we),P.innerText="",P.classList.add(we),N.classList.remove(b),ee.classList.remove(b),ue.classList.remove(b),Je.classList.remove(b),F.classList.remove(b)}var Dr="uploader-magazine-form",x="is-invalid",Te="d-none",Sr=t(Dr),G=t("uploader-magazine-alert"),j=t("uploader-magazine-file"),et=t("uploader-magazine-last-modified"),Hr=t("uploader-magazine-list-1"),tt=t("uploader-magazine-magic"),te=t("uploader-magazine-month"),de=t("uploader-magazine-releaser-1"),$=t("uploader-magazine-results"),Ee=t("uploader-magazine-title"),K=t("uploader-magazine-year");Sr.addEventListener("reset",function(){et.value="",tt.value="",at()});j.addEventListener("change",Yr);de.addEventListener("input",c);K.addEventListener("input",f);te.addEventListener("input",d);function rt(e){t(e).addEventListener("click",function(){let r=!0;if(Ee.value==""&&(Ee.classList.add(x),r=!1),de.value==""&&(de.classList.add(x),r=!1),n(K.value)==!1&&(K.classList.add(x),r=!1),o(te.value)==!1&&(te.classList.add(x),r=!1),te.value!=""&&K.value==""&&(K.classList.add(x),r=!1),j.value==""&&(j.classList.add(x),r=!1),r==!1)return L(G,$);at(),$.innerText="...",$.classList.remove(Te)})}async function Yr(){v(j,G,$);let e=this.files[0],a=[u(e),Fr(e)];p(a,G,j,$),m(e,G,j,$),h(e,et,tt)}function Fr(e){return Pe(e.type)?"":`The chosen file mime type ${e.type} is probably not suitable for an image.`}function at(){Hr.innerHTML="",$.innerHTML="",$.classList.add(Te),G.innerText="",G.classList.add(Te),K.classList.remove(x),te.classList.remove(x),de.classList.remove(x),j.classList.remove(x),Ee.classList.remove(x)}var jr="uploader-text-form",g="is-invalid",ke="d-none",Cr=t(jr),U=t("uploader-text-alert"),C=t("uploader-text-file"),st=t("uploader-text-last-modified"),Ar=t("uploader-text-list-1"),Vr=t("uploader-text-list-2"),it=t("uploader-text-magic"),re=t("uploader-text-month"),fe=t("uploader-text-releaser-1"),I=t("uploader-text-results"),Me=t("uploader-text-title"),O=t("uploader-text-year");Cr.addEventListener("reset",function(){st.value="",it.value="",ot()});C.addEventListener("change",Rr);fe.addEventListener("input",c);O.addEventListener("input",f);re.addEventListener("input",d);function nt(e){t(e).addEventListener("click",function(){let r=!0;if(Me.value==""&&(Me.classList.add(g),r=!1),fe.value==""&&(fe.classList.add(g),r=!1),n(O.value)==!1&&(O.classList.add(g),r=!1),o(re.value)==!1&&(re.classList.add(g),r=!1),re.value!=""&&O.value==""&&(O.classList.add(g),r=!1),C.value==""&&(C.classList.add(g),r=!1),r==!1)return L(U,I);ot(),I.innerText="...",I.classList.remove(ke)})}async function Rr(){v(C,U,I);let e=this.files[0],a=[u(e),qr(e)];p(a,U,C,I),m(e,U,C,I),h(e,st,it)}function qr(e){return Ke(e.type)?"":`The chosen file mime type ${e.type} is probably not suitable for a text.`}function ot(){Ar.innerHTML="",Vr.innerHTML="",I.innerHTML="",I.classList.add(ke),U.innerText="",U.classList.add(ke),O.classList.remove(g),re.classList.remove(g),fe.classList.remove(g),C.classList.remove(g),Me.classList.remove(g)}var Nr="uploader-trainer-form",y="is-invalid",ze="d-none",Pr=t(Nr),Z=t("uploader-trainer-alert"),A=t("uploader-trainer-file"),lt=t("uploader-trainer-last-modified"),Kr=t("uploader-trainer-list-1"),Gr=t("uploader-trainer-list-2"),ct=t("uploader-trainer-magic"),ae=t("uploader-trainer-month"),pe=t("uploader-trainer-releaser-1"),B=t("uploader-trainer-results"),$e=t("uploader-trainer-title"),X=t("uploader-trainer-year");Pr.addEventListener("reset",function(){lt.value="",ct.value="",dt()});A.addEventListener("change",Or);pe.addEventListener("input",c);X.addEventListener("input",f);ae.addEventListener("input",d);function ut(e){t(e).addEventListener("click",function(){let r=!0;if($e.value==""&&($e.classList.add(y),r=!1),pe.value==""&&(pe.classList.add(y),r=!1),n(X.value)==!1&&(X.classList.add(y),r=!1),o(ae.value)==!1&&(ae.classList.add(y),r=!1),ae.value!=""&&X.value==""&&(X.classList.add(y),r=!1),A.value==""&&(A.classList.add(y),r=!1),r==!1)return L(Z,B);dt(),B.innerText="...",B.classList.remove(ze)})}async function Or(){v(A,Z,B);let e=this.files[0],a=[u(e),Ur(e)];p(a,Z,A,B),m(e,Z,A,B),h(e,lt,ct)}function Ur(e){return le(e.type)?"":`The chosen file mime type ${e.type} is probably not suitable for an intro.`}function dt(){Kr.innerHTML="",Gr.innerHTML="",B.innerHTML="",B.classList.add(ze),Z.innerText="",Z.classList.add(ze),X.classList.remove(y),ae.classList.remove(y),pe.classList.remove(y),A.classList.remove(y),$e.classList.remove(y)}var Xr="uploader-advanced-form",i="is-invalid",Ie="d-none",Zr=t(Xr),J=t("uploader-advanced-alert"),me=t("uploader-advanced-category"),_r=t("uploader-advanced-classification-help"),he=t("uploader-advanced-day"),V=t("uploader-advanced-file"),ft=t("uploader-advanced-last-modified"),Jr=t("uploader-advanced-list-1"),Qr=t("uploader-advanced-list-2"),pt=t("uploader-advanced-magic"),se=t("uploader-advanced-month"),ve=t("uploader-advanced-operating-system"),Le=t("uploader-advanced-releaser-1"),D=t("uploader-advanced-results"),_=t("uploader-advanced-year");Zr.addEventListener("reset",function(){ft.value="",pt.value="",ht()});V.addEventListener("change",Wr);Le.addEventListener("input",c);_.addEventListener("input",f);se.addEventListener("input",d);he.addEventListener("input",Ye);me.addEventListener("change",c);ve.addEventListener("change",c);function mt(e){t(e).addEventListener("click",function(){let r=!0;if(Le.value==""&&(Le.classList.add(i),r=!1),n(_.value)==!1&&(_.classList.add(i),r=!1),o(se.value)==!1&&(se.classList.add(i),r=!1),ne(he.value)==!1&&(he.classList.add(i),r=!1),se.value!=""&&_.value==""&&(_.classList.add(i),r=!1),V.value==""&&(V.classList.add(i),r=!1),ve.value==""&&(ve.classList.add(i),r=!1),me.value==""&&(me.classList.add(i),r=!1),r==!1)return L(J,D);ht(),D.innerText="...",D.classList.remove(Ie)})}async function Wr(){v(V,J,D);let e=this.files[0],a=[u(e),ea(e)];p(a,J,V,D),m(e,J,V,D),h(e,ft,pt)}function ea(e){return qe(e.type)?`The chosen file mime type ${e.type} is probably not suitable for an upload.`:""}function ht(){Jr.innerHTML="",Qr.innerHTML="",D.innerHTML="",_r.innerHTML="",D.classList.add(Ie),J.innerText="",J.classList.add(Ie),_.classList.remove(i),se.classList.remove(i),he.classList.remove(i),Le.classList.remove(i),V.classList.remove(i),ve.classList.remove(i),me.classList.remove(i)}(()=>{"use strict";je(),ye("demozoo-submission","Demozoo"),ye("pouet-submission","Pou\xEBt"),Ue("uploader-image-submit"),H("uploader-image-form","uploader-image-progress"),Qe("uploader-intro-submit"),H("uploader-intro-form","uploader-intro-progress"),ut("uploader-trainer-submit"),H("uploader-trainer-form","uploader-trainer-progress"),rt("uploader-magazine-submit"),H("uploader-magazine-form","uploader-magazine-progress"),nt("uploader-text-submit"),H("uploader-text-form","uploader-text-progress"),mt("uploader-advanced-submit"),H("uploader-advanced-form","uploader-advanced-progress")})();})();
+(()=>{function t(e){let a=document.getElementById(e);if(a==null)throw new Error(`The ${e} for getElmById() element is null.`);return a}function n(e){if(`${e}`=="")return!0;let a=1980,r=new Date().getFullYear();return!(er)}function o(e){return`${e}`==""?!0:!(e<1||e>12)}function ne(e){return`${e}`==""?!0:!(e<1||e>31)}function Se(e,a){if(e=="")return!0;let r=Number(e),s=Number(a);if(!Number.isInteger(s)||s<1)throw new Error(`The ID sanity value is invalid: ${s}`);return Number.isInteger(r)&&r>0&&r<=s}var l="is-invalid",k="d-none",gt=100,xe=1024*1024,He=100*xe;function T(e,a){if(e==null)throw new Error("The elementId value of focusModalById is null.");if(a==null)throw new Error("The submissionId value of focusModalById is null.");let r=document.getElementById(a);if(r==null)throw new Error(`The ${a} element is null.`);let s=t(e);if(s.addEventListener("shown.bs.modal",function(){r.focus()}),bootstrap===void 0)throw new Error("The bootstrap object is undefined.");return new bootstrap.Modal(s,{keyboard:!0})}async function yt(e){if(e==null)throw new Error("The file value of checkSHA is null.");try{let a=await bt(e),r=await fetch(`/uploader/sha384/${a}`,{method:"PATCH",headers:{"Content-Type":"text/plain"},body:a});if(!r.ok)throw new Error(`Hashing is not possible, server response: ${r.status}`);return await r.text()=="true"}catch(a){console.log(`Hashing is not possible: ${a}`)}}async function bt(e){if(e==null)throw new Error("The file value of sha384 is null.");try{let a=await e.arrayBuffer(),r=await crypto.subtle.digest("SHA-384",a);return Array.from(new Uint8Array(r)).map(s=>s.toString(16).padStart(2,"0")).join("")}catch(a){throw new Error(`Could not use arrayBuffer or crypto.subtle: ${a}`)}}function H(e,a){if(e==null)throw new Error("The formId value of progress is null.");if(a==null)throw new Error("The elementId value of progress is null.");htmx.on(`#${e}`,"htmx:xhr:progress",function(r){r.target.id==`${e}`&&htmx.find(`#${a}`).setAttribute("value",r.detail.loaded/r.detail.total*gt)})}function u(e){if(e==null)throw new Error("The file value of checkSize is null.");return e.size>He?`The chosen file is too big at ${Math.round(e.size/xe)}MB, maximum size is ${He/xe}MB.`:""}function Ye(){return ne(this.value)==!1?(this.classList.add(l),!1):(this.classList.remove(l),!0)}function d(){return console.log(`The month value is ${this.value}.`),o(this.value)==!1?(this.classList.add(l),!1):(this.classList.remove(l),!0)}function f(){return n(this.value)==!1?(this.classList.add(l),!1):(this.classList.remove(l),!0)}function p(e,a,r,s){if(e==null)throw new Error("The errors value of checkErrors is null.");if(a==null)throw new Error("The alert value of checkErrors is null.");if(r==null)throw new Error("The fileInput value of checkErrors is null.");if(s==null)throw new Error("The results value of checkErrors is null.");e=e.filter(w=>w!=""),!(e.length<=0)&&(a.innerText=e.join(" "),a.classList.remove(k),r.innerText="",r.classList.add(l),s.classList.add(k))}async function m(e,a,r,s){if(e==null)throw new Error("The file value of checkDuplicate is null.");if(a==null)throw new Error("The alert value of checkDuplicate is null.");if(r==null)throw new Error("The fileInput value of checkDuplicate is null.");if(s==null)throw new Error("The results value of checkDuplicate is null.");await yt(e)!=!1&&(a.innerText=`The chosen file already exists in the database: ${e.name}`,a.classList.remove(k),r.innerText="",r.classList.add(l),s.classList.add(k))}function h(e,a,r){if(e==null)throw new Error("The file1 value of hiddenDetails is null.");if(a==null)throw new Error("The lastMod value of hiddenDetails is null.");if(r==null)throw new Error("The magic value of hiddenDetails is null.");let s=e.lastModified,w=new Date().getTime(),Be=60*60*1e3;w-s=400&&s.classList.remove(Q)}),document.body.addEventListener("htmx:afterRequest",function(S){if(S.detail.elt===null||S.detail.elt.id!==`${e}`)return;if(S.detail.successful)return Vt(r);let ie=S.detail.xhr;if(S.detail.failed&&ie)return ie.status===404?Rt(s,w,a):Nt(s,ie);qt(s)})}function je(e,a){e.addEventListener("input",function(){if(!Se(e.value,a)){e.classList.add(ge);return}e.classList.remove(ge)})}function At(e,a){a.innerHTML="",e.innerText="",e.classList.add(Q)}function Vt(e){e.focus()}function Rt(e,a,r){a.innerText=`Production not found on ${r}.`}function qt(e){e.innerText="Something with the browser is not working, please refresh the page.",e.classList.remove(Q)}function Nt(e,a){e.innerText=`Something went wrong, ${a.status} status: ${a.responseText}.`,e.classList.remove(Q)}var Pt="application/x-freearc",Kt="application/x-arj",Gt="application/x-bzip",Ot="application/x-bzip2",Ut="application/gzip",Xt="application/vnd.rar",Zt="application/x-tar",_t="application/zip",Jt="application/x-7z-compressed",Qt="application/x-msdos-program",Wt="image/bmp",er="image/gif",tr="image/jpeg",rr="image/vnd.zbrush.pcx",ar="image/png",sr="image/tiff",ir="image/webp",nr="application/x-csh",or="application/x-chrome-extension",lr="text/x-script.perl",cr="application/x-httpd-php",ur="text/x-script.phyton",dr="text/x-script.rexx",fr="application/x-sh",pr="application/x-shellscript",mr="text/x-script.tcl",hr="text/x-shellscript",vr="text/x-script.zsh";function Lr(){return[nr,or,lr,cr,ur,dr,fr,pr,mr,hr,vr]}function Ae(){return[Qt]}function oe(){return[Pt,Kt,Gt,Ot,Ut,Xt,Zt,_t,Jt]}function Ve(){return["application/octet-stream","application/x-binary","application/x-ms-dos-executable"]}function xr(){return[Wt,er,tr,rr,ar,sr,ir]}function Re(){return["text/plain","text/x-nfo"]}function qe(e){return Lr().includes(e)}function Ne(e){return xr().concat(oe()).includes(e)}function le(e){return Ae().concat(oe(),Ve()).includes(e)}function Pe(e){return Re().concat(oe(),Ae(),Ve()).includes(e)}function Ke(e){return Re().concat(oe()).includes(e)}var gr="uploader-image-form",E="is-invalid",be="d-none",yr=t(gr),q=t("uploader-image-alert"),Y=t("uploader-image-file"),Ge=t("uploader-image-last-modified"),br=t("uploader-image-list-1"),wr=t("uploader-image-list-2"),Oe=t("uploader-image-magic"),W=t("uploader-image-month"),ce=t("uploader-image-releaser-1"),M=t("uploader-image-results"),R=t("uploader-image-year");yr.addEventListener("reset",function(){Ge.value="",Oe.value="",Xe()});Y.addEventListener("change",Tr);ce.addEventListener("input",c);R.addEventListener("input",f);W.addEventListener("input",d);function Ue(e){t(e).addEventListener("click",function(){let r=!0;if(ce.value==""&&(ce.classList.add(E),r=!1),n(R.value)==!1&&(R.classList.add(E),r=!1),o(W.value)==!1&&(W.classList.add(E),r=!1),W.value!=""&&R.value==""&&(R.classList.add(E),r=!1),Y.value==""&&(Y.classList.add(E),r=!1),r==!1)return L(q,M);Xe(),M.innerText="...",M.classList.remove(be)})}async function Tr(){v(Y,q,M);let e=this.files[0],a=[u(e),Er(e)];p(a,q,Y,M),m(e,q,Y,M),h(e,Ge,Oe)}function Er(e){return Ne(e.type)?"":`The chosen file mime type ${e.type} is probably not suitable for an image.`}function Xe(){br.innerHTML="",wr.innerHTML="",M.innerHTML="",M.classList.add(be),q.innerText="",q.classList.add(be),R.classList.remove(E),W.classList.remove(E),ce.classList.remove(E),Y.classList.remove(E)}var kr="uploader-intro-form",b="is-invalid",we="d-none",Mr=t(kr),P=t("uploader-intro-alert"),F=t("uploader-intro-file"),Ze=t("uploader-intro-last-modified"),zr=t("uploader-intro-list-1"),$r=t("uploader-intro-list-2"),_e=t("uploader-intro-magic"),ee=t("uploader-intro-month"),ue=t("uploader-intro-releaser-1"),z=t("uploader-intro-results"),N=t("uploader-intro-year"),Je=t("uploader-intro-youtube");Mr.addEventListener("reset",function(){Ze.value="",_e.value="",We()});F.addEventListener("change",Ir);ue.addEventListener("input",c);N.addEventListener("input",f);ee.addEventListener("input",d);Je.addEventListener("input",Fe);function Qe(e){t(e).addEventListener("click",function(){let r=!0;if(ue.value==""&&(ue.classList.add(b),r=!1),n(N.value)==!1&&(N.classList.add(b),r=!1),o(ee.value)==!1&&(ee.classList.add(b),r=!1),ee.value!=""&&N.value==""&&(N.classList.add(b),r=!1),F.value==""&&(F.classList.add(b),r=!1),r==!1)return L(P,z);We(),z.innerText="...",z.classList.remove(we)})}async function Ir(){v(F,P,z);let e=this.files[0],a=[u(e),Br(e)];p(a,P,F,z),m(e,P,F,z),h(e,Ze,_e)}function Br(e){return le(e.type)?"":`The chosen file mime type ${e.type} is probably not suitable for an intro.`}function We(){zr.innerHTML="",$r.innerHTML="",z.innerHTML="",z.classList.add(we),P.innerText="",P.classList.add(we),N.classList.remove(b),ee.classList.remove(b),ue.classList.remove(b),Je.classList.remove(b),F.classList.remove(b)}var Dr="uploader-magazine-form",x="is-invalid",Te="d-none",Sr=t(Dr),G=t("uploader-magazine-alert"),C=t("uploader-magazine-file"),et=t("uploader-magazine-last-modified"),Hr=t("uploader-magazine-list-1"),tt=t("uploader-magazine-magic"),te=t("uploader-magazine-month"),de=t("uploader-magazine-releaser-1"),$=t("uploader-magazine-results"),Ee=t("uploader-magazine-title"),K=t("uploader-magazine-year");Sr.addEventListener("reset",function(){et.value="",tt.value="",at()});C.addEventListener("change",Yr);de.addEventListener("input",c);K.addEventListener("input",f);te.addEventListener("input",d);function rt(e){t(e).addEventListener("click",function(){let r=!0;if(Ee.value==""&&(Ee.classList.add(x),r=!1),de.value==""&&(de.classList.add(x),r=!1),n(K.value)==!1&&(K.classList.add(x),r=!1),o(te.value)==!1&&(te.classList.add(x),r=!1),te.value!=""&&K.value==""&&(K.classList.add(x),r=!1),C.value==""&&(C.classList.add(x),r=!1),r==!1)return L(G,$);at(),$.innerText="...",$.classList.remove(Te)})}async function Yr(){v(C,G,$);let e=this.files[0],a=[u(e),Fr(e)];p(a,G,C,$),m(e,G,C,$),h(e,et,tt)}function Fr(e){return Pe(e.type)?"":`The chosen file mime type ${e.type} is probably not suitable for an image.`}function at(){Hr.innerHTML="",$.innerHTML="",$.classList.add(Te),G.innerText="",G.classList.add(Te),K.classList.remove(x),te.classList.remove(x),de.classList.remove(x),C.classList.remove(x),Ee.classList.remove(x)}var Cr="uploader-text-form",g="is-invalid",ke="d-none",jr=t(Cr),U=t("uploader-text-alert"),j=t("uploader-text-file"),st=t("uploader-text-last-modified"),Ar=t("uploader-text-list-1"),Vr=t("uploader-text-list-2"),it=t("uploader-text-magic"),re=t("uploader-text-month"),fe=t("uploader-text-releaser-1"),I=t("uploader-text-results"),Me=t("uploader-text-title"),O=t("uploader-text-year");jr.addEventListener("reset",function(){st.value="",it.value="",ot()});j.addEventListener("change",Rr);fe.addEventListener("input",c);O.addEventListener("input",f);re.addEventListener("input",d);function nt(e){t(e).addEventListener("click",function(){let r=!0;if(Me.value==""&&(Me.classList.add(g),r=!1),fe.value==""&&(fe.classList.add(g),r=!1),n(O.value)==!1&&(O.classList.add(g),r=!1),o(re.value)==!1&&(re.classList.add(g),r=!1),re.value!=""&&O.value==""&&(O.classList.add(g),r=!1),j.value==""&&(j.classList.add(g),r=!1),r==!1)return L(U,I);ot(),I.innerText="...",I.classList.remove(ke)})}async function Rr(){v(j,U,I);let e=this.files[0],a=[u(e),qr(e)];p(a,U,j,I),m(e,U,j,I),h(e,st,it)}function qr(e){return Ke(e.type)?"":`The chosen file mime type ${e.type} is probably not suitable for a text.`}function ot(){Ar.innerHTML="",Vr.innerHTML="",I.innerHTML="",I.classList.add(ke),U.innerText="",U.classList.add(ke),O.classList.remove(g),re.classList.remove(g),fe.classList.remove(g),j.classList.remove(g),Me.classList.remove(g)}var Nr="uploader-trainer-form",y="is-invalid",ze="d-none",Pr=t(Nr),Z=t("uploader-trainer-alert"),A=t("uploader-trainer-file"),lt=t("uploader-trainer-last-modified"),Kr=t("uploader-trainer-list-1"),Gr=t("uploader-trainer-list-2"),ct=t("uploader-trainer-magic"),ae=t("uploader-trainer-month"),pe=t("uploader-trainer-releaser-1"),B=t("uploader-trainer-results"),$e=t("uploader-trainer-title"),X=t("uploader-trainer-year");Pr.addEventListener("reset",function(){lt.value="",ct.value="",dt()});A.addEventListener("change",Or);pe.addEventListener("input",c);X.addEventListener("input",f);ae.addEventListener("input",d);function ut(e){t(e).addEventListener("click",function(){let r=!0;if($e.value==""&&($e.classList.add(y),r=!1),pe.value==""&&(pe.classList.add(y),r=!1),n(X.value)==!1&&(X.classList.add(y),r=!1),o(ae.value)==!1&&(ae.classList.add(y),r=!1),ae.value!=""&&X.value==""&&(X.classList.add(y),r=!1),A.value==""&&(A.classList.add(y),r=!1),r==!1)return L(Z,B);dt(),B.innerText="...",B.classList.remove(ze)})}async function Or(){v(A,Z,B);let e=this.files[0],a=[u(e),Ur(e)];p(a,Z,A,B),m(e,Z,A,B),h(e,lt,ct)}function Ur(e){return le(e.type)?"":`The chosen file mime type ${e.type} is probably not suitable for an intro.`}function dt(){Kr.innerHTML="",Gr.innerHTML="",B.innerHTML="",B.classList.add(ze),Z.innerText="",Z.classList.add(ze),X.classList.remove(y),ae.classList.remove(y),pe.classList.remove(y),A.classList.remove(y),$e.classList.remove(y)}var Xr="uploader-advanced-form",i="is-invalid",Ie="d-none",Zr=t(Xr),J=t("uploader-advanced-alert"),me=t("uploader-advanced-category"),_r=t("uploader-advanced-classification-help"),he=t("uploader-advanced-day"),V=t("uploader-advanced-file"),ft=t("uploader-advanced-last-modified"),Jr=t("uploader-advanced-list-1"),Qr=t("uploader-advanced-list-2"),pt=t("uploader-advanced-magic"),se=t("uploader-advanced-month"),ve=t("uploader-advanced-operating-system"),Le=t("uploader-advanced-releaser-1"),D=t("uploader-advanced-results"),_=t("uploader-advanced-year");Zr.addEventListener("reset",function(){ft.value="",pt.value="",ht()});V.addEventListener("change",Wr);Le.addEventListener("input",c);_.addEventListener("input",f);se.addEventListener("input",d);he.addEventListener("input",Ye);me.addEventListener("change",c);ve.addEventListener("change",c);function mt(e){t(e).addEventListener("click",function(){let r=!0;if(Le.value==""&&(Le.classList.add(i),r=!1),n(_.value)==!1&&(_.classList.add(i),r=!1),o(se.value)==!1&&(se.classList.add(i),r=!1),ne(he.value)==!1&&(he.classList.add(i),r=!1),se.value!=""&&_.value==""&&(_.classList.add(i),r=!1),V.value==""&&(V.classList.add(i),r=!1),ve.value==""&&(ve.classList.add(i),r=!1),me.value==""&&(me.classList.add(i),r=!1),r==!1)return L(J,D);ht(),D.innerText="...",D.classList.remove(Ie)})}async function Wr(){v(V,J,D);let e=this.files[0],a=[u(e),ea(e)];p(a,J,V,D),m(e,J,V,D),h(e,ft,pt)}function ea(e){return qe(e.type)?`The chosen file mime type ${e.type} is probably not suitable for an upload.`:""}function ht(){Jr.innerHTML="",Qr.innerHTML="",D.innerHTML="",_r.innerHTML="",D.classList.add(Ie),J.innerText="",J.classList.add(Ie),_.classList.remove(i),se.classList.remove(i),he.classList.remove(i),Le.classList.remove(i),V.classList.remove(i),ve.classList.remove(i),me.classList.remove(i)}(()=>{"use strict";Ce(),ye("demozoo-submission","Demozoo"),ye("pouet-submission","Pou\xEBt"),Ue("uploader-image-submit"),H("uploader-image-form","uploader-image-progress"),Qe("uploader-intro-submit"),H("uploader-intro-form","uploader-intro-progress"),ut("uploader-trainer-submit"),H("uploader-trainer-form","uploader-trainer-progress"),rt("uploader-magazine-submit"),H("uploader-magazine-form","uploader-magazine-progress"),nt("uploader-text-submit"),H("uploader-text-form","uploader-text-progress"),mt("uploader-advanced-submit"),H("uploader-advanced-form","uploader-advanced-progress")})();})();
diff --git a/view/app/artifactedit.tmpl b/view/app/artifactedit.tmpl
index 98ebab13..ecb36653 100644
--- a/view/app/artifactedit.tmpl
+++ b/view/app/artifactedit.tmpl
@@ -240,6 +240,7 @@ aria-labelledby="artifact-delete-forever-modal-label" aria-hidden="true">
hx-include="[name='artifact-editor-key'],
[name='artifact-editor-titleundo']">
Reset title to {{$title}}
+
{{/* Comments */}}
diff --git a/view/app/artifactjsdos.tmpl b/view/app/artifactjsdos.tmpl
index 116c281f..b30c1672 100644
--- a/view/app/artifactjsdos.tmpl
+++ b/view/app/artifactjsdos.tmpl
@@ -63,9 +63,10 @@
"-c", "SET PATH=%PATH%;C:\\DOS4GW",
"-c", "{{$runProgram}}",
];
- ctx.font = "16px serif";
- ctx.fillText("Not working?", 10, 50);
- ctx.fillText("Try the browser Console for errors.", 10, 70);
+ ctx.font = "14px serif";
+ ctx.fillText("Stuck and not loading?", 10, 50);
+ ctx.fillText("1) try refreshing this tab.", 13, 70);
+ ctx.fillText("2) view the the tab Console for errors.", 13, 90);
const stopButton = document.getElementById("jsdosStop");
stopButton.addEventListener("click", () => {
try {
diff --git a/view/app/uploader_modal.tmpl b/view/app/uploader_modal.tmpl
index 8ad8363e..540b6955 100644
--- a/view/app/uploader_modal.tmpl
+++ b/view/app/uploader_modal.tmpl
@@ -314,7 +314,7 @@
+
@@ -335,12 +335,12 @@
Writers
-
-
@@ -429,7 +429,7 @@
Creators
-
@@ -509,7 +509,7 @@
Writers
-