]> OzVa Git service - delta-velorum/commitdiff
Renaming and adding Delta Velorum
authorMax Value <greenwoodw50@gmail.com>
Mon, 4 May 2026 11:59:34 +0000 (12:59 +0100)
committerMax Value <greenwoodw50@gmail.com>
Mon, 4 May 2026 11:59:34 +0000 (12:59 +0100)
119 files changed:
Makefile
argo/__init__.py [new file with mode: 0644]
argo/admin.py [new file with mode: 0644]
argo/database/__init__.py [new file with mode: 0644]
argo/database/read.py [new file with mode: 0644]
argo/database/utils.py [new file with mode: 0644]
argo/database/write.py [new file with mode: 0644]
argo/src/admin.ts [new file with mode: 0644]
argo/src/discount.ts [new file with mode: 0644]
argo/src/price.ts [new file with mode: 0644]
argo/src/show_until.ts [new file with mode: 0644]
argo/src/sound.ts [new file with mode: 0644]
argo/src/state.ts [new file with mode: 0644]
argo/src/style.ts [new file with mode: 0644]
argo/src/text.ts [new file with mode: 0644]
argo/src/time.ts [new file with mode: 0644]
argo/src/until.ts [new file with mode: 0644]
argo/src/update.ts [new file with mode: 0644]
argo/src/utils.ts [new file with mode: 0644]
argo/static/admin.css [new file with mode: 0644]
argo/static/andika.css [new file with mode: 0644]
argo/static/fonts/Andika-Bold.woff2 [new file with mode: 0644]
argo/static/fonts/Andika-BoldItalic.woff2 [new file with mode: 0644]
argo/static/fonts/Andika-Italic.woff2 [new file with mode: 0644]
argo/static/fonts/Andika-Medium.woff2 [new file with mode: 0644]
argo/static/fonts/Andika-MediumItalic.woff2 [new file with mode: 0644]
argo/static/fonts/Andika-Regular.woff2 [new file with mode: 0644]
argo/static/fonts/Andika-SemiBold.woff2 [new file with mode: 0644]
argo/static/fonts/Andika-SemiBoldItalic.woff2 [new file with mode: 0644]
argo/static/info.css [new file with mode: 0644]
argo/static/media/sfx/banner_shout.wav [new file with mode: 0644]
argo/static/media/sfx/clock.wav [new file with mode: 0644]
argo/static/media/sfx/shout.wav [new file with mode: 0644]
argo/static/media/sfx/state_change.wav [new file with mode: 0644]
argo/static/media/velo.jpg [new file with mode: 0644]
argo/static/style.css [new file with mode: 0644]
argo/static/style/banner_box.css [new file with mode: 0644]
argo/static/style/box.css [new file with mode: 0644]
argo/static/style/center_shout.css [new file with mode: 0644]
argo/static/style/discount_box.css [new file with mode: 0644]
argo/static/style/item_box.css [new file with mode: 0644]
argo/static/style/logo_box.css [new file with mode: 0644]
argo/static/style/pricing_box.css [new file with mode: 0644]
argo/static/style/qty_box.css [new file with mode: 0644]
argo/static/style/show_until.css [new file with mode: 0644]
argo/static/style/side_box.css [new file with mode: 0644]
argo/static/style/side_timer_box.css [new file with mode: 0644]
argo/templates/admin.html [new file with mode: 0644]
argo/templates/admin/color.html [new file with mode: 0644]
argo/templates/admin/float.html [new file with mode: 0644]
argo/templates/admin/number.html [new file with mode: 0644]
argo/templates/admin/text.html [new file with mode: 0644]
argo/templates/admin/textarea.html [new file with mode: 0644]
argo/templates/admin/trigger.html [new file with mode: 0644]
argo/templates/index.html [new file with mode: 0644]
argo/templates/info/a.html [new file with mode: 0644]
argo/templates/info/b.html [new file with mode: 0644]
argo/templates/info/c.html [new file with mode: 0644]
argo/templates/table.html [new file with mode: 0644]
argo/utils.py [new file with mode: 0644]
director/__init__.py [deleted file]
director/admin.py [deleted file]
director/database/__init__.py [deleted file]
director/database/read.py [deleted file]
director/database/utils.py [deleted file]
director/database/write.py [deleted file]
director/src/admin.ts [deleted file]
director/src/discount.ts [deleted file]
director/src/price.ts [deleted file]
director/src/show_until.ts [deleted file]
director/src/sound.ts [deleted file]
director/src/state.ts [deleted file]
director/src/style.ts [deleted file]
director/src/text.ts [deleted file]
director/src/time.ts [deleted file]
director/src/until.ts [deleted file]
director/src/update.ts [deleted file]
director/src/utils.ts [deleted file]
director/static/admin.css [deleted file]
director/static/andika.css [deleted file]
director/static/fonts/Andika-Bold.woff2 [deleted file]
director/static/fonts/Andika-BoldItalic.woff2 [deleted file]
director/static/fonts/Andika-Italic.woff2 [deleted file]
director/static/fonts/Andika-Medium.woff2 [deleted file]
director/static/fonts/Andika-MediumItalic.woff2 [deleted file]
director/static/fonts/Andika-Regular.woff2 [deleted file]
director/static/fonts/Andika-SemiBold.woff2 [deleted file]
director/static/fonts/Andika-SemiBoldItalic.woff2 [deleted file]
director/static/info.css [deleted file]
director/static/media/sfx/banner_shout.wav [deleted file]
director/static/media/sfx/clock.wav [deleted file]
director/static/media/sfx/shout.wav [deleted file]
director/static/media/sfx/state_change.wav [deleted file]
director/static/style.css [deleted file]
director/static/style/banner_box.css [deleted file]
director/static/style/box.css [deleted file]
director/static/style/center_shout.css [deleted file]
director/static/style/discount_box.css [deleted file]
director/static/style/item_box.css [deleted file]
director/static/style/logo_box.css [deleted file]
director/static/style/pricing_box.css [deleted file]
director/static/style/qty_box.css [deleted file]
director/static/style/show_until.css [deleted file]
director/static/style/side_box.css [deleted file]
director/static/style/side_timer_box.css [deleted file]
director/templates/admin.html [deleted file]
director/templates/admin/color.html [deleted file]
director/templates/admin/float.html [deleted file]
director/templates/admin/number.html [deleted file]
director/templates/admin/text.html [deleted file]
director/templates/admin/textarea.html [deleted file]
director/templates/admin/trigger.html [deleted file]
director/templates/index.html [deleted file]
director/templates/info/a.html [deleted file]
director/templates/info/b.html [deleted file]
director/templates/info/c.html [deleted file]
director/templates/table.html [deleted file]
director/utils.py [deleted file]
tsconfig.json

index 0709a5c2adafcbcd3ab24a133a00cab44a5b787f..dcd7bf164fd4eedcf2b9c1283fb30d248c84460a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 main : .venv/touchfile
        npx tsc
-       .venv/bin/flask --app director run --debug
+       .venv/bin/flask --app argo run --debug
 
 .venv/touchfile : requirements.txt
        python3 -m venv .venv
