Merge branch 'feature/terminal-game-engine'
This commit is contained in:
commit
2c1434f412
23 changed files with 5110 additions and 1 deletions
194
assets/js/games/engine/ansi-converter.js
Normal file
194
assets/js/games/engine/ansi-converter.js
Normal file
|
|
@ -0,0 +1,194 @@
|
||||||
|
// ANSI to HTML Converter (256-color + bold, persistent spans)
|
||||||
|
const AnsiConverter = {
|
||||||
|
// Standard + 256-color palette
|
||||||
|
palette: [
|
||||||
|
"#000000",
|
||||||
|
"#800000",
|
||||||
|
"#008000",
|
||||||
|
"#808000",
|
||||||
|
"#000080",
|
||||||
|
"#800080",
|
||||||
|
"#008080",
|
||||||
|
"#c0c0c0",
|
||||||
|
"#808080",
|
||||||
|
"#ff0000",
|
||||||
|
"#00ff00",
|
||||||
|
"#ffff00",
|
||||||
|
"#0000ff",
|
||||||
|
"#ff00ff",
|
||||||
|
"#00ffff",
|
||||||
|
"#ffffff",
|
||||||
|
// 216-color cube (16-231)
|
||||||
|
...(() => {
|
||||||
|
const colors = [];
|
||||||
|
const levels = [0, 95, 135, 175, 215, 255];
|
||||||
|
for (let r = 0; r < 6; r++) {
|
||||||
|
for (let g = 0; g < 6; g++) {
|
||||||
|
for (let b = 0; b < 6; b++) {
|
||||||
|
colors.push(
|
||||||
|
`#${levels[r].toString(16).padStart(2, "0")}${levels[g].toString(16).padStart(2, "0")}${levels[b].toString(16).padStart(2, "0")}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return colors;
|
||||||
|
})(),
|
||||||
|
// Grayscale (232-255)
|
||||||
|
...(() => {
|
||||||
|
const grays = [];
|
||||||
|
for (let i = 0; i < 24; i++) {
|
||||||
|
const level = 8 + i * 10;
|
||||||
|
const hex = level.toString(16).padStart(2, "0");
|
||||||
|
grays.push(`#${hex}${hex}${hex}`);
|
||||||
|
}
|
||||||
|
return grays;
|
||||||
|
})(),
|
||||||
|
],
|
||||||
|
|
||||||
|
// Convert 256-color index to hex
|
||||||
|
ansi256ToHex(index) {
|
||||||
|
index = Number(index);
|
||||||
|
if (index < this.palette.length) return this.palette[index];
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Escape HTML special characters
|
||||||
|
escapeHtml(text) {
|
||||||
|
return text
|
||||||
|
.replace(/&/g, "&")
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/>/g, ">")
|
||||||
|
.replace(/"/g, """);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Convert style object to CSS string
|
||||||
|
styleToCss(style) {
|
||||||
|
const css = [];
|
||||||
|
if (style.color) css.push(`color:${style.color}`);
|
||||||
|
if (style.backgroundColor)
|
||||||
|
css.push(`background-color:${style.backgroundColor}`);
|
||||||
|
if (style.bold) css.push("font-weight:bold");
|
||||||
|
return css.join(";");
|
||||||
|
},
|
||||||
|
|
||||||
|
// Convert ANSI string to HTML
|
||||||
|
convert(ansiString) {
|
||||||
|
// Normalize escapes (\e and \x1b)
|
||||||
|
let processed = ansiString
|
||||||
|
.replace(/\\e/g, "\x1b")
|
||||||
|
.replace(/\\x1b/g, "\x1b");
|
||||||
|
|
||||||
|
// Regex to match ANSI SGR sequences
|
||||||
|
const ansiRegex = /\x1b\[([0-9;]*)m/g;
|
||||||
|
|
||||||
|
let html = "";
|
||||||
|
let lastIndex = 0;
|
||||||
|
let spanOpen = false;
|
||||||
|
let currentStyle = {};
|
||||||
|
|
||||||
|
let match;
|
||||||
|
while ((match = ansiRegex.exec(processed)) !== null) {
|
||||||
|
// Append text before escape sequence
|
||||||
|
const textBefore = processed.slice(lastIndex, match.index);
|
||||||
|
if (textBefore) html += this.escapeHtml(textBefore);
|
||||||
|
|
||||||
|
// Parse SGR codes
|
||||||
|
const codes = match[1].split(";").map((s) => (s === "" ? 0 : Number(s)));
|
||||||
|
let styleChanged = false;
|
||||||
|
|
||||||
|
for (let i = 0; i < codes.length; i++) {
|
||||||
|
const code = codes[i];
|
||||||
|
|
||||||
|
// Reset
|
||||||
|
if (code === 0) {
|
||||||
|
currentStyle = {};
|
||||||
|
styleChanged = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bold
|
||||||
|
if (code === 1) {
|
||||||
|
currentStyle.bold = true;
|
||||||
|
styleChanged = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Foreground 30-37
|
||||||
|
if (code >= 30 && code <= 37) {
|
||||||
|
currentStyle.color = this.palette[code - 30];
|
||||||
|
styleChanged = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bright foreground 90-97
|
||||||
|
if (code >= 90 && code <= 97) {
|
||||||
|
currentStyle.color = this.palette[code - 90 + 8];
|
||||||
|
styleChanged = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Background 40-47
|
||||||
|
if (code >= 40 && code <= 47) {
|
||||||
|
currentStyle.backgroundColor = this.palette[code - 40];
|
||||||
|
styleChanged = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bright background 100-107
|
||||||
|
if (code >= 100 && code <= 107) {
|
||||||
|
currentStyle.backgroundColor = this.palette[code - 100 + 8];
|
||||||
|
styleChanged = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 256-color foreground: 38;5;N
|
||||||
|
if (code === 38 && codes[i + 1] === 5) {
|
||||||
|
currentStyle.color = this.ansi256ToHex(codes[i + 2]);
|
||||||
|
i += 2;
|
||||||
|
styleChanged = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 256-color background: 48;5;N
|
||||||
|
if (code === 48 && codes[i + 1] === 5) {
|
||||||
|
currentStyle.backgroundColor = this.ansi256ToHex(codes[i + 2]);
|
||||||
|
i += 2;
|
||||||
|
styleChanged = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update span if style changed
|
||||||
|
if (styleChanged) {
|
||||||
|
if (spanOpen) html += "</span>";
|
||||||
|
const css = this.styleToCss(currentStyle);
|
||||||
|
if (css) {
|
||||||
|
html += `<span style="${css}">`;
|
||||||
|
spanOpen = true;
|
||||||
|
} else {
|
||||||
|
spanOpen = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastIndex = match.index + match[0].length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append remaining text
|
||||||
|
const remaining = processed.slice(lastIndex);
|
||||||
|
if (remaining) html += this.escapeHtml(remaining);
|
||||||
|
|
||||||
|
// Close final span
|
||||||
|
if (spanOpen) html += "</span>";
|
||||||
|
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Wrap in <pre> for proper display
|
||||||
|
convertToBlock(ansiString, className = "ansi-art") {
|
||||||
|
console.log("AnsiConverter.convertToBlock called");
|
||||||
|
return `<pre class="${className}">${this.convert(ansiString)}</pre>`;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Export for browser
|
||||||
|
if (typeof window !== "undefined") window.AnsiConverter = AnsiConverter;
|
||||||
357
assets/js/games/engine/game-engine.js
Normal file
357
assets/js/games/engine/game-engine.js
Normal file
|
|
@ -0,0 +1,357 @@
|
||||||
|
// Game Engine - Main orchestrator for terminal games
|
||||||
|
class GameEngine {
|
||||||
|
constructor(gameDefinition) {
|
||||||
|
this.definition = gameDefinition;
|
||||||
|
this.terminal = null;
|
||||||
|
this.adapter = null;
|
||||||
|
this.state = null;
|
||||||
|
this.sharedState = null; // For series games
|
||||||
|
this.input = null;
|
||||||
|
this.sound = null;
|
||||||
|
this.scenes = null;
|
||||||
|
|
||||||
|
this.isRunning = false;
|
||||||
|
this.originalExecuteCommand = null;
|
||||||
|
|
||||||
|
// Series support
|
||||||
|
this.seriesId = gameDefinition.seriesId || null;
|
||||||
|
this.chapterNumber = gameDefinition.chapterNumber || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register this game as a terminal command
|
||||||
|
register() {
|
||||||
|
if (!window.terminal) {
|
||||||
|
console.warn(
|
||||||
|
"Terminal not available, cannot register game:",
|
||||||
|
this.definition.id,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.terminal = window.terminal;
|
||||||
|
const self = this;
|
||||||
|
const def = this.definition;
|
||||||
|
|
||||||
|
// this.terminal.registerCommand(
|
||||||
|
// def.command || def.id,
|
||||||
|
// def.description || `Play ${def.name}`,
|
||||||
|
// async (args) => {
|
||||||
|
// if (args[0] === "reset") {
|
||||||
|
// self._reset();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (args[0] === "reset-series" && self.seriesId) {
|
||||||
|
// self._resetSeries();
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// if (args[0] === "continue" || args[0] === "resume") {
|
||||||
|
// await self.start(true);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// await self.start();
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the game
|
||||||
|
async start(continueGame = false) {
|
||||||
|
if (this.isRunning) {
|
||||||
|
this.terminal.printWarning("Game is already running!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize shared state for series games (do this early for chapter check)
|
||||||
|
if (this.seriesId && window.SharedStateManager) {
|
||||||
|
this.sharedState = new SharedStateManager(this.seriesId);
|
||||||
|
this.sharedState.init(this.definition.sharedStateDefaults || {});
|
||||||
|
|
||||||
|
// Check if this chapter can be played (sequential unlock)
|
||||||
|
if (this.chapterNumber && this.chapterNumber > 1) {
|
||||||
|
if (!this.sharedState.canPlayChapter(this.chapterNumber)) {
|
||||||
|
const prevChapter = this.chapterNumber - 1;
|
||||||
|
this.terminal.printError(
|
||||||
|
`You must complete Chapter ${prevChapter} before playing Chapter ${this.chapterNumber}.`,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the global HTML to add the game in progress details
|
||||||
|
document.body.classList.add("game-in-progress");
|
||||||
|
console.log(document.body.classList);
|
||||||
|
|
||||||
|
this.isRunning = true;
|
||||||
|
|
||||||
|
// Initialize components
|
||||||
|
this.adapter = new TerminalAdapter(this.terminal);
|
||||||
|
this.state = new StateManager(this.definition.id, this.sharedState);
|
||||||
|
this.input = new InputManager(this.adapter);
|
||||||
|
|
||||||
|
// Initialize sound manager if SoundManager is available
|
||||||
|
if (window.SoundManager) {
|
||||||
|
this.sound = new SoundManager(this.adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.scenes = new SceneManager(
|
||||||
|
this.adapter,
|
||||||
|
this.state,
|
||||||
|
this.input,
|
||||||
|
this.sound,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Initialize state
|
||||||
|
this.state.init(this.definition.initialState || {});
|
||||||
|
|
||||||
|
// Load and merge external scenes if defined
|
||||||
|
const mergedScenes = this._getMergedScenes();
|
||||||
|
|
||||||
|
// Register scenes
|
||||||
|
this.scenes.registerScenes(mergedScenes);
|
||||||
|
|
||||||
|
// Hook into terminal input
|
||||||
|
this._hookInput();
|
||||||
|
|
||||||
|
// Check for existing save
|
||||||
|
const hasSave = this.state.hasSavedState();
|
||||||
|
|
||||||
|
// Show intro unless continuing
|
||||||
|
if (!continueGame && !hasSave) {
|
||||||
|
if (this.definition.intro) {
|
||||||
|
await this._playIntro();
|
||||||
|
}
|
||||||
|
} else if (hasSave && !continueGame) {
|
||||||
|
// Ask if player wants to continue
|
||||||
|
this.adapter.clear();
|
||||||
|
this.adapter.printInfo("A saved game was found.");
|
||||||
|
const shouldContinue = await this.input.awaitConfirm(
|
||||||
|
"Continue from where you left off?",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!shouldContinue) {
|
||||||
|
this.state.reset();
|
||||||
|
this.state.init(this.definition.initialState || {});
|
||||||
|
if (this.definition.intro) {
|
||||||
|
await this._playIntro();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go to start scene (or last scene if continuing)
|
||||||
|
const startScene =
|
||||||
|
this.state.get("_currentScene") || this.definition.startScene || "start";
|
||||||
|
await this.scenes.goTo(startScene);
|
||||||
|
}
|
||||||
|
|
||||||
|
async _playIntro() {
|
||||||
|
this.adapter.clear();
|
||||||
|
|
||||||
|
// Show title
|
||||||
|
if (this.definition.name) {
|
||||||
|
this.adapter.printHTML(
|
||||||
|
`<div class="game-title">${this.definition.name}</div>`,
|
||||||
|
);
|
||||||
|
this.adapter.print("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show intro content
|
||||||
|
if (typeof this.definition.intro === "string") {
|
||||||
|
this.adapter.print(this.definition.intro);
|
||||||
|
} else if (Array.isArray(this.definition.intro)) {
|
||||||
|
await this.scenes._renderContent(this.definition.intro);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.adapter.print("");
|
||||||
|
|
||||||
|
// Wait for input to continue
|
||||||
|
await this.input.awaitOption(
|
||||||
|
[{ text: "Begin", value: true }],
|
||||||
|
"Press Enter or 1 to start...",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_hookInput() {
|
||||||
|
// Store original executeCommand
|
||||||
|
this.originalExecuteCommand = this.terminal.executeCommand.bind(
|
||||||
|
this.terminal,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Override to intercept input
|
||||||
|
const self = this;
|
||||||
|
this.terminal.executeCommand = function (commandString) {
|
||||||
|
if (!self.isRunning) {
|
||||||
|
return self.originalExecuteCommand(commandString);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for exit commands
|
||||||
|
const cmd = commandString.toLowerCase().trim();
|
||||||
|
if (cmd === "quit" || cmd === "exit" || cmd === "q") {
|
||||||
|
self.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for save command
|
||||||
|
if (cmd === "save") {
|
||||||
|
self._saveProgress();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for debug scene skip command (goto <sceneName>)
|
||||||
|
if (cmd.startsWith("goto ")) {
|
||||||
|
const sceneName = commandString.trim().substring(5).trim();
|
||||||
|
self._debugGoToScene(sceneName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass to input manager if in text mode
|
||||||
|
if (self.input.getMode() === "text") {
|
||||||
|
self.input.handleTextInput(commandString);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_saveProgress() {
|
||||||
|
// Save current scene for resuming
|
||||||
|
const currentSceneId = this.scenes.getCurrentSceneId();
|
||||||
|
if (currentSceneId) {
|
||||||
|
this.state.set("_currentScene", currentSceneId);
|
||||||
|
}
|
||||||
|
this.adapter.printSuccess("Game progress saved.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop the game and restore terminal
|
||||||
|
stop() {
|
||||||
|
// Save progress before stopping
|
||||||
|
this._saveProgress();
|
||||||
|
|
||||||
|
// Update the global HTML to remove the game in progress details
|
||||||
|
document.body.classList.remove("game-in-progress");
|
||||||
|
|
||||||
|
this.isRunning = false;
|
||||||
|
|
||||||
|
// Cleanup sound manager
|
||||||
|
if (this.sound) {
|
||||||
|
this.sound.stopAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup input manager
|
||||||
|
if (this.input) {
|
||||||
|
this.input.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Restore original command handler
|
||||||
|
if (this.originalExecuteCommand) {
|
||||||
|
this.terminal.executeCommand = this.originalExecuteCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.adapter.print("");
|
||||||
|
this.adapter.printInfo(`Exited ${this.definition.name}. Progress saved.`);
|
||||||
|
this.adapter.print('Type "help" for available commands.');
|
||||||
|
this.adapter.print(
|
||||||
|
`Type "${this.definition.command || this.definition.id}" to continue playing.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_reset() {
|
||||||
|
if (this.state) {
|
||||||
|
this.state.reset();
|
||||||
|
} else {
|
||||||
|
// Create temporary state manager just to reset
|
||||||
|
const tempState = new StateManager(this.definition.id);
|
||||||
|
tempState.reset();
|
||||||
|
}
|
||||||
|
this.terminal.printSuccess(
|
||||||
|
`${this.definition.name} progress has been reset.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset entire series progress (for series games)
|
||||||
|
_resetSeries() {
|
||||||
|
// Reset chapter state
|
||||||
|
this._reset();
|
||||||
|
|
||||||
|
// Reset shared state
|
||||||
|
if (this.seriesId) {
|
||||||
|
const sharedState = new SharedStateManager(this.seriesId);
|
||||||
|
sharedState.reset();
|
||||||
|
this.terminal.printSuccess(
|
||||||
|
`All ${this.definition.name} series progress has been reset.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create context for scene factories
|
||||||
|
_createSceneContext() {
|
||||||
|
return {
|
||||||
|
chapterNumber: this.chapterNumber || 1,
|
||||||
|
seriesId: this.seriesId,
|
||||||
|
sharedState: this.sharedState,
|
||||||
|
art: this.definition.art || {},
|
||||||
|
additionalOptions: this.definition.additionalHubOptions || [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load external scenes and merge with inline scenes
|
||||||
|
_getMergedScenes() {
|
||||||
|
const inlineScenes = this.definition.scenes || {};
|
||||||
|
|
||||||
|
// If no external scenes defined, just return inline scenes
|
||||||
|
if (
|
||||||
|
!this.definition.externalScenes ||
|
||||||
|
this.definition.externalScenes.length === 0
|
||||||
|
) {
|
||||||
|
return inlineScenes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load external scenes from registered factories
|
||||||
|
const externalScenes = {};
|
||||||
|
const context = this._createSceneContext();
|
||||||
|
|
||||||
|
for (const sceneRef of this.definition.externalScenes) {
|
||||||
|
const factory = window.SceneFactories?.[sceneRef];
|
||||||
|
if (factory) {
|
||||||
|
try {
|
||||||
|
const scenes = factory(context);
|
||||||
|
Object.assign(externalScenes, scenes);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Failed to load external scenes from ${sceneRef}:`, e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn(`Scene factory not found: ${sceneRef}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inline scenes override external scenes (allows chapter-specific overrides)
|
||||||
|
return { ...externalScenes, ...inlineScenes };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug command to skip to a specific scene
|
||||||
|
async _debugGoToScene(sceneName) {
|
||||||
|
const scene = this.scenes.getScene(sceneName);
|
||||||
|
if (!scene) {
|
||||||
|
this.adapter.printError(`Scene not found: ${sceneName}`);
|
||||||
|
this.adapter.print("");
|
||||||
|
this.adapter.printInfo("Available scenes:");
|
||||||
|
const sceneNames = Object.keys(this.definition.scenes).sort();
|
||||||
|
for (const name of sceneNames) {
|
||||||
|
this.adapter.print(` ${name}`);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.adapter.printWarning(`[DEBUG] Skipping to scene: ${sceneName}`);
|
||||||
|
await this.scenes.goTo(sceneName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if game is currently running
|
||||||
|
isActive() {
|
||||||
|
return this.isRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get game definition
|
||||||
|
getDefinition() {
|
||||||
|
return this.definition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make available globally
|
||||||
|
window.GameEngine = GameEngine;
|
||||||
215
assets/js/games/engine/input-manager.js
Normal file
215
assets/js/games/engine/input-manager.js
Normal file
|
|
@ -0,0 +1,215 @@
|
||||||
|
// Input Manager - Handles text input and option selection modes
|
||||||
|
class InputManager {
|
||||||
|
constructor(adapter) {
|
||||||
|
this.adapter = adapter;
|
||||||
|
this.mode = "idle"; // "idle" | "text" | "options"
|
||||||
|
this.options = [];
|
||||||
|
this.selectedIndex = 0;
|
||||||
|
this.inputResolve = null;
|
||||||
|
this.optionsContainerId = "game-options-" + Date.now();
|
||||||
|
this.keydownHandler = null;
|
||||||
|
|
||||||
|
this._setupKeyboardListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
_setupKeyboardListener() {
|
||||||
|
this.keydownHandler = (e) => {
|
||||||
|
if (this.mode !== "options") return;
|
||||||
|
|
||||||
|
// Check if terminal input has text - if so, let user submit commands like "quit"
|
||||||
|
const terminalInput = document.getElementById("input");
|
||||||
|
const hasInputText =
|
||||||
|
terminalInput && terminalInput.value.trim().length > 0;
|
||||||
|
|
||||||
|
if (e.key === "ArrowUp") {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
this._selectPrevious();
|
||||||
|
} else if (e.key === "ArrowDown") {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
this._selectNext();
|
||||||
|
} else if (e.key === "Enter") {
|
||||||
|
// If user has typed something, let it through to submit the command
|
||||||
|
if (hasInputText) return;
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
this._confirmSelection();
|
||||||
|
} else if (/^[1-9]$/.test(e.key)) {
|
||||||
|
// Only intercept if input is empty (user isn't typing a command)
|
||||||
|
if (hasInputText) return;
|
||||||
|
const index = parseInt(e.key) - 1;
|
||||||
|
if (index < this.options.length) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
this.selectedIndex = index;
|
||||||
|
this._confirmSelection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener("keydown", this.keydownHandler, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text input mode - wait for user to type something
|
||||||
|
awaitText(prompt = "") {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
if (prompt) {
|
||||||
|
this.adapter.printInfo(prompt);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mode = "text";
|
||||||
|
this.inputResolve = resolve;
|
||||||
|
|
||||||
|
this.adapter.captureInput((value) => {
|
||||||
|
this.adapter.print(`> ${value}`);
|
||||||
|
this.mode = "idle";
|
||||||
|
this.adapter.releaseInput();
|
||||||
|
if (this.inputResolve) {
|
||||||
|
const res = this.inputResolve;
|
||||||
|
this.inputResolve = null;
|
||||||
|
res(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.adapter.focusInput();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Options selection mode - display choices and wait for selection
|
||||||
|
awaitOption(options, prompt = "") {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
this.mode = "options";
|
||||||
|
this.options = options;
|
||||||
|
this.selectedIndex = 0;
|
||||||
|
this.optionsContainerId = "game-options-" + Date.now();
|
||||||
|
|
||||||
|
if (prompt) {
|
||||||
|
this.adapter.print("");
|
||||||
|
this.adapter.printInfo("------------------");
|
||||||
|
this.adapter.printInfo(prompt);
|
||||||
|
}
|
||||||
|
this.adapter.print("");
|
||||||
|
|
||||||
|
this._renderOptions();
|
||||||
|
|
||||||
|
this.inputResolve = (index) => {
|
||||||
|
this.mode = "idle";
|
||||||
|
resolve({
|
||||||
|
index,
|
||||||
|
option: this.options[index],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yes/No confirmation
|
||||||
|
awaitConfirm(prompt = "Continue?") {
|
||||||
|
return this.awaitOption(
|
||||||
|
[
|
||||||
|
{ text: "Yes", value: true },
|
||||||
|
{ text: "No", value: false },
|
||||||
|
],
|
||||||
|
prompt,
|
||||||
|
).then((result) => result.option.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle text input from game engine
|
||||||
|
handleTextInput(value) {
|
||||||
|
if (this.mode === "text" && this.inputResolve) {
|
||||||
|
this.adapter.print(`> ${value}`);
|
||||||
|
this.mode = "idle";
|
||||||
|
const res = this.inputResolve;
|
||||||
|
this.inputResolve = null;
|
||||||
|
res(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderOptions() {
|
||||||
|
const optionsHTML = this.options
|
||||||
|
.map((opt, idx) => {
|
||||||
|
const selected = idx === this.selectedIndex;
|
||||||
|
const prefix = selected ? ">" : " ";
|
||||||
|
const className = selected ? "game-option-selected" : "game-option";
|
||||||
|
const text = typeof opt === "string" ? opt : opt.text;
|
||||||
|
return `<div class="${className}" data-index="${idx}">${prefix} ${idx + 1}. ${text}</div>`;
|
||||||
|
})
|
||||||
|
.join("");
|
||||||
|
|
||||||
|
this.adapter.printHTML(
|
||||||
|
`<div id="${this.optionsContainerId}" class="game-options">${optionsHTML}</div>`,
|
||||||
|
);
|
||||||
|
this.adapter.scrollToBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateOptionsDisplay() {
|
||||||
|
const container = document.getElementById(this.optionsContainerId);
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
const optionDivs = container.querySelectorAll("div");
|
||||||
|
optionDivs.forEach((div, idx) => {
|
||||||
|
const selected = idx === this.selectedIndex;
|
||||||
|
div.className = selected ? "game-option-selected" : "game-option";
|
||||||
|
const text =
|
||||||
|
typeof this.options[idx] === "string"
|
||||||
|
? this.options[idx]
|
||||||
|
: this.options[idx].text;
|
||||||
|
div.textContent = `${selected ? ">" : " "} ${idx + 1}. ${text}`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_selectPrevious() {
|
||||||
|
if (this.selectedIndex > 0) {
|
||||||
|
this.selectedIndex--;
|
||||||
|
this._updateOptionsDisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_selectNext() {
|
||||||
|
if (this.selectedIndex < this.options.length - 1) {
|
||||||
|
this.selectedIndex++;
|
||||||
|
this._updateOptionsDisplay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_confirmSelection() {
|
||||||
|
if (this.inputResolve) {
|
||||||
|
const res = this.inputResolve;
|
||||||
|
this.inputResolve = null;
|
||||||
|
|
||||||
|
// Show what was selected
|
||||||
|
const selectedOpt = this.options[this.selectedIndex];
|
||||||
|
const text =
|
||||||
|
typeof selectedOpt === "string" ? selectedOpt : selectedOpt.text;
|
||||||
|
this.adapter.print("");
|
||||||
|
this.adapter.printSuccess(`> ${text}`);
|
||||||
|
|
||||||
|
res(this.selectedIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if currently waiting for input
|
||||||
|
isWaiting() {
|
||||||
|
return this.mode !== "idle";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current mode
|
||||||
|
getMode() {
|
||||||
|
return this.mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cancel current input (for cleanup)
|
||||||
|
cancel() {
|
||||||
|
this.mode = "idle";
|
||||||
|
this.inputResolve = null;
|
||||||
|
this.adapter.releaseInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup when game ends
|
||||||
|
destroy() {
|
||||||
|
if (this.keydownHandler) {
|
||||||
|
document.removeEventListener("keydown", this.keydownHandler, true);
|
||||||
|
}
|
||||||
|
this.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
754
assets/js/games/engine/scene-manager.js
Normal file
754
assets/js/games/engine/scene-manager.js
Normal file
|
|
@ -0,0 +1,754 @@
|
||||||
|
// Scene Manager - Handles scene definitions, rendering, and transitions
|
||||||
|
class SceneManager {
|
||||||
|
constructor(adapter, stateManager, inputManager, soundManager = null) {
|
||||||
|
this.adapter = adapter;
|
||||||
|
this.state = stateManager;
|
||||||
|
this.input = inputManager;
|
||||||
|
this.sound = soundManager;
|
||||||
|
this.scenes = {};
|
||||||
|
this.currentScene = null;
|
||||||
|
this.sceneHistory = [];
|
||||||
|
this.activeSounds = new Map(); // Track sounds started in current scene
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register scenes from game definition
|
||||||
|
registerScenes(sceneDefinitions) {
|
||||||
|
for (const [id, scene] of Object.entries(sceneDefinitions)) {
|
||||||
|
this.scenes[id] = { id, ...scene };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get scene by ID
|
||||||
|
getScene(sceneId) {
|
||||||
|
return this.scenes[sceneId];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigate to a scene
|
||||||
|
async goTo(sceneId, options = {}) {
|
||||||
|
const scene = this.getScene(sceneId);
|
||||||
|
if (!scene) {
|
||||||
|
this.adapter.printError(`Scene not found: ${sceneId}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track history for back navigation
|
||||||
|
if (this.currentScene && !options.noHistory) {
|
||||||
|
this.sceneHistory.push(this.currentScene.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop scene-specific sounds from previous scene
|
||||||
|
await this._cleanupSceneSounds();
|
||||||
|
|
||||||
|
this.currentScene = scene;
|
||||||
|
|
||||||
|
// Preload sounds for this scene
|
||||||
|
if (this.sound && scene.sounds) {
|
||||||
|
await this._preloadSceneSounds(scene.sounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute onEnter actions
|
||||||
|
if (scene.onEnter) {
|
||||||
|
await this._executeActions(scene.onEnter);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the scene
|
||||||
|
await this._renderScene(scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go back to previous scene
|
||||||
|
async goBack() {
|
||||||
|
if (this.sceneHistory.length === 0) {
|
||||||
|
this.adapter.printWarning("No previous scene");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const previousId = this.sceneHistory.pop();
|
||||||
|
await this.goTo(previousId, { noHistory: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render a scene
|
||||||
|
async _renderScene(scene) {
|
||||||
|
// Clear screen unless disabled
|
||||||
|
if (scene.clear !== false) {
|
||||||
|
this.adapter.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render title
|
||||||
|
if (scene.title) {
|
||||||
|
this.adapter.printHTML(
|
||||||
|
`<span class="game-scene-title">${scene.title}</span>`,
|
||||||
|
);
|
||||||
|
this.adapter.print("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render content blocks
|
||||||
|
if (scene.content) {
|
||||||
|
await this._renderContent(scene.content);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute onAfterRender actions (after content, before options)
|
||||||
|
if (scene.onAfterRender) {
|
||||||
|
await this._executeActions(scene.onAfterRender);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle navigation
|
||||||
|
if (scene.options) {
|
||||||
|
await this._handleOptions(scene);
|
||||||
|
} else if (scene.input) {
|
||||||
|
await this._handleTextInput(scene);
|
||||||
|
} else if (scene.next) {
|
||||||
|
// Auto-advance with optional delay
|
||||||
|
const delay = scene.delay || 0;
|
||||||
|
if (delay > 0) {
|
||||||
|
await this._sleep(delay);
|
||||||
|
}
|
||||||
|
await this.goTo(scene.next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render content blocks (supports conditional content)
|
||||||
|
async _renderContent(content) {
|
||||||
|
const blocks = Array.isArray(content) ? content : [content];
|
||||||
|
|
||||||
|
for (const block of blocks) {
|
||||||
|
// Simple string
|
||||||
|
if (typeof block === "string") {
|
||||||
|
this._printText(block);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conditional block
|
||||||
|
if (block.condition !== undefined) {
|
||||||
|
if (this.state.evaluate(block.condition)) {
|
||||||
|
if (block.content) {
|
||||||
|
await this._renderContent(block.content);
|
||||||
|
}
|
||||||
|
} else if (block.else) {
|
||||||
|
await this._renderContent(block.else);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Typed blocks
|
||||||
|
if (block.type === "ascii") {
|
||||||
|
this.adapter.print(block.art, block.className || "game-ascii");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block.type === "ansi") {
|
||||||
|
// Convert ANSI escape codes to HTML
|
||||||
|
const html = AnsiConverter.convertToBlock(
|
||||||
|
block.art,
|
||||||
|
block.className || "game-ansi-art",
|
||||||
|
);
|
||||||
|
this.adapter.printHTML(html);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block.type === "html") {
|
||||||
|
this.adapter.printHTML(block.html, block.className || "");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block.type === "delay") {
|
||||||
|
await this._sleep(block.ms || 1000);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block.type === "typewriter") {
|
||||||
|
await this._typewriter(block.text, block.speed || 50, {
|
||||||
|
bold: block.bold,
|
||||||
|
italic: block.italic,
|
||||||
|
className: block.className,
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block.type === "table") {
|
||||||
|
await this._renderTable(block);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block.type === "sound") {
|
||||||
|
await this._handleSound(block);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block.type === "glitch") {
|
||||||
|
await this._renderGlitch(block);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Text with optional className (supports html: true for HTML content)
|
||||||
|
if (block.text !== undefined) {
|
||||||
|
if (block.html) {
|
||||||
|
this._printHTML(block.text, block.className || "");
|
||||||
|
} else {
|
||||||
|
this._printText(block.text, block.className || "", {
|
||||||
|
bold: block.bold,
|
||||||
|
italic: block.italic,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print text with variable interpolation
|
||||||
|
_printText(text, className = "", options = {}) {
|
||||||
|
// Support ${path} interpolation
|
||||||
|
const interpolated = text.replace(/\$\{([^}]+)\}/g, (match, path) => {
|
||||||
|
const value = this.state.get(path);
|
||||||
|
return value !== undefined ? String(value) : match;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Build style classes based on options
|
||||||
|
let styleClasses = className;
|
||||||
|
if (options.bold)
|
||||||
|
styleClasses += (styleClasses ? " " : "") + "typewriter-bold";
|
||||||
|
if (options.italic)
|
||||||
|
styleClasses += (styleClasses ? " " : "") + "typewriter-italic";
|
||||||
|
|
||||||
|
if (styleClasses) {
|
||||||
|
this.adapter.print(interpolated, styleClasses);
|
||||||
|
} else {
|
||||||
|
this.adapter.print(interpolated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print HTML with variable interpolation
|
||||||
|
_printHTML(html, className = "") {
|
||||||
|
// Support ${path} interpolation
|
||||||
|
const interpolated = html.replace(/\$\{([^}]+)\}/g, (match, path) => {
|
||||||
|
const value = this.state.get(path);
|
||||||
|
return value !== undefined ? String(value) : match;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (className) {
|
||||||
|
this.adapter.printHTML(
|
||||||
|
`<span class="${className}">${interpolated}</span>`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.adapter.printHTML(interpolated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle options/choices
|
||||||
|
async _handleOptions(scene) {
|
||||||
|
// Filter options based on conditions
|
||||||
|
const availableOptions = scene.options.filter((opt) => {
|
||||||
|
if (opt.condition !== undefined) {
|
||||||
|
return this.state.evaluate(opt.condition);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (availableOptions.length === 0) {
|
||||||
|
if (scene.fallback) {
|
||||||
|
await this.goTo(scene.fallback);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = await this.input.awaitOption(
|
||||||
|
availableOptions.map((o) => ({
|
||||||
|
text: this._interpolateText(o.text),
|
||||||
|
value: o,
|
||||||
|
})),
|
||||||
|
scene.prompt || "What do you do?",
|
||||||
|
);
|
||||||
|
|
||||||
|
const selected = result.option.value;
|
||||||
|
|
||||||
|
// Execute option actions
|
||||||
|
if (selected.actions) {
|
||||||
|
await this._executeActions(selected.actions);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigate to next scene
|
||||||
|
if (selected.next) {
|
||||||
|
await this.goTo(selected.next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle text input
|
||||||
|
async _handleTextInput(scene) {
|
||||||
|
const inputDef = scene.input;
|
||||||
|
const value = await this.input.awaitText(inputDef.prompt);
|
||||||
|
|
||||||
|
// Store value if specified
|
||||||
|
if (inputDef.store) {
|
||||||
|
this.state.set(inputDef.store, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for pattern matches
|
||||||
|
if (inputDef.matches) {
|
||||||
|
for (const match of inputDef.matches) {
|
||||||
|
const pattern =
|
||||||
|
match.pattern instanceof RegExp
|
||||||
|
? match.pattern
|
||||||
|
: new RegExp(match.pattern, "i");
|
||||||
|
|
||||||
|
if (pattern.test(value)) {
|
||||||
|
if (match.actions) {
|
||||||
|
await this._executeActions(match.actions);
|
||||||
|
}
|
||||||
|
if (match.next) {
|
||||||
|
await this.goTo(match.next);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No match - use default
|
||||||
|
if (inputDef.default) {
|
||||||
|
if (inputDef.default.actions) {
|
||||||
|
await this._executeActions(inputDef.default.actions);
|
||||||
|
}
|
||||||
|
if (inputDef.default.next) {
|
||||||
|
await this.goTo(inputDef.default.next);
|
||||||
|
}
|
||||||
|
} else if (inputDef.next) {
|
||||||
|
await this.goTo(inputDef.next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute action commands
|
||||||
|
async _executeActions(actions) {
|
||||||
|
const actionList = Array.isArray(actions) ? actions : [actions];
|
||||||
|
|
||||||
|
for (const action of actionList) {
|
||||||
|
if (action.set !== undefined) {
|
||||||
|
this.state.set(action.set, action.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set value in shared state (for series games)
|
||||||
|
if (action.setShared !== undefined) {
|
||||||
|
this.state.setShared(action.setShared, action.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark a chapter as complete in shared state
|
||||||
|
if (action.markChapterComplete !== undefined) {
|
||||||
|
const sharedState = this.state.getSharedState();
|
||||||
|
if (sharedState) {
|
||||||
|
sharedState.markChapterComplete(action.markChapterComplete);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.increment !== undefined) {
|
||||||
|
this.state.increment(action.increment, action.amount || 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.decrement !== undefined) {
|
||||||
|
this.state.decrement(action.decrement, action.amount || 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.addItem !== undefined) {
|
||||||
|
this.state.addToArray(action.to || "inventory", action.addItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.removeItem !== undefined) {
|
||||||
|
this.state.removeFromArray(
|
||||||
|
action.from || "inventory",
|
||||||
|
action.removeItem,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.print !== undefined) {
|
||||||
|
this._printText(action.print, action.className || "");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.printSuccess !== undefined) {
|
||||||
|
this.adapter.printSuccess(this._interpolateText(action.printSuccess));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.printError !== undefined) {
|
||||||
|
this.adapter.printError(this._interpolateText(action.printError));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.printWarning !== undefined) {
|
||||||
|
this.adapter.printWarning(this._interpolateText(action.printWarning));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.printInfo !== undefined) {
|
||||||
|
this.adapter.printInfo(this._interpolateText(action.printInfo));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.delay !== undefined) {
|
||||||
|
await this._sleep(action.delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.goTo !== undefined) {
|
||||||
|
await this.goTo(action.goTo);
|
||||||
|
return; // Stop processing further actions after navigation
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action.callback && typeof action.callback === "function") {
|
||||||
|
await action.callback(this.state, this.adapter, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interpolate variables in text
|
||||||
|
_interpolateText(text) {
|
||||||
|
if (typeof text !== "string") return text;
|
||||||
|
return text.replace(/\$\{([^}]+)\}/g, (match, path) => {
|
||||||
|
const value = this.state.get(path);
|
||||||
|
return value !== undefined ? String(value) : match;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Typewriter effect
|
||||||
|
async _typewriter(text, speed, options = {}) {
|
||||||
|
const interpolated = this._interpolateText(text);
|
||||||
|
let output = "";
|
||||||
|
|
||||||
|
// Build style classes based on options
|
||||||
|
let styleClasses = "typewriter-line";
|
||||||
|
if (options.bold) styleClasses += " typewriter-bold";
|
||||||
|
if (options.italic) styleClasses += " typewriter-italic";
|
||||||
|
if (options.className) styleClasses += " " + options.className;
|
||||||
|
|
||||||
|
for (const char of interpolated) {
|
||||||
|
output += char;
|
||||||
|
// Create a single updating line for typewriter
|
||||||
|
const typewriterSpan =
|
||||||
|
this.adapter.terminal.output.querySelector(".typewriter-line");
|
||||||
|
|
||||||
|
if (typewriterSpan) {
|
||||||
|
typewriterSpan.textContent = output;
|
||||||
|
} else {
|
||||||
|
this.adapter.printHTML(
|
||||||
|
`<span class="${styleClasses}">${output}</span>`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.adapter.scrollToBottom();
|
||||||
|
await this._sleep(speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finalize the line - remove the typewriter-line class so future typewriters create new lines
|
||||||
|
const typewriterSpan =
|
||||||
|
this.adapter.terminal.output.querySelector(".typewriter-line");
|
||||||
|
if (typewriterSpan) {
|
||||||
|
typewriterSpan.classList.remove("typewriter-line");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_sleep(ms) {
|
||||||
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render a dynamic table with conditional row support
|
||||||
|
async _renderTable(block) {
|
||||||
|
// Filter rows based on conditions
|
||||||
|
const filteredRows = [];
|
||||||
|
for (const row of block.rows || []) {
|
||||||
|
// Row can be: array of cells, or object with { cells, condition, className }
|
||||||
|
if (Array.isArray(row)) {
|
||||||
|
// Simple row - array of cells
|
||||||
|
filteredRows.push(row);
|
||||||
|
} else if (row.condition !== undefined) {
|
||||||
|
// Conditional row
|
||||||
|
if (this.state.evaluate(row.condition)) {
|
||||||
|
filteredRows.push(this._processTableRow(row));
|
||||||
|
}
|
||||||
|
} else if (row.cells) {
|
||||||
|
// Object row without condition
|
||||||
|
filteredRows.push(this._processTableRow(row));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build table using TableHelper
|
||||||
|
const tableOutput = TableHelper.table({
|
||||||
|
title: block.title ? this._interpolateText(block.title) : undefined,
|
||||||
|
headers: block.headers,
|
||||||
|
rows: filteredRows,
|
||||||
|
widths: block.widths,
|
||||||
|
align: block.align,
|
||||||
|
style: block.style || "single",
|
||||||
|
padding: block.padding,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Render each line of the table
|
||||||
|
for (const line of tableOutput) {
|
||||||
|
if (typeof line === "string") {
|
||||||
|
this._printText(line);
|
||||||
|
} else if (line.text) {
|
||||||
|
this._printText(line.text, line.className || "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process a table row object into cell array format for TableHelper
|
||||||
|
_processTableRow(row) {
|
||||||
|
// If row has className, apply it to cells that don't have their own
|
||||||
|
const cells = row.cells.map((cell) => {
|
||||||
|
if (typeof cell === "string" && row.className) {
|
||||||
|
return { text: this._interpolateText(cell), className: row.className };
|
||||||
|
} else if (typeof cell === "object" && cell.text) {
|
||||||
|
return {
|
||||||
|
text: this._interpolateText(cell.text),
|
||||||
|
className: cell.className || row.className,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return typeof cell === "string" ? this._interpolateText(cell) : cell;
|
||||||
|
});
|
||||||
|
return cells;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current scene ID
|
||||||
|
getCurrentSceneId() {
|
||||||
|
return this.currentScene ? this.currentScene.id : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset scene history
|
||||||
|
resetHistory() {
|
||||||
|
this.sceneHistory = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preload sounds for a scene
|
||||||
|
async _preloadSceneSounds(sounds) {
|
||||||
|
if (!this.sound) return;
|
||||||
|
|
||||||
|
const soundList = Array.isArray(sounds) ? sounds : [sounds];
|
||||||
|
let hasShownLoading = false;
|
||||||
|
|
||||||
|
for (const soundDef of soundList) {
|
||||||
|
const soundId = soundDef.id;
|
||||||
|
const url = soundDef.url || soundDef.src;
|
||||||
|
|
||||||
|
if (!soundId || !url) {
|
||||||
|
console.warn("Invalid sound definition:", soundDef);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip if already loaded
|
||||||
|
if (this.sound.isLoaded(soundId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show loading indicator if not shown yet
|
||||||
|
if (!hasShownLoading) {
|
||||||
|
this.adapter.printHTML(
|
||||||
|
'<span class="sound-loading info">Loading audio...</span>',
|
||||||
|
);
|
||||||
|
hasShownLoading = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.sound.preload(soundId, url);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Failed to preload sound ${soundId}:`, error);
|
||||||
|
// Continue loading other sounds even if one fails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove loading indicator
|
||||||
|
if (hasShownLoading) {
|
||||||
|
const indicator =
|
||||||
|
this.adapter.terminal.output.querySelector(".sound-loading");
|
||||||
|
if (indicator) {
|
||||||
|
indicator.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle sound playback in content blocks
|
||||||
|
async _handleSound(block) {
|
||||||
|
if (!this.sound) {
|
||||||
|
console.warn("Sound manager not available");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const action = block.action || "play"; // play, stop, stopAll
|
||||||
|
const soundId = block.id || block.sound;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (action === "play") {
|
||||||
|
const options = {
|
||||||
|
loop: block.loop || false,
|
||||||
|
volume: block.volume !== undefined ? block.volume : 1.0,
|
||||||
|
fade: block.fade || false,
|
||||||
|
fadeDuration: block.fadeDuration || 1000,
|
||||||
|
};
|
||||||
|
|
||||||
|
const controller = await this.sound.play(soundId, options);
|
||||||
|
|
||||||
|
// Store reference for cleanup unless it's a one-shot sound
|
||||||
|
if (block.loop || block.persist) {
|
||||||
|
this.activeSounds.set(soundId, controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-stop after duration if specified
|
||||||
|
if (block.duration) {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (block.fadeOut !== false) {
|
||||||
|
controller.fadeOut(block.fadeDuration || 1000);
|
||||||
|
} else {
|
||||||
|
controller.stop();
|
||||||
|
}
|
||||||
|
}, block.duration);
|
||||||
|
}
|
||||||
|
} else if (action === "stop") {
|
||||||
|
const controller = this.activeSounds.get(soundId);
|
||||||
|
if (controller) {
|
||||||
|
if (block.fadeOut !== false) {
|
||||||
|
await controller.fadeOut(block.fadeDuration || 1000);
|
||||||
|
} else {
|
||||||
|
controller.stop();
|
||||||
|
}
|
||||||
|
this.activeSounds.delete(soundId);
|
||||||
|
}
|
||||||
|
} else if (action === "stopAll") {
|
||||||
|
await this._cleanupSceneSounds();
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Sound error (${action} ${soundId}):`, error);
|
||||||
|
// Don't show error to user, just log it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up sounds when leaving a scene
|
||||||
|
async _cleanupSceneSounds() {
|
||||||
|
if (!this.sound) return;
|
||||||
|
|
||||||
|
const fadePromises = [];
|
||||||
|
|
||||||
|
for (const [, controller] of this.activeSounds) {
|
||||||
|
if (controller.fadeOut) {
|
||||||
|
fadePromises.push(
|
||||||
|
controller.fadeOut(500).catch((e) => console.error("Fade error:", e)),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
controller.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for all fades to complete
|
||||||
|
await Promise.all(fadePromises);
|
||||||
|
this.activeSounds.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render glitching text effect
|
||||||
|
async _renderGlitch(block) {
|
||||||
|
const text = this._interpolateText(block.text || "");
|
||||||
|
const intensity = block.intensity || 0.3; // How much glitch (0-1)
|
||||||
|
const spread = block.spread || 2; // How many lines above/below to infect
|
||||||
|
const speed = block.speed || 50; // Animation speed in ms
|
||||||
|
const duration = block.duration || 2000; // How long the glitch lasts
|
||||||
|
const className = block.className || "glitch-text";
|
||||||
|
|
||||||
|
// Glitch character pool - mix of unicode, symbols, and corrupted chars
|
||||||
|
const glitchChars = [
|
||||||
|
"▓", "▒", "░", "█", "▀", "▄", "▌", "▐", "║", "╬", "╣", "╠",
|
||||||
|
"¡", "¿", "‽", "※", "§", "¶", "†", "‡", "∞", "≈", "≠", "±",
|
||||||
|
"░", "▒", "▓", "█", "▀", "▄", "▌", "▐", "╔", "╗", "╚", "╝",
|
||||||
|
"Ω", "∑", "∏", "∫", "√", "∂", "∆", "∇", "∈", "∉", "∩", "∪",
|
||||||
|
"̴", "̵", "̶", "̷", "̸", "̡", "̢", "̧", "̨", "̛", "̖", "̗",
|
||||||
|
"É", "È", "Ê", "Ë", "Á", "À", "Â", "Ã", "Ä", "Å", "Æ", "Ç",
|
||||||
|
"Ñ", "Õ", "Ö", "Ø", "Ú", "Ù", "Û", "Ü", "Ý", "Þ", "ß", "ð",
|
||||||
|
"!", "@", "#", "$", "%", "^", "&", "*", "?", "~", "`", "|"
|
||||||
|
];
|
||||||
|
|
||||||
|
// Generate the glitched text
|
||||||
|
const generateGlitch = (baseText, glitchAmount) => {
|
||||||
|
let result = "";
|
||||||
|
for (let i = 0; i < baseText.length; i++) {
|
||||||
|
if (Math.random() < glitchAmount && baseText[i] !== " ") {
|
||||||
|
// Replace character with glitch
|
||||||
|
result += glitchChars[Math.floor(Math.random() * glitchChars.length)];
|
||||||
|
} else {
|
||||||
|
result += baseText[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Generate random glitch lines that "infect" surrounding area
|
||||||
|
const generateInfectionLines = (baseLength) => {
|
||||||
|
const lines = [];
|
||||||
|
for (let i = 0; i < spread; i++) {
|
||||||
|
const lineLength = Math.floor(baseLength * Math.random() * 0.7);
|
||||||
|
const offset = Math.floor(Math.random() * baseLength * 0.3);
|
||||||
|
const glitchLine = " ".repeat(offset) +
|
||||||
|
Array.from({ length: lineLength }, () =>
|
||||||
|
glitchChars[Math.floor(Math.random() * glitchChars.length)]
|
||||||
|
).join("");
|
||||||
|
lines.push(glitchLine);
|
||||||
|
}
|
||||||
|
return lines;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create container for animated glitch
|
||||||
|
const containerId = `glitch-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
|
||||||
|
this.adapter.printHTML(
|
||||||
|
`<div id="${containerId}" class="${className}"></div>`
|
||||||
|
);
|
||||||
|
|
||||||
|
const container = this.adapter.terminal.output.querySelector(`#${containerId}`);
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
// Animation loop
|
||||||
|
const startTime = Date.now();
|
||||||
|
let finalLinesAbove = [];
|
||||||
|
let finalLinesBelow = [];
|
||||||
|
|
||||||
|
const animate = () => {
|
||||||
|
const elapsed = Date.now() - startTime;
|
||||||
|
|
||||||
|
if (elapsed >= duration) {
|
||||||
|
// Final state - show original text with minimal glitch, keep infection lines
|
||||||
|
const finalGlitch = generateGlitch(text, intensity * 0.1);
|
||||||
|
|
||||||
|
let output = "";
|
||||||
|
finalLinesAbove.forEach(line => {
|
||||||
|
output += `<div class="glitch-line glitch-above">${line}</div>`;
|
||||||
|
});
|
||||||
|
output += `<div class="glitch-line glitch-main">${finalGlitch}</div>`;
|
||||||
|
finalLinesBelow.forEach(line => {
|
||||||
|
output += `<div class="glitch-line glitch-below">${line}</div>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
container.innerHTML = output;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Current glitch intensity (ramps up then down)
|
||||||
|
const progress = elapsed / duration;
|
||||||
|
const currentIntensity = intensity * Math.sin(progress * Math.PI);
|
||||||
|
|
||||||
|
// Generate infected lines above
|
||||||
|
const linesAbove = generateInfectionLines(text.length);
|
||||||
|
const linesBelow = generateInfectionLines(text.length);
|
||||||
|
|
||||||
|
// Store for final state
|
||||||
|
finalLinesAbove = linesAbove;
|
||||||
|
finalLinesBelow = linesBelow;
|
||||||
|
|
||||||
|
// Generate glitched main text
|
||||||
|
const glitchedText = generateGlitch(text, currentIntensity);
|
||||||
|
|
||||||
|
// Build output
|
||||||
|
let output = "";
|
||||||
|
linesAbove.forEach(line => {
|
||||||
|
output += `<div class="glitch-line glitch-above">${line}</div>`;
|
||||||
|
});
|
||||||
|
output += `<div class="glitch-line glitch-main">${glitchedText}</div>`;
|
||||||
|
linesBelow.forEach(line => {
|
||||||
|
output += `<div class="glitch-line glitch-below">${line}</div>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
container.innerHTML = output;
|
||||||
|
|
||||||
|
// Continue animation
|
||||||
|
setTimeout(animate, speed);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Start animation
|
||||||
|
animate();
|
||||||
|
|
||||||
|
// Wait for animation to complete
|
||||||
|
await this._sleep(duration);
|
||||||
|
}
|
||||||
|
}
|
||||||
66
assets/js/games/engine/scene-registry.js
Normal file
66
assets/js/games/engine/scene-registry.js
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
// Scene Registry - Global registry for shared scene factories
|
||||||
|
// Scene factories are functions that take a context and return scene definitions
|
||||||
|
|
||||||
|
// Initialize global scene factories object
|
||||||
|
window.SceneFactories = window.SceneFactories || {};
|
||||||
|
|
||||||
|
// Helper class for working with scene factories
|
||||||
|
class SceneRegistry {
|
||||||
|
// Register a scene factory
|
||||||
|
static register(id, factory) {
|
||||||
|
if (typeof factory !== "function") {
|
||||||
|
console.error(`Scene factory must be a function: ${id}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
window.SceneFactories[id] = factory;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a scene factory
|
||||||
|
static get(id) {
|
||||||
|
return window.SceneFactories[id] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a factory exists
|
||||||
|
static has(id) {
|
||||||
|
return id in window.SceneFactories;
|
||||||
|
}
|
||||||
|
|
||||||
|
// List all registered factories
|
||||||
|
static list() {
|
||||||
|
return Object.keys(window.SceneFactories);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unregister a factory
|
||||||
|
static unregister(id) {
|
||||||
|
delete window.SceneFactories[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create scenes from a factory with context
|
||||||
|
static createScenes(id, context) {
|
||||||
|
const factory = this.get(id);
|
||||||
|
if (!factory) {
|
||||||
|
console.warn(`Scene factory not found: ${id}`);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return factory(context);
|
||||||
|
} catch (e) {
|
||||||
|
console.error(`Error creating scenes from factory ${id}:`, e);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge multiple factories into one scene object
|
||||||
|
static mergeFactories(factoryIds, context) {
|
||||||
|
const merged = {};
|
||||||
|
for (const id of factoryIds) {
|
||||||
|
const scenes = this.createScenes(id, context);
|
||||||
|
Object.assign(merged, scenes);
|
||||||
|
}
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make available globally
|
||||||
|
window.SceneRegistry = SceneRegistry;
|
||||||
190
assets/js/games/engine/shared-state-manager.js
Normal file
190
assets/js/games/engine/shared-state-manager.js
Normal file
|
|
@ -0,0 +1,190 @@
|
||||||
|
// Shared State Manager - Manages game state across multiple chapters in a series
|
||||||
|
class SharedStateManager {
|
||||||
|
constructor(seriesId) {
|
||||||
|
this.seriesId = seriesId;
|
||||||
|
this.state = {};
|
||||||
|
this.storageKey = `series_${seriesId}_state`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize with default state (only sets values not already in storage)
|
||||||
|
init(defaultState = {}) {
|
||||||
|
this.state = this._deepClone(defaultState);
|
||||||
|
this._loadFromStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get value using dot notation path (e.g., "inventory.sword")
|
||||||
|
get(path, defaultValue = undefined) {
|
||||||
|
const parts = path.split(".");
|
||||||
|
let current = this.state;
|
||||||
|
|
||||||
|
for (const part of parts) {
|
||||||
|
if (current === undefined || current === null) {
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
current = current[part];
|
||||||
|
}
|
||||||
|
|
||||||
|
return current !== undefined ? current : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set value using dot notation path
|
||||||
|
set(path, value) {
|
||||||
|
const parts = path.split(".");
|
||||||
|
let current = this.state;
|
||||||
|
|
||||||
|
for (let i = 0; i < parts.length - 1; i++) {
|
||||||
|
const part = parts[i];
|
||||||
|
if (current[part] === undefined) {
|
||||||
|
current[part] = {};
|
||||||
|
}
|
||||||
|
current = current[part];
|
||||||
|
}
|
||||||
|
|
||||||
|
current[parts[parts.length - 1]] = value;
|
||||||
|
this._saveToStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment a numeric value
|
||||||
|
increment(path, amount = 1) {
|
||||||
|
const current = this.get(path, 0);
|
||||||
|
this.set(path, current + amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrement a numeric value
|
||||||
|
decrement(path, amount = 1) {
|
||||||
|
this.increment(path, -amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add item to an array (if not already present)
|
||||||
|
addToArray(path, item) {
|
||||||
|
const arr = this.get(path, []);
|
||||||
|
if (!arr.includes(item)) {
|
||||||
|
arr.push(item);
|
||||||
|
this.set(path, arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove item from an array
|
||||||
|
removeFromArray(path, item) {
|
||||||
|
const arr = this.get(path, []);
|
||||||
|
const index = arr.indexOf(item);
|
||||||
|
if (index > -1) {
|
||||||
|
arr.splice(index, 1);
|
||||||
|
this.set(path, arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if array contains item
|
||||||
|
hasItem(path, item) {
|
||||||
|
const arr = this.get(path, []);
|
||||||
|
return arr.includes(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a specific chapter is complete
|
||||||
|
isChapterComplete(chapterNumber) {
|
||||||
|
const completed = this.get("chapters_completed", []);
|
||||||
|
return completed.includes(chapterNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark a chapter as complete
|
||||||
|
markChapterComplete(chapterNumber) {
|
||||||
|
this.addToArray("chapters_completed", chapterNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if chapter can be played (previous chapters complete)
|
||||||
|
canPlayChapter(chapterNumber) {
|
||||||
|
if (chapterNumber <= 1) return true;
|
||||||
|
return this.isChapterComplete(chapterNumber - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the highest completed chapter number
|
||||||
|
getHighestCompletedChapter() {
|
||||||
|
const completed = this.get("chapters_completed", []);
|
||||||
|
return completed.length > 0 ? Math.max(...completed) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get entire state (for debugging)
|
||||||
|
getAll() {
|
||||||
|
return this._deepClone(this.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset all series state
|
||||||
|
reset() {
|
||||||
|
this.state = {};
|
||||||
|
try {
|
||||||
|
localStorage.removeItem(this.storageKey);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Failed to clear series state from storage:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there is saved state
|
||||||
|
hasSavedState() {
|
||||||
|
try {
|
||||||
|
return localStorage.getItem(this.storageKey) !== null;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Export state for debugging or backup
|
||||||
|
exportState() {
|
||||||
|
return JSON.stringify(this.state, null, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Import state from backup
|
||||||
|
importState(jsonString) {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(jsonString);
|
||||||
|
this.state = data;
|
||||||
|
this._saveToStorage();
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to import state:", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_saveToStorage() {
|
||||||
|
try {
|
||||||
|
localStorage.setItem(this.storageKey, JSON.stringify(this.state));
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Failed to save series state:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadFromStorage() {
|
||||||
|
try {
|
||||||
|
const saved = localStorage.getItem(this.storageKey);
|
||||||
|
if (saved) {
|
||||||
|
const parsed = JSON.parse(saved);
|
||||||
|
this.state = this._mergeDeep(this.state, parsed);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Failed to load series state:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_deepClone(obj) {
|
||||||
|
return JSON.parse(JSON.stringify(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
_mergeDeep(target, source) {
|
||||||
|
const result = { ...target };
|
||||||
|
for (const key of Object.keys(source)) {
|
||||||
|
if (
|
||||||
|
source[key] &&
|
||||||
|
typeof source[key] === "object" &&
|
||||||
|
!Array.isArray(source[key])
|
||||||
|
) {
|
||||||
|
result[key] = this._mergeDeep(result[key] || {}, source[key]);
|
||||||
|
} else {
|
||||||
|
result[key] = source[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make available globally
|
||||||
|
window.SharedStateManager = SharedStateManager;
|
||||||
247
assets/js/games/engine/sound-manager.js
Normal file
247
assets/js/games/engine/sound-manager.js
Normal file
|
|
@ -0,0 +1,247 @@
|
||||||
|
// Sound Manager - Handles audio loading, caching, and playback for games
|
||||||
|
class SoundManager {
|
||||||
|
constructor(adapter) {
|
||||||
|
this.adapter = adapter;
|
||||||
|
this.sounds = new Map(); // soundId -> { audio, loaded, loading, error }
|
||||||
|
this.currentlyPlaying = new Set(); // Track currently playing sounds
|
||||||
|
this.globalVolume = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preload a sound file
|
||||||
|
async preload(soundId, url) {
|
||||||
|
// If already loaded or loading, return existing promise
|
||||||
|
if (this.sounds.has(soundId)) {
|
||||||
|
const sound = this.sounds.get(soundId);
|
||||||
|
if (sound.loaded) {
|
||||||
|
return sound.audio;
|
||||||
|
}
|
||||||
|
if (sound.loading) {
|
||||||
|
return sound.loadingPromise;
|
||||||
|
}
|
||||||
|
if (sound.error) {
|
||||||
|
throw new Error(`Sound ${soundId} failed to load: ${sound.error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new audio element
|
||||||
|
const audio = new Audio();
|
||||||
|
const soundEntry = {
|
||||||
|
audio,
|
||||||
|
loaded: false,
|
||||||
|
loading: true,
|
||||||
|
error: null,
|
||||||
|
url,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create promise for loading
|
||||||
|
const loadingPromise = new Promise((resolve, reject) => {
|
||||||
|
const onLoad = () => {
|
||||||
|
soundEntry.loaded = true;
|
||||||
|
soundEntry.loading = false;
|
||||||
|
audio.removeEventListener("canplaythrough", onLoad);
|
||||||
|
audio.removeEventListener("error", onError);
|
||||||
|
resolve(audio);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onError = (e) => {
|
||||||
|
soundEntry.loading = false;
|
||||||
|
soundEntry.error = e.message || "Failed to load audio";
|
||||||
|
audio.removeEventListener("canplaythrough", onLoad);
|
||||||
|
audio.removeEventListener("error", onError);
|
||||||
|
reject(new Error(`Failed to load sound ${soundId}: ${soundEntry.error}`));
|
||||||
|
};
|
||||||
|
|
||||||
|
audio.addEventListener("canplaythrough", onLoad, { once: true });
|
||||||
|
audio.addEventListener("error", onError, { once: true });
|
||||||
|
audio.preload = "auto";
|
||||||
|
audio.src = url;
|
||||||
|
audio.load();
|
||||||
|
});
|
||||||
|
|
||||||
|
soundEntry.loadingPromise = loadingPromise;
|
||||||
|
this.sounds.set(soundId, soundEntry);
|
||||||
|
|
||||||
|
return loadingPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Play a sound (will load if not already loaded)
|
||||||
|
async play(soundId, options = {}) {
|
||||||
|
const {
|
||||||
|
loop = false,
|
||||||
|
volume = 1.0,
|
||||||
|
onEnd = null,
|
||||||
|
fade = false,
|
||||||
|
fadeDuration = 1000,
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
let soundEntry = this.sounds.get(soundId);
|
||||||
|
|
||||||
|
if (!soundEntry) {
|
||||||
|
throw new Error(`Sound ${soundId} not preloaded. Use preload() first.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for loading if still loading
|
||||||
|
if (soundEntry.loading) {
|
||||||
|
await soundEntry.loadingPromise;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (soundEntry.error) {
|
||||||
|
throw new Error(`Sound ${soundId} failed to load: ${soundEntry.error}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const audio = soundEntry.audio;
|
||||||
|
|
||||||
|
// Clone the audio element for concurrent playback
|
||||||
|
const playInstance = audio.cloneNode();
|
||||||
|
playInstance.loop = loop;
|
||||||
|
playInstance.volume = fade ? 0 : volume * this.globalVolume;
|
||||||
|
|
||||||
|
// Track this instance
|
||||||
|
const trackingId = `${soundId}_${Date.now()}`;
|
||||||
|
this.currentlyPlaying.add(trackingId);
|
||||||
|
|
||||||
|
// Handle end event
|
||||||
|
const cleanup = () => {
|
||||||
|
this.currentlyPlaying.delete(trackingId);
|
||||||
|
playInstance.removeEventListener("ended", cleanup);
|
||||||
|
if (onEnd) onEnd();
|
||||||
|
};
|
||||||
|
|
||||||
|
playInstance.addEventListener("ended", cleanup);
|
||||||
|
|
||||||
|
// Play the sound
|
||||||
|
try {
|
||||||
|
await playInstance.play();
|
||||||
|
|
||||||
|
// Fade in if requested
|
||||||
|
if (fade) {
|
||||||
|
this._fadeIn(playInstance, volume * this.globalVolume, fadeDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
instance: playInstance,
|
||||||
|
stop: () => {
|
||||||
|
playInstance.pause();
|
||||||
|
playInstance.currentTime = 0;
|
||||||
|
cleanup();
|
||||||
|
},
|
||||||
|
fadeOut: (duration = fadeDuration) => {
|
||||||
|
return this._fadeOut(playInstance, duration).then(() => {
|
||||||
|
playInstance.pause();
|
||||||
|
cleanup();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
cleanup();
|
||||||
|
throw new Error(`Failed to play sound ${soundId}: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fade in audio
|
||||||
|
_fadeIn(audio, targetVolume, duration) {
|
||||||
|
const steps = 20;
|
||||||
|
const stepDuration = duration / steps;
|
||||||
|
const volumeStep = targetVolume / steps;
|
||||||
|
let currentStep = 0;
|
||||||
|
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
currentStep++;
|
||||||
|
audio.volume = Math.min(volumeStep * currentStep, targetVolume);
|
||||||
|
|
||||||
|
if (currentStep >= steps) {
|
||||||
|
clearInterval(interval);
|
||||||
|
audio.volume = targetVolume;
|
||||||
|
}
|
||||||
|
}, stepDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fade out audio
|
||||||
|
_fadeOut(audio, duration) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const steps = 20;
|
||||||
|
const stepDuration = duration / steps;
|
||||||
|
const startVolume = audio.volume;
|
||||||
|
const volumeStep = startVolume / steps;
|
||||||
|
let currentStep = 0;
|
||||||
|
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
currentStep++;
|
||||||
|
audio.volume = Math.max(startVolume - volumeStep * currentStep, 0);
|
||||||
|
|
||||||
|
if (currentStep >= steps) {
|
||||||
|
clearInterval(interval);
|
||||||
|
audio.volume = 0;
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}, stepDuration);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop all currently playing sounds
|
||||||
|
stopAll() {
|
||||||
|
for (const soundId of Array.from(this.currentlyPlaying)) {
|
||||||
|
const [id] = soundId.split("_");
|
||||||
|
const soundEntry = this.sounds.get(id);
|
||||||
|
if (soundEntry && soundEntry.audio) {
|
||||||
|
soundEntry.audio.pause();
|
||||||
|
soundEntry.audio.currentTime = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.currentlyPlaying.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set global volume (0.0 to 1.0)
|
||||||
|
setGlobalVolume(volume) {
|
||||||
|
this.globalVolume = Math.max(0, Math.min(1, volume));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a sound is loaded
|
||||||
|
isLoaded(soundId) {
|
||||||
|
const sound = this.sounds.get(soundId);
|
||||||
|
return sound && sound.loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a sound is currently loading
|
||||||
|
isLoading(soundId) {
|
||||||
|
const sound = this.sounds.get(soundId);
|
||||||
|
return sound && sound.loading;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get loading progress for all sounds
|
||||||
|
getLoadingStatus() {
|
||||||
|
const status = {
|
||||||
|
total: this.sounds.size,
|
||||||
|
loaded: 0,
|
||||||
|
loading: 0,
|
||||||
|
failed: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const [, sound] of this.sounds) {
|
||||||
|
if (sound.loaded) status.loaded++;
|
||||||
|
else if (sound.loading) status.loading++;
|
||||||
|
else if (sound.error) status.failed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear all sounds (useful for cleanup)
|
||||||
|
clear() {
|
||||||
|
this.stopAll();
|
||||||
|
this.sounds.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove a specific sound from cache
|
||||||
|
unload(soundId) {
|
||||||
|
const sound = this.sounds.get(soundId);
|
||||||
|
if (sound && sound.audio) {
|
||||||
|
sound.audio.pause();
|
||||||
|
sound.audio.src = "";
|
||||||
|
}
|
||||||
|
this.sounds.delete(soundId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make available globally
|
||||||
|
window.SoundManager = SoundManager;
|
||||||
248
assets/js/games/engine/state-manager.js
Normal file
248
assets/js/games/engine/state-manager.js
Normal file
|
|
@ -0,0 +1,248 @@
|
||||||
|
// State Manager - Manages game state with persistence and conditions
|
||||||
|
class StateManager {
|
||||||
|
constructor(gameId, sharedState = null) {
|
||||||
|
this.gameId = gameId;
|
||||||
|
this.sharedState = sharedState; // Optional SharedStateManager for series games
|
||||||
|
this.state = {};
|
||||||
|
this.storageKey = `game_${gameId}_state`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize with default state
|
||||||
|
init(defaultState = {}) {
|
||||||
|
this.state = this._deepClone(defaultState);
|
||||||
|
this._loadFromStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get value using dot notation path (e.g., "inventory.sword")
|
||||||
|
// Checks local state first, then falls back to shared state if available
|
||||||
|
get(path, defaultValue = undefined) {
|
||||||
|
// First check local state
|
||||||
|
const localValue = this._getFromState(this.state, path);
|
||||||
|
if (localValue !== undefined) {
|
||||||
|
return localValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to shared state if available
|
||||||
|
if (this.sharedState) {
|
||||||
|
const sharedValue = this.sharedState.get(path);
|
||||||
|
if (sharedValue !== undefined) {
|
||||||
|
return sharedValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal helper to get value from a specific state object
|
||||||
|
_getFromState(stateObj, path) {
|
||||||
|
const parts = path.split(".");
|
||||||
|
let current = stateObj;
|
||||||
|
|
||||||
|
for (const part of parts) {
|
||||||
|
if (current === undefined || current === null) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
current = current[part];
|
||||||
|
}
|
||||||
|
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set value using dot notation path
|
||||||
|
set(path, value) {
|
||||||
|
const parts = path.split(".");
|
||||||
|
let current = this.state;
|
||||||
|
|
||||||
|
for (let i = 0; i < parts.length - 1; i++) {
|
||||||
|
const part = parts[i];
|
||||||
|
if (current[part] === undefined) {
|
||||||
|
current[part] = {};
|
||||||
|
}
|
||||||
|
current = current[part];
|
||||||
|
}
|
||||||
|
|
||||||
|
current[parts[parts.length - 1]] = value;
|
||||||
|
this._saveToStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment a numeric value
|
||||||
|
increment(path, amount = 1) {
|
||||||
|
const current = this.get(path, 0);
|
||||||
|
this.set(path, current + amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrement a numeric value
|
||||||
|
decrement(path, amount = 1) {
|
||||||
|
this.increment(path, -amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add item to an array (if not already present)
|
||||||
|
addToArray(path, item) {
|
||||||
|
const arr = this.get(path, []);
|
||||||
|
if (!arr.includes(item)) {
|
||||||
|
arr.push(item);
|
||||||
|
this.set(path, arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove item from an array
|
||||||
|
removeFromArray(path, item) {
|
||||||
|
const arr = this.get(path, []);
|
||||||
|
const index = arr.indexOf(item);
|
||||||
|
if (index > -1) {
|
||||||
|
arr.splice(index, 1);
|
||||||
|
this.set(path, arr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if array contains item
|
||||||
|
hasItem(path, item) {
|
||||||
|
const arr = this.get(path, []);
|
||||||
|
return arr.includes(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set value in shared state (for series games)
|
||||||
|
setShared(path, value) {
|
||||||
|
if (!this.sharedState) {
|
||||||
|
console.warn("No shared state manager - setting locally instead");
|
||||||
|
return this.set(path, value);
|
||||||
|
}
|
||||||
|
this.sharedState.set(path, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if path exists in shared state
|
||||||
|
hasShared(path) {
|
||||||
|
return this.sharedState?.get(path) !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get reference to shared state manager
|
||||||
|
getSharedState() {
|
||||||
|
return this.sharedState;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate a condition against current state
|
||||||
|
evaluate(condition) {
|
||||||
|
if (typeof condition === "boolean") {
|
||||||
|
return condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof condition === "string") {
|
||||||
|
// Simple path check - truthy value
|
||||||
|
return !!this.get(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof condition === "object" && condition !== null) {
|
||||||
|
return this._evaluateConditionObject(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_evaluateConditionObject(cond) {
|
||||||
|
// Logical operators
|
||||||
|
if (cond.and) {
|
||||||
|
return cond.and.every((c) => this.evaluate(c));
|
||||||
|
}
|
||||||
|
if (cond.or) {
|
||||||
|
return cond.or.some((c) => this.evaluate(c));
|
||||||
|
}
|
||||||
|
if (cond.not) {
|
||||||
|
return !this.evaluate(cond.not);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value comparisons
|
||||||
|
const value = this.get(cond.path);
|
||||||
|
|
||||||
|
if ("equals" in cond) {
|
||||||
|
return value === cond.equals;
|
||||||
|
}
|
||||||
|
if ("notEquals" in cond) {
|
||||||
|
return value !== cond.notEquals;
|
||||||
|
}
|
||||||
|
if ("greaterThan" in cond) {
|
||||||
|
return value > cond.greaterThan;
|
||||||
|
}
|
||||||
|
if ("greaterThanOrEqual" in cond) {
|
||||||
|
return value >= cond.greaterThanOrEqual;
|
||||||
|
}
|
||||||
|
if ("lessThan" in cond) {
|
||||||
|
return value < cond.lessThan;
|
||||||
|
}
|
||||||
|
if ("lessThanOrEqual" in cond) {
|
||||||
|
return value <= cond.lessThanOrEqual;
|
||||||
|
}
|
||||||
|
if ("contains" in cond) {
|
||||||
|
return Array.isArray(value) && value.includes(cond.contains);
|
||||||
|
}
|
||||||
|
if ("notContains" in cond) {
|
||||||
|
return !Array.isArray(value) || !value.includes(cond.notContains);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default: check truthiness of path
|
||||||
|
return !!value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get entire state (for debugging)
|
||||||
|
getAll() {
|
||||||
|
return this._deepClone(this.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset state and clear storage
|
||||||
|
reset() {
|
||||||
|
this.state = {};
|
||||||
|
try {
|
||||||
|
localStorage.removeItem(this.storageKey);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Failed to clear game state from storage:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there is saved state
|
||||||
|
hasSavedState() {
|
||||||
|
try {
|
||||||
|
return localStorage.getItem(this.storageKey) !== null;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_saveToStorage() {
|
||||||
|
try {
|
||||||
|
localStorage.setItem(this.storageKey, JSON.stringify(this.state));
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Failed to save game state:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_loadFromStorage() {
|
||||||
|
try {
|
||||||
|
const saved = localStorage.getItem(this.storageKey);
|
||||||
|
if (saved) {
|
||||||
|
const parsed = JSON.parse(saved);
|
||||||
|
this.state = this._mergeDeep(this.state, parsed);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Failed to load game state:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_deepClone(obj) {
|
||||||
|
return JSON.parse(JSON.stringify(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
_mergeDeep(target, source) {
|
||||||
|
const result = { ...target };
|
||||||
|
for (const key of Object.keys(source)) {
|
||||||
|
if (
|
||||||
|
source[key] &&
|
||||||
|
typeof source[key] === "object" &&
|
||||||
|
!Array.isArray(source[key])
|
||||||
|
) {
|
||||||
|
result[key] = this._mergeDeep(result[key] || {}, source[key]);
|
||||||
|
} else {
|
||||||
|
result[key] = source[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
241
assets/js/games/engine/table-helper.js
Normal file
241
assets/js/games/engine/table-helper.js
Normal file
|
|
@ -0,0 +1,241 @@
|
||||||
|
// Table Helper - Generates monospace box-drawn tables for terminal games
|
||||||
|
|
||||||
|
const TableHelper = {
|
||||||
|
// Box drawing characters
|
||||||
|
chars: {
|
||||||
|
single: {
|
||||||
|
topLeft: "┌",
|
||||||
|
topRight: "┐",
|
||||||
|
bottomLeft: "└",
|
||||||
|
bottomRight: "┘",
|
||||||
|
horizontal: "─",
|
||||||
|
vertical: "│",
|
||||||
|
leftT: "├",
|
||||||
|
rightT: "┤",
|
||||||
|
topT: "┬",
|
||||||
|
bottomT: "┴",
|
||||||
|
cross: "┼",
|
||||||
|
},
|
||||||
|
double: {
|
||||||
|
topLeft: "╔",
|
||||||
|
topRight: "╗",
|
||||||
|
bottomLeft: "╚",
|
||||||
|
bottomRight: "╝",
|
||||||
|
horizontal: "═",
|
||||||
|
vertical: "║",
|
||||||
|
leftT: "╠",
|
||||||
|
rightT: "╣",
|
||||||
|
topT: "╦",
|
||||||
|
bottomT: "╩",
|
||||||
|
cross: "╬",
|
||||||
|
},
|
||||||
|
ascii: {
|
||||||
|
topLeft: "+",
|
||||||
|
topRight: "+",
|
||||||
|
bottomLeft: "+",
|
||||||
|
bottomRight: "+",
|
||||||
|
horizontal: "-",
|
||||||
|
vertical: "|",
|
||||||
|
leftT: "+",
|
||||||
|
rightT: "+",
|
||||||
|
topT: "+",
|
||||||
|
bottomT: "+",
|
||||||
|
cross: "+",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a complete table with headers and rows
|
||||||
|
* @param {Object} options - Table configuration
|
||||||
|
* @param {string} [options.title] - Optional title for the table
|
||||||
|
* @param {string[]} [options.headers] - Column headers
|
||||||
|
* @param {Array<Array<string|{text: string, className?: string}>>} options.rows - Table data rows
|
||||||
|
* @param {number[]} [options.widths] - Column widths (auto-calculated if not provided)
|
||||||
|
* @param {string[]} [options.align] - Column alignments ('left', 'right', 'center')
|
||||||
|
* @param {string} [options.style='single'] - Border style ('single', 'double', 'ascii')
|
||||||
|
* @param {number} [options.padding=1] - Cell padding
|
||||||
|
* @returns {Array<string|{text: string, className?: string}>} Array of content blocks
|
||||||
|
*/
|
||||||
|
table(options) {
|
||||||
|
const {
|
||||||
|
title,
|
||||||
|
headers,
|
||||||
|
rows = [],
|
||||||
|
widths: customWidths,
|
||||||
|
align = [],
|
||||||
|
style = "single",
|
||||||
|
padding = 1,
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
const c = this.chars[style] || this.chars.single;
|
||||||
|
const output = [];
|
||||||
|
|
||||||
|
// Calculate column widths
|
||||||
|
const widths = customWidths || this._calculateWidths(headers, rows, padding);
|
||||||
|
const totalWidth = widths.reduce((a, b) => a + b, 0) + widths.length + 1;
|
||||||
|
|
||||||
|
// Top border
|
||||||
|
output.push(c.topLeft + c.horizontal.repeat(totalWidth - 2) + c.topRight);
|
||||||
|
|
||||||
|
// Title (if provided)
|
||||||
|
if (title) {
|
||||||
|
output.push(this._centerText(title, totalWidth, c.vertical));
|
||||||
|
output.push(c.leftT + c.horizontal.repeat(totalWidth - 2) + c.rightT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Headers (if provided)
|
||||||
|
if (headers) {
|
||||||
|
output.push(this._formatRow(headers, widths, align, c.vertical, padding));
|
||||||
|
output.push(c.leftT + c.horizontal.repeat(totalWidth - 2) + c.rightT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Data rows
|
||||||
|
for (const row of rows) {
|
||||||
|
const formattedRow = this._formatRow(row, widths, align, c.vertical, padding);
|
||||||
|
|
||||||
|
// Check if any cell has a className
|
||||||
|
const hasClassName = row.some(cell => cell && typeof cell === "object" && cell.className);
|
||||||
|
|
||||||
|
if (hasClassName) {
|
||||||
|
// Find the className from the row (use first one found)
|
||||||
|
const className = row.find(cell => cell && typeof cell === "object" && cell.className)?.className;
|
||||||
|
output.push({ text: formattedRow, className });
|
||||||
|
} else {
|
||||||
|
output.push(formattedRow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bottom border
|
||||||
|
output.push(c.bottomLeft + c.horizontal.repeat(totalWidth - 2) + c.bottomRight);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a simple bordered box with text
|
||||||
|
* @param {string|string[]} content - Content to display
|
||||||
|
* @param {Object} [options] - Box options
|
||||||
|
* @param {number} [options.width] - Box width (auto if not set)
|
||||||
|
* @param {string} [options.style='single'] - Border style
|
||||||
|
* @param {string} [options.align='left'] - Text alignment
|
||||||
|
* @returns {string[]} Array of strings
|
||||||
|
*/
|
||||||
|
box(content, options = {}) {
|
||||||
|
const { width: customWidth, style = "single", align = "left" } = options;
|
||||||
|
const c = this.chars[style] || this.chars.single;
|
||||||
|
const lines = Array.isArray(content) ? content : [content];
|
||||||
|
|
||||||
|
const maxLineWidth = Math.max(...lines.map(l => this._textLength(l)));
|
||||||
|
const width = customWidth || maxLineWidth + 4;
|
||||||
|
const innerWidth = width - 2;
|
||||||
|
|
||||||
|
const output = [];
|
||||||
|
output.push(c.topLeft + c.horizontal.repeat(innerWidth) + c.topRight);
|
||||||
|
|
||||||
|
for (const line of lines) {
|
||||||
|
const text = typeof line === "string" ? line : line.text || "";
|
||||||
|
const padded = this._alignText(text, innerWidth - 2, align);
|
||||||
|
output.push(c.vertical + " " + padded + " " + c.vertical);
|
||||||
|
}
|
||||||
|
|
||||||
|
output.push(c.bottomLeft + c.horizontal.repeat(innerWidth) + c.bottomRight);
|
||||||
|
return output;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a separator line
|
||||||
|
* @param {number} width - Line width
|
||||||
|
* @param {string} [style='single'] - Border style
|
||||||
|
* @param {string} [type='middle'] - 'top', 'middle', 'bottom'
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
separator(width, style = "single", type = "middle") {
|
||||||
|
const c = this.chars[style] || this.chars.single;
|
||||||
|
const inner = c.horizontal.repeat(width - 2);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case "top":
|
||||||
|
return c.topLeft + inner + c.topRight;
|
||||||
|
case "bottom":
|
||||||
|
return c.bottomLeft + inner + c.bottomRight;
|
||||||
|
default:
|
||||||
|
return c.leftT + inner + c.rightT;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pad or truncate text to exact width
|
||||||
|
* @param {string} text - Input text
|
||||||
|
* @param {number} width - Target width
|
||||||
|
* @param {string} [align='left'] - Alignment
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
pad(text, width, align = "left") {
|
||||||
|
return this._alignText(text, width, align);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Internal helpers
|
||||||
|
|
||||||
|
_calculateWidths(headers, rows, padding) {
|
||||||
|
const allRows = headers ? [headers, ...rows] : rows;
|
||||||
|
const numCols = Math.max(...allRows.map(r => r.length));
|
||||||
|
const widths = new Array(numCols).fill(0);
|
||||||
|
|
||||||
|
for (const row of allRows) {
|
||||||
|
for (let i = 0; i < row.length; i++) {
|
||||||
|
const cell = row[i];
|
||||||
|
const text = typeof cell === "object" ? (cell.text || "") : String(cell || "");
|
||||||
|
widths[i] = Math.max(widths[i], text.length + padding * 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return widths;
|
||||||
|
},
|
||||||
|
|
||||||
|
_formatRow(row, widths, alignments, verticalChar, padding) {
|
||||||
|
const cells = [];
|
||||||
|
for (let i = 0; i < widths.length; i++) {
|
||||||
|
const cell = row[i];
|
||||||
|
const text = typeof cell === "object" ? (cell.text || "") : String(cell || "");
|
||||||
|
const align = alignments[i] || "left";
|
||||||
|
const cellWidth = widths[i] - padding * 2;
|
||||||
|
const padChar = " ".repeat(padding);
|
||||||
|
cells.push(padChar + this._alignText(text, cellWidth, align) + padChar);
|
||||||
|
}
|
||||||
|
return verticalChar + cells.join(verticalChar) + verticalChar;
|
||||||
|
},
|
||||||
|
|
||||||
|
_centerText(text, totalWidth, verticalChar) {
|
||||||
|
const innerWidth = totalWidth - 2;
|
||||||
|
const padded = this._alignText(text, innerWidth, "center");
|
||||||
|
return verticalChar + padded + verticalChar;
|
||||||
|
},
|
||||||
|
|
||||||
|
_alignText(text, width, align) {
|
||||||
|
const len = text.length;
|
||||||
|
if (len >= width) {
|
||||||
|
return text.substring(0, width);
|
||||||
|
}
|
||||||
|
|
||||||
|
const diff = width - len;
|
||||||
|
switch (align) {
|
||||||
|
case "right":
|
||||||
|
return " ".repeat(diff) + text;
|
||||||
|
case "center":
|
||||||
|
const left = Math.floor(diff / 2);
|
||||||
|
const right = diff - left;
|
||||||
|
return " ".repeat(left) + text + " ".repeat(right);
|
||||||
|
default:
|
||||||
|
return text + " ".repeat(diff);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_textLength(item) {
|
||||||
|
if (typeof item === "string") return item.length;
|
||||||
|
if (item && item.text) return item.text.length;
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Make available globally
|
||||||
|
window.TableHelper = TableHelper;
|
||||||
76
assets/js/games/engine/terminal-adapter.js
Normal file
76
assets/js/games/engine/terminal-adapter.js
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
// Terminal Adapter - Bridges game engine to existing TerminalShell
|
||||||
|
class TerminalAdapter {
|
||||||
|
constructor(terminal) {
|
||||||
|
this.terminal = terminal;
|
||||||
|
this.inputCallback = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output methods - delegate to terminal
|
||||||
|
print(text, className = "") {
|
||||||
|
this.terminal.print(text, className);
|
||||||
|
this.scrollToBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
printHTML(html, className = "") {
|
||||||
|
this.terminal.printHTML(html, className);
|
||||||
|
this.scrollToBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
printError(text) {
|
||||||
|
this.terminal.printError(text);
|
||||||
|
this.scrollToBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
printSuccess(text) {
|
||||||
|
this.terminal.printSuccess(text);
|
||||||
|
this.scrollToBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
printInfo(text) {
|
||||||
|
this.terminal.printInfo(text);
|
||||||
|
this.scrollToBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
printWarning(text) {
|
||||||
|
this.terminal.printWarning(text);
|
||||||
|
this.scrollToBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.terminal.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollToBottom() {
|
||||||
|
this.terminal.scrollToBottom();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input capture - allows game to intercept terminal input
|
||||||
|
captureInput(callback) {
|
||||||
|
this.inputCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
releaseInput() {
|
||||||
|
this.inputCallback = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by game engine when input is received
|
||||||
|
handleInput(value) {
|
||||||
|
if (this.inputCallback) {
|
||||||
|
this.inputCallback(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the input element for focus management
|
||||||
|
getInputElement() {
|
||||||
|
return this.terminal.input;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Focus the input
|
||||||
|
focusInput() {
|
||||||
|
if (this.terminal.input) {
|
||||||
|
this.terminal.input.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
128
assets/js/games/games/ascii-art.js
Normal file
128
assets/js/games/games/ascii-art.js
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
const BOXING_DAY_TITLE1 = `
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;233;48;5;0m▄▄▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;233;48;5;0m▄▄▄▄▄\x1b[38;5;234;48;5;0m▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;233;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;235;48;5;0m▄▄▄\x1b[38;5;234;48;5;0m▄▄▄▄▄\x1b[38;5;233;48;5;0m▄▄▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;233;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄▄▄\x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;232;48;5;232m▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;234;48;5;232m▄\x1b[38;5;38;48;5;233m▄\x1b[38;5;17;48;5;232m▄\x1b[38;5;38;48;5;233m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;31;48;5;0m▄\x1b[38;5;17;48;5;0m▄▄\x1b[38;5;44;48;5;0m▄\x1b[38;5;17;48;5;0m▄▄\x1b[38;5;17;48;5;232m▄\x1b[38;5;17;48;5;233m▄\x1b[38;5;17;48;5;235m▄\x1b[38;5;17;48;5;17m▄▄▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;23;48;5;6m▄\x1b[38;5;23;48;5;80m▄\x1b[38;5;23;48;5;14m▄\x1b[38;5;24;48;5;14m▄\x1b[38;5;24;48;5;44m▄\x1b[38;5;24;48;5;45m▄▄\x1b[38;5;24;48;5;14m▄\x1b[38;5;31;48;5;17m▄\x1b[38;5;86;48;5;23m▄\x1b[38;5;37;48;5;17m▄\x1b[38;5;44;48;5;17m▄\x1b[38;5;87;48;5;72m▄\x1b[38;5;86;48;5;78m▄\x1b[38;5;80;48;5;23m▄\x1b[38;5;81;48;5;17m▄▄\x1b[38;5;14;48;5;17m▄▄\x1b[38;5;45;48;5;17m▄▄\x1b[38;5;44;48;5;17m▄▄▄\x1b[38;5;38;48;5;17m▄\x1b[38;5;31;48;5;38m▄\x1b[38;5;31;48;5;17m▄\x1b[38;5;24;48;5;17m▄▄▄\x1b[38;5;23;48;5;31m▄\x1b[38;5;80;48;5;23m▄\x1b[38;5;45;48;5;17m▄\x1b[38;5;23;48;5;24m▄\x1b[38;5;23;48;5;17m▄▄▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;17;48;5;236m▄\x1b[38;5;17;48;5;235m▄\x1b[38;5;17;48;5;233m▄\x1b[38;5;17;48;5;0m▄▄▄▄▄\x1b[38;5;236;48;5;0m▄\x1b[38;5;23;48;5;0m▄\x1b[38;5;72;48;5;232m▄\x1b[38;5;17;48;5;232m▄▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;232;48;5;0m▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;31;48;5;17m▄\x1b[38;5;17;48;5;74m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;23;48;5;31m▄\x1b[38;5;87;48;5;14m▄\x1b[38;5;17;48;5;45m▄\x1b[38;5;233;48;5;14m▄▄▄\x1b[38;5;232;48;5;14m▄\x1b[38;5;232;48;5;44m▄\x1b[38;5;232;48;5;14m▄\x1b[38;5;232;48;5;81m▄\x1b[38;5;232;48;5;6m▄\x1b[38;5;232;48;5;23m▄▄\x1b[38;5;233;48;5;23m▄▄\x1b[38;5;233;48;5;17m▄\x1b[38;5;234;48;5;17m▄\x1b[38;5;233;48;5;17m▄▄▄▄▄▄▄▄\x1b[38;5;233;48;5;235m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;17m▄▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;233;48;5;17m▄▄▄▄\x1b[38;5;233;48;5;234m▄▄▄\x1b[38;5;233;48;5;17m▄\x1b[38;5;234;48;5;17m▄▄▄▄\x1b[38;5;233;48;5;17m▄▄▄▄▄▄\x1b[38;5;233;48;5;23m▄\x1b[38;5;233;48;5;17m▄\x1b[38;5;232;48;5;23m▄▄\x1b[38;5;232;48;5;24m▄\x1b[38;5;232;48;5;37m▄\x1b[38;5;232;48;5;87m▄\x1b[38;5;232;48;5;14m▄▄▄\x1b[38;5;233;48;5;14m▄▄\x1b[38;5;234;48;5;14m▄\x1b[38;5;14;48;5;14m▄\x1b[38;5;32;48;5;17m▄\x1b[38;5;38;48;5;17m▄▄\x1b[38;5;32;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;233;48;5;232m▄▄\x1b[38;5;0;48;5;0m▄▄\x1b[m
|
||||||
|
\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;23;48;5;17m▄\x1b[38;5;44;48;5;86m▄\x1b[38;5;17;48;5;17m▄▄\x1b[38;5;23;48;5;17m▄\x1b[38;5;23;48;5;38m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;158;48;5;233m▄\x1b[38;5;158;48;5;236m▄▄\x1b[38;5;194;48;5;236m▄\x1b[38;5;195;48;5;236m▄\x1b[38;5;22;48;5;235m▄\x1b[38;5;72;48;5;236m▄\x1b[38;5;195;48;5;236m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;233m▄\x1b[38;5;236;48;5;235m▄\x1b[38;5;194;48;5;22m▄\x1b[38;5;23;48;5;235m▄\x1b[38;5;194;48;5;236m▄\x1b[38;5;195;48;5;29m▄\x1b[38;5;195;48;5;65m▄\x1b[38;5;194;48;5;72m▄▄\x1b[38;5;236;48;5;235m▄\x1b[38;5;72;48;5;22m▄\x1b[38;5;71;48;5;23m▄\x1b[38;5;78;48;5;23m▄\x1b[38;5;72;48;5;23m▄\x1b[38;5;115;48;5;23m▄\x1b[38;5;158;48;5;23m▄▄\x1b[38;5;195;48;5;23m▄▄▄▄\x1b[38;5;194;48;5;23m▄\x1b[38;5;29;48;5;236m▄\x1b[38;5;194;48;5;23m▄\x1b[38;5;194;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;158;48;5;234m▄\x1b[38;5;194;48;5;236m▄\x1b[38;5;22;48;5;234m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;30;48;5;87m▄\x1b[38;5;17;48;5;17m▄▄▄▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;0;48;5;0m▄▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;0m \x1b[38;5;17;48;5;17m▄\x1b[38;5;23;48;5;80m▄\x1b[38;5;31;48;5;17m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;17;48;5;23m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;194;48;5;194m▄\x1b[38;5;194;48;5;158m▄\x1b[38;5;194;48;5;237m▄\x1b[38;5;194;48;5;236m▄▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;236;48;5;115m▄\x1b[38;5;194;48;5;195m▄\x1b[38;5;195;48;5;194m▄\x1b[38;5;195;48;5;237m▄\x1b[38;5;194;48;5;195m▄\x1b[38;5;23;48;5;195m▄\x1b[38;5;236;48;5;237m▄\x1b[38;5;158;48;5;195m▄\x1b[38;5;195;48;5;23m▄▄\x1b[38;5;195;48;5;237m▄▄\x1b[38;5;72;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;115;48;5;78m▄\x1b[38;5;78;48;5;78m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;65;48;5;152m▄\x1b[38;5;78;48;5;255m▄\x1b[38;5;71;48;5;237m▄\x1b[38;5;71;48;5;236m▄\x1b[38;5;35;48;5;236m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;235;48;5;23m▄\x1b[38;5;71;48;5;194m▄\x1b[38;5;115;48;5;194m▄\x1b[38;5;78;48;5;29m▄\x1b[38;5;78;48;5;195m▄\x1b[38;5;78;48;5;194m▄\x1b[38;5;22;48;5;23m▄\x1b[48;5;233m \x1b[38;5;232;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;23;48;5;25m▄\x1b[38;5;17;48;5;17m▄▄▄▄\x1b[48;5;0m \x1b[38;5;233;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄\x1b[m
|
||||||
|
\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;17;48;5;23m▄\x1b[38;5;38;48;5;74m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;24;48;5;23m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;65;48;5;235m▄\x1b[38;5;115;48;5;23m▄\x1b[38;5;158;48;5;23m▄▄\x1b[38;5;194;48;5;158m▄\x1b[38;5;195;48;5;194m▄\x1b[38;5;234;48;5;235m▄▄\x1b[38;5;72;48;5;71m▄\x1b[38;5;255;48;5;195m▄\x1b[38;5;236;48;5;23m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;236;48;5;235m▄\x1b[38;5;195;48;5;236m▄\x1b[38;5;195;48;5;23m▄\x1b[38;5;195;48;5;237m▄\x1b[38;5;195;48;5;23m▄\x1b[38;5;195;48;5;195m▄\x1b[38;5;115;48;5;115m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;195;48;5;115m▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;233m▄\x1b[38;5;65;48;5;29m▄\x1b[38;5;255;48;5;78m▄\x1b[38;5;195;48;5;237m▄\x1b[38;5;195;48;5;236m▄\x1b[38;5;194;48;5;236m▄\x1b[38;5;194;48;5;235m▄\x1b[38;5;23;48;5;237m▄\x1b[38;5;194;48;5;71m▄\x1b[38;5;236;48;5;235m▄\x1b[38;5;234;48;5;195m▄\x1b[38;5;235;48;5;23m▄\x1b[38;5;158;48;5;72m▄\x1b[38;5;115;48;5;23m▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;23;48;5;23m▄▄\x1b[38;5;23;48;5;17m▄\x1b[38;5;17;48;5;17m▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;234;48;5;233m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[38;5;0;48;5;0m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;233;48;5;235m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;17m▄▄\x1b[38;5;32;48;5;38m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;80;48;5;31m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;234;48;5;232m▄▄▄▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;158m▄\x1b[38;5;235;48;5;194m▄▄\x1b[38;5;236;48;5;195m▄▄\x1b[38;5;235;48;5;236m▄\x1b[38;5;233;48;5;233m▄▄\x1b[38;5;235;48;5;72m▄\x1b[38;5;236;48;5;255m▄\x1b[38;5;236;48;5;235m▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;237;48;5;236m▄\x1b[38;5;23;48;5;195m▄▄▄\x1b[38;5;237;48;5;195m▄\x1b[38;5;23;48;5;195m▄\x1b[38;5;237;48;5;236m▄\x1b[38;5;237;48;5;234m▄▄\x1b[38;5;236;48;5;195m▄\x1b[38;5;235;48;5;195m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;23;48;5;255m▄▄\x1b[38;5;237;48;5;195m▄\x1b[38;5;236;48;5;195m▄▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;235;48;5;195m▄\x1b[38;5;233;48;5;235m▄\x1b[38;5;234;48;5;233m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;235;48;5;194m▄\x1b[38;5;235;48;5;158m▄\x1b[38;5;234;48;5;233m▄\x1b[38;5;233;48;5;232m▄▄\x1b[38;5;234;48;5;232m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;44;48;5;24m▄\x1b[38;5;23;48;5;23m▄▄▄\x1b[38;5;23;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;233;48;5;233m▄▄\x1b[38;5;17;48;5;232m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;24;48;5;17m▄\x1b[38;5;24;48;5;31m▄\x1b[38;5;24;48;5;24m▄\x1b[38;5;87;48;5;87m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;234;48;5;233m▄\x1b[38;5;158;48;5;235m▄\x1b[38;5;29;48;5;158m▄\x1b[38;5;23;48;5;194m▄▄\x1b[38;5;23;48;5;158m▄\x1b[38;5;237;48;5;235m▄\x1b[38;5;195;48;5;194m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;194;48;5;195m▄\x1b[38;5;158;48;5;195m▄\x1b[38;5;255;48;5;195m▄\x1b[38;5;194;48;5;195m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;194;48;5;158m▄\x1b[38;5;15;48;5;195m▄\x1b[38;5;237;48;5;23m▄\x1b[38;5;23;48;5;195m▄▄\x1b[38;5;195;48;5;195m▄\x1b[38;5;23;48;5;195m▄▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;15;48;5;195m▄\x1b[38;5;115;48;5;195m▄\x1b[38;5;23;48;5;195m▄▄\x1b[38;5;15;48;5;72m▄\x1b[38;5;195;48;5;236m▄\x1b[38;5;115;48;5;29m▄\x1b[38;5;15;48;5;195m▄\x1b[38;5;195;48;5;195m▄\x1b[38;5;23;48;5;195m▄\x1b[38;5;195;48;5;195m▄\x1b[38;5;15;48;5;115m▄\x1b[38;5;23;48;5;237m▄\x1b[38;5;15;48;5;195m▄\x1b[38;5;195;48;5;194m▄\x1b[38;5;236;48;5;235m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;23;48;5;236m▄\x1b[38;5;194;48;5;195m▄\x1b[38;5;23;48;5;236m▄\x1b[38;5;194;48;5;195m▄\x1b[38;5;194;48;5;23m▄\x1b[38;5;65;48;5;234m▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;195;48;5;158m▄\x1b[38;5;23;48;5;22m▄\x1b[38;5;236;48;5;233m▄\x1b[38;5;158;48;5;233m▄\x1b[38;5;234;48;5;232m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;87;48;5;81m▄\x1b[38;5;23;48;5;23m▄▄▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;234;48;5;232m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;233;48;5;233m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;44;48;5;17m▄\x1b[38;5;17;48;5;50m▄\x1b[38;5;24;48;5;31m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;24;48;5;38m▄\x1b[38;5;14;48;5;87m▄\x1b[38;5;233;48;5;234m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;233;48;5;235m▄\x1b[38;5;22;48;5;158m▄\x1b[38;5;158;48;5;115m▄\x1b[38;5;194;48;5;115m▄\x1b[38;5;194;48;5;122m▄\x1b[38;5;195;48;5;122m▄\x1b[38;5;23;48;5;236m▄\x1b[38;5;158;48;5;72m▄▄\x1b[38;5;121;48;5;78m▄\x1b[38;5;115;48;5;115m▄\x1b[38;5;78;48;5;79m▄\x1b[38;5;115;48;5;72m▄\x1b[38;5;194;48;5;195m▄▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;236;48;5;235m▄\x1b[38;5;195;48;5;194m▄\x1b[38;5;195;48;5;195m▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;15;48;5;255m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;237;48;5;237m▄\x1b[38;5;15;48;5;255m▄\x1b[38;5;115;48;5;115m▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;237;48;5;236m▄\x1b[38;5;15;48;5;195m▄\x1b[38;5;15;48;5;255m▄\x1b[38;5;72;48;5;79m▄\x1b[38;5;15;48;5;255m▄\x1b[38;5;237;48;5;237m▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;195;48;5;255m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;195;48;5;195m▄▄\x1b[38;5;195;48;5;23m▄\x1b[38;5;195;48;5;195m▄\x1b[38;5;29;48;5;23m▄\x1b[38;5;195;48;5;195m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;194;48;5;195m▄\x1b[38;5;23;48;5;195m▄\x1b[38;5;194;48;5;195m▄\x1b[38;5;195;48;5;23m▄\x1b[38;5;194;48;5;194m▄\x1b[38;5;72;48;5;29m▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;235;48;5;158m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;232m▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;14;48;5;14m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;17;48;5;23m▄▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;17;48;5;235m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[48;5;233m \x1b[38;5;233;48;5;232m▄\x1b[38;5;31;48;5;17m▄\x1b[38;5;38;48;5;24m▄\x1b[38;5;17;48;5;75m▄\x1b[38;5;17;48;5;17m▄▄\x1b[38;5;87;48;5;14m▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;234;48;5;233m▄\x1b[38;5;158;48;5;236m▄▄▄\x1b[38;5;158;48;5;23m▄\x1b[38;5;158;48;5;194m▄\x1b[38;5;236;48;5;23m▄\x1b[38;5;194;48;5;195m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;233;48;5;235m▄\x1b[38;5;235;48;5;236m▄\x1b[38;5;194;48;5;195m▄\x1b[38;5;72;48;5;115m▄\x1b[38;5;23;48;5;195m▄\x1b[38;5;195;48;5;195m▄\x1b[38;5;195;48;5;23m▄▄\x1b[38;5;195;48;5;195m▄\x1b[38;5;23;48;5;195m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;237;48;5;23m▄\x1b[38;5;15;48;5;195m▄\x1b[38;5;237;48;5;237m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;237;48;5;236m▄\x1b[38;5;15;48;5;195m▄\x1b[38;5;15;48;5;115m▄\x1b[38;5;15;48;5;23m▄\x1b[38;5;15;48;5;29m▄\x1b[38;5;29;48;5;195m▄\x1b[38;5;237;48;5;195m▄\x1b[38;5;23;48;5;72m▄\x1b[38;5;195;48;5;195m▄\x1b[38;5;15;48;5;195m▄\x1b[38;5;15;48;5;23m▄\x1b[38;5;195;48;5;195m▄\x1b[38;5;194;48;5;195m▄\x1b[38;5;236;48;5;23m▄\x1b[38;5;195;48;5;195m▄▄\x1b[38;5;23;48;5;195m▄\x1b[38;5;236;48;5;23m▄\x1b[38;5;195;48;5;195m▄▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;195;48;5;195m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;235;48;5;236m▄\x1b[38;5;235;48;5;195m▄\x1b[38;5;158;48;5;195m▄\x1b[38;5;72;48;5;72m▄\x1b[38;5;236;48;5;235m▄\x1b[38;5;158;48;5;158m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;87;48;5;87m▄\x1b[38;5;23;48;5;23m▄▄▄\x1b[38;5;17;48;5;17m▄▄\x1b[38;5;233;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;232;48;5;232m▄▄\x1b[38;5;17;48;5;74m▄\x1b[38;5;17;48;5;17m▄▄▄▄\x1b[38;5;14;48;5;14m▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;232;48;5;235m▄▄▄\x1b[38;5;232;48;5;236m▄\x1b[38;5;232;48;5;235m▄\x1b[38;5;232;48;5;234m▄\x1b[38;5;232;48;5;235m▄\x1b[38;5;232;48;5;234m▄\x1b[38;5;232;48;5;233m▄▄\x1b[38;5;232;48;5;235m▄▄\x1b[38;5;232;48;5;234m▄\x1b[38;5;233;48;5;236m▄▄▄\x1b[38;5;235;48;5;236m▄\x1b[38;5;194;48;5;236m▄\x1b[38;5;158;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;72;48;5;237m▄\x1b[38;5;72;48;5;236m▄\x1b[38;5;115;48;5;236m▄\x1b[38;5;194;48;5;236m▄\x1b[38;5;66;48;5;237m▄\x1b[38;5;237;48;5;23m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;158;48;5;23m▄\x1b[38;5;78;48;5;23m▄\x1b[38;5;72;48;5;237m▄\x1b[38;5;78;48;5;236m▄\x1b[38;5;237;48;5;237m▄\x1b[38;5;23;48;5;237m▄\x1b[38;5;115;48;5;23m▄\x1b[38;5;158;48;5;23m▄\x1b[38;5;158;48;5;237m▄\x1b[38;5;78;48;5;236m▄\x1b[38;5;235;48;5;236m▄\x1b[38;5;233;48;5;236m▄\x1b[38;5;233;48;5;235m▄\x1b[38;5;232;48;5;234m▄\x1b[38;5;232;48;5;235m▄▄▄▄\x1b[38;5;232;48;5;234m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;232;48;5;235m▄\x1b[38;5;232;48;5;234m▄▄▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;14;48;5;87m▄\x1b[38;5;17;48;5;23m▄\x1b[38;5;17;48;5;17m▄▄▄▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;234;48;5;233m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;23;48;5;17m▄▄▄▄\x1b[38;5;24;48;5;17m▄\x1b[38;5;14;48;5;14m▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;0;48;5;232m▄▄▄▄▄▄▄▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;234;48;5;72m▄\x1b[38;5;29;48;5;78m▄\x1b[38;5;115;48;5;158m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;151;48;5;157m▄\x1b[38;5;152;48;5;23m▄\x1b[38;5;115;48;5;23m▄\x1b[38;5;79;48;5;23m▄\x1b[38;5;115;48;5;158m▄\x1b[38;5;23;48;5;237m▄\x1b[38;5;195;48;5;158m▄\x1b[38;5;158;48;5;23m▄\x1b[38;5;115;48;5;23m▄\x1b[38;5;78;48;5;23m▄\x1b[38;5;115;48;5;122m▄\x1b[38;5;23;48;5;236m▄\x1b[38;5;79;48;5;115m▄\x1b[38;5;78;48;5;23m▄▄\x1b[38;5;79;48;5;23m▄\x1b[38;5;115;48;5;115m▄\x1b[38;5;236;48;5;235m▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;232m▄▄▄▄▄\x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;14;48;5;87m▄\x1b[38;5;17;48;5;17m▄\x1b[48;5;17m \x1b[38;5;17;48;5;17m▄▄\x1b[38;5;31;48;5;17m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;24;48;5;23m▄▄\x1b[38;5;31;48;5;23m▄\x1b[38;5;37;48;5;24m▄\x1b[38;5;44;48;5;24m▄\x1b[38;5;14;48;5;87m▄\x1b[38;5;233;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄▄\x1b[38;5;0;48;5;232m▄▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;232m▄▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;115;48;5;234m▄\x1b[38;5;71;48;5;23m▄\x1b[38;5;72;48;5;72m▄\x1b[38;5;35;48;5;235m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;78;48;5;23m▄\x1b[38;5;195;48;5;23m▄▄\x1b[38;5;78;48;5;23m▄\x1b[38;5;79;48;5;78m▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;236;48;5;23m▄\x1b[38;5;158;48;5;23m▄\x1b[38;5;115;48;5;23m▄\x1b[38;5;72;48;5;23m▄\x1b[38;5;78;48;5;72m▄\x1b[38;5;236;48;5;237m▄\x1b[38;5;235;48;5;236m▄\x1b[38;5;72;48;5;23m▄▄\x1b[38;5;78;48;5;23m▄\x1b[38;5;158;48;5;158m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;234;48;5;233m▄\x1b[38;5;14;48;5;14m▄\x1b[38;5;17;48;5;17m▄▄\x1b[38;5;75;48;5;17m▄\x1b[38;5;4;48;5;74m▄\x1b[38;5;17;48;5;25m▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;233;48;5;232m▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;234;48;5;234m▄\x1b[38;5;236;48;5;235m▄\x1b[38;5;37;48;5;6m▄\x1b[38;5;44;48;5;38m▄\x1b[38;5;14;48;5;81m▄\x1b[38;5;14;48;5;14m▄▄\x1b[38;5;14;48;5;44m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;232m▄▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;233;48;5;121m▄\x1b[38;5;233;48;5;72m▄\x1b[38;5;233;48;5;35m▄▄\x1b[38;5;233;48;5;235m▄\x1b[38;5;233;48;5;115m▄\x1b[38;5;233;48;5;195m▄▄\x1b[38;5;234;48;5;78m▄\x1b[38;5;233;48;5;237m▄\x1b[38;5;233;48;5;234m▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;234;48;5;158m▄\x1b[38;5;234;48;5;79m▄\x1b[38;5;233;48;5;29m▄▄\x1b[38;5;232;48;5;234m▄\x1b[38;5;232;48;5;235m▄\x1b[38;5;233;48;5;71m▄\x1b[38;5;233;48;5;29m▄\x1b[38;5;233;48;5;35m▄\x1b[38;5;232;48;5;72m▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;0;48;5;232m▄▄▄▄▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;232m▄▄▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;87;48;5;87m▄\x1b[38;5;74;48;5;75m▄\x1b[38;5;74;48;5;31m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;50;48;5;17m▄\x1b[38;5;17;48;5;50m▄\x1b[38;5;233;48;5;235m▄\x1b[38;5;233;48;5;233m▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[38;5;0;48;5;0m▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;65;48;5;79m▄\x1b[38;5;85;48;5;85m▄\x1b[38;5;79;48;5;85m▄\x1b[38;5;85;48;5;79m▄▄\x1b[38;5;87;48;5;14m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;23;48;5;232m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;232;48;5;232m▄▄▄▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;17;48;5;233m▄\x1b[38;5;31;48;5;234m▄\x1b[38;5;87;48;5;23m▄▄\x1b[38;5;6;48;5;234m▄\x1b[38;5;17;48;5;233m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;232;48;5;232m▄▄\x1b[38;5;0;48;5;232m▄▄▄▄▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;87;48;5;14m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;38;48;5;38m▄\x1b[38;5;17;48;5;17m▄▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;232;48;5;233m▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;232m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;84;48;5;78m▄▄\x1b[38;5;85;48;5;85m▄\x1b[38;5;72;48;5;79m▄\x1b[38;5;37;48;5;80m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;232;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;232m▄▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;23;48;5;236m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;234;48;5;233m▄\x1b[38;5;80;48;5;17m▄\x1b[38;5;24;48;5;87m▄\x1b[38;5;17;48;5;87m▄\x1b[38;5;87;48;5;87m▄▄\x1b[38;5;17;48;5;87m▄\x1b[38;5;24;48;5;87m▄\x1b[38;5;81;48;5;17m▄\x1b[38;5;234;48;5;232m▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;31;48;5;81m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;74;48;5;38m▄\x1b[38;5;17;48;5;17m▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;234;48;5;233m▄\x1b[38;5;0;48;5;232m▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;23;48;5;79m▄\x1b[38;5;17;48;5;84m▄\x1b[38;5;17;48;5;85m▄\x1b[38;5;17;48;5;66m▄\x1b[38;5;24;48;5;23m▄\x1b[38;5;17;48;5;234m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄▄▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;232;48;5;80m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;158;48;5;23m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;17m▄\x1b[38;5;87;48;5;87m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;17;48;5;87m▄▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;87;48;5;87m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;232;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;24;48;5;24m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;24;48;5;31m▄\x1b[38;5;31;48;5;23m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;233m▄\x1b[48;5;0m \x1b[38;5;17;48;5;17m▄▄▄▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;23;48;5;17m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;232;48;5;234m▄\x1b[38;5;232;48;5;236m▄\x1b[38;5;232;48;5;158m▄\x1b[38;5;232;48;5;234m▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;233;48;5;23m▄\x1b[38;5;23;48;5;87m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;87;48;5;23m▄▄\x1b[38;5;23;48;5;24m▄\x1b[38;5;23;48;5;87m▄\x1b[38;5;233;48;5;23m▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;232m▄▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;23;48;5;17m▄\x1b[38;5;24;48;5;24m▄\x1b[38;5;24;48;5;17m▄\x1b[38;5;75;48;5;4m▄\x1b[38;5;39;48;5;44m▄\x1b[38;5;32;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;233;48;5;234m▄\x1b[38;5;0;48;5;0m▄▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;232m▄\x1b[48;5;0m \x1b[38;5;38;48;5;17m▄\x1b[38;5;17;48;5;17m▄▄▄▄\x1b[38;5;44;48;5;23m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;232;48;5;0m▄▄▄▄▄▄▄▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄▄▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;232;48;5;0m▄▄▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;232;48;5;234m▄\x1b[38;5;232;48;5;17m▄▄\x1b[38;5;232;48;5;234m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄▄▄▄▄▄▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;233;48;5;232m▄▄\x1b[38;5;44;48;5;23m▄\x1b[38;5;17;48;5;24m▄\x1b[38;5;17;48;5;4m▄\x1b[38;5;17;48;5;17m▄▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;31;48;5;39m▄\x1b[38;5;17;48;5;17m▄▄▄▄\x1b[38;5;17;48;5;14m▄▄\x1b[38;5;23;48;5;14m▄\x1b[38;5;25;48;5;44m▄\x1b[38;5;24;48;5;24m▄\x1b[38;5;4;48;5;23m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;23;48;5;17m▄\x1b[38;5;24;48;5;17m▄▄▄\x1b[38;5;24;48;5;234m▄\x1b[38;5;38;48;5;234m▄\x1b[38;5;87;48;5;234m▄▄\x1b[38;5;14;48;5;234m▄\x1b[38;5;14;48;5;233m▄▄\x1b[38;5;87;48;5;233m▄\x1b[38;5;14;48;5;233m▄\x1b[38;5;14;48;5;234m▄\x1b[38;5;14;48;5;233m▄\x1b[38;5;45;48;5;233m▄\x1b[38;5;14;48;5;233m▄\x1b[38;5;87;48;5;233m▄▄▄▄▄▄\x1b[38;5;87;48;5;234m▄\x1b[38;5;87;48;5;17m▄\x1b[38;5;87;48;5;233m▄▄▄▄▄▄▄\x1b[38;5;14;48;5;233m▄▄\x1b[38;5;14;48;5;234m▄▄\x1b[38;5;87;48;5;234m▄\x1b[38;5;14;48;5;233m▄▄\x1b[38;5;14;48;5;234m▄\x1b[38;5;87;48;5;234m▄▄▄\x1b[38;5;37;48;5;234m▄\x1b[38;5;6;48;5;17m▄\x1b[38;5;24;48;5;17m▄\x1b[38;5;23;48;5;17m▄▄\x1b[38;5;23;48;5;23m▄▄\x1b[38;5;17;48;5;23m▄\x1b[38;5;23;48;5;37m▄\x1b[38;5;17;48;5;45m▄\x1b[38;5;17;48;5;14m▄▄\x1b[38;5;17;48;5;17m▄▄\x1b[38;5;236;48;5;17m▄\x1b[38;5;235;48;5;17m▄\x1b[38;5;79;48;5;17m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;232;48;5;232m▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;37m▄\x1b[38;5;232;48;5;31m▄\x1b[38;5;17;48;5;17m▄▄▄▄\x1b[38;5;45;48;5;38m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;38;48;5;32m▄\x1b[38;5;45;48;5;24m▄\x1b[38;5;38;48;5;38m▄\x1b[38;5;23;48;5;45m▄▄▄▄\x1b[38;5;23;48;5;31m▄\x1b[38;5;24;48;5;24m▄\x1b[38;5;31;48;5;23m▄\x1b[38;5;81;48;5;23m▄\x1b[38;5;14;48;5;17m▄\x1b[38;5;45;48;5;17m▄\x1b[38;5;17;48;5;17m▄▄\x1b[38;5;80;48;5;17m▄\x1b[38;5;17;48;5;17m▄▄\x1b[38;5;17;48;5;38m▄\x1b[38;5;38;48;5;17m▄\x1b[38;5;17;48;5;17m▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;17;48;5;23m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;121;48;5;121m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;79;48;5;72m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;17;48;5;23m▄\x1b[38;5;23;48;5;79m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;235;48;5;17m▄\x1b[38;5;235;48;5;23m▄\x1b[38;5;29;48;5;85m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;78;48;5;78m▄\x1b[38;5;17;48;5;85m▄\x1b[38;5;17;48;5;79m▄\x1b[38;5;236;48;5;85m▄\x1b[38;5;23;48;5;78m▄\x1b[38;5;79;48;5;23m▄\x1b[38;5;78;48;5;236m▄\x1b[38;5;84;48;5;17m▄\x1b[38;5;72;48;5;17m▄\x1b[38;5;237;48;5;17m▄\x1b[38;5;235;48;5;17m▄\x1b[38;5;234;48;5;17m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;233;48;5;17m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;233m▄▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;232m▄▄▄\x1b[38;5;0;48;5;233m▄▄\x1b[38;5;0;48;5;232m▄▄▄▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;234;48;5;0m▄▄▄▄\x1b[38;5;235;48;5;0m▄▄\x1b[38;5;234;48;5;232m▄\x1b[38;5;235;48;5;233m▄\x1b[38;5;235;48;5;17m▄\x1b[38;5;235;48;5;44m▄\x1b[38;5;235;48;5;17m▄▄\x1b[38;5;234;48;5;17m▄▄\x1b[38;5;235;48;5;14m▄\x1b[38;5;233;48;5;17m▄▄▄\x1b[38;5;234;48;5;32m▄\x1b[38;5;233;48;5;17m▄\x1b[38;5;232;48;5;17m▄▄▄▄▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;232;48;5;17m▄▄▄▄\x1b[38;5;235;48;5;236m▄\x1b[38;5;234;48;5;17m▄\x1b[38;5;235;48;5;17m▄\x1b[38;5;235;48;5;84m▄\x1b[38;5;234;48;5;17m▄\x1b[38;5;235;48;5;79m▄\x1b[38;5;234;48;5;17m▄\x1b[38;5;235;48;5;17m▄\x1b[38;5;235;48;5;236m▄\x1b[38;5;235;48;5;72m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;235;48;5;232m▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;234;48;5;0m▄▄▄▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;234m▄▄▄▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;232m▄▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[m
|
||||||
|
`;
|
||||||
|
|
||||||
|
const BOXING_DAY_TITLE = `
|
||||||
|
\x1b[48;5;234m \x1b[38;5;234;48;5;235m▄▄\x1b[38;5;235;48;5;235m▄\x1b[48;5;235m \x1b[38;5;60;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;239;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;235;48;5;235m▄▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄\x1b[48;5;234m \x1b[38;5;235;48;5;235m▄▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;110;48;5;234m▄▄\x1b[38;5;74;48;5;234m▄▄▄▄\x1b[38;5;74;48;5;235m▄▄▄\x1b[38;5;73;48;5;234m▄\x1b[38;5;67;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;253;48;5;234m▄▄▄\x1b[38;5;188;48;5;234m▄▄▄\x1b[38;5;252;48;5;234m▄▄\x1b[38;5;188;48;5;234m▄▄\x1b[38;5;252;48;5;234m▄▄▄\x1b[38;5;8;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄▄▄▄▄▄\x1b[38;5;234;48;5;235m▄▄\x1b[38;5;234;48;5;234m▄▄▄▄▄▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;239;48;5;234m▄\x1b[38;5;60;48;5;234m▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;239;48;5;234m▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;239;48;5;234m▄\x1b[m
|
||||||
|
\x1b[48;5;234m \x1b[38;5;235;48;5;60m▄\x1b[48;5;234m \x1b[38;5;234;48;5;235m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;234;48;5;61m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;238m▄▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;239;48;5;60m▄\x1b[38;5;238;48;5;60m▄\x1b[38;5;238;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;236;48;5;234m▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄▄\x1b[38;5;74;48;5;234m▄▄\x1b[38;5;103;48;5;238m▄\x1b[38;5;234;48;5;74m▄\x1b[38;5;234;48;5;110m▄\x1b[38;5;234;48;5;103m▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;238m▄\x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;61m▄\x1b[38;5;234;48;5;110m▄\x1b[38;5;234;48;5;74m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;74;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;252;48;5;234m▄\x1b[38;5;151;48;5;187m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;109;48;5;151m▄▄\x1b[38;5;115;48;5;151m▄▄\x1b[38;5;109;48;5;151m▄\x1b[38;5;110;48;5;151m▄\x1b[38;5;109;48;5;151m▄\x1b[38;5;103;48;5;110m▄▄▄▄\x1b[38;5;104;48;5;110m▄\x1b[38;5;103;48;5;116m▄\x1b[38;5;110;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;97m \x1b[38;5;97;48;5;97m▄▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;103;48;5;235m▄\x1b[38;5;234;48;5;103m▄\x1b[38;5;234;48;5;61m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;237;48;5;236m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;235;48;5;235m▄\x1b[48;5;234m \x1b[38;5;234;48;5;60m▄\x1b[38;5;234;48;5;61m▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;61m▄\x1b[m
|
||||||
|
\x1b[48;5;234m \x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;234m▄▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;236;48;5;103m▄\x1b[38;5;237;48;5;103m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;61m▄▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;234;48;5;235m▄▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;151;48;5;59m▄\x1b[38;5;151;48;5;247m▄\x1b[38;5;151;48;5;248m▄\x1b[38;5;151;48;5;247m▄▄▄\x1b[38;5;151;48;5;248m▄\x1b[38;5;151;48;5;247m▄\x1b[38;5;151;48;5;246m▄\x1b[38;5;151;48;5;247m▄▄\x1b[38;5;151;48;5;246m▄▄\x1b[38;5;151;48;5;245m▄\x1b[38;5;151;48;5;246m▄▄▄\x1b[38;5;151;48;5;247m▄▄▄▄▄▄\x1b[38;5;151;48;5;249m▄\x1b[38;5;151;48;5;152m▄\x1b[38;5;151;48;5;145m▄\x1b[38;5;151;48;5;247m▄\x1b[38;5;151;48;5;246m▄\x1b[38;5;151;48;5;247m▄▄▄▄▄\x1b[38;5;151;48;5;248m▄\x1b[38;5;151;48;5;144m▄\x1b[38;5;151;48;5;248m▄\x1b[38;5;151;48;5;145m▄▄▄▄\x1b[38;5;151;48;5;249m▄\x1b[38;5;151;48;5;145m▄▄\x1b[38;5;151;48;5;252m▄\x1b[38;5;151;48;5;251m▄\x1b[38;5;151;48;5;7m▄\x1b[38;5;151;48;5;250m▄▄\x1b[38;5;151;48;5;187m▄▄\x1b[38;5;151;48;5;251m▄\x1b[38;5;151;48;5;152m▄\x1b[38;5;7;48;5;152m▄\x1b[38;5;251;48;5;152m▄▄▄\x1b[38;5;252;48;5;152m▄▄▄▄\x1b[38;5;188;48;5;152m▄▄\x1b[38;5;188;48;5;252m▄\x1b[38;5;152;48;5;252m▄▄\x1b[38;5;252;48;5;251m▄\x1b[38;5;252;48;5;7m▄\x1b[38;5;74;48;5;235m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;61m▄▄\x1b[38;5;234;48;5;60m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[38;5;238;48;5;234m▄\x1b[38;5;61;48;5;104m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;61;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;237;48;5;237m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;97;48;5;60m▄\x1b[38;5;235;48;5;60m▄\x1b[38;5;235;48;5;235m▄\x1b[48;5;234m \x1b[38;5;238;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄\x1b[m
|
||||||
|
\x1b[48;5;234m \x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;235m▄\x1b[48;5;235m \x1b[38;5;60;48;5;60m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;247;48;5;108m▄\x1b[38;5;150;48;5;108m▄▄▄▄▄\x1b[38;5;151;48;5;108m▄\x1b[38;5;150;48;5;108m▄\x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;234;48;5;239m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;253;48;5;187m▄\x1b[38;5;151;48;5;151m▄▄▄▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄▄▄▄▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;115;48;5;151m▄\x1b[38;5;116;48;5;151m▄▄\x1b[38;5;110;48;5;151m▄▄\x1b[38;5;110;48;5;251m▄▄\x1b[38;5;110;48;5;110m▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;234;48;5;239m▄\x1b[38;5;234;48;5;60m▄▄▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;103;48;5;110m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;238;48;5;238m▄\x1b[38;5;61;48;5;60m▄\x1b[38;5;236;48;5;97m▄\x1b[38;5;237;48;5;235m▄\x1b[38;5;238;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄\x1b[m
|
||||||
|
\x1b[38;5;235;48;5;234m▄\x1b[38;5;236;48;5;234m▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;97;48;5;238m▄\x1b[38;5;60;48;5;237m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;60;48;5;235m▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;97;48;5;238m▄\x1b[38;5;97;48;5;237m▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;194;48;5;194m▄\x1b[38;5;151;48;5;151m▄▄▄\x1b[38;5;151;48;5;103m▄\x1b[38;5;151;48;5;151m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;115;48;5;151m▄\x1b[38;5;109;48;5;151m▄▄▄▄▄▄▄▄\x1b[38;5;110;48;5;115m▄\x1b[38;5;74;48;5;115m▄▄\x1b[38;5;110;48;5;115m▄▄\x1b[38;5;74;48;5;110m▄\x1b[38;5;110;48;5;110m▄▄▄▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄▄▄▄▄▄▄\x1b[38;5;73;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄▄▄\x1b[38;5;67;48;5;234m▄\x1b[38;5;236;48;5;103m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;61;48;5;237m▄\x1b[38;5;61;48;5;234m▄\x1b[38;5;60;48;5;234m▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;239;48;5;234m▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[m
|
||||||
|
\x1b[38;5;238;48;5;60m▄▄\x1b[38;5;237;48;5;60m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;60;48;5;60m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[38;5;60;48;5;235m▄▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;60;48;5;235m▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;60;48;5;235m▄▄\x1b[38;5;60;48;5;236m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;234;48;5;235m▄\x1b[48;5;234m \x1b[38;5;194;48;5;194m▄\x1b[38;5;151;48;5;151m▄▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[38;5;103;48;5;103m▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;104;48;5;103m▄\x1b[38;5;110;48;5;103m▄▄▄▄\x1b[38;5;74;48;5;103m▄\x1b[38;5;234;48;5;103m▄▄\x1b[38;5;235;48;5;103m▄▄▄▄\x1b[38;5;234;48;5;103m▄\x1b[38;5;235;48;5;103m▄\x1b[38;5;234;48;5;103m▄▄▄▄▄\x1b[38;5;235;48;5;103m▄\x1b[38;5;234;48;5;103m▄\x1b[38;5;235;48;5;103m▄▄\x1b[38;5;234;48;5;103m▄▄▄\x1b[38;5;235;48;5;97m▄\x1b[38;5;110;48;5;97m▄\x1b[38;5;73;48;5;235m▄▄\x1b[38;5;104;48;5;235m▄▄▄\x1b[38;5;103;48;5;235m▄\x1b[38;5;97;48;5;235m▄▄\x1b[38;5;237;48;5;235m▄▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;236;48;5;234m▄▄▄▄\x1b[38;5;236;48;5;235m▄▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;103;48;5;60m▄\x1b[38;5;110;48;5;110m▄▄▄▄▄▄\x1b[38;5;97;48;5;110m▄\x1b[38;5;74;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;110;48;5;103m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;110;48;5;234m▄\x1b[38;5;74;48;5;234m▄▄\x1b[38;5;234;48;5;234m▄▄▄▄▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[m
|
||||||
|
\x1b[38;5;61;48;5;238m▄▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;238m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;234;48;5;61m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄\x1b[38;5;234;48;5;97m▄\x1b[38;5;234;48;5;96m▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;248;48;5;234m▄\x1b[38;5;151;48;5;235m▄\x1b[38;5;187;48;5;193m▄\x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[38;5;103;48;5;103m▄▄\x1b[38;5;103;48;5;237m▄\x1b[38;5;61;48;5;103m▄\x1b[38;5;110;48;5;103m▄\x1b[38;5;234;48;5;103m▄\x1b[38;5;234;48;5;110m▄▄\x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;170;48;5;234m▄\x1b[38;5;206;48;5;234m▄\x1b[38;5;170;48;5;234m▄\x1b[38;5;212;48;5;234m▄\x1b[38;5;206;48;5;234m▄\x1b[38;5;176;48;5;234m▄\x1b[38;5;170;48;5;235m▄\x1b[38;5;212;48;5;235m▄\x1b[38;5;212;48;5;234m▄\x1b[38;5;170;48;5;235m▄▄\x1b[38;5;206;48;5;235m▄\x1b[38;5;176;48;5;234m▄\x1b[38;5;170;48;5;234m▄▄▄\x1b[38;5;206;48;5;234m▄\x1b[38;5;170;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;110m▄▄▄\x1b[38;5;234;48;5;104m▄\x1b[38;5;234;48;5;103m▄\x1b[38;5;73;48;5;103m▄\x1b[38;5;74;48;5;103m▄\x1b[38;5;103;48;5;103m▄▄▄\x1b[38;5;253;48;5;251m▄\x1b[38;5;110;48;5;110m▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄▄▄\x1b[38;5;235;48;5;97m▄\x1b[38;5;103;48;5;110m▄\x1b[38;5;110;48;5;110m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;61;48;5;60m▄\x1b[38;5;234;48;5;97m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;103;48;5;103m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;234;48;5;74m▄\x1b[38;5;104;48;5;74m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;235;48;5;235m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[m
|
||||||
|
\x1b[38;5;234;48;5;236m▄▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;235m▄▄▄\x1b[38;5;238;48;5;235m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;60;48;5;235m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;233;48;5;234m▄\x1b[38;5;151;48;5;234m▄\x1b[38;5;151;48;5;235m▄\x1b[38;5;151;48;5;151m▄▄▄\x1b[38;5;253;48;5;253m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄▄\x1b[38;5;103;48;5;103m▄▄\x1b[38;5;110;48;5;103m▄\x1b[38;5;234;48;5;233m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;236;48;5;65m▄\x1b[38;5;237;48;5;66m▄\x1b[38;5;241;48;5;66m▄\x1b[38;5;241;48;5;236m▄\x1b[38;5;242;48;5;235m▄\x1b[38;5;242;48;5;236m▄\x1b[38;5;96;48;5;236m▄\x1b[38;5;96;48;5;237m▄\x1b[38;5;96;48;5;236m▄▄\x1b[38;5;96;48;5;235m▄\x1b[38;5;132;48;5;235m▄\x1b[38;5;132;48;5;234m▄\x1b[38;5;132;48;5;235m▄\x1b[38;5;132;48;5;234m▄▄▄\x1b[38;5;133;48;5;234m▄\x1b[38;5;169;48;5;235m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;169;48;5;235m▄\x1b[38;5;237;48;5;235m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;234;48;5;110m▄\x1b[38;5;253;48;5;103m▄\x1b[38;5;253;48;5;253m▄▄\x1b[38;5;110;48;5;110m▄▄▄▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;97;48;5;235m▄\x1b[38;5;103;48;5;110m▄\x1b[38;5;110;48;5;110m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;103;48;5;234m▄\x1b[38;5;237;48;5;60m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;238;48;5;234m▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;235;48;5;234m▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;61;48;5;74m▄\x1b[38;5;67;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;239;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[m
|
||||||
|
\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;234m▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;60;48;5;60m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄▄▄▄\x1b[38;5;187;48;5;187m▄\x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[38;5;253;48;5;253m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄\x1b[38;5;103;48;5;103m▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;238;48;5;72m▄\x1b[38;5;60;48;5;114m▄\x1b[38;5;60;48;5;110m▄\x1b[38;5;239;48;5;110m▄\x1b[38;5;235;48;5;170m▄▄▄▄▄▄▄▄▄▄\x1b[38;5;235;48;5;206m▄\x1b[38;5;235;48;5;170m▄\x1b[38;5;235;48;5;169m▄\x1b[38;5;235;48;5;235m▄▄▄▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;235m▄▄\x1b[38;5;235;48;5;235m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;67;48;5;110m▄\x1b[48;5;253m \x1b[48;5;110m \x1b[38;5;110;48;5;110m▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;60;48;5;235m▄\x1b[38;5;60;48;5;239m▄\x1b[38;5;97;48;5;103m▄\x1b[38;5;110;48;5;110m▄\x1b[38;5;74;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;97;48;5;97m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;236;48;5;235m▄\x1b[38;5;237;48;5;237m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;68;48;5;68m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;234;48;5;238m▄\x1b[38;5;234;48;5;234m▄▄▄▄\x1b[m
|
||||||
|
\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;61m▄▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;234;48;5;61m▄▄▄\x1b[38;5;234;48;5;60m▄▄\x1b[38;5;234;48;5;97m▄▄\x1b[38;5;234;48;5;61m▄\x1b[38;5;235;48;5;61m▄\x1b[38;5;235;48;5;97m▄\x1b[48;5;235m \x1b[38;5;187;48;5;187m▄\x1b[38;5;151;48;5;151m▄▄▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[38;5;253;48;5;253m▄\x1b[38;5;151;48;5;151m▄▄▄▄\x1b[38;5;103;48;5;103m▄\x1b[38;5;110;48;5;110m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;71;48;5;238m▄\x1b[38;5;110;48;5;240m▄\x1b[38;5;110;48;5;60m▄▄\x1b[38;5;133;48;5;97m▄\x1b[38;5;169;48;5;133m▄\x1b[38;5;170;48;5;133m▄\x1b[38;5;133;48;5;133m▄▄▄▄▄▄▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;235m▄▄\x1b[38;5;235;48;5;235m▄▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄▄\x1b[38;5;234;48;5;234m▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;73;48;5;73m▄\x1b[38;5;253;48;5;253m▄▄\x1b[38;5;110;48;5;110m▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;60m▄▄\x1b[38;5;234;48;5;97m▄\x1b[38;5;97;48;5;103m▄\x1b[38;5;74;48;5;74m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;238m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;104;48;5;68m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;60;48;5;233m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[m
|
||||||
|
\x1b[38;5;234;48;5;234m▄\x1b[38;5;60;48;5;235m▄\x1b[38;5;61;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄▄▄▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;237m▄\x1b[48;5;235m \x1b[38;5;187;48;5;187m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄▄▄\x1b[38;5;253;48;5;253m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[38;5;103;48;5;103m▄\x1b[38;5;110;48;5;110m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;71;48;5;234m▄\x1b[38;5;72;48;5;234m▄\x1b[38;5;74;48;5;235m▄▄\x1b[38;5;176;48;5;235m▄▄\x1b[38;5;151;48;5;250m▄▄\x1b[38;5;151;48;5;249m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;151;48;5;249m▄\x1b[38;5;65;48;5;242m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;151;48;5;234m▄\x1b[38;5;151;48;5;151m▄▄▄▄\x1b[38;5;150;48;5;151m▄\x1b[48;5;235m \x1b[38;5;151;48;5;151m▄▄▄▄▄▄\x1b[38;5;240;48;5;59m▄\x1b[38;5;151;48;5;151m▄▄▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;151;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;151;48;5;234m▄\x1b[38;5;151;48;5;151m▄\x1b[48;5;235m \x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;152;48;5;152m▄\x1b[48;5;253m \x1b[48;5;110m \x1b[38;5;110;48;5;110m▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;60m▄\x1b[38;5;97;48;5;60m▄▄\x1b[38;5;97;48;5;103m▄\x1b[38;5;103;48;5;74m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;74;48;5;234m▄\x1b[38;5;97;48;5;104m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;235;48;5;60m▄\x1b[38;5;235;48;5;234m▄\x1b[48;5;234m \x1b[m
|
||||||
|
\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;235;48;5;236m▄\x1b[38;5;97;48;5;236m▄\x1b[38;5;206;48;5;237m▄▄\x1b[38;5;206;48;5;236m▄\x1b[38;5;206;48;5;235m▄▄\x1b[38;5;234;48;5;234m▄▄▄▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;187;48;5;187m▄\x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[38;5;253;48;5;253m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[38;5;103;48;5;103m▄\x1b[38;5;234;48;5;74m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;236;48;5;65m▄\x1b[38;5;242;48;5;109m▄\x1b[38;5;60;48;5;67m▄▄\x1b[38;5;96;48;5;96m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;151;48;5;234m▄▄▄\x1b[38;5;150;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;151m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;151;48;5;239m▄\x1b[38;5;151;48;5;234m▄\x1b[38;5;151;48;5;108m▄\x1b[38;5;234;48;5;151m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;151;48;5;234m▄▄▄\x1b[38;5;235;48;5;234m▄\x1b[48;5;235m \x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;237;48;5;236m▄\x1b[48;5;235m \x1b[38;5;240;48;5;240m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;150;48;5;234m▄▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;151m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;234;48;5;151m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[48;5;234m \x1b[38;5;235;48;5;235m▄\x1b[38;5;116;48;5;152m▄\x1b[38;5;253;48;5;253m▄\x1b[38;5;110;48;5;110m▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄▄\x1b[38;5;234;48;5;234m▄▄▄▄▄▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄▄▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;110;48;5;234m▄\x1b[38;5;104;48;5;68m▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;60;48;5;60m▄▄\x1b[38;5;60;48;5;238m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[m
|
||||||
|
\x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;234;48;5;60m▄▄\x1b[38;5;97;48;5;97m▄\x1b[38;5;206;48;5;206m▄▄▄▄▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;235;48;5;234m▄\x1b[48;5;234m \x1b[38;5;235;48;5;235m▄\x1b[48;5;235m \x1b[38;5;187;48;5;187m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;253;48;5;253m▄\x1b[38;5;151;48;5;151m▄▄▄\x1b[48;5;151m \x1b[38;5;103;48;5;103m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;233;48;5;235m▄\x1b[38;5;233;48;5;71m▄\x1b[38;5;234;48;5;110m▄▄▄\x1b[38;5;234;48;5;140m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;151m▄▄\x1b[38;5;234;48;5;247m▄\x1b[38;5;234;48;5;150m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;108;48;5;151m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;234;48;5;151m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;150m▄▄▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;235;48;5;235m▄\x1b[48;5;234m \x1b[38;5;235;48;5;235m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;237;48;5;236m▄\x1b[38;5;234;48;5;235m▄▄\x1b[38;5;240;48;5;240m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;108m▄\x1b[38;5;234;48;5;108m▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;116;48;5;116m▄\x1b[48;5;253m \x1b[38;5;110;48;5;110m▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[38;5;61;48;5;240m▄\x1b[38;5;61;48;5;60m▄▄\x1b[38;5;103;48;5;103m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;74;48;5;234m▄\x1b[38;5;103;48;5;67m▄\x1b[38;5;234;48;5;110m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;61;48;5;234m▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[m
|
||||||
|
\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;60;48;5;236m▄▄\x1b[38;5;97;48;5;97m▄\x1b[38;5;97;48;5;206m▄▄▄▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;97;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;187;48;5;187m▄\x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;253;48;5;253m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[38;5;103;48;5;103m▄\x1b[48;5;234m \x1b[38;5;239;48;5;71m▄\x1b[38;5;65;48;5;71m▄\x1b[38;5;67;48;5;73m▄\x1b[38;5;66;48;5;110m▄\x1b[38;5;234;48;5;67m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;151m▄▄▄▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;108m▄\x1b[38;5;234;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[48;5;234m \x1b[38;5;234;48;5;151m▄▄▄▄▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;151m▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;240m▄\x1b[38;5;234;48;5;151m▄▄\x1b[38;5;234;48;5;150m▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;151m▄\x1b[38;5;234;48;5;235m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[48;5;234m \x1b[48;5;235m \x1b[38;5;116;48;5;116m▄\x1b[48;5;253m \x1b[38;5;110;48;5;110m▄▄▄▄\x1b[48;5;110m \x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;60;48;5;236m▄\x1b[38;5;60;48;5;235m▄\x1b[38;5;61;48;5;238m▄\x1b[38;5;103;48;5;103m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;97;48;5;234m▄▄\x1b[38;5;97;48;5;238m▄\x1b[38;5;234;48;5;74m▄\x1b[38;5;234;48;5;110m▄\x1b[38;5;234;48;5;61m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;235;48;5;234m▄▄\x1b[38;5;235;48;5;239m▄\x1b[38;5;235;48;5;236m▄\x1b[38;5;235;48;5;239m▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;234;48;5;239m▄▄\x1b[38;5;234;48;5;234m▄\x1b[m
|
||||||
|
\x1b[38;5;61;48;5;234m▄\x1b[38;5;97;48;5;234m▄\x1b[38;5;61;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;239m▄▄\x1b[38;5;60;48;5;237m▄▄\x1b[38;5;60;48;5;235m▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;60;48;5;236m▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;238;48;5;236m▄\x1b[38;5;239;48;5;237m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;187;48;5;187m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[38;5;253;48;5;253m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄▄\x1b[38;5;103;48;5;103m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;71;48;5;239m▄\x1b[38;5;71;48;5;238m▄\x1b[38;5;74;48;5;240m▄\x1b[38;5;67;48;5;239m▄\x1b[38;5;108;48;5;234m▄\x1b[38;5;151;48;5;234m▄▄▄▄\x1b[38;5;237;48;5;235m▄\x1b[38;5;151;48;5;234m▄▄\x1b[38;5;234;48;5;235m▄\x1b[48;5;235m \x1b[38;5;151;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;151;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;151;48;5;234m▄▄\x1b[38;5;65;48;5;234m▄\x1b[38;5;151;48;5;234m▄▄▄▄▄\x1b[38;5;247;48;5;234m▄\x1b[38;5;151;48;5;234m▄▄▄\x1b[38;5;150;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;108;48;5;234m▄\x1b[38;5;151;48;5;234m▄▄▄\x1b[38;5;108;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;151;48;5;234m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;151;48;5;234m▄▄\x1b[38;5;238;48;5;234m▄\x1b[38;5;151;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄\x1b[38;5;151;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;116;48;5;116m▄\x1b[38;5;253;48;5;253m▄\x1b[38;5;110;48;5;110m▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;97m▄\x1b[38;5;235;48;5;97m▄\x1b[38;5;238;48;5;97m▄\x1b[38;5;97;48;5;103m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;60;48;5;235m▄\x1b[38;5;60;48;5;61m▄▄\x1b[38;5;60;48;5;235m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;234;48;5;61m▄\x1b[38;5;234;48;5;60m▄▄\x1b[m
|
||||||
|
\x1b[38;5;238;48;5;237m▄\x1b[38;5;237;48;5;238m▄\x1b[38;5;234;48;5;237m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;235;48;5;60m▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;235;48;5;60m▄▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;235;48;5;235m▄\x1b[38;5;187;48;5;187m▄\x1b[38;5;151;48;5;151m▄▄▄▄▄\x1b[38;5;253;48;5;253m▄\x1b[38;5;151;48;5;151m▄▄▄▄\x1b[38;5;103;48;5;103m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;71;48;5;234m▄▄\x1b[38;5;110;48;5;236m▄\x1b[38;5;67;48;5;236m▄\x1b[38;5;108;48;5;108m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;151;48;5;235m▄▄▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;151;48;5;234m▄\x1b[38;5;151;48;5;235m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;151;48;5;151m▄▄\x1b[48;5;235m \x1b[38;5;234;48;5;235m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;235;48;5;235m▄▄\x1b[38;5;247;48;5;108m▄\x1b[38;5;151;48;5;151m▄\x1b[48;5;234m \x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;59;48;5;59m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;237;48;5;238m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;150;48;5;151m▄\x1b[38;5;144;48;5;234m▄\x1b[38;5;236;48;5;235m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;151;48;5;65m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;116;48;5;116m▄\x1b[48;5;253m \x1b[38;5;110;48;5;110m▄▄▄▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;61;48;5;60m▄▄\x1b[38;5;97;48;5;97m▄▄\x1b[38;5;238;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;238m▄\x1b[38;5;61;48;5;234m▄\x1b[38;5;97;48;5;234m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;236;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[m
|
||||||
|
\x1b[38;5;234;48;5;60m▄▄▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;237;48;5;61m▄\x1b[38;5;237;48;5;60m▄▄\x1b[38;5;237;48;5;61m▄\x1b[38;5;237;48;5;235m▄\x1b[38;5;236;48;5;234m▄▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;60;48;5;239m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;187;48;5;187m▄\x1b[38;5;151;48;5;151m▄▄▄▄▄\x1b[38;5;253;48;5;253m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄▄\x1b[38;5;103;48;5;103m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;65;48;5;238m▄\x1b[38;5;65;48;5;237m▄\x1b[38;5;67;48;5;60m▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;235;48;5;108m▄▄▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;238;48;5;238m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;234;48;5;243m▄\x1b[38;5;235;48;5;243m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;151;48;5;151m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;235m▄\x1b[38;5;247;48;5;247m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;151;48;5;151m▄\x1b[48;5;235m \x1b[38;5;151;48;5;151m▄\x1b[38;5;236;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;65;48;5;241m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;237;48;5;237m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;151m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄\x1b[38;5;116;48;5;116m▄\x1b[38;5;253;48;5;253m▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄▄\x1b[38;5;234;48;5;234m▄▄▄▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;97m▄\x1b[38;5;60;48;5;236m▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;237m▄▄\x1b[38;5;61;48;5;234m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;61;48;5;234m▄\x1b[38;5;60;48;5;234m▄▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;61;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[m
|
||||||
|
\x1b[38;5;234;48;5;239m▄▄▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;234;48;5;239m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;235m \x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;187m \x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄\x1b[38;5;253;48;5;253m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[48;5;103m \x1b[48;5;234m \x1b[38;5;234;48;5;71m▄▄\x1b[38;5;235;48;5;110m▄\x1b[38;5;235;48;5;109m▄\x1b[38;5;234;48;5;8m▄\x1b[38;5;235;48;5;151m▄▄\x1b[38;5;234;48;5;151m▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;151m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;235m▄\x1b[38;5;235;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;235;48;5;238m▄\x1b[38;5;235;48;5;151m▄▄\x1b[38;5;235;48;5;150m▄\x1b[38;5;235;48;5;237m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;235;48;5;151m▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;247m▄\x1b[38;5;234;48;5;151m▄▄▄\x1b[38;5;234;48;5;150m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;235;48;5;238m▄\x1b[38;5;235;48;5;151m▄▄▄\x1b[38;5;234;48;5;238m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;108m▄\x1b[38;5;234;48;5;150m▄\x1b[38;5;234;48;5;240m▄\x1b[38;5;235;48;5;243m▄\x1b[38;5;235;48;5;151m▄\x1b[38;5;235;48;5;237m▄\x1b[38;5;235;48;5;238m▄\x1b[38;5;235;48;5;150m▄\x1b[38;5;235;48;5;235m▄\x1b[48;5;234m \x1b[38;5;234;48;5;237m▄\x1b[38;5;235;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;150m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;116;48;5;116m▄\x1b[38;5;253;48;5;253m▄\x1b[38;5;110;48;5;110m▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;60;48;5;60m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;235;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;237;48;5;237m▄\x1b[38;5;235;48;5;234m▄▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;235;48;5;60m▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[m
|
||||||
|
\x1b[38;5;74;48;5;234m▄\x1b[38;5;66;48;5;234m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;239m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;234;48;5;60m▄\x1b[48;5;234m \x1b[38;5;187;48;5;187m▄\x1b[38;5;151;48;5;151m▄▄▄▄▄\x1b[38;5;253;48;5;253m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄\x1b[48;5;151m \x1b[38;5;103;48;5;103m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;239m▄\x1b[38;5;65;48;5;71m▄\x1b[38;5;67;48;5;74m▄\x1b[38;5;67;48;5;73m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;65;48;5;234m▄\x1b[38;5;8;48;5;234m▄\x1b[38;5;151;48;5;234m▄▄\x1b[38;5;235;48;5;234m▄\x1b[48;5;234m \x1b[38;5;243;48;5;234m▄\x1b[38;5;151;48;5;234m▄▄▄▄▄\x1b[38;5;239;48;5;234m▄\x1b[38;5;240;48;5;234m▄\x1b[38;5;151;48;5;234m▄▄▄▄\x1b[38;5;151;48;5;233m▄\x1b[38;5;108;48;5;235m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;150;48;5;234m▄\x1b[38;5;151;48;5;234m▄▄▄\x1b[38;5;151;48;5;233m▄\x1b[38;5;108;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[48;5;235m \x1b[38;5;116;48;5;116m▄\x1b[38;5;253;48;5;253m▄\x1b[38;5;110;48;5;110m▄▄▄▄▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;60;48;5;60m▄\x1b[38;5;60;48;5;61m▄▄▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;238;48;5;234m▄\x1b[38;5;60;48;5;234m▄▄\x1b[38;5;60;48;5;60m▄▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[m
|
||||||
|
\x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;234;48;5;97m▄▄\x1b[38;5;235;48;5;74m▄\x1b[38;5;97;48;5;74m▄\x1b[38;5;103;48;5;234m▄▄\x1b[38;5;67;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;60;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;235m▄\x1b[38;5;187;48;5;187m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;151m▄▄▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;253;48;5;253m▄\x1b[38;5;151;48;5;151m▄▄\x1b[48;5;151m \x1b[38;5;103;48;5;103m▄\x1b[38;5;74;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;71;48;5;237m▄\x1b[38;5;72;48;5;237m▄\x1b[38;5;74;48;5;237m▄\x1b[38;5;234;48;5;235m▄\x1b[48;5;234m \x1b[38;5;234;48;5;108m▄\x1b[38;5;234;48;5;151m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;235;48;5;235m▄▄\x1b[38;5;108;48;5;108m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄\x1b[48;5;234m \x1b[38;5;235;48;5;235m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;240;48;5;240m▄\x1b[38;5;65;48;5;240m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;151;48;5;151m▄\x1b[38;5;108;48;5;108m▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;151;48;5;151m▄\x1b[48;5;235m \x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄\x1b[48;5;235m \x1b[38;5;234;48;5;235m▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄▄▄▄\x1b[48;5;235m \x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;235;48;5;235m▄\x1b[38;5;110;48;5;116m▄\x1b[38;5;253;48;5;253m▄\x1b[38;5;110;48;5;110m▄▄▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;60;48;5;235m▄\x1b[38;5;61;48;5;236m▄▄\x1b[38;5;97;48;5;237m▄\x1b[38;5;60;48;5;60m▄\x1b[48;5;234m \x1b[38;5;60;48;5;234m▄\x1b[38;5;61;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;238;48;5;238m▄\x1b[38;5;60;48;5;234m▄▄▄▄\x1b[38;5;238;48;5;235m▄\x1b[38;5;61;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[m
|
||||||
|
\x1b[38;5;234;48;5;234m▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;61m▄\x1b[38;5;234;48;5;104m▄\x1b[38;5;235;48;5;74m▄\x1b[38;5;104;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;187;48;5;187m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;237;48;5;151m▄▄\x1b[38;5;236;48;5;151m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;253;48;5;253m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄▄\x1b[38;5;103;48;5;103m▄\x1b[38;5;110;48;5;110m▄\x1b[48;5;234m \x1b[38;5;71;48;5;234m▄▄\x1b[38;5;67;48;5;238m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;234;48;5;235m▄\x1b[48;5;234m \x1b[38;5;234;48;5;108m▄\x1b[38;5;151;48;5;151m▄▄▄▄▄\x1b[38;5;239;48;5;239m▄\x1b[38;5;234;48;5;65m▄\x1b[38;5;108;48;5;151m▄\x1b[38;5;151;48;5;151m▄▄▄▄\x1b[38;5;108;48;5;108m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;8;48;5;151m▄\x1b[38;5;151;48;5;151m▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;235m▄\x1b[48;5;235m \x1b[38;5;235;48;5;234m▄\x1b[48;5;235m \x1b[38;5;234;48;5;235m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;188;48;5;188m▄\x1b[38;5;253;48;5;253m▄\x1b[38;5;110;48;5;110m▄▄▄▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;236;48;5;60m▄▄▄▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;238;48;5;238m▄\x1b[38;5;234;48;5;239m▄\x1b[38;5;234;48;5;60m▄▄▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;61m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄\x1b[m
|
||||||
|
\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;235m \x1b[38;5;234;48;5;235m▄\x1b[48;5;234m \x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;67m▄\x1b[38;5;74;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;187;48;5;187m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;151;48;5;235m▄▄▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;253;48;5;253m▄\x1b[38;5;151;48;5;151m▄▄▄▄\x1b[38;5;103;48;5;103m▄\x1b[38;5;110;48;5;110m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;65m▄\x1b[38;5;236;48;5;71m▄\x1b[38;5;236;48;5;110m▄\x1b[38;5;235;48;5;110m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;65;48;5;234m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;65;48;5;234m▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;239;48;5;234m▄\x1b[38;5;65;48;5;234m▄▄▄▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;240;48;5;239m▄\x1b[38;5;238;48;5;234m▄\x1b[38;5;65;48;5;234m▄▄▄▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;108;48;5;108m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;65;48;5;234m▄▄▄▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;235m▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;66;48;5;235m▄\x1b[38;5;252;48;5;188m▄\x1b[48;5;253m \x1b[38;5;110;48;5;110m▄▄▄▄▄▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;60;48;5;61m▄▄▄\x1b[38;5;60;48;5;60m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;237;48;5;238m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;60;48;5;61m▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄▄\x1b[48;5;235m \x1b[38;5;235;48;5;234m▄\x1b[48;5;234m \x1b[m
|
||||||
|
\x1b[38;5;234;48;5;234m▄▄▄▄▄▄▄\x1b[48;5;234m \x1b[48;5;235m \x1b[38;5;235;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;97;48;5;110m▄\x1b[38;5;74;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;187;48;5;187m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;235m▄▄▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;187;48;5;253m▄\x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[38;5;103;48;5;103m▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;238;48;5;71m▄\x1b[38;5;237;48;5;71m▄\x1b[38;5;67;48;5;74m▄\x1b[38;5;238;48;5;234m▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;151m▄▄▄\x1b[38;5;234;48;5;150m▄\x1b[38;5;234;48;5;65m▄\x1b[38;5;234;48;5;108m▄\x1b[38;5;234;48;5;151m▄▄▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;59m▄\x1b[38;5;234;48;5;151m▄▄▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;151m▄▄▄▄▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;235m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;116;48;5;110m▄\x1b[38;5;253;48;5;253m▄\x1b[48;5;253m \x1b[38;5;110;48;5;110m▄▄▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;61;48;5;235m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;60;48;5;235m▄\x1b[38;5;60;48;5;60m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;236;48;5;237m▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;235m▄\x1b[48;5;235m \x1b[38;5;235;48;5;235m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[m
|
||||||
|
\x1b[38;5;234;48;5;74m▄\x1b[38;5;103;48;5;234m▄\x1b[38;5;74;48;5;234m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;235m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;60;48;5;68m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;67;48;5;234m▄\x1b[38;5;109;48;5;234m▄\x1b[38;5;187;48;5;187m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;235;48;5;151m▄▄▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;253;48;5;187m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[38;5;103;48;5;103m▄▄\x1b[38;5;110;48;5;110m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;235m▄▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;152;48;5;116m▄\x1b[48;5;253m \x1b[38;5;253;48;5;253m▄\x1b[38;5;110;48;5;110m▄▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[38;5;235;48;5;60m▄▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;235;48;5;60m▄\x1b[38;5;60;48;5;60m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;239m▄▄▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[48;5;235m \x1b[38;5;234;48;5;234m▄▄\x1b[m
|
||||||
|
\x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;234;48;5;104m▄\x1b[38;5;235;48;5;110m▄\x1b[38;5;103;48;5;234m▄\x1b[38;5;66;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;73;48;5;234m▄\x1b[38;5;103;48;5;234m▄\x1b[38;5;236;48;5;74m▄\x1b[38;5;234;48;5;110m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;187;48;5;187m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;238;48;5;150m▄\x1b[38;5;237;48;5;150m▄▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;253;48;5;253m▄\x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;103;48;5;103m▄▄▄\x1b[38;5;110;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;74;48;5;234m▄\x1b[38;5;253;48;5;109m▄\x1b[38;5;253;48;5;253m▄▄▄\x1b[38;5;110;48;5;110m▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;61;48;5;234m▄▄\x1b[38;5;97;48;5;235m▄▄▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄\x1b[48;5;234m \x1b[48;5;235m \x1b[38;5;235;48;5;235m▄\x1b[48;5;235m \x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[m
|
||||||
|
\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;97m▄\x1b[38;5;235;48;5;74m▄\x1b[38;5;110;48;5;234m▄\x1b[38;5;67;48;5;234m▄\x1b[38;5;67;48;5;66m▄\x1b[38;5;234;48;5;74m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;193;48;5;187m▄\x1b[38;5;151;48;5;151m▄▄▄▄\x1b[48;5;151m \x1b[38;5;253;48;5;253m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;103;48;5;103m▄▄\x1b[38;5;252;48;5;103m▄\x1b[38;5;253;48;5;104m▄\x1b[38;5;253;48;5;188m▄\x1b[38;5;253;48;5;252m▄\x1b[38;5;253;48;5;110m▄\x1b[38;5;253;48;5;241m▄\x1b[38;5;188;48;5;234m▄\x1b[38;5;152;48;5;234m▄\x1b[38;5;116;48;5;234m▄▄\x1b[38;5;110;48;5;235m▄▄\x1b[38;5;234;48;5;234m▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;235;48;5;234m▄\x1b[38;5;239;48;5;234m▄▄▄▄▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;110;48;5;234m▄▄\x1b[38;5;252;48;5;234m▄\x1b[38;5;252;48;5;235m▄\x1b[38;5;188;48;5;237m▄\x1b[38;5;253;48;5;237m▄\x1b[38;5;253;48;5;116m▄▄\x1b[38;5;253;48;5;253m▄▄▄\x1b[38;5;253;48;5;251m▄\x1b[38;5;253;48;5;253m▄\x1b[38;5;188;48;5;253m▄\x1b[38;5;110;48;5;110m▄▄▄▄▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;236;48;5;239m▄▄\x1b[38;5;237;48;5;239m▄\x1b[38;5;97;48;5;239m▄\x1b[38;5;97;48;5;97m▄\x1b[38;5;234;48;5;97m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;234;48;5;61m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄▄▄\x1b[m
|
||||||
|
\x1b[38;5;236;48;5;234m▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;236;48;5;234m▄▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;74;48;5;234m▄\x1b[38;5;235;48;5;74m▄\x1b[38;5;234;48;5;67m▄\x1b[38;5;240;48;5;234m▄\x1b[38;5;239;48;5;234m▄\x1b[38;5;237;48;5;234m▄▄\x1b[38;5;238;48;5;234m▄▄▄▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;235;48;5;238m▄\x1b[38;5;234;48;5;248m▄\x1b[38;5;235;48;5;151m▄\x1b[38;5;247;48;5;151m▄\x1b[38;5;150;48;5;151m▄\x1b[38;5;187;48;5;253m▄\x1b[38;5;151;48;5;151m▄▄▄\x1b[48;5;151m \x1b[38;5;151;48;5;103m▄\x1b[38;5;151;48;5;252m▄\x1b[38;5;151;48;5;188m▄\x1b[38;5;151;48;5;253m▄▄▄▄▄▄▄▄▄\x1b[38;5;151;48;5;188m▄▄\x1b[38;5;151;48;5;253m▄\x1b[38;5;151;48;5;188m▄\x1b[38;5;7;48;5;188m▄\x1b[38;5;251;48;5;253m▄\x1b[38;5;152;48;5;253m▄\x1b[38;5;252;48;5;152m▄▄\x1b[38;5;152;48;5;116m▄\x1b[38;5;252;48;5;116m▄▄▄▄▄▄\x1b[38;5;188;48;5;116m▄▄\x1b[38;5;252;48;5;116m▄▄▄▄▄\x1b[38;5;152;48;5;116m▄\x1b[38;5;152;48;5;152m▄\x1b[38;5;152;48;5;188m▄▄▄▄\x1b[38;5;152;48;5;253m▄▄\x1b[38;5;116;48;5;253m▄\x1b[38;5;110;48;5;253m▄▄▄▄▄▄▄▄▄▄\x1b[38;5;110;48;5;188m▄▄▄▄\x1b[38;5;110;48;5;146m▄\x1b[38;5;110;48;5;110m▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;237;48;5;61m▄\x1b[38;5;238;48;5;61m▄\x1b[38;5;60;48;5;61m▄\x1b[38;5;97;48;5;97m▄\x1b[38;5;238;48;5;97m▄\x1b[38;5;234;48;5;97m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;236;48;5;234m▄▄\x1b[38;5;237;48;5;234m▄▄\x1b[38;5;236;48;5;234m▄▄\x1b[38;5;238;48;5;234m▄\x1b[38;5;237;48;5;234m▄▄\x1b[m
|
||||||
|
\x1b[38;5;235;48;5;97m▄\x1b[38;5;60;48;5;239m▄\x1b[38;5;240;48;5;97m▄\x1b[38;5;60;48;5;97m▄▄\x1b[38;5;60;48;5;103m▄\x1b[38;5;109;48;5;236m▄\x1b[38;5;234;48;5;73m▄\x1b[38;5;243;48;5;235m▄\x1b[38;5;108;48;5;242m▄\x1b[38;5;243;48;5;150m▄\x1b[38;5;239;48;5;151m▄\x1b[38;5;65;48;5;151m▄\x1b[38;5;65;48;5;150m▄\x1b[38;5;59;48;5;150m▄\x1b[38;5;240;48;5;151m▄\x1b[38;5;59;48;5;150m▄\x1b[38;5;65;48;5;150m▄\x1b[38;5;238;48;5;150m▄\x1b[38;5;243;48;5;236m▄\x1b[38;5;65;48;5;150m▄\x1b[38;5;65;48;5;236m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;187;48;5;193m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄▄▄▄▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄▄▄▄▄\x1b[38;5;151;48;5;115m▄\x1b[38;5;115;48;5;115m▄▄▄▄▄\x1b[38;5;115;48;5;110m▄▄▄▄\x1b[38;5;110;48;5;110m▄▄▄▄▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄▄▄▄▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄▄▄▄▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;61;48;5;236m▄\x1b[38;5;97;48;5;236m▄\x1b[38;5;97;48;5;97m▄\x1b[38;5;234;48;5;97m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;234;48;5;60m▄\x1b[38;5;234;48;5;97m▄▄\x1b[38;5;237;48;5;97m▄\x1b[38;5;238;48;5;97m▄\x1b[38;5;237;48;5;97m▄\x1b[38;5;238;48;5;97m▄\x1b[38;5;238;48;5;237m▄\x1b[38;5;237;48;5;97m▄▄▄\x1b[38;5;238;48;5;97m▄▄▄▄\x1b[38;5;234;48;5;97m▄\x1b[m
|
||||||
|
\x1b[38;5;238;48;5;97m▄\x1b[38;5;237;48;5;97m▄\x1b[38;5;236;48;5;109m▄\x1b[38;5;235;48;5;115m▄\x1b[38;5;237;48;5;151m▄\x1b[38;5;235;48;5;236m▄\x1b[38;5;110;48;5;74m▄\x1b[38;5;241;48;5;151m▄\x1b[38;5;237;48;5;151m▄\x1b[38;5;238;48;5;151m▄\x1b[38;5;239;48;5;150m▄\x1b[38;5;239;48;5;151m▄▄▄▄\x1b[38;5;237;48;5;151m▄▄\x1b[38;5;240;48;5;108m▄\x1b[38;5;239;48;5;150m▄\x1b[38;5;59;48;5;150m▄\x1b[38;5;65;48;5;150m▄\x1b[38;5;240;48;5;150m▄▄\x1b[38;5;235;48;5;234m▄▄\x1b[38;5;253;48;5;188m▄\x1b[38;5;151;48;5;151m▄▄▄▄\x1b[38;5;103;48;5;103m▄\x1b[38;5;236;48;5;238m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;60;48;5;243m▄\x1b[38;5;150;48;5;239m▄\x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄▄▄\x1b[48;5;151m \x1b[38;5;151;48;5;151m▄\x1b[38;5;151;48;5;115m▄\x1b[38;5;151;48;5;109m▄\x1b[38;5;109;48;5;109m▄\x1b[38;5;73;48;5;109m▄▄▄▄▄\x1b[38;5;109;48;5;109m▄\x1b[38;5;110;48;5;109m▄▄▄▄▄\x1b[38;5;110;48;5;110m▄\x1b[38;5;116;48;5;110m▄\x1b[38;5;110;48;5;110m▄▄▄▄▄▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄▄▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;97;48;5;234m▄▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;110;48;5;110m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄▄▄\x1b[38;5;152;48;5;152m▄\x1b[38;5;110;48;5;110m▄▄▄▄▄\x1b[38;5;97;48;5;234m▄\x1b[38;5;97;48;5;97m▄\x1b[38;5;234;48;5;97m▄\x1b[38;5;234;48;5;234m▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;234;48;5;60m▄▄▄▄\x1b[38;5;239;48;5;97m▄\x1b[38;5;238;48;5;97m▄\x1b[38;5;60;48;5;97m▄\x1b[38;5;234;48;5;97m▄\x1b[38;5;238;48;5;97m▄\x1b[38;5;239;48;5;97m▄\x1b[38;5;240;48;5;97m▄▄\x1b[m
|
||||||
|
\x1b[38;5;234;48;5;109m▄\x1b[38;5;233;48;5;114m▄\x1b[38;5;234;48;5;151m▄\x1b[38;5;233;48;5;150m▄\x1b[38;5;234;48;5;150m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;110;48;5;110m▄\x1b[38;5;60;48;5;151m▄\x1b[38;5;233;48;5;240m▄\x1b[38;5;234;48;5;150m▄▄\x1b[38;5;233;48;5;150m▄\x1b[38;5;233;48;5;151m▄▄\x1b[38;5;233;48;5;150m▄\x1b[38;5;234;48;5;108m▄\x1b[38;5;233;48;5;150m▄▄▄▄▄\x1b[38;5;233;48;5;151m▄\x1b[38;5;234;48;5;150m▄\x1b[38;5;233;48;5;150m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;103;48;5;188m▄\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;151;48;5;248m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;151;48;5;248m▄\x1b[38;5;151;48;5;151m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;115;48;5;151m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;115;48;5;151m▄▄\x1b[38;5;115;48;5;115m▄\x1b[38;5;151;48;5;115m▄\x1b[38;5;115;48;5;109m▄▄\x1b[38;5;115;48;5;115m▄▄\x1b[38;5;115;48;5;109m▄▄\x1b[38;5;109;48;5;109m▄\x1b[38;5;115;48;5;109m▄\x1b[38;5;116;48;5;110m▄▄▄▄\x1b[38;5;110;48;5;110m▄▄▄\x1b[48;5;110m \x1b[38;5;110;48;5;110m▄▄\x1b[38;5;152;48;5;237m▄\x1b[38;5;152;48;5;235m▄\x1b[38;5;152;48;5;234m▄▄\x1b[38;5;152;48;5;235m▄\x1b[38;5;152;48;5;234m▄▄▄\x1b[38;5;110;48;5;110m▄\x1b[38;5;110;48;5;104m▄\x1b[38;5;188;48;5;234m▄\x1b[38;5;188;48;5;109m▄\x1b[38;5;252;48;5;109m▄\x1b[38;5;188;48;5;109m▄\x1b[38;5;188;48;5;73m▄▄\x1b[38;5;152;48;5;73m▄\x1b[38;5;253;48;5;152m▄\x1b[38;5;110;48;5;110m▄\x1b[38;5;110;48;5;103m▄\x1b[38;5;110;48;5;110m▄\x1b[38;5;103;48;5;110m▄\x1b[38;5;110;48;5;110m▄\x1b[38;5;234;48;5;97m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;234;48;5;67m▄\x1b[38;5;236;48;5;66m▄\x1b[38;5;234;48;5;74m▄▄▄\x1b[38;5;233;48;5;74m▄\x1b[38;5;234;48;5;110m▄\x1b[38;5;232;48;5;110m▄\x1b[38;5;233;48;5;110m▄▄\x1b[m
|
||||||
|
\x1b[38;5;108;48;5;241m▄\x1b[38;5;108;48;5;151m▄\x1b[38;5;8;48;5;151m▄\x1b[38;5;243;48;5;151m▄\x1b[38;5;65;48;5;235m▄\x1b[38;5;59;48;5;234m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;67m▄\x1b[38;5;97;48;5;239m▄\x1b[38;5;110;48;5;151m▄\x1b[38;5;110;48;5;150m▄\x1b[38;5;234;48;5;150m▄\x1b[38;5;237;48;5;151m▄\x1b[38;5;65;48;5;151m▄\x1b[38;5;240;48;5;150m▄▄▄▄\x1b[38;5;237;48;5;151m▄\x1b[38;5;240;48;5;151m▄\x1b[38;5;59;48;5;150m▄▄\x1b[38;5;65;48;5;150m▄\x1b[38;5;243;48;5;150m▄▄\x1b[38;5;65;48;5;61m▄\x1b[38;5;243;48;5;151m▄\x1b[38;5;234;48;5;151m▄\x1b[38;5;234;48;5;248m▄▄▄▄▄▄▄▄▄▄\x1b[38;5;235;48;5;248m▄▄▄\x1b[38;5;234;48;5;248m▄▄\x1b[38;5;235;48;5;248m▄▄\x1b[38;5;234;48;5;248m▄\x1b[38;5;234;48;5;145m▄\x1b[38;5;235;48;5;248m▄\x1b[38;5;234;48;5;248m▄\x1b[38;5;234;48;5;145m▄\x1b[38;5;235;48;5;145m▄\x1b[38;5;235;48;5;248m▄\x1b[38;5;235;48;5;145m▄▄\x1b[38;5;235;48;5;249m▄▄\x1b[38;5;234;48;5;109m▄\x1b[38;5;234;48;5;250m▄\x1b[38;5;234;48;5;109m▄▄▄\x1b[38;5;235;48;5;109m▄\x1b[38;5;235;48;5;110m▄\x1b[38;5;234;48;5;110m▄\x1b[38;5;235;48;5;110m▄\x1b[38;5;234;48;5;110m▄\x1b[38;5;235;48;5;110m▄\x1b[38;5;234;48;5;110m▄\x1b[38;5;235;48;5;110m▄▄\x1b[38;5;234;48;5;110m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;234;48;5;104m▄\x1b[38;5;103;48;5;103m▄\x1b[38;5;234;48;5;110m▄\x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;235;48;5;66m▄\x1b[38;5;67;48;5;67m▄▄\x1b[38;5;73;48;5;73m▄▄\x1b[38;5;73;48;5;74m▄\x1b[38;5;73;48;5;66m▄\x1b[38;5;236;48;5;74m▄\x1b[38;5;67;48;5;74m▄▄\x1b[38;5;67;48;5;110m▄\x1b[38;5;67;48;5;74m▄\x1b[38;5;66;48;5;74m▄\x1b[38;5;66;48;5;240m▄\x1b[m
|
||||||
|
\x1b[38;5;151;48;5;151m▄▄\x1b[38;5;150;48;5;150m▄\x1b[38;5;237;48;5;150m▄\x1b[38;5;150;48;5;65m▄\x1b[38;5;151;48;5;150m▄\x1b[38;5;151;48;5;151m▄\x1b[38;5;151;48;5;236m▄\x1b[38;5;150;48;5;234m▄\x1b[38;5;151;48;5;234m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;240;48;5;237m▄\x1b[38;5;234;48;5;103m▄▄\x1b[38;5;234;48;5;104m▄\x1b[38;5;234;48;5;110m▄▄▄\x1b[38;5;65;48;5;110m▄\x1b[38;5;65;48;5;109m▄▄\x1b[38;5;65;48;5;103m▄\x1b[38;5;243;48;5;247m▄\x1b[38;5;150;48;5;150m▄▄▄▄\x1b[38;5;150;48;5;237m▄\x1b[38;5;236;48;5;234m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;97;48;5;234m▄\x1b[38;5;60;48;5;234m▄▄\x1b[38;5;61;48;5;234m▄\x1b[38;5;60;48;5;234m▄▄\x1b[38;5;234;48;5;234m▄▄▄▄▄▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;97;48;5;234m▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;237;48;5;235m▄\x1b[38;5;234;48;5;97m▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;66;48;5;234m▄\x1b[38;5;66;48;5;240m▄\x1b[38;5;67;48;5;240m▄\x1b[38;5;110;48;5;59m▄\x1b[38;5;74;48;5;74m▄\x1b[38;5;74;48;5;110m▄▄\x1b[38;5;66;48;5;74m▄\x1b[38;5;74;48;5;74m▄▄\x1b[38;5;110;48;5;74m▄▄▄\x1b[38;5;110;48;5;73m▄\x1b[38;5;236;48;5;74m▄\x1b[38;5;74;48;5;74m▄▄▄\x1b[m
|
||||||
|
\x1b[38;5;151;48;5;151m▄\x1b[38;5;243;48;5;151m▄\x1b[38;5;151;48;5;243m▄\x1b[38;5;151;48;5;151m▄▄▄▄▄\x1b[38;5;238;48;5;151m▄\x1b[38;5;151;48;5;236m▄\x1b[38;5;151;48;5;151m▄▄▄▄▄\x1b[38;5;114;48;5;151m▄\x1b[38;5;151;48;5;108m▄\x1b[38;5;151;48;5;150m▄\x1b[38;5;150;48;5;150m▄\x1b[38;5;151;48;5;151m▄▄▄▄▄\x1b[38;5;151;48;5;108m▄\x1b[38;5;150;48;5;151m▄▄\x1b[38;5;150;48;5;234m▄\x1b[38;5;234;48;5;103m▄\x1b[38;5;97;48;5;97m▄▄\x1b[38;5;97;48;5;239m▄\x1b[38;5;97;48;5;97m▄\x1b[38;5;97;48;5;60m▄\x1b[38;5;238;48;5;239m▄\x1b[38;5;237;48;5;239m▄\x1b[38;5;236;48;5;238m▄\x1b[38;5;236;48;5;237m▄\x1b[38;5;237;48;5;238m▄▄\x1b[38;5;236;48;5;238m▄▄\x1b[38;5;237;48;5;237m▄\x1b[38;5;236;48;5;238m▄\x1b[38;5;236;48;5;237m▄\x1b[38;5;236;48;5;238m▄\x1b[38;5;237;48;5;237m▄\x1b[38;5;236;48;5;238m▄\x1b[38;5;236;48;5;237m▄\x1b[38;5;236;48;5;238m▄▄▄\x1b[38;5;236;48;5;237m▄\x1b[38;5;236;48;5;238m▄\x1b[38;5;236;48;5;237m▄▄▄\x1b[38;5;236;48;5;238m▄\x1b[38;5;236;48;5;237m▄▄\x1b[38;5;236;48;5;238m▄▄\x1b[38;5;236;48;5;237m▄▄\x1b[38;5;236;48;5;238m▄\x1b[38;5;237;48;5;237m▄\x1b[38;5;236;48;5;237m▄▄\x1b[38;5;237;48;5;237m▄\x1b[38;5;236;48;5;237m▄\x1b[38;5;237;48;5;237m▄\x1b[38;5;236;48;5;237m▄▄\x1b[38;5;236;48;5;238m▄\x1b[38;5;236;48;5;237m▄▄\x1b[38;5;236;48;5;238m▄\x1b[38;5;236;48;5;237m▄▄▄\x1b[38;5;236;48;5;238m▄\x1b[38;5;236;48;5;237m▄\x1b[38;5;237;48;5;237m▄\x1b[38;5;238;48;5;238m▄▄\x1b[38;5;97;48;5;239m▄\x1b[38;5;61;48;5;239m▄\x1b[38;5;97;48;5;60m▄\x1b[38;5;97;48;5;97m▄\x1b[38;5;97;48;5;60m▄\x1b[38;5;97;48;5;97m▄\x1b[38;5;234;48;5;97m▄\x1b[48;5;234m \x1b[38;5;67;48;5;234m▄\x1b[38;5;67;48;5;74m▄\x1b[38;5;67;48;5;73m▄\x1b[38;5;67;48;5;74m▄▄\x1b[38;5;74;48;5;239m▄\x1b[38;5;74;48;5;74m▄▄\x1b[38;5;110;48;5;74m▄▄▄▄▄\x1b[38;5;74;48;5;66m▄\x1b[38;5;236;48;5;74m▄\x1b[38;5;74;48;5;74m▄▄▄▄▄\x1b[38;5;110;48;5;237m▄\x1b[38;5;110;48;5;74m▄\x1b[38;5;74;48;5;74m▄\x1b[m
|
||||||
|
\x1b[38;5;234;48;5;238m▄\x1b[38;5;234;48;5;237m▄▄\x1b[38;5;234;48;5;236m▄▄▄▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;238m▄\x1b[38;5;234;48;5;237m▄▄▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;238m▄\x1b[38;5;234;48;5;237m▄▄▄\x1b[38;5;234;48;5;236m▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;238m▄\x1b[38;5;234;48;5;237m▄▄▄▄▄▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;97m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄\x1b[38;5;235;48;5;235m▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;234;48;5;235m▄▄▄\x1b[38;5;234;48;5;236m▄▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;236m▄▄▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;238m▄\x1b[38;5;235;48;5;236m▄\x1b[38;5;234;48;5;236m▄▄▄▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;234;48;5;236m▄\x1b[m
|
||||||
|
\x1b[38;5;234;48;5;234m▄▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;235;48;5;234m▄▄▄\x1b[38;5;234;48;5;234m▄▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;234;48;5;234m▄▄▄▄▄\x1b[38;5;235;48;5;234m▄▄\x1b[38;5;234;48;5;234m▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄\x1b[38;5;235;48;5;234m▄▄▄▄▄▄▄\x1b[38;5;234;48;5;234m▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄▄▄▄▄▄▄\x1b[48;5;234m \x1b[38;5;234;48;5;234m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[m
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
const DARK_TOWER_HEADER1 = `
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;235;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;232;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;17;48;5;0m▄▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄▄▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[48;5;0m \x1b[38;5;52;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;17;48;5;4m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[48;5;0m \x1b[38;5;0;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;202;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄\x1b[38;5;124;48;5;0m▄\x1b[38;5;124;48;5;232m▄\x1b[38;5;202;48;5;124m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;52;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;152;48;5;17m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;52;48;5;0m▄\x1b[38;5;239;48;5;52m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;124;48;5;232m▄\x1b[38;5;202;48;5;233m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;4;48;5;103m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;144;48;5;0m▄\x1b[38;5;19;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;20;48;5;0m▄\x1b[38;5;20;48;5;19m▄\x1b[38;5;20;48;5;18m▄\x1b[38;5;237;48;5;109m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;14;48;5;19m▄\x1b[38;5;19;48;5;18m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;24;48;5;18m▄\x1b[38;5;232;48;5;17m▄\x1b[38;5;236;48;5;0m▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;1;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;124m▄\x1b[38;5;9;48;5;160m▄\x1b[38;5;228;48;5;214m▄\x1b[38;5;9;48;5;52m▄\x1b[38;5;0;48;5;52m▄\x1b[38;5;1;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;1;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;52;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;52;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;232;48;5;52m▄\x1b[38;5;202;48;5;52m▄\x1b[38;5;208;48;5;202m▄\x1b[38;5;202;48;5;1m▄\x1b[38;5;232;48;5;52m▄\x1b[48;5;0m \x1b[38;5;232;48;5;233m▄\x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;19;48;5;233m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;20;48;5;19m▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;60;48;5;237m▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;246;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;241;48;5;234m▄\x1b[38;5;17;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;153;48;5;0m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;124m▄\x1b[38;5;15;48;5;220m▄\x1b[38;5;15;48;5;214m▄\x1b[38;5;233;48;5;202m▄\x1b[38;5;0;48;5;202m▄▄\x1b[38;5;215;48;5;220m▄\x1b[38;5;15;48;5;15m▄\x1b[38;5;230;48;5;124m▄\x1b[38;5;52;48;5;52m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;58m▄\x1b[38;5;214;48;5;11m▄\x1b[38;5;137;48;5;220m▄\x1b[38;5;255;48;5;220m▄\x1b[38;5;0;48;5;208m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;172m▄\x1b[38;5;15;48;5;11m▄\x1b[38;5;230;48;5;11m▄\x1b[38;5;0;48;5;11m▄▄\x1b[38;5;15;48;5;166m▄\x1b[38;5;15;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;220m▄\x1b[38;5;249;48;5;220m▄\x1b[38;5;187;48;5;228m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;255;48;5;227m▄\x1b[38;5;130;48;5;227m▄\x1b[38;5;0;48;5;214m▄\x1b[38;5;0;48;5;220m▄▄\x1b[38;5;52;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;20;48;5;19m▄\x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;17m▄▄\x1b[38;5;17;48;5;18m▄\x1b[38;5;20;48;5;189m▄\x1b[38;5;27;48;5;20m▄\x1b[48;5;0m \x1b[38;5;241;48;5;254m▄\x1b[38;5;234;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;25;48;5;20m▄\x1b[38;5;27;48;5;27m▄\x1b[38;5;20;48;5;0m▄▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;19;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;188;48;5;246m▄\x1b[38;5;246;48;5;255m▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;255;48;5;246m▄\x1b[38;5;251;48;5;255m▄\x1b[38;5;221;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;208;48;5;139m▄\x1b[38;5;0;48;5;136m▄\x1b[38;5;145;48;5;253m▄\x1b[38;5;223;48;5;136m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;214;48;5;222m▄\x1b[38;5;251;48;5;15m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;230;48;5;58m▄\x1b[38;5;102;48;5;254m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;52m▄\x1b[38;5;145;48;5;247m▄\x1b[38;5;8;48;5;249m▄\x1b[38;5;255;48;5;0m▄\x1b[38;5;214;48;5;144m▄\x1b[38;5;0;48;5;130m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;17;48;5;233m▄\x1b[38;5;0;48;5;235m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;18;48;5;232m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;20;48;5;19m▄\x1b[38;5;26;48;5;235m▄\x1b[38;5;239;48;5;253m▄\x1b[38;5;234;48;5;7m▄\x1b[38;5;24;48;5;242m▄\x1b[38;5;23;48;5;239m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;17;48;5;24m▄\x1b[38;5;39;48;5;0m▄\x1b[38;5;33;48;5;45m▄\x1b[38;5;0;48;5;32m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;18m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;19m▄▄\x1b[38;5;4;48;5;19m▄\x1b[38;5;19;48;5;17m▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;4m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;243;48;5;236m▄\x1b[38;5;253;48;5;145m▄\x1b[38;5;233;48;5;235m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;95m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;240;48;5;251m▄\x1b[38;5;239;48;5;252m▄\x1b[38;5;0;48;5;230m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;247;48;5;243m▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;246;48;5;249m▄\x1b[38;5;248;48;5;247m▄\x1b[38;5;240;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;245;48;5;245m▄\x1b[38;5;235;48;5;8m▄\x1b[38;5;0;48;5;240m▄\x1b[38;5;245;48;5;239m▄\x1b[38;5;102;48;5;255m▄\x1b[38;5;251;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;242;48;5;236m▄\x1b[38;5;59;48;5;59m▄\x1b[38;5;0;48;5;102m▄\x1b[38;5;245;48;5;243m▄\x1b[38;5;242;48;5;235m▄\x1b[38;5;52;48;5;233m▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;18;48;5;4m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;4;48;5;19m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;25;48;5;19m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;26m▄\x1b[38;5;69;48;5;20m▄\x1b[38;5;69;48;5;33m▄\x1b[38;5;26;48;5;12m▄\x1b[38;5;235;48;5;243m▄\x1b[38;5;236;48;5;243m▄\x1b[38;5;6;48;5;102m▄\x1b[38;5;245;48;5;0m▄\x1b[38;5;23;48;5;0m▄\x1b[38;5;0;48;5;67m▄\x1b[38;5;232;48;5;234m▄\x1b[38;5;33;48;5;75m▄\x1b[38;5;17;48;5;19m▄\x1b[38;5;24;48;5;12m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;31;48;5;0m▄\x1b[38;5;23;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;235m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;52;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;9;48;5;0m▄\x1b[38;5;160;48;5;0m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;137;48;5;59m▄\x1b[38;5;240;48;5;241m▄\x1b[38;5;234;48;5;233m▄\x1b[38;5;241;48;5;0m▄▄\x1b[38;5;249;48;5;102m▄\x1b[38;5;0;48;5;236m▄\x1b[38;5;0;48;5;7m▄\x1b[38;5;145;48;5;0m▄\x1b[38;5;243;48;5;243m▄\x1b[38;5;188;48;5;251m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;239;48;5;0m▄\x1b[38;5;243;48;5;233m▄\x1b[38;5;239;48;5;241m▄\x1b[38;5;255;48;5;0m▄\x1b[38;5;59;48;5;8m▄\x1b[38;5;102;48;5;236m▄\x1b[38;5;248;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;242m▄\x1b[38;5;237;48;5;249m▄\x1b[38;5;241;48;5;0m▄\x1b[38;5;239;48;5;0m▄\x1b[38;5;242;48;5;239m▄\x1b[38;5;234;48;5;239m▄\x1b[38;5;245;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;238m▄\x1b[38;5;187;48;5;172m▄\x1b[38;5;230;48;5;52m▄\x1b[38;5;9;48;5;17m▄\x1b[38;5;124;48;5;233m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;88;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;52;48;5;17m▄\x1b[38;5;52;48;5;4m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;233;48;5;220m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;4;48;5;26m▄\x1b[38;5;19;48;5;27m▄\x1b[38;5;238;48;5;246m▄\x1b[38;5;8;48;5;245m▄\x1b[38;5;239;48;5;11m▄\x1b[38;5;103;48;5;232m▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;220;48;5;208m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;26;48;5;19m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;24;48;5;232m▄\x1b[38;5;17;48;5;4m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;4;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;20;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;52m▄\x1b[38;5;243;48;5;202m▄\x1b[38;5;0;48;5;202m▄▄\x1b[38;5;235;48;5;208m▄\x1b[38;5;173;48;5;202m▄\x1b[38;5;239;48;5;208m▄\x1b[38;5;0;48;5;214m▄\x1b[38;5;222;48;5;220m▄\x1b[38;5;181;48;5;214m▄\x1b[38;5;233;48;5;1m▄\x1b[38;5;95;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;220;48;5;0m▄\x1b[38;5;11;48;5;0m▄\x1b[38;5;220;48;5;0m▄\x1b[38;5;227;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;208;48;5;0m▄\x1b[38;5;214;48;5;0m▄\x1b[38;5;220;48;5;0m▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;0;48;5;232m▄▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;227;48;5;0m▄\x1b[38;5;227;48;5;232m▄\x1b[38;5;220;48;5;52m▄\x1b[38;5;228;48;5;0m▄\x1b[38;5;220;48;5;0m▄\x1b[38;5;214;48;5;0m▄\x1b[38;5;208;48;5;0m▄\x1b[38;5;214;48;5;0m▄▄▄\x1b[38;5;227;48;5;0m▄\x1b[38;5;0;48;5;52m▄\x1b[38;5;0;48;5;172m▄\x1b[38;5;15;48;5;208m▄\x1b[38;5;230;48;5;202m▄\x1b[38;5;101;48;5;202m▄\x1b[38;5;0;48;5;202m▄\x1b[38;5;0;48;5;208m▄\x1b[38;5;230;48;5;208m▄\x1b[38;5;15;48;5;220m▄\x1b[38;5;220;48;5;229m▄\x1b[38;5;214;48;5;52m▄\x1b[38;5;232;48;5;130m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;17;48;5;236m▄\x1b[38;5;4;48;5;17m▄\x1b[38;5;4;48;5;25m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;246;48;5;248m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;234;48;5;238m▄\x1b[38;5;0;48;5;243m▄▄\x1b[38;5;0;48;5;235m▄\x1b[38;5;239;48;5;0m▄\x1b[38;5;0;48;5;237m▄\x1b[38;5;0;48;5;20m▄\x1b[38;5;25;48;5;38m▄\x1b[38;5;24;48;5;74m▄\x1b[38;5;24;48;5;17m▄\x1b[38;5;25;48;5;17m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;223;48;5;144m▄\x1b[38;5;242;48;5;138m▄\x1b[38;5;144;48;5;143m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;247m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;246;48;5;166m▄\x1b[38;5;7;48;5;220m▄\x1b[38;5;246;48;5;214m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;52;48;5;0m▄\x1b[38;5;240;48;5;221m▄\x1b[38;5;145;48;5;220m▄\x1b[38;5;249;48;5;208m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;247;48;5;221m▄\x1b[38;5;8;48;5;187m▄\x1b[38;5;221;48;5;3m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;52m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;246;48;5;181m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;52;48;5;233m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;248;48;5;223m▄\x1b[38;5;59;48;5;187m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;249;48;5;179m▄\x1b[38;5;249;48;5;180m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;8m▄\x1b[38;5;247;48;5;186m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;247;48;5;252m▄\x1b[38;5;242;48;5;242m▄\x1b[38;5;7;48;5;222m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;101m▄\x1b[38;5;247;48;5;254m▄\x1b[38;5;8;48;5;253m▄\x1b[38;5;187;48;5;143m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;20;48;5;17m▄\x1b[38;5;27;48;5;27m▄\x1b[38;5;103;48;5;236m▄\x1b[38;5;239;48;5;237m▄\x1b[38;5;240;48;5;241m▄\x1b[38;5;60;48;5;59m▄\x1b[38;5;237;48;5;236m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;27;48;5;17m▄\x1b[38;5;25;48;5;0m▄▄\x1b[38;5;237;48;5;0m▄\x1b[38;5;0;48;5;232m▄▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;17;48;5;20m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;245;48;5;248m▄\x1b[38;5;245;48;5;59m▄\x1b[38;5;247;48;5;251m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;235m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;250;48;5;229m▄\x1b[38;5;238;48;5;8m▄\x1b[38;5;250;48;5;252m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;52m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;240;48;5;248m▄\x1b[38;5;248;48;5;241m▄\x1b[38;5;241;48;5;143m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;236;48;5;247m▄\x1b[38;5;240;48;5;243m▄\x1b[48;5;0m \x1b[38;5;0;48;5;52m▄\x1b[38;5;237;48;5;187m▄\x1b[38;5;236;48;5;188m▄\x1b[38;5;237;48;5;144m▄\x1b[38;5;0;48;5;88m▄\x1b[38;5;236;48;5;0m▄\x1b[38;5;248;48;5;239m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[48;5;0m \x1b[38;5;250;48;5;242m▄\x1b[38;5;242;48;5;253m▄\x1b[38;5;144;48;5;0m▄\x1b[38;5;180;48;5;0m▄\x1b[38;5;229;48;5;0m▄\x1b[38;5;187;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;243;48;5;234m▄\x1b[38;5;238;48;5;237m▄\x1b[38;5;239;48;5;248m▄\x1b[48;5;0m \x1b[38;5;145;48;5;0m▄\x1b[38;5;241;48;5;255m▄\x1b[38;5;102;48;5;249m▄\x1b[38;5;0;48;5;145m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;25;48;5;20m▄\x1b[38;5;18;48;5;19m▄\x1b[38;5;66;48;5;234m▄\x1b[38;5;66;48;5;237m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;66;48;5;60m▄\x1b[38;5;235;48;5;239m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;220;48;5;208m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;17;48;5;27m▄\x1b[38;5;17;48;5;18m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;24;48;5;24m▄\x1b[38;5;0;48;5;25m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;234;48;5;233m▄\x1b[m
|
||||||
|
\x1b[38;5;0;48;5;0m▄\x1b[38;5;31;48;5;0m▄\x1b[38;5;66;48;5;0m▄\x1b[38;5;24;48;5;235m▄\x1b[38;5;25;48;5;0m▄▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;4;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;248;48;5;255m▄\x1b[38;5;60;48;5;240m▄\x1b[38;5;249;48;5;62m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;239;48;5;242m▄\x1b[38;5;62;48;5;240m▄\x1b[38;5;67;48;5;246m▄\x1b[38;5;236;48;5;237m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;62;48;5;249m▄\x1b[38;5;61;48;5;247m▄\x1b[38;5;25;48;5;235m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;61;48;5;246m▄\x1b[38;5;60;48;5;249m▄\x1b[38;5;68;48;5;7m▄\x1b[38;5;68;48;5;243m▄\x1b[38;5;62;48;5;248m▄\x1b[38;5;81;48;5;246m▄\x1b[38;5;24;48;5;241m▄\x1b[38;5;75;48;5;250m▄\x1b[38;5;104;48;5;145m▄\x1b[38;5;26;48;5;251m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;8;48;5;241m▄\x1b[38;5;236;48;5;8m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;250m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;111m▄\x1b[38;5;63;48;5;242m▄\x1b[38;5;62;48;5;243m▄\x1b[38;5;251;48;5;250m▄\x1b[38;5;0;48;5;250m▄\x1b[38;5;25;48;5;59m▄\x1b[38;5;61;48;5;242m▄\x1b[38;5;61;48;5;145m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;24;48;5;235m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;236;48;5;103m▄\x1b[38;5;60;48;5;239m▄\x1b[38;5;66;48;5;60m▄\x1b[38;5;67;48;5;60m▄\x1b[38;5;66;48;5;238m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;237;48;5;234m▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;236;48;5;0m▄\x1b[38;5;26;48;5;4m▄\x1b[38;5;32;48;5;0m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;32;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;152m▄\x1b[38;5;0;48;5;241m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;24;48;5;25m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;233;48;5;17m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;117;48;5;69m▄\x1b[38;5;17;48;5;4m▄\x1b[38;5;81;48;5;110m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;110m▄\x1b[38;5;39;48;5;60m▄\x1b[38;5;74;48;5;67m▄\x1b[38;5;81;48;5;235m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;32;48;5;103m▄\x1b[38;5;45;48;5;238m▄\x1b[38;5;0;48;5;249m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;24;48;5;249m▄\x1b[38;5;23;48;5;245m▄\x1b[38;5;117;48;5;60m▄\x1b[38;5;17;48;5;0m▄▄\x1b[38;5;45;48;5;249m▄\x1b[38;5;39;48;5;239m▄\x1b[38;5;45;48;5;247m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;18;48;5;19m▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;24;48;5;243m▄\x1b[38;5;31;48;5;240m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;19;48;5;4m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;123;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;27;48;5;101m▄\x1b[38;5;26;48;5;242m▄\x1b[38;5;87;48;5;253m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;7m▄\x1b[38;5;68;48;5;239m▄\x1b[38;5;69;48;5;61m▄\x1b[38;5;25;48;5;61m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;234;48;5;234m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;232;48;5;17m▄\x1b[38;5;59;48;5;66m▄\x1b[38;5;0;48;5;103m▄\x1b[38;5;60;48;5;232m▄\x1b[38;5;238;48;5;232m▄\x1b[38;5;214;48;5;24m▄\x1b[38;5;66;48;5;232m▄\x1b[38;5;23;48;5;0m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;235;48;5;23m▄\x1b[38;5;236;48;5;60m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;232;48;5;239m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;25;48;5;232m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;25;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;17;48;5;232m▄\x1b[48;5;0m \x1b[38;5;17;48;5;17m▄\x1b[38;5;27;48;5;19m▄\x1b[38;5;14;48;5;195m▄\x1b[38;5;18;48;5;25m▄\x1b[38;5;26;48;5;81m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;98;48;5;0m▄\x1b[38;5;75;48;5;0m▄\x1b[38;5;0;48;5;44m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;27;48;5;67m▄\x1b[38;5;26;48;5;19m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;0;48;5;45m▄\x1b[38;5;0;48;5;159m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;4;48;5;18m▄\x1b[38;5;17;48;5;87m▄\x1b[38;5;38;48;5;23m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;18;48;5;18m▄\x1b[38;5;19;48;5;17m▄\x1b[38;5;0;48;5;123m▄\x1b[38;5;14;48;5;87m▄\x1b[38;5;17;48;5;123m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;159;48;5;0m▄\x1b[38;5;15;48;5;4m▄\x1b[38;5;15;48;5;45m▄\x1b[38;5;15;48;5;24m▄\x1b[38;5;15;48;5;123m▄▄▄\x1b[38;5;195;48;5;81m▄\x1b[38;5;15;48;5;74m▄\x1b[38;5;17;48;5;18m▄\x1b[38;5;15;48;5;24m▄\x1b[38;5;39;48;5;69m▄\x1b[38;5;39;48;5;27m▄\x1b[38;5;14;48;5;159m▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;19;48;5;87m▄\x1b[38;5;45;48;5;27m▄\x1b[38;5;33;48;5;26m▄\x1b[38;5;39;48;5;87m▄\x1b[38;5;38;48;5;17m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;25;48;5;236m▄\x1b[38;5;236;48;5;0m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;236m▄\x1b[38;5;238;48;5;220m▄\x1b[38;5;60;48;5;59m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;24;48;5;23m▄\x1b[38;5;30;48;5;233m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;23;48;5;236m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;25;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;87;48;5;233m▄\x1b[38;5;25;48;5;18m▄\x1b[38;5;25;48;5;45m▄\x1b[38;5;26;48;5;87m▄\x1b[38;5;26;48;5;159m▄\x1b[38;5;19;48;5;123m▄\x1b[38;5;17;48;5;195m▄\x1b[38;5;0;48;5;15m▄▄\x1b[38;5;0;48;5;152m▄\x1b[38;5;0;48;5;23m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;17m▄▄\x1b[38;5;0;48;5;20m▄\x1b[38;5;20;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;4;48;5;14m▄\x1b[38;5;0;48;5;159m▄\x1b[38;5;18;48;5;18m▄\x1b[38;5;32;48;5;26m▄\x1b[38;5;39;48;5;45m▄\x1b[38;5;25;48;5;25m▄\x1b[38;5;0;48;5;15m▄\x1b[38;5;20;48;5;14m▄\x1b[38;5;0;48;5;39m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;27m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;0;48;5;87m▄\x1b[38;5;17;48;5;15m▄\x1b[38;5;233;48;5;15m▄\x1b[38;5;0;48;5;195m▄▄\x1b[38;5;0;48;5;87m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;4;48;5;20m▄\x1b[38;5;81;48;5;45m▄\x1b[38;5;25;48;5;32m▄\x1b[38;5;15;48;5;45m▄\x1b[38;5;123;48;5;27m▄\x1b[38;5;159;48;5;18m▄\x1b[38;5;17;48;5;232m▄\x1b[38;5;25;48;5;25m▄▄\x1b[38;5;24;48;5;24m▄\x1b[38;5;24;48;5;236m▄\x1b[38;5;25;48;5;240m▄\x1b[38;5;237;48;5;60m▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;23;48;5;4m▄\x1b[38;5;23;48;5;236m▄\x1b[38;5;234;48;5;23m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;232m▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;233m▄▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;19;48;5;26m▄\x1b[38;5;19;48;5;19m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;4;48;5;18m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;60;48;5;18m▄\x1b[38;5;67;48;5;235m▄\x1b[38;5;241;48;5;0m▄\x1b[38;5;240;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;237;48;5;0m▄\x1b[38;5;233;48;5;17m▄\x1b[38;5;236;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;17;48;5;26m▄\x1b[38;5;27;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;32;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;236;48;5;0m▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;232;48;5;24m▄\x1b[38;5;60;48;5;235m▄\x1b[38;5;24;48;5;233m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;4;48;5;17m▄\x1b[38;5;19;48;5;232m▄\x1b[38;5;4;48;5;17m▄\x1b[38;5;25;48;5;232m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;18;48;5;26m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;17;48;5;25m▄\x1b[38;5;0;48;5;25m▄\x1b[38;5;0;48;5;45m▄\x1b[38;5;232;48;5;38m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;235m▄\x1b[38;5;23;48;5;237m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;23;48;5;73m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;23;48;5;0m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;23m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;18;48;5;232m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;23m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;23;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;233;48;5;249m▄\x1b[38;5;245;48;5;145m▄\x1b[38;5;0;48;5;8m▄\x1b[38;5;0;48;5;23m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;8m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;60;48;5;24m▄\x1b[38;5;235;48;5;17m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;0;48;5;25m▄\x1b[38;5;60;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;23;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;235;48;5;24m▄\x1b[38;5;235;48;5;66m▄\x1b[38;5;0;48;5;245m▄\x1b[38;5;233;48;5;240m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;0;48;5;67m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;59;48;5;0m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;17m▄▄\x1b[38;5;234;48;5;17m▄\x1b[38;5;237;48;5;236m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;23;48;5;17m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;81m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[m
|
||||||
|
\x1b[49;38;5;0m▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀\x1b[49;38;5;239m▀\x1b[49;38;5;0m▀\x1b[49;38;5;232m▀\x1b[49;38;5;24m▀\x1b[49;38;5;0m▀\x1b[49;38;5;235m▀\x1b[49;38;5;232m▀\x1b[49;38;5;0m▀▀▀▀\x1b[49;38;5;116m▀\x1b[49;38;5;0m▀▀▀▀▀▀▀▀▀\x1b[49;38;5;234m▀\x1b[49;38;5;0m▀\x1b[49;38;5;233m▀\x1b[49;38;5;60m▀\x1b[49;38;5;80m▀\x1b[49;38;5;17m▀\x1b[49;38;5;0m▀\x1b[49;38;5;23m▀\x1b[49;38;5;232m▀\x1b[49;38;5;0m▀▀\x1b[49;38;5;232m▀\x1b[49;38;5;0m▀▀▀\x1b[49;38;5;24m▀\x1b[49;38;5;23m▀\x1b[49;38;5;0m▀\x1b[49;38;5;234m▀\x1b[49;38;5;0m▀\x1b[49;38;5;233m▀\x1b[49;38;5;17m▀\x1b[49;38;5;0m▀\x1b[49;38;5;234m▀▀\x1b[49;38;5;23m▀\x1b[49;38;5;24m▀\x1b[49;38;5;23m▀\x1b[49;38;5;0m▀\x1b[49;38;5;235m▀\x1b[49;38;5;24m▀\x1b[49;38;5;232m▀\x1b[49;38;5;0m▀▀▀▀▀▀▀▀▀▀▀\x1b[m
|
||||||
|
`;
|
||||||
|
|
||||||
|
const DARK_TOWER_HEADER = `
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;0;48;5;245m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;144m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;235m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[48;5;0m \x1b[38;5;166;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄\x1b[38;5;222;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄\x1b[38;5;19;48;5;4m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;87m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;243;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;232;48;5;235m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄\x1b[38;5;88;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;185m▄\x1b[48;5;0m \x1b[38;5;238;48;5;0m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;45;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;23m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;17;48;5;0m▄▄\x1b[38;5;18;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;238m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[38;5;124;48;5;0m▄\x1b[38;5;0;48;5;88m▄\x1b[38;5;52;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;19;48;5;17m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;19;48;5;19m▄\x1b[38;5;19;48;5;17m▄\x1b[38;5;248;48;5;234m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;17;48;5;19m▄\x1b[38;5;19;48;5;19m▄\x1b[38;5;255;48;5;4m▄\x1b[38;5;18;48;5;4m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;18;48;5;18m▄\x1b[38;5;17;48;5;4m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[38;5;172;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;52;48;5;160m▄\x1b[38;5;124;48;5;52m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;20m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;20m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;202;48;5;160m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;17;48;5;19m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;61;48;5;19m▄\x1b[38;5;4;48;5;18m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;17;48;5;0m▄▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;19;48;5;18m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;19;48;5;17m▄\x1b[38;5;18;48;5;12m▄\x1b[38;5;20;48;5;20m▄\x1b[38;5;17;48;5;20m▄\x1b[38;5;246;48;5;245m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;20;48;5;19m▄\x1b[38;5;232;48;5;19m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;18;48;5;18m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[m
|
||||||
|
\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;94m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;58m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄▄\x1b[38;5;0;48;5;124m▄\x1b[38;5;227;48;5;202m▄\x1b[38;5;9;48;5;9m▄\x1b[38;5;1;48;5;52m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[38;5;255;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;19m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄\x1b[38;5;94;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;232m▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;214;48;5;160m▄\x1b[38;5;11;48;5;202m▄\x1b[38;5;88;48;5;52m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;62;48;5;19m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;0;48;5;236m▄\x1b[38;5;17;48;5;19m▄\x1b[38;5;19;48;5;20m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;19;48;5;20m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;12;48;5;12m▄\x1b[38;5;18;48;5;18m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;239;48;5;0m▄\x1b[38;5;245;48;5;246m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;19;48;5;19m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;243;48;5;0m▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;18;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;23m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;52m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;88;48;5;52m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;160;48;5;0m▄\x1b[38;5;15;48;5;229m▄\x1b[38;5;229;48;5;220m▄\x1b[38;5;9;48;5;0m▄\x1b[38;5;124;48;5;52m▄\x1b[38;5;124;48;5;0m▄▄\x1b[38;5;88;48;5;0m▄\x1b[38;5;1;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;124;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[38;5;0;48;5;130m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;52;48;5;0m▄\x1b[38;5;95;48;5;232m▄\x1b[38;5;124;48;5;17m▄\x1b[38;5;125;48;5;0m▄\x1b[38;5;160;48;5;0m▄\x1b[38;5;52;48;5;202m▄\x1b[38;5;9;48;5;202m▄\x1b[38;5;15;48;5;229m▄\x1b[38;5;202;48;5;202m▄\x1b[38;5;0;48;5;130m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;20;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;4;48;5;17m▄\x1b[38;5;232;48;5;19m▄\x1b[38;5;4;48;5;18m▄\x1b[38;5;19;48;5;18m▄\x1b[38;5;20;48;5;4m▄\x1b[38;5;12;48;5;4m▄\x1b[38;5;247;48;5;0m▄\x1b[38;5;17;48;5;20m▄\x1b[38;5;0;48;5;59m▄\x1b[38;5;0;48;5;247m▄\x1b[38;5;59;48;5;243m▄\x1b[38;5;23;48;5;240m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;103;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;12;48;5;19m▄\x1b[38;5;236;48;5;102m▄\x1b[38;5;12;48;5;20m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;17;48;5;0m▄▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;17;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;4;48;5;0m▄\x1b[38;5;17;48;5;17m▄▄\x1b[48;5;0m \x1b[38;5;17;48;5;18m▄\x1b[38;5;0;48;5;17m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;208m▄\x1b[38;5;1;48;5;220m▄\x1b[38;5;208;48;5;221m▄\x1b[38;5;214;48;5;229m▄\x1b[38;5;173;48;5;222m▄\x1b[38;5;0;48;5;215m▄\x1b[38;5;0;48;5;221m▄\x1b[38;5;233;48;5;230m▄\x1b[38;5;172;48;5;15m▄\x1b[38;5;221;48;5;15m▄\x1b[38;5;227;48;5;15m▄\x1b[38;5;220;48;5;9m▄\x1b[38;5;215;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;220;48;5;0m▄\x1b[38;5;227;48;5;124m▄\x1b[38;5;15;48;5;88m▄\x1b[38;5;15;48;5;1m▄\x1b[38;5;130;48;5;52m▄\x1b[38;5;0;48;5;52m▄\x1b[38;5;17;48;5;0m▄▄\x1b[38;5;52;48;5;0m▄\x1b[38;5;208;48;5;0m▄\x1b[38;5;215;48;5;0m▄\x1b[38;5;214;48;5;0m▄\x1b[38;5;202;48;5;0m▄▄▄\x1b[38;5;215;48;5;0m▄\x1b[38;5;229;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;178m▄\x1b[38;5;166;48;5;208m▄\x1b[38;5;230;48;5;208m▄▄\x1b[38;5;214;48;5;172m▄\x1b[38;5;0;48;5;214m▄\x1b[38;5;17;48;5;17m▄▄\x1b[38;5;227;48;5;228m▄\x1b[38;5;221;48;5;229m▄\x1b[38;5;202;48;5;15m▄\x1b[38;5;202;48;5;229m▄\x1b[38;5;0;48;5;228m▄\x1b[38;5;0;48;5;230m▄\x1b[38;5;52;48;5;15m▄\x1b[38;5;0;48;5;15m▄\x1b[38;5;0;48;5;230m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;1;48;5;0m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;4m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;19m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;4;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;20;48;5;19m▄\x1b[38;5;63;48;5;104m▄\x1b[38;5;20;48;5;20m▄\x1b[38;5;20;48;5;19m▄\x1b[38;5;12;48;5;12m▄\x1b[38;5;242;48;5;238m▄\x1b[38;5;233;48;5;254m▄\x1b[38;5;248;48;5;240m▄\x1b[38;5;238;48;5;102m▄\x1b[38;5;234;48;5;245m▄\x1b[38;5;233;48;5;239m▄\x1b[38;5;59;48;5;102m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;233;48;5;17m▄\x1b[38;5;233;48;5;239m▄\x1b[38;5;27;48;5;20m▄\x1b[38;5;12;48;5;0m▄\x1b[38;5;17;48;5;19m▄\x1b[38;5;61;48;5;17m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;19;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;17;48;5;19m▄\x1b[38;5;0;48;5;232m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;153m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[48;5;0m \x1b[38;5;17;48;5;68m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;248;48;5;138m▄\x1b[38;5;248;48;5;242m▄\x1b[38;5;251;48;5;255m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;94m▄\x1b[38;5;215;48;5;15m▄\x1b[38;5;255;48;5;187m▄\x1b[38;5;243;48;5;222m▄\x1b[38;5;187;48;5;232m▄\x1b[38;5;0;48;5;52m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;253;48;5;229m▄\x1b[38;5;130;48;5;215m▄\x1b[38;5;222;48;5;187m▄\x1b[38;5;15;48;5;15m▄\x1b[38;5;181;48;5;221m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;234;48;5;232m▄\x1b[38;5;248;48;5;185m▄\x1b[38;5;250;48;5;222m▄\x1b[38;5;233;48;5;234m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;208;48;5;253m▄\x1b[38;5;255;48;5;15m▄\x1b[38;5;15;48;5;223m▄\x1b[38;5;172;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;255;48;5;15m▄\x1b[38;5;254;48;5;15m▄\x1b[38;5;208;48;5;214m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;187;48;5;0m▄\x1b[38;5;208;48;5;230m▄\x1b[38;5;0;48;5;137m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;19;48;5;20m▄▄\x1b[38;5;12;48;5;12m▄\x1b[38;5;20;48;5;19m▄\x1b[38;5;0;48;5;12m▄\x1b[38;5;233;48;5;236m▄\x1b[38;5;250;48;5;233m▄\x1b[38;5;243;48;5;251m▄\x1b[38;5;102;48;5;238m▄\x1b[38;5;247;48;5;232m▄\x1b[38;5;236;48;5;232m▄\x1b[38;5;242;48;5;238m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;239;48;5;0m▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;27;48;5;12m▄\x1b[38;5;27;48;5;20m▄\x1b[38;5;26;48;5;19m▄\x1b[38;5;18;48;5;20m▄\x1b[38;5;18;48;5;19m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;3m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;18;48;5;0m▄▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;130;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄\x1b[38;5;255;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;237m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;145;48;5;245m▄\x1b[38;5;242;48;5;241m▄\x1b[38;5;243;48;5;238m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;234;48;5;236m▄\x1b[38;5;249;48;5;248m▄\x1b[38;5;242;48;5;254m▄\x1b[38;5;246;48;5;248m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;228;48;5;0m▄\x1b[38;5;137;48;5;59m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;179m▄\x1b[38;5;239;48;5;241m▄\x1b[38;5;250;48;5;246m▄\x1b[38;5;221;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;238;48;5;58m▄\x1b[38;5;7;48;5;145m▄\x1b[38;5;252;48;5;247m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;230;48;5;0m▄\x1b[38;5;243;48;5;241m▄\x1b[38;5;250;48;5;240m▄\x1b[38;5;0;48;5;94m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;247;48;5;246m▄\x1b[38;5;243;48;5;241m▄\x1b[38;5;178;48;5;208m▄\x1b[38;5;7;48;5;0m▄\x1b[38;5;246;48;5;248m▄\x1b[38;5;130;48;5;239m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;17;48;5;18m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;173;48;5;137m▄\x1b[38;5;17;48;5;232m▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;20;48;5;0m▄\x1b[38;5;20;48;5;19m▄\x1b[38;5;23;48;5;19m▄\x1b[38;5;0;48;5;23m▄\x1b[38;5;20;48;5;19m▄\x1b[38;5;20;48;5;20m▄\x1b[38;5;27;48;5;0m▄\x1b[38;5;236;48;5;15m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;238;48;5;246m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;239;48;5;0m▄\x1b[38;5;233;48;5;236m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;24m▄\x1b[48;5;0m \x1b[38;5;27;48;5;33m▄\x1b[38;5;27;48;5;69m▄\x1b[38;5;18;48;5;12m▄\x1b[38;5;4;48;5;19m▄\x1b[38;5;233;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;4;48;5;4m▄\x1b[38;5;17;48;5;18m▄\x1b[38;5;0;48;5;236m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;18;48;5;19m▄\x1b[38;5;19;48;5;19m▄▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;17;48;5;19m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;4;48;5;17m▄\x1b[38;5;17;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;238;48;5;243m▄\x1b[38;5;236;48;5;242m▄\x1b[38;5;251;48;5;243m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;238;48;5;243m▄\x1b[38;5;238;48;5;250m▄\x1b[38;5;235;48;5;102m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;243;48;5;248m▄\x1b[38;5;254;48;5;234m▄\x1b[38;5;255;48;5;0m▄\x1b[38;5;15;48;5;0m▄\x1b[38;5;15;48;5;251m▄\x1b[38;5;248;48;5;249m▄\x1b[38;5;249;48;5;246m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;238;48;5;236m▄\x1b[38;5;236;48;5;243m▄\x1b[38;5;102;48;5;243m▄\x1b[38;5;232;48;5;247m▄\x1b[38;5;243;48;5;248m▄\x1b[38;5;237;48;5;8m▄\x1b[38;5;245;48;5;243m▄\x1b[38;5;15;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;246;48;5;241m▄\x1b[38;5;242;48;5;248m▄\x1b[38;5;243;48;5;59m▄\x1b[38;5;0;48;5;242m▄\x1b[38;5;59;48;5;249m▄\x1b[38;5;247;48;5;247m▄\x1b[38;5;221;48;5;232m▄\x1b[38;5;0;48;5;94m▄\x1b[38;5;236;48;5;232m▄\x1b[38;5;235;48;5;232m▄\x1b[38;5;232;48;5;4m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;18;48;5;19m▄\x1b[38;5;19;48;5;19m▄\x1b[38;5;20;48;5;17m▄\x1b[38;5;18;48;5;18m▄\x1b[38;5;17;48;5;17m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;18;48;5;19m▄\x1b[38;5;19;48;5;19m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;20;48;5;20m▄\x1b[38;5;26;48;5;19m▄\x1b[38;5;12;48;5;20m▄\x1b[38;5;20;48;5;12m▄\x1b[38;5;33;48;5;12m▄\x1b[38;5;26;48;5;27m▄\x1b[38;5;0;48;5;241m▄\x1b[38;5;233;48;5;238m▄\x1b[38;5;102;48;5;246m▄\x1b[38;5;8;48;5;243m▄\x1b[38;5;0;48;5;59m▄\x1b[38;5;233;48;5;102m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;23;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;60;48;5;232m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;26;48;5;33m▄\x1b[38;5;19;48;5;19m▄\x1b[38;5;25;48;5;17m▄\x1b[38;5;17;48;5;12m▄\x1b[38;5;31;48;5;20m▄\x1b[38;5;17;48;5;20m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;61;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;232;48;5;17m▄\x1b[38;5;0;48;5;17m▄▄\x1b[38;5;18;48;5;232m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;247;48;5;248m▄\x1b[38;5;243;48;5;251m▄\x1b[38;5;246;48;5;240m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;247;48;5;187m▄\x1b[38;5;59;48;5;239m▄\x1b[38;5;239;48;5;238m▄\x1b[38;5;234;48;5;253m▄\x1b[48;5;0m \x1b[38;5;233;48;5;0m▄\x1b[38;5;240;48;5;242m▄\x1b[38;5;0;48;5;242m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;240;48;5;241m▄\x1b[38;5;8;48;5;145m▄\x1b[38;5;7;48;5;248m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;246;48;5;249m▄\x1b[38;5;8;48;5;242m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;250m▄\x1b[38;5;243;48;5;245m▄\x1b[38;5;243;48;5;8m▄\x1b[38;5;245;48;5;7m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;242;48;5;243m▄\x1b[38;5;237;48;5;248m▄\x1b[38;5;145;48;5;59m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;188m▄\x1b[38;5;249;48;5;242m▄\x1b[38;5;237;48;5;8m▄\x1b[38;5;8;48;5;208m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;236m▄\x1b[38;5;17;48;5;232m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;52;48;5;17m▄\x1b[38;5;232;48;5;17m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;25m▄\x1b[38;5;232;48;5;24m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;25;48;5;69m▄\x1b[38;5;33;48;5;69m▄\x1b[38;5;27;48;5;0m▄\x1b[38;5;233;48;5;32m▄\x1b[38;5;240;48;5;7m▄\x1b[38;5;235;48;5;232m▄\x1b[38;5;233;48;5;234m▄\x1b[38;5;220;48;5;130m▄\x1b[38;5;237;48;5;246m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;232;48;5;237m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;236;48;5;0m▄\x1b[38;5;233;48;5;234m▄\x1b[38;5;26;48;5;27m▄\x1b[38;5;25;48;5;32m▄\x1b[38;5;0;48;5;17m▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;24m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄\x1b[38;5;232;48;5;52m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;88;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;9;48;5;233m▄▄\x1b[38;5;124;48;5;232m▄\x1b[38;5;52;48;5;0m▄\x1b[38;5;230;48;5;0m▄\x1b[38;5;144;48;5;245m▄\x1b[38;5;239;48;5;250m▄\x1b[38;5;246;48;5;250m▄\x1b[38;5;237;48;5;0m▄\x1b[38;5;246;48;5;0m▄\x1b[38;5;242;48;5;0m▄\x1b[38;5;59;48;5;0m▄\x1b[38;5;251;48;5;254m▄\x1b[38;5;252;48;5;239m▄\x1b[38;5;0;48;5;8m▄\x1b[38;5;0;48;5;247m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;7;48;5;0m▄\x1b[38;5;239;48;5;252m▄\x1b[38;5;240;48;5;238m▄\x1b[38;5;252;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;243;48;5;247m▄\x1b[38;5;235;48;5;243m▄\x1b[38;5;240;48;5;238m▄\x1b[38;5;245;48;5;0m▄\x1b[38;5;238;48;5;0m▄\x1b[38;5;250;48;5;239m▄\x1b[38;5;247;48;5;240m▄\x1b[38;5;8;48;5;242m▄\x1b[38;5;243;48;5;0m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;249;48;5;240m▄\x1b[38;5;239;48;5;240m▄\x1b[38;5;238;48;5;248m▄\x1b[38;5;246;48;5;0m▄\x1b[38;5;253;48;5;0m▄\x1b[38;5;242;48;5;237m▄\x1b[38;5;248;48;5;236m▄\x1b[38;5;233;48;5;246m▄\x1b[38;5;249;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;8m▄\x1b[38;5;188;48;5;246m▄\x1b[38;5;255;48;5;180m▄\x1b[38;5;215;48;5;52m▄\x1b[38;5;208;48;5;233m▄\x1b[38;5;160;48;5;0m▄\x1b[38;5;160;48;5;232m▄\x1b[38;5;1;48;5;233m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;124;48;5;0m▄\x1b[38;5;52;48;5;233m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;52;48;5;0m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;88;48;5;67m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;235;48;5;232m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;236m▄\x1b[38;5;235;48;5;232m▄\x1b[38;5;24;48;5;4m▄\x1b[38;5;17;48;5;18m▄\x1b[38;5;17;48;5;12m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;30;48;5;20m▄\x1b[38;5;20;48;5;20m▄\x1b[38;5;246;48;5;246m▄\x1b[38;5;238;48;5;242m▄\x1b[38;5;59;48;5;239m▄\x1b[38;5;241;48;5;235m▄\x1b[38;5;246;48;5;178m▄\x1b[38;5;66;48;5;240m▄\x1b[38;5;232;48;5;232m▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;184;48;5;220m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;12;48;5;20m▄\x1b[38;5;17;48;5;24m▄\x1b[38;5;25;48;5;20m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;23;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;1;48;5;0m▄\x1b[38;5;166;48;5;220m▄\x1b[38;5;216;48;5;220m▄\x1b[38;5;255;48;5;220m▄\x1b[38;5;181;48;5;214m▄\x1b[38;5;8;48;5;214m▄\x1b[38;5;101;48;5;214m▄\x1b[38;5;214;48;5;220m▄\x1b[38;5;208;48;5;220m▄\x1b[38;5;215;48;5;11m▄\x1b[38;5;222;48;5;227m▄\x1b[38;5;221;48;5;227m▄\x1b[38;5;215;48;5;11m▄\x1b[38;5;220;48;5;227m▄\x1b[38;5;208;48;5;227m▄\x1b[38;5;0;48;5;202m▄\x1b[38;5;0;48;5;53m▄\x1b[38;5;0;48;5;235m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;52;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄▄\x1b[48;5;0m \x1b[38;5;232;48;5;1m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;237;48;5;0m▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;17;48;5;52m▄\x1b[38;5;0;48;5;52m▄\x1b[38;5;0;48;5;11m▄\x1b[38;5;202;48;5;11m▄\x1b[38;5;208;48;5;227m▄▄\x1b[38;5;214;48;5;227m▄\x1b[38;5;172;48;5;11m▄\x1b[38;5;138;48;5;220m▄\x1b[38;5;215;48;5;11m▄\x1b[38;5;208;48;5;227m▄\x1b[38;5;202;48;5;227m▄\x1b[38;5;202;48;5;230m▄\x1b[38;5;208;48;5;131m▄\x1b[38;5;214;48;5;124m▄\x1b[38;5;255;48;5;160m▄\x1b[38;5;160;48;5;160m▄\x1b[38;5;124;48;5;52m▄\x1b[38;5;232;48;5;52m▄\x1b[38;5;233;48;5;18m▄\x1b[38;5;238;48;5;237m▄\x1b[38;5;94;48;5;241m▄\x1b[38;5;18;48;5;25m▄\x1b[38;5;20;48;5;67m▄\x1b[38;5;20;48;5;17m▄\x1b[38;5;240;48;5;17m▄\x1b[38;5;242;48;5;17m▄\x1b[38;5;237;48;5;236m▄\x1b[38;5;245;48;5;247m▄\x1b[38;5;66;48;5;247m▄\x1b[38;5;66;48;5;245m▄\x1b[38;5;66;48;5;240m▄\x1b[38;5;235;48;5;102m▄\x1b[38;5;17;48;5;24m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;60;48;5;233m▄\x1b[38;5;23;48;5;0m▄\x1b[38;5;237;48;5;235m▄\x1b[38;5;19;48;5;26m▄\x1b[38;5;27;48;5;17m▄\x1b[38;5;81;48;5;24m▄\x1b[38;5;74;48;5;25m▄\x1b[38;5;31;48;5;32m▄\x1b[38;5;0;48;5;32m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;60m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;62m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;12m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;245;48;5;188m▄\x1b[38;5;0;48;5;241m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;101;48;5;238m▄\x1b[38;5;144;48;5;179m▄\x1b[38;5;180;48;5;179m▄\x1b[38;5;180;48;5;173m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;239m▄\x1b[38;5;179;48;5;208m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;208;48;5;0m▄\x1b[38;5;202;48;5;0m▄\x1b[38;5;208;48;5;11m▄▄\x1b[38;5;173;48;5;220m▄\x1b[38;5;209;48;5;11m▄\x1b[38;5;208;48;5;227m▄\x1b[38;5;208;48;5;11m▄\x1b[38;5;208;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;234;48;5;214m▄\x1b[38;5;202;48;5;214m▄\x1b[38;5;221;48;5;220m▄\x1b[38;5;222;48;5;11m▄\x1b[38;5;131;48;5;220m▄\x1b[38;5;0;48;5;1m▄\x1b[38;5;0;48;5;124m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;130;48;5;0m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;215;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;52m▄\x1b[38;5;130;48;5;11m▄\x1b[38;5;214;48;5;11m▄\x1b[38;5;166;48;5;11m▄\x1b[38;5;0;48;5;214m▄\x1b[38;5;0;48;5;52m▄\x1b[38;5;239;48;5;221m▄\x1b[38;5;222;48;5;227m▄\x1b[38;5;222;48;5;11m▄\x1b[38;5;227;48;5;220m▄\x1b[38;5;242;48;5;214m▄\x1b[38;5;247;48;5;208m▄\x1b[38;5;245;48;5;214m▄\x1b[38;5;101;48;5;214m▄\x1b[38;5;179;48;5;208m▄\x1b[38;5;208;48;5;208m▄\x1b[38;5;180;48;5;227m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;144;48;5;180m▄\x1b[38;5;180;48;5;223m▄\x1b[38;5;187;48;5;230m▄\x1b[38;5;188;48;5;230m▄\x1b[38;5;222;48;5;143m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;130m▄\x1b[38;5;234;48;5;179m▄\x1b[38;5;255;48;5;229m▄\x1b[38;5;230;48;5;220m▄\x1b[38;5;255;48;5;214m▄▄\x1b[38;5;94;48;5;0m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;236;48;5;17m▄\x1b[38;5;18;48;5;20m▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;18;48;5;20m▄\x1b[38;5;33;48;5;20m▄\x1b[38;5;39;48;5;0m▄\x1b[38;5;233;48;5;248m▄\x1b[38;5;59;48;5;232m▄\x1b[38;5;245;48;5;233m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;66;48;5;239m▄\x1b[38;5;11;48;5;0m▄\x1b[38;5;237;48;5;232m▄\x1b[38;5;236;48;5;17m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;220;48;5;220m▄\x1b[48;5;0m \x1b[38;5;0;48;5;232m▄\x1b[38;5;18;48;5;39m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;26;48;5;25m▄\x1b[38;5;26;48;5;4m▄\x1b[38;5;0;48;5;25m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;0;48;5;32m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;237m▄\x1b[38;5;0;48;5;0m▄▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄▄\x1b[38;5;0;48;5;250m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;255;48;5;223m▄\x1b[38;5;248;48;5;246m▄\x1b[38;5;240;48;5;248m▄\x1b[38;5;247;48;5;246m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;233;48;5;233m▄\x1b[48;5;0m \x1b[38;5;27;48;5;186m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;214;48;5;0m▄\x1b[38;5;248;48;5;166m▄\x1b[38;5;246;48;5;222m▄\x1b[38;5;249;48;5;187m▄\x1b[38;5;102;48;5;144m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;101m▄\x1b[38;5;251;48;5;186m▄\x1b[38;5;7;48;5;221m▄\x1b[38;5;7;48;5;208m▄\x1b[38;5;220;48;5;0m▄\x1b[48;5;0m \x1b[38;5;101;48;5;187m▄\x1b[38;5;247;48;5;249m▄\x1b[38;5;246;48;5;7m▄\x1b[38;5;254;48;5;221m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;94;48;5;233m▄\x1b[38;5;232;48;5;52m▄\x1b[38;5;172;48;5;0m▄\x1b[38;5;251;48;5;253m▄\x1b[38;5;215;48;5;214m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;180;48;5;186m▄\x1b[38;5;252;48;5;180m▄\x1b[38;5;235;48;5;101m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;252;48;5;187m▄\x1b[38;5;250;48;5;187m▄\x1b[38;5;245;48;5;7m▄\x1b[38;5;186;48;5;143m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;251m▄\x1b[38;5;243;48;5;179m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;243;48;5;247m▄\x1b[38;5;246;48;5;249m▄\x1b[38;5;8;48;5;241m▄\x1b[38;5;59;48;5;248m▄\x1b[38;5;187;48;5;223m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;137;48;5;137m▄\x1b[38;5;7;48;5;252m▄\x1b[38;5;251;48;5;250m▄\x1b[38;5;238;48;5;8m▄\x1b[38;5;144;48;5;179m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;18;48;5;233m▄\x1b[38;5;20;48;5;17m▄\x1b[38;5;27;48;5;25m▄\x1b[38;5;12;48;5;20m▄\x1b[38;5;32;48;5;17m▄\x1b[38;5;20;48;5;18m▄\x1b[38;5;102;48;5;246m▄\x1b[38;5;109;48;5;247m▄\x1b[38;5;235;48;5;59m▄\x1b[38;5;66;48;5;60m▄\x1b[38;5;59;48;5;234m▄\x1b[38;5;66;48;5;233m▄\x1b[38;5;240;48;5;245m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;233;48;5;0m▄\x1b[48;5;0m \x1b[38;5;60;48;5;0m▄\x1b[38;5;12;48;5;20m▄\x1b[38;5;19;48;5;17m▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;25;48;5;233m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;239;48;5;24m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;18;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;20;48;5;17m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;254;48;5;254m▄\x1b[38;5;249;48;5;243m▄\x1b[38;5;102;48;5;247m▄\x1b[38;5;240;48;5;102m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;250;48;5;247m▄\x1b[38;5;241;48;5;7m▄\x1b[38;5;248;48;5;253m▄\x1b[38;5;255;48;5;247m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;252;48;5;254m▄\x1b[38;5;249;48;5;251m▄\x1b[38;5;249;48;5;188m▄\x1b[38;5;249;48;5;145m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;235m▄\x1b[38;5;145;48;5;247m▄\x1b[38;5;237;48;5;247m▄\x1b[38;5;188;48;5;250m▄\x1b[38;5;228;48;5;179m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;1;48;5;52m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;188;48;5;188m▄\x1b[38;5;250;48;5;8m▄\x1b[38;5;145;48;5;247m▄\x1b[38;5;223;48;5;208m▄\x1b[48;5;0m \x1b[38;5;0;48;5;52m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;240;48;5;245m▄\x1b[38;5;253;48;5;253m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;188;48;5;254m▄\x1b[38;5;15;48;5;251m▄\x1b[38;5;241;48;5;255m▄\x1b[38;5;241;48;5;186m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;242;48;5;248m▄\x1b[38;5;245;48;5;8m▄\x1b[38;5;247;48;5;245m▄\x1b[38;5;241;48;5;246m▄\x1b[38;5;247;48;5;187m▄\x1b[48;5;0m \x1b[38;5;0;48;5;19m▄\x1b[38;5;18;48;5;0m▄\x1b[48;5;0m \x1b[38;5;232;48;5;0m▄\x1b[38;5;249;48;5;254m▄\x1b[38;5;7;48;5;247m▄\x1b[38;5;145;48;5;247m▄\x1b[38;5;247;48;5;236m▄\x1b[38;5;0;48;5;251m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;4;48;5;18m▄\x1b[38;5;17;48;5;18m▄\x1b[38;5;20;48;5;20m▄\x1b[38;5;20;48;5;12m▄\x1b[38;5;26;48;5;12m▄\x1b[38;5;17;48;5;27m▄\x1b[38;5;0;48;5;27m▄\x1b[38;5;239;48;5;246m▄\x1b[38;5;241;48;5;232m▄\x1b[38;5;233;48;5;67m▄\x1b[38;5;66;48;5;66m▄\x1b[38;5;59;48;5;66m▄\x1b[38;5;242;48;5;245m▄\x1b[38;5;60;48;5;243m▄\x1b[38;5;23;48;5;60m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;23;48;5;0m▄\x1b[38;5;23;48;5;233m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;12;48;5;27m▄\x1b[38;5;26;48;5;27m▄\x1b[38;5;4;48;5;26m▄\x1b[38;5;4;48;5;17m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;237m▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;4;48;5;17m▄\x1b[38;5;25;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;0;48;5;4m▄▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;15;48;5;145m▄\x1b[38;5;241;48;5;241m▄\x1b[38;5;240;48;5;246m▄\x1b[38;5;188;48;5;251m▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;239;48;5;188m▄\x1b[38;5;241;48;5;245m▄\x1b[38;5;8;48;5;242m▄\x1b[38;5;238;48;5;243m▄\x1b[38;5;237;48;5;238m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;7;48;5;249m▄\x1b[38;5;241;48;5;239m▄\x1b[38;5;239;48;5;245m▄\x1b[38;5;247;48;5;8m▄\x1b[38;5;250;48;5;240m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;251m▄\x1b[38;5;145;48;5;243m▄\x1b[38;5;246;48;5;102m▄\x1b[38;5;145;48;5;240m▄\x1b[48;5;0m \x1b[38;5;0;48;5;52m▄\x1b[38;5;248;48;5;240m▄\x1b[38;5;242;48;5;239m▄\x1b[38;5;238;48;5;245m▄\x1b[38;5;241;48;5;246m▄\x1b[38;5;247;48;5;243m▄\x1b[38;5;8;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;249;48;5;250m▄\x1b[38;5;248;48;5;243m▄\x1b[38;5;0;48;5;248m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;255;48;5;239m▄\x1b[38;5;243;48;5;59m▄\x1b[38;5;246;48;5;239m▄\x1b[38;5;242;48;5;241m▄\x1b[38;5;245;48;5;186m▄\x1b[38;5;243;48;5;137m▄\x1b[38;5;239;48;5;229m▄\x1b[38;5;243;48;5;193m▄\x1b[38;5;0;48;5;187m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;255;48;5;248m▄\x1b[38;5;239;48;5;239m▄\x1b[38;5;234;48;5;238m▄\x1b[38;5;242;48;5;237m▄\x1b[38;5;145;48;5;102m▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;252;48;5;0m▄\x1b[38;5;251;48;5;0m▄\x1b[38;5;245;48;5;0m▄\x1b[38;5;250;48;5;8m▄\x1b[38;5;233;48;5;240m▄\x1b[38;5;0;48;5;245m▄\x1b[38;5;0;48;5;254m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;31;48;5;232m▄\x1b[38;5;110;48;5;0m▄\x1b[38;5;60;48;5;17m▄\x1b[38;5;232;48;5;18m▄\x1b[38;5;66;48;5;0m▄\x1b[38;5;240;48;5;109m▄\x1b[38;5;59;48;5;109m▄\x1b[38;5;60;48;5;66m▄\x1b[38;5;239;48;5;240m▄\x1b[38;5;60;48;5;241m▄\x1b[38;5;233;48;5;66m▄\x1b[38;5;0;48;5;59m▄\x1b[38;5;0;48;5;66m▄\x1b[38;5;233;48;5;17m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;235m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;238m▄\x1b[38;5;0;48;5;27m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;232;48;5;25m▄\x1b[38;5;220;48;5;25m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;32m▄\x1b[38;5;233;48;5;24m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;23;48;5;31m▄\x1b[38;5;31;48;5;25m▄\x1b[38;5;232;48;5;25m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;23;48;5;0m▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;67;48;5;0m▄\x1b[38;5;31;48;5;23m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;188;48;5;153m▄\x1b[38;5;61;48;5;240m▄\x1b[38;5;61;48;5;237m▄\x1b[38;5;238;48;5;239m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[38;5;248;48;5;145m▄\x1b[38;5;25;48;5;238m▄\x1b[38;5;60;48;5;236m▄\x1b[38;5;25;48;5;60m▄\x1b[38;5;61;48;5;239m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;247;48;5;250m▄\x1b[38;5;62;48;5;59m▄\x1b[38;5;101;48;5;240m▄\x1b[38;5;237;48;5;242m▄\x1b[38;5;68;48;5;145m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;249;48;5;59m▄\x1b[38;5;24;48;5;103m▄\x1b[38;5;61;48;5;248m▄\x1b[38;5;103;48;5;246m▄\x1b[38;5;187;48;5;0m▄\x1b[38;5;103;48;5;243m▄\x1b[38;5;0;48;5;245m▄\x1b[38;5;23;48;5;247m▄\x1b[38;5;237;48;5;237m▄\x1b[38;5;236;48;5;245m▄\x1b[38;5;249;48;5;59m▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;103;48;5;239m▄\x1b[38;5;62;48;5;248m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[38;5;237;48;5;249m▄\x1b[38;5;61;48;5;239m▄\x1b[38;5;237;48;5;246m▄\x1b[38;5;7;48;5;248m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;247m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;61;48;5;247m▄\x1b[38;5;60;48;5;234m▄\x1b[38;5;18;48;5;238m▄\x1b[38;5;234;48;5;243m▄\x1b[38;5;250;48;5;250m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;145;48;5;243m▄\x1b[38;5;60;48;5;239m▄\x1b[38;5;60;48;5;8m▄\x1b[38;5;60;48;5;243m▄\x1b[38;5;18;48;5;251m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;24;48;5;23m▄\x1b[38;5;24;48;5;235m▄\x1b[38;5;31;48;5;25m▄\x1b[38;5;0;48;5;109m▄\x1b[38;5;24;48;5;232m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;240;48;5;66m▄\x1b[38;5;235;48;5;60m▄\x1b[38;5;235;48;5;233m▄\x1b[38;5;103;48;5;232m▄\x1b[38;5;67;48;5;237m▄\x1b[38;5;60;48;5;237m▄\x1b[38;5;67;48;5;66m▄\x1b[38;5;67;48;5;238m▄\x1b[38;5;23;48;5;59m▄\x1b[38;5;17;48;5;233m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;233m▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;23;48;5;232m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;25;48;5;24m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;234;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;234m▄\x1b[m
|
||||||
|
\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;66m▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;25;48;5;234m▄\x1b[38;5;235;48;5;67m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;237;48;5;17m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;4m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;195;48;5;254m▄\x1b[38;5;60;48;5;24m▄\x1b[38;5;18;48;5;68m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;20;48;5;18m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;237;48;5;26m▄\x1b[38;5;60;48;5;62m▄\x1b[38;5;239;48;5;67m▄\x1b[38;5;236;48;5;19m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;75;48;5;237m▄\x1b[38;5;236;48;5;19m▄\x1b[38;5;103;48;5;18m▄\x1b[38;5;233;48;5;103m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;109m▄\x1b[38;5;243;48;5;69m▄\x1b[38;5;250;48;5;249m▄\x1b[38;5;240;48;5;238m▄\x1b[38;5;246;48;5;249m▄\x1b[38;5;32;48;5;68m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;75;48;5;7m▄\x1b[38;5;249;48;5;248m▄\x1b[38;5;239;48;5;238m▄\x1b[38;5;237;48;5;253m▄\x1b[38;5;8;48;5;8m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;60;48;5;4m▄\x1b[38;5;237;48;5;60m▄\x1b[38;5;236;48;5;24m▄\x1b[38;5;7;48;5;250m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;20;48;5;17m▄\x1b[38;5;110;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;60;48;5;103m▄\x1b[38;5;101;48;5;60m▄\x1b[38;5;237;48;5;63m▄\x1b[38;5;239;48;5;236m▄\x1b[38;5;251;48;5;7m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;59;48;5;8m▄\x1b[38;5;237;48;5;60m▄\x1b[38;5;60;48;5;8m▄\x1b[38;5;237;48;5;240m▄\x1b[38;5;234;48;5;103m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;19;48;5;19m▄\x1b[38;5;66;48;5;0m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;31;48;5;0m▄\x1b[38;5;24;48;5;24m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;109;48;5;241m▄\x1b[38;5;67;48;5;66m▄\x1b[38;5;234;48;5;103m▄\x1b[38;5;60;48;5;66m▄\x1b[38;5;66;48;5;66m▄\x1b[38;5;66;48;5;60m▄\x1b[38;5;11;48;5;0m▄\x1b[38;5;60;48;5;109m▄\x1b[38;5;66;48;5;67m▄\x1b[38;5;17;48;5;234m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;24;48;5;24m▄\x1b[38;5;220;48;5;220m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;236;48;5;0m▄\x1b[38;5;24;48;5;17m▄\x1b[38;5;0;48;5;38m▄\x1b[38;5;67;48;5;233m▄\x1b[38;5;59;48;5;243m▄\x1b[38;5;24;48;5;241m▄\x1b[38;5;25;48;5;109m▄\x1b[38;5;233;48;5;67m▄\x1b[38;5;233;48;5;17m▄\x1b[38;5;25;48;5;23m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;60m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;24;48;5;17m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;17;48;5;233m▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;17;48;5;24m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;66m▄\x1b[38;5;4;48;5;4m▄\x1b[38;5;195;48;5;159m▄\x1b[38;5;75;48;5;62m▄\x1b[38;5;39;48;5;68m▄\x1b[38;5;69;48;5;19m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;19;48;5;18m▄\x1b[38;5;19;48;5;17m▄\x1b[38;5;0;48;5;81m▄\x1b[38;5;25;48;5;17m▄\x1b[38;5;38;48;5;24m▄\x1b[38;5;81;48;5;74m▄\x1b[38;5;81;48;5;87m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;4;48;5;17m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;25;48;5;18m▄\x1b[38;5;31;48;5;81m▄\x1b[38;5;38;48;5;24m▄\x1b[38;5;25;48;5;17m▄\x1b[38;5;17;48;5;80m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;18;48;5;18m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;159;48;5;87m▄\x1b[38;5;81;48;5;81m▄\x1b[38;5;45;48;5;38m▄\x1b[38;5;81;48;5;31m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;17m \x1b[38;5;0;48;5;0m▄\x1b[38;5;123;48;5;45m▄\x1b[38;5;31;48;5;31m▄\x1b[38;5;31;48;5;24m▄\x1b[38;5;81;48;5;38m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;17;48;5;18m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;19;48;5;17m▄▄\x1b[38;5;38;48;5;45m▄\x1b[38;5;81;48;5;32m▄\x1b[38;5;38;48;5;38m▄\x1b[38;5;81;48;5;38m▄\x1b[38;5;4;48;5;17m▄▄\x1b[38;5;20;48;5;18m▄\x1b[38;5;20;48;5;19m▄\x1b[38;5;17;48;5;19m▄\x1b[38;5;38;48;5;0m▄\x1b[38;5;44;48;5;37m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;26;48;5;25m▄\x1b[38;5;25;48;5;17m▄\x1b[38;5;18;48;5;25m▄\x1b[38;5;26;48;5;25m▄\x1b[38;5;159;48;5;81m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;87;48;5;67m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;25;48;5;235m▄\x1b[38;5;69;48;5;4m▄\x1b[38;5;25;48;5;75m▄\x1b[38;5;38;48;5;0m▄\x1b[38;5;4;48;5;4m▄\x1b[38;5;0;48;5;25m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;237;48;5;236m▄\x1b[38;5;66;48;5;67m▄\x1b[38;5;136;48;5;166m▄\x1b[38;5;60;48;5;240m▄\x1b[38;5;66;48;5;66m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;52;48;5;208m▄\x1b[38;5;66;48;5;60m▄\x1b[38;5;60;48;5;66m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;23;48;5;236m▄\x1b[38;5;17;48;5;184m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;232;48;5;17m▄\x1b[38;5;25;48;5;25m▄\x1b[38;5;23;48;5;25m▄\x1b[38;5;247;48;5;17m▄\x1b[38;5;232;48;5;25m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;25;48;5;18m▄\x1b[38;5;87;48;5;159m▄\x1b[38;5;14;48;5;39m▄\x1b[38;5;39;48;5;39m▄▄\x1b[38;5;159;48;5;31m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;20m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;237;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;87m▄\x1b[38;5;0;48;5;81m▄\x1b[38;5;0;48;5;45m▄\x1b[38;5;33;48;5;45m▄\x1b[38;5;75;48;5;23m▄\x1b[38;5;74;48;5;45m▄\x1b[38;5;116;48;5;14m▄\x1b[38;5;0;48;5;87m▄\x1b[38;5;0;48;5;45m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;20;48;5;18m▄\x1b[38;5;0;48;5;110m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;20;48;5;19m▄\x1b[38;5;18;48;5;116m▄\x1b[38;5;123;48;5;45m▄\x1b[38;5;14;48;5;45m▄\x1b[38;5;0;48;5;123m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;19;48;5;18m▄\x1b[38;5;19;48;5;17m▄\x1b[38;5;20;48;5;18m▄\x1b[38;5;0;48;5;159m▄\x1b[38;5;87;48;5;45m▄\x1b[38;5;87;48;5;38m▄\x1b[38;5;19;48;5;24m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;195;48;5;19m▄\x1b[38;5;15;48;5;159m▄\x1b[38;5;15;48;5;81m▄\x1b[38;5;15;48;5;14m▄\x1b[38;5;15;48;5;39m▄\x1b[38;5;15;48;5;45m▄\x1b[38;5;15;48;5;38m▄\x1b[38;5;15;48;5;25m▄\x1b[38;5;15;48;5;80m▄\x1b[38;5;195;48;5;25m▄\x1b[38;5;15;48;5;39m▄\x1b[38;5;15;48;5;14m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;19;48;5;18m▄\x1b[38;5;233;48;5;232m▄\x1b[38;5;25;48;5;26m▄\x1b[38;5;26;48;5;26m▄\x1b[38;5;32;48;5;26m▄\x1b[38;5;45;48;5;39m▄\x1b[38;5;159;48;5;195m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;20;48;5;0m▄\x1b[38;5;4;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;195;48;5;32m▄\x1b[38;5;39;48;5;32m▄\x1b[38;5;39;48;5;33m▄\x1b[38;5;39;48;5;39m▄\x1b[38;5;81;48;5;81m▄\x1b[38;5;195;48;5;17m▄\x1b[38;5;24;48;5;17m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;18;48;5;4m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;31m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;24;48;5;23m▄\x1b[38;5;233;48;5;23m▄\x1b[38;5;60;48;5;237m▄\x1b[38;5;61;48;5;60m▄\x1b[38;5;60;48;5;239m▄\x1b[38;5;24;48;5;239m▄\x1b[38;5;60;48;5;233m▄\x1b[38;5;60;48;5;59m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;67;48;5;236m▄\x1b[38;5;17;48;5;232m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;236;48;5;23m▄\x1b[38;5;233;48;5;17m▄\x1b[38;5;36;48;5;234m▄\x1b[38;5;24;48;5;234m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;23m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;23m▄\x1b[38;5;0;48;5;235m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;25;48;5;6m▄\x1b[38;5;12;48;5;234m▄\x1b[38;5;27;48;5;24m▄\x1b[38;5;14;48;5;25m▄\x1b[38;5;87;48;5;33m▄\x1b[38;5;195;48;5;87m▄\x1b[38;5;15;48;5;87m▄\x1b[38;5;15;48;5;14m▄\x1b[38;5;39;48;5;14m▄\x1b[38;5;4;48;5;45m▄\x1b[38;5;232;48;5;45m▄\x1b[38;5;232;48;5;110m▄\x1b[38;5;232;48;5;17m▄\x1b[38;5;232;48;5;20m▄\x1b[38;5;0;48;5;20m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;19m▄▄\x1b[38;5;0;48;5;26m▄\x1b[38;5;0;48;5;27m▄▄▄\x1b[38;5;0;48;5;26m▄▄\x1b[38;5;32;48;5;27m▄\x1b[38;5;27;48;5;32m▄\x1b[38;5;19;48;5;32m▄\x1b[38;5;0;48;5;32m▄\x1b[38;5;232;48;5;33m▄\x1b[38;5;26;48;5;45m▄\x1b[38;5;27;48;5;45m▄\x1b[38;5;233;48;5;14m▄\x1b[38;5;0;48;5;87m▄\x1b[38;5;32;48;5;19m▄\x1b[38;5;81;48;5;15m▄\x1b[38;5;15;48;5;123m▄\x1b[38;5;159;48;5;17m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;87;48;5;26m▄▄\x1b[38;5;33;48;5;26m▄\x1b[38;5;27;48;5;17m▄\x1b[38;5;15;48;5;87m▄\x1b[38;5;39;48;5;195m▄\x1b[38;5;45;48;5;19m▄\x1b[38;5;0;48;5;25m▄\x1b[38;5;0;48;5;45m▄\x1b[38;5;32;48;5;39m▄\x1b[38;5;33;48;5;26m▄\x1b[38;5;23;48;5;27m▄\x1b[38;5;23;48;5;33m▄\x1b[38;5;26;48;5;27m▄\x1b[38;5;26;48;5;26m▄\x1b[38;5;26;48;5;17m▄\x1b[38;5;0;48;5;17m▄▄▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;24;48;5;18m▄\x1b[38;5;23;48;5;19m▄\x1b[38;5;24;48;5;19m▄\x1b[38;5;31;48;5;17m▄\x1b[38;5;66;48;5;0m▄\x1b[38;5;60;48;5;123m▄\x1b[38;5;60;48;5;39m▄\x1b[38;5;60;48;5;25m▄\x1b[38;5;61;48;5;32m▄\x1b[38;5;195;48;5;45m▄\x1b[38;5;15;48;5;195m▄\x1b[38;5;195;48;5;87m▄\x1b[38;5;159;48;5;26m▄\x1b[38;5;26;48;5;19m▄\x1b[38;5;20;48;5;18m▄\x1b[38;5;19;48;5;17m▄\x1b[38;5;27;48;5;87m▄\x1b[38;5;123;48;5;45m▄\x1b[38;5;14;48;5;14m▄▄▄\x1b[38;5;159;48;5;26m▄\x1b[38;5;26;48;5;18m▄\x1b[38;5;26;48;5;17m▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;0;48;5;25m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;32;48;5;25m▄\x1b[38;5;24;48;5;25m▄\x1b[38;5;25;48;5;24m▄\x1b[38;5;67;48;5;234m▄\x1b[38;5;235;48;5;60m▄\x1b[38;5;60;48;5;60m▄▄\x1b[38;5;66;48;5;60m▄\x1b[38;5;67;48;5;0m▄\x1b[38;5;60;48;5;60m▄\x1b[38;5;24;48;5;23m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;24;48;5;214m▄\x1b[38;5;23;48;5;24m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;19;48;5;234m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;240m▄\x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;241;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;233;48;5;18m▄\x1b[38;5;234;48;5;25m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;23;48;5;0m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;4;48;5;25m▄\x1b[38;5;20;48;5;159m▄\x1b[38;5;17;48;5;195m▄\x1b[38;5;25;48;5;25m▄\x1b[38;5;19;48;5;26m▄▄\x1b[38;5;20;48;5;27m▄\x1b[38;5;27;48;5;27m▄\x1b[38;5;19;48;5;25m▄\x1b[38;5;18;48;5;18m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;17;48;5;232m▄\x1b[38;5;24;48;5;18m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[38;5;4;48;5;4m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄\x1b[38;5;0;48;5;19m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;0;48;5;20m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;18;48;5;26m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;27;48;5;81m▄\x1b[38;5;0;48;5;32m▄\x1b[38;5;19;48;5;25m▄\x1b[38;5;19;48;5;15m▄\x1b[38;5;26;48;5;15m▄\x1b[38;5;19;48;5;33m▄\x1b[38;5;17;48;5;33m▄\x1b[38;5;0;48;5;39m▄\x1b[38;5;27;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;20;48;5;233m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;27m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;235;48;5;232m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;24;48;5;24m▄\x1b[38;5;234;48;5;17m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;4;48;5;24m▄\x1b[38;5;25;48;5;17m▄▄\x1b[38;5;17;48;5;24m▄\x1b[38;5;45;48;5;44m▄\x1b[38;5;24;48;5;25m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;17;48;5;25m▄\x1b[38;5;0;48;5;25m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;23;48;5;26m▄\x1b[38;5;17;48;5;27m▄\x1b[38;5;17;48;5;159m▄\x1b[38;5;4;48;5;159m▄\x1b[38;5;17;48;5;15m▄\x1b[38;5;25;48;5;123m▄\x1b[38;5;25;48;5;87m▄\x1b[38;5;17;48;5;159m▄\x1b[38;5;87;48;5;26m▄\x1b[38;5;87;48;5;4m▄\x1b[38;5;25;48;5;26m▄\x1b[38;5;24;48;5;17m▄\x1b[38;5;17;48;5;24m▄\x1b[38;5;24;48;5;4m▄\x1b[38;5;24;48;5;236m▄\x1b[38;5;24;48;5;235m▄\x1b[38;5;24;48;5;232m▄\x1b[38;5;234;48;5;235m▄\x1b[38;5;234;48;5;238m▄\x1b[38;5;23;48;5;235m▄\x1b[38;5;236;48;5;237m▄\x1b[38;5;24;48;5;233m▄\x1b[38;5;17;48;5;233m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;235;48;5;232m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;0;48;5;235m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;19;48;5;19m▄\x1b[38;5;4;48;5;232m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;4m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;17m▄▄▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;17;48;5;4m▄\x1b[38;5;20;48;5;19m▄\x1b[38;5;17;48;5;12m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;240;48;5;232m▄\x1b[38;5;245;48;5;236m▄\x1b[38;5;233;48;5;239m▄\x1b[38;5;0;48;5;23m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄\x1b[38;5;0;48;5;27m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;26m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;20m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;19;48;5;19m▄\x1b[38;5;0;48;5;20m▄\x1b[38;5;27;48;5;0m▄\x1b[38;5;0;48;5;27m▄\x1b[38;5;0;48;5;18m▄\x1b[38;5;19;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;26m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;232;48;5;23m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;236;48;5;235m▄\x1b[38;5;232;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;27m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;18;48;5;17m▄\x1b[38;5;17;48;5;233m▄\x1b[38;5;4;48;5;87m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;232;48;5;26m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;0;48;5;17m▄▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;24m▄\x1b[38;5;24;48;5;17m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;25;48;5;14m▄\x1b[38;5;24;48;5;24m▄\x1b[38;5;17;48;5;24m▄\x1b[38;5;23;48;5;25m▄\x1b[38;5;0;48;5;237m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;236;48;5;23m▄\x1b[38;5;23;48;5;23m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;0;48;5;23m▄\x1b[38;5;23;48;5;24m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;246;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;12m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;18m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;17;48;5;237m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;0;48;5;23m▄\x1b[38;5;23;48;5;232m▄\x1b[38;5;236;48;5;0m▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;233;48;5;0m▄\x1b[38;5;0;48;5;247m▄\x1b[38;5;67;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;238m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;23;48;5;233m▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;17;48;5;233m▄\x1b[38;5;23;48;5;0m▄\x1b[38;5;234;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[38;5;19;48;5;0m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;0;48;5;27m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄▄\x1b[38;5;0;48;5;241m▄\x1b[38;5;8;48;5;235m▄\x1b[38;5;232;48;5;233m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;103m▄\x1b[38;5;24;48;5;241m▄\x1b[38;5;0;48;5;236m▄\x1b[38;5;235;48;5;0m▄\x1b[38;5;0;48;5;237m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;62m▄\x1b[38;5;18;48;5;0m▄\x1b[38;5;232;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;18m▄\x1b[38;5;0;48;5;17m▄▄\x1b[38;5;17;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;4m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄▄▄▄\x1b[38;5;232;48;5;234m▄\x1b[38;5;235;48;5;23m▄\x1b[38;5;233;48;5;24m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;235m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;232;48;5;232m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;235;48;5;23m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;239;48;5;17m▄\x1b[38;5;232;48;5;24m▄\x1b[38;5;0;48;5;23m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;233;48;5;0m▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;24;48;5;17m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;81;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;0;48;5;0m▄\x1b[48;5;0m \x1b[m
|
||||||
|
\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄▄▄▄▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;234m▄\x1b[48;5;0m \x1b[38;5;0;48;5;233m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;17;48;5;24m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;0;48;5;32m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;236;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;60;48;5;0m▄\x1b[38;5;236;48;5;232m▄\x1b[38;5;242;48;5;238m▄\x1b[38;5;234;48;5;237m▄\x1b[38;5;237;48;5;0m▄\x1b[38;5;235;48;5;233m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;233m▄\x1b[38;5;0;48;5;191m▄\x1b[38;5;238;48;5;0m▄\x1b[38;5;237;48;5;232m▄\x1b[38;5;0;48;5;60m▄\x1b[38;5;232;48;5;60m▄\x1b[38;5;235;48;5;233m▄\x1b[38;5;17;48;5;233m▄\x1b[38;5;0;48;5;238m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;25m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;146;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄▄▄\x1b[38;5;24;48;5;0m▄\x1b[38;5;0;48;5;25m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;236;48;5;0m▄\x1b[38;5;0;48;5;32m▄\x1b[38;5;0;48;5;239m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;234m▄\x1b[38;5;232;48;5;246m▄\x1b[38;5;74;48;5;246m▄\x1b[38;5;235;48;5;234m▄\x1b[38;5;236;48;5;236m▄\x1b[38;5;233;48;5;24m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;17;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;26m▄\x1b[38;5;232;48;5;24m▄\x1b[38;5;17;48;5;0m▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;17m▄▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;31;48;5;25m▄\x1b[38;5;25;48;5;0m▄\x1b[38;5;24;48;5;232m▄\x1b[38;5;4;48;5;0m▄\x1b[38;5;24;48;5;26m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;233;48;5;25m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;23;48;5;17m▄\x1b[38;5;0;48;5;61m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;233;48;5;233m▄\x1b[38;5;60;48;5;233m▄\x1b[38;5;232;48;5;235m▄\x1b[38;5;25;48;5;24m▄\x1b[38;5;67;48;5;23m▄\x1b[38;5;234;48;5;23m▄\x1b[38;5;23;48;5;23m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;239;48;5;239m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;232m▄\x1b[38;5;109;48;5;236m▄\x1b[38;5;0;48;5;17m▄\x1b[38;5;0;48;5;23m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[38;5;233;48;5;23m▄\x1b[38;5;0;48;5;0m▄\x1b[38;5;0;48;5;24m▄\x1b[38;5;232;48;5;0m▄\x1b[38;5;0;48;5;0m▄▄▄\x1b[48;5;0m \x1b[38;5;0;48;5;0m▄▄▄\x1b[m
|
||||||
|
\x1b[49;38;5;0m▀▀▀▀▀▀▀▀▀▀\x1b[49;38;5;242m▀\x1b[49;38;5;102m▀\x1b[49;38;5;0m▀▀▀▀▀▀▀▀▀▀▀▀\x1b[49;38;5;239m▀\x1b[49;38;5;241m▀\x1b[49;38;5;0m▀▀▀▀▀▀\x1b[49;38;5;4m▀\x1b[49;38;5;17m▀\x1b[49;38;5;0m▀▀▀▀▀\x1b[49;38;5;18m▀\x1b[49;38;5;0m▀\x1b[49;38;5;24m▀\x1b[49;38;5;0m▀▀▀▀▀▀▀▀▀▀▀▀▀▀\x1b[49;38;5;241m▀\x1b[49;38;5;0m▀\x1b[49;38;5;232m▀\x1b[49;38;5;234m▀\x1b[49;38;5;233m▀\x1b[49;38;5;234m▀\x1b[49;38;5;0m▀\x1b[49;38;5;18m▀\x1b[49;38;5;19m▀\x1b[49;38;5;233m▀\x1b[49;38;5;232m▀\x1b[49;38;5;23m▀\x1b[49;38;5;74m▀\x1b[49;38;5;0m▀▀▀\x1b[49;38;5;233m▀\x1b[49;38;5;0m▀▀\x1b[49;38;5;17m▀\x1b[49;38;5;0m▀▀\x1b[49;38;5;233m▀\x1b[49;38;5;0m▀\x1b[49;38;5;237m▀\x1b[49;38;5;0m▀▀▀▀\x1b[49;38;5;235m▀\x1b[49;38;5;0m▀▀▀▀▀▀\x1b[49;38;5;25m▀\x1b[49;38;5;24m▀\x1b[49;38;5;234m▀\x1b[49;38;5;23m▀\x1b[49;38;5;232m▀\x1b[49;38;5;235m▀\x1b[49;38;5;0m▀\x1b[49;38;5;60m▀\x1b[49;38;5;237m▀\x1b[49;38;5;243m▀\x1b[49;38;5;239m▀\x1b[49;38;5;0m▀\x1b[49;38;5;233m▀\x1b[49;38;5;0m▀▀▀\x1b[49;38;5;23m▀\x1b[49;38;5;0m▀▀▀▀▀▀▀▀▀▀▀\x1b[m
|
||||||
|
|
||||||
|
`;
|
||||||
|
|
||||||
|
const LIGHTHOUSE_HEADER = `
|
||||||
|
.
|
||||||
|
/|\\
|
||||||
|
/ | \\
|
||||||
|
/ | \\
|
||||||
|
/ | \\
|
||||||
|
/ | \\
|
||||||
|
/ .--+--. \\
|
||||||
|
/__/ | \\__\\
|
||||||
|
[__] | [__]
|
||||||
|
|
|
||||||
|
~~~~~~~|~~~~~~~
|
||||||
|
`;
|
||||||
561
assets/js/games/games/system-shutdown-1999/chapter-1.js
Normal file
561
assets/js/games/games/system-shutdown-1999/chapter-1.js
Normal file
|
|
@ -0,0 +1,561 @@
|
||||||
|
// System Shutdown: 1999 - Chapter 1: Boxing Day
|
||||||
|
// December 26, 1999 - Five days until the millennium
|
||||||
|
// This is the refactored version using shared scenes and series state
|
||||||
|
|
||||||
|
const CHAPTER1_GLITCH_ART = `
|
||||||
|
▓▓▓▒▒░░ E̸̢R̷̨R̵̢O̸̧R̷̨ ░░▒▒▓▓▓
|
||||||
|
░▒▓█ D̶̨A̷̧T̸̢Ą̵ C̷̢Ǫ̸Ŗ̵R̷̨U̸̢P̵̧T̷̨ █▓▒░
|
||||||
|
▓░▒█ ???????????????? █▒░▓
|
||||||
|
`;
|
||||||
|
|
||||||
|
const CHAPTER1_END_SCREEN = `
|
||||||
|
╔════════════════════════════════════════╗
|
||||||
|
║ ║
|
||||||
|
║ CONNECTION TERMINATED ║
|
||||||
|
║ ║
|
||||||
|
║ Five days remain... ║
|
||||||
|
║ ║
|
||||||
|
╚════════════════════════════════════════╝
|
||||||
|
`;
|
||||||
|
|
||||||
|
const chapter1Game = {
|
||||||
|
// Series integration
|
||||||
|
id: "system-shutdown-1999-chapter-1",
|
||||||
|
seriesId: "system-shutdown-1999",
|
||||||
|
chapterNumber: 1,
|
||||||
|
|
||||||
|
// Game metadata
|
||||||
|
name: "System Shutdown: 1999 - Boxing Day",
|
||||||
|
command: "dial",
|
||||||
|
description: "Connect to Dark Tower BBS - December 26, 1999",
|
||||||
|
|
||||||
|
// Art assets (passed to scene factories via context)
|
||||||
|
art: {
|
||||||
|
CHAPTER1_GLITCH_ART,
|
||||||
|
CHAPTER1_END_SCREEN,
|
||||||
|
},
|
||||||
|
|
||||||
|
// External shared scenes to load
|
||||||
|
externalScenes: [
|
||||||
|
"system-shutdown-1999/dark-tower-hub",
|
||||||
|
"system-shutdown-1999/lighthouse-hub",
|
||||||
|
],
|
||||||
|
|
||||||
|
// Chapter-specific initial state (resets each playthrough)
|
||||||
|
initialState: {
|
||||||
|
// Message discovery
|
||||||
|
read_new_message: false,
|
||||||
|
found_number: false,
|
||||||
|
|
||||||
|
// Scene visit tracking (chapter-local)
|
||||||
|
visited: {},
|
||||||
|
},
|
||||||
|
|
||||||
|
// Shared state defaults (only set if not already present in series state)
|
||||||
|
sharedStateDefaults: {
|
||||||
|
// Completion tracking
|
||||||
|
chapters_completed: [],
|
||||||
|
|
||||||
|
// Cross-chapter decisions
|
||||||
|
downloaded_cascade: false,
|
||||||
|
talked_to_sysop: false,
|
||||||
|
deleted_corrupted_file: false,
|
||||||
|
route_taken: null,
|
||||||
|
|
||||||
|
// World state changes
|
||||||
|
archives_deleted: false,
|
||||||
|
corrupted_file_deleted: false,
|
||||||
|
|
||||||
|
// Discovery flags (shared so later chapters know)
|
||||||
|
dialed_lighthouse: false,
|
||||||
|
seen_archive_glitch: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
intro: [
|
||||||
|
{
|
||||||
|
type: "ansi",
|
||||||
|
art: BOXING_DAY_TITLE,
|
||||||
|
className: "game-ansi-art center",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ text: "December 26, 1999 - 10:47 PM", className: "info" },
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
"Five days until the millennium.",
|
||||||
|
{ type: "delay", ms: 1500 },
|
||||||
|
"Five days until everything might change.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 1000 },
|
||||||
|
"Your 56k modem hums quietly in the dark.",
|
||||||
|
"The house is silent. Everyone else is asleep.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 400 },
|
||||||
|
{
|
||||||
|
text: "<strong>This game occasionally plays sounds, mute your tab now if that offends you.</strong>",
|
||||||
|
html: true,
|
||||||
|
className: "warning",
|
||||||
|
},
|
||||||
|
{ text: 'Type "quit" at any time to save and exit.', className: "info" },
|
||||||
|
],
|
||||||
|
|
||||||
|
startScene: "connect_prompt",
|
||||||
|
|
||||||
|
// Chapter-specific scenes (these override or extend shared scenes)
|
||||||
|
scenes: {
|
||||||
|
// ==========================================
|
||||||
|
// OPENING SEQUENCE (Chapter 1 specific)
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
connect_prompt: {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
text: "<em>Your terminal awaits a command.</em>",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "<em>The familiar glow illuminates your face.</em>",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: [{ text: "Connect to Dark Tower BBS", next: "modem_connect" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
modem_connect: {
|
||||||
|
clear: true,
|
||||||
|
sounds: [{ id: "modem_connect", url: "/audio/modem-connect.mp3" }],
|
||||||
|
content: [
|
||||||
|
{ type: "typewriter", text: "ATDT 555-0199", speed: 80 },
|
||||||
|
"",
|
||||||
|
{ type: "sound", id: "modem_connect", volume: 0.6 },
|
||||||
|
{ type: "delay", ms: 400 },
|
||||||
|
{ text: "DIALING...", className: "info" },
|
||||||
|
{ type: "delay", ms: 3000 },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "~~ eEe ~~ EEE ~~ eee ~~",
|
||||||
|
speed: 35,
|
||||||
|
italic: true,
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 3000 },
|
||||||
|
"CONNECT 56000",
|
||||||
|
"",
|
||||||
|
{ text: "Carrier detected.", className: "success" },
|
||||||
|
{ type: "delay", ms: 4500 },
|
||||||
|
"Negotiating protocol...",
|
||||||
|
{ type: "delay", ms: 4500 },
|
||||||
|
{ text: "Connection established.", className: "success" },
|
||||||
|
{ type: "delay", ms: 2000 },
|
||||||
|
],
|
||||||
|
next: "dark_tower_main",
|
||||||
|
delay: 1200,
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// MESSAGE DISCOVERY (Chapter 1 specific)
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
read_messages: {
|
||||||
|
content: [
|
||||||
|
...TableHelper.table({
|
||||||
|
title: "Private Messages for 0BSERVER0",
|
||||||
|
headers: ["#", "FROM", "TO", "DATE", "STATUS"],
|
||||||
|
rows: [
|
||||||
|
[
|
||||||
|
"23",
|
||||||
|
"[UNKNOWN]",
|
||||||
|
"0BSERVER0",
|
||||||
|
"24/12",
|
||||||
|
{ text: "NEW", className: "warning" },
|
||||||
|
],
|
||||||
|
["22", "NIGHTWATCHER", "0BSERVER0", "12/12", "READ"],
|
||||||
|
["21", "0BSERVER0", "NIGHTWATCHER", "11/12", "SENT"],
|
||||||
|
["22", "NIGHTWATCHER", "0BSERVER0", "10/12", "READ"],
|
||||||
|
],
|
||||||
|
widths: [4, 12, 12, 8, 8],
|
||||||
|
align: ["right", "left", "left", "left", "left"],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
options: [
|
||||||
|
{ text: "Open unread message", next: "new_message" },
|
||||||
|
{ text: "Back to main menu", next: "dark_tower_main" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
new_message: {
|
||||||
|
content: [
|
||||||
|
{ type: "delay", ms: 300 },
|
||||||
|
"─── BEGIN MESSAGE ───",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "I know you've been searching.",
|
||||||
|
speed: 50,
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "The lighthouse keeper left something behind.",
|
||||||
|
speed: 50,
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "Dial 555-0237 before midnight strikes.",
|
||||||
|
speed: 50,
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
"",
|
||||||
|
{ type: "typewriter", text: "The cascade is coming.", speed: 70 },
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
"",
|
||||||
|
"─── END MESSAGE ───",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
text: "<br /><em>The number burns in your mind: 555-0237</em>",
|
||||||
|
html: true,
|
||||||
|
className: "warning",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 1000 },
|
||||||
|
{
|
||||||
|
text: "<em>Your clock reads 11:54 PM.</em>",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "<em>Six minutes until midnight.</em><br/><br />",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
"",
|
||||||
|
],
|
||||||
|
onEnter: [
|
||||||
|
{ set: "read_new_message", value: true },
|
||||||
|
{ set: "found_number", value: true },
|
||||||
|
{ setShared: "found_number", value: true },
|
||||||
|
],
|
||||||
|
prompt: "What do you do?",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
text: "Dial the number NOW",
|
||||||
|
next: "choice_immediate",
|
||||||
|
actions: [{ setShared: "route_taken", value: "immediate" }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Explore Dark Tower first",
|
||||||
|
next: "dark_tower_main",
|
||||||
|
actions: [{ setShared: "route_taken", value: "cautious" }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Delete the message and forget it",
|
||||||
|
next: "choice_ignored",
|
||||||
|
actions: [{ setShared: "route_taken", value: "ignored" }],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
message_archive: {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "table",
|
||||||
|
title: "Private Messages for 0BSERVER0",
|
||||||
|
headers: ["#", "FROM", "TO", "DATE", "STATUS"],
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
condition: { not: "read_new_message" },
|
||||||
|
cells: ["23", "[UNKNOWN]", "0BSERVER0", "24/12", "NEW"],
|
||||||
|
className: "warning",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: "read_new_message",
|
||||||
|
cells: ["23", "[UNKNOWN]", "0BSERVER0", "24/12", "READ"],
|
||||||
|
},
|
||||||
|
["22", "NIGHTWATCHER", "0BSERVER0", "12/12", "READ"],
|
||||||
|
["21", "0BSERVER0", "NIGHTWATCHER", "11/12", "SENT"],
|
||||||
|
["22", "NIGHTWATCHER", "0BSERVER0", "10/12", "READ"],
|
||||||
|
{
|
||||||
|
condition: { and: ["has_secret", { not: "revealed_secret" }] },
|
||||||
|
cells: ["99", "???", "???", "??/??", "HIDDEN"],
|
||||||
|
className: "error",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
widths: [4, 12, 12, 8, 8],
|
||||||
|
align: ["right", "left", "left", "left", "left"],
|
||||||
|
style: "single",
|
||||||
|
},
|
||||||
|
{ text: "<em>No new messages.</em>", html: true, className: "info" },
|
||||||
|
{
|
||||||
|
condition: "read_new_message",
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
text: "<em>Just the number... 555-0237...</em>",
|
||||||
|
html: true,
|
||||||
|
className: "warning",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
],
|
||||||
|
options: [{ text: "Back", next: "dark_tower_main" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// CHOICE ROUTES (Chapter 1 specific)
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
choice_immediate: {
|
||||||
|
clear: true,
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: "<em>Your fingers move before doubt can settle.</em>",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ type: "typewriter", text: "ATH0", speed: 100 },
|
||||||
|
{ type: "delay", ms: 400 },
|
||||||
|
{ text: "NO CARRIER", className: "warning" },
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
text: "<em>You disconnect from Dark Tower.</em>",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "<em>The silence of your room feels heavier now.</em>",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "Something compels you forward...",
|
||||||
|
italic: true,
|
||||||
|
speed: 100,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 1500 },
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "...555-0237",
|
||||||
|
italic: true,
|
||||||
|
speed: 100,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 2000 },
|
||||||
|
],
|
||||||
|
next: "dial_lighthouse",
|
||||||
|
delay: 1000,
|
||||||
|
},
|
||||||
|
|
||||||
|
choice_ignored: {
|
||||||
|
clear: true,
|
||||||
|
content: [
|
||||||
|
"You highlight the message.",
|
||||||
|
"",
|
||||||
|
{ type: "typewriter", text: "DELETE MESSAGE? [Y/N]", speed: 50 },
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
{ type: "typewriter", text: "Y", speed: 100 },
|
||||||
|
{ type: "delay", ms: 400 },
|
||||||
|
"",
|
||||||
|
{ text: "MESSAGE DELETED", className: "success" },
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 1000 },
|
||||||
|
"The number fades from memory.",
|
||||||
|
"Just another piece of BBS spam, you tell yourself.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 2000 },
|
||||||
|
"You browse Dark Tower for another hour.",
|
||||||
|
"Download some wallpapers.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 2000 },
|
||||||
|
"At 11:57 PM, you disconnect.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 2000 },
|
||||||
|
"Five days later, the millennium arrives.",
|
||||||
|
"Fireworks. Champagne. Relief.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
"Nothing happens.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 2000 },
|
||||||
|
{ text: "Or does it?", className: "warning" },
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 2000 },
|
||||||
|
"You never find out what cascade.exe would have done.",
|
||||||
|
"The lighthouse keeper's message was never meant for you.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 1000 },
|
||||||
|
{ text: "Perhaps that's for the best.", className: "info" },
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 1000 },
|
||||||
|
{ text: "[END - Route C: The Road Not Taken]", className: "warning" },
|
||||||
|
],
|
||||||
|
options: [{ text: "Return to terminal", next: "game_end_ignored" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
game_end_ignored: {
|
||||||
|
clear: true,
|
||||||
|
content: [
|
||||||
|
{ type: "ascii", art: CHAPTER1_END_SCREEN, className: "game-ascii" },
|
||||||
|
"",
|
||||||
|
{ text: "BOXING DAY", className: "game-title" },
|
||||||
|
{ text: "Day 1 Complete - Route C", className: "info" },
|
||||||
|
"",
|
||||||
|
"You chose not to follow the signal.",
|
||||||
|
"Some doors are better left closed.",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
text: 'Type "dial" to play again, or "dial reset" to start fresh.',
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onEnter: [{ markChapterComplete: 1 }],
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// CHAPTER 1 SPECIFIC ENDINGS
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
sleep_ending: {
|
||||||
|
clear: true,
|
||||||
|
content: [
|
||||||
|
"You power down the modem.",
|
||||||
|
"The room falls silent.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
"As you drift off to sleep, you think about the message.",
|
||||||
|
"The cascade. The keeper. The lighthouse.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
"Tomorrow, you tell yourself.",
|
||||||
|
"You'll investigate tomorrow.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 1000 },
|
||||||
|
"But tomorrow, you'll forget.",
|
||||||
|
"The way everyone forgets.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
{
|
||||||
|
condition: { not: "found_number" },
|
||||||
|
content: {
|
||||||
|
text: "[END - Route C: Peaceful Sleep]",
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
else: { text: "[END - Route B: Postponed]", className: "warning" },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: [{ text: "Return to terminal", next: "game_end_sleep" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
game_end_sleep: {
|
||||||
|
clear: true,
|
||||||
|
content: [
|
||||||
|
{ type: "ascii", art: CHAPTER1_END_SCREEN, className: "game-ascii" },
|
||||||
|
"",
|
||||||
|
{ text: "BOXING DAY", className: "game-title" },
|
||||||
|
{ text: "Day 1 Complete", className: "info" },
|
||||||
|
"",
|
||||||
|
"You chose rest over curiosity.",
|
||||||
|
"The lighthouse keeper will have to wait.",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
text: 'Type "dial" to play again, or "dial reset" to start fresh.',
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onEnter: [{ markChapterComplete: 1 }],
|
||||||
|
},
|
||||||
|
|
||||||
|
// Final ending scene (overrides shared scene for chapter-specific summary)
|
||||||
|
carrier_lost: {
|
||||||
|
clear: true,
|
||||||
|
content: [
|
||||||
|
{ type: "delay", ms: 300 },
|
||||||
|
{ type: "typewriter", text: "ATH0", speed: 100 },
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
"",
|
||||||
|
{ text: "NO CARRIER", className: "error" },
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 1200 },
|
||||||
|
"",
|
||||||
|
{ type: "ascii", art: CHAPTER1_END_SCREEN, className: "game-ascii" },
|
||||||
|
"",
|
||||||
|
{ text: "BOXING DAY", className: "game-title" },
|
||||||
|
{ text: "Day 1 Complete", className: "info" },
|
||||||
|
"",
|
||||||
|
{ text: "─── SESSION SUMMARY ───", className: "info" },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
condition: "downloaded_cascade",
|
||||||
|
content: { text: "[X] Downloaded CASCADE.EXE", className: "success" },
|
||||||
|
else: { text: "[ ] Downloaded CASCADE.EXE", className: "info" },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: "talked_to_sysop",
|
||||||
|
content: { text: "[X] Spoke with Keeper", className: "success" },
|
||||||
|
else: { text: "[ ] Spoke with Keeper", className: "info" },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: "deleted_corrupted_file",
|
||||||
|
content: { text: "[X] Accessed SHADOW.DAT", className: "warning" },
|
||||||
|
else: { text: "[ ] Accessed SHADOW.DAT", className: "info" },
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
condition: "archives_deleted",
|
||||||
|
content: {
|
||||||
|
text: "[!] The Archives have been deleted",
|
||||||
|
className: "error",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: "corrupted_file_deleted",
|
||||||
|
content: {
|
||||||
|
text: "[!] SHADOW.DAT has been removed",
|
||||||
|
className: "error",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ text: "Route: ${route_taken}", className: "info" },
|
||||||
|
"",
|
||||||
|
{ text: "To be continued...", className: "warning" },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
text: 'Type "dial" to replay, or "dial reset" to clear progress.',
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onEnter: [
|
||||||
|
{ set: "day_1_complete", value: true },
|
||||||
|
{ markChapterComplete: 1 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register the game when DOM is ready (ensures all scripts including scene factories are loaded)
|
||||||
|
function registerChapter1() {
|
||||||
|
if (window.terminal && window.GameEngine) {
|
||||||
|
const game = new GameEngine(chapter1Game);
|
||||||
|
game.register();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If DOM is already loaded, register immediately, otherwise wait
|
||||||
|
if (document.readyState === "loading") {
|
||||||
|
document.addEventListener("DOMContentLoaded", registerChapter1);
|
||||||
|
} else {
|
||||||
|
registerChapter1();
|
||||||
|
}
|
||||||
328
assets/js/games/games/test-adventure.js
Normal file
328
assets/js/games/games/test-adventure.js
Normal file
|
|
@ -0,0 +1,328 @@
|
||||||
|
// Test Adventure - A simple game to test the game engine
|
||||||
|
const testAdventureGame = {
|
||||||
|
id: "test-adventure",
|
||||||
|
name: "Terminal Quest",
|
||||||
|
command: "quest",
|
||||||
|
description: "A test adventure game",
|
||||||
|
|
||||||
|
initialState: {
|
||||||
|
gold: 0,
|
||||||
|
inventory: [],
|
||||||
|
visited: {},
|
||||||
|
},
|
||||||
|
|
||||||
|
intro: [
|
||||||
|
{
|
||||||
|
type: "ascii",
|
||||||
|
art: `
|
||||||
|
╔════════════════════════════════╗
|
||||||
|
║ TERMINAL QUEST ║
|
||||||
|
║ A Test Adventure ║
|
||||||
|
╚════════════════════════════════╝
|
||||||
|
`,
|
||||||
|
className: "game-ascii",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
"You wake up in a strange digital world...",
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
"The cursor blinks patiently before you.",
|
||||||
|
"",
|
||||||
|
{ text: 'Type "quit" at any time to exit.', className: "info" },
|
||||||
|
],
|
||||||
|
|
||||||
|
startScene: "start",
|
||||||
|
|
||||||
|
scenes: {
|
||||||
|
start: {
|
||||||
|
title: "The Terminal",
|
||||||
|
content: [
|
||||||
|
"You find yourself at a command prompt.",
|
||||||
|
"A green cursor blinks steadily in the darkness.",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
condition: { path: "visited.start" },
|
||||||
|
content: { text: "You've been here before...", className: "info" },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: { path: "gold", greaterThan: 0 },
|
||||||
|
content: "Your gold pouch jingles with ${gold} coins.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onEnter: [{ set: "visited.start", value: true }],
|
||||||
|
options: [
|
||||||
|
{ text: "Look around", next: "look-around" },
|
||||||
|
{ text: "Check inventory", next: "inventory" },
|
||||||
|
{
|
||||||
|
text: "Enter the code cave",
|
||||||
|
condition: { path: "inventory", contains: "flashlight" },
|
||||||
|
next: "code-cave",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Talk to the cursor",
|
||||||
|
condition: { not: { path: "visited.cursor-talk" } },
|
||||||
|
next: "cursor-talk",
|
||||||
|
},
|
||||||
|
{ text: "Test glitch effect", next: "glitch-demo" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
"glitch-demo": {
|
||||||
|
title: "Glitch Effect Demo",
|
||||||
|
content: [
|
||||||
|
"The terminal screen begins to distort...",
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "glitch",
|
||||||
|
text: "REALITY CORRUPTING",
|
||||||
|
intensity: 0.5,
|
||||||
|
spread: 3,
|
||||||
|
duration: 2500,
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
"The corruption spreads across nearby lines...",
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "glitch",
|
||||||
|
text: "ERROR: MEMORY FAULT AT 0x7FFFFFFF",
|
||||||
|
intensity: 0.7,
|
||||||
|
spread: 4,
|
||||||
|
speed: 40,
|
||||||
|
duration: 3000,
|
||||||
|
className: "error glitch-text",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
"A subtle glitch flickers briefly...",
|
||||||
|
{ type: "delay", ms: 400 },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "glitch",
|
||||||
|
text: "Connection unstable",
|
||||||
|
intensity: 0.2,
|
||||||
|
spread: 1,
|
||||||
|
duration: 1500,
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 300 },
|
||||||
|
"The screen stabilizes again.",
|
||||||
|
],
|
||||||
|
options: [{ text: "Back to start", next: "start" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
"look-around": {
|
||||||
|
title: "Searching...",
|
||||||
|
content: ["You search the area carefully...", { type: "delay", ms: 500 }],
|
||||||
|
onEnter: [
|
||||||
|
{
|
||||||
|
callback: (state, adapter) => {
|
||||||
|
// Random chance to find gold
|
||||||
|
if (Math.random() > 0.5) {
|
||||||
|
const found = Math.floor(Math.random() * 10) + 1;
|
||||||
|
state.increment("gold", found);
|
||||||
|
adapter.printSuccess(`You found ${found} gold coins!`);
|
||||||
|
} else {
|
||||||
|
adapter.print("You don't find anything this time.");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
next: "start",
|
||||||
|
delay: 1000,
|
||||||
|
},
|
||||||
|
|
||||||
|
inventory: {
|
||||||
|
title: "Inventory",
|
||||||
|
clear: false,
|
||||||
|
content: [
|
||||||
|
"",
|
||||||
|
"=== Your Inventory ===",
|
||||||
|
{ text: "Gold: ${gold}", className: "warning" },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
condition: { path: "inventory", contains: "flashlight" },
|
||||||
|
content: "- Flashlight (lights up dark places)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: { path: "inventory", contains: "key" },
|
||||||
|
content: "- Mysterious Key",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: {
|
||||||
|
and: [
|
||||||
|
{ not: { path: "inventory", contains: "flashlight" } },
|
||||||
|
{ not: { path: "inventory", contains: "key" } },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
content: { text: "Your inventory is empty.", className: "info" },
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
],
|
||||||
|
options: [{ text: "Back", next: "start" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
"cursor-talk": {
|
||||||
|
title: "The Blinking Cursor",
|
||||||
|
content: [
|
||||||
|
"The cursor seems to acknowledge you.",
|
||||||
|
"",
|
||||||
|
{ type: "typewriter", text: "HELLO, USER.", speed: 80 },
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
{ type: "typewriter", text: "I HAVE BEEN WAITING FOR YOU.", speed: 60 },
|
||||||
|
{ type: "delay", ms: 300 },
|
||||||
|
"",
|
||||||
|
"The cursor offers you something...",
|
||||||
|
],
|
||||||
|
onEnter: [
|
||||||
|
{ set: "visited.cursor-talk", value: true },
|
||||||
|
{ addItem: "flashlight" },
|
||||||
|
{ printSuccess: "You received a flashlight!" },
|
||||||
|
],
|
||||||
|
options: [
|
||||||
|
{ text: "Thank the cursor", next: "cursor-thanks" },
|
||||||
|
{ text: "Ask about the code cave", next: "cursor-cave-info" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
"cursor-thanks": {
|
||||||
|
content: [
|
||||||
|
{ type: "typewriter", text: "YOU ARE WELCOME, USER.", speed: 60 },
|
||||||
|
"",
|
||||||
|
"The cursor resumes its patient blinking.",
|
||||||
|
],
|
||||||
|
next: "start",
|
||||||
|
delay: 1500,
|
||||||
|
},
|
||||||
|
|
||||||
|
"cursor-cave-info": {
|
||||||
|
content: [
|
||||||
|
{ type: "typewriter", text: "THE CAVE HOLDS SECRETS...", speed: 60 },
|
||||||
|
{ type: "delay", ms: 300 },
|
||||||
|
{ type: "typewriter", text: "USE THE LIGHT TO FIND THEM.", speed: 60 },
|
||||||
|
"",
|
||||||
|
"The cursor dims slightly, as if tired from speaking.",
|
||||||
|
],
|
||||||
|
next: "start",
|
||||||
|
delay: 1500,
|
||||||
|
},
|
||||||
|
|
||||||
|
"code-cave": {
|
||||||
|
title: "The Code Cave",
|
||||||
|
content: [
|
||||||
|
"Your flashlight illuminates a cavern of glowing text.",
|
||||||
|
"Ancient code scrolls across the walls.",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "ascii",
|
||||||
|
art: `
|
||||||
|
function mystery() {
|
||||||
|
return ??????;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
condition: { not: { path: "visited.code-cave" } },
|
||||||
|
content: "This is your first time in the code cave.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: { path: "visited.code-cave" },
|
||||||
|
content: "The familiar glow of code surrounds you.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onEnter: [{ set: "visited.code-cave", value: true }],
|
||||||
|
prompt: "What do you do?",
|
||||||
|
options: [
|
||||||
|
{ text: "Examine the code", next: "examine-code" },
|
||||||
|
{
|
||||||
|
text: "Search for treasure",
|
||||||
|
condition: { not: { path: "inventory", contains: "key" } },
|
||||||
|
next: "find-key",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Use the mysterious key",
|
||||||
|
condition: { path: "inventory", contains: "key" },
|
||||||
|
next: "use-key",
|
||||||
|
},
|
||||||
|
{ text: "Return to the terminal", next: "start" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
"examine-code": {
|
||||||
|
content: [
|
||||||
|
"You study the ancient code...",
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
"",
|
||||||
|
"It seems to be a function that returns...",
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
{ text: "...the meaning of everything?", className: "warning" },
|
||||||
|
"",
|
||||||
|
"How curious.",
|
||||||
|
],
|
||||||
|
next: "code-cave",
|
||||||
|
delay: 3000,
|
||||||
|
},
|
||||||
|
|
||||||
|
"find-key": {
|
||||||
|
content: [
|
||||||
|
"You search among the glowing symbols...",
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
"",
|
||||||
|
"Behind a cascade of semicolons, you find something!",
|
||||||
|
],
|
||||||
|
onEnter: [
|
||||||
|
{ addItem: "key" },
|
||||||
|
{ printSuccess: "You found a mysterious key!" },
|
||||||
|
],
|
||||||
|
next: "code-cave",
|
||||||
|
delay: 1000,
|
||||||
|
},
|
||||||
|
|
||||||
|
"use-key": {
|
||||||
|
title: "The Hidden Chamber",
|
||||||
|
content: [
|
||||||
|
"The key fits into a slot hidden in the code.",
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
"",
|
||||||
|
"A hidden chamber opens before you!",
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "ascii",
|
||||||
|
art: `
|
||||||
|
╔═══════════════════════════════╗
|
||||||
|
║ ║
|
||||||
|
║ CONGRATULATIONS! ║
|
||||||
|
║ ║
|
||||||
|
║ You found the secret ║
|
||||||
|
║ of the Terminal Quest! ║
|
||||||
|
║ ║
|
||||||
|
║ The treasure is: ║
|
||||||
|
║ KNOWLEDGE ║
|
||||||
|
║ ║
|
||||||
|
╚═══════════════════════════════╝
|
||||||
|
`,
|
||||||
|
className: "success",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ text: "Thanks for playing this test adventure!", className: "info" },
|
||||||
|
"",
|
||||||
|
'Type "quest" to play again, or "quest reset" to start fresh.',
|
||||||
|
],
|
||||||
|
onEnter: [
|
||||||
|
{ increment: "gold", amount: 100 },
|
||||||
|
{ printSuccess: "You also found 100 gold!" },
|
||||||
|
{ set: "completed", value: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register the game when terminal is available
|
||||||
|
if (window.terminal && window.GameEngine) {
|
||||||
|
const game = new GameEngine(testAdventureGame);
|
||||||
|
game.register();
|
||||||
|
}
|
||||||
33
assets/js/games/scenes/system-shutdown-1999/art/index.js
Normal file
33
assets/js/games/scenes/system-shutdown-1999/art/index.js
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
// Art assets index for System Shutdown: 1999 series
|
||||||
|
// These reference the ANSI art defined in ascii-art.js
|
||||||
|
|
||||||
|
// Art constants are loaded from ascii-art.js and made available globally
|
||||||
|
// This file provides a namespace for the series' art assets
|
||||||
|
|
||||||
|
window.SystemShutdown1999Art = window.SystemShutdown1999Art || {};
|
||||||
|
|
||||||
|
// These will be populated by ascii-art.js when it loads
|
||||||
|
// The art constants are:
|
||||||
|
// - BOXING_DAY_TITLE: Chapter 1 title screen
|
||||||
|
// - DARK_TOWER_HEADER: Dark Tower BBS header
|
||||||
|
// - LIGHTHOUSE_HEADER: The Lighthouse BBS header
|
||||||
|
|
||||||
|
// Helper to get art by name
|
||||||
|
window.SystemShutdown1999Art.get = function (name) {
|
||||||
|
switch (name) {
|
||||||
|
case "BOXING_DAY_TITLE":
|
||||||
|
return window.BOXING_DAY_TITLE;
|
||||||
|
case "DARK_TOWER_HEADER":
|
||||||
|
return window.DARK_TOWER_HEADER;
|
||||||
|
case "LIGHTHOUSE_HEADER":
|
||||||
|
return window.LIGHTHOUSE_HEADER;
|
||||||
|
default:
|
||||||
|
console.warn(`Unknown art asset: ${name}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// List available art assets
|
||||||
|
window.SystemShutdown1999Art.list = function () {
|
||||||
|
return ["BOXING_DAY_TITLE", "DARK_TOWER_HEADER", "LIGHTHOUSE_HEADER"];
|
||||||
|
};
|
||||||
89
assets/js/games/scenes/system-shutdown-1999/config.js
Normal file
89
assets/js/games/scenes/system-shutdown-1999/config.js
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
// Series configuration for System Shutdown: 1999
|
||||||
|
window.SystemShutdown1999Config = {
|
||||||
|
seriesId: "system-shutdown-1999",
|
||||||
|
name: "System Shutdown: 1999",
|
||||||
|
|
||||||
|
// Chapter definitions
|
||||||
|
chapters: [
|
||||||
|
{
|
||||||
|
number: 1,
|
||||||
|
id: "system-shutdown-1999-chapter-1",
|
||||||
|
command: "dial",
|
||||||
|
date: "1999-12-26",
|
||||||
|
title: "Boxing Day",
|
||||||
|
description: "Connect to Dark Tower BBS - December 26, 1999",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 2,
|
||||||
|
id: "system-shutdown-1999-chapter-2",
|
||||||
|
command: "dial2",
|
||||||
|
date: "1999-12-27",
|
||||||
|
title: "Day 2",
|
||||||
|
description: "The day after - December 27, 1999",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 3,
|
||||||
|
id: "system-shutdown-1999-chapter-3",
|
||||||
|
command: "dial3",
|
||||||
|
date: "1999-12-28",
|
||||||
|
title: "Day 3",
|
||||||
|
description: "Three days remain - December 28, 1999",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 4,
|
||||||
|
id: "system-shutdown-1999-chapter-4",
|
||||||
|
command: "dial4",
|
||||||
|
date: "1999-12-29",
|
||||||
|
title: "Day 4",
|
||||||
|
description: "Two days remain - December 29, 1999",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 5,
|
||||||
|
id: "system-shutdown-1999-chapter-5",
|
||||||
|
command: "dial5",
|
||||||
|
date: "1999-12-30",
|
||||||
|
title: "Day 5",
|
||||||
|
description: "The eve - December 30, 1999",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
number: 6,
|
||||||
|
id: "system-shutdown-1999-chapter-6",
|
||||||
|
command: "dial6",
|
||||||
|
date: "1999-12-31",
|
||||||
|
title: "New Year's Eve",
|
||||||
|
description: "The final night - December 31, 1999",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
// Shared state schema with defaults
|
||||||
|
// These values persist across all chapters
|
||||||
|
sharedStateDefaults: {
|
||||||
|
// Completion tracking
|
||||||
|
chapters_completed: [],
|
||||||
|
|
||||||
|
// Core cross-chapter decisions
|
||||||
|
downloaded_cascade: false,
|
||||||
|
talked_to_sysop: false,
|
||||||
|
deleted_corrupted_file: false,
|
||||||
|
route_taken: null, // "immediate" | "cautious" | "ignored"
|
||||||
|
|
||||||
|
// World state changes (persist across chapters)
|
||||||
|
archives_deleted: false,
|
||||||
|
corrupted_file_deleted: false,
|
||||||
|
|
||||||
|
// Discovery flags
|
||||||
|
found_number: false,
|
||||||
|
dialed_lighthouse: false,
|
||||||
|
seen_archive_glitch: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
// Helper to get chapter by number
|
||||||
|
getChapter(number) {
|
||||||
|
return this.chapters.find((c) => c.number === number);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Helper to get next chapter
|
||||||
|
getNextChapter(currentNumber) {
|
||||||
|
return this.chapters.find((c) => c.number === currentNumber + 1);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,574 @@
|
||||||
|
// Dark Tower BBS Hub - Shared scenes for System Shutdown: 1999
|
||||||
|
// These scenes can be used across multiple chapters
|
||||||
|
|
||||||
|
window.SceneFactories = window.SceneFactories || {};
|
||||||
|
|
||||||
|
window.SceneFactories["system-shutdown-1999/dark-tower-hub"] = function (
|
||||||
|
context,
|
||||||
|
) {
|
||||||
|
const { chapterNumber, art, additionalOptions = [] } = context;
|
||||||
|
|
||||||
|
// Get art from bundle scope (loaded by ascii-art.js in same bundle)
|
||||||
|
// Falls back to context.art if not found (for standalone loading)
|
||||||
|
const DARK_TOWER_HEADER_ART =
|
||||||
|
typeof DARK_TOWER_HEADER !== "undefined"
|
||||||
|
? DARK_TOWER_HEADER
|
||||||
|
: art.DARK_TOWER_HEADER;
|
||||||
|
|
||||||
|
return {
|
||||||
|
// ==========================================
|
||||||
|
// DARK TOWER BBS HUB
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
dark_tower_main: {
|
||||||
|
clear: true,
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "ansi",
|
||||||
|
art: DARK_TOWER_HEADER_ART,
|
||||||
|
className: "game-ansi-art center",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
text: "---=[ D A R K T O W E R B B S - E S T. 1 9 9 5 ]=---",
|
||||||
|
className: "info center",
|
||||||
|
},
|
||||||
|
// User count can change based on chapter/state
|
||||||
|
{
|
||||||
|
condition: { path: "chapters_completed", contains: 1 },
|
||||||
|
content: {
|
||||||
|
text: "[ Users Connected - 2 ] - [ SysOp - NightWatchman ]",
|
||||||
|
className: "info center",
|
||||||
|
},
|
||||||
|
else: {
|
||||||
|
text: "[ Users Connected - 3 ] - [ SysOp - NightWatchman ]",
|
||||||
|
className: "info center",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ text: "[ Local Time: 10:52 PM ]", className: "info center" },
|
||||||
|
"",
|
||||||
|
// New message notification if not read
|
||||||
|
{
|
||||||
|
condition: { not: "read_new_message" },
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
text: "*** YOU HAVE 1 NEW PRIVATE MESSAGE ***",
|
||||||
|
className: "warning center",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Show warning if archives were deleted (cascade effect)
|
||||||
|
{
|
||||||
|
condition: "archives_deleted",
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
text: "[!] Some system data appears to be missing...",
|
||||||
|
className: "error center",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onAfterRender: [{ set: "visited.dark_tower_main", value: true }],
|
||||||
|
prompt: "Select:",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
text: "Read Private Messages",
|
||||||
|
next: "read_messages",
|
||||||
|
condition: { not: "read_new_message" },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Message Archive",
|
||||||
|
next: "message_archive",
|
||||||
|
condition: "read_new_message",
|
||||||
|
},
|
||||||
|
{ text: "Browse Message Boards", next: "browse_boards" },
|
||||||
|
{ text: "File Library", next: "dark_tower_files" },
|
||||||
|
{ text: "Who's Online", next: "whos_online" },
|
||||||
|
{
|
||||||
|
text: "Dial The Lighthouse (555-0237)",
|
||||||
|
next: "confirm_dial_lighthouse",
|
||||||
|
condition: "found_number",
|
||||||
|
},
|
||||||
|
// Additional options can be passed by chapters
|
||||||
|
...additionalOptions,
|
||||||
|
{ text: "Disconnect", next: "leave_early" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// MESSAGE BOARDS
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
browse_boards: {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "table",
|
||||||
|
title: "DARK TOWER / MESSAGE BOARDS",
|
||||||
|
headers: ["#", "NAME", "NEW MSG", "LAST"],
|
||||||
|
rows: [
|
||||||
|
["1", "General Discussion", "8", "24/12"],
|
||||||
|
["2", "Tech Support", "1", "25/12"],
|
||||||
|
["3", "File Updates", "3", "23/12"],
|
||||||
|
// Display the archives or have them deleted
|
||||||
|
{
|
||||||
|
condition: { not: "archives_deleted" },
|
||||||
|
cells: ["4", "ARCHIVED", "-", "-"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: "archives_deleted",
|
||||||
|
cells: ["4", "<BOARD REMOVED>", "-", "-"],
|
||||||
|
className: "error",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
widths: [4, 20, 10, 8],
|
||||||
|
align: ["right", "left", "left", "left"],
|
||||||
|
style: "single",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: "archives_deleted",
|
||||||
|
content: {
|
||||||
|
type: "typewriter",
|
||||||
|
italic: true,
|
||||||
|
text: "The archived messages are just... gone...",
|
||||||
|
speed: 80,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
prompt: "Select board:",
|
||||||
|
options: [
|
||||||
|
{ text: "General Discussion", next: "board_general" },
|
||||||
|
{ text: "Tech Support", next: "board_tech" },
|
||||||
|
{ text: "File Updates", next: "board_files" },
|
||||||
|
{
|
||||||
|
text: "ARCHIVED",
|
||||||
|
next: "board_archives",
|
||||||
|
condition: { not: "archives_deleted" },
|
||||||
|
},
|
||||||
|
{ text: "Back to main menu", next: "dark_tower_main" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
board_general: {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "table",
|
||||||
|
title: "GENERAL DISCUSSION",
|
||||||
|
headers: ["#", "SUBJECT", "MSG", "LAST"],
|
||||||
|
rows: [
|
||||||
|
["1", "2K Preparation Thread", "243", "25/12"],
|
||||||
|
["2", "Anyone else getting weird messages?", "3", "25/12"],
|
||||||
|
["3", "Happy Boxing Day everyone!", "5", "25/12"],
|
||||||
|
["4", "Best BBS games?", "43", "23/12"],
|
||||||
|
["5", "New user intro thread", "67", "20/12"],
|
||||||
|
],
|
||||||
|
widths: [4, 40, 6, 8],
|
||||||
|
align: ["right", "left", "right", "left"],
|
||||||
|
style: "single",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "The usual chatter.",
|
||||||
|
italic: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: "found_number",
|
||||||
|
content: {
|
||||||
|
type: "text",
|
||||||
|
italic: true,
|
||||||
|
text: "Nothing about lighthouses...",
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: [
|
||||||
|
{ text: "Read 'weird messages' thread", next: "thread_weird" },
|
||||||
|
{ text: "Back to boards", next: "browse_boards" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
thread_weird: {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "table",
|
||||||
|
title: "Anyone else getting weird messages?",
|
||||||
|
headers: ["FROM", "TO", "DATE"],
|
||||||
|
rows: [["Static_User", "All", "25/12/99"]],
|
||||||
|
widths: [20, 20, 10],
|
||||||
|
align: ["left", "left", "left"],
|
||||||
|
style: "single",
|
||||||
|
},
|
||||||
|
" Got a strange PM last night. No sender listed.",
|
||||||
|
" Just a phone number and something about a 'cascade'.",
|
||||||
|
" Probably spam, but creepy timing with Y2K coming up.",
|
||||||
|
"",
|
||||||
|
"---",
|
||||||
|
{ text: "Reply from: NightWatchman [SYSOP]", className: "warning" },
|
||||||
|
" Looking into it. Please forward any suspicious messages.",
|
||||||
|
" And don't dial any numbers you don't recognize.",
|
||||||
|
"",
|
||||||
|
"---",
|
||||||
|
{ text: "Reply from: [DELETED USER]", className: "error" },
|
||||||
|
" [This post cannot be accessed]",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 1000 },
|
||||||
|
{
|
||||||
|
condition: "found_number",
|
||||||
|
content: {
|
||||||
|
text: "<br /><br /><em>You notice your message was similar...</em>",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: [{ text: "Back", next: "board_general" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
board_tech: {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "table",
|
||||||
|
title: "TECH SUPPORT",
|
||||||
|
headers: ["#", "SUBJECT", "MSG", "LAST"],
|
||||||
|
rows: [
|
||||||
|
["1", "READ FIRST: Y2K Compliance Guide", "152", "25/12"],
|
||||||
|
["2", "Modem dropping connection at midnight?", "3", "25/12"],
|
||||||
|
["3", "How to increase download speeds", "98", "25/12"],
|
||||||
|
["4", "We are migrating to TELNET/IP on 01/04/00", "429", "11/12"],
|
||||||
|
["5", "Inputs not registering", "2", "29/11"],
|
||||||
|
],
|
||||||
|
widths: [4, 45, 6, 8],
|
||||||
|
align: ["right", "left", "right", "left"],
|
||||||
|
style: "single",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Standard tech questions. Nothing unusual.",
|
||||||
|
italic: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: [{ text: "Back to boards", next: "browse_boards" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
board_archives: {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "table",
|
||||||
|
title: "THE ARCHIVES",
|
||||||
|
headers: ["#", "SUBJECT", "OP", "LAST"],
|
||||||
|
rows: [
|
||||||
|
["1", "The Lighthouse Project", "NightWatchman", "1998"],
|
||||||
|
["2", "Frequencies and Patterns", "Signal_Lost", "1999"],
|
||||||
|
["3", "RE: Has anyone heard from Keeper?", "[UNKNOWN]", "1999"],
|
||||||
|
],
|
||||||
|
widths: [4, 35, 16, 8],
|
||||||
|
align: ["right", "left", "right", "left"],
|
||||||
|
style: "single",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Historical posts, read only...",
|
||||||
|
italic: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: { not: "visited.archive_warning" },
|
||||||
|
content: [
|
||||||
|
"",
|
||||||
|
{ text: "These posts feel... different.", className: "warning" },
|
||||||
|
{ text: "Like echoes from somewhere else.", className: "info" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onEnter: [{ set: "visited.archive_warning", value: true }],
|
||||||
|
options: [
|
||||||
|
{ text: "Read 'The Lighthouse Project'", next: "archive_lighthouse" },
|
||||||
|
{
|
||||||
|
text: "Read 'Frequencies and Patterns'",
|
||||||
|
next: "archive_frequencies",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "Read 'Has anyone heard from Keeper?'",
|
||||||
|
next: "archive_keeper",
|
||||||
|
},
|
||||||
|
{ text: "Back to boards", next: "browse_boards" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
archive_lighthouse: {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "table",
|
||||||
|
title: "The Lighthouse Project",
|
||||||
|
headers: ["FROM", "TO", "DATE"],
|
||||||
|
rows: [["NightWatchman [SYSOP]", "All", "15/11/98"]],
|
||||||
|
widths: [25, 15, 10],
|
||||||
|
align: ["left", "left", "left"],
|
||||||
|
style: "single",
|
||||||
|
},
|
||||||
|
"Some of you have asked about the secondary BBS.",
|
||||||
|
"Yes, it exists. No, I can't give you the number.",
|
||||||
|
"",
|
||||||
|
"The Lighthouse was set up by someone who called himself 'Keeper'.",
|
||||||
|
"He said he found something in the noise between stations.",
|
||||||
|
"Patterns that shouldn't exist.",
|
||||||
|
"",
|
||||||
|
"I set up his board as a favor.",
|
||||||
|
"Then one day, he stopped logging in.",
|
||||||
|
"",
|
||||||
|
"The board is still there. Still running.",
|
||||||
|
"I check it sometimes. The files he left behind...",
|
||||||
|
"",
|
||||||
|
"Some doors are better left closed.",
|
||||||
|
{ text: "- NW", className: "info" },
|
||||||
|
],
|
||||||
|
options: [{ text: "Back", next: "board_archives" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
archive_frequencies: {
|
||||||
|
title: "Frequencies and Patterns",
|
||||||
|
content: [
|
||||||
|
"═══ Frequencies and Patterns ═══",
|
||||||
|
{ text: "Posted by: Signal_Lost - March 22, 1999", className: "info" },
|
||||||
|
"",
|
||||||
|
"I've been analyzing radio static for three months.",
|
||||||
|
"There's something there. In the spaces between signals.",
|
||||||
|
"",
|
||||||
|
"It's not random. It's STRUCTURED.",
|
||||||
|
"Like code. Like a message.",
|
||||||
|
"",
|
||||||
|
"Keeper knew. That's why he built cascade.exe.",
|
||||||
|
"To translate. To REVEAL.",
|
||||||
|
"",
|
||||||
|
"I'm close to understanding.",
|
||||||
|
"So close.",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
text: "[User Signal_Lost has not logged in since March 23, 1999]",
|
||||||
|
className: "warning",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: [{ text: "Back", next: "board_archives" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
archive_keeper: {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "table",
|
||||||
|
title: "RE: Has anyone heard from Keeper?",
|
||||||
|
headers: ["FROM", "TO", "DATE"],
|
||||||
|
rows: [["[UNKNOWN]", "All", "20/12/99"]],
|
||||||
|
widths: [25, 15, 10],
|
||||||
|
align: ["left", "left", "left"],
|
||||||
|
style: "single",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
"He's still there.",
|
||||||
|
"In The Lighthouse.",
|
||||||
|
"Waiting.",
|
||||||
|
"",
|
||||||
|
"The cascade is ready.",
|
||||||
|
"It just needs carriers.",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "glitch",
|
||||||
|
text: "ERROR: MEMORY FAULT AT 0x555f0237",
|
||||||
|
intensity: 0.7,
|
||||||
|
spread: 0,
|
||||||
|
speed: 200,
|
||||||
|
duration: 2000,
|
||||||
|
className: "error glitch-text",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
"Before midnight on the 31st.",
|
||||||
|
"The alignment only happens once.",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
text: "[This post was flagged for removal but persists]",
|
||||||
|
className: "error",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
html: true,
|
||||||
|
text: "<br /><br />",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: { not: "seen_archive_glitch" },
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
text: "What the hell was that...",
|
||||||
|
italic: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
else: [
|
||||||
|
{
|
||||||
|
text: "The glitch persists...",
|
||||||
|
italic: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: "found_number",
|
||||||
|
content: {
|
||||||
|
text: "The memory location looks oddly like the phone number... 555-0237",
|
||||||
|
italic: true,
|
||||||
|
className: "warning",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onAfterRender: [{ set: "seen_archive_glitch", value: true }],
|
||||||
|
options: [{ text: "Back", next: "board_archives" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
board_files: {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "table",
|
||||||
|
title: "FILE ANNOUNCEMENTS",
|
||||||
|
headers: ["#", "SUBJECT", "MSG", "LAST"],
|
||||||
|
rows: [
|
||||||
|
["1", "1001FONTS.ZIP - Font Collection", "1", "25/12"],
|
||||||
|
["2", "Y2K_FIX.ZIP - Y2K compliance patches", "4", "23/12"],
|
||||||
|
["3", "DOOM_WAD.ZIP - New Doom Levels", "3", "11/12"],
|
||||||
|
["4", "BRUCE.JPEG - Just my dog :-)", "15", "20/11"],
|
||||||
|
["5", "CATS.GIF - All your base are belong to us", "1", "01/11"],
|
||||||
|
],
|
||||||
|
widths: [4, 45, 6, 8],
|
||||||
|
align: ["right", "left", "right", "left"],
|
||||||
|
style: "single",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "<em>New fonts... At last...</em>",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "<em>Can't get distracted just yet.</em>",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: [{ text: "Back to boards", next: "browse_boards" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
dark_tower_files: {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "table",
|
||||||
|
title: "FILE LIBRARY",
|
||||||
|
headers: ["#", "DIR", "QTY", "UPDATED"],
|
||||||
|
rows: [
|
||||||
|
["1", "/IMAGES", "234", "25/12"],
|
||||||
|
["2", "/GAMES", "67", "12/12"],
|
||||||
|
["3", "/MUSIC", "89", "30/11"],
|
||||||
|
["4", "/UTILS", "156", "23/11"],
|
||||||
|
["5", "/MISC", "13", "09/10"],
|
||||||
|
],
|
||||||
|
widths: [4, 25, 6, 8],
|
||||||
|
align: ["right", "left", "right", "left"],
|
||||||
|
style: "single",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "<em>Standard BBS fare. Nothing unusual.</em>",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: [{ text: "Back to main menu", next: "dark_tower_main" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
whos_online: {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "table",
|
||||||
|
title: "CONNECTED USERS",
|
||||||
|
headers: ["#", "USER", "LOC", "UPDATED"],
|
||||||
|
rows: [
|
||||||
|
["1", "0BSERVER0", "Main Menu", "10:54 PM"],
|
||||||
|
// Static_User might not be online in later chapters
|
||||||
|
{
|
||||||
|
condition: { not: { path: "chapters_completed", contains: 1 } },
|
||||||
|
cells: ["2", "Static_User", "Message Boards", "10:39 PM"],
|
||||||
|
},
|
||||||
|
["3", "NightWatchman", "SysOp Console", "10:12 PM"],
|
||||||
|
],
|
||||||
|
widths: [4, 15, 15, 8],
|
||||||
|
align: ["right", "left", "right", "left"],
|
||||||
|
style: "single",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: [{ text: "Back", next: "dark_tower_main" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
leave_early: {
|
||||||
|
content: [
|
||||||
|
"Are you sure you want to disconnect?",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
condition: "found_number",
|
||||||
|
content: {
|
||||||
|
text: "You still have the number: 555-0237",
|
||||||
|
className: "warning",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
text: "Dial The Lighthouse first",
|
||||||
|
next: "confirm_dial_lighthouse",
|
||||||
|
condition: "found_number",
|
||||||
|
},
|
||||||
|
{ text: "Yes, disconnect", next: "disconnect_early" },
|
||||||
|
{ text: "Stay connected", next: "dark_tower_main" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
disconnect_early: {
|
||||||
|
clear: true,
|
||||||
|
content: [
|
||||||
|
{ type: "typewriter", text: "ATH0", speed: 100 },
|
||||||
|
{ type: "delay", ms: 400 },
|
||||||
|
{ text: "NO CARRIER", className: "warning" },
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
"You disconnect from Dark Tower.",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
condition: "found_number",
|
||||||
|
content: [
|
||||||
|
"The number lingers in your mind.",
|
||||||
|
{ text: "555-0237", className: "warning" },
|
||||||
|
"",
|
||||||
|
"You could always dial it directly...",
|
||||||
|
],
|
||||||
|
else: ["Another quiet night online.", "Nothing unusual."],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
text: "Dial 555-0237",
|
||||||
|
next: "dial_lighthouse",
|
||||||
|
condition: "found_number",
|
||||||
|
},
|
||||||
|
{ text: "Go to sleep", next: "sleep_ending" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
confirm_dial_lighthouse: {
|
||||||
|
content: [
|
||||||
|
{ text: "555-0237", className: "warning" },
|
||||||
|
"",
|
||||||
|
"The number from the message.",
|
||||||
|
"Something waits on the other end.",
|
||||||
|
"",
|
||||||
|
{ text: "Your clock reads 11:56 PM.", className: "info" },
|
||||||
|
],
|
||||||
|
options: [
|
||||||
|
{ text: "Dial The Lighthouse", next: "dial_lighthouse" },
|
||||||
|
{ text: "Not yet", next: "dark_tower_main" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,625 @@
|
||||||
|
// The Lighthouse BBS Hub - Shared scenes for System Shutdown: 1999
|
||||||
|
// These scenes can be used across multiple chapters
|
||||||
|
|
||||||
|
window.SceneFactories = window.SceneFactories || {};
|
||||||
|
|
||||||
|
window.SceneFactories["system-shutdown-1999/lighthouse-hub"] = function (
|
||||||
|
context,
|
||||||
|
) {
|
||||||
|
const { chapterNumber, art, additionalOptions = [] } = context;
|
||||||
|
|
||||||
|
// Get art from bundle scope (loaded by ascii-art.js in same bundle)
|
||||||
|
// Falls back to context.art if not found (for standalone loading)
|
||||||
|
const LIGHTHOUSE_HEADER_ART =
|
||||||
|
typeof LIGHTHOUSE_HEADER !== "undefined"
|
||||||
|
? LIGHTHOUSE_HEADER
|
||||||
|
: art.LIGHTHOUSE_HEADER;
|
||||||
|
|
||||||
|
return {
|
||||||
|
// ==========================================
|
||||||
|
// THE LIGHTHOUSE
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
dial_lighthouse: {
|
||||||
|
clear: true,
|
||||||
|
content: [
|
||||||
|
{ type: "typewriter", text: "ATDT 555-0237", speed: 80 },
|
||||||
|
{ type: "delay", ms: 1000 },
|
||||||
|
"",
|
||||||
|
{ text: "DIALING...", className: "info" },
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
"",
|
||||||
|
{ text: "RING", className: "warning" },
|
||||||
|
{ type: "delay", ms: 1200 },
|
||||||
|
{ text: "RING", className: "warning" },
|
||||||
|
{ type: "delay", ms: 1200 },
|
||||||
|
{ text: "RING", className: "warning" },
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "~~ crackle ~~ hiss ~~ CONNECT 14400",
|
||||||
|
speed: 40,
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
"",
|
||||||
|
{ text: "Connection unstable.", className: "warning" },
|
||||||
|
{ text: "Signal degraded.", className: "warning" },
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
"",
|
||||||
|
{ type: "typewriter", text: "Welcome to THE LIGHTHOUSE", speed: 40 },
|
||||||
|
{ type: "delay", ms: 300 },
|
||||||
|
{ type: "typewriter", text: "A beacon in the static.", speed: 40 },
|
||||||
|
],
|
||||||
|
onEnter: [{ setShared: "dialed_lighthouse", value: true }],
|
||||||
|
next: "lighthouse_main",
|
||||||
|
delay: 1000,
|
||||||
|
},
|
||||||
|
|
||||||
|
lighthouse_main: {
|
||||||
|
clear: true,
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "ascii",
|
||||||
|
art: LIGHTHOUSE_HEADER_ART,
|
||||||
|
className: "game-ascii",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ text: "T H E L I G H T H O U S E", className: "center" },
|
||||||
|
{ text: "Last updated: 24/12/1999 23:59:59", className: "center" },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
condition: { not: "visited.lighthouse_main" },
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
text: "Something feels wrong here.",
|
||||||
|
italic: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "The BBS feels... frozen. Abandoned.",
|
||||||
|
italic: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: "downloaded_cascade",
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
text: "The signal flickers. Something has changed.",
|
||||||
|
className: "error",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onAfterRender: [{ set: "visited.lighthouse_main", value: true }],
|
||||||
|
prompt: "Navigate:",
|
||||||
|
options: [
|
||||||
|
{ text: "The Keeper's Log", next: "lighthouse_log" },
|
||||||
|
{ text: "Transmissions", next: "lighthouse_transmissions" },
|
||||||
|
{ text: "File Vault", next: "lighthouse_files" },
|
||||||
|
{
|
||||||
|
text: "Request SysOp Chat",
|
||||||
|
next: "chat_request",
|
||||||
|
condition: {
|
||||||
|
and: [{ not: "downloaded_cascade" }, { not: "talked_to_sysop" }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// Additional options can be passed by chapters
|
||||||
|
...additionalOptions,
|
||||||
|
{ text: "Disconnect", next: "disconnect_choice" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
lighthouse_log: {
|
||||||
|
content: [
|
||||||
|
"═══ THE KEEPER'S LOG ═══",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
text: "Entry 1 - November 3, 1998<br /><br />",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
" I've found something. In the static between radio stations.",
|
||||||
|
" Patterns. Structures. A language, maybe.",
|
||||||
|
{
|
||||||
|
text: "<br />Entry 7 - December 12, 1998<br /><br />",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
" The patterns are getting clearer. They want to be understood.",
|
||||||
|
" They want to SPREAD.",
|
||||||
|
{
|
||||||
|
text: "<br />Entry 15 - March 19, 1999<br /><br />",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
" CASCADE.EXE is complete. A translator. A carrier. A key.",
|
||||||
|
" When run at the right moment, it will open the door.",
|
||||||
|
{
|
||||||
|
text: "<br />Entry 23 - December 24, 1999<br /><br />",
|
||||||
|
html: true,
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
" The alignment approaches.",
|
||||||
|
" Seven days until the millennium.",
|
||||||
|
" I can hear them now. Always.",
|
||||||
|
"",
|
||||||
|
{ type: "typewriter", text: " They are beautiful...", speed: 100 },
|
||||||
|
{ type: "delay", ms: 2000 },
|
||||||
|
],
|
||||||
|
options: [{ text: "Back", next: "lighthouse_main" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
lighthouse_transmissions: {
|
||||||
|
title: "Transmissions",
|
||||||
|
content: [
|
||||||
|
"═══ RECORDED TRANSMISSIONS ═══",
|
||||||
|
"",
|
||||||
|
{ text: "[AUDIO FILES - PLAYBACK UNAVAILABLE]", className: "error" },
|
||||||
|
"",
|
||||||
|
"Transcript excerpts:",
|
||||||
|
"",
|
||||||
|
" TRANS_001.WAV:",
|
||||||
|
' "...signal detected at 1420 MHz..."',
|
||||||
|
"",
|
||||||
|
" TRANS_014.WAV:",
|
||||||
|
' "...pattern repeats every 23 seconds..."',
|
||||||
|
"",
|
||||||
|
" TRANS_047.WAV:",
|
||||||
|
' "...not random... structured... alive?..."',
|
||||||
|
"",
|
||||||
|
" TRANS_099.WAV:",
|
||||||
|
{ text: ' "[TRANSCRIPT CORRUPTED]"', className: "error" },
|
||||||
|
"",
|
||||||
|
{ text: "The audio files existed once.", className: "info" },
|
||||||
|
{ text: "Now only fragments remain.", className: "warning" },
|
||||||
|
],
|
||||||
|
options: [{ text: "Back", next: "lighthouse_main" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
lighthouse_files: {
|
||||||
|
title: "File Vault",
|
||||||
|
content: [
|
||||||
|
"═══ FILE VAULT v2.1 ═══",
|
||||||
|
{ text: '"The keeper\'s collection"', className: "info" },
|
||||||
|
"",
|
||||||
|
{ text: "Available files:", className: "info" },
|
||||||
|
"",
|
||||||
|
" [1] README.TXT 1.2 KB 12/24/1999",
|
||||||
|
" [2] CASCADE.EXE 47.0 KB 12/25/1999",
|
||||||
|
// Corrupted file - conditionally shown
|
||||||
|
{
|
||||||
|
condition: { not: "corrupted_file_deleted" },
|
||||||
|
content: " [3] SHADOW.DAT ??? KB ??/??/????",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
condition: "corrupted_file_deleted",
|
||||||
|
content: { text: " [3] <FILE REMOVED>", className: "error" },
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
condition: { not: "visited.lighthouse_files" },
|
||||||
|
content: {
|
||||||
|
text: "CASCADE.EXE pulses faintly on your screen.",
|
||||||
|
className: "warning",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
onEnter: [{ set: "visited.lighthouse_files", value: true }],
|
||||||
|
prompt: "Select file:",
|
||||||
|
options: [
|
||||||
|
{ text: "View README.TXT", next: "file_readme" },
|
||||||
|
{ text: "Download CASCADE.EXE", next: "download_confirm" },
|
||||||
|
{
|
||||||
|
text: "Access SHADOW.DAT",
|
||||||
|
next: "choice_corrupted",
|
||||||
|
condition: { not: "corrupted_file_deleted" },
|
||||||
|
},
|
||||||
|
{ text: "Back", next: "lighthouse_main" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
file_readme: {
|
||||||
|
title: "README.TXT",
|
||||||
|
content: [
|
||||||
|
"═══ README.TXT ═══",
|
||||||
|
"",
|
||||||
|
"To whoever finds this:",
|
||||||
|
"",
|
||||||
|
"I built cascade.exe to show them.",
|
||||||
|
"To show everyone what I found in the frequencies.",
|
||||||
|
"",
|
||||||
|
"It spreads. It copies. It REVEALS.",
|
||||||
|
"",
|
||||||
|
"Don't be afraid when the old files disappear.",
|
||||||
|
"They were never real anyway.",
|
||||||
|
"",
|
||||||
|
"Run it before midnight on 01/01/2000.",
|
||||||
|
"The alignment only happens once.",
|
||||||
|
"",
|
||||||
|
{ text: " - K", className: "info" },
|
||||||
|
"",
|
||||||
|
{ text: "P.S. Don't try to open SHADOW.DAT.", className: "warning" },
|
||||||
|
{
|
||||||
|
text: " Some doors shouldn't be opened twice.",
|
||||||
|
className: "warning",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: [{ text: "Back to files", next: "lighthouse_files" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
download_confirm: {
|
||||||
|
content: [
|
||||||
|
{ text: "CASCADE.EXE - 47,104 bytes", className: "warning" },
|
||||||
|
"",
|
||||||
|
"The file waits.",
|
||||||
|
"47 kilobytes of unknown code.",
|
||||||
|
"",
|
||||||
|
"The README said it 'reveals' something.",
|
||||||
|
"That old files will 'disappear'.",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
text: "In five days, everyone worries about Y2K bugs.",
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
{ text: "This feels different.", className: "warning" },
|
||||||
|
],
|
||||||
|
prompt: "Download CASCADE.EXE?",
|
||||||
|
options: [
|
||||||
|
{ text: "Yes, download it", next: "choice_download" },
|
||||||
|
{ text: "No, leave it alone", next: "choice_no_download" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
choice_download: {
|
||||||
|
title: "Downloading...",
|
||||||
|
clear: true,
|
||||||
|
content: [
|
||||||
|
{ type: "typewriter", text: "XMODEM TRANSFER INITIATED", speed: 45 },
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
"",
|
||||||
|
{ text: "Receiving: CASCADE.EXE", className: "info" },
|
||||||
|
{ type: "delay", ms: 400 },
|
||||||
|
"",
|
||||||
|
{ type: "typewriter", text: "[", speed: 20 },
|
||||||
|
{ type: "typewriter", text: "████████████████████", speed: 80 },
|
||||||
|
{ type: "typewriter", text: "] 100%", speed: 20 },
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
"",
|
||||||
|
{ text: "TRANSFER COMPLETE", className: "success" },
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
"",
|
||||||
|
"The file sits in your download folder.",
|
||||||
|
"47,104 bytes of... something.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 1000 },
|
||||||
|
{
|
||||||
|
text: "Somewhere, distantly, you hear static.",
|
||||||
|
className: "warning",
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: 'A whisper in the noise: "Thank you."',
|
||||||
|
speed: 50,
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 1200 },
|
||||||
|
{ text: "Something has changed.", className: "error" },
|
||||||
|
],
|
||||||
|
onEnter: [
|
||||||
|
{ setShared: "downloaded_cascade", value: true },
|
||||||
|
{ setShared: "archives_deleted", value: true }, // Archives are removed
|
||||||
|
],
|
||||||
|
next: "post_download",
|
||||||
|
delay: 1500,
|
||||||
|
},
|
||||||
|
|
||||||
|
post_download: {
|
||||||
|
clear: true,
|
||||||
|
content: [
|
||||||
|
{ text: "CONNECTION INTERRUPTED", className: "error" },
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
"",
|
||||||
|
"For a moment, your screen fills with symbols.",
|
||||||
|
"Patterns that almost make sense.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
"Then, clarity.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
"You remember Dark Tower's board list.",
|
||||||
|
{ text: "Board #3 - The Archives.", className: "info" },
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
{ text: "It's gone.", className: "warning" },
|
||||||
|
{ text: "Like it was never there.", className: "warning" },
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
{ text: "The cascade has begun.", className: "error" },
|
||||||
|
],
|
||||||
|
next: "closing_message",
|
||||||
|
delay: 2000,
|
||||||
|
},
|
||||||
|
|
||||||
|
choice_no_download: {
|
||||||
|
content: [
|
||||||
|
"Something holds you back.",
|
||||||
|
"47 kilobytes of unknown code.",
|
||||||
|
"From a stranger who hears things in static.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
{ text: "You leave CASCADE.EXE untouched.", className: "info" },
|
||||||
|
"",
|
||||||
|
"The keeper's work remains on the server.",
|
||||||
|
"Waiting for someone else. Or no one.",
|
||||||
|
],
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
text: "Chat with the SysOp",
|
||||||
|
next: "chat_request",
|
||||||
|
condition: { not: "talked_to_sysop" },
|
||||||
|
},
|
||||||
|
{ text: "Return to file list", next: "lighthouse_files" },
|
||||||
|
{ text: "Disconnect", next: "disconnect_choice" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
choice_corrupted: {
|
||||||
|
title: "Accessing SHADOW.DAT...",
|
||||||
|
clear: true,
|
||||||
|
content: [
|
||||||
|
{ type: "typewriter", text: "ATTEMPTING TO READ FILE...", speed: 50 },
|
||||||
|
{ type: "delay", ms: 1000 },
|
||||||
|
"",
|
||||||
|
{ text: "ERROR: FILE HEADER CORRUPTED", className: "error" },
|
||||||
|
{ type: "delay", ms: 400 },
|
||||||
|
{ text: "ERROR: UNEXPECTED EOF", className: "error" },
|
||||||
|
{ type: "delay", ms: 400 },
|
||||||
|
{ text: "ERROR: ????????????????????", className: "error" },
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "ascii",
|
||||||
|
art: `
|
||||||
|
▓▓▓▒▒░░ E̸̢R̷̨R̵̢O̸̧R̷̨ ░░▒▒▓▓▓
|
||||||
|
░▒▓█ D̶̨A̷̧T̸̢Ą̵ C̷̢Ǫ̸Ŗ̵R̷̨U̸̢P̵̧T̷̨ █▓▒░
|
||||||
|
▓░▒█ ???????????????? █▒░▓
|
||||||
|
`,
|
||||||
|
className: "error",
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 1000 },
|
||||||
|
"",
|
||||||
|
"Your screen flickers violently.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
{ text: "A sound from your speakers.", className: "warning" },
|
||||||
|
{
|
||||||
|
text: "A voice, maybe. Or static shaped like words:",
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ type: "typewriter", text: '"Not yet. Not yet. Not yet."', speed: 90 },
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 1200 },
|
||||||
|
{
|
||||||
|
text: "SHADOW.DAT has been removed from the file listing.",
|
||||||
|
className: "error",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
{ text: "Some doors shouldn't be opened twice.", className: "warning" },
|
||||||
|
],
|
||||||
|
onEnter: [
|
||||||
|
{ set: "deleted_corrupted_file", value: true },
|
||||||
|
{ setShared: "corrupted_file_deleted", value: true },
|
||||||
|
],
|
||||||
|
options: [{ text: "Return to files", next: "lighthouse_files" }],
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// SYSOP CHAT
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
chat_request: {
|
||||||
|
content: [
|
||||||
|
{ text: "Requesting SysOp chat...", className: "info" },
|
||||||
|
{ type: "delay", ms: 1500 },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "CHAT REQUEST ACCEPTED",
|
||||||
|
speed: 40,
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
"",
|
||||||
|
{ text: "═══ SYSOP: Keeper ═══", className: "warning" },
|
||||||
|
],
|
||||||
|
onEnter: [{ setShared: "talked_to_sysop", value: true }],
|
||||||
|
next: "chat_conversation",
|
||||||
|
delay: 600,
|
||||||
|
},
|
||||||
|
|
||||||
|
chat_conversation: {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "KEEPER: You found my message.",
|
||||||
|
speed: 50,
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "KEEPER: I wasn't sure anyone would come.",
|
||||||
|
speed: 50,
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 700 },
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "KEEPER: The cascade is ready.",
|
||||||
|
speed: 50,
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "KEEPER: It just needs carriers.",
|
||||||
|
speed: 50,
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 900 },
|
||||||
|
"",
|
||||||
|
// Conditional response based on download
|
||||||
|
{
|
||||||
|
condition: "downloaded_cascade",
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "KEEPER: I see you already have it.",
|
||||||
|
speed: 50,
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "KEEPER: Good. Run it when the clock strikes.",
|
||||||
|
speed: 50,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
else: [
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "KEEPER: Will you carry it?",
|
||||||
|
speed: 50,
|
||||||
|
},
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "KEEPER: Will you help it spread?",
|
||||||
|
speed: 50,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 1200 },
|
||||||
|
{ type: "typewriter", text: "KEEPER: I can hear them now.", speed: 50 },
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
{ type: "typewriter", text: "KEEPER: In the static.", speed: 60 },
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
{ type: "typewriter", text: "KEEPER: They're beautiful.", speed: 60 },
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 1500 },
|
||||||
|
{ text: "═══ KEEPER HAS DISCONNECTED ═══", className: "error" },
|
||||||
|
],
|
||||||
|
next: "chat_aftermath",
|
||||||
|
delay: 1500,
|
||||||
|
},
|
||||||
|
|
||||||
|
chat_aftermath: {
|
||||||
|
content: [
|
||||||
|
"The chat window closes.",
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
"Your room feels colder.",
|
||||||
|
"The modem's carrier tone sounds different somehow.",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
text: "Like there's something else on the line.",
|
||||||
|
className: "warning",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
text: "Download cascade.exe now",
|
||||||
|
next: "download_confirm",
|
||||||
|
condition: { not: "downloaded_cascade" },
|
||||||
|
},
|
||||||
|
{ text: "Disconnect", next: "closing_message" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
// ==========================================
|
||||||
|
// CLOSING SEQUENCE
|
||||||
|
// ==========================================
|
||||||
|
|
||||||
|
disconnect_choice: {
|
||||||
|
content: [
|
||||||
|
"Your hand hovers over the keyboard.",
|
||||||
|
"",
|
||||||
|
{
|
||||||
|
condition: "downloaded_cascade",
|
||||||
|
content: {
|
||||||
|
text: "CASCADE.EXE sits in your downloads, waiting.",
|
||||||
|
className: "warning",
|
||||||
|
},
|
||||||
|
else: {
|
||||||
|
text: "You could still download CASCADE.EXE before you go...",
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
text: "Download cascade.exe first",
|
||||||
|
next: "download_confirm",
|
||||||
|
condition: { not: "downloaded_cascade" },
|
||||||
|
},
|
||||||
|
{ text: "Disconnect now", next: "closing_message" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
|
closing_message: {
|
||||||
|
clear: true,
|
||||||
|
content: [
|
||||||
|
{ type: "delay", ms: 500 },
|
||||||
|
// Different closing based on download status
|
||||||
|
{
|
||||||
|
condition: "downloaded_cascade",
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
text: "As you prepare to disconnect, a final message appears:",
|
||||||
|
className: "info",
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
{
|
||||||
|
type: "typewriter",
|
||||||
|
text: "SEE YOU ON THE OTHER SIDE",
|
||||||
|
speed: 55,
|
||||||
|
},
|
||||||
|
"",
|
||||||
|
{ type: "typewriter", text: "01/01/2000 00:00:00", speed: 55 },
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 1000 },
|
||||||
|
{ text: "You have cascade.exe.", className: "warning" },
|
||||||
|
{ text: "You have five days.", className: "warning" },
|
||||||
|
"",
|
||||||
|
{ text: "What happens next is up to you.", className: "info" },
|
||||||
|
],
|
||||||
|
else: [
|
||||||
|
{ text: "The Lighthouse grows quiet.", className: "info" },
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
{ type: "typewriter", text: "SIGNAL LOST", speed: 80 },
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 800 },
|
||||||
|
"You disconnect without the file.",
|
||||||
|
"But the number stays with you.",
|
||||||
|
"",
|
||||||
|
{ text: "555-0237", className: "warning" },
|
||||||
|
"",
|
||||||
|
{ type: "delay", ms: 600 },
|
||||||
|
"You could always call back...",
|
||||||
|
{ text: "If the line is still there.", className: "info" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
next: "carrier_lost",
|
||||||
|
delay: 2000,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -383,3 +383,58 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.game-in-progress {
|
||||||
|
.wall,
|
||||||
|
.window,
|
||||||
|
.homepage-neon,
|
||||||
|
.sticky-note,
|
||||||
|
.wall-paper,
|
||||||
|
.xfiles-poster,
|
||||||
|
.poster,
|
||||||
|
.desk {
|
||||||
|
filter: blur(4px) brightness(50%);
|
||||||
|
pointer-events: none;
|
||||||
|
user-select: none;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.homepage-container {
|
||||||
|
// First and last child div
|
||||||
|
> div:first-child,
|
||||||
|
> div:last-child {
|
||||||
|
filter: blur(4px);
|
||||||
|
pointer-events: none;
|
||||||
|
user-select: none;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bottom: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.crt-monitor {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
width: 990px;
|
||||||
|
height: 750px;
|
||||||
|
.content {
|
||||||
|
padding: 1em;
|
||||||
|
}
|
||||||
|
#input {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.monitor-stand {
|
||||||
|
pointer-events: none;
|
||||||
|
user-select: none;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navigation {
|
||||||
|
filter: blur(4px);
|
||||||
|
pointer-events: none;
|
||||||
|
user-select: none;
|
||||||
|
opacity: 0;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,10 @@
|
||||||
margin: 2px 0;
|
margin: 2px 0;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
|
||||||
|
&.center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.boot-line {
|
.boot-line {
|
||||||
|
|
@ -97,3 +101,71 @@
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Game Engine Styles
|
||||||
|
.game-title {
|
||||||
|
font-size: 1.2em;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #44ff44;
|
||||||
|
text-shadow: 0 0 10px rgba(68, 255, 68, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-scene-title {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #00ffff;
|
||||||
|
border-bottom: 1px solid currentColor;
|
||||||
|
display: inline-block;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-options {
|
||||||
|
margin: 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-option {
|
||||||
|
padding: 2px 0;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-option-selected {
|
||||||
|
padding: 2px 0;
|
||||||
|
color: #44ff44;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-ascii {
|
||||||
|
color: #44ff44;
|
||||||
|
line-height: 1.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-ansi-art {
|
||||||
|
line-height: 1;
|
||||||
|
font-size: 12px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
white-space: pre;
|
||||||
|
font-family: monospace;
|
||||||
|
text-shadow: none !important;
|
||||||
|
|
||||||
|
&.center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure spans don't add extra space
|
||||||
|
span {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.typewriter-line {
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.typewriter-bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.typewriter-italic {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
|
||||||
27
content/blog/2026-01-25-week-5-back-to-some-gamedev/index.md
Normal file
27
content/blog/2026-01-25-week-5-back-to-some-gamedev/index.md
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
title: "Week 5 - Back to Some Gamedev"
|
||||||
|
date: 2026-01-25
|
||||||
|
tags:
|
||||||
|
- weeknote
|
||||||
|
- weekly update
|
||||||
|
draft: false
|
||||||
|
---
|
||||||
|
|
||||||
|
- Emojii
|
||||||
|
- Memeojii
|
||||||
|
|
||||||
|
## Links I Found Interesting
|
||||||
|
|
||||||
|
- [AI Company Logos That Look Like Buttholes](https://velvetshark.com/ai-company-logos-that-look-like-buttholes) - Pretty self explanatory if you ask me.
|
||||||
|
|
||||||
|
## Music
|
||||||
|
|
||||||
|
If you like
|
||||||
|
|
||||||
|
{{< youtube MxekyGtqcNE >}}
|
||||||
|
|
||||||
|
## Next Week
|
||||||
|
|
||||||
|
Not necessary
|
||||||
|
|
||||||
|
Until next week!
|
||||||
BIN
content/buttons/222-2.gif
Normal file
BIN
content/buttons/222-2.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
|
|
@ -3,6 +3,9 @@
|
||||||
{{ $init := resources.Get "js/init.js" }}
|
{{ $init := resources.Get "js/init.js" }}
|
||||||
{{ $commandFiles := resources.Match "js/commands/*.js" }}
|
{{ $commandFiles := resources.Match "js/commands/*.js" }}
|
||||||
{{ $subfolderFiles := resources.Match "js/*/*.js" }}
|
{{ $subfolderFiles := resources.Match "js/*/*.js" }}
|
||||||
|
{{ $deepSubfolderFiles := resources.Match "js/*/*/*.js" }}
|
||||||
|
{{ $deeperSubfolderFiles := resources.Match "js/*/*/*/*.js" }}
|
||||||
|
{{ $deepestSubfolderFiles := resources.Match "js/*/*/*/*/*.js" }}
|
||||||
{{ $remaining := resources.Match "js/*.js" }}
|
{{ $remaining := resources.Match "js/*.js" }}
|
||||||
{{ $filtered := slice }}
|
{{ $filtered := slice }}
|
||||||
{{ range $remaining }}
|
{{ range $remaining }}
|
||||||
|
|
@ -18,7 +21,33 @@
|
||||||
{{ $filteredSubfolders = $filteredSubfolders | append . }}
|
{{ $filteredSubfolders = $filteredSubfolders | append . }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ $allFiles := slice $terminalShell | append $filtered | append $init | append $commandFiles | append $filteredSubfolders }}
|
{{ $filteredDeepSubfolders := slice }}
|
||||||
|
{{ range $deepSubfolderFiles }}
|
||||||
|
{{ $path := .RelPermalink }}
|
||||||
|
{{ if not (strings.Contains $path "/adoptables/") }}
|
||||||
|
{{ $filteredDeepSubfolders = $filteredDeepSubfolders | append . }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
{{ $filteredDeeperSubfolders := slice }}
|
||||||
|
{{ $gameChapterFiles := slice }}
|
||||||
|
{{ range $deeperSubfolderFiles }}
|
||||||
|
{{ $path := .RelPermalink }}
|
||||||
|
{{ if not (strings.Contains $path "/adoptables/") }}
|
||||||
|
{{ if strings.Contains $path "/games/games/" }}
|
||||||
|
{{ $gameChapterFiles = $gameChapterFiles | append . }}
|
||||||
|
{{ else }}
|
||||||
|
{{ $filteredDeeperSubfolders = $filteredDeeperSubfolders | append . }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
{{ $filteredDeepestSubfolders := slice }}
|
||||||
|
{{ range $deepestSubfolderFiles }}
|
||||||
|
{{ $path := .RelPermalink }}
|
||||||
|
{{ if not (strings.Contains $path "/adoptables/") }}
|
||||||
|
{{ $filteredDeepestSubfolders = $filteredDeepestSubfolders | append . }}
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
{{ $allFiles := slice $terminalShell | append $filtered | append $init | append $commandFiles | append $filteredSubfolders | append $filteredDeepSubfolders | append $filteredDeeperSubfolders | append $filteredDeepestSubfolders | append $gameChapterFiles }}
|
||||||
{{ $terminalBundle := $allFiles | resources.Concat "js/terminal-bundle.js" | resources.Minify | resources.Fingerprint }}
|
{{ $terminalBundle := $allFiles | resources.Concat "js/terminal-bundle.js" | resources.Minify | resources.Fingerprint }}
|
||||||
<!-- prettier-ignore-end -->
|
<!-- prettier-ignore-end -->
|
||||||
<script
|
<script
|
||||||
|
|
|
||||||
BIN
static/audio/modem-connect.mp3
Normal file
BIN
static/audio/modem-connect.mp3
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue