summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitja Felicijan <mitja.felicijan@gmail.com>2026-02-18 17:17:33 +0100
committerMitja Felicijan <mitja.felicijan@gmail.com>2026-02-18 17:17:33 +0100
commit148bd1115e328defead3205878039e8cc598712e (patch)
treeea7bde7487d080e0959cc0a26eb9c156c1db4a57
parent6e4ab703d370e94ed0575ee986fa6235de7009ea (diff)
downloadllmnpc-148bd1115e328defead3205878039e8cc598712e.tar.gz
Map editor
-rw-r--r--Makefile12
-rw-r--r--game.c387
-rw-r--r--mapeditor.html722
-rw-r--r--maps/map1.h348
-rw-r--r--maps/map1.txt40
5 files changed, 1460 insertions, 49 deletions
diff --git a/Makefile b/Makefile
index 807a256..696534f 100644
--- a/Makefile
+++ b/Makefile
@@ -13,6 +13,9 @@ LDFLAGS = -L$(LLAMA_DIR)/build/src -L$(LLAMA_DIR)/build/ggml/src \
PROMPT_TXT := $(wildcard prompts/*.txt)
PROMPT_HEADERS := $(PROMPT_TXT:.txt=.h)
+MAP_TXT := $(wildcard maps/*.txt)
+MAP_HEADERS := $(MAP_TXT:.txt=.h)
+
help: .help
build/llama.cpp: .assure # Build llama.cpp libraries
@@ -27,10 +30,12 @@ build/context: context.c vectordb.c models.h # Build context binary for testing
build/npc: build/prompts npc.c vectordb.c models.h # Build npc binary for testing
$(CC) $(CFLAGS) npc.c vectordb.c -o npc $(LDFLAGS)
-build/game: build/prompts game.c vectordb.c models.h # Build npc binary for testing
+build/game: build/prompts build/maps game.c vectordb.c models.h # Build npc binary for testing
$(CC) $(CFLAGS) game.c vectordb.c -o game $(LDFLAGS)
-build/prompts: $(PROMPT_HEADERS) # Generate C style header
+build/prompts: $(PROMPT_HEADERS) # Generate prompts in C style header
+
+build/maps: $(MAP_HEADERS) # Generate maps in C style header
run/fetch-models: .assure # Fetch GGUF models
-mkdir -p models
@@ -47,3 +52,6 @@ run/clean: # Cleans up all the build artefacts
prompts/%.h: prompts/%.txt .assure
xxd -i $< > $@
+
+maps/%.h: maps/%.txt .assure
+ xxd -i $< > $@
diff --git a/game.c b/game.c
index b7bb81c..d430ba3 100644
--- a/game.c
+++ b/game.c
@@ -3,6 +3,11 @@
#define TB_IMPL
#include "termbox2.h"
+#define NONSTD_IMPLEMENTATION
+#include "nonstd.h"
+
+#include "maps/map1.h"
+
#define MIN_W 40
#define MIN_H 12
#define SIDEBAR_W 40
@@ -12,6 +17,47 @@
#define CP_TR 0x2510
#define CP_BL 0x2514
#define CP_BR 0x2518
+#define MAP_FLOOR_CH '.'
+#define MAP_BORDER_MIN 0x2500
+#define MAP_BORDER_MAX 0x257f
+#define MAP_FLOOR_FG 234
+#define COLOR_WHITE_256 0x0f
+#define COLOR_RED_256 161
+#define COLOR_GREEN_256 0x2e
+#define COLOR_BORDER_256 101
+#define COLOR_CYAN_256 0x33
+#define COLOR_ORANGE_256 0xd0
+#define COLOR_BLUE_256 0x1b
+
+typedef struct {
+ char key;
+ const char *name;
+} InventoryItem;
+
+typedef struct {
+ array(InventoryItem) items;
+} Inventory;
+
+typedef struct {
+ int x;
+ int y;
+ int hp;
+ int hp_max;
+ int ac;
+ int str;
+ int gold;
+ Inventory inventory;
+} Player;
+
+typedef struct {
+ const unsigned char *data;
+ int len;
+ int width;
+ int height;
+ u32 *cells;
+} Map;
+
+static int clamp(int value, int min, int max);
static void draw_border(int x, int y, int w, int h, uintattr_t fg) {
int ix;
@@ -52,10 +98,176 @@ static void get_layout(int w, int h, int *map_x, int *map_y, int *map_w,
*msg2_y = h - 1;
}
-static void draw_map(int map_x, int map_y, int map_w, int map_h, int px,
- int py) {
- if (px >= 0 && py >= 0) {
- tb_set_cell(map_x + px, map_y + py, '@', TB_WHITE | TB_BOLD, TB_DEFAULT);
+static void map_init(Map *map, const unsigned char *data, int len) {
+ array(int) line_lengths;
+ int width = 0;
+ int height = 0;
+ int line_len = 0;
+ int i = 0;
+
+ map->data = data;
+ map->len = len;
+ map->cells = NULL;
+ array_init(line_lengths);
+ while (i < len) {
+ uint32_t ch = 0;
+ int consumed = tb_utf8_char_to_unicode(&ch, (const char *)&data[i]);
+ if (consumed <= 0) {
+ i++;
+ continue;
+ }
+ i += consumed;
+ if (ch == '\n') {
+ array_push(line_lengths, line_len);
+ if (line_len > width) {
+ width = line_len;
+ }
+ height++;
+ line_len = 0;
+ } else {
+ line_len++;
+ }
+ }
+ if (line_len > 0 || (len > 0 && data[len - 1] != '\n')) {
+ array_push(line_lengths, line_len);
+ if (line_len > width) {
+ width = line_len;
+ }
+ height++;
+ }
+
+ map->width = width;
+ map->height = height;
+ if (width > 0 && height > 0) {
+ map->cells = ALLOC(u32, (usize)width * (usize)height);
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ map->cells[(y * width) + x] = ' ';
+ }
+ }
+ }
+
+ i = 0;
+ int x = 0;
+ int y = 0;
+ while (i < len && y < height) {
+ uint32_t ch = 0;
+ int consumed = tb_utf8_char_to_unicode(&ch, (const char *)&data[i]);
+ if (consumed <= 0) {
+ i++;
+ continue;
+ }
+ i += consumed;
+ if (ch == '\n') {
+ y++;
+ x = 0;
+ continue;
+ }
+ if (map->cells && x < width) {
+ map->cells[(y * width) + x] = ch;
+ }
+ x++;
+ }
+ array_free(line_lengths);
+}
+
+static u32 map_get(const Map *map, int x, int y) {
+ if (!map->cells || x < 0 || y < 0 || x >= map->width || y >= map->height) {
+ return ' ';
+ }
+ return map->cells[(y * map->width) + x];
+}
+
+static void map_set(Map *map, int x, int y, u32 ch) {
+ if (!map->cells || x < 0 || y < 0 || x >= map->width || y >= map->height) {
+ return;
+ }
+ map->cells[(y * map->width) + x] = ch;
+}
+
+static int map_is_walkable(const Map *map, int x, int y) {
+ u32 ch = map_get(map, x, y);
+ return ch == MAP_FLOOR_CH || ch == '$';
+}
+
+static void map_free(Map *map) {
+ FREE(map->cells);
+}
+
+static void update_camera(const Map *map, int view_w, int view_h,
+ const Player *player, int *cam_x, int *cam_y) {
+ int max_cam_x;
+ int max_cam_y;
+ int margin_x;
+ int margin_y;
+ int next_x = *cam_x;
+ int next_y = *cam_y;
+
+ if (view_w <= 0 || view_h <= 0 || map->width <= 0 || map->height <= 0) {
+ *cam_x = 0;
+ *cam_y = 0;
+ return;
+ }
+
+ margin_x = view_w > 8 ? 3 : view_w / 3;
+ margin_y = view_h > 8 ? 3 : view_h / 3;
+ max_cam_x = map->width - view_w;
+ max_cam_y = map->height - view_h;
+ if (max_cam_x < 0) {
+ max_cam_x = 0;
+ }
+ if (max_cam_y < 0) {
+ max_cam_y = 0;
+ }
+
+ if (player->x < next_x + margin_x) {
+ next_x = player->x - margin_x;
+ } else if (player->x > next_x + view_w - 1 - margin_x) {
+ next_x = player->x - (view_w - 1 - margin_x);
+ }
+ if (player->y < next_y + margin_y) {
+ next_y = player->y - margin_y;
+ } else if (player->y > next_y + view_h - 1 - margin_y) {
+ next_y = player->y - (view_h - 1 - margin_y);
+ }
+
+ *cam_x = clamp(next_x, 0, max_cam_x);
+ *cam_y = clamp(next_y, 0, max_cam_y);
+}
+
+static void draw_map(const Map *map, int map_x, int map_y, int view_w,
+ int view_h, const Player *player, int cam_x, int cam_y) {
+ int ix;
+ int iy;
+
+ for (iy = 0; iy < view_h; iy++) {
+ for (ix = 0; ix < view_w; ix++) {
+ int mx = cam_x + ix;
+ int my = cam_y + iy;
+ u32 ch = map_get(map, mx, my);
+ uintattr_t fg = COLOR_WHITE_256;
+ if (ch == MAP_FLOOR_CH) {
+ fg = MAP_FLOOR_FG;
+ } else if (ch == '~') {
+ fg = COLOR_BLUE_256;
+ } else if (ch == '$') {
+ fg = COLOR_ORANGE_256;
+ } else if (ch == 'B' || ch == 'S' || ch == 'G') {
+ fg = COLOR_RED_256;
+ } else if (ch == 'N') {
+ fg = COLOR_CYAN_256;
+ } else if (ch >= MAP_BORDER_MIN && ch <= MAP_BORDER_MAX) {
+ fg = COLOR_BORDER_256;
+ }
+ tb_set_cell(map_x + ix, map_y + iy, ch, fg, TB_DEFAULT);
+ }
+ }
+
+ if (player->x >= cam_x && player->x < cam_x + view_w && player->y >= cam_y
+ && player->y < cam_y + view_h) {
+ int sx = map_x + (player->x - cam_x);
+ int sy = map_y + (player->y - cam_y);
+ tb_set_cell(sx, sy, '@', COLOR_GREEN_256 | TB_BOLD, TB_DEFAULT);
}
}
@@ -78,30 +290,65 @@ static void draw_progress_bar(int x, int y, int w, int value, int max) {
}
filled = (inner_w * value) / max;
- tb_set_cell(x, y, '[', TB_WHITE, TB_DEFAULT);
+ tb_set_cell(x, y, '[', COLOR_WHITE_256, TB_DEFAULT);
for (ix = 0; ix < inner_w; ix++) {
- uintattr_t fg = ix < filled ? TB_GREEN : TB_WHITE;
+ uintattr_t fg = ix < filled ? COLOR_GREEN_256 : COLOR_WHITE_256;
uint32_t ch = ix < filled ? '=' : ' ';
tb_set_cell(x + 1 + ix, y, ch, fg, TB_DEFAULT);
}
- tb_set_cell(x + w - 1, y, ']', TB_WHITE, TB_DEFAULT);
+ tb_set_cell(x + w - 1, y, ']', COLOR_WHITE_256, TB_DEFAULT);
+}
+
+static void inventory_init(Inventory *inv) {
+ array_init(inv->items);
+}
+
+static void inventory_add(Inventory *inv, char key, const char *name) {
+ InventoryItem item = {.key = key, .name = name};
+ array_push(inv->items, item);
+}
+
+static void inventory_free(Inventory *inv) {
+ array_free(inv->items);
+}
+
+static void player_init(Player *player) {
+ player->x = 6;
+ player->y = 4;
+ player->hp = 12;
+ player->hp_max = 12;
+ player->ac = 7;
+ player->str = 16;
+ player->gold = 42;
+ inventory_init(&player->inventory);
+ inventory_add(&player->inventory, 'a', "dagger");
+ inventory_add(&player->inventory, 'b', "ration");
+ inventory_add(&player->inventory, 'c', "potion");
+ inventory_add(&player->inventory, 'd', "scroll");
}
-static void draw_stats(int x, int y) {
- tb_print(x, y, TB_WHITE | TB_BOLD, TB_DEFAULT, "Stats");
- tb_print(x, y + 2, TB_WHITE, TB_DEFAULT, "HP 12/12");
- draw_progress_bar(x, y + 3, 18, 12, 12);
- tb_print(x, y + 4, TB_WHITE, TB_DEFAULT, "AC: 7");
- tb_print(x, y + 5, TB_WHITE, TB_DEFAULT, "Str: 16");
- tb_print(x, y + 6, TB_WHITE, TB_DEFAULT, "Gold: 42");
+static void player_free(Player *player) {
+ inventory_free(&player->inventory);
}
-static void draw_inventory(int x, int y) {
- tb_print(x, y, TB_WHITE | TB_BOLD, TB_DEFAULT, "Inventory");
- tb_print(x, y + 2, TB_WHITE, TB_DEFAULT, "a) dagger");
- tb_print(x, y + 3, TB_WHITE, TB_DEFAULT, "b) ration");
- tb_print(x, y + 4, TB_WHITE, TB_DEFAULT, "c) potion");
- tb_print(x, y + 5, TB_WHITE, TB_DEFAULT, "d) scroll");
+static void draw_stats(int x, int y, const Player *player) {
+ tb_print(x, y, COLOR_WHITE_256 | TB_BOLD, TB_DEFAULT, "Stats");
+ tb_printf(x, y + 2, COLOR_WHITE_256, TB_DEFAULT, "HP %d/%d", player->hp, player->hp_max);
+ draw_progress_bar(x, y + 3, 18, player->hp, player->hp_max);
+ tb_printf(x, y + 4, COLOR_WHITE_256, TB_DEFAULT, "AC: %d", player->ac);
+ tb_printf(x, y + 5, COLOR_WHITE_256, TB_DEFAULT, "Str: %d", player->str);
+ tb_printf(x, y + 6, COLOR_WHITE_256, TB_DEFAULT, "Gold: %d", player->gold);
+}
+
+static void draw_inventory(int x, int y, const Inventory *inv) {
+ InventoryItem item;
+ usize idx = 0;
+
+ tb_print(x, y, COLOR_WHITE_256 | TB_BOLD, TB_DEFAULT, "Inventory");
+ array_foreach(inv->items, item) {
+ tb_printf(x, y + 2 + (int)idx, COLOR_WHITE_256, TB_DEFAULT, "%c) %s", item.key, item.name);
+ idx++;
+ }
}
static const char *status_msg = "";
@@ -110,7 +357,8 @@ static void update_status(const char *message) {
status_msg = message ? message : "";
}
-static void render(int px, int py, int *out_map_w, int *out_map_h) {
+static void render(const Map *map, const Player *player, int *cam_x,
+ int *cam_y, int *out_view_w, int *out_view_h) {
int w;
int h;
int map_x;
@@ -131,6 +379,12 @@ static void render(int px, int py, int *out_map_w, int *out_map_h) {
int inv_h;
int msg1_y;
int msg2_y;
+ int view_w;
+ int view_h;
+ int draw_w;
+ int draw_h;
+ int pad_x;
+ int pad_y;
w = tb_width();
h = tb_height();
@@ -138,15 +392,29 @@ static void render(int px, int py, int *out_map_w, int *out_map_h) {
tb_clear();
if (w < MIN_W || h < MIN_H || map_w < 8 || map_h < 3) {
- tb_print(1, 1, TB_RED | TB_BOLD, TB_DEFAULT, "Window too small. Resize to at least 40x12.");
+ tb_print(1, 1, COLOR_RED_256 | TB_BOLD, TB_DEFAULT, "Window too small. Resize to at least 40x12.");
tb_present();
- *out_map_w = map_w;
- *out_map_h = map_h;
+ *out_view_w = map_w;
+ *out_view_h = map_h;
return;
}
- draw_border(map_x, map_y, map_w, map_h, TB_WHITE);
- draw_map(map_x + 1, map_y + 1, map_w - 2, map_h - 2, px, py);
+ view_w = map_w - 2;
+ view_h = map_h - 2;
+ draw_w = view_w;
+ draw_h = view_h;
+ if (map->width < draw_w) {
+ draw_w = map->width;
+ }
+ if (map->height < draw_h) {
+ draw_h = map->height;
+ }
+ pad_x = view_w > draw_w ? (view_w - draw_w) / 2 : 0;
+ pad_y = view_h > draw_h ? (view_h - draw_h) / 2 : 0;
+
+ draw_border(map_x, map_y, map_w, map_h, COLOR_WHITE_256);
+ update_camera(map, view_w, view_h, player, cam_x, cam_y);
+ draw_map(map, map_x + 1 + pad_x, map_y + 1 + pad_y, draw_w, draw_h, player, *cam_x, *cam_y);
stats_x = side_x;
stats_y = side_y;
@@ -157,20 +425,20 @@ static void render(int px, int py, int *out_map_w, int *out_map_h) {
inv_w = side_w;
inv_h = side_h - stats_h;
if (stats_w >= 12 && stats_h >= 9) {
- draw_border(stats_x, stats_y, stats_w, stats_h, TB_WHITE);
- draw_stats(stats_x + 2, stats_y + 1);
+ draw_border(stats_x, stats_y, stats_w, stats_h, COLOR_WHITE_256);
+ draw_stats(stats_x + 2, stats_y + 1, player);
}
if (inv_w >= 12 && inv_h >= 7) {
- draw_border(inv_x, inv_y, inv_w, inv_h, TB_WHITE);
- draw_inventory(inv_x + 2, inv_y + 1);
+ draw_border(inv_x, inv_y, inv_w, inv_h, COLOR_WHITE_256);
+ draw_inventory(inv_x + 2, inv_y + 1, &player->inventory);
}
- tb_print(2, msg1_y, TB_GREEN, TB_DEFAULT, status_msg);
- tb_print(2, msg2_y, TB_WHITE, TB_DEFAULT, "Move: arrows Quit: q/ESC");
+ tb_print(2, msg1_y, COLOR_GREEN_256, TB_DEFAULT, status_msg);
+ tb_print(2, msg2_y, COLOR_WHITE_256, TB_DEFAULT, "Move: arrows Quit: q/ESC");
tb_present();
- *out_map_w = map_w - 2;
- *out_map_h = map_h - 2;
+ *out_view_w = view_w;
+ *out_view_h = view_h;
}
static int clamp(int value, int min, int max) {
@@ -184,11 +452,16 @@ static int clamp(int value, int min, int max) {
}
int main(void) {
- int px = 6;
- int py = 4;
+ Player player = {0};
+ Map map = {0};
int running = 1;
- int map_w = 0;
- int map_h = 0;
+ int view_w = 0;
+ int view_h = 0;
+ int cam_x = 0;
+ int cam_y = 0;
+
+ player_init(&player);
+ map_init(&map, maps_map1_txt, (int)maps_map1_txt_len);
if (tb_init() != TB_OK) {
fprintf(stderr, "Failed to init termbox.\n");
@@ -196,32 +469,52 @@ int main(void) {
}
tb_set_input_mode(TB_INPUT_ESC);
+ tb_set_output_mode(TB_OUTPUT_256);
update_status("You feel like you have a lot of potential.");
while (running) {
struct tb_event ev;
- render(px, py, &map_w, &map_h);
+ render(&map, &player, &cam_x, &cam_y, &view_w, &view_h);
tb_poll_event(&ev);
if (ev.type == TB_EVENT_KEY) {
if (ev.key == TB_KEY_ESC || ev.ch == 'q') {
running = 0;
} else if (ev.key == TB_KEY_ARROW_UP) {
- py -= 1;
+ int next_y = player.y - 1;
+ if (map_is_walkable(&map, player.x, next_y)) {
+ player.y = next_y;
+ }
} else if (ev.key == TB_KEY_ARROW_DOWN) {
- py += 1;
+ int next_y = player.y + 1;
+ if (map_is_walkable(&map, player.x, next_y)) {
+ player.y = next_y;
+ }
} else if (ev.key == TB_KEY_ARROW_LEFT) {
- px -= 1;
+ int next_x = player.x - 1;
+ if (map_is_walkable(&map, next_x, player.y)) {
+ player.x = next_x;
+ }
} else if (ev.key == TB_KEY_ARROW_RIGHT) {
- px += 1;
+ int next_x = player.x + 1;
+ if (map_is_walkable(&map, next_x, player.y)) {
+ player.x = next_x;
+ }
+ }
+ if (map_get(&map, player.x, player.y) == '$') {
+ player.gold += 10;
+ map_set(&map, player.x, player.y, MAP_FLOOR_CH);
+ update_status("You pick up 10 gold.");
}
- px = clamp(px, 0, map_w > 1 ? map_w - 1 : 0);
- py = clamp(py, 0, map_h > 1 ? map_h - 1 : 0);
+ player.x = clamp(player.x, 0, map.width > 1 ? map.width - 1 : 0);
+ player.y = clamp(player.y, 0, map.height > 1 ? map.height - 1 : 0);
} else if (ev.type == TB_EVENT_RESIZE) {
- px = clamp(px, 0, map_w > 1 ? map_w - 1 : 0);
- py = clamp(py, 0, map_h > 1 ? map_h - 1 : 0);
+ player.x = clamp(player.x, 0, map.width > 1 ? map.width - 1 : 0);
+ player.y = clamp(player.y, 0, map.height > 1 ? map.height - 1 : 0);
}
}
+ player_free(&player);
+ map_free(&map);
tb_shutdown();
return 0;
}
diff --git a/mapeditor.html b/mapeditor.html
new file mode 100644
index 0000000..03661e7
--- /dev/null
+++ b/mapeditor.html
@@ -0,0 +1,722 @@
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ <title>ASCII Map Editor</title>
+ <style>
+ :root {
+ color-scheme: light;
+ --gridline: rgba(0, 0, 0, 0.1);
+ --mono: "SFMono-Regular", Menlo, Consolas, monospace;
+ }
+
+ * {
+ box-sizing: border-box;
+ }
+
+ body {
+ margin: 0;
+ font-family: system-ui, sans-serif;
+ background: #f5f5f5;
+ color: #222;
+ height: 100vh;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ }
+
+ header {
+ padding: 16px 20px 8px;
+ }
+
+ header h1 {
+ margin: 0 0 6px;
+ font-size: 1.2rem;
+ }
+
+ header p {
+ margin: 0;
+ color: #555;
+ }
+
+ .layout {
+ display: grid;
+ grid-template-columns: 280px 1fr;
+ gap: 16px;
+ padding: 0 20px 20px;
+ flex: 1;
+ min-height: 0;
+ }
+
+ .panel,
+ .grid-wrap {
+ background: #fff;
+ border: 1px solid #ddd;
+ border-radius: 6px;
+ padding: 12px;
+ overflow: auto;
+ min-height: 0;
+ }
+
+ .panel h2 {
+ font-size: 0.9rem;
+ margin: 0 0 10px;
+ }
+
+ .controls {
+ display: grid;
+ gap: 12px;
+ }
+
+ .control-group {
+ display: grid;
+ gap: 8px;
+ padding-bottom: 8px;
+ border-bottom: 1px solid #eee;
+ }
+
+ .control-group:last-child {
+ border-bottom: 0;
+ padding-bottom: 0;
+ }
+
+ .row {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 8px;
+ }
+
+ .palette {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 6px;
+ }
+
+ .tile-btn {
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ padding: 6px 0;
+ background: #f7f7f7;
+ font-family: var(--mono);
+ cursor: pointer;
+ }
+
+ .tile-btn.active {
+ outline: 2px solid #2b7fff;
+ border-color: #2b7fff;
+ }
+
+ .button {
+ background: #2b7fff;
+ color: #fff;
+ border: none;
+ border-radius: 4px;
+ padding: 6px 10px;
+ cursor: pointer;
+ }
+
+ .button.secondary {
+ background: #fff;
+ color: #222;
+ border: 1px solid #ccc;
+ }
+
+ input[type="range"] {
+ width: 100%;
+ }
+
+ .stat {
+ font-family: var(--mono);
+ color: #2b7fff;
+ font-size: 0.85rem;
+ }
+
+ #gridCanvas {
+ display: block;
+ background: #fff;
+ border: 1px solid #ddd;
+ image-rendering: pixelated;
+ cursor: crosshair;
+ }
+
+ .footer-note {
+ color: #666;
+ font-size: 0.85rem;
+ }
+
+ @media (max-width: 980px) {
+ .layout {
+ grid-template-columns: 1fr;
+ }
+ }
+ </style>
+ </head>
+ <body>
+ <header>
+ <h1>ASCII Map Editor</h1>
+ <p>Paint tiles directly onto the grid. Export keeps the same text layout as your map files.</p>
+ </header>
+ <div class="layout">
+ <aside class="panel">
+ <h2>Tools</h2>
+ <div class="controls">
+ <div class="control-group">
+ <div class="row">
+ <span>Tile</span>
+ <span class="stat" id="activeTile">#</span>
+ </div>
+ <div class="palette" id="palette"></div>
+ </div>
+ <div class="control-group">
+ <div class="row">
+ <span>Brush</span>
+ <span class="stat" id="brushLabel">1</span>
+ </div>
+ <input type="range" id="brushSize" min="1" max="5" value="1" />
+ </div>
+ <div class="control-group">
+ <div class="row">
+ <span>Grid</span>
+ <span class="stat" id="gridSize">0 x 0</span>
+ </div>
+ <div class="row">
+ <button class="button secondary" id="toggleGrid">Toggle Gridlines</button>
+ <button class="button secondary" id="clearMap">Clear</button>
+ </div>
+ <div class="row">
+ <button class="button secondary" id="addBorder">Add Border</button>
+ <button class="button secondary" id="addDoubleBorder">Add Double Border</button>
+ </div>
+ <div class="row">
+ <label>
+ W
+ <input type="number" id="gridWidth" min="1" value="118" style="width: 64px" />
+ </label>
+ <label>
+ H
+ <input type="number" id="gridHeight" min="1" value="59" style="width: 64px" />
+ </label>
+ <button class="button secondary" id="resizeGrid">Resize</button>
+ </div>
+ </div>
+ <div class="control-group">
+ <div class="row">
+ <button class="button" id="saveMap">Download .txt</button>
+ <button class="button secondary" id="copyMap">Copy</button>
+ </div>
+ <div class="row">
+ <input type="file" id="fileInput" accept=".txt" />
+ </div>
+ <div class="footer-note" id="status">Loaded maps/map1.txt</div>
+ </div>
+ <div class="control-group">
+ <div class="footer-note">
+ Paint: click or drag. Hold Shift for straight lines. Shortcut: 1-4 to pick tile.
+ </div>
+ </div>
+ </div>
+ </aside>
+ <main class="grid-wrap" id="gridWrap">
+ <canvas id="gridCanvas" aria-label="Map grid" role="img"></canvas>
+ </main>
+ </div>
+
+ <script>
+ const storageKey = "mapeditor-state";
+ const defaultCols = 118;
+ const defaultRows = 59;
+ const tileOrder = [
+ "┌",
+ "┐",
+ "└",
+ "┘",
+ "─",
+ "│",
+ "╔",
+ "╗",
+ "╚",
+ "╝",
+ "═",
+ "║",
+ "#",
+ ".",
+ "~",
+ " ",
+ "N",
+ "B",
+ "S",
+ "G",
+ "$",
+ ];
+ const tileLabels = {
+ "#": "Wall",
+ ".": "Floor",
+ "~": "Water",
+ "N": "Cyan",
+ "B": "Red",
+ "S": "Red",
+ "G": "Red",
+ "$": "Gold",
+ " ": "Void",
+ "┌": "Border corner",
+ "┐": "Border corner",
+ "└": "Border corner",
+ "┘": "Border corner",
+ "─": "Border",
+ "│": "Border",
+ "╔": "Double border corner",
+ "╗": "Double border corner",
+ "╚": "Double border corner",
+ "╝": "Double border corner",
+ "═": "Double border",
+ "║": "Double border",
+ };
+
+ const canvas = document.getElementById("gridCanvas");
+ const ctx = canvas.getContext("2d");
+ const gridWrap = document.getElementById("gridWrap");
+ const paletteEl = document.getElementById("palette");
+ const activeTileEl = document.getElementById("activeTile");
+ const brushSizeEl = document.getElementById("brushSize");
+ const brushLabelEl = document.getElementById("brushLabel");
+ const gridSizeEl = document.getElementById("gridSize");
+ const toggleGridBtn = document.getElementById("toggleGrid");
+ const clearBtn = document.getElementById("clearMap");
+ const addBorderBtn = document.getElementById("addBorder");
+ const addDoubleBorderBtn = document.getElementById("addDoubleBorder");
+ const gridWidthEl = document.getElementById("gridWidth");
+ const gridHeightEl = document.getElementById("gridHeight");
+ const resizeGridBtn = document.getElementById("resizeGrid");
+ const saveBtn = document.getElementById("saveMap");
+ const copyBtn = document.getElementById("copyMap");
+ const fileInput = document.getElementById("fileInput");
+ const statusEl = document.getElementById("status");
+
+ let mapData = [];
+ let activeTile = "#";
+ let isPainting = false;
+ let lastCell = null;
+ let showGridLines = true;
+
+ const baseFontSize = 14;
+ const minZoom = 0.5;
+ const maxZoom = 4;
+ let zoom = 1;
+ let cellMetrics = { width: baseFontSize, height: baseFontSize, fontSize: baseFontSize };
+ let devicePixelRatioValue = window.devicePixelRatio || 1;
+ let autoSaveId = null;
+ const tileStyle = {
+ wall: { fill: "#8a6b3e", text: "#251a0b" },
+ floor: { fill: "#f7f7f7", text: "#b9b9b9" },
+ water: { fill: "#4a8fa3", text: "#e9f7f9" },
+ cyan: { fill: "#27c8d1", text: "#07353a" },
+ red: { fill: "#d84545", text: "#3d0a0a" },
+ gold: { fill: "#d7a627", text: "#3a2605" },
+ void: { fill: "#222", text: "#777" },
+ };
+
+ const tileClass = (tile) => {
+ if ("#┌┐└┘─│╔╗╚╝═║".includes(tile)) return "wall";
+ if (tile === ".") return "floor";
+ if (tile === "~") return "water";
+ if (tile === "N") return "cyan";
+ if ("BSG".includes(tile)) return "red";
+ if (tile === "$") return "gold";
+ return "void";
+ };
+
+ const setStatus = (text) => {
+ statusEl.textContent = text;
+ };
+
+ const normalizeMap = (lines) => {
+ const cleanLines = lines.filter((line) => line.length > 0);
+ const width = Math.max(...cleanLines.map((line) => line.length));
+ return cleanLines.map((line) => line.padEnd(width, " ").split(""));
+ };
+
+ const mapToText = () => mapData.map((row) => row.join("")).join("\n");
+
+ const buildCanvas = () => {
+ if (!mapData.length) return;
+ const rows = mapData.length;
+ const cols = mapData[0].length;
+ resizeCanvas(cols, rows);
+ gridSizeEl.textContent = `${cols} x ${rows}`;
+ gridWidthEl.value = cols;
+ gridHeightEl.value = rows;
+ renderAll();
+ };
+
+ const resizeCanvas = (cols, rows) => {
+ const fontSize = Math.max(8, Math.round(baseFontSize * zoom));
+ devicePixelRatioValue = window.devicePixelRatio || 1;
+ ctx.setTransform(devicePixelRatioValue, 0, 0, devicePixelRatioValue, 0, 0);
+ ctx.font = `${fontSize}px ${getComputedStyle(document.documentElement).getPropertyValue("--mono")}`;
+ const metrics = ctx.measureText("M");
+ const glyphWidth = Math.max(1, Math.ceil(metrics.width));
+ const glyphHeight = Math.max(
+ 1,
+ Math.ceil((metrics.actualBoundingBoxAscent || fontSize) + (metrics.actualBoundingBoxDescent || 0))
+ );
+ cellMetrics = { width: glyphWidth, height: glyphHeight, fontSize };
+ canvas.style.width = `${cols * cellMetrics.width}px`;
+ canvas.style.height = `${rows * cellMetrics.height}px`;
+ canvas.width = Math.round(cols * cellMetrics.width * devicePixelRatioValue);
+ canvas.height = Math.round(rows * cellMetrics.height * devicePixelRatioValue);
+ ctx.setTransform(devicePixelRatioValue, 0, 0, devicePixelRatioValue, 0, 0);
+ ctx.font = `${fontSize}px ${getComputedStyle(document.documentElement).getPropertyValue("--mono")}`;
+ ctx.textAlign = "left";
+ ctx.textBaseline = "top";
+ };
+
+ const drawCell = (x, y, tile) => {
+ const type = tileClass(tile);
+ const style = tileStyle[type];
+ const px = x * cellMetrics.width;
+ const py = y * cellMetrics.height;
+ ctx.fillStyle = style.fill;
+ ctx.fillRect(px, py, cellMetrics.width, cellMetrics.height);
+ if (showGridLines) {
+ ctx.strokeStyle = getComputedStyle(document.documentElement)
+ .getPropertyValue("--gridline")
+ .trim();
+ ctx.strokeRect(
+ px + 0.5,
+ py + 0.5,
+ Math.max(1, cellMetrics.width - 1),
+ Math.max(1, cellMetrics.height - 1)
+ );
+ }
+ if (tile !== " ") {
+ ctx.fillStyle = style.text;
+ ctx.fillText(tile, px, py);
+ }
+ };
+
+ const renderAll = () => {
+ const rows = mapData.length;
+ const cols = mapData[0].length;
+ for (let y = 0; y < rows; y += 1) {
+ for (let x = 0; x < cols; x += 1) {
+ drawCell(x, y, mapData[y][x]);
+ }
+ }
+ };
+
+ const updateCell = (x, y, tile) => {
+ if (!mapData[y] || mapData[y][x] === undefined) return;
+ mapData[y][x] = tile;
+ drawCell(x, y, tile);
+ };
+
+ const paintAt = (x, y) => {
+ const size = Number(brushSizeEl.value);
+ const half = Math.floor(size / 2);
+ for (let dy = -half; dy <= half; dy += 1) {
+ for (let dx = -half; dx <= half; dx += 1) {
+ updateCell(x + dx, y + dy, activeTile);
+ }
+ }
+ };
+
+ const drawLine = (from, to) => {
+ const dx = Math.abs(to.x - from.x);
+ const dy = Math.abs(to.y - from.y);
+ const sx = from.x < to.x ? 1 : -1;
+ const sy = from.y < to.y ? 1 : -1;
+ let err = dx - dy;
+ let x = from.x;
+ let y = from.y;
+ while (true) {
+ paintAt(x, y);
+ if (x === to.x && y === to.y) break;
+ const e2 = err * 2;
+ if (e2 > -dy) {
+ err -= dy;
+ x += sx;
+ }
+ if (e2 < dx) {
+ err += dx;
+ y += sy;
+ }
+ }
+ };
+
+ const setActiveTile = (tile) => {
+ activeTile = tile;
+ activeTileEl.textContent = tile === " " ? "(space)" : tile;
+ paletteEl.querySelectorAll(".tile-btn").forEach((btn) => {
+ btn.classList.toggle("active", btn.dataset.tile === tile);
+ });
+ };
+
+ const setupPalette = () => {
+ paletteEl.innerHTML = "";
+ tileOrder.forEach((tile) => {
+ const btn = document.createElement("button");
+ btn.type = "button";
+ btn.className = "tile-btn";
+ btn.dataset.tile = tile;
+ btn.textContent = tile === " " ? "space" : tile;
+ btn.title = tileLabels[tile] || tile;
+ btn.addEventListener("click", () => setActiveTile(tile));
+ paletteEl.appendChild(btn);
+ });
+ setActiveTile(activeTile);
+ };
+
+ const loadFromText = (text, sourceLabel) => {
+ const lines = text.replace(/\r/g, "").split("\n");
+ mapData = normalizeMap(lines);
+ buildCanvas();
+ setStatus(`Loaded ${sourceLabel}`);
+ };
+
+ const loadDefaultMap = () => {
+ const row = ".".repeat(defaultCols);
+ const empty = Array.from({ length: defaultRows }, () => row).join("\n");
+ loadFromText(empty, "empty map");
+ };
+
+ const saveState = () => {
+ if (!mapData.length) return;
+ const state = {
+ map: mapToText(),
+ cols: mapData[0].length,
+ rows: mapData.length,
+ zoom,
+ brush: Number(brushSizeEl.value),
+ tile: activeTile,
+ grid: showGridLines,
+ };
+ try {
+ localStorage.setItem(storageKey, JSON.stringify(state));
+ setStatus("Autosaved");
+ } catch (error) {
+ setStatus("Autosave failed");
+ }
+ };
+
+ const loadState = () => {
+ try {
+ const raw = localStorage.getItem(storageKey);
+ if (!raw) return false;
+ const state = JSON.parse(raw);
+ if (!state?.map) return false;
+ loadFromText(state.map, "local autosave");
+ if (state.zoom) applyZoom(state.zoom);
+ if (state.brush) {
+ brushSizeEl.value = state.brush;
+ brushLabelEl.textContent = state.brush;
+ }
+ if (state.tile) setActiveTile(state.tile);
+ if (typeof state.grid === "boolean") showGridLines = state.grid;
+ renderAll();
+ return true;
+ } catch (error) {
+ return false;
+ }
+ };
+
+ brushSizeEl.addEventListener("input", () => {
+ brushLabelEl.textContent = brushSizeEl.value;
+ });
+
+ toggleGridBtn.addEventListener("click", () => {
+ showGridLines = !showGridLines;
+ renderAll();
+ });
+
+ clearBtn.addEventListener("click", () => {
+ mapData = mapData.map((row) => row.map(() => "."));
+ buildCanvas();
+ setStatus("Cleared to floor tiles");
+ });
+
+ resizeGridBtn.addEventListener("click", () => {
+ const newCols = Math.max(1, Number(gridWidthEl.value) || 1);
+ const newRows = Math.max(1, Number(gridHeightEl.value) || 1);
+ const oldRows = mapData.length;
+ const oldCols = mapData[0]?.length || 0;
+ const resized = [];
+ for (let y = 0; y < newRows; y += 1) {
+ const row = [];
+ for (let x = 0; x < newCols; x += 1) {
+ const tile = mapData[y]?.[x] ?? ".";
+ row.push(tile);
+ }
+ resized.push(row);
+ }
+ mapData = resized;
+ buildCanvas();
+ setStatus(`Resized from ${oldCols}x${oldRows} to ${newCols}x${newRows}`);
+ });
+
+ addBorderBtn.addEventListener("click", () => {
+ if (!mapData.length) return;
+ const rows = mapData.length;
+ const cols = mapData[0].length;
+ if (cols < 2 || rows < 2) return;
+ updateCell(0, 0, "┌");
+ updateCell(cols - 1, 0, "┐");
+ updateCell(0, rows - 1, "└");
+ updateCell(cols - 1, rows - 1, "┘");
+ for (let x = 1; x < cols - 1; x += 1) {
+ updateCell(x, 0, "─");
+ updateCell(x, rows - 1, "─");
+ }
+ for (let y = 1; y < rows - 1; y += 1) {
+ updateCell(0, y, "│");
+ updateCell(cols - 1, y, "│");
+ }
+ setStatus("Added box border tiles");
+ });
+
+ addDoubleBorderBtn.addEventListener("click", () => {
+ if (!mapData.length) return;
+ const rows = mapData.length;
+ const cols = mapData[0].length;
+ if (cols < 2 || rows < 2) return;
+ updateCell(0, 0, "╔");
+ updateCell(cols - 1, 0, "╗");
+ updateCell(0, rows - 1, "╚");
+ updateCell(cols - 1, rows - 1, "╝");
+ for (let x = 1; x < cols - 1; x += 1) {
+ updateCell(x, 0, "═");
+ updateCell(x, rows - 1, "═");
+ }
+ for (let y = 1; y < rows - 1; y += 1) {
+ updateCell(0, y, "║");
+ updateCell(cols - 1, y, "║");
+ }
+ setStatus("Added double border tiles");
+ });
+
+ saveBtn.addEventListener("click", () => {
+ const blob = new Blob([mapToText()], { type: "text/plain" });
+ const url = URL.createObjectURL(blob);
+ const link = document.createElement("a");
+ link.href = url;
+ link.download = "map.txt";
+ document.body.appendChild(link);
+ link.click();
+ link.remove();
+ URL.revokeObjectURL(url);
+ setStatus("Downloaded map.txt");
+ });
+
+ copyBtn.addEventListener("click", async () => {
+ try {
+ await navigator.clipboard.writeText(mapToText());
+ setStatus("Copied map to clipboard");
+ } catch (error) {
+ setStatus("Clipboard unavailable");
+ }
+ });
+
+ fileInput.addEventListener("change", async (event) => {
+ const file = event.target.files[0];
+ if (!file) return;
+ const text = await file.text();
+ loadFromText(text, file.name);
+ });
+
+ canvas.addEventListener("contextmenu", (event) => {
+ event.preventDefault();
+ });
+
+ const getCellFromEvent = (event) => {
+ const rect = canvas.getBoundingClientRect();
+ const x = Math.floor((event.clientX - rect.left) / cellMetrics.width);
+ const y = Math.floor((event.clientY - rect.top) / cellMetrics.height);
+ if (x < 0 || y < 0) return null;
+ if (!mapData.length) return null;
+ if (y >= mapData.length || x >= mapData[0].length) return null;
+ return { x, y };
+ };
+
+ const applyZoom = (newZoom, anchor) => {
+ const rows = mapData.length;
+ const cols = mapData[0]?.length || 0;
+ if (!rows || !cols) return;
+ const clamped = Math.min(maxZoom, Math.max(minZoom, newZoom));
+ if (clamped === zoom) return;
+ const sizeBeforeX = cellMetrics.width;
+ const sizeBeforeY = cellMetrics.height;
+ const offsetX = anchor?.x ?? gridWrap.clientWidth / 2;
+ const offsetY = anchor?.y ?? gridWrap.clientHeight / 2;
+ const worldX = (gridWrap.scrollLeft + offsetX) / sizeBeforeX;
+ const worldY = (gridWrap.scrollTop + offsetY) / sizeBeforeY;
+ zoom = clamped;
+ resizeCanvas(cols, rows);
+ renderAll();
+ gridWrap.scrollLeft = worldX * cellMetrics.width - offsetX;
+ gridWrap.scrollTop = worldY * cellMetrics.height - offsetY;
+ };
+
+ const handleCanvasEvent = (event, overrideTile = null) => {
+ const cell = getCellFromEvent(event);
+ if (!cell) return;
+ const previousTile = activeTile;
+ if (overrideTile !== null) activeTile = overrideTile;
+ if (event.shiftKey && lastCell) {
+ drawLine(lastCell, cell);
+ } else {
+ paintAt(cell.x, cell.y);
+ }
+ if (overrideTile !== null) activeTile = previousTile;
+ lastCell = cell;
+ };
+
+ canvas.addEventListener("mousedown", (event) => {
+ if (event.button === 2) {
+ isPainting = true;
+ handleCanvasEvent(event, ".");
+ return;
+ }
+ isPainting = true;
+ handleCanvasEvent(event);
+ });
+
+ canvas.addEventListener("mousemove", (event) => {
+ if (!isPainting) return;
+ if (event.buttons === 2) {
+ handleCanvasEvent(event, ".");
+ return;
+ }
+ handleCanvasEvent(event);
+ });
+
+ canvas.addEventListener("wheel", (event) => {
+ event.preventDefault();
+ const delta = event.deltaY > 0 ? -0.1 : 0.1;
+ const rect = canvas.getBoundingClientRect();
+ const anchor = {
+ x: event.clientX - rect.left,
+ y: event.clientY - rect.top,
+ };
+ applyZoom(zoom + delta, anchor);
+ });
+
+ document.addEventListener("mouseup", () => {
+ isPainting = false;
+ lastCell = null;
+ });
+
+ document.addEventListener("keydown", (event) => {
+ if (event.target.matches("input, textarea")) return;
+ if (event.key >= "1" && event.key <= "4") {
+ const tile = tileOrder[Number(event.key) - 1];
+ setActiveTile(tile);
+ }
+ });
+
+ setupPalette();
+ if (!loadState()) loadDefaultMap();
+ autoSaveId = setInterval(saveState, 5000);
+ </script>
+ </body>
+</html>
diff --git a/maps/map1.h b/maps/map1.h
new file mode 100644
index 0000000..110a939
--- /dev/null
+++ b/maps/map1.h
@@ -0,0 +1,348 @@
+unsigned char maps_map1_txt[] = {
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x7e,
+ 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x7e, 0x7e, 0x7e, 0x7e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x53, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x7e,
+ 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x47, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e,
+ 0x7e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x7e, 0x7e, 0x7e,
+ 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x47, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x24, 0x2e, 0x2e, 0x24, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x24, 0x2e, 0x2e, 0xe2, 0x95, 0x94, 0xe2, 0x95, 0x90,
+ 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90,
+ 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90,
+ 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90,
+ 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x97, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x24, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a,
+ 0x2e, 0x2e, 0x24, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x91,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x91, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x91, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0xe2, 0x95, 0x91, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x91, 0x2e, 0x2e, 0x2e, 0x4e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x91,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0xe2, 0x95, 0x91, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x4e, 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x91, 0x2e, 0x24, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x24,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x91,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x91, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x91, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0xe2, 0x95, 0x91, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x47, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x91, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x91,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x47, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0xe2, 0x95, 0x91, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x91, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x91,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x91, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x9a, 0xe2, 0x95, 0x90,
+ 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90, 0xe2,
+ 0x95, 0x90, 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x90, 0xe2, 0x95, 0x9d, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x24, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x24, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x42, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x47, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x47, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x0a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
+ 0x2e, 0x2e, 0x2e, 0x2e, 0x2e
+};
+unsigned int maps_map1_txt_len = 4133;
diff --git a/maps/map1.txt b/maps/map1.txt
new file mode 100644
index 0000000..fe3b47a
--- /dev/null
+++ b/maps/map1.txt
@@ -0,0 +1,40 @@
+....................................................................................................
+..................~~~~~~............................................................................
+...................~~~~.............................................................................
+...................................S........~~~~~~~~~...............................................
+........G...................................~~~~~~~~~...............................................
+............................................~~~~~~~~................................................
+............................................~~~~~~.......G..........................................
+.....$..$...........................................................................................
+....................................................................................................
+......$..╔═══════════════╗.........................................$................................
+..$......║...............║..........................................................................
+.........║...............║..........................................................................
+.........║...N...........║..........................................................................
+.........║...........N...║.$............$...........................................................
+.........║...............║..........................................................................
+.........║...............║...............................G..........................................
+.........║...............║...................................................G......................
+.........║...............║..........................................................................
+.........║...............║..........................................................................
+.........╚═════.....═════╝..........................................................................
+....................................................................................................
+....................................................................................................
+....................................................................................................
+....................................................................................................
+........................................$...........................................................
+....................................................................................................
+..............................................................$.....................................
+....................................................................................................
+.............B......................................................................................
+....................................................................................................
+....................................................................................................
+....................................................................................................
+....................................................................................................
+..........................................................................G.........................
+....................................................................................................
+............................................G.......................................................
+....................................................................................................
+....................................................................................................
+....................................................................................................
+.................................................................................................... \ No newline at end of file