diff --git a/argo/__init__.py b/argo/__init__.py
new file mode 100644 (file)
index 0000000..2b0c685
--- /dev/null
@@ -0,0 +1,65 @@
+from werkzeug.security import generate_password_hash, check_password_hash
+from flask import Flask, render_template, send_from_directory, request
+from flask_socketio import SocketIO, emit
+from flask_httpauth import HTTPBasicAuth
+from flask_cors import CORS
+import json
+import os
+
+from .utils import deindex
+
+STAR = os.getenv("DELTA_VELORUM", "B")
+import argo.admin as admin
+
+from argo.database.read import read_views as database_read_views
+
+app = Flask(__name__, instance_relative_config=False)
+socketio = SocketIO(app, logger=False, engineio_logger=False)
+auth = HTTPBasicAuth()
+CORS(app)
+
+# import authentication data
+
+with open(f"{app.root_path}/../../secrets.json", "r", encoding="utf-8") as f:
+       users = json.loads(f.read())
+users = {k: generate_password_hash(v) for (k, v) in users.items()}
+
+# password verifier
+
+def verify_password(username, password):
+    if username in users and check_password_hash(users.get(username), password):
+        return username
+
+auth.verify_password(verify_password)
+
+# root movements
+
+@app.route("/", methods=['get'])
+def index():
+       return render_template("index.html")
+
+@socketio.on('connect')
+def connecting():
+       emit("update", database_read_views(), json=True, namespace="/", broadcast=True)
+
+# info screen pages
+
+@app.route("/info/<string:screen>", methods=["get"])
+def info(screen):
+       return render_template(f"info/{screen}.html")
+
+# admin screen pages
+
+app.route("/admin", methods=["get"])(auth.login_required(admin.admin_main))
+app.route("/admin/<string:table_name>", methods=["get", "post"])(auth.login_required(admin.admin_table))
+
+# script pages
+
+@app.route("/script/<path:filename>", methods=["get"])
+def script(filename):
+       return send_from_directory(os.path.join(app.root_path, "build"), filename)
+
+@app.route("/db", methods=["get"])
+@auth.login_required
+def download_db():
+       return send_from_directory(f"{app.root_path}/../data", "main.db")
diff --git a/argo/admin.py b/argo/admin.py
new file mode 100644 (file)
index 0000000..dac3bb5
--- /dev/null
@@ -0,0 +1,40 @@
+from flask import render_template, request
+from flask_socketio import emit
+import time
+
+from argo.database.read import read_indexes as database_read_indexes
+from argo.database.read import read_views as database_read_views
+from argo.database.write import write as database_write
+from argo.database.read import read as database_read
+
+from argo import STAR
+
+def admin_main():
+       return render_template(
+               "admin.html",
+               indexes=database_read_indexes(),
+               star=STAR
+               )
+
+def admin_table(table_name):
+       start = time.time()
+
+       if request.method == "POST":
+               database_write(request.form)
+
+               emit(
+                       "update",
+                       database_read_views(table_name),
+                       json=True, namespace="/", broadcast=True
+                       )
+
+       end = time.time()
+
+       return render_template(
+               "table.html",
+               indexes=database_read_indexes(),
+               table=database_read(table_name),
+               table_name=table_name,
+               time_taken = end - start,
+               star=STAR
+               )
diff --git a/argo/database/__init__.py b/argo/database/__init__.py
new file mode 100644 (file)
index 0000000..e408c87
--- /dev/null
@@ -0,0 +1,14 @@
+"""
+       package to read and write to the database
+
+       check if file exists and pragam check the database on init
+"""
+
+from .utils import integrity_check, optimize
+import sqlite3
+import os
+
+assert os.path.exists("./data/main.db"), "Database missing"
+assert integrity_check(), "Database integrity error"
+
+optimize()
diff --git a/argo/database/read.py b/argo/database/read.py
new file mode 100644 (file)
index 0000000..b180b39
--- /dev/null
@@ -0,0 +1,69 @@
+import sqlite3
+
+from .utils import list_all, list_views
+
+def read_all_current():
+       tables = list_all()
+       indexes = read_indexes()
+
+       with sqlite3.connect("./data/main.db") as connection:
+               cursor = connection.cursor()
+
+               data = {}
+               for table in tables:
+                       if table == "indexes": continue
+
+                       if "__view" in table:
+                               index_table = table.split("__view")[0]
+                       else: index_table = table
+
+                       cursor.execute(f"SELECT * FROM {table};")
+
+                       names = list(map(lambda x: f"{table}~~{x[0]}", cursor.description))
+                       row = cursor.fetchall()[indexes[f"int--{index_table}"]]
+
+                       data.update(dict(zip(names, row)))
+
+               return data
+
+def read(table):
+       """
+               reads a table by name
+       """
+       with sqlite3.connect("./data/main.db") as connection:
+               cursor = connection.cursor()
+
+               cursor.execute(f"SELECT * FROM {table};")
+
+               names = list(map(lambda x: x[0], cursor.description))
+               rows = [dict(zip(names, row)) for row in cursor.fetchall()]
+
+       return rows
+
+def read_views(table=None):
+       """
+               Reads views. If a table is specified, it reads all views related to that
+               table. If not it reads all views.
+       """
+       if table is None:
+               related = list_views()
+       else:
+               related = [view for view in list_views() if view.split("__view")[0] == table]
+
+       data = {}
+       for view in related:
+               for key, value in read(view)[0].items():
+                       data.update({f"{view.replace('__view', '')}~~{key}": value})
+
+       return data
+
+def read_indexes():
+       with sqlite3.connect("./data/main.db") as connection:
+               cursor = connection.cursor()
+
+               cursor.execute("SELECT * FROM indexes;")
+
+               names = list(map(lambda x: x[0], cursor.description))
+               indexes = [dict(zip(names, row)) for row in cursor.fetchall()][0]
+
+               return indexes
diff --git a/argo/database/utils.py b/argo/database/utils.py
new file mode 100644 (file)
index 0000000..6866761
--- /dev/null
@@ -0,0 +1,37 @@
+import sqlite3
+
+def integrity_check():
+       """
+               check the database is ok and return true if it is
+       """
+       with sqlite3.connect("./data/main.db") as connection:
+               cursor = connection.cursor()
+               integrity = cursor.execute('PRAGMA integrity_check')
+
+               return integrity.fetchone()[0] == "ok"
+
+def optimize():
+       """
+               check the database is ok and return true if it is
+       """
+       with sqlite3.connect("./data/main.db") as connection:
+               cursor = connection.cursor()
+               integrity = cursor.execute('PRAGMA optimize')
+
+def list_all():
+       """
+               get a list of all the tables and views in the database
+       """
+       with sqlite3.connect("./data/main.db") as connection:
+               cursor = connection.cursor()
+               cursor.execute("SELECT name FROM sqlite_master WHERE type IN ('table', 'view');")
+               return [table[0] for table in cursor.fetchall()]
+
+def list_views():
+       """
+               get a list of all the views in the database
+       """
+       with sqlite3.connect("./data/main.db") as connection:
+               cursor = connection.cursor()
+               cursor.execute("SELECT name FROM sqlite_master WHERE type='view';")
+               return [table[0] for table in cursor.fetchall()]
diff --git a/argo/database/write.py b/argo/database/write.py
new file mode 100644 (file)
index 0000000..eea0126
--- /dev/null
@@ -0,0 +1,20 @@
+import sqlite3
+
+from .utils import list_all
+from .read import read
+
+def write(data):
+
+       with sqlite3.connect("./data/main.db") as connection:
+               cursor = connection.cursor()
+
+               for key in data:
+                       table, index, feild = key.split("~~")
+
+                       cursor.execute(f"""
+                               UPDATE {table}
+                               SET '{feild}' = '{data[key]}'
+                               WHERE ROWID = {int(index) + 1};
+                               """)
+
+                       connection.commit()
diff --git a/argo/src/admin.ts b/argo/src/admin.ts
new file mode 100644 (file)
index 0000000..22e72e3
--- /dev/null
@@ -0,0 +1,40 @@
+const outlineStyle: string = "4px solid green";
+const outlineTime: number = 500; // ms
+
+export function setupTrigger() {
+       // setup all trigger buttons to send post request on click
+       const el: HTMLCollectionOf<Element> =
+               document.getElementsByClassName("trigger");
+
+       for (let e of el) {
+               e.addEventListener("click", (event) => {
+                       if (event.target instanceof HTMLElement) {
+                               let time: number = Math.round(Date.now() / 1000);
+                               let body: FormData = new FormData();
+                               let delay = document.getElementById(`${event.target.getAttribute('name')}+delay`);
+
+                               if (delay instanceof HTMLInputElement) {
+                                       body.set(`${event.target.getAttribute('name')}`, `${time}+${delay.value}`);
+
+                                       fetch("", {
+                                               method: "POST",
+                                               body: body
+                                       });
+
+                                       // trigger the button to turn green for approx same time (or 1s)
+                                       let timeout: number = delay.value as unknown as number * 1000;
+                                       if (timeout < outlineTime) { timeout = outlineTime; }
+
+                                       if ( event.target instanceof HTMLElement) {
+                                               event.target.style.outline = outlineStyle;
+                                               setTimeout(function () {
+                                                       if ( event.target instanceof HTMLElement) {
+                                                               event.target.style.outline = "none"
+                                                       }
+                                               }, timeout);
+                                       }
+                               }
+                       }
+               })
+       }
+}
diff --git a/argo/src/discount.ts b/argo/src/discount.ts
new file mode 100644 (file)
index 0000000..d05bd20
--- /dev/null
@@ -0,0 +1,25 @@
+export function renderDiscount(): void {
+       const el: HTMLCollectionOf<Element> =
+               document.getElementsByClassName("discount");
+
+       for (let e of el) {
+               if (e instanceof HTMLElement) {
+                       if (typeof e.dataset.raw === "string") {
+                               e.innerHTML = `${e.dataset.raw}%`;
+                       }
+               }
+       }
+}
+
+export function renderReverseDiscount(): void {
+       const el: HTMLCollectionOf<Element> =
+       document.getElementsByClassName("reverseDiscount");
+
+       for (let e of el) {
+               if (e instanceof HTMLElement) {
+                       if (typeof e.dataset.raw === "string") {
+                               e.innerHTML = `${100 - Number(e.dataset.raw)}%`;
+                       }
+               }
+       }
+}
diff --git a/argo/src/price.ts b/argo/src/price.ts
new file mode 100644 (file)
index 0000000..0d926c5
--- /dev/null
@@ -0,0 +1,12 @@
+export default function renderPrice(): void {
+       const el: HTMLCollectionOf<Element> =
+               document.getElementsByClassName("price");
+
+       for (let e of el) {
+               if (e instanceof HTMLElement) {
+                       if (typeof e.dataset.raw === "string") {
+                               e.innerHTML = String(parseFloat(e.dataset.raw).toFixed(2));
+                       }
+               }
+       }
+}
diff --git a/argo/src/show_until.ts b/argo/src/show_until.ts
new file mode 100644 (file)
index 0000000..6658b09
--- /dev/null
@@ -0,0 +1,16 @@
+export default function renderShowUntil(): void {
+       const el: HTMLCollectionOf<Element> =
+               document.getElementsByClassName("showUntil");
+
+       for (let e of el) {
+               if (e instanceof HTMLElement) {
+                       if (typeof e.dataset.raw === "string") {
+                               let duration: number = (eval(e.dataset.raw) * 1000) - Date.now();
+                               if (duration > 0) {
+                                       e.classList.add("showUntil-showing")
+                                       setTimeout(function () {e.classList.remove("showUntil-showing")}, duration)
+                               }
+                       }
+               }
+       }
+}
diff --git a/argo/src/sound.ts b/argo/src/sound.ts
new file mode 100644 (file)
index 0000000..b387907
--- /dev/null
@@ -0,0 +1,30 @@
+export function setupSounds() {
+       const el: HTMLCollectionOf<Element> =
+               document.getElementsByClassName("sound");
+
+       const context = new AudioContext();
+       if (el.length > 0) {
+               for (let e of el) {
+                       if (e instanceof HTMLMediaElement) {
+                               const track = context.createMediaElementSource(e);
+                               track.connect(context.destination);
+                       }
+               }
+       }
+}
+
+export function playSounds() {
+       const el: HTMLCollectionOf<Element> =
+               document.getElementsByClassName("sound");
+
+       for (let e of el) {
+               if (e instanceof HTMLMediaElement) {
+                       if (typeof e.dataset.raw === "string") {
+                               if (e.dataset.rawLast != e.dataset.raw) {
+                                       e.play();
+                               }
+                               e.dataset.rawLast = e.dataset.raw;
+                       }
+               }
+       }
+}
diff --git a/argo/src/state.ts b/argo/src/state.ts
new file mode 100644 (file)
index 0000000..d206f25
--- /dev/null
@@ -0,0 +1,18 @@
+export default function renderState(): void {
+       const el: HTMLCollectionOf<Element> =
+               document.getElementsByClassName("state");
+
+       for (let e of el) {
+               if (e instanceof HTMLElement) {
+                       if (typeof e.dataset.raw === "string") {
+                               for (let className of e.classList) {
+                                       if (className.startsWith("state-")) {
+                                               e.classList.remove(className);
+                                       }
+                               }
+
+                               e.classList.add(`state-${e.dataset.raw}`);
+                       }
+               }
+       }
+}
diff --git a/argo/src/style.ts b/argo/src/style.ts
new file mode 100644 (file)
index 0000000..380559e
--- /dev/null
@@ -0,0 +1,31 @@
+export function setupStyle(): void {
+       const el: HTMLCollectionOf<Element> =
+               document.getElementsByClassName("style");
+
+       for (let i = 0; i < el.length; i++) {
+               const stylesheet = new CSSStyleSheet();
+               document.adoptedStyleSheets.push(stylesheet);
+       }
+}
+
+export function renderStyle(): void {
+       const el: HTMLCollectionOf<Element> =
+               document.getElementsByClassName("style");
+
+       for (let [i, e] of Array.from(el).entries()) {
+               if (e instanceof HTMLElement) {
+                       let variable;
+                       for (let className of e.classList) {
+                               if (className.includes("--")) {
+                                       variable = className.split("--")[1];
+                               }
+                       }
+
+                       if (typeof e.dataset.raw === "string") {
+                               document.adoptedStyleSheets[i].replace(`
+                               :root {--${variable}: ${e.dataset.raw};}
+                               `);
+                       }
+               }
+       }
+}
diff --git a/argo/src/text.ts b/argo/src/text.ts
new file mode 100644 (file)
index 0000000..7695065
--- /dev/null
@@ -0,0 +1,10 @@
+export default function renderText(): void {
+       const el = document.querySelectorAll(".text,.title");
+       for (let e of el) {
+               if (e instanceof HTMLElement) {
+                       if (typeof e.dataset.raw === "string") {
+                               e.innerHTML = e.dataset.raw;
+                       }
+               }
+       }
+}
diff --git a/argo/src/time.ts b/argo/src/time.ts
new file mode 100644 (file)
index 0000000..84b69f3
--- /dev/null
@@ -0,0 +1,51 @@
+import { timeSince, timeUntil, timeFormatBroadcast } from "./utils.js";
+
+const timeUpdate: number = 1000; // ms
+
+export function setupTimeSince(): void {
+       const el: HTMLCollectionOf<Element> =
+               document.getElementsByClassName("since");
+
+       if (el.length > 0) {
+               setInterval(
+                       function () {
+                               const el: HTMLCollectionOf<Element> =
+                                       document.getElementsByClassName("since");
+
+                               for (let e of el) {
+                                       if (e instanceof HTMLElement) {
+                                               if (typeof e.dataset.raw === "string") {
+                                                       let [hours, minutes, seconds] = timeSince(eval(e.dataset.raw))
+                                                       e.innerHTML = timeFormatBroadcast(hours, minutes, seconds);
+                                               }
+                                       }
+                               }
+                       },
+                       timeUpdate
+               );
+       }
+}
+
+export function setupTimeUntil(): void {
+       const el: HTMLCollectionOf<Element> =
+       document.getElementsByClassName("until");
+
+       if (el.length > 0) {
+               setInterval(
+                       function () {
+                               const el: HTMLCollectionOf<Element> =
+                               document.getElementsByClassName("until");
+
+                               for (let e of el) {
+                                       if (e instanceof HTMLElement) {
+                                               if (typeof e.dataset.raw === "string") {
+                                                       let [hours, minutes, seconds] = timeUntil(eval(e.dataset.raw))
+                                                       e.innerHTML = timeFormatBroadcast(hours, minutes, seconds);
+                                               }
+                                       }
+                               }
+                       },
+                       timeUpdate
+               );
+       }
+}
diff --git a/argo/src/until.ts b/argo/src/until.ts
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/argo/src/update.ts b/argo/src/update.ts
new file mode 100644 (file)
index 0000000..f122da3
--- /dev/null
@@ -0,0 +1,43 @@
+import { io } from "socket.io-client";
+
+import { renderDiscount, renderReverseDiscount } from "./discount.js";
+import { setupTimeSince, setupTimeUntil } from "./time.js";
+import { setupSounds, playSounds } from "./sound.js";
+import { setupStyle, renderStyle } from "./style.js";
+import renderShowUntil from "./show_until.js";
+import renderState from "./state.js";
+import renderPrice from "./price.js"
+import renderText from "./text.js";
+
+export default function setupUpdate(): void {
+       setupTimeSince();
+       setupTimeUntil();
+       setupSounds();
+       setupStyle();
+
+       const socket = io();
+       socket.on("update", (data) => {
+               const start = performance.now()
+
+               for (const [key, value] of Object.entries(data)) {
+                       const el = document.querySelectorAll(`.update[class~='${key}']`);
+
+                       for (let e of el) {
+                               if (e instanceof HTMLElement) {
+                                       e.dataset.raw = value as unknown as string;
+                               }
+                       }
+               }
+
+               renderReverseDiscount();
+               renderShowUntil();
+               renderDiscount();
+               renderState();
+               renderPrice();
+               renderStyle();
+               renderText();
+               playSounds();
+
+               console.log(`Updated in ${performance.now() - start}ms`);
+       });
+}
diff --git a/argo/src/utils.ts b/argo/src/utils.ts
new file mode 100644 (file)
index 0000000..684ee85
--- /dev/null
@@ -0,0 +1,35 @@
+export function timeUntil(end: number): number[] {
+       let current: number = Date.now() / 1000;
+       var time: number = end - current;
+
+       if (Math.sign(time) == -1) {time = 0;}
+
+       let hours: number = Math.floor(time / 3600);
+       time %= 3600;
+       let minutes: number = Math.floor(time / 60);
+       let seconds: number = Math.floor(time % 60);
+
+       return [hours, minutes, seconds]
+}
+
+export function timeSince(end: number): number[] {
+       let current: number = Date.now() / 1000;
+       var time: number = current - end;
+
+       if (Math.sign(time) == -1) {time = 0;}
+
+       let hours: number = Math.floor(time / 3600);
+       time %= 3600;
+       let minutes: number = Math.floor(time / 60);
+       let seconds: number = Math.floor(time % 60);
+
+       return [hours, minutes, seconds]
+}
+
+export function timeFormatBroadcast(hours: number, minutes: number, seconds: number): string {
+       var hoursString = hours.toString().padStart(2, "0");
+       var minutesString = minutes.toString().padStart(2, "0");
+       var secondsString = seconds.toString().padStart(2, "0");
+
+       return `${hoursString}h ${minutesString}' ${secondsString}"`
+}
diff --git a/argo/static/admin.css b/argo/static/admin.css
new file mode 100644 (file)
index 0000000..8ec2ddc
--- /dev/null
@@ -0,0 +1,79 @@
+/* PAGE POSITIONING */
+
+:root {
+       --nav-background: lightgray;
+}
+
+body > * {
+       padding: 15px;
+       overflow: scroll
+}
+nav {
+       position: absolute;
+       top: 0; bottom: 0; left: 0;
+       right: max(80%, calc(100vw - 350px));
+       background-color: var(--nav-background);
+}
+main {
+       position: absolute;
+       top: 0; bottom: 0; right: 0;
+       left: min(20%, calc(350px));
+}
+
+/* THE OPTIONS GRID */
+
+.optionsGrid {
+       display: grid;
+       grid-template-columns: 50px auto auto auto;
+}
+.optionsGrid > * {
+       padding: 10px;
+       border: 1px solid gray;
+       margin-top: -1px;
+       margin-right: -1px;
+}
+.optionsGridSpacer { border: none; }
+
+
+:target {
+       outline: 4px solid blue;
+       z-index: 1;
+}
+.currentValue { color: red; }
+.currentValue[type="radio"] { background-color: red; }
+
+i {
+       font-style: normal;
+       color: white;
+       text-shadow:
+               1px 1px 0 black,
+               -1px 1px 0 black,
+               1px -1px 0 black,
+               -1px -1px 0 black,
+               0px 1px 0 black,
+               0px -1px 0 black,
+               1px 0px 0 black,
+               -1px 0px 0 black;
+}
+
+/* PRINT MODE
+               need to work on this a little bit, currently just hides things that
+               shouldnt be printed and thats all. Should be able to potentially display
+               extra elements or manipulate the page in a way that make it easy to read
+               or annotate on the page.
+ */
+
+@media ( max-width: 1000px ) {
+       nav { position: static; }
+       main { position: static; }
+}
+
+@media print {
+       nav, [type="radio"] { display: none }
+       [type="submit"] { opacity: 0; }
+       main { position: static; }
+       .currentValue { color: black; }
+       .optionsGrid { grid-template-columns: 0 auto 0 auto; }
+       .optionsGrid > * { padding: 0; }
+       .optionsGridSpacer { padding: 20px; }
+}
diff --git a/argo/static/andika.css b/argo/static/andika.css
new file mode 100644 (file)
index 0000000..0f268e5
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+This file is from the Andika project (https://software.sil.org/andika/).\r
+Copyright (c) 2004-2025 SIL Global (https://www.sil.org/) with Reserved\r
+Font Names "Andika" and "SIL". This Font Software is licensed under the SIL\r
+Open Font License, Version 1.1 (https://openfontlicense.org).\r
+*/\r
+\r
+@font-face {\r
+       font-family: "Andika";\r
+       font-weight: 400;\r
+       src: url(/static/fonts/Andika-Regular.woff2);\r
+}\r
+@font-face {\r
+       font-family: "Andika";\r
+       font-weight: 500;\r
+       src: url(/static/fonts/Andika-Medium.woff2);\r
+}\r
+@font-face {\r
+       font-family: "Andika";\r
+       font-weight: 600;\r
+       src: url(/static/fonts/Andika-SemiBold.woff2);\r
+}\r
+@font-face {\r
+       font-family: "Andika";\r
+       font-weight: 700;\r
+       src: url(/static/fonts/Andika-Bold.woff2);\r
+}\r
+@font-face {\r
+       font-family: "Andika";\r
+       font-weight: 400;\r
+       font-style: italic;\r
+       src: url(/static/fonts/Andika-Italic.woff2);\r
+}\r
+@font-face {\r
+       font-family: "Andika";\r
+       font-weight: 500;\r
+       font-style: italic;\r
+       src: url(/static/fonts/Andika-MediumItalic.woff2);\r
+}\r
+@font-face {\r
+       font-family: "Andika";\r
+       font-weight: 600;\r
+       font-style: italic;\r
+       src: url(/static/fonts/Andika-SemiBoldItalic.woff2);\r
+}\r
+@font-face {\r
+       font-family: "Andika";\r
+       font-weight: 700;\r
+       font-style: italic;\r
+       src: url(/static/fonts/Andika-BoldItalic.woff2);\r
+}\r
+\r
+:root {\r
+       font-family: "Andika", sans-serif;\r
+}\r
diff --git a/argo/static/fonts/Andika-Bold.woff2 b/argo/static/fonts/Andika-Bold.woff2
new file mode 100644 (file)
index 0000000..866d64a
Binary files /dev/null and b/argo/static/fonts/Andika-Bold.woff2 differ
diff --git a/argo/static/fonts/Andika-BoldItalic.woff2 b/argo/static/fonts/Andika-BoldItalic.woff2
new file mode 100644 (file)
index 0000000..6941dca
Binary files /dev/null and b/argo/static/fonts/Andika-BoldItalic.woff2 differ
diff --git a/argo/static/fonts/Andika-Italic.woff2 b/argo/static/fonts/Andika-Italic.woff2
new file mode 100644 (file)
index 0000000..29d7283
Binary files /dev/null and b/argo/static/fonts/Andika-Italic.woff2 differ
diff --git a/argo/static/fonts/Andika-Medium.woff2 b/argo/static/fonts/Andika-Medium.woff2
new file mode 100644 (file)
index 0000000..e47adf4
Binary files /dev/null and b/argo/static/fonts/Andika-Medium.woff2 differ
diff --git a/argo/static/fonts/Andika-MediumItalic.woff2 b/argo/static/fonts/Andika-MediumItalic.woff2
new file mode 100644 (file)
index 0000000..928f4e3
Binary files /dev/null and b/argo/static/fonts/Andika-MediumItalic.woff2 differ
diff --git a/argo/static/fonts/Andika-Regular.woff2 b/argo/static/fonts/Andika-Regular.woff2
new file mode 100644 (file)
index 0000000..d3e1a0d
Binary files /dev/null and b/argo/static/fonts/Andika-Regular.woff2 differ
diff --git a/argo/static/fonts/Andika-SemiBold.woff2 b/argo/static/fonts/Andika-SemiBold.woff2
new file mode 100644 (file)
index 0000000..09b7ebd
Binary files /dev/null and b/argo/static/fonts/Andika-SemiBold.woff2 differ
diff --git a/argo/static/fonts/Andika-SemiBoldItalic.woff2 b/argo/static/fonts/Andika-SemiBoldItalic.woff2
new file mode 100644 (file)
index 0000000..69ae382
Binary files /dev/null and b/argo/static/fonts/Andika-SemiBoldItalic.woff2 differ
diff --git a/argo/static/info.css b/argo/static/info.css
new file mode 100644 (file)
index 0000000..c8c37b9
--- /dev/null
@@ -0,0 +1,39 @@
+:root {
+       font-family: sans-serif;
+       color: white;
+       background-color: black;
+}
+
+.infoA { font-size: var(--aFontSize); }
+.infoB { font-size: var(--bFontSize); }
+.infoC { font-size: var(--cFontSize); }
+
+.title { text-transform: capitalize; }
+
+/* INFO A */
+.infoA div > * { padding: 20px; }
+.infoA div {
+       position: absolute;
+       top: 0; left: 0; bottom: 0; right: 0;
+       display: grid;
+       grid: none / 1fr;
+}
+
+/* INFO B */
+.infoB div > * { padding: 20px; }
+.infoB div {
+       position: absolute;
+       top: 0; left: 0; bottom: 0; right: 0;
+       display: grid;
+       grid: none / 1fr 1fr;
+}
+
+/* INFO C */
+.infoC div > * { padding: 20px; text-align: center; }
+.infoC div {
+       position: absolute;
+       top: 0; left: 0; bottom: 0; right: 0;
+       display: grid;
+       grid: none / 6fr 1fr 6fr;
+}
+
diff --git a/argo/static/media/sfx/banner_shout.wav b/argo/static/media/sfx/banner_shout.wav
new file mode 100644 (file)
index 0000000..4525408
Binary files /dev/null and b/argo/static/media/sfx/banner_shout.wav differ
diff --git a/argo/static/media/sfx/clock.wav b/argo/static/media/sfx/clock.wav
new file mode 100644 (file)
index 0000000..a760531
Binary files /dev/null and b/argo/static/media/sfx/clock.wav differ
diff --git a/argo/static/media/sfx/shout.wav b/argo/static/media/sfx/shout.wav
new file mode 100644 (file)
index 0000000..4a6849d
Binary files /dev/null and b/argo/static/media/sfx/shout.wav differ
diff --git a/argo/static/media/sfx/state_change.wav b/argo/static/media/sfx/state_change.wav
new file mode 100644 (file)
index 0000000..9a34860
Binary files /dev/null and b/argo/static/media/sfx/state_change.wav differ
diff --git a/argo/static/media/velo.jpg b/argo/static/media/velo.jpg
new file mode 100644 (file)
index 0000000..1394cb8
Binary files /dev/null and b/argo/static/media/velo.jpg differ
diff --git a/argo/static/style.css b/argo/static/style.css
new file mode 100644 (file)
index 0000000..3295c95
--- /dev/null
@@ -0,0 +1,5 @@
+:root {
+       font-size: var(--baseFontSize);
+       font-weight: 600;
+}
+.title { text-transform: capitalize; }
diff --git a/argo/static/style/banner_box.css b/argo/static/style/banner_box.css
new file mode 100644 (file)
index 0000000..83213b6
--- /dev/null
@@ -0,0 +1,20 @@
+body:not(.state-sold, .state-move) .styleBannerBox {
+       padding: 0; margin: 0;
+}
+.styleBannerBox {
+       opacity: 0; max-height: 0;
+       transform: translateX(-20px);
+       /* should do some tweeking for the below */
+       transition:
+       opacity var(--baseAnimationLength),
+       max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1),
+       padding var(--baseAnimationLength),
+       margin var(--baseAnimationLength),
+       transform var(--baseAnimationLength);
+       overflow: hidden;
+}
+body.state-sold .styleBannerBox,
+body.state-move .styleBannerBox {
+       opacity: 1; max-height: 50vh;
+       transform: translateX(0px);
+}
diff --git a/argo/static/style/box.css b/argo/static/style/box.css
new file mode 100644 (file)
index 0000000..35a7a24
--- /dev/null
@@ -0,0 +1,59 @@
+:root {
+       --boxHPad: 6px;
+       --boxVPad: 2px;
+       --boxHMar: 0px;
+       --boxVMar: 5px;
+}
+.boxA {
+       width: calc(100% - 2 * (var(--boxHMar) + var(--boxHPad) + var(--borderASize)));
+
+       color: var(--textAColor);
+       text-shadow: var(--textAShadow);
+
+       background: var(--backgroundA);
+       box-shadow: inset 0 0 var(--innerGlowSize) var(--innerGlowColor);
+       border: var(--borderASize) solid var(--borderAColor);
+
+       border-radius: var(--borderARadius);
+       padding: var(--boxVPad) var(--boxHPad) var(--boxVPad) var(--boxHPad);
+       margin: var(--boxVMar) var(--boxHMar) var(--boxVMar) var(--boxHMar);
+}
+.boxA.styleExpand.showUntil:not(.showUntil-showing) {
+       margin-bottom: calc(-2 * var(--borderASize));
+}
+
+.boxB {
+       width: calc(100% - 2 * (var(--boxHMar) + var(--boxHPad) + var(--borderBSize)));
+
+       color: var(--textBColor);
+       text-shadow: var(--textBShadow);
+
+       background: var(--backgroundB);
+       box-shadow: inset 0 0 var(--innerGlowSize) var(--innerGlowColor);
+       border: var(--borderBSize) solid var(--borderBColor);
+
+       border-radius: var(--borderBRadius);
+       padding: var(--boxVPad) var(--boxHPad) var(--boxVPad) var(--boxHPad);
+       margin: var(--boxVMar) var(--boxHMar) var(--boxVMar) var(--boxHMar);
+}
+.boxB.styleExpand.showUntil:not(.showUntil-showing) {
+       margin-bottom: calc(-2 * var(--borderBSize));
+}
+
+.boxC {
+       width: calc(100% - 2 * (var(--boxHMar) + var(--boxHPad) + var(--borderCSize)));
+
+       color: var(--textCColor);
+       text-shadow: var(--textCShadow);
+
+       background: var(--backgroundC);
+       box-shadow: inset 0 0 var(--innerGlowSize) var(--innerGlowColor);
+       border: var(--borderCSize) solid var(--borderCColor);
+
+       border-radius: var(--borderCRadius);
+       padding: var(--boxVPad) var(--boxHPad) var(--boxVPad) var(--boxHPad);
+       margin: var(--boxVMar) var(--boxHMar) var(--boxVMar) var(--boxHMar);
+}
+.boxC.styleExpand.showUntil:not(.showUntil-showing) {
+       margin: 0 0 calc(-2 * var(--borderCSize)) 0;
+}
diff --git a/argo/static/style/center_shout.css b/argo/static/style/center_shout.css
new file mode 100644 (file)
index 0000000..21b5949
--- /dev/null
@@ -0,0 +1,29 @@
+.styleCenterShout {
+       position: absolute;
+       top: 0; left: 0; bottom: 0; right: 0;
+
+       display: flex;
+       align-items: center; justify-content: center;
+
+       text-transform: uppercase;
+}
+.styleCenterShout > div { background-color: red; }
+
+.styleCenterShout.showUntil > div {
+       transform: translateX(-100px);
+       opacity: 0;
+       transition:
+               transform var(--baseAnimationLength),
+               opacity var(--baseAnimationLength);
+}
+.styleCenterShout.showUntil > div > span {
+       display: block;
+       transform: translateX(200px);
+       transition: transform var(--baseAnimationLength);
+
+       text-transform: uppercase;
+}
+.styleCenterShout.showUntil-showing * {
+       opacity: 1 !important;
+       transform: translateX(0px) !important;
+}
diff --git a/argo/static/style/discount_box.css b/argo/static/style/discount_box.css
new file mode 100644 (file)
index 0000000..2c84661
--- /dev/null
@@ -0,0 +1,30 @@
+.styleDiscountBox > em {
+       display: block;
+       font-size: 0.7em;
+       line-height: 1.4em;
+}
+.styleDiscountBox > div {
+       font-size: 1.2em;
+}
+
+body:not(.state-discount, .state-move) .styleDiscountBox {
+       padding: 0; margin: 0;
+}
+.styleDiscountBox {
+       opacity: 0; max-height: 0;
+       transform: translateX(-20px);
+       /* should do some tweeking for the below */
+       transition:
+       opacity var(--baseAnimationLength),
+       max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1),
+       padding var(--baseAnimationLength),
+       margin var(--baseAnimationLength),
+       transform var(--baseAnimationLength);
+       overflow: hidden;
+}
+body.state-discount .styleDiscountBox,
+body.state-move .styleDiscountBox {
+       opacity: 1; max-height: 50vh;
+       transform: translateX(0px);
+}
+
diff --git a/argo/static/style/item_box.css b/argo/static/style/item_box.css
new file mode 100644 (file)
index 0000000..f40ef48
--- /dev/null
@@ -0,0 +1,29 @@
+body:not(
+       .state-product,
+       .state-price,
+       .state-discount,
+       .state-move,
+       .state-sold
+) .styleItemBox {
+       padding: 0; margin: 0;
+}
+.styleItemBox {
+       opacity: 0; max-height: 0;
+       transform: translateX(-20px);
+       /* should do some tweeking for the below */
+       transition:
+       opacity var(--baseAnimationLength),
+       max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1),
+       padding var(--baseAnimationLength),
+       margin var(--baseAnimationLength),
+       transform var(--baseAnimationLength);
+       overflow: hidden;
+}
+body.state-product .styleItemBox,
+body.state-price .styleItemBox,
+body.state-discount .styleItemBox,
+body.state-move .styleItemBox,
+body.state-sold .styleItemBox {
+       opacity: 1; max-height: 50vh;
+       transform: translateX(0px);
+}
diff --git a/argo/static/style/logo_box.css b/argo/static/style/logo_box.css
new file mode 100644 (file)
index 0000000..c070292
--- /dev/null
@@ -0,0 +1,23 @@
+body:not(
+       .state-crawler,
+       .state-product
+) .styleLogoBox {
+       padding: 0; margin: 0;
+}
+.styleLogoBox {
+       opacity: 0; max-height: 0;
+       transform: translateX(-20px);
+       /* should do some tweeking for the below */
+       transition:
+       opacity var(--baseAnimationLength),
+       max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1),
+       padding var(--baseAnimationLength),
+       margin var(--baseAnimationLength),
+       transform var(--baseAnimationLength);
+       overflow: hidden;
+}
+body.state-product .styleLogoBox,
+body.state-crawler .styleLogoBox {
+       opacity: 1; max-height: 50vh;
+       transform: translateX(0px);
+}
diff --git a/argo/static/style/pricing_box.css b/argo/static/style/pricing_box.css
new file mode 100644 (file)
index 0000000..57d2fff
--- /dev/null
@@ -0,0 +1,21 @@
+body:not(.state-price, .state-discount, .state-move) .stylePricingBox {
+       padding: 0; margin: 0;
+}
+.stylePricingBox {
+       opacity: 0; max-height: 0;
+       transform: translateX(-20px);
+       /* should do some tweeking for the below */
+       transition:
+       opacity var(--baseAnimationLength),
+       max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1),
+       padding var(--baseAnimationLength),
+       margin var(--baseAnimationLength),
+       transform var(--baseAnimationLength);
+       overflow: hidden;
+}
+body.state-price .stylePricingBox,
+body.state-discount .stylePricingBox,
+body.state-move .stylePricingBox {
+       opacity: 1; max-height: 50vh;
+       transform: translateX(0px);
+}
diff --git a/argo/static/style/qty_box.css b/argo/static/style/qty_box.css
new file mode 100644 (file)
index 0000000..b774fa3
--- /dev/null
@@ -0,0 +1,24 @@
+.styleQtyBox {
+       font-size: 0.7em;
+}
+
+body:not(.state-sold, .state-move) .styleQtyBox {
+       padding: 0; margin: 0;
+}
+.styleQtyBox {
+       opacity: 0; max-height: 0;
+       transform: translateX(-20px);
+       /* should do some tweeking for the below */
+       transition:
+       opacity var(--baseAnimationLength),
+       max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1),
+       padding var(--baseAnimationLength),
+       margin var(--baseAnimationLength),
+       transform var(--baseAnimationLength);
+       overflow: hidden;
+}
+body.state-sold .styleQtyBox,
+body.state-move .styleQtyBox {
+       opacity: 1; max-height: 50vh;
+       transform: translateX(0px);
+}
diff --git a/argo/static/style/show_until.css b/argo/static/style/show_until.css
new file mode 100644 (file)
index 0000000..451952f
--- /dev/null
@@ -0,0 +1,19 @@
+.styleExpand.showUntil:not(.showUntil-showing) {
+       padding: 0; margin: 0;
+}
+.styleExpand.showUntil {
+       opacity: 0; max-height: 0;
+       transform: translateX(-20px);
+       /* should do some tweeking for the below */
+       transition:
+               opacity var(--baseAnimationLength),
+               max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1),
+               padding var(--baseAnimationLength),
+               margin var(--baseAnimationLength),
+               transform var(--baseAnimationLength);
+       overflow: hidden;
+}
+.styleExpand.showUntil.showUntil-showing {
+       opacity: 1; max-height: 50vh;
+       transform: translateX(0px);
+}
diff --git a/argo/static/style/side_box.css b/argo/static/style/side_box.css
new file mode 100644 (file)
index 0000000..066842e
--- /dev/null
@@ -0,0 +1,12 @@
+.styleSideBox {
+       width: var(--sideBoxWidth);
+
+       display: flex;
+       flex-direction: column;
+
+       margin: 50px;
+}
+.styleSideBox > * {
+       margin-bottom: 5px;
+       width: 100%;
+}
diff --git a/argo/static/style/side_timer_box.css b/argo/static/style/side_timer_box.css
new file mode 100644 (file)
index 0000000..dfd48d4
--- /dev/null
@@ -0,0 +1,4 @@
+.styleSideTimerBox {
+       display: inline;
+       width: fit-content !important;
+}
diff --git a/argo/templates/admin.html b/argo/templates/admin.html
new file mode 100644 (file)
index 0000000..5a5bc22
--- /dev/null
@@ -0,0 +1,55 @@
+{#
+
+       builds the admin page
+
+#}
+<!DOCTYPE html>
+<html>
+       <head>
+               <title>&delta; Velorum</title>
+               <link rel="stylesheet" href="/static/admin.css">
+
+               <script type="module" defer>
+
+import { setupTrigger } from "/script/admin.js";
+setupTrigger();
+
+               </script>
+       </head>
+       <body>
+               <nav>
+                       <p><b>Tables</b></p>
+                       <ul style="border: 1px solid gray">
+                               {% for table in indexes %}
+                                       {% set table_name = table.split("--")[1] %}
+                                       <li><a href="/admin/{{ table_name }}">{{ table_name }}</a></li>
+                               {% endfor %}
+                       </ul>
+               </nav>
+               <main>
+                       <h1><i>&delta; Velorum {{ star }}</i> &ldquo;Alsephina&rdquo; <em>
+                               {{ {"Aa": "The Ship", "Ab": "The Liferaft", "B": "Unknown"}[star] }}
+                       </em></h1>
+
+                       <form method="GET" action="/db">
+                               <button type="submit">Donwload database</button>
+                       </form>
+                       <form method="POST" action="/db">
+                               <input type="file"/>
+                               <button type="submit">Upload database</button>
+                       </form>
+
+                       <ul>
+                               <li><a href="/">Main GFX overlay</a></li>
+                               <li><a href="/info/a">Info page A</a> <em>(Item name, description, Anchor notes)</em></li>
+                               <li><a href="/info/b">Info page B</a> <em>(Price, discount and stock)</em></li>
+                               <li><a href="/info/c">Info page C</a> <em>(Gallery screen, timing and state)</em></li>
+                       </ul>
+
+                               <img
+                                       src="/static/media/velo.jpg"
+                                       attributionsrc="https://commons.wikimedia.org/w/index.php?curid=4075468"
+                                       style="width: min(100%, 700px);" />
+               </main>
+       </body>
+</html>
diff --git a/argo/templates/admin/color.html b/argo/templates/admin/color.html
new file mode 100644 (file)
index 0000000..1ecd886
--- /dev/null
@@ -0,0 +1,6 @@
+<label>{{ label }}</label>
+<span>
+       <input id="{{ name }}" type="color" name="{{ name }}" value="{{ value }}" />
+       {{ value }}
+</span>
+<span class="currentValue" style="background-color: {{ value }};"></span>
diff --git a/argo/templates/admin/float.html b/argo/templates/admin/float.html
new file mode 100644 (file)
index 0000000..12f8b00
--- /dev/null
@@ -0,0 +1,3 @@
+<label>{{ label }}</label>
+<input id="{{ name }}" type="number" name="{{ name }}" value="{{ value }}" step="0.01" />
+<span class="currentValue">{{ value }}</span>
diff --git a/argo/templates/admin/number.html b/argo/templates/admin/number.html
new file mode 100644 (file)
index 0000000..7ffe0c7
--- /dev/null
@@ -0,0 +1,3 @@
+<label>{{ label }}</label>
+<input id="{{ name }}" type="number" name="{{ name }}" value="{{ value }}" />
+<span class="currentValue">{{ value }}</span>
diff --git a/argo/templates/admin/text.html b/argo/templates/admin/text.html
new file mode 100644 (file)
index 0000000..3878cc8
--- /dev/null
@@ -0,0 +1,4 @@
+<label>{{ label }}</label>
+<input id="{{ name }}" type="text" name="{{ name }}" value="{{ value }}" />
+<span class="currentValue">{{ value }}</span>
+
diff --git a/argo/templates/admin/textarea.html b/argo/templates/admin/textarea.html
new file mode 100644 (file)
index 0000000..a9ce85b
--- /dev/null
@@ -0,0 +1,4 @@
+<label>{{ label }}</label>
+<textarea id="{{ name }}" style="grid-column: 3 / span 2;" name="{{ name }}">
+       {{- value -}}
+</textarea>
diff --git a/argo/templates/admin/trigger.html b/argo/templates/admin/trigger.html
new file mode 100644 (file)
index 0000000..322450d
--- /dev/null
@@ -0,0 +1,7 @@
+<span id="{{ name }}" style="grid-column: 2 / span 3;">
+       <noscript style="color: red;">Trigger will not function without JS<br></noscript>
+       <button type="button" name="{{ name }}" value="{{ label }}" class="trigger">
+               {{ label }}
+       </button>
+       <input type="number" id="{{ name }}+delay" value="{{ value.split('+')[1] }}"/><span> seconds delay <em>(This does not update the triggered data.)</em></span>
+</span>
diff --git a/argo/templates/index.html b/argo/templates/index.html
new file mode 100644 (file)
index 0000000..af8760e
--- /dev/null
@@ -0,0 +1,155 @@
+<!doctype html>
+<html>
+       <head>
+               <link rel="stylesheet" href="/static/style.css">
+               <link rel="stylesheet" href="/static/andika.css">
+
+               {# ELEMENT STYLING IMPORTS #}
+               <link rel="stylesheet" href="/static/style/side_box.css">
+               <link rel="stylesheet" href="/static/style/qty_box.css">
+               <link rel="stylesheet" href="/static/style/side_timer_box.css">
+               <link rel="stylesheet" href="/static/style/center_shout.css">
+               <link rel="stylesheet" href="/static/style/discount_box.css">
+               <link rel="stylesheet" href="/static/style/banner_box.css">
+               <link rel="stylesheet" href="/static/style/pricing_box.css">
+               <link rel="stylesheet" href="/static/style/item_box.css">
+               <link rel="stylesheet" href="/static/style/logo_box.css">
+
+               {# HELPER IMPORTS #}
+               <link rel="stylesheet" href="/static/style/box.css">
+               <link rel="stylesheet" href="/static/style/show_until.css">
+               <link rel="stylesheet" href="/static/style/background.css">
+
+               <script type="importmap">
+               {
+                       "imports": {
+                       "socket.io-client": "https://cdn.socket.io/4.8.3/socket.io.esm.min.js"
+                       }
+               }
+               </script>
+               <script type="module" defer>
+
+import setupUpdate from "/script/update.js";
+setupUpdate();
+
+               </script>
+       </head>
+       <body class="update data__state~~text--state state">
+
+               {# GLOBAL STYLING ELEMENTS #}
+               <span class="update style~~text--baseAnimationLength style"></span>
+               <span class="update style~~text--sideBoxWidth style"></span>
+               <span class="update style~~text--baseFontSize style"></span>
+
+               {# DYNAMIC STYLING ELEMENTS #}
+
+               <span class="update style__colorscheme~~text--borderASize style"></span>
+               <span class="update style__colorscheme~~color--borderAColor style"></span>
+               <span class="update style__colorscheme~~text--borderBSize style"></span>
+               <span class="update style__colorscheme~~color--borderBColor style"></span>
+               <span class="update style__colorscheme~~text--borderCSize style"></span>
+               <span class="update style__colorscheme~~color--borderCColor style"></span>
+
+               <span class="update style__colorscheme~~color--textAColor style"></span>
+               <span class="update style__colorscheme~~color--textBColor style"></span>
+               <span class="update style__colorscheme~~color--textCColor style"></span>
+               <span class="update style__colorscheme~~text--textAShadow style"></span>
+               <span class="update style__colorscheme~~text--textBShadow style"></span>
+               <span class="update style__colorscheme~~text--textCShadow style"></span>
+
+               <span class="update style__colorscheme~~text--borderARadius style"></span>
+               <span class="update style__colorscheme~~text--borderBRadius style"></span>
+               <span class="update style__colorscheme~~text--borderCRadius style"></span>
+
+               <span class="update style__colorscheme__backgroundA~~text--backgroundA style"></span>
+               <span class="update style__colorscheme__backgroundB~~text--backgroundB style"></span>
+               <span class="update style__colorscheme__backgroundC~~text--backgroundC style"></span>
+
+               <span class="update style__colorscheme~~color--innerGlowColor style"></span>
+               <span class="update style__colorscheme~~text--innerGlowSize style"></span>
+
+               {# SFX ELEMENTS #}
+               <audio src="/static/media/sfx/banner_shout.wav" class="update data~~trigger--bannerShoutTrigger sound"></audio>
+               <audio src="/static/media/sfx/clock.wav" class="update data__clock~~number--positionDegrees sound"></audio>
+               <audio src="/static/media/sfx/state_change.wav" class="update data__state~~text--state sound"></audio>
+               <audio src="/static/media/sfx/shout.wav" class="update data~~trigger--centerShoutTrigger sound"></audio>
+
+               {# CENTER SHOUT #}
+               <div class="styleCenterShout update data~~trigger--centerShoutTrigger showUntil">
+                       <div>
+                               <span class="update data~~text--centerShoutText text"></span>
+                       </div>
+               </div>
+
+               {# SIDE BOX
+                               includes (top to bottom):
+                               - LOGO BOX (show during: crawler, product)
+                               - BANNER BOX (show during: move, sold)
+                               - ITEM BOX (show during: product, price, discount, move, sold)
+                               - PRICING BOX (show during: price, discount, move)
+                               - DISCOUNT BOX (show during: discount, move)
+                               - BANNER SHOUT BOX (show AD)
+                               - QTY BOX (show during: move, sold)
+                               - TIMER 1 BOX (show AD)
+                               - TIMER 2 BOX (show AD)
+
+                               these are switched on and off using the state class from the
+                               body tag.
+               #}
+               <div class="styleSideBox">
+
+                       {# LOGO BOX #}
+                       <div class="styleLogoBox">
+                               LOGO BOX
+                       </div>
+
+                       {# BANNER BOX #}
+                       <div class="styleBannerBox boxC">
+                               BANNER BOX
+                       </div>
+
+                       {# ITEM BOX #}
+                       <div class="styleItemBox boxB">
+                               <div class="boxA">
+                                       ITEM BOX
+                               </div>
+                       </div>
+
+                       {# PRICING BOX #}
+                       <div class="stylePricingBox boxA">
+                               PRICING BOX
+                       </div>
+
+                       {# DISOUNT BOX #}
+                       <div class="styleDiscountBox boxB">
+                               <em>Now only...</em>
+                               <div class="boxA">
+                                       <b><span class="update data__product~~number--discount discount"></span></b>
+                                       OFF!
+                               </div>
+                       </div>
+
+                       {# BANNER SHOUT BOX #}
+                       <div class="styleExpand boxC update data~~trigger--bannerShoutTrigger showUntil">
+                               <span class="update data~~text--bannerShoutText title"></span>
+                       </div>
+
+                       {# QTY BOX #}
+                       <div class="styleQtyBox boxB">
+                               <em>Sold:
+                               <span class="update data__product~~number--quantityTotal text"></span>...</em>
+                               only
+                               <span class="update data__product~~number--quantityCurrent text"></span>
+                               LEFT
+                       </div>
+
+                       {# TIMER BOX #}
+                       <div class="styleSideTimerBox boxA">
+                               TIMER 1!
+                       </div>
+                       <div class="styleSideTimerBox boxA">
+                               TIMER 2!
+                       </div>
+               </div>
+       </body>
+</html>
diff --git a/argo/templates/info/a.html b/argo/templates/info/a.html
new file mode 100644 (file)
index 0000000..fa6e8cc
--- /dev/null
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+       <head>
+               <link rel="stylesheet" href="/static/info.css">
+               <script type="importmap">
+               {
+                       "imports": {
+                       "socket.io-client": "https://cdn.socket.io/4.8.3/socket.io.esm.min.js"
+                       }
+               }
+               </script>
+               <script type="module" defer>
+
+import setupUpdate from "/script/update.js";
+setupUpdate();
+
+               </script>
+       </head>
+       <body class="infoA">
+               <span class="update style~~text--aFontSize style"></span>
+
+               <div>
+                       <span>
+                               <u style="color: pink;"><span class="update data__product~~text--name text"></span></u><br>
+                               <span style="color: pink" class="update data__product~~text--description text"></span>
+                       </span>
+
+                       <span class="styleProductNotes update data__product~~textarea--notes text"></span>
+
+                       <span style="color: yellow" class="update data~~textarea--anchorNotes text"></span>
+               </div>
+       </body>
+</html>
diff --git a/argo/templates/info/b.html b/argo/templates/info/b.html
new file mode 100644 (file)
index 0000000..c06b48e
--- /dev/null
@@ -0,0 +1,51 @@
+<!doctype html>
+<html>
+       <head>
+               <link rel="stylesheet" href="/static/info.css">
+               <script type="importmap">
+               {
+                       "imports": {
+                       "socket.io-client": "https://cdn.socket.io/4.8.3/socket.io.esm.min.js"
+                       }
+               }
+               </script>
+               <script type="module" defer>
+
+import setupUpdate from "/script/update.js";
+setupUpdate();
+
+               </script>
+       </head>
+       <body class="infoB">
+               <span class="update style~~text--bFontSize style"></span>
+
+               <div>
+                       <span>
+                               <span style="background-color: green" class="update data__product__currentPriceString~~text--currentPriceString text"></span> <em>(was <span class="update data__product__originalPriceString~~text--originalPriceString text"></span>)</em>
+                       </span>
+
+                       <span>
+                               <span class="update data__product~~number--quantityCurrent text"></span>
+                               left of
+                               <span class="update data__product~~number--quantityTotal text"></span>
+                               total
+                       </span>
+
+                       <span>
+                               <span style="background-color: purple;" class="update data__product~~number--discount discount"></span> off
+                       </span>
+
+                       <span>
+                               <span style="background-color: purple;" class="update data__product~~number--discount reverseDiscount"></span> full price
+                       </span>
+
+                       <span style="grid-column: 1 / span 2;">
+                               Target: <span style="background-color: orange;" class="update data__product~~number--targetDiscount discount"></span> (<span class="update data__product__remainingDiscount~~number--remainingDiscount discount"></span> left to drop)
+                       </span>
+
+                       <span style="grid-column: 1 / span 2;">
+                               Max: <span style="background-color: red;" class="update data__product~~number--maximumDiscount discount"></span> (<span class="update data__product__remainingMaximumDiscount~~number--remainingMaximumDiscount discount"></span> left to drop)
+                       </span>
+               </div>
+       </body>
+</html>
diff --git a/argo/templates/info/c.html b/argo/templates/info/c.html
new file mode 100644 (file)
index 0000000..b35ba79
--- /dev/null
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+       <head>
+               <link rel="stylesheet" href="/static/info.css">
+               <script type="importmap">
+               {
+                       "imports": {
+                       "socket.io-client": "https://cdn.socket.io/4.8.3/socket.io.esm.min.js"
+                       }
+               }
+               </script>
+               <script type="module" defer>
+
+import setupUpdate from "/script/update.js";
+setupUpdate();
+
+               </script>
+       </head>
+       <body class="infoC">
+               <span class="update style~~text--cFontSize style"></span>
+
+               <div>
+                       <span>Current product:<br><span style="background-color: blue;" class="update data__product~~text--name text"></span></span>
+                       <span>&rarr;</span>
+                       <span>Next product:<br><span style="background-color: blue;" class="update data__product__next~~text--name text"></span></span>
+
+                       <span>Current state: <span class="update data__state~~text--state title"></span></span>
+                       <span>&rarr;</span>
+                       <span>Next state: <span class="update data__state~~text--nextState title"></span></span>
+
+                       <span style="grid-column: 1 / span 3; font-size: 2em; font-size: 2em;">
+                               <span class="update data~~trigger--startTrigger since"></span> <span style="background-color: red;">T-<span class="update data__endTime~~text--endTime until"></span></span>
+                       </span>
+               </div>
+       </body>
+</html>
diff --git a/argo/templates/table.html b/argo/templates/table.html
new file mode 100644 (file)
index 0000000..98dd490
--- /dev/null
@@ -0,0 +1,99 @@
+{#
+
+       builds the admin page
+
+#}
+<!DOCTYPE html>
+<html>
+       <head>
+               <title>&delta; Velorum</title>
+               <link rel="stylesheet" href="/static/admin.css">
+
+               <script type="module" defer>
+
+import { setupTrigger } from "/script/admin.js";
+setupTrigger();
+
+               </script>
+       </head>
+       <body>
+               <nav>
+                       <p><a href="/admin">.. back</a></p>
+                       <p><b>{{ table_name }}</b></p>
+                       <ol>
+                       {% for row in table %}
+                               <li style="border: 1px solid gray; margin-top: -1px;"><ul>
+                                       {% set group = loop.index0 %}
+                                       {% for key in row %}
+                                               <li><a href="#{{ table_name ~ "~~" ~ group ~ "~~" ~ key }}">{{ key }}</a></li>
+                                       {% endfor %}
+                               </ul></li>
+                       {% endfor %}
+                       </ol>
+               </nav>
+               <main>
+                       <h1><i>&delta; Velorum {{ star }}</i> Table: {{ table_name }}</h1>
+                       <form class="optionsGrid" method="post">
+                               <input type="submit" value="Submit table" style="grid-column: 1 / span 4;">
+                               <span class="optionsGridSpacer" style="grid-column: 1 / span 4;"></span>
+                               {% for row in table %}
+
+                                       {# CREATE RADIO BUTTON FOR ROW #}
+
+                                               <span style="
+                                                       grid-row: {{ ((row|length + 1) * loop.index0) + 3 }} / span {{ row|length }};
+                                                       display: flex;
+                                                       justify-content: center;
+                                                       align-items: center;
+                                                       ">
+                                                       {% if loop.index0 == indexes["int--" ~ table_name] %}
+                                                               <input type="radio" name="{{ "indexes~~0~~int--" ~ table_name }}" value="{{ loop.index0 }}" checked="checked" class="currentValue">
+                                                       {% else %}
+                                                               <input type="radio" name="{{ "indexes~~0~~int--" ~ table_name }}" value="{{ loop.index0 }}" >
+                                                       {% endif %}
+                                               </span>
+
+                                       {# CREATE FEILDS #}
+
+                                       {% set group = loop.index0 %}
+                                       {% for feild in row %}
+
+                                               {# SELECT ELEMENT FROM TYPE #}
+
+                                               {% set type, label = feild.split('--') %}
+                                               {% set value = row[feild] %}
+                                               {% set name = table_name ~ "~~" ~ group ~ "~~" ~ feild %}
+
+                                               {% if type == "textarea" %}
+                                                       {% include "admin/textarea.html" %}
+                                               {% elif type == "text" %}
+                                                       {% include "admin/text.html" %}
+                                               {% elif type == "number" %}
+                                                       {% include "admin/number.html" %}
+                                               {% elif type == "float" %}
+                                                       {% include "admin/float.html" %}
+                                               {% elif type == "trigger" %}
+                                                       {% include "admin/trigger.html" %}
+                                               {% elif type == "color" %}
+                                                       {% include "admin/color.html" %}
+                                               {% endif %}
+                                       {% endfor %}
+                                       <span class="optionsGridSpacer" style="grid-column: 1 / span 4;"></span>
+
+                               {% endfor %}
+                               <input type="submit" value="Submit table" style="grid-column: 1 / span 4;">
+                       </form>
+
+                       <code>
+                               Note: Tables are rendered statically, it is not safe to opperate the same interface in two places at once.
+                               <br>
+                               Processed {{ table|length * table[0]|length }} feilds in
+                               {% if (time_taken * 1000)|round(2) > 20 %}
+                                       <span style="color: red;">{{ (time_taken * 1000)|round(2) }}ms</span>
+                               {% else %}
+                                       {{ (time_taken * 1000)|round(2) }}ms
+                               {% endif %}
+                       </code>
+               </main>
+       </body>
+</html>
diff --git a/argo/utils.py b/argo/utils.py
new file mode 100644 (file)
index 0000000..d2fc032
--- /dev/null
@@ -0,0 +1,10 @@
+def deindex(data, indexes):
+       deindexed = {}
+       for key in data:
+               table, index, feild = key.split("~~")
+               if table != "indexes" and int(index) == indexes[f"int--{table}"]:
+                       deindexed.update({
+                               f"{table}~~{feild}": data[key]
+                               })
+
+       return deindexed
diff --git a/director/__init__.py b/director/__init__.py
deleted file mode 100644 (file)
index 706cd5e..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-from werkzeug.security import generate_password_hash, check_password_hash
-from flask import Flask, render_template, send_from_directory, request
-from flask_socketio import SocketIO, emit
-from flask_httpauth import HTTPBasicAuth
-from flask_cors import CORS
-import json
-import os
-
-from .utils import deindex
-
-import director.admin as admin
-
-from director.database.read import read_views as database_read_views
-
-app = Flask(__name__, instance_relative_config=False)
-socketio = SocketIO(app, logger=False, engineio_logger=False)
-auth = HTTPBasicAuth()
-CORS(app)
-
-# import authentication data
-
-with open(f"{app.root_path}/../../secrets.json", "r", encoding="utf-8") as f:
-       users = json.loads(f.read())
-users = {k: generate_password_hash(v) for (k, v) in users.items()}
-
-# password verifier
-
-def verify_password(username, password):
-    if username in users and check_password_hash(users.get(username), password):
-        return username
-
-auth.verify_password(verify_password)
-
-# root movements
-
-@app.route("/", methods=['get'])
-def index():
-       return render_template("index.html")
-
-@socketio.on('connect')
-def connecting():
-       emit("update", database_read_views(), json=True, namespace="/", broadcast=True)
-
-# info screen pages
-
-@app.route("/info/<string:screen>", methods=["get"])
-def info(screen):
-       return render_template(f"info/{screen}.html")
-
-# admin screen pages
-
-app.route("/admin", methods=["get"])(auth.login_required(admin.admin_main))
-app.route("/admin/<string:table_name>", methods=["get", "post"])(auth.login_required(admin.admin_table))
-
-# script pages
-
-@app.route("/script/<path:filename>", methods=["get"])
-def script(filename):
-       return send_from_directory(os.path.join(app.root_path, "build"), filename)
-
-@app.route("/db", methods=["get"])
-@auth.login_required
-def download_db():
-       return send_from_directory(f"{app.root_path}/../data", "main.db")
diff --git a/director/admin.py b/director/admin.py
deleted file mode 100644 (file)
index 400f09d..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-from flask import render_template, request
-from flask_socketio import emit
-import time
-
-from director.database.read import read_indexes as database_read_indexes
-from director.database.read import read_views as database_read_views
-from director.database.write import write as database_write
-from director.database.read import read as database_read
-
-def admin_main():
-       return render_template("admin.html", indexes=database_read_indexes())
-
-def admin_table(table_name):
-       start = time.time()
-
-       if request.method == "POST":
-               database_write(request.form)
-
-               emit(
-                       "update",
-                       database_read_views(table_name),
-                       json=True, namespace="/", broadcast=True
-                       )
-
-       end = time.time()
-
-       return render_template(
-               "table.html",
-               indexes=database_read_indexes(),
-               table=database_read(table_name),
-               table_name=table_name,
-               time_taken = end - start
-               )
diff --git a/director/database/__init__.py b/director/database/__init__.py
deleted file mode 100644 (file)
index e408c87..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-"""
-       package to read and write to the database
-
-       check if file exists and pragam check the database on init
-"""
-
-from .utils import integrity_check, optimize
-import sqlite3
-import os
-
-assert os.path.exists("./data/main.db"), "Database missing"
-assert integrity_check(), "Database integrity error"
-
-optimize()
diff --git a/director/database/read.py b/director/database/read.py
deleted file mode 100644 (file)
index b180b39..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-import sqlite3
-
-from .utils import list_all, list_views
-
-def read_all_current():
-       tables = list_all()
-       indexes = read_indexes()
-
-       with sqlite3.connect("./data/main.db") as connection:
-               cursor = connection.cursor()
-
-               data = {}
-               for table in tables:
-                       if table == "indexes": continue
-
-                       if "__view" in table:
-                               index_table = table.split("__view")[0]
-                       else: index_table = table
-
-                       cursor.execute(f"SELECT * FROM {table};")
-
-                       names = list(map(lambda x: f"{table}~~{x[0]}", cursor.description))
-                       row = cursor.fetchall()[indexes[f"int--{index_table}"]]
-
-                       data.update(dict(zip(names, row)))
-
-               return data
-
-def read(table):
-       """
-               reads a table by name
-       """
-       with sqlite3.connect("./data/main.db") as connection:
-               cursor = connection.cursor()
-
-               cursor.execute(f"SELECT * FROM {table};")
-
-               names = list(map(lambda x: x[0], cursor.description))
-               rows = [dict(zip(names, row)) for row in cursor.fetchall()]
-
-       return rows
-
-def read_views(table=None):
-       """
-               Reads views. If a table is specified, it reads all views related to that
-               table. If not it reads all views.
-       """
-       if table is None:
-               related = list_views()
-       else:
-               related = [view for view in list_views() if view.split("__view")[0] == table]
-
-       data = {}
-       for view in related:
-               for key, value in read(view)[0].items():
-                       data.update({f"{view.replace('__view', '')}~~{key}": value})
-
-       return data
-
-def read_indexes():
-       with sqlite3.connect("./data/main.db") as connection:
-               cursor = connection.cursor()
-
-               cursor.execute("SELECT * FROM indexes;")
-
-               names = list(map(lambda x: x[0], cursor.description))
-               indexes = [dict(zip(names, row)) for row in cursor.fetchall()][0]
-
-               return indexes
diff --git a/director/database/utils.py b/director/database/utils.py
deleted file mode 100644 (file)
index 6866761..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-import sqlite3
-
-def integrity_check():
-       """
-               check the database is ok and return true if it is
-       """
-       with sqlite3.connect("./data/main.db") as connection:
-               cursor = connection.cursor()
-               integrity = cursor.execute('PRAGMA integrity_check')
-
-               return integrity.fetchone()[0] == "ok"
-
-def optimize():
-       """
-               check the database is ok and return true if it is
-       """
-       with sqlite3.connect("./data/main.db") as connection:
-               cursor = connection.cursor()
-               integrity = cursor.execute('PRAGMA optimize')
-
-def list_all():
-       """
-               get a list of all the tables and views in the database
-       """
-       with sqlite3.connect("./data/main.db") as connection:
-               cursor = connection.cursor()
-               cursor.execute("SELECT name FROM sqlite_master WHERE type IN ('table', 'view');")
-               return [table[0] for table in cursor.fetchall()]
-
-def list_views():
-       """
-               get a list of all the views in the database
-       """
-       with sqlite3.connect("./data/main.db") as connection:
-               cursor = connection.cursor()
-               cursor.execute("SELECT name FROM sqlite_master WHERE type='view';")
-               return [table[0] for table in cursor.fetchall()]
diff --git a/director/database/write.py b/director/database/write.py
deleted file mode 100644 (file)
index eea0126..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-import sqlite3
-
-from .utils import list_all
-from .read import read
-
-def write(data):
-
-       with sqlite3.connect("./data/main.db") as connection:
-               cursor = connection.cursor()
-
-               for key in data:
-                       table, index, feild = key.split("~~")
-
-                       cursor.execute(f"""
-                               UPDATE {table}
-                               SET '{feild}' = '{data[key]}'
-                               WHERE ROWID = {int(index) + 1};
-                               """)
-
-                       connection.commit()
diff --git a/director/src/admin.ts b/director/src/admin.ts
deleted file mode 100644 (file)
index 22e72e3..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-const outlineStyle: string = "4px solid green";
-const outlineTime: number = 500; // ms
-
-export function setupTrigger() {
-       // setup all trigger buttons to send post request on click
-       const el: HTMLCollectionOf<Element> =
-               document.getElementsByClassName("trigger");
-
-       for (let e of el) {
-               e.addEventListener("click", (event) => {
-                       if (event.target instanceof HTMLElement) {
-                               let time: number = Math.round(Date.now() / 1000);
-                               let body: FormData = new FormData();
-                               let delay = document.getElementById(`${event.target.getAttribute('name')}+delay`);
-
-                               if (delay instanceof HTMLInputElement) {
-                                       body.set(`${event.target.getAttribute('name')}`, `${time}+${delay.value}`);
-
-                                       fetch("", {
-                                               method: "POST",
-                                               body: body
-                                       });
-
-                                       // trigger the button to turn green for approx same time (or 1s)
-                                       let timeout: number = delay.value as unknown as number * 1000;
-                                       if (timeout < outlineTime) { timeout = outlineTime; }
-
-                                       if ( event.target instanceof HTMLElement) {
-                                               event.target.style.outline = outlineStyle;
-                                               setTimeout(function () {
-                                                       if ( event.target instanceof HTMLElement) {
-                                                               event.target.style.outline = "none"
-                                                       }
-                                               }, timeout);
-                                       }
-                               }
-                       }
-               })
-       }
-}
diff --git a/director/src/discount.ts b/director/src/discount.ts
deleted file mode 100644 (file)
index d05bd20..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-export function renderDiscount(): void {
-       const el: HTMLCollectionOf<Element> =
-               document.getElementsByClassName("discount");
-
-       for (let e of el) {
-               if (e instanceof HTMLElement) {
-                       if (typeof e.dataset.raw === "string") {
-                               e.innerHTML = `${e.dataset.raw}%`;
-                       }
-               }
-       }
-}
-
-export function renderReverseDiscount(): void {
-       const el: HTMLCollectionOf<Element> =
-       document.getElementsByClassName("reverseDiscount");
-
-       for (let e of el) {
-               if (e instanceof HTMLElement) {
-                       if (typeof e.dataset.raw === "string") {
-                               e.innerHTML = `${100 - Number(e.dataset.raw)}%`;
-                       }
-               }
-       }
-}
diff --git a/director/src/price.ts b/director/src/price.ts
deleted file mode 100644 (file)
index 0d926c5..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-export default function renderPrice(): void {
-       const el: HTMLCollectionOf<Element> =
-               document.getElementsByClassName("price");
-
-       for (let e of el) {
-               if (e instanceof HTMLElement) {
-                       if (typeof e.dataset.raw === "string") {
-                               e.innerHTML = String(parseFloat(e.dataset.raw).toFixed(2));
-                       }
-               }
-       }
-}
diff --git a/director/src/show_until.ts b/director/src/show_until.ts
deleted file mode 100644 (file)
index 6658b09..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-export default function renderShowUntil(): void {
-       const el: HTMLCollectionOf<Element> =
-               document.getElementsByClassName("showUntil");
-
-       for (let e of el) {
-               if (e instanceof HTMLElement) {
-                       if (typeof e.dataset.raw === "string") {
-                               let duration: number = (eval(e.dataset.raw) * 1000) - Date.now();
-                               if (duration > 0) {
-                                       e.classList.add("showUntil-showing")
-                                       setTimeout(function () {e.classList.remove("showUntil-showing")}, duration)
-                               }
-                       }
-               }
-       }
-}
diff --git a/director/src/sound.ts b/director/src/sound.ts
deleted file mode 100644 (file)
index b387907..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-export function setupSounds() {
-       const el: HTMLCollectionOf<Element> =
-               document.getElementsByClassName("sound");
-
-       const context = new AudioContext();
-       if (el.length > 0) {
-               for (let e of el) {
-                       if (e instanceof HTMLMediaElement) {
-                               const track = context.createMediaElementSource(e);
-                               track.connect(context.destination);
-                       }
-               }
-       }
-}
-
-export function playSounds() {
-       const el: HTMLCollectionOf<Element> =
-               document.getElementsByClassName("sound");
-
-       for (let e of el) {
-               if (e instanceof HTMLMediaElement) {
-                       if (typeof e.dataset.raw === "string") {
-                               if (e.dataset.rawLast != e.dataset.raw) {
-                                       e.play();
-                               }
-                               e.dataset.rawLast = e.dataset.raw;
-                       }
-               }
-       }
-}
diff --git a/director/src/state.ts b/director/src/state.ts
deleted file mode 100644 (file)
index d206f25..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-export default function renderState(): void {
-       const el: HTMLCollectionOf<Element> =
-               document.getElementsByClassName("state");
-
-       for (let e of el) {
-               if (e instanceof HTMLElement) {
-                       if (typeof e.dataset.raw === "string") {
-                               for (let className of e.classList) {
-                                       if (className.startsWith("state-")) {
-                                               e.classList.remove(className);
-                                       }
-                               }
-
-                               e.classList.add(`state-${e.dataset.raw}`);
-                       }
-               }
-       }
-}
diff --git a/director/src/style.ts b/director/src/style.ts
deleted file mode 100644 (file)
index 380559e..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-export function setupStyle(): void {
-       const el: HTMLCollectionOf<Element> =
-               document.getElementsByClassName("style");
-
-       for (let i = 0; i < el.length; i++) {
-               const stylesheet = new CSSStyleSheet();
-               document.adoptedStyleSheets.push(stylesheet);
-       }
-}
-
-export function renderStyle(): void {
-       const el: HTMLCollectionOf<Element> =
-               document.getElementsByClassName("style");
-
-       for (let [i, e] of Array.from(el).entries()) {
-               if (e instanceof HTMLElement) {
-                       let variable;
-                       for (let className of e.classList) {
-                               if (className.includes("--")) {
-                                       variable = className.split("--")[1];
-                               }
-                       }
-
-                       if (typeof e.dataset.raw === "string") {
-                               document.adoptedStyleSheets[i].replace(`
-                               :root {--${variable}: ${e.dataset.raw};}
-                               `);
-                       }
-               }
-       }
-}
diff --git a/director/src/text.ts b/director/src/text.ts
deleted file mode 100644 (file)
index 7695065..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-export default function renderText(): void {
-       const el = document.querySelectorAll(".text,.title");
-       for (let e of el) {
-               if (e instanceof HTMLElement) {
-                       if (typeof e.dataset.raw === "string") {
-                               e.innerHTML = e.dataset.raw;
-                       }
-               }
-       }
-}
diff --git a/director/src/time.ts b/director/src/time.ts
deleted file mode 100644 (file)
index 84b69f3..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-import { timeSince, timeUntil, timeFormatBroadcast } from "./utils.js";
-
-const timeUpdate: number = 1000; // ms
-
-export function setupTimeSince(): void {
-       const el: HTMLCollectionOf<Element> =
-               document.getElementsByClassName("since");
-
-       if (el.length > 0) {
-               setInterval(
-                       function () {
-                               const el: HTMLCollectionOf<Element> =
-                                       document.getElementsByClassName("since");
-
-                               for (let e of el) {
-                                       if (e instanceof HTMLElement) {
-                                               if (typeof e.dataset.raw === "string") {
-                                                       let [hours, minutes, seconds] = timeSince(eval(e.dataset.raw))
-                                                       e.innerHTML = timeFormatBroadcast(hours, minutes, seconds);
-                                               }
-                                       }
-                               }
-                       },
-                       timeUpdate
-               );
-       }
-}
-
-export function setupTimeUntil(): void {
-       const el: HTMLCollectionOf<Element> =
-       document.getElementsByClassName("until");
-
-       if (el.length > 0) {
-               setInterval(
-                       function () {
-                               const el: HTMLCollectionOf<Element> =
-                               document.getElementsByClassName("until");
-
-                               for (let e of el) {
-                                       if (e instanceof HTMLElement) {
-                                               if (typeof e.dataset.raw === "string") {
-                                                       let [hours, minutes, seconds] = timeUntil(eval(e.dataset.raw))
-                                                       e.innerHTML = timeFormatBroadcast(hours, minutes, seconds);
-                                               }
-                                       }
-                               }
-                       },
-                       timeUpdate
-               );
-       }
-}
diff --git a/director/src/until.ts b/director/src/until.ts
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/director/src/update.ts b/director/src/update.ts
deleted file mode 100644 (file)
index f122da3..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-import { io } from "socket.io-client";
-
-import { renderDiscount, renderReverseDiscount } from "./discount.js";
-import { setupTimeSince, setupTimeUntil } from "./time.js";
-import { setupSounds, playSounds } from "./sound.js";
-import { setupStyle, renderStyle } from "./style.js";
-import renderShowUntil from "./show_until.js";
-import renderState from "./state.js";
-import renderPrice from "./price.js"
-import renderText from "./text.js";
-
-export default function setupUpdate(): void {
-       setupTimeSince();
-       setupTimeUntil();
-       setupSounds();
-       setupStyle();
-
-       const socket = io();
-       socket.on("update", (data) => {
-               const start = performance.now()
-
-               for (const [key, value] of Object.entries(data)) {
-                       const el = document.querySelectorAll(`.update[class~='${key}']`);
-
-                       for (let e of el) {
-                               if (e instanceof HTMLElement) {
-                                       e.dataset.raw = value as unknown as string;
-                               }
-                       }
-               }
-
-               renderReverseDiscount();
-               renderShowUntil();
-               renderDiscount();
-               renderState();
-               renderPrice();
-               renderStyle();
-               renderText();
-               playSounds();
-
-               console.log(`Updated in ${performance.now() - start}ms`);
-       });
-}
diff --git a/director/src/utils.ts b/director/src/utils.ts
deleted file mode 100644 (file)
index 684ee85..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-export function timeUntil(end: number): number[] {
-       let current: number = Date.now() / 1000;
-       var time: number = end - current;
-
-       if (Math.sign(time) == -1) {time = 0;}
-
-       let hours: number = Math.floor(time / 3600);
-       time %= 3600;
-       let minutes: number = Math.floor(time / 60);
-       let seconds: number = Math.floor(time % 60);
-
-       return [hours, minutes, seconds]
-}
-
-export function timeSince(end: number): number[] {
-       let current: number = Date.now() / 1000;
-       var time: number = current - end;
-
-       if (Math.sign(time) == -1) {time = 0;}
-
-       let hours: number = Math.floor(time / 3600);
-       time %= 3600;
-       let minutes: number = Math.floor(time / 60);
-       let seconds: number = Math.floor(time % 60);
-
-       return [hours, minutes, seconds]
-}
-
-export function timeFormatBroadcast(hours: number, minutes: number, seconds: number): string {
-       var hoursString = hours.toString().padStart(2, "0");
-       var minutesString = minutes.toString().padStart(2, "0");
-       var secondsString = seconds.toString().padStart(2, "0");
-
-       return `${hoursString}h ${minutesString}' ${secondsString}"`
-}
diff --git a/director/static/admin.css b/director/static/admin.css
deleted file mode 100644 (file)
index cc4422f..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/* PAGE POSITIONING */
-
-:root {
-       --nav-background: lightgray;
-}
-
-body > * {
-       padding: 15px;
-       overflow: scroll
-}
-nav {
-       position: absolute;
-       top: 0; bottom: 0; left: 0;
-       right: max(80%, calc(100vw - 350px));
-       background-color: var(--nav-background);
-}
-main {
-       position: absolute;
-       top: 0; bottom: 0; right: 0;
-       left: min(20%, calc(350px));
-}
-
-/* THE OPTIONS GRID */
-
-.optionsGrid {
-       display: grid;
-       grid-template-columns: 50px auto auto auto;
-}
-.optionsGrid > * {
-       padding: 10px;
-       border: 1px solid gray;
-       margin-top: -1px;
-       margin-right: -1px;
-}
-.optionsGridSpacer { border: none; }
-
-
-:target {
-       outline: 4px solid blue;
-       z-index: 1;
-}
-.currentValue { color: red; }
-.currentValue[type="radio"] { background-color: red; }
-
-
-/* PRINT MODE
-               need to work on this a little bit, currently just hides things that
-               shouldnt be printed and thats all. Should be able to potentially display
-               extra elements or manipulate the page in a way that make it easy to read
-               or annotate on the page.
- */
-
-@media ( max-width: 1000px ) {
-       nav { position: static; }
-       main { position: static; }
-}
-
-@media print {
-       nav, [type="radio"] { display: none }
-       [type="submit"] { opacity: 0; }
-       main { position: static; }
-       .currentValue { color: black; }
-       .optionsGrid { grid-template-columns: 0 auto 0 auto; }
-       .optionsGrid > * { padding: 0; }
-       .optionsGridSpacer { padding: 20px; }
-}
diff --git a/director/static/andika.css b/director/static/andika.css
deleted file mode 100644 (file)
index 0f268e5..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*\r
-This file is from the Andika project (https://software.sil.org/andika/).\r
-Copyright (c) 2004-2025 SIL Global (https://www.sil.org/) with Reserved\r
-Font Names "Andika" and "SIL". This Font Software is licensed under the SIL\r
-Open Font License, Version 1.1 (https://openfontlicense.org).\r
-*/\r
-\r
-@font-face {\r
-       font-family: "Andika";\r
-       font-weight: 400;\r
-       src: url(/static/fonts/Andika-Regular.woff2);\r
-}\r
-@font-face {\r
-       font-family: "Andika";\r
-       font-weight: 500;\r
-       src: url(/static/fonts/Andika-Medium.woff2);\r
-}\r
-@font-face {\r
-       font-family: "Andika";\r
-       font-weight: 600;\r
-       src: url(/static/fonts/Andika-SemiBold.woff2);\r
-}\r
-@font-face {\r
-       font-family: "Andika";\r
-       font-weight: 700;\r
-       src: url(/static/fonts/Andika-Bold.woff2);\r
-}\r
-@font-face {\r
-       font-family: "Andika";\r
-       font-weight: 400;\r
-       font-style: italic;\r
-       src: url(/static/fonts/Andika-Italic.woff2);\r
-}\r
-@font-face {\r
-       font-family: "Andika";\r
-       font-weight: 500;\r
-       font-style: italic;\r
-       src: url(/static/fonts/Andika-MediumItalic.woff2);\r
-}\r
-@font-face {\r
-       font-family: "Andika";\r
-       font-weight: 600;\r
-       font-style: italic;\r
-       src: url(/static/fonts/Andika-SemiBoldItalic.woff2);\r
-}\r
-@font-face {\r
-       font-family: "Andika";\r
-       font-weight: 700;\r
-       font-style: italic;\r
-       src: url(/static/fonts/Andika-BoldItalic.woff2);\r
-}\r
-\r
-:root {\r
-       font-family: "Andika", sans-serif;\r
-}\r
diff --git a/director/static/fonts/Andika-Bold.woff2 b/director/static/fonts/Andika-Bold.woff2
deleted file mode 100644 (file)
index 866d64a..0000000
Binary files a/director/static/fonts/Andika-Bold.woff2 and /dev/null differ
diff --git a/director/static/fonts/Andika-BoldItalic.woff2 b/director/static/fonts/Andika-BoldItalic.woff2
deleted file mode 100644 (file)
index 6941dca..0000000
Binary files a/director/static/fonts/Andika-BoldItalic.woff2 and /dev/null differ
diff --git a/director/static/fonts/Andika-Italic.woff2 b/director/static/fonts/Andika-Italic.woff2
deleted file mode 100644 (file)
index 29d7283..0000000
Binary files a/director/static/fonts/Andika-Italic.woff2 and /dev/null differ
diff --git a/director/static/fonts/Andika-Medium.woff2 b/director/static/fonts/Andika-Medium.woff2
deleted file mode 100644 (file)
index e47adf4..0000000
Binary files a/director/static/fonts/Andika-Medium.woff2 and /dev/null differ
diff --git a/director/static/fonts/Andika-MediumItalic.woff2 b/director/static/fonts/Andika-MediumItalic.woff2
deleted file mode 100644 (file)
index 928f4e3..0000000
Binary files a/director/static/fonts/Andika-MediumItalic.woff2 and /dev/null differ
diff --git a/director/static/fonts/Andika-Regular.woff2 b/director/static/fonts/Andika-Regular.woff2
deleted file mode 100644 (file)
index d3e1a0d..0000000
Binary files a/director/static/fonts/Andika-Regular.woff2 and /dev/null differ
diff --git a/director/static/fonts/Andika-SemiBold.woff2 b/director/static/fonts/Andika-SemiBold.woff2
deleted file mode 100644 (file)
index 09b7ebd..0000000
Binary files a/director/static/fonts/Andika-SemiBold.woff2 and /dev/null differ
diff --git a/director/static/fonts/Andika-SemiBoldItalic.woff2 b/director/static/fonts/Andika-SemiBoldItalic.woff2
deleted file mode 100644 (file)
index 69ae382..0000000
Binary files a/director/static/fonts/Andika-SemiBoldItalic.woff2 and /dev/null differ
diff --git a/director/static/info.css b/director/static/info.css
deleted file mode 100644 (file)
index c8c37b9..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-:root {
-       font-family: sans-serif;
-       color: white;
-       background-color: black;
-}
-
-.infoA { font-size: var(--aFontSize); }
-.infoB { font-size: var(--bFontSize); }
-.infoC { font-size: var(--cFontSize); }
-
-.title { text-transform: capitalize; }
-
-/* INFO A */
-.infoA div > * { padding: 20px; }
-.infoA div {
-       position: absolute;
-       top: 0; left: 0; bottom: 0; right: 0;
-       display: grid;
-       grid: none / 1fr;
-}
-
-/* INFO B */
-.infoB div > * { padding: 20px; }
-.infoB div {
-       position: absolute;
-       top: 0; left: 0; bottom: 0; right: 0;
-       display: grid;
-       grid: none / 1fr 1fr;
-}
-
-/* INFO C */
-.infoC div > * { padding: 20px; text-align: center; }
-.infoC div {
-       position: absolute;
-       top: 0; left: 0; bottom: 0; right: 0;
-       display: grid;
-       grid: none / 6fr 1fr 6fr;
-}
-
diff --git a/director/static/media/sfx/banner_shout.wav b/director/static/media/sfx/banner_shout.wav
deleted file mode 100644 (file)
index 4525408..0000000
Binary files a/director/static/media/sfx/banner_shout.wav and /dev/null differ
diff --git a/director/static/media/sfx/clock.wav b/director/static/media/sfx/clock.wav
deleted file mode 100644 (file)
index a760531..0000000
Binary files a/director/static/media/sfx/clock.wav and /dev/null differ
diff --git a/director/static/media/sfx/shout.wav b/director/static/media/sfx/shout.wav
deleted file mode 100644 (file)
index 4a6849d..0000000
Binary files a/director/static/media/sfx/shout.wav and /dev/null differ
diff --git a/director/static/media/sfx/state_change.wav b/director/static/media/sfx/state_change.wav
deleted file mode 100644 (file)
index 9a34860..0000000
Binary files a/director/static/media/sfx/state_change.wav and /dev/null differ
diff --git a/director/static/style.css b/director/static/style.css
deleted file mode 100644 (file)
index 3295c95..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-:root {
-       font-size: var(--baseFontSize);
-       font-weight: 600;
-}
-.title { text-transform: capitalize; }
diff --git a/director/static/style/banner_box.css b/director/static/style/banner_box.css
deleted file mode 100644 (file)
index 83213b6..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-body:not(.state-sold, .state-move) .styleBannerBox {
-       padding: 0; margin: 0;
-}
-.styleBannerBox {
-       opacity: 0; max-height: 0;
-       transform: translateX(-20px);
-       /* should do some tweeking for the below */
-       transition:
-       opacity var(--baseAnimationLength),
-       max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1),
-       padding var(--baseAnimationLength),
-       margin var(--baseAnimationLength),
-       transform var(--baseAnimationLength);
-       overflow: hidden;
-}
-body.state-sold .styleBannerBox,
-body.state-move .styleBannerBox {
-       opacity: 1; max-height: 50vh;
-       transform: translateX(0px);
-}
diff --git a/director/static/style/box.css b/director/static/style/box.css
deleted file mode 100644 (file)
index 35a7a24..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-:root {
-       --boxHPad: 6px;
-       --boxVPad: 2px;
-       --boxHMar: 0px;
-       --boxVMar: 5px;
-}
-.boxA {
-       width: calc(100% - 2 * (var(--boxHMar) + var(--boxHPad) + var(--borderASize)));
-
-       color: var(--textAColor);
-       text-shadow: var(--textAShadow);
-
-       background: var(--backgroundA);
-       box-shadow: inset 0 0 var(--innerGlowSize) var(--innerGlowColor);
-       border: var(--borderASize) solid var(--borderAColor);
-
-       border-radius: var(--borderARadius);
-       padding: var(--boxVPad) var(--boxHPad) var(--boxVPad) var(--boxHPad);
-       margin: var(--boxVMar) var(--boxHMar) var(--boxVMar) var(--boxHMar);
-}
-.boxA.styleExpand.showUntil:not(.showUntil-showing) {
-       margin-bottom: calc(-2 * var(--borderASize));
-}
-
-.boxB {
-       width: calc(100% - 2 * (var(--boxHMar) + var(--boxHPad) + var(--borderBSize)));
-
-       color: var(--textBColor);
-       text-shadow: var(--textBShadow);
-
-       background: var(--backgroundB);
-       box-shadow: inset 0 0 var(--innerGlowSize) var(--innerGlowColor);
-       border: var(--borderBSize) solid var(--borderBColor);
-
-       border-radius: var(--borderBRadius);
-       padding: var(--boxVPad) var(--boxHPad) var(--boxVPad) var(--boxHPad);
-       margin: var(--boxVMar) var(--boxHMar) var(--boxVMar) var(--boxHMar);
-}
-.boxB.styleExpand.showUntil:not(.showUntil-showing) {
-       margin-bottom: calc(-2 * var(--borderBSize));
-}
-
-.boxC {
-       width: calc(100% - 2 * (var(--boxHMar) + var(--boxHPad) + var(--borderCSize)));
-
-       color: var(--textCColor);
-       text-shadow: var(--textCShadow);
-
-       background: var(--backgroundC);
-       box-shadow: inset 0 0 var(--innerGlowSize) var(--innerGlowColor);
-       border: var(--borderCSize) solid var(--borderCColor);
-
-       border-radius: var(--borderCRadius);
-       padding: var(--boxVPad) var(--boxHPad) var(--boxVPad) var(--boxHPad);
-       margin: var(--boxVMar) var(--boxHMar) var(--boxVMar) var(--boxHMar);
-}
-.boxC.styleExpand.showUntil:not(.showUntil-showing) {
-       margin: 0 0 calc(-2 * var(--borderCSize)) 0;
-}
diff --git a/director/static/style/center_shout.css b/director/static/style/center_shout.css
deleted file mode 100644 (file)
index 21b5949..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-.styleCenterShout {
-       position: absolute;
-       top: 0; left: 0; bottom: 0; right: 0;
-
-       display: flex;
-       align-items: center; justify-content: center;
-
-       text-transform: uppercase;
-}
-.styleCenterShout > div { background-color: red; }
-
-.styleCenterShout.showUntil > div {
-       transform: translateX(-100px);
-       opacity: 0;
-       transition:
-               transform var(--baseAnimationLength),
-               opacity var(--baseAnimationLength);
-}
-.styleCenterShout.showUntil > div > span {
-       display: block;
-       transform: translateX(200px);
-       transition: transform var(--baseAnimationLength);
-
-       text-transform: uppercase;
-}
-.styleCenterShout.showUntil-showing * {
-       opacity: 1 !important;
-       transform: translateX(0px) !important;
-}
diff --git a/director/static/style/discount_box.css b/director/static/style/discount_box.css
deleted file mode 100644 (file)
index 2c84661..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-.styleDiscountBox > em {
-       display: block;
-       font-size: 0.7em;
-       line-height: 1.4em;
-}
-.styleDiscountBox > div {
-       font-size: 1.2em;
-}
-
-body:not(.state-discount, .state-move) .styleDiscountBox {
-       padding: 0; margin: 0;
-}
-.styleDiscountBox {
-       opacity: 0; max-height: 0;
-       transform: translateX(-20px);
-       /* should do some tweeking for the below */
-       transition:
-       opacity var(--baseAnimationLength),
-       max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1),
-       padding var(--baseAnimationLength),
-       margin var(--baseAnimationLength),
-       transform var(--baseAnimationLength);
-       overflow: hidden;
-}
-body.state-discount .styleDiscountBox,
-body.state-move .styleDiscountBox {
-       opacity: 1; max-height: 50vh;
-       transform: translateX(0px);
-}
-
diff --git a/director/static/style/item_box.css b/director/static/style/item_box.css
deleted file mode 100644 (file)
index f40ef48..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-body:not(
-       .state-product,
-       .state-price,
-       .state-discount,
-       .state-move,
-       .state-sold
-) .styleItemBox {
-       padding: 0; margin: 0;
-}
-.styleItemBox {
-       opacity: 0; max-height: 0;
-       transform: translateX(-20px);
-       /* should do some tweeking for the below */
-       transition:
-       opacity var(--baseAnimationLength),
-       max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1),
-       padding var(--baseAnimationLength),
-       margin var(--baseAnimationLength),
-       transform var(--baseAnimationLength);
-       overflow: hidden;
-}
-body.state-product .styleItemBox,
-body.state-price .styleItemBox,
-body.state-discount .styleItemBox,
-body.state-move .styleItemBox,
-body.state-sold .styleItemBox {
-       opacity: 1; max-height: 50vh;
-       transform: translateX(0px);
-}
diff --git a/director/static/style/logo_box.css b/director/static/style/logo_box.css
deleted file mode 100644 (file)
index c070292..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-body:not(
-       .state-crawler,
-       .state-product
-) .styleLogoBox {
-       padding: 0; margin: 0;
-}
-.styleLogoBox {
-       opacity: 0; max-height: 0;
-       transform: translateX(-20px);
-       /* should do some tweeking for the below */
-       transition:
-       opacity var(--baseAnimationLength),
-       max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1),
-       padding var(--baseAnimationLength),
-       margin var(--baseAnimationLength),
-       transform var(--baseAnimationLength);
-       overflow: hidden;
-}
-body.state-product .styleLogoBox,
-body.state-crawler .styleLogoBox {
-       opacity: 1; max-height: 50vh;
-       transform: translateX(0px);
-}
diff --git a/director/static/style/pricing_box.css b/director/static/style/pricing_box.css
deleted file mode 100644 (file)
index 57d2fff..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-body:not(.state-price, .state-discount, .state-move) .stylePricingBox {
-       padding: 0; margin: 0;
-}
-.stylePricingBox {
-       opacity: 0; max-height: 0;
-       transform: translateX(-20px);
-       /* should do some tweeking for the below */
-       transition:
-       opacity var(--baseAnimationLength),
-       max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1),
-       padding var(--baseAnimationLength),
-       margin var(--baseAnimationLength),
-       transform var(--baseAnimationLength);
-       overflow: hidden;
-}
-body.state-price .stylePricingBox,
-body.state-discount .stylePricingBox,
-body.state-move .stylePricingBox {
-       opacity: 1; max-height: 50vh;
-       transform: translateX(0px);
-}
diff --git a/director/static/style/qty_box.css b/director/static/style/qty_box.css
deleted file mode 100644 (file)
index b774fa3..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-.styleQtyBox {
-       font-size: 0.7em;
-}
-
-body:not(.state-sold, .state-move) .styleQtyBox {
-       padding: 0; margin: 0;
-}
-.styleQtyBox {
-       opacity: 0; max-height: 0;
-       transform: translateX(-20px);
-       /* should do some tweeking for the below */
-       transition:
-       opacity var(--baseAnimationLength),
-       max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1),
-       padding var(--baseAnimationLength),
-       margin var(--baseAnimationLength),
-       transform var(--baseAnimationLength);
-       overflow: hidden;
-}
-body.state-sold .styleQtyBox,
-body.state-move .styleQtyBox {
-       opacity: 1; max-height: 50vh;
-       transform: translateX(0px);
-}
diff --git a/director/static/style/show_until.css b/director/static/style/show_until.css
deleted file mode 100644 (file)
index 451952f..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-.styleExpand.showUntil:not(.showUntil-showing) {
-       padding: 0; margin: 0;
-}
-.styleExpand.showUntil {
-       opacity: 0; max-height: 0;
-       transform: translateX(-20px);
-       /* should do some tweeking for the below */
-       transition:
-               opacity var(--baseAnimationLength),
-               max-height var(--baseAnimationLength) cubic-bezier(1,0,0,1),
-               padding var(--baseAnimationLength),
-               margin var(--baseAnimationLength),
-               transform var(--baseAnimationLength);
-       overflow: hidden;
-}
-.styleExpand.showUntil.showUntil-showing {
-       opacity: 1; max-height: 50vh;
-       transform: translateX(0px);
-}
diff --git a/director/static/style/side_box.css b/director/static/style/side_box.css
deleted file mode 100644 (file)
index 066842e..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-.styleSideBox {
-       width: var(--sideBoxWidth);
-
-       display: flex;
-       flex-direction: column;
-
-       margin: 50px;
-}
-.styleSideBox > * {
-       margin-bottom: 5px;
-       width: 100%;
-}
diff --git a/director/static/style/side_timer_box.css b/director/static/style/side_timer_box.css
deleted file mode 100644 (file)
index dfd48d4..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-.styleSideTimerBox {
-       display: inline;
-       width: fit-content !important;
-}
diff --git a/director/templates/admin.html b/director/templates/admin.html
deleted file mode 100644 (file)
index 4c62a4e..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-{#
-
-       builds the admin page
-
-#}
-<!DOCTYPE html>
-<html>
-       <head>
-               <link rel="stylesheet" href="/static/admin.css">
-
-               <script type="module" defer>
-
-import { setupTrigger } from "/script/admin.js";
-setupTrigger();
-
-               </script>
-       </head>
-       <body>
-               <nav>
-                       <p><b>Tables</b></p>
-                       <ul style="border: 1px solid gray">
-                               {% for table in indexes %}
-                                       {% set table_name = table.split("--")[1] %}
-                                       <li><a href="/admin/{{ table_name }}">{{ table_name }}</a></li>
-                               {% endfor %}
-                       </ul>
-               </nav>
-               <main>
-                       <h1>Admin</h1>
-
-                       <form method="GET" action="/db">
-                               <button type="submit">Donwload database</button>
-                       </form>
-                       <form method="POST" action="/db">
-                               <input type="file"/>
-                               <button type="submit">Upload database</button>
-                       </form>
-
-                       <ul>
-                               <li><a href="/">Main GFX overlay</a></li>
-                               <li><a href="/info/a">Info page A</a> <em>(Item name, description, Anchor notes)</em></li>
-                               <li><a href="/info/b">Info page B</a> <em>(Price, discount and stock)</em></li>
-                               <li><a href="/info/c">Info page C</a> <em>(Gallery screen, timing and state)</em></li>
-                       </ul>
-               </main>
-       </body>
-</html>
diff --git a/director/templates/admin/color.html b/director/templates/admin/color.html
deleted file mode 100644 (file)
index 1ecd886..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-<label>{{ label }}</label>
-<span>
-       <input id="{{ name }}" type="color" name="{{ name }}" value="{{ value }}" />
-       {{ value }}
-</span>
-<span class="currentValue" style="background-color: {{ value }};"></span>
diff --git a/director/templates/admin/float.html b/director/templates/admin/float.html
deleted file mode 100644 (file)
index 12f8b00..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<label>{{ label }}</label>
-<input id="{{ name }}" type="number" name="{{ name }}" value="{{ value }}" step="0.01" />
-<span class="currentValue">{{ value }}</span>
diff --git a/director/templates/admin/number.html b/director/templates/admin/number.html
deleted file mode 100644 (file)
index 7ffe0c7..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<label>{{ label }}</label>
-<input id="{{ name }}" type="number" name="{{ name }}" value="{{ value }}" />
-<span class="currentValue">{{ value }}</span>
diff --git a/director/templates/admin/text.html b/director/templates/admin/text.html
deleted file mode 100644 (file)
index 3878cc8..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<label>{{ label }}</label>
-<input id="{{ name }}" type="text" name="{{ name }}" value="{{ value }}" />
-<span class="currentValue">{{ value }}</span>
-
diff --git a/director/templates/admin/textarea.html b/director/templates/admin/textarea.html
deleted file mode 100644 (file)
index a9ce85b..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<label>{{ label }}</label>
-<textarea id="{{ name }}" style="grid-column: 3 / span 2;" name="{{ name }}">
-       {{- value -}}
-</textarea>
diff --git a/director/templates/admin/trigger.html b/director/templates/admin/trigger.html
deleted file mode 100644 (file)
index 322450d..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-<span id="{{ name }}" style="grid-column: 2 / span 3;">
-       <noscript style="color: red;">Trigger will not function without JS<br></noscript>
-       <button type="button" name="{{ name }}" value="{{ label }}" class="trigger">
-               {{ label }}
-       </button>
-       <input type="number" id="{{ name }}+delay" value="{{ value.split('+')[1] }}"/><span> seconds delay <em>(This does not update the triggered data.)</em></span>
-</span>
diff --git a/director/templates/index.html b/director/templates/index.html
deleted file mode 100644 (file)
index af8760e..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-<!doctype html>
-<html>
-       <head>
-               <link rel="stylesheet" href="/static/style.css">
-               <link rel="stylesheet" href="/static/andika.css">
-
-               {# ELEMENT STYLING IMPORTS #}
-               <link rel="stylesheet" href="/static/style/side_box.css">
-               <link rel="stylesheet" href="/static/style/qty_box.css">
-               <link rel="stylesheet" href="/static/style/side_timer_box.css">
-               <link rel="stylesheet" href="/static/style/center_shout.css">
-               <link rel="stylesheet" href="/static/style/discount_box.css">
-               <link rel="stylesheet" href="/static/style/banner_box.css">
-               <link rel="stylesheet" href="/static/style/pricing_box.css">
-               <link rel="stylesheet" href="/static/style/item_box.css">
-               <link rel="stylesheet" href="/static/style/logo_box.css">
-
-               {# HELPER IMPORTS #}
-               <link rel="stylesheet" href="/static/style/box.css">
-               <link rel="stylesheet" href="/static/style/show_until.css">
-               <link rel="stylesheet" href="/static/style/background.css">
-
-               <script type="importmap">
-               {
-                       "imports": {
-                       "socket.io-client": "https://cdn.socket.io/4.8.3/socket.io.esm.min.js"
-                       }
-               }
-               </script>
-               <script type="module" defer>
-
-import setupUpdate from "/script/update.js";
-setupUpdate();
-
-               </script>
-       </head>
-       <body class="update data__state~~text--state state">
-
-               {# GLOBAL STYLING ELEMENTS #}
-               <span class="update style~~text--baseAnimationLength style"></span>
-               <span class="update style~~text--sideBoxWidth style"></span>
-               <span class="update style~~text--baseFontSize style"></span>
-
-               {# DYNAMIC STYLING ELEMENTS #}
-
-               <span class="update style__colorscheme~~text--borderASize style"></span>
-               <span class="update style__colorscheme~~color--borderAColor style"></span>
-               <span class="update style__colorscheme~~text--borderBSize style"></span>
-               <span class="update style__colorscheme~~color--borderBColor style"></span>
-               <span class="update style__colorscheme~~text--borderCSize style"></span>
-               <span class="update style__colorscheme~~color--borderCColor style"></span>
-
-               <span class="update style__colorscheme~~color--textAColor style"></span>
-               <span class="update style__colorscheme~~color--textBColor style"></span>
-               <span class="update style__colorscheme~~color--textCColor style"></span>
-               <span class="update style__colorscheme~~text--textAShadow style"></span>
-               <span class="update style__colorscheme~~text--textBShadow style"></span>
-               <span class="update style__colorscheme~~text--textCShadow style"></span>
-
-               <span class="update style__colorscheme~~text--borderARadius style"></span>
-               <span class="update style__colorscheme~~text--borderBRadius style"></span>
-               <span class="update style__colorscheme~~text--borderCRadius style"></span>
-
-               <span class="update style__colorscheme__backgroundA~~text--backgroundA style"></span>
-               <span class="update style__colorscheme__backgroundB~~text--backgroundB style"></span>
-               <span class="update style__colorscheme__backgroundC~~text--backgroundC style"></span>
-
-               <span class="update style__colorscheme~~color--innerGlowColor style"></span>
-               <span class="update style__colorscheme~~text--innerGlowSize style"></span>
-
-               {# SFX ELEMENTS #}
-               <audio src="/static/media/sfx/banner_shout.wav" class="update data~~trigger--bannerShoutTrigger sound"></audio>
-               <audio src="/static/media/sfx/clock.wav" class="update data__clock~~number--positionDegrees sound"></audio>
-               <audio src="/static/media/sfx/state_change.wav" class="update data__state~~text--state sound"></audio>
-               <audio src="/static/media/sfx/shout.wav" class="update data~~trigger--centerShoutTrigger sound"></audio>
-
-               {# CENTER SHOUT #}
-               <div class="styleCenterShout update data~~trigger--centerShoutTrigger showUntil">
-                       <div>
-                               <span class="update data~~text--centerShoutText text"></span>
-                       </div>
-               </div>
-
-               {# SIDE BOX
-                               includes (top to bottom):
-                               - LOGO BOX (show during: crawler, product)
-                               - BANNER BOX (show during: move, sold)
-                               - ITEM BOX (show during: product, price, discount, move, sold)
-                               - PRICING BOX (show during: price, discount, move)
-                               - DISCOUNT BOX (show during: discount, move)
-                               - BANNER SHOUT BOX (show AD)
-                               - QTY BOX (show during: move, sold)
-                               - TIMER 1 BOX (show AD)
-                               - TIMER 2 BOX (show AD)
-
-                               these are switched on and off using the state class from the
-                               body tag.
-               #}
-               <div class="styleSideBox">
-
-                       {# LOGO BOX #}
-                       <div class="styleLogoBox">
-                               LOGO BOX
-                       </div>
-
-                       {# BANNER BOX #}
-                       <div class="styleBannerBox boxC">
-                               BANNER BOX
-                       </div>
-
-                       {# ITEM BOX #}
-                       <div class="styleItemBox boxB">
-                               <div class="boxA">
-                                       ITEM BOX
-                               </div>
-                       </div>
-
-                       {# PRICING BOX #}
-                       <div class="stylePricingBox boxA">
-                               PRICING BOX
-                       </div>
-
-                       {# DISOUNT BOX #}
-                       <div class="styleDiscountBox boxB">
-                               <em>Now only...</em>
-                               <div class="boxA">
-                                       <b><span class="update data__product~~number--discount discount"></span></b>
-                                       OFF!
-                               </div>
-                       </div>
-
-                       {# BANNER SHOUT BOX #}
-                       <div class="styleExpand boxC update data~~trigger--bannerShoutTrigger showUntil">
-                               <span class="update data~~text--bannerShoutText title"></span>
-                       </div>
-
-                       {# QTY BOX #}
-                       <div class="styleQtyBox boxB">
-                               <em>Sold:
-                               <span class="update data__product~~number--quantityTotal text"></span>...</em>
-                               only
-                               <span class="update data__product~~number--quantityCurrent text"></span>
-                               LEFT
-                       </div>
-
-                       {# TIMER BOX #}
-                       <div class="styleSideTimerBox boxA">
-                               TIMER 1!
-                       </div>
-                       <div class="styleSideTimerBox boxA">
-                               TIMER 2!
-                       </div>
-               </div>
-       </body>
-</html>
diff --git a/director/templates/info/a.html b/director/templates/info/a.html
deleted file mode 100644 (file)
index fa6e8cc..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-<!doctype html>
-<html>
-       <head>
-               <link rel="stylesheet" href="/static/info.css">
-               <script type="importmap">
-               {
-                       "imports": {
-                       "socket.io-client": "https://cdn.socket.io/4.8.3/socket.io.esm.min.js"
-                       }
-               }
-               </script>
-               <script type="module" defer>
-
-import setupUpdate from "/script/update.js";
-setupUpdate();
-
-               </script>
-       </head>
-       <body class="infoA">
-               <span class="update style~~text--aFontSize style"></span>
-
-               <div>
-                       <span>
-                               <u style="color: pink;"><span class="update data__product~~text--name text"></span></u><br>
-                               <span style="color: pink" class="update data__product~~text--description text"></span>
-                       </span>
-
-                       <span class="styleProductNotes update data__product~~textarea--notes text"></span>
-
-                       <span style="color: yellow" class="update data~~textarea--anchorNotes text"></span>
-               </div>
-       </body>
-</html>
diff --git a/director/templates/info/b.html b/director/templates/info/b.html
deleted file mode 100644 (file)
index c06b48e..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-<!doctype html>
-<html>
-       <head>
-               <link rel="stylesheet" href="/static/info.css">
-               <script type="importmap">
-               {
-                       "imports": {
-                       "socket.io-client": "https://cdn.socket.io/4.8.3/socket.io.esm.min.js"
-                       }
-               }
-               </script>
-               <script type="module" defer>
-
-import setupUpdate from "/script/update.js";
-setupUpdate();
-
-               </script>
-       </head>
-       <body class="infoB">
-               <span class="update style~~text--bFontSize style"></span>
-
-               <div>
-                       <span>
-                               <span style="background-color: green" class="update data__product__currentPriceString~~text--currentPriceString text"></span> <em>(was <span class="update data__product__originalPriceString~~text--originalPriceString text"></span>)</em>
-                       </span>
-
-                       <span>
-                               <span class="update data__product~~number--quantityCurrent text"></span>
-                               left of
-                               <span class="update data__product~~number--quantityTotal text"></span>
-                               total
-                       </span>
-
-                       <span>
-                               <span style="background-color: purple;" class="update data__product~~number--discount discount"></span> off
-                       </span>
-
-                       <span>
-                               <span style="background-color: purple;" class="update data__product~~number--discount reverseDiscount"></span> full price
-                       </span>
-
-                       <span style="grid-column: 1 / span 2;">
-                               Target: <span style="background-color: orange;" class="update data__product~~number--targetDiscount discount"></span> (<span class="update data__product__remainingDiscount~~number--remainingDiscount discount"></span> left to drop)
-                       </span>
-
-                       <span style="grid-column: 1 / span 2;">
-                               Max: <span style="background-color: red;" class="update data__product~~number--maximumDiscount discount"></span> (<span class="update data__product__remainingMaximumDiscount~~number--remainingMaximumDiscount discount"></span> left to drop)
-                       </span>
-               </div>
-       </body>
-</html>
diff --git a/director/templates/info/c.html b/director/templates/info/c.html
deleted file mode 100644 (file)
index b35ba79..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<!doctype html>
-<html>
-       <head>
-               <link rel="stylesheet" href="/static/info.css">
-               <script type="importmap">
-               {
-                       "imports": {
-                       "socket.io-client": "https://cdn.socket.io/4.8.3/socket.io.esm.min.js"
-                       }
-               }
-               </script>
-               <script type="module" defer>
-
-import setupUpdate from "/script/update.js";
-setupUpdate();
-
-               </script>
-       </head>
-       <body class="infoC">
-               <span class="update style~~text--cFontSize style"></span>
-
-               <div>
-                       <span>Current product:<br><span style="background-color: blue;" class="update data__product~~text--name text"></span></span>
-                       <span>&rarr;</span>
-                       <span>Next product:<br><span style="background-color: blue;" class="update data__product__next~~text--name text"></span></span>
-
-                       <span>Current state: <span class="update data__state~~text--state title"></span></span>
-                       <span>&rarr;</span>
-                       <span>Next state: <span class="update data__state~~text--nextState title"></span></span>
-
-                       <span style="grid-column: 1 / span 3; font-size: 2em; font-size: 2em;">
-                               <span class="update data~~trigger--startTrigger since"></span> <span style="background-color: red;">T-<span class="update data__endTime~~text--endTime until"></span></span>
-                       </span>
-               </div>
-       </body>
-</html>
diff --git a/director/templates/table.html b/director/templates/table.html
deleted file mode 100644 (file)
index 38b7a9e..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-{#
-
-       builds the admin page
-
-#}
-<!DOCTYPE html>
-<html>
-       <head>
-               <link rel="stylesheet" href="/static/admin.css">
-
-               <script type="module" defer>
-
-import { setupTrigger } from "/script/admin.js";
-setupTrigger();
-
-               </script>
-       </head>
-       <body>
-               <nav>
-                       <p><a href="/admin">.. back</a></p>
-                       <p><b>{{ table_name }}</b></p>
-                       <ol>
-                       {% for row in table %}
-                               <li style="border: 1px solid gray; margin-top: -1px;"><ul>
-                                       {% set group = loop.index0 %}
-                                       {% for key in row %}
-                                               <li><a href="#{{ table_name ~ "~~" ~ group ~ "~~" ~ key }}">{{ key }}</a></li>
-                                       {% endfor %}
-                               </ul></li>
-                       {% endfor %}
-                       </ol>
-               </nav>
-               <main>
-                       <h1>Table: {{ table_name }}</h1>
-                       <form class="optionsGrid" method="post">
-                               <input type="submit" value="Submit table" style="grid-column: 1 / span 4;">
-                               <span class="optionsGridSpacer" style="grid-column: 1 / span 4;"></span>
-                               {% for row in table %}
-
-                                       {# CREATE RADIO BUTTON FOR ROW #}
-
-                                               <span style="
-                                                       grid-row: {{ ((row|length + 1) * loop.index0) + 3 }} / span {{ row|length }};
-                                                       display: flex;
-                                                       justify-content: center;
-                                                       align-items: center;
-                                                       ">
-                                                       {% if loop.index0 == indexes["int--" ~ table_name] %}
-                                                               <input type="radio" name="{{ "indexes~~0~~int--" ~ table_name }}" value="{{ loop.index0 }}" checked="checked" class="currentValue">
-                                                       {% else %}
-                                                               <input type="radio" name="{{ "indexes~~0~~int--" ~ table_name }}" value="{{ loop.index0 }}" >
-                                                       {% endif %}
-                                               </span>
-
-                                       {# CREATE FEILDS #}
-
-                                       {% set group = loop.index0 %}
-                                       {% for feild in row %}
-
-                                               {# SELECT ELEMENT FROM TYPE #}
-
-                                               {% set type, label = feild.split('--') %}
-                                               {% set value = row[feild] %}
-                                               {% set name = table_name ~ "~~" ~ group ~ "~~" ~ feild %}
-
-                                               {% if type == "textarea" %}
-                                                       {% include "admin/textarea.html" %}
-                                               {% elif type == "text" %}
-                                                       {% include "admin/text.html" %}
-                                               {% elif type == "number" %}
-                                                       {% include "admin/number.html" %}
-                                               {% elif type == "float" %}
-                                                       {% include "admin/float.html" %}
-                                               {% elif type == "trigger" %}
-                                                       {% include "admin/trigger.html" %}
-                                               {% elif type == "color" %}
-                                                       {% include "admin/color.html" %}
-                                               {% endif %}
-                                       {% endfor %}
-                                       <span class="optionsGridSpacer" style="grid-column: 1 / span 4;"></span>
-
-                               {% endfor %}
-                               <input type="submit" value="Submit table" style="grid-column: 1 / span 4;">
-                       </form>
-
-                       <code>
-                               Note: Tables are rendered statically, it is not safe to opperate the same interface in two places at once.
-                               <br>
-                               Processed {{ table|length * table[0]|length }} feilds in
-                               {% if (time_taken * 1000)|round(2) > 20 %}
-                                       <span style="color: red;">{{ (time_taken * 1000)|round(2) }}ms</span>
-                               {% else %}
-                                       {{ (time_taken * 1000)|round(2) }}ms
-                               {% endif %}
-                       </code>
-               </main>
-       </body>
-</html>
diff --git a/director/utils.py b/director/utils.py
deleted file mode 100644 (file)
index d2fc032..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-def deindex(data, indexes):
-       deindexed = {}
-       for key in data:
-               table, index, feild = key.split("~~")
-               if table != "indexes" and int(index) == indexes[f"int--{table}"]:
-                       deindexed.update({
-                               f"{table}~~{feild}": data[key]
-                               })
-
-       return deindexed
index 3c138d242b1065b655efa0e4d021e2b7f220acd1..747a9b37cff17c57abded094fca08fc0db100253 100644 (file)
@@ -1,9 +1,9 @@
 {
-  "include": ["./director/src","./director/static"],
+  "include": ["./argo/src","./argo/static"],
 
   "compilerOptions": {
-    "rootDir": "./director/src",
-    "outDir": "./director/build",
+    "rootDir": "./argo/src",
+    "outDir": "./argo/build",
 
     "module": "esnext",
     "target": "esnext",