/* ===================================================================== * terminal.js — the homepage's interactive terminal. * * Flow: a short boot log streams in, the side chrome fades in alongside * it, then the banner + a pinned prompt appear. You type a command and * the output is appended to the scrollback BELOW the input — the input * itself never moves. * ===================================================================== */ (function terminal() { const root = document.getElementById("terminal"); if (!root) return; // arch.ascii (hyfetch format) is fetched once at startup for `hyfetch`. let archLines = null; function loadArt() { fetch("/arch.ascii").then(function (r) { return r.ok ? r.text() : ""; }).then(function (t) { if (!t) return; var lines = t.replace(/\r/g, "").split("\n"); if (lines[0] && lines[0].trim().charAt(0) === "{") lines.shift(); lines = lines.map(function (l) { return l.replace(/\$\{c\d\}/g, ""); }); while (lines.length && lines[lines.length - 1].trim() === "") lines.pop(); archLines = lines; }).catch(function () { }); } // ---- ascii banner ------------------------------------------------------- const BANNER = [ " ██████╗██╗ ██████╗ ██╗ ██╗███████╗", "██╔════╝██║ ██╔═══██╗██║ ██║██╔════╝", "██║ ██║ ██║ ██║██║ ██║█████╗ ", "██║ ██║ ██║ ██║╚██╗ ██╔╝██╔══╝ ", "╚██████╗███████╗╚██████╔╝ ╚████╔╝ ███████╗", " ╚═════╝╚══════╝ ╚═════╝ ╚═══╝ ╚══════╝" ].join("\n"); // ---- boot log ----------------------------------------------------------- const BOOT = [ ["info", "starting clovesh..."], ["info", "mounting /dev/estrogen..."], ["ok", "estrogen levels nominal"], ["info", "loading kernel modules (catppuccin)..."], ["ok", "modules loaded"], ["info", "summoning cats..."], ["ok", "oneko ready"], ["info", "connecting to discord via lanyard..."], ["ok", "presence online"], ["info", "mounting button wall..."], ["ok", "88x31 buttons hung"], ["info", "starting terminal..."], ["ok", "ready — type 'help'"] ]; // ---- build DOM ---------------------------------------------------------- root.innerHTML = '
' + '' + esc(BANNER) + "" + '
' + info + "" }; } const colors = ["#5bcefa", "#f5a9b8", "#ffffff", "#f5a9b8", "#5bcefa"]; const n = archLines.length; const logo = archLines.map(function (ln, i) { const c = colors[Math.min(colors.length - 1, Math.floor((i / n) * colors.length))]; return '' + esc(ln) + ""; }).join("\n"); return { html: '
' + logo + "" + '
' + info + "