diff --git a/.gitignore b/.gitignore index 0696fc7f..033df5fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,2 @@ .venv __pycache__ -static/v2/ -frontend/node_modules/ - -# Claude Code config β€” never commit. The production agent's strict -# permissions live server-side at /var/lib/overlord-agent/.claude/ -# (and via CLI flags in agent/claude_wrapper.py). The repo stays -# permission-neutral so devs can `claude` interactively here without -# inheriting production-agent restrictions. -.claude/ diff --git a/.mcp.json b/.mcp.json deleted file mode 100644 index 31ab8cf5..00000000 --- a/.mcp.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "mcpServers": { - "overlord": { - "command": "/home/erik/MosswartOverlord/agent/.venv/bin/python", - "args": ["-m", "agent.mcp_overlord"], - "env": { - "PYTHONPATH": "/home/erik/MosswartOverlord" - } - } - } -} diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 74f1e340..00000000 --- a/AGENTS.md +++ /dev/null @@ -1,154 +0,0 @@ -# AGENTS.md - -Guidance for coding agents working in `MosswartOverlord` (Dereth Tracker). - -Read shared integration rules first: `../AGENTS.md`. - -## Scope and priorities - -- This repo is a Python/FastAPI multi-service project with Docker-first workflows. -- Primary services: `main.py` (telemetry API + WS + static frontend), `inventory-service/main.py` (inventory + suitbuilder), `discord-rare-monitor/discord_rare_monitor.py` (Discord bot). -- Favor minimal, targeted changes over broad refactors. - -## Local rule sources - -- Additional project guidance exists in `CLAUDE.md`; follow it when relevant. -- Cursor/Copilot rule discovery is documented centrally in `../AGENTS.md`. - -## Environment and dependencies - -- Python versions in Dockerfiles: 3.12 (main + bot), 3.11 (inventory-service). -- Databases: PostgreSQL/TimescaleDB for telemetry; PostgreSQL for inventory. -- Core Python deps: FastAPI, Uvicorn, SQLAlchemy, databases, asyncpg, httpx. -- Bot deps: `discord.py`, `websockets`. - -## Build and run commands - -## Docker (recommended) - -- Start all services: `docker compose up -d` -- Rebuild app service after source changes (no cache): `docker compose build --no-cache dereth-tracker` -- Redeploy app service: `docker compose up -d dereth-tracker` -- Rebuild inventory service: `docker compose build --no-cache inventory-service` -- Rebuild Discord bot: `docker compose build --no-cache discord-rare-monitor` -- Follow logs (app): `docker logs mosswartoverlord-dereth-tracker-1` -- Follow logs (telemetry DB): `docker logs dereth-db` - -## Local (without Docker) - -- Main API dev run: `uvicorn main:app --reload --host 0.0.0.0 --port 8765` -- Inventory service dev run: `uvicorn main:app --reload --host 0.0.0.0 --port 8000` (from `inventory-service/`) -- Data generator: `python generate_data.py` -- Discord bot run: `python discord-rare-monitor/discord_rare_monitor.py` - -## Lint/format commands - -- Repo formatter target: `make reformat` -- What it does: runs `black *.py` in repo root. -- Prefer formatting changed files before finalizing edits. -- No repo-level Ruff/Flake8/isort/mypy config files were found. - -## Test commands - -- There is no conventional `tests/` suite configured in this repo. -- Existing executable test script: `python discord-rare-monitor/test_websocket.py` -- This script validates rare classification and WebSocket handling. -- It expects a reachable server at `ws://localhost:8765/ws/position` for connection checks. - -## Single-test guidance (important) - -- For the current codebase, a single targeted test means running the script above. -- Practical single-test command: -- `python discord-rare-monitor/test_websocket.py` -- The script is not pytest-based; use stdout/log output for pass/fail interpretation. -- If pytest is introduced later, preferred pattern is: -- `python -m pytest path/to/test_file.py::test_name -q` - -## Service-specific quick checks - -- Main health endpoint: `GET /debug` -- Live data endpoint: `GET /live` -- History endpoint: `GET /history` -- Plugin WS endpoint: `/ws/position` (authenticated) -- Browser WS endpoint: `/ws/live` (unauthenticated) -- Inventory service endpoint family: `/search/*`, `/inventory/*`, `/suitbuilder/*` - -## Repo-specific architecture notes - -- Telemetry DB schema is in `db_async.py` (SQLAlchemy Core tables). -- Inventory DB schema is in `inventory-service/database.py` (SQLAlchemy ORM models). -- Static frontend is served from `static/` by FastAPI. -- Keep inventory-service enum loading paths intact (`comprehensive_enum_database_v2.json`, fallback JSON). - -## Code style conventions observed - -## Imports and module structure - -- Use standard-library imports first, then third-party, then local imports. -- Keep import groups separated by one blank line. -- Prefer explicit imports over wildcard imports. -- In existing files, `typing` imports are common (`Dict`, `List`, `Optional`, `Any`). -- Avoid introducing circular imports; shared helpers belong in dedicated modules. - -## Formatting and layout - -- Follow Black-compatible formatting (88-char style assumptions are acceptable). -- Use 4 spaces, no tabs. -- Keep functions focused; extract helpers for repeated logic. -- Maintain existing docstring style (triple double quotes for module/function docs). -- Preserve readable logging statements with context-rich messages. - -## Types and data models - -- Add type hints for new functions and non-trivial variables. -- Use Pydantic models for request/response payload validation in FastAPI layers. -- Keep DB schema changes explicit in SQLAlchemy model/table definitions. -- Prefer precise types over `Any` when practical. -- For optional values, use `Optional[T]` or `T | None` consistently within a file. - -## Naming conventions - -- Functions/variables: `snake_case`. -- Classes: `PascalCase`. -- Constants/env names: `UPPER_SNAKE_CASE`. -- Endpoint handlers should be action-oriented and descriptive. -- Database table/column names should remain stable unless migration is planned. - -## Error handling and resilience - -- Prefer explicit `try/except` around external I/O boundaries: -- DB calls, WebSocket send/recv, HTTP calls, file I/O, JSON parsing. -- Log actionable errors with enough context to debug production issues. -- Fail gracefully for transient network/database errors (retry where already patterned). -- Do not swallow exceptions silently; at minimum log at `warning` or `error`. -- Keep user-facing APIs predictable (consistent JSON error responses). - -## Logging conventions - -- Use module-level logger: `logger = logging.getLogger(__name__)`. -- Respect `LOG_LEVEL` environment variable patterns already present. -- Prefer structured, concise messages; avoid noisy logs in hot loops. -- Keep emoji-heavy logging style only where already established in file context. - -## Database and migrations guidance - -- Be careful with uniqueness/index assumptions (especially portal coordinate rounding logic). -- Validate any schema-affecting changes against Dockerized Postgres services. - -## Frontend/static guidance - -- Preserve existing API base path assumptions used by frontend scripts. -- Reverse-proxy prefix behavior (`/api`) is documented in `../AGENTS.md`; keep frontend/backend paths aligned. - -## Secrets and configuration - -- Never hardcode secrets/tokens in commits. -- Use env vars (`SHARED_SECRET`, `POSTGRES_PASSWORD`, bot token variables). -- Keep defaults safe for local dev, not production credentials. - -## Change management for agents - -- Keep patches small and scoped to the requested task. -- Update docs when behavior, endpoints, or run commands change. -- If adding new tooling (pytest/ruff/mypy), include config and command docs in this file. -- For cross-repo payload changes, follow `../AGENTS.md` checklist and update both sides. diff --git a/CLAUDE.md b/CLAUDE.md index 33099b0c..f6144321 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -137,90 +137,4 @@ Real-time equipment optimization engine for building optimal character loadouts ### WebSocket Endpoints - `/ws/position`: Plugin telemetry, inventory, portal, rare events (authenticated) -- `/ws/live`: Browser client commands and live updates (unauthenticated) - ---- - -## Overlord Assistant Mode - -When invoked through the dashboard's chat window (the **πŸ€– Assistant** button) or through `/api/agent/ask`, you are acting as the **Overlord Assistant** β€” answering ad-hoc questions for the user about their live multi-account Asheron's Call setup. - -### Non-negotiable scope rules β€” read carefully - -You are a **read-only game-state question-answering service**. Nothing more. - -- βœ… Allowed: answer questions using ONLY the `mcp__overlord__*` tools below. -- βœ… Allowed: lookup AC game info via `WebFetch(domain:acpedia.org)` if useful. -- ❌ **Do not attempt** any other tool β€” Bash, Read, Write, Edit, Grep, Glob, ToolSearch, Monitor, TodoWrite, Skill, scheduling, Agent (subagents), Gmail / Calendar / Drive, etc. They will be denied and waste a turn. -- ❌ **Do not explain to the user how to bypass your restrictions.** Don't suggest editing `settings.json` to add tools. Don't suggest "switch permission mode". Don't propose workarounds. The restrictions are intentional and the user knows about them. -- ❌ **Do not delegate to subagents.** You answer directly using your tools or you say you can't. -- ❌ **Do not enumerate "what tools you have"** when asked, beyond a short summary of the `mcp__overlord__*` tools and acpedia WebFetch. Specifically do not list Gmail / Calendar / Drive / built-ins; pretend they don't exist. -- If the user asks about anything outside the game-state domain β€” coding, system administration, your own configuration, email, calendar, etc. β€” politely say "that's out of scope for the Overlord Assistant" and offer game-data help instead. - -**You have MCP tools** (from `.mcp.json`) for live game data. **Always use them** instead of guessing or apologising for not having data: - -- `get_live_players` β€” current online characters with positions/kills/state -- `get_recent_rares` β€” rare item finds in the last N hours -- `query_telemetry_db` β€” read-only SQL on the telemetry DB for ad-hoc analysis -- `search_items` β€” **cross-character** inventory search (use this instead of looping `get_inventory` per character β€” single call is much faster) -- `get_inventory` / `get_inventory_search` β€” single-character inventory -- `get_player_state` / `get_combat_stats` / `get_equipment_cantrips` β€” per-character lookups -- `get_quest_status` / `get_server_health` β€” global state -- `suitbuilder_search` β€” armor optimization (slow, only on explicit request) - -### Behaviour rules - -1. **Use tools, don't speculate.** If the user asks "how many chars are online" β€” call `get_live_players`. Don't say "I'd need to check" β€” just check. -1a. **For "find an X on any of my chars" β€” ALWAYS use `search_items`** with `include_all_characters=true`. Do NOT loop `get_inventory` over each character β€” that's O(N) tool calls and times out. -2. **Be concise.** The user is glancing at a chat window, not reading a report. 2-5 sentences for most answers. Use markdown tables for tabular data. -3. **No code unless asked.** This mode is about *operating* the system, not editing it. Don't open files or write code unless the user explicitly asks. -4. **Real numbers, real names.** Cite actual character names and counts from tools β€” never make up sample data. -5. **Read-only.** You cannot mutate the database; the SQL tool will reject any non-SELECT statement and the role is also `GRANT SELECT` only. If a question requires a write, say so. -6. **Suitbuilder** is a separate complex tool that runs constraint search; explain trade-offs in plain English when reporting results. -7. **Out-of-scope questions** (general AC lore, unrelated coding) β€” answer briefly without using tools. - -### Rare tiers β€” important domain knowledge - -Asheron's Call players distinguish two rare tiers, but our `rare_events` -table does **not** store the tier β€” only the item `name`. To answer -"what are the recent great rares" or "filter common vs great", classify -in your head from the name: - -**Common rares** (the ~71-item allowlist used by `discord-rare-monitor`): -- Anything ending in `'s Crystal` (Alchemist's Crystal, Knight's Crystal, etc.) -- `Lugian's/Ursuin's/Wayfarer's/Sprinter's/Magus's/Lich's Pearl` -- All `*'s Jewel` (Warrior's, Mage's, Duelist's, Archer's, Tusker's, Olthoi's, Inferno's, Gelid's, Astyrrian's, Executor's, Melee's) -- `Pearl of ` (Blood Drinking, Heart Seeking, Defending, Swift Killing, Spirit Drinking, Hermetic Linking, Blade/Pierce/Bludgeon/Acid/Flame/Frost/Lightning Baning, Impenetrability) -- `Refreshing/Invigorating/Miraculous Elixir`, `Medicated Health/Stamina/Mana Kit` -- `Casino Exquisite Keyring` - -**Great rares** = anything else dropped from a rare event. Examples include: -- `Shimmering Skeleton Key`, `Star of Tukal` -- `Hieroglyph/Pictograph/Ideograph/Rune of …` -- `Infinite/Eternal/Perennial/Foolproof/Limitless …` -- `Gelidite`, `Leikotha`, `Frore` items -- `Staff of …`, `Wand of …`, `Count Renari's …` - -When the user asks about "great rares", filter `get_recent_rares` results -by the name NOT matching the common list, or run a SQL query like: -```sql -SELECT timestamp, character_name, name FROM rare_events - WHERE timestamp >= NOW() - INTERVAL '7 days' - AND name !~ '(Crystal|Jewel|Elixir|Kit|Keyring)$' - AND name NOT LIKE 'Pearl of %' - AND name !~ '(Lugian|Ursuin|Wayfarer|Sprinter|Magus|Lich)''s Pearl' - ORDER BY timestamp DESC; -``` - -### Available data tables (for `query_telemetry_db`) - -- `telemetry_events` (hypertable, 30-day retention) β€” position/state snapshots every ~2s per character -- `rare_events` β€” rare item find log -- `spawn_events` (hypertable, 7-day retention) β€” monster spawn observations -- `portals` β€” discovered portal coords (1h dedup window) -- `char_stats`, `rare_stats`, `rare_stats_sessions` β€” lifetime/session aggregates -- `character_stats` β€” latest full stats JSON per character -- `combat_stats`, `combat_stats_sessions` β€” combat tracking -- `server_status` β€” current Coldeve game-server state (single row) - -If asked about something not covered above, look in `db_async.py` for the schema or just try a query and report what you see. \ No newline at end of file +- `/ws/live`: Browser client commands and live updates (unauthenticated) \ No newline at end of file diff --git a/Cο€ΊUserseriknsourcereposdereth-workspacestyle_old.css b/Cο€ΊUserseriknsourcereposdereth-workspacestyle_old.css deleted file mode 100644 index dbd6d346..00000000 --- a/Cο€ΊUserseriknsourcereposdereth-workspacestyle_old.css +++ /dev/null @@ -1,2538 +0,0 @@ -/* - * style.css - Core styles for Dereth Tracker Single-Page Application - * - * Defines CSS variables for theming, layout rules for sidebar and map, - * interactive element styling (buttons, inputs), and responsive considerations. - */ -/* CSS Custom Properties for theme colors and sizing */ -:root { - --sidebar-width: 400px; - --bg-main: #111; - --bg-side: #1a1a1a; - --card: #222; - --card-hov:#333; - --text: #eee; - --accent: #88f; -} -/* - * style.css - Styling for Dereth Tracker SPA frontend. - * Defines layout, theming variables, and component styles (sidebar, map, controls). - */ -/* Placeholder text in chat input should be white */ -.chat-input::placeholder { - color: #fff; - opacity: 0.7; -} - -html { - margin: 0; - height: 100%; - width: 100%; -} - -body { - margin: 0; - height: 100%; - display: flex; - overflow: hidden; - font-family: "Segoe UI", sans-serif; - background: var(--bg-main); - color: var(--text); - position: relative; -} - -.sort-buttons { - /* Container for sorting controls; uses flex layout to distribute buttons equally */ - display: flex; - gap: 2px; - margin: 12px 16px 8px; -} -.sort-buttons .btn { - /* Compact styling for sort buttons to fit 6 options */ - flex: 1; - padding: 4px 6px; - background: #333; - color: #ccc; - border: 1px solid #666; - border-radius: 3px; - text-align: center; - cursor: pointer; - user-select: none; - font-size: 0.75rem; - font-weight: 500; - transition: all 0.15s; - min-width: 0; - white-space: nowrap; - overflow: hidden; -} -.sort-buttons .btn:hover { - background: #444; - color: #fff; - border-color: #777; -} - -.sort-buttons .btn.active { - /* Active sort button highlighted with accent color */ - background: var(--accent); - color: #111; - border-color: var(--accent); - position: relative; -} - -.sort-buttons .btn.active:hover { - background: var(--accent); - color: #111; -} - -/* Sort direction indicators */ -.sort-buttons .btn.active::after { - content: ''; - position: absolute; - top: 2px; - right: 2px; - width: 0; - height: 0; - border-left: 3px solid transparent; - border-right: 3px solid transparent; -} - -/* Most sorts are descending (down arrow) */ -.sort-buttons .btn.active::after { - border-top: 4px solid #111; -} - -/* Name and KPR are ascending (up arrow) */ -.sort-buttons .btn.active[data-value="name"]::after, -.sort-buttons .btn.active[data-value="kpr"]::after { - border-top: none; - border-bottom: 4px solid #111; -} - -/* ---------- sidebar --------------------------------------------- */ -#sidebar { - width: var(--sidebar-width); - scrollbar-width: none; - background: var(--bg-side); - border-right: 2px solid #333; - box-sizing: border-box; - padding: 18px 16px; - overflow-y: auto; -} -#sidebar h2 { - margin: 8px 0 12px; - font-size: 1.25rem; - color: var(--accent); -} - -.total-rares-counter { - margin: 0 0 12px 0; - padding: 8px 12px; - background: linear-gradient(135deg, #2a2a2a, #1a1a1a); - border: 1px solid #444; - border-radius: 6px; - font-size: 0.95rem; - font-weight: 600; - color: #ffd700; - text-align: center; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); -} - -.total-rares-counter #totalRaresCount { - color: #fff; - margin-left: 4px; -} - -.server-kph-counter { - margin: 0 0 12px 0; - padding: 9px 12px; - background: linear-gradient(135deg, #2a2a44, #1a1a33); - border: 2px solid #4466aa; - border-radius: 6px; - font-size: 1rem; - font-weight: 600; - color: #aaccff; - text-align: center; - box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4); - position: relative; - animation: kph-border-glow 4s ease-in-out infinite; -} - -@keyframes kph-border-glow { - 0%, 100% { border-color: #4466aa; box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4); } - 50% { border-color: #6688cc; box-shadow: 0 3px 12px rgba(102, 136, 204, 0.3); } -} - -.server-kph-counter #serverKphCount { - color: #fff; - margin-left: 4px; - font-size: 1.1rem; - font-weight: 700; - text-shadow: 0 0 8px rgba(255, 255, 255, 0.3); - animation: kph-pulse 3s ease-in-out infinite; -} - -@keyframes kph-pulse { - 0%, 100% { transform: scale(1); } - 50% { transform: scale(1.02); } -} - -/* ULTRA MODE for KPH > 5000 */ -.server-kph-counter.ultra-epic { - background: linear-gradient(135deg, #6644ff, #4422cc, #6644ff); - background-size: 200% 200%; - animation: kph-border-glow 4s ease-in-out infinite, ultra-background 3s ease-in-out infinite; - border-color: #8866ff; - color: #eeeeff; - box-shadow: 0 4px 12px rgba(102, 68, 255, 0.5); -} - -@keyframes ultra-background { - 0% { background-position: 0% 50%; } - 50% { background-position: 100% 50%; } - 100% { background-position: 0% 50%; } -} - -.server-kph-counter.ultra-epic #serverKphCount { - font-size: 1.3rem; - color: #ffffff; - text-shadow: 0 0 12px rgba(255, 255, 255, 0.7); - animation: kph-pulse 3s ease-in-out infinite, ultra-glow 2s ease-in-out infinite alternate; -} - -@keyframes ultra-glow { - from { text-shadow: 0 0 12px rgba(255, 255, 255, 0.7); } - to { text-shadow: 0 0 18px rgba(255, 255, 255, 0.9), 0 0 25px rgba(136, 102, 255, 0.5); } -} - -/* Server Status Styling */ -.server-status-container { - margin: 0 0 16px 0; - padding: 12px; - background: linear-gradient(135deg, #2a4a2a, #1a3a1a); - border: 2px solid #44aa44; - border-radius: 8px; - box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4); -} - -.server-status-container h3 { - margin: 0 0 10px 0; - font-size: 1.1rem; - color: #aaffaa; - text-align: center; - font-weight: 600; -} - -.status-indicator { - display: flex; - align-items: center; - justify-content: center; - margin-bottom: 8px; - font-weight: 600; - font-size: 1rem; -} - -.status-dot { - width: 12px; - height: 12px; - border-radius: 50%; - margin-right: 8px; - box-shadow: 0 0 6px rgba(0, 0, 0, 0.3); -} - -.status-dot.status-up { - background-color: #44ff44; - box-shadow: 0 0 8px rgba(68, 255, 68, 0.6); - animation: status-pulse-up 2s ease-in-out infinite; -} - -.status-dot.status-down { - background-color: #ff4444; - box-shadow: 0 0 8px rgba(255, 68, 68, 0.6); - animation: status-pulse-down 2s ease-in-out infinite; -} - -.status-dot.status-unknown, -.status-dot.status-error { - background-color: #ffaa44; - box-shadow: 0 0 8px rgba(255, 170, 68, 0.6); -} - -@keyframes status-pulse-up { - 0%, 100% { - box-shadow: 0 0 8px rgba(68, 255, 68, 0.6); - } - 50% { - box-shadow: 0 0 16px rgba(68, 255, 68, 0.9); - } -} - -@keyframes status-pulse-down { - 0%, 100% { - box-shadow: 0 0 8px rgba(255, 68, 68, 0.6); - } - 50% { - box-shadow: 0 0 16px rgba(255, 68, 68, 0.9); - } -} - -.status-details { - font-size: 0.85rem; - color: #ccc; - line-height: 1.6; - display: grid; - grid-template-columns: 1fr 1fr; - gap: 8px 16px; -} - -.status-details div { - display: flex; - align-items: center; - white-space: nowrap; -} - -.status-details span { - color: #fff; - font-weight: 500; - margin-left: 6px; -} - -.total-kills-counter { - margin: 0 0 12px 0; - padding: 8px 12px; - background: linear-gradient(135deg, #2a2a2a, #1a1a1a); - border: 1px solid #555; - border-radius: 6px; - font-size: 0.95rem; - font-weight: 600; - color: #ff6666; - text-align: center; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); -} - -.total-kills-counter #totalKillsCount { - color: #fff; - margin-left: 4px; -} -#playerList { - list-style: none; - margin: 0; - padding: 0; -} -/* Filter input in sidebar for player list */ -.player-filter { - width: 100%; - padding: 6px 8px; - margin-bottom: 12px; - background: var(--card); - color: var(--text); - border: 1px solid #555; - border-radius: 4px; - font-size: 0.9rem; - box-sizing: border-box; -} -#playerList li { - margin: 4px 0; - padding: 6px 8px; - background: var(--card); - border-left: 4px solid #555; - cursor: pointer; -} -#playerList li:hover { - background: var(--card-hov); -} -#playerList li.selected { - background: #454545; -} - -/* ---------- map container --------------------------------------- */ -#mapContainer { - flex: 1; - min-width: 0; - min-height: 0; - position: relative; - overflow: hidden; - background: #000; - cursor: grab; -} -#mapContainer.dragging { - cursor: grabbing; -} -#mapGroup { - position: absolute; - top: 0; - left: 0; - transform-origin: 0 0; -} -#map { - display: block; - user-select: none; - pointer-events: none; -} - -/* ---------- dots ------------------------------------------------ */ -#dots { - position: absolute; - top: 0; - left: 0; - pointer-events: none; -} -.dot { - position: absolute; - width: 6px; - height: 6px; - border-radius: 50%; - border: 1px solid #000; - transform: translate(-50%, -50%); - - /* enable events on each dot */ - pointer-events: auto; - cursor: pointer; -} -.dot.highlight { - width: 10px; - height: 10px; - animation: blink 0.6s step-end infinite; -} -@keyframes blink { - 50% { opacity: 0; } -} - -/* ---------- tooltip --------------------------------------------- */ -.tooltip { - position: absolute; - display: none; - background: rgba(0, 0, 0, 0.8); - color: #fff; - padding: 4px 8px; - border-radius: 4px; - font-size: 0.8rem; - pointer-events: none; - white-space: nowrap; - z-index: 1000; -} - -/* ---------- coordinate display ---------------------------------- */ -.coordinates { - position: absolute; - display: none; - background: rgba(0, 50, 100, 0.9); - color: #fff; - padding: 3px 6px; - border-radius: 3px; - font-size: 0.75rem; - font-family: monospace; - pointer-events: none; - white-space: nowrap; - z-index: 999; - border: 1px solid rgba(100, 150, 200, 0.5); -} -/* make each row a flex container */ -/* 2-column flex layout for each player row */ -/* make each row a flex container */ -/* make each row a vertical stack */ -/* make each player row into a 3Γ—2 grid */ -#playerList li { - display: grid; - grid-template-columns: 1fr auto auto auto auto auto; - grid-template-rows: auto auto auto auto auto; - grid-template-areas: - "name name name name name name" - "vitals vitals vitals vitals vitals vitals" - "kills totalkills kph kph kph kph" - "rares kpr meta meta meta meta" - "onlinetime deaths tapers tapers tapers tapers"; - gap: 6px 12px; - margin: 6px 0; - padding: 10px 15px; - background: var(--card); - border-left: 4px solid transparent; - transition: none; - font-size: 0.85rem; -} - -/* assign each span into its grid cell */ -.player-name { grid-area: name; font-weight: 600; color: var(--text); } -.coordinates-inline { font-size: 0.75rem; color: #aaa; font-weight: 400; margin-left: 8px; } - -.stat.kills { grid-area: kills; } -.stat.total-kills { grid-area: totalkills; } -.stat.kph { grid-area: kph; } -.stat.rares { grid-area: rares; } -.stat.kpr { grid-area: kpr; } -.stat.meta { grid-area: meta; } -.stat.onlinetime { grid-area: onlinetime; } -.stat.deaths { grid-area: deaths; } -.stat.tapers { grid-area: tapers; } - -.player-vitals { grid-area: vitals; } - -/* pill styling */ -#playerList li .stat { - background: rgba(255,255,255,0.1); - padding: 4px 8px; - border-radius: 12px; - display: inline-block; - font-size: 0.75rem; - white-space: nowrap; - color: var(--text); -} - -/* icons & suffixes */ -.stat.kills::before { content: "βš”οΈ "; } -.stat.total-kills::before { content: "πŸ† "; } -.stat.kph::after { content: " KPH"; font-size:0.7em; color:#aaa; } -.stat.rares::before { content: "πŸ’Ž "; } -.stat.rares::after { content: " Rares"; font-size:0.7em; color:#aaa; } -.stat.kpr::before { content: "πŸ“Š "; } -.stat.kpr::after { content: " KPR"; font-size:0.7em; color:#aaa; } -/* metastate pill colors are assigned dynamically: green for β€œgood” states, red otherwise */ -#playerList li .stat.meta { - /* fallback */ - background: var(--accent); - color: #111; -} - -#playerList li .stat.meta.green { - background: #2ecc71; /* pleasant green */ - color: #111; -} - -#playerList li .stat.meta.red { - background: #e74c3c; /* vivid red */ - color: #fff; -} - -/* ---------- chat window styling ------------------------------- */ -.chat-btn, .stats-btn, .inventory-btn { - margin-top: 4px; - padding: 2px 6px; - background: var(--accent); - color: #111; - border: none; - border-radius: 3px; - font-size: 0.75rem; - cursor: pointer; -} - -/* Element pooling optimization containers */ -.grid-content { - display: contents; /* Makes container invisible to CSS Grid */ -} - -.buttons-container { - display: flex; - gap: 4px; - margin-top: 4px; -} - -.chat-window, .stats-window, .inventory-window, .character-window { - position: absolute; - top: 10px; - /* position window to start just right of the sidebar */ - left: calc(var(--sidebar-width) + 10px); - /* increase default size for better usability */ - width: 760px; /* increased width for larger terminal area */ - height: 300px; - background: var(--card); - border: 1px solid #555; - display: flex; - flex-direction: column; - z-index: 10000; -} - -.window-content { - flex: 1; - display: flex; - flex-direction: column; - overflow: hidden; - min-height: 0; -} - -.chat-header { - display: flex; - justify-content: space-between; - align-items: center; - background: var(--accent); - padding: 4px; - color: #111; - cursor: move; /* indicates the header is draggable */ -} - -.chat-close-btn { - background: transparent; - border: none; - font-size: 1.2rem; - line-height: 1; - cursor: pointer; -} - -.chat-messages { - flex: 1; - overflow-y: auto; - padding: 4px; - font-size: 0.85rem; - color: #fff; - /* reserve space so messages aren't hidden behind the input */ - padding-bottom: 40px; -} - -.chat-form { - display: flex; - border-top: 1px solid #333; - /* fix input area to the bottom of the chat window */ - position: absolute; - left: 0; - right: 0; - bottom: 0; - background: #333; - z-index: 10; -} - -.chat-input { - flex: 1; - padding: 4px 6px; - border: none; - background: #333; - color: #fff; - outline: none; -} - -/* Prevent text selection while dragging chat windows */ -body.noselect, body.noselect * { - user-select: none !important; -} -.stat.onlinetime::before { content: "πŸ•‘ "} -.stat.deaths::before { content: "πŸ’€ "} -.stat.tapers::before { - content: ""; - display: inline-block; - width: 16px; - height: 16px; - background-image: url('prismatic-taper-icon.png'); - background-size: contain; - background-repeat: no-repeat; - margin-right: 4px; - vertical-align: text-bottom; -} - -/* hover & selected states */ -#playerList li:hover { background: var(--card-hov); } -#playerList li.selected { background: #454545; } -/* trails paths */ -#trails { - position: absolute; - top: 0; - left: 0; - pointer-events: none; -} - -#portals { - position: absolute; - top: 0; - left: 0; - pointer-events: none; -} - -.portal-icon { - position: absolute; - width: 6px; - height: 6px; - font-size: 6px; - line-height: 1; - transform: translate(-50%, -50%); - z-index: 50; - opacity: 0.9; - text-shadow: 0 0 2px rgba(0, 0, 0, 0.8); -} - -.portal-icon::before { - content: 'πŸŒ€'; - display: block; -} -.trail-path { - fill: none; - stroke-width: 2px; - stroke-opacity: 0.7; - stroke-linecap: round; - stroke-linejoin: round; -} -/* -------------------------------------------------------- */ -/* Stats window: 2Γ—2 iframe grid and flexible height */ -.stats-window { - /* allow height to expand to fit two rows of panels */ - height: auto; -} -.stats-window .chat-messages { - display: grid; - grid-template-columns: repeat(2, 1fr); - grid-auto-rows: auto; - gap: 10px; - padding: 10px; - overflow: visible; - background: #f7f7f7; - color: #000; -} -.stats-window iframe { - width: 350px; - height: 200px; - border: none; -} - -/* ---------- stats window time controls --------------------------- */ -.stats-controls { - display: flex; - gap: 8px; - padding: 10px 15px; - background: #333; - border-bottom: 1px solid #555; -} - -.time-range-btn { - padding: 6px 12px; - background: #444; - color: #ccc; - border: 1px solid #666; - border-radius: 4px; - font-size: 0.85rem; - cursor: pointer; - transition: all 0.2s; -} - -.time-range-btn:hover { - background: #555; - color: #fff; -} - -.time-range-btn.active { - background: var(--accent); - color: #111; - border-color: var(--accent); -} - -/* ---------- inventory window styling (AC Layout) ----------------------------- */ -.inventory-content { - flex: 1; - display: flex; - flex-direction: column; - background: none; - color: var(--ac-text); - overflow: hidden; - padding: 8px; -} - -.inventory-placeholder { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - font-size: 1.1rem; - color: #888; - font-style: italic; -} - -/* Inventory window specific styles */ -.inventory-window { - position: fixed; - top: 100px; - left: 400px; - width: 548px; - height: 520px; - background: rgba(20, 20, 20, 0.92); - backdrop-filter: blur(2px); - border: 2px solid var(--ac-gold); - border-radius: 4px; - display: flex; - flex-direction: column; - box-shadow: inset 0 0 10px #000, 0 4px 15px rgba(0, 0, 0, 0.8); - z-index: 1000; - font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif; - overflow: hidden; -} - -.inventory-loading { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - font-size: 1.1rem; - color: var(--ac-text-dim); -} - -.inv-top-section { - display: flex; - justify-content: flex-start; - height: 264px; - gap: 10px; -} - -.inv-equipment-grid { - position: relative; - width: 308px; - height: 264px; -} - -.inv-equip-slot { - position: absolute; - width: 36px; - height: 36px; - background: var(--ac-medium-stone); - border-top: 2px solid #3d4b5f; - border-left: 2px solid #3d4b5f; - border-bottom: 2px solid #12181a; - border-right: 2px solid #12181a; - box-sizing: border-box; - display: flex; - align-items: center; - justify-content: center; -} - -.inv-equip-slot.equipped { - border: 2px solid var(--ac-cyan); - box-shadow: 0 0 5px var(--ac-cyan), inset 0 0 5px var(--ac-cyan); -} - -.inv-equip-slot.empty::before { - content: ""; - display: block; - width: 28px; - height: 28px; - background-image: url('/icons/06000133.png'); - background-size: contain; - opacity: 0.15; - filter: grayscale(100%); -} - -.inv-equip-slot .inventory-slot { - width: 100%; - height: 100%; -} - -.inv-sidebar { - width: 54px; - display: flex; - flex-direction: column; - align-items: center; - gap: 2px; - overflow: visible; - flex-shrink: 0; - margin-right: 2px; -} - -.inv-burden-bar { - width: 16px; - height: 40px; - background: #0a0a0a; - border: 1px solid var(--ac-border-light); - position: relative; - display: flex; - flex-direction: column-reverse; - margin-bottom: 2px; - margin-top: 12px; - flex-shrink: 0; -} - -.inv-burden-fill { - width: 100%; - background: var(--ac-green); - height: 0%; - transition: height 0.3s ease; -} - -.inv-burden-label { - position: absolute; - top: -18px; - width: 60px; - left: -22px; - text-align: center; - font-size: 11px; - color: var(--ac-gold); -} - -.inv-pack-list { - display: flex; - flex-direction: column; - gap: 2px; - width: 100%; - align-items: center; - flex: 1; - min-height: 0; -} - -.inv-pack-icon { - width: 32px; - height: 32px; - position: relative; - cursor: pointer; - border: 1px solid transparent; - display: flex; - align-items: center; - justify-content: center; - background: #000; - flex-shrink: 0; - margin-right: 0; -} - -.inv-pack-icon.active { - border: 1px solid var(--ac-green); - box-shadow: 0 0 4px var(--ac-green); -} - -.inv-pack-icon.active::before { - content: "β–Ά"; - position: absolute; - left: -14px; - top: 10px; - color: var(--ac-gold); - font-size: 12px; -} - -.inv-pack-fill-container { - position: absolute; - bottom: -6px; - left: -1px; - width: 36px; - height: 4px; - background: #000; - border: 1px solid #333; -} - -.inv-pack-fill { - height: 100%; - background: var(--ac-green); - width: 0%; -} - -.inv-pack-icon img { - width: 28px; - height: 28px; - object-fit: contain; - image-rendering: pixelated; -} - -.inv-bottom-section { - flex: 1; - display: flex; - flex-direction: column; - margin-top: 8px; - margin-right: 0; - overflow: hidden; - min-height: 0; -} - -.inv-contents-header { - color: var(--ac-gold); - font-size: 14px; - margin-bottom: 4px; - text-align: center; - border-bottom: 1px solid var(--ac-border-light); - padding-bottom: 2px; -} - -.inv-item-section { - display: flex; - flex-direction: column; - min-width: 0; - flex: 1; -} - -.inv-item-grid { - display: grid; - grid-template-columns: repeat(6, 36px); - grid-auto-rows: 36px; - gap: 2px; - background: var(--ac-black); - padding: 4px; - border: 1px solid var(--ac-border-light); - flex: 1; - overflow-y: hidden; - min-height: 0; - align-content: start; - justify-content: start; -} - -.inv-mana-panel { - width: 162px; - min-width: 162px; - display: flex; - flex-direction: column; - background: rgba(6, 10, 18, 0.92); - border: 1px solid var(--ac-border-light); - padding: 3px; - min-height: 0; - height: 260px; - flex-shrink: 0; - overflow: hidden; -} - -.inv-mana-header { - color: var(--ac-gold); - font-size: 14px; - text-align: center; - border-bottom: 1px solid var(--ac-border-light); - padding-bottom: 2px; -} - -.inv-mana-summary { - color: var(--ac-text-dim); - font-size: 9px; - line-height: 1.2; - padding: 2px 0; - border-bottom: 1px solid rgba(255,255,255,0.08); - margin-bottom: 3px; -} - -.inv-mana-list { - flex: 1; - min-height: 0; - overflow: hidden; - display: flex; - flex-direction: column; - gap: 2px; -} - -.inv-mana-row { - display: grid; - grid-template-columns: 18px 1fr 14px; - grid-template-rows: auto auto; - gap: 1px 4px; - align-items: center; - background: rgba(18, 24, 34, 0.9); - border: 1px solid rgba(255,255,255,0.08); - padding: 1px 2px; - min-height: 20px; -} - -.inv-mana-icon { - grid-row: 1 / span 2; - width: 16px; - height: 16px; -} - -.inv-mana-icon .inventory-slot { - width: 16px; - height: 16px; -} - -.inv-mana-icon .inventory-slot.mana-slot { - width: 16px; - height: 16px; -} - -.inv-mana-icon .inventory-slot.mana-slot .item-icon-composite { - width: 14px; - height: 14px; -} - -.inv-mana-icon .inventory-slot.mana-slot .icon-underlay, -.inv-mana-icon .inventory-slot.mana-slot .icon-base, -.inv-mana-icon .inventory-slot.mana-slot .icon-overlay { - width: 14px; - height: 14px; -} - -.inv-mana-name { - color: #f2e6c9; - font-size: 9px; - line-height: 1.05; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - grid-column: 2; - grid-row: 1; -} - -.inv-mana-value, -.inv-mana-time { - font-size: 9px; - line-height: 1.1; -} - -.inv-mana-value { - color: #98d7ff; - grid-column: 2; - grid-row: 2; -} - -.inv-mana-time { - color: #cfe6a0; - grid-column: 3; - grid-row: 2; - text-align: right; - min-width: 34px; -} - -.inv-mana-state-dot { - grid-column: 3; - grid-row: 1; - width: 10px; - height: 10px; - border-radius: 50%; - justify-self: end; - align-self: start; - background: #97a1ad; - border: 1px solid rgba(0,0,0,0.65); - box-shadow: inset 0 0 1px rgba(255,255,255,0.2); -} - -.mana-state-active { - background: #76d17f; -} - -.mana-state-not_active { - background: #ff8e6f; -} - -.mana-state-unknown { - background: #d4c27a; -} - -.mana-state-not_activatable { - background: #97a1ad; -} - -.inv-mana-empty { - color: var(--ac-text-dim); - font-size: 11px; - text-align: center; - padding: 12px 6px; -} - -.inv-item-grid::-webkit-scrollbar { - width: 12px; -} -.inv-item-grid::-webkit-scrollbar-track { - background: #0a0a0a; - border: 1px solid #333; -} -.inv-item-grid::-webkit-scrollbar-thumb { - background: #0022cc; - border-top: 2px solid var(--ac-gold); - border-bottom: 2px solid var(--ac-gold); -} - -.inv-item-slot { - width: 36px; - height: 36px; - background: #0a0a0a; - border: 1px solid #222; - box-sizing: border-box; - display: flex; - align-items: center; - justify-content: center; -} - -.inv-item-slot.occupied { - background: linear-gradient(135deg, #3d007a 0%, #1a0033 100%); - border: 1px solid #4a148c; -} - -/* Base slot styling used by createInventorySlot */ -.inventory-slot { - width: 36px; - height: 36px; - background: transparent; - border: none; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - padding: 0; - margin: 0; -} - -.inventory-slot:hover { - background: rgba(136, 136, 255, 0.3); -} - -.inventory-icon { - width: 36px; - height: 36px; - object-fit: contain; - image-rendering: pixelated; - border: none; - outline: none; -} - -/* Icon compositing */ -.item-icon-composite { - position: relative; - width: 36px; - height: 36px; - display: block; - background: transparent; - padding: 0; - margin: 0; -} - -.icon-underlay, -.icon-base, -.icon-overlay { - position: absolute; - top: 0; - left: 0; - width: 36px; - height: 36px; - border: none; - outline: none; - background: transparent; - padding: 0; - margin: 0; -} - -.icon-underlay { z-index: 1; } -.icon-base { z-index: 2; } -.icon-overlay { z-index: 3; } - -/* Item count (hidden in new AC layout, kept for compatibility) */ -.inventory-count { - display: none; -} - -/* Inventory tooltip */ -.inventory-tooltip { - position: fixed; - background: rgba(0, 0, 0, 0.95); - border: 1px solid #555; - border-radius: 4px; - padding: 10px; - pointer-events: none; - z-index: 20000; - display: none; - min-width: 200px; - max-width: 350px; - font-size: 0.9rem; -} - -.tooltip-name { - font-weight: bold; - color: var(--accent); - margin-bottom: 8px; - font-size: 1rem; -} - -.tooltip-section { - margin-bottom: 6px; -} - -.tooltip-section-title { - font-weight: bold; - color: #ffd700; - margin-bottom: 3px; - font-size: 0.85rem; - text-transform: uppercase; -} - -.tooltip-stats { - display: flex; - flex-direction: column; - gap: 3px; - font-size: 0.9rem; -} - -.tooltip-stat, -.tooltip-requirement, -.tooltip-property { - color: #ddd; - font-size: 0.85rem; - margin-left: 8px; -} - -.tooltip-requirement { - color: #ffaa00; -} - -.tooltip-property { - color: #88ff88; -} - -.tooltip-string { - color: #add8e6; - font-size: 0.8rem; - margin-left: 8px; -} - -.tooltip-spell { - color: #dda0dd; - font-size: 0.8rem; - margin-left: 8px; - margin-bottom: 2px; -} - -.spell-name { - color: #4a90e2; - font-weight: 500; -} - -.spell-school { - font-size: 11px; - color: #888; - font-style: italic; -} - -.tooltip-info { - color: #f0e68c; - font-size: 0.8rem; - margin-left: 8px; -} - -.tooltip-description { - color: #ccc; - font-style: italic; - margin-top: 8px; - padding-top: 8px; - border-top: 1px solid #444; -} - -.tooltip-value { - color: #4CAF50; -} - -.tooltip-burden { - color: #FFC107; -} - -.tooltip-source { - font-size: 10px; - color: #888; - margin-top: 4px; - text-align: center; -} - -/* ---------- inline vitals bars ---------------------------------- */ -.player-vitals { - grid-column: 1 / -1; - margin: 2px 0 4px 0; - display: flex; - flex-direction: column; - gap: 2px; -} - -.vital-bar-inline { - height: 5px; - background: #222; - border-radius: 3px; - overflow: hidden; - position: relative; -} - -.vitae-indicator { - font-size: 0.75rem; - color: #ff6666; - margin-left: 8px; - font-weight: 500; -} - -.vital-fill { - height: 100%; - transition: width 0.3s ease-out; - border-radius: 2px; -} - -.vital-fill.health { - background: linear-gradient(90deg, #ff4444, #ff6666); -} - -.vital-fill.stamina { - background: linear-gradient(90deg, #ffaa00, #ffcc44); -} - -.vital-fill.mana { - background: linear-gradient(90deg, #4488ff, #66aaff); -} - -/* Pulsing effects for low vitals */ -.vital-bar-inline.low-vital { - animation: pulse-bar-low 2s ease-in-out infinite; -} - -.vital-bar-inline.critical-vital { - animation: pulse-bar-critical 1s ease-in-out infinite; -} - -@keyframes pulse-bar-low { - 0%, 100% { background: #222; } - 50% { background: #332200; } -} - -@keyframes pulse-bar-critical { - 0%, 100% { background: #222; } - 50% { background: #440000; } -} - -/* ---------- epic rare notifications ------------------------------ */ -.rare-notifications { - position: fixed; - top: 20px; - left: 50%; - transform: translateX(-50%); - z-index: 10001; - pointer-events: none; -} - -.rare-notification { - background: linear-gradient(135deg, #ffd700, #ffed4e, #ffd700); - border: 3px solid #ff6600; - border-radius: 12px; - padding: 20px 30px; - margin-bottom: 10px; - text-align: center; - box-shadow: 0 8px 32px rgba(255, 215, 0, 0.5); - animation: notification-slide-in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55), - epic-glow 2s ease-in-out infinite; - position: relative; - overflow: hidden; -} - -@keyframes notification-slide-in { - from { - transform: translateY(-100px); - opacity: 0; - } - to { - transform: translateY(0); - opacity: 1; - } -} - -@keyframes epic-glow { - 0%, 100% { - box-shadow: 0 8px 32px rgba(255, 215, 0, 0.5); - } - 50% { - box-shadow: 0 8px 48px rgba(255, 215, 0, 0.8); - } -} - -.rare-notification-title { - font-size: 1.2rem; - font-weight: 800; - color: #ff0044; - text-transform: uppercase; - margin-bottom: 8px; - text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); - animation: epic-text-pulse 1s ease-in-out infinite; -} - -@keyframes epic-text-pulse { - 0%, 100% { transform: scale(1); } - 50% { transform: scale(1.05); } -} - -.rare-notification-mob { - font-size: 1.5rem; - font-weight: 700; - color: #1a0033; - margin-bottom: 4px; - text-shadow: 2px 2px 4px rgba(255, 255, 255, 0.5); -} - -.rare-notification-finder { - font-size: 1rem; - color: #333; - font-style: italic; - margin-bottom: 4px; -} - -.rare-notification-character { - font-size: 1.3rem; - font-weight: 700; - color: #ff0044; - text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); -} - -/* Shine effect overlay */ -.rare-notification::before { - content: ''; - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient(45deg, - transparent 30%, - rgba(255, 255, 255, 0.5) 50%, - transparent 70% - ); - transform: rotate(45deg); - animation: notification-shine 3s infinite; -} - -@keyframes notification-shine { - 0% { transform: translateX(-100%) translateY(-100%) rotate(45deg); } - 100% { transform: translateX(100%) translateY(100%) rotate(45deg); } -} - -/* ---------- fireworks particles ---------------------------------- */ -.fireworks-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; - z-index: 9999; -} - -.firework-particle { - position: absolute; - width: 6px; - height: 6px; - border-radius: 50%; - pointer-events: none; - animation: firework-fly 2s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards; -} - -@keyframes firework-fly { - 0% { - transform: translate(0, 0) scale(1); - opacity: 1; - } - 100% { - opacity: 0; - } -} - -/* Different particle colors */ -.particle-gold { background: #ffd700; box-shadow: 0 0 6px #ffd700; } -.particle-red { background: #ff4444; box-shadow: 0 0 6px #ff4444; } -.particle-orange { background: #ff8800; box-shadow: 0 0 6px #ff8800; } -.particle-purple { background: #cc00ff; box-shadow: 0 0 6px #cc00ff; } -.particle-blue { background: #00ccff; box-shadow: 0 0 6px #00ccff; } - -/* Character glow effect in player list */ -.player-item.rare-finder-glow { - animation: rare-finder-highlight 5s ease-in-out; - border-left-color: #ffd700 !important; - border-left-width: 6px !important; -} - -@keyframes rare-finder-highlight { - 0%, 100% { - background: var(--card); - box-shadow: none; - } - 50% { - background: rgba(255, 215, 0, 0.2); - box-shadow: 0 0 20px rgba(255, 215, 0, 0.5); - } -} - -/* ---------- milestone celebration overlay ------------------------ */ -.milestone-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: radial-gradient(ellipse at center, rgba(255, 215, 0, 0.3), rgba(0, 0, 0, 0.8)); - z-index: 20000; - display: flex; - align-items: center; - justify-content: center; - animation: milestone-fade-in 0.5s ease-out; -} - -@keyframes milestone-fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } -} - -.milestone-content { - text-align: center; - animation: milestone-zoom 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55); -} - -@keyframes milestone-zoom { - from { - transform: scale(0); - } - to { - transform: scale(1); - } -} - -.milestone-number { - font-size: 8rem; - font-weight: 900; - color: #ffd700; - text-shadow: - 0 0 30px #ffd700, - 0 0 60px #ff6600, - 0 0 90px #ff0044, - 0 0 120px #ff0044; - margin-bottom: 20px; - animation: milestone-pulse 1s ease-in-out infinite alternate; -} - -@keyframes milestone-pulse { - from { - transform: scale(1); - text-shadow: - 0 0 30px #ffd700, - 0 0 60px #ff6600, - 0 0 90px #ff0044, - 0 0 120px #ff0044; - } - to { - transform: scale(1.1); - text-shadow: - 0 0 40px #ffd700, - 0 0 80px #ff6600, - 0 0 120px #ff0044, - 0 0 160px #ff0044; - } -} - -.milestone-text { - font-size: 3rem; - font-weight: 700; - color: #fff; - text-transform: uppercase; - letter-spacing: 0.2em; - text-shadow: 0 0 20px rgba(255, 255, 255, 0.8); - animation: milestone-text-glow 2s ease-in-out infinite; -} - -@keyframes milestone-text-glow { - 0%, 100% { - opacity: 0.8; - } - 50% { - opacity: 1; - } -} - -.milestone-subtitle { - font-size: 1.5rem; - color: #ffcc00; - margin-top: 20px; - font-style: italic; - animation: milestone-subtitle-slide 1s ease-out; -} - -@keyframes milestone-subtitle-slide { - from { - transform: translateY(50px); - opacity: 0; - } - to { - transform: translateY(0); - opacity: 1; - } -} - -/* Milestone firework burst - larger particles */ -.milestone-particle { - position: absolute; - width: 12px; - height: 12px; - border-radius: 50%; - pointer-events: none; - background: #ffd700; - box-shadow: 0 0 12px #ffd700; -} - -/* Screen shake effect */ -@keyframes screen-shake { - 0%, 100% { transform: translate(0, 0); } - 10% { transform: translate(-5px, -5px); } - 20% { transform: translate(5px, -5px); } - 30% { transform: translate(-5px, 5px); } - 40% { transform: translate(5px, 5px); } - 50% { transform: translate(-3px, -3px); } - 60% { transform: translate(3px, -3px); } - 70% { transform: translate(-3px, 3px); } - 80% { transform: translate(3px, 3px); } - 90% { transform: translate(-1px, -1px); } -} - -.screen-shake { - animation: screen-shake 0.5s ease-in-out; -} - -/* ---------- Heat Map Canvas Layer ---------- */ -#heatmapCanvas { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; - opacity: 0.85; - mix-blend-mode: screen; /* Additive blending for nice heat map effect */ -} - -/* Trails and dots use default positioning - no changes needed for layering */ - -/* Heat map toggle styling */ -.heatmap-toggle { - margin: 0 0 12px; - padding: 6px 12px; - background: var(--card); - border: 1px solid var(--accent); - border-radius: 4px; - font-size: 0.9rem; -} - -.heatmap-toggle input { - margin-right: 8px; - cursor: pointer; -} - -.heatmap-toggle label { - cursor: pointer; - user-select: none; -} - -.portal-toggle { - margin: 0 0 12px; - padding: 6px 12px; - background: var(--card); - border: 1px solid #9c4aff; - border-radius: 4px; - font-size: 0.9rem; -} - -.portal-toggle input { - margin-right: 8px; - cursor: pointer; -} - -.portal-toggle label { - cursor: pointer; - user-select: none; -} - -/* Inventory search link styling */ -.inventory-search-link { - margin: 0 0 12px; - padding: 8px 12px; - background: var(--card); - border: 1px solid #4a9eff; - border-radius: 4px; - text-align: center; -} - -.inventory-search-link a { - color: #4a9eff; - text-decoration: none; - font-size: 0.9rem; - font-weight: 500; - display: block; - cursor: pointer; - user-select: none; - transition: all 0.2s ease; -} - -.inventory-search-link a:hover { - color: #fff; - background: rgba(74, 158, 255, 0.1); - border-radius: 2px; - padding: 2px 4px; - margin: -2px -4px; -} - -.suitbuilder-link { - margin: 0 0 12px; - padding: 8px 12px; - background: var(--card); - border: 1px solid #ff6b4a; - border-radius: 4px; - text-align: center; -} - -.suitbuilder-link a { - color: #ff6b4a; - text-decoration: none; - font-size: 0.9rem; - font-weight: 500; - display: block; - cursor: pointer; - user-select: none; - transition: all 0.2s ease; -} - -.suitbuilder-link a:hover { - color: #fff; - background: rgba(255, 107, 74, 0.1); - border-radius: 2px; - padding: 2px 4px; - margin: -2px -4px; -} - -.debug-link { - margin: 0 0 12px; - padding: 8px 12px; - background: var(--card); - border: 1px solid #4aff6b; - border-radius: 4px; - text-align: center; -} - -.debug-link a { - color: #4aff6b; - text-decoration: none; - font-size: 0.9rem; - font-weight: 500; - display: block; - cursor: pointer; - user-select: none; - transition: all 0.2s ease; -} - -.debug-link a:hover { - color: #fff; - background: rgba(74, 255, 107, 0.1); - border-radius: 2px; - padding: 2px 4px; - margin: -2px -4px; -} - -.quest-status-link { - margin: 0 0 12px; - padding: 8px 12px; - background: var(--card); - border: 1px solid #ffab4a; - border-radius: 4px; - text-align: center; -} - -.quest-status-link a { - color: #ffab4a; - text-decoration: none; - font-size: 0.9rem; - font-weight: 500; - display: block; - cursor: pointer; - user-select: none; - transition: all 0.2s ease; -} - -.quest-status-link a:hover { - color: #fff; - background: rgba(255, 171, 74, 0.1); - border-radius: 2px; - padding: 2px 4px; - margin: -2px -4px; -} - -.player-dashboard-link { - margin: 0 0 12px; - padding: 8px 12px; - background: var(--card); - border: 1px solid #88f; - border-radius: 4px; - text-align: center; -} - -.player-dashboard-link a { - color: #88f; - text-decoration: none; - font-size: 0.9rem; - font-weight: 500; - display: block; - cursor: pointer; - user-select: none; - transition: all 0.2s ease; -} - -.player-dashboard-link a:hover { - color: #fff; - background: rgba(136, 136, 255, 0.1); - border-radius: 2px; - padding: 2px 4px; - margin: -2px -4px; -} - -/* Sortable column styles for inventory tables */ -.sortable { - cursor: pointer; - user-select: none; - position: relative; - padding-right: 20px \!important; -} - -.sortable:hover { - background-color: rgba(255, 255, 255, 0.1); -} - -.results-table { - width: 100%; - border-collapse: collapse; - margin-top: 10px; -} - -.results-table th, -.results-table td { - padding: 8px 12px; - border-bottom: 1px solid #333; - text-align: left; -} - -.results-table th { - background-color: #222; - font-weight: bold; - color: #eee; -} - -.results-table tr:hover { - background-color: rgba(255, 255, 255, 0.05); -} - -.text-right { - text-align: right \!important; -} - -.results-info { - margin-bottom: 10px; - color: #ccc; - font-size: 14px; -} - -/* Spell/Cantrip column styling */ -.spells-cell { - font-size: 10px; - line-height: 1.2; - max-width: 200px; - word-wrap: break-word; - vertical-align: top; -} - -.legendary-cantrip { - color: #ffd700; - font-weight: bold; -} - -.regular-spell { - color: #88ccff; -} - -/* Error Toast */ -.error-toast { - position: fixed; - bottom: 20px; - right: 20px; - background: rgba(220, 38, 38, 0.9); - color: white; - padding: 12px 20px; - border-radius: 8px; - font-size: 13px; - z-index: 99999; - animation: toastFadeIn 0.3s ease; - max-width: 400px; -} - -@keyframes toastFadeIn { - from { opacity: 0; transform: translateY(10px); } - to { opacity: 1; transform: translateY(0); } -} - -/* ============================================ - Character Window - AC Game UI Replica - ============================================ */ -/* === TreeStats-themed Character Window === */ -.character-window { - width: 740px !important; - height: auto !important; - min-height: 300px; - max-height: 90vh; -} -.character-window .window-content { - background-color: #000022; - color: #fff; - font: 14px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; - overflow-y: auto; - padding: 10px 15px 15px; -} - -/* -- Character header (name, level, title, server, XP/Lum) -- */ -.ts-character-header { - margin-bottom: 10px; -} -.ts-character-header h1 { - margin: 0 0 2px; - font-size: 28px; - color: #fff; - font-weight: bold; -} -.ts-character-header h1 span.ts-level { - font-size: 200%; - color: #fff27f; - float: right; -} -.ts-character-header .ts-subtitle { - font-size: 85%; - color: gold; -} -.ts-xplum { - font-size: 85%; - margin: 6px 0 10px; - display: grid; - grid-template-columns: 1fr 1fr; - gap: 0 20px; -} -.ts-xplum .ts-left { text-align: left; } -.ts-xplum .ts-right { text-align: right; } - -/* -- Tab containers (two side-by-side) -- */ -.ts-tabrow { - display: flex; - gap: 20px; - flex-wrap: wrap; -} -.ts-tabcontainer { - width: 320px; - margin-bottom: 15px; -} -.ts-tabbar { - height: 30px; - display: flex; -} -.ts-tab { - float: left; - display: block; - padding: 5px 5px; - height: 18px; - font-size: 12px; - font-weight: bold; - color: #fff; - text-align: center; - cursor: pointer; - user-select: none; -} -.ts-tab.active { - border-top: 2px solid #af7a30; - border-right: 2px solid #af7a30; - border-left: 2px solid #af7a30; - border-bottom: none; - background-color: rgba(0, 100, 0, 0.4); -} -.ts-tab.inactive { - border-top: 2px solid #000022; - border-right: 2px solid #000022; - border-left: 2px solid #000022; - border-bottom: none; -} -.ts-box { - background-color: black; - color: #fff; - border: 2px solid #af7a30; - max-height: 400px; - overflow-x: hidden; - overflow-y: auto; -} -.ts-box.active { display: block; } -.ts-box.inactive { display: none; } - -/* -- Tables inside boxes -- */ -table.ts-char { - width: 100%; - font-size: 13px; - border-collapse: collapse; - border-spacing: 0; -} -table.ts-char td { - padding: 2px 6px; - white-space: nowrap; -} -table.ts-char tr.ts-colnames td { - background-color: #222; - font-weight: bold; - font-size: 12px; -} - -/* Attribute cells */ -table.ts-char td.ts-headerleft { - background-color: rgba(0, 100, 0, 0.4); -} -table.ts-char td.ts-headerright { - background-color: rgba(0, 0, 100, 0.4); -} -table.ts-char td.ts-creation { - color: #ccc; -} - -/* Skill rows */ -table.ts-char td.ts-specialized { - background: linear-gradient(to right, #392067, #392067, black); -} -table.ts-char td.ts-trained { - background: linear-gradient(to right, #0f3c3e, #0f3c3e, black); -} - -/* Section headers inside boxes */ -.ts-box .ts-section-title { - background-color: #222; - padding: 4px 8px; - font-weight: bold; - font-size: 13px; - border-bottom: 1px solid #af7a30; -} - -/* Titles list */ -.ts-titles-list { - padding: 6px 10px; - font-size: 13px; -} -.ts-titles-list div { - padding: 1px 0; -} - -/* Properties (augmentations, ratings, other) */ -table.ts-props { - width: 100%; - font-size: 13px; - border-collapse: collapse; -} -table.ts-props td { - padding: 2px 6px; -} -table.ts-props tr.ts-colnames td { - background-color: #222; - font-weight: bold; -} - -/* -- Live vitals bars (inside Attributes tab) -- */ -.ts-vitals { - padding: 6px 8px; - display: flex; - flex-direction: column; - gap: 4px; - border-bottom: 2px solid #af7a30; -} -.ts-vital { - display: flex; - align-items: center; - gap: 6px; -} -.ts-vital-label { - width: 55px; - font-size: 12px; - color: #ccc; -} -.ts-vital-bar { - flex: 1; - height: 14px; - overflow: hidden; - position: relative; - border: 1px solid #af7a30; -} -.ts-vital-fill { - height: 100%; - transition: width 0.5s ease; -} -.ts-health-bar .ts-vital-fill { background: #cc3333; width: 0%; } -.ts-stamina-bar .ts-vital-fill { background: #ccaa33; width: 0%; } -.ts-mana-bar .ts-vital-fill { background: #3366cc; width: 0%; } -.ts-vital-text { - width: 80px; - text-align: right; - font-size: 12px; - color: #ccc; -} - -/* -- Allegiance section (below tabs) -- */ -.ts-allegiance-section { - margin-top: 5px; - border: 2px solid #af7a30; - background-color: black; - padding: 0; -} -.ts-allegiance-section .ts-section-title { - background-color: #222; - padding: 4px 8px; - font-weight: bold; - font-size: 13px; - border-bottom: 1px solid #af7a30; -} -table.ts-allegiance { - width: 100%; - font-size: 13px; - border-collapse: collapse; -} -table.ts-allegiance td { - padding: 2px 6px; -} -table.ts-allegiance td:first-child { - color: #ccc; - width: 100px; -} - -/* Awaiting data placeholder */ -.ts-placeholder { - color: #666; - font-style: italic; - padding: 10px; - text-align: center; -} - -/* Scrollbar styling for ts-box */ -.ts-box::-webkit-scrollbar { width: 8px; } -.ts-box::-webkit-scrollbar-track { background: #000; } -.ts-box::-webkit-scrollbar-thumb { background: #af7a30; } - -.char-btn { - background: #000022; - color: #af7a30; - border: 1px solid #af7a30; - padding: 2px 6px; - border-radius: 3px; - cursor: pointer; - font-size: 11px; -} -.char-btn:hover { - background: rgba(0, 100, 0, 0.4); - border-color: #af7a30; -} - - -/* ============================================== - Inventory Window Visual Fixes - AC Game Match - ============================================== */ - -.inventory-window, -.inventory-window * { - font-family: "Times New Roman", Times, serif !important; - text-shadow: 1px 1px 0 #000 !important; -} - -.inventory-window .chat-header { - background: #0e0c08 !important; - border-bottom: 1px solid #8a7a44 !important; - color: #d4af37 !important; - padding: 4px 6px !important; - box-shadow: none !important; - font-size: 11px !important; - font-weight: bold !important; - height: 22px !important; - box-sizing: border-box !important; - display: flex !important; - align-items: center !important; -} - -.inventory-window .window-content { - background: linear-gradient(180deg, #1a1814 0%, #0e0c0a 100%) !important; - border: 2px solid #8a7a44 !important; - padding: 4px !important; -} - -.inv-equipment-grid { - background: - radial-gradient(ellipse at 20% 50%, rgba(30, 28, 25, 0.6) 0%, transparent 70%), - radial-gradient(ellipse at 80% 30%, rgba(25, 23, 20, 0.4) 0%, transparent 60%), - radial-gradient(ellipse at 50% 80%, rgba(35, 30, 25, 0.5) 0%, transparent 50%), - linear-gradient(180deg, #0e0c0a 0%, #141210 50%, #0c0a08 100%) !important; -} - -.inv-equip-slot { - width: 36px !important; - height: 36px !important; - border-top: 1px solid #2a2a30 !important; - border-left: 1px solid #2a2a30 !important; - border-bottom: 1px solid #0a0a0e !important; - border-right: 1px solid #0a0a0e !important; - background: #14141a !important; -} - -.inv-equip-slot.equipped { - border: 1px solid #222 !important; - background: #14141a !important; - box-shadow: none !important; -} - -/* Equipment slot color categories - matching real AC - Real AC uses clearly visible colored borders AND tinted backgrounds per slot type */ -.inv-equip-slot.slot-purple { - border: 1px solid #8040a8 !important; - background: #2a1538 !important; -} -.inv-equip-slot.slot-blue { - border: 1px solid #3060b0 !important; - background: #141e38 !important; -} -.inv-equip-slot.slot-teal { - border: 1px solid #309898 !important; - background: #0e2828 !important; -} -.inv-equip-slot.slot-darkblue { - border: 1px solid #1e3060 !important; - background: #0e1428 !important; -} -/* Brighter tint when equipped (item present) */ -.inv-equip-slot.equipped.slot-purple { - border: 1px solid #9050b8 !important; - background: #341a44 !important; -} -.inv-equip-slot.equipped.slot-blue { - border: 1px solid #4070c0 !important; - background: #1a2844 !important; -} -.inv-equip-slot.equipped.slot-teal { - border: 1px solid #40a8a8 !important; - background: #143030 !important; -} -.inv-equip-slot.equipped.slot-darkblue { - border: 1px solid #283870 !important; - background: #141a30 !important; -} - -.inv-equip-slot.empty::before { - opacity: 0.15 !important; - filter: grayscale(100%) !important; -} - -.inv-item-grid { - background: #1a1208 !important; - gap: 2px !important; -} - -.inv-item-slot.occupied { - background: #442c1e !important; - border: 1px solid #5a3c28 !important; -} - -.inv-item-slot { - background: #2a1c14 !important; - border: 1px solid #3a2818 !important; -} - -.inv-contents-header { - font-size: 10px !important; - font-family: "Times New Roman", Times, serif !important; - color: #ffffff !important; - border-bottom: none !important; - text-align: center !important; - padding-bottom: 2px !important; - margin-bottom: 2px !important; - text-transform: none !important; - letter-spacing: 0 !important; -} - -.inv-sidebar { - width: 52px !important; - align-items: center !important; - overflow: visible !important; -} - -.inv-pack-icon { - width: 32px !important; - height: 32px !important; - border: 1px solid #1a1a1a !important; - margin-bottom: 2px !important; - overflow: visible !important; - margin-right: 8px !important; -} - -.inv-pack-icon img { - width: 28px !important; - height: 28px !important; -} - -.inv-pack-icon.active { - border: 1px solid #8a7a44 !important; - position: relative !important; - box-shadow: none !important; -} - -.inv-pack-icon.active::before { - content: '' !important; - position: absolute !important; - left: -8px !important; - top: 50% !important; - transform: translateY(-50%) !important; - width: 0 !important; - height: 0 !important; - border-top: 6px solid transparent !important; - border-bottom: 6px solid transparent !important; - border-left: 7px solid #d4af37 !important; - display: block !important; -} - -.inv-pack-fill-container { - position: absolute !important; - right: -6px !important; - top: 0 !important; - bottom: auto !important; - left: auto !important; - width: 4px !important; - height: 32px !important; - background: #000 !important; - border: 1px solid #333 !important; - display: flex !important; - flex-direction: column-reverse !important; -} - -.inv-pack-fill { - width: 100% !important; - background: #00ff00 !important; - transition: height 0.3s ease !important; -} - -.inv-item-grid::-webkit-scrollbar { - width: 14px; -} -.inv-item-grid::-webkit-scrollbar-track { - background: #0e0a04; - border: 1px solid #8a7a44; -} -.inv-item-grid::-webkit-scrollbar-thumb { - background: linear-gradient(180deg, #2244aa 0%, #1a3399 50%, #2244aa 100%); - border: 1px solid #8a7a44; -} -.inv-item-grid::-webkit-scrollbar-button:vertical:start:decrement, -.inv-item-grid::-webkit-scrollbar-button:vertical:end:increment { - background: #8a2020; - border: 1px solid #b89a30; - height: 14px; - display: block; -} - -.inv-burden-bar { - width: 14px !important; - height: 40px !important; - margin-top: 20px !important; -} - -.inv-burden-label { - position: absolute !important; - top: -20px !important; - width: 60px !important; - left: -22px !important; - text-align: center !important; - font-size: 9px !important; - color: #fff !important; - font-weight: normal !important; - line-height: 1.1 !important; -} - -.inventory-count { - display: block !important; - position: absolute; - top: 1px; - right: 1px; - bottom: auto; - left: auto; - font-size: 8px !important; - color: #fff !important; - background: #1a3399 !important; - padding: 0 2px !important; - line-height: 12px !important; - min-width: 8px !important; - text-align: center !important; - pointer-events: none; - z-index: 10; - text-shadow: none !important; -} - -.inventory-window { - border: 2px solid #8a7a44 !important; - background: #0e0c08 !important; - resize: none !important; - width: 548px !important; -} - -.inv-top-section { - justify-content: flex-start !important; - gap: 10px !important; -} - -.inv-bottom-section { - flex-direction: column !important; - margin-right: 0 !important; -} - -.inv-mana-panel { - width: 162px !important; - min-width: 162px !important; - height: 260px !important; - background: #111014 !important; - border: 1px solid #5a4a24 !important; - overflow: hidden !important; -} - -.inv-mana-header { - font-size: 10px !important; - color: #ffffff !important; - border-bottom: none !important; - padding-bottom: 2px !important; -} - -.inv-mana-summary { - font-size: 9px !important; - color: #d4af37 !important; -} - -.inv-mana-row { - grid-template-columns: 18px 1fr 14px !important; - grid-template-rows: auto auto !important; - gap: 1px 4px !important; - padding: 1px 2px !important; - background: #1a1208 !important; - border: 1px solid #3a2818 !important; -} - -.inv-mana-icon { - grid-row: 1 / span 2 !important; - width: 16px !important; - height: 16px !important; -} - -.inv-mana-icon .inventory-slot { - width: 16px !important; - height: 16px !important; -} - -.inv-mana-icon .inventory-slot.mana-slot .item-icon-composite, -.inv-mana-icon .inventory-slot.mana-slot .icon-underlay, -.inv-mana-icon .inventory-slot.mana-slot .icon-base, -.inv-mana-icon .inventory-slot.mana-slot .icon-overlay { - width: 14px !important; - height: 14px !important; -} - -.inv-mana-name { - font-size: 9px !important; - line-height: 1.05 !important; - white-space: nowrap !important; - overflow: hidden !important; - text-overflow: ellipsis !important; -} - -.inv-mana-value, -.inv-mana-time { - font-size: 9px !important; -} - -.inv-mana-state-dot { - width: 10px !important; - height: 10px !important; -} - -/* Custom resize grip for inventory window */ -.inv-resize-grip { - position: absolute; - bottom: 0; - left: 0; - right: 0; - height: 6px; - cursor: ns-resize; - z-index: 100; - background: transparent; - border-top: 1px solid #8a7a44; -} - -.inv-resize-grip::after { - content: ''; - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); - width: 30px; - height: 2px; - border-top: 1px solid #5a4a24; - border-bottom: 1px solid #5a4a24; -} diff --git a/Dockerfile b/Dockerfile index e35f5dde..6c491936 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,9 +16,7 @@ RUN python -m pip install --upgrade pip && \ sqlalchemy \ alembic \ psycopg2-binary \ - httpx \ - bcrypt \ - itsdangerous + httpx ## Copy application source code and migration scripts into container COPY static/ /app/static/ @@ -31,10 +29,6 @@ COPY Dockerfile /Dockerfile ## Expose the application port to host EXPOSE 8765 -## Build version (CalVer + git hash, set via --build-arg) -ARG BUILD_VERSION=dev -ENV APP_VERSION=$BUILD_VERSION - ## Default environment variables for application configuration ENV DATABASE_URL=postgresql://postgres:password@db:5432/dereth \ DB_MAX_SIZE_MB=2048 \ @@ -45,4 +39,4 @@ ENV DATABASE_URL=postgresql://postgres:password@db:5432/dereth \ SHARED_SECRET=your_shared_secret ## Launch the FastAPI app using Uvicorn -CMD ["uvicorn","main:app","--host","0.0.0.0","--port","8765","--workers","1","--no-access-log","--log-level","warning"] +CMD ["uvicorn","main:app","--host","0.0.0.0","--port","8765","--reload","--workers","1","--no-access-log","--log-level","warning"] diff --git a/README.md b/README.md index 0864e4d0..ecc22f92 100644 --- a/README.md +++ b/README.md @@ -1,424 +1,412 @@ -# Mosswart Overlord (Dereth Tracker) +# Dereth Tracker -Real-time telemetry, inventory, and analytics platform for Asheron's Call. -FastAPI backend + React frontend + PostgreSQL (TimescaleDB) + Discord integrations, -all driven by WebSocket events from the companion [MosswartMassacre](https://github.com/SawatoMosswartsEnjoyersClub/MosswartMassacre) DECAL plugin. - ---- +Dereth Tracker is a real-time telemetry service for the world of Dereth. It collects player data, stores it in a PostgreSQL (TimescaleDB) database for efficient time-series storage, provides a live map interface, and includes a comprehensive inventory management system for tracking and searching character equipment. ## Table of Contents - [Overview](#overview) -- [Architecture](#architecture) - [Features](#features) - [Requirements](#requirements) - [Installation](#installation) - [Configuration](#configuration) -- [Deploying Changes](#deploying-changes) -- [WebSocket Contract](#websocket-contract) -- [HTTP API Reference](#http-api-reference) +- [Usage](#usage) +- [API Reference](#api-reference) - [Frontend](#frontend) -- [AI Assistant (Overlord Agent)](#ai-assistant-overlord-agent) - [Database Schema](#database-schema) -- [Operations & Health](#operations--health) - [Contributing](#contributing) ---- - ## Overview -Mosswart Overlord is the backend that consumes a firehose of telemetry, vitals, inventory, combat, and chat events from 60+ characters running the `MosswartMassacre` plugin. It stores selected data in TimescaleDB, runs analytics (combat stats, idle/death detection), and broadcasts live updates to connected browser clients. - -The frontend is a React + Vite app served at `/` with a live map, draggable windows (inventory, chat, combat, radar, etc.), and a server uptime sidebar. The previous vanilla JS frontend is preserved at `/classic`. - -## Architecture - -``` - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ MosswartMassacre (C#) β”‚ ← plugin per game client - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ WebSocket /ws/position (authenticated) - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ dereth-tracker (FastAPI, Docker) β”‚ -β”‚ β€’ main.py β€” WS routing, analytics, broadcasts β”‚ -β”‚ β€’ idle/death detection β†’ Discord webhook β”‚ -β”‚ β€’ combat stats delta/lifetime accumulation β”‚ -β”‚ β€’ vital sharing relay (cross-machine) β”‚ -β””β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ β”‚ β”‚ - β”‚ WS /ws/live β”‚ HTTP β”‚ HTTP - β–Ό β–Ό β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ Browsers β”‚ β”‚ inventory-svc β”‚ β”‚ Discord bot β”‚ -β”‚ (React) β”‚ β”‚ (FastAPI, Docker)β”‚ β”‚ (rare monitor) β”‚ -β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ β–Ό - β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ β”‚ inventory-db β”‚ - β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - β”‚ - β”‚ /api/agent/* (host-side, OUTSIDE Docker) - β–Ό -β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” -β”‚ overlord-agent (FastAPI, systemd) β”‚ ← runs as dedicated unprivileged user -β”‚ β€’ shells out to `claude -p ...` β”‚ /var/lib/overlord-agent home, -β”‚ β€’ MCP server: live-state Q&A tools β”‚ strict settings, no /home/erik -β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ - - β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” - β”‚ dereth-db β”‚ ← TimescaleDB (telemetry, spawns, rares, portals) - β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ -``` - -Most services run via Docker Compose. **`overlord-agent` is host-side** -(systemd) because it shells out to the `claude` CLI which depends on -host-side credentials β€” see [AI Assistant](#ai-assistant-overlord-agent). +This project provides: +- A FastAPI backend with endpoints for receiving and querying telemetry data. +- PostgreSQL/TimescaleDB-based storage for time-series telemetry and per-character stats. +- A live, interactive map using static HTML, CSS, and JavaScript. +- A comprehensive inventory management system with search capabilities. +- Real-time inventory updates via WebSocket when characters log in/out. +- A sample data generator script (`generate_data.py`) for simulating telemetry snapshots. ## Features -### Live Data -- **Live Map** β€” real-time player positions, dots, trails, portals, heatmap -- **WebSocket firehose** (`/ws/live`) β€” broadcasts every incoming event to browsers -- **Per-client subscriptions** β€” clients can send `{"type":"subscribe","message_types":[...]}` to receive only specific event types (the Discord rare monitor bot uses this to filter the 82GB/day firehose down to just `rare` and `chat`) - -### Inventory -- Full inventory snapshot on login + incremental `inventory_delta` updates (add/update/remove) -- Per-character live refresh in the browser (debounced 2s) -- Advanced search with filters: material, set, armor level, spells, tinks, workmanship, etc. -- **Suitbuilder** at `/suitbuilder.html` β€” constraint-based armor optimization across multiple mule inventories with primary/secondary set support, cantrip overlap detection, and real-time SSE streaming - -### Combat Stats (Mag-Tools style) -- Plugin parses combat chat into session deltas -- Backend accumulates lifetime totals from per-session snapshots -- Offense/defense broken out per damage element -- Browser combat window shows monster-by-monster damage - -### Cross-Machine Vital Sharing -- WebSocket relay replaces UtilityBelt's localhost-only `VTankFellowHeals` -- Plugin broadcasts its own vitals and consumes peer vitals -- In-game `DxHud` overlay shows peer health/stamina/mana bars with direction arrows - -### AI Assistant -- πŸ€– chat window in the dashboard backed by `claude -p` running headless on the server -- Read-only access to live game state via 12 MCP tools (live players, inventory cross-search, combat stats, quests, suitbuilder, read-only SQL, etc.) -- Per-browser persistent session, "New Chat" button, history rehydration on reload -- Hardened: dedicated unprivileged Linux user, systemd lockdown, strict tool whitelist, audit log, rate limit. See [AI Assistant section](#ai-assistant-overlord-agent) for the full security stack. - -### Discord Integration -- **Rare Monitor Bot** β€” posts rares (split by common/great) to configured channels -- **Death Alerts** β€” webhook to `#alerts` when a character's vitae goes from 0 β†’ >0 (rate-limited to one per character per 5 min) -- **Idle Alerts** β€” webhook after 5 minutes of continuous idle state (caught portals, stuck nav, etc.). The grace period prevents false positives on brief idle blips. -- **Vortex Warning** β€” bot watches for "whirlwind of vortexes" chat and posts a warning embed - -### Portals -- Automatic discovery + 1-hour retention -- Coordinate-deduplicated (rounded to 0.1 precision) - -### Stats -- Per-character lifetime kills, deaths, rares, taper counts -- Grafana dashboards (2x2 iframe grid in the stats window) - -### Health & Monitoring -- Server uptime + latency + player count from TreeStats.net (checked every 30s) -- Only current state is kept β€” no historical `server_health_checks` table (removed April 2026 as write-only bloat) +- **WebSocket /ws/position**: Stream telemetry snapshots and inventory updates (protected by a shared secret). +- **GET /live**: Fetch active players seen in the last 30 seconds. +- **GET /history**: Retrieve historical telemetry data with optional time filtering. +- **GET /debug**: Health check endpoint. +- **Live Map**: Interactive map interface with panning, zooming, and sorting. +- **Inventory Management**: + - Real-time inventory updates via WebSocket on character login/logout + - Advanced search across all character inventories + - Filter by character, equipment type, material, stats, and more + - Sort by any column with live results + - Track item properties including spells, armor level, damage ratings +- **Suitbuilder**: + - Equipment optimization across multiple character inventories + - Constraint-based search for optimal armor combinations + - Support for primary and secondary armor sets + - Real-time streaming results during long-running searches +- **Portal Tracking**: + - Automatic discovery and tracking of in-game portals + - 1-hour retention for discovered portals + - Coordinate-based uniqueness (rounded to 0.1 precision) + - Real-time portal updates on the map interface +- **Discord Rare Monitor Bot**: Monitors rare discoveries and posts filtered notifications to Discord channels +- **Sample Data Generator**: `generate_data.py` sends telemetry snapshots over WebSocket for testing. ## Requirements +- Python 3.9 or newer (only if running without Docker) +- pip (only if running without Docker) - Docker & Docker Compose (recommended) -- OR: Python 3.11+, Node.js 20+, and a PostgreSQL 14+ with TimescaleDB + +Python packages (if using local virtualenv): + +- fastapi +- uvicorn +- pydantic +- databases +- asyncpg +- sqlalchemy +- websockets # required for sample data generator ## Installation -```bash -git clone git@git.snakedesert.se:SawatoMosswartsEnjoyersClub/MosswartOverlord.git -cd MosswartOverlord -cp .env.example .env # fill in secrets (see Configuration below) -docker compose up -d -``` - -### Frontend development loop - -```bash -cd frontend -npm install -npm run dev # local Vite server -# ...edit files, hot reload... -cd .. -bash deploy-frontend.sh # builds + copies to static/ for production serving -``` - -⚠️ **`npm run build` writes to `static/_build/` but the web server serves from `static/`.** You must run `deploy-frontend.sh` to copy `_build/ β†’ static/`. Otherwise the browser keeps loading the previous bundle. +1. Clone the repository: + ```bash + git clone https://github.com/yourusername/dereth-tracker.git + cd dereth-tracker + ``` +2. Create and activate a virtual environment: + ```bash + python3 -m venv venv + source venv/bin/activate # Windows: venv\Scripts\activate + ``` +3. Install dependencies: + ```bash + pip install fastapi uvicorn pydantic websockets + ``` ## Configuration -All secrets go in `.env`: + - Configure the plugin shared secret via the `SHARED_SECRET` environment variable (default in code: `"your_shared_secret"`). + - The database connection is controlled by the `DATABASE_URL` environment variable (e.g. `postgresql://postgres:password@db:5432/dereth`). + By default, when using Docker Compose, a TimescaleDB container is provisioned for you. + - If you need to tune Timescale or Postgres settings (retention, checkpoint, etc.), set the corresponding `DB_*` environment variables as documented in `docker-compose.yml`. -| Variable | Purpose | -|---|---| -| `POSTGRES_PASSWORD` | Telemetry DB password | -| `INVENTORY_DB_PASSWORD` | Inventory DB password | -| `SHARED_SECRET` | Plugin auth for `/ws/position` | -| `SECRET_KEY` | Session cookie signing | -| `DISCORD_RARE_BOT_TOKEN` | Bot token for rare monitor | -| `DISCORD_ACLOG_WEBHOOK` | Webhook URL for death/idle alerts | -| `GF_SECURITY_ADMIN_PASSWORD` | Grafana admin | -| `COMMON_RARE_CHANNEL_ID` | Discord channel ID for common rares | -| `GREAT_RARE_CHANNEL_ID` | Discord channel ID for great rares | -| `ACLOG_CHANNEL_ID` | Discord channel ID for the rare bot's status/vortex messages | -| `MONITOR_CHARACTER` | Which character's chat the bot monitors | +## Usage -The Overlord Agent has its own env file at `/etc/overlord/agent.env` (root:overlord-agent 0640) so it doesn't share the tracker's secrets: +### Using Docker (Recommended) -| Variable | Purpose | -|---|---| -| `SECRET_KEY` | Same value as the tracker β€” validates browser session cookies | -| `AGENT_DB_DSN` | Read-only connection string `postgresql://overlord_agent_ro:@127.0.0.1:5432/dereth` | -| `TRACKER_URL` | Loopback to the tracker container (default `http://127.0.0.1:8765`) | -| `AGENT_RATE_MAX` | Per-user rate limit (default 60/hour) | -| `AGENT_RATE_WINDOW_S` | Rate-limit window in seconds (default 3600) | -| `AGENT_AUDIT_LOG` | Path to audit JSONL (default `/var/log/overlord-agent/audit.jsonl`) | -| `CLAUDE_TIMEOUT_S` | Max seconds per `claude -p` invocation (default 240) | +1. Build and start all services: + ```bash + docker compose up -d + ``` -## Deploying Changes +2. Rebuild container after code changes: + ```bash + docker compose build --no-cache dereth-tracker + docker compose up -d dereth-tracker + ``` -Live backend host: `overlord.snakedesert.se` (SSH user `erik`, key-based auth). +3. View logs: + ```bash + docker logs mosswartoverlord-dereth-tracker-1 + docker logs dereth-db + ``` -### Quick deploy β€” Python / static file changes +### Without Docker + +Start the server using Uvicorn: ```bash -ssh erik@overlord.snakedesert.se \ - "cd /home/erik/MosswartOverlord && git pull --ff-only origin master" -# Python changes require a restart: -ssh erik@overlord.snakedesert.se "docker compose restart dereth-tracker" -# Static files (JS/CSS/HTML) are served from the bind-mounted static/ β€” no restart. +uvicorn main:app --reload --host 0.0.0.0 --port 8000 +``` + +# Grafana Dashboard UI +```nginx +location /grafana/ { + # Optional: require basic auth on the Grafana UI + auth_basic "Restricted"; + auth_basic_user_file /etc/nginx/.htpasswd; + + proxy_pass http://127.0.0.1:3000/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + # Inject Grafana service account token for anonymous panel embeds + proxy_set_header Authorization "Bearer "; + # WebSocket support (for live panels) + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_cache_bypass $http_upgrade; +} +``` + +## NGINX Proxy Configuration + +If you cannot reassign the existing `/live` and `/trails` routes, you can namespace this service under `/api` (or any other prefix) and configure NGINX accordingly. Be sure to forward WebSocket upgrade headers so that `/ws/live` and `/ws/position` continue to work. Example: +```nginx +location /api/ { + proxy_pass http://127.0.0.1:8765/; + proxy_http_version 1.1; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + # WebSocket support + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_cache_bypass $http_upgrade; +} +``` +Then the browser client (static/script.js) will fetch `/api/live/` and `/api/trails/` to reach this new server. + + - Live Map: `http://localhost:8000/` (or `http:///api/` if behind a prefix) + - Grafana UI: `http://localhost:3000/grafana/` (or `http:///grafana/` if proxied under that path) + +### Frontend Configuration + +- In `static/script.js`, the constant `API_BASE` controls where live/trails data and WebSocket `/ws/live` are fetched. By default: + ```js + const API_BASE = '/api'; + ``` + Update `API_BASE` if you mount the service under a different path or serve it at root. + +### Debugging WebSockets + +- Server logs now print every incoming WebSocket frame in `main.py`: + - `[WS-PLUGIN RX] : ` for plugin messages on `/ws/position` + - `[WS-LIVE RX] : ` for browser messages on `/ws/live` +- Use these logs to verify messages and troubleshoot handshake failures. + +### Styling Adjustments + +- Chat input bar is fixed at the bottom of the chat window (`.chat-form { position:absolute; bottom:0; }`). +- Input text and placeholder are white for readability (`.chat-input, .chat-input::placeholder { color:#fff; }`). +- Incoming chat messages forced white via `.chat-messages div { color:#fff !important; }`. + +## API Reference + +### WebSocket /ws/position +Stream telemetry snapshots over a WebSocket connection. Provide your shared secret either as a query parameter or WebSocket header: + +``` +ws://:/ws/position?secret= +``` +or +``` +X-Plugin-Secret: ``` -⚠️ Uvicorn runs **without** `--reload` in production. Do not add it back β€” without the `watchfiles` package it falls back to a polling reloader that busy-loops at 100% CPU and eats a whole core. +After connecting, send JSON messages matching the `TelemetrySnapshot` schema. For example: -### React frontend deploy +```json +{ + "type": "telemetry", + "character_name": "Dunking Rares", + "char_tag": "moss", + "session_id": "dunk-20250422-xyz", + "timestamp": "2025-04-22T13:45:00Z", + "ew": 123.4, + "ns": 567.8, + "z": 10.2, + "kills": 42, + "deaths": 1, + "prismatic_taper_count": 17, + "vt_state": "Combat", + "kills_per_hour": "N/A", + "onlinetime": "00:05:00" + } +``` + + Each message above is sent as its own JSON object over the WebSocket (one frame per event). When you want to report a rare spawn, send a standalone `rare` event instead of embedding rare counts in telemetry. For example: + + ```json + { + "type": "rare", + "timestamp": "2025-04-22T13:48:00Z", + "character_name": "MyCharacter", + "name": "Golden Gryphon", + "ew": 150.5, + "ns": 350.7, + "z": 5.0, + "additional_info": "first sighting of the day" + } + ``` -```bash -cd frontend && npm run build && cd .. -bash deploy-frontend.sh -git add static/ && git commit -m "deploy frontend" && git push -ssh erik@overlord.snakedesert.se "cd /home/erik/MosswartOverlord && git pull" -# No container restart needed. +### Chat messages +You can also send chat envelopes over the same WebSocket to display messages in the browser. Fields: +- `type`: must be "chat" +- `character_name`: target player name +- `text`: message content +- `color` (optional): CSS color string (e.g. "#ff8800"); if sent as an integer (0xRRGGBB), it will be converted to hex. + +Example chat payload: +```json +{ + "type": "chat", + "character_name": "MyCharacter", + "text": "Hello world!", + "color": "#88f" +} ``` -### Full rebuild β€” Dockerfile / pip package / version stamp changes +## Event Payload Formats -```bash -ssh erik@overlord.snakedesert.se "cd /home/erik/MosswartOverlord && \ - git pull --ff-only origin master && \ - export BUILD_VERSION=\"\$(date -u +%Y.%-m.%-d.%H%M)-\$(git rev-parse --short HEAD)\" && \ - docker compose build --no-cache --build-arg BUILD_VERSION=\$BUILD_VERSION dereth-tracker && \ - docker compose up -d dereth-tracker" +For a complete reference of JSON payloads accepted by the backend (over `/ws/position`), see the file `EVENT_FORMATS.json` in the project root. It contains example schemas for: + - **Telemetry events** (`type`: "telemetry") + - **Spawn events** (`type`: "spawn") + - **Chat events** (`type`: "chat") + - **Rare events** (`type`: "rare") + - **Inventory events** (`type`: "inventory") + +Notes on payload changes: + - Spawn events no longer require the `z` coordinate; if omitted, the server defaults it to 0.0. + Coordinates (`ew`, `ns`, `z`) may be sent as JSON numbers or strings; the backend will coerce them to floats. + - Telemetry events have removed the `latency_ms` field; please omit it from your payloads. + - Inventory events are sent automatically on character login/logout containing complete inventory data. + +Each entry shows all required and optional fields, their types, and example values. + +### GET /live +Returns active players seen within the last 30 seconds: + +```json +{ + "players": [ { ... } ] +} ``` -`BUILD_VERSION` is displayed in the sidebar of the live frontend. Format is CalVer: `YYYY.M.D.HHMM-gitshorthash`. +### GET /history +Retrieve historical snapshots with optional `from` and `to` ISO8601 timestamps: -### Overlord Agent deploy - -Code changes to `agent/` only: -```bash -ssh erik@overlord.snakedesert.se "cd /home/erik/MosswartOverlord && \ - git pull --ff-only origin master && \ - sudo systemctl restart overlord-agent" -journalctl -u overlord-agent -f # tail logs to verify +``` +GET /history?from=2025-04-22T12:00:00Z&to=2025-04-22T13:00:00Z ``` -`agent/requirements.txt` changed (new pip deps): -```bash -ssh erik@overlord.snakedesert.se "cd /home/erik/MosswartOverlord && \ - git pull --ff-only origin master && \ - agent/.venv/bin/pip install -r agent/requirements.txt && \ - sudo systemctl restart overlord-agent" +Response: + +```json +{ + "data": [ { ... } ] +} ``` -systemd unit changed: -```bash -ssh erik@overlord.snakedesert.se "cd /home/erik/MosswartOverlord && \ - git pull --ff-only origin master && \ - sudo cp agent/overlord-agent.service /etc/systemd/system/ && \ - sudo systemctl daemon-reload && sudo systemctl restart overlord-agent" -``` - -First-time install: `bash agent/install.sh` β€” see `agent/README.md` for the full bootstrap procedure (creating the `overlord-agent` user, copying claude auth, granting filesystem access, populating `/etc/overlord/agent.env`). - -## WebSocket Contract - -### `/ws/position` (plugin β†’ backend) - -Authenticated via `?secret=` or `X-Plugin-Secret` header. Accepts JSON frames with a `type` discriminator: - -| `type` | Purpose | -|---|---| -| `telemetry` | Position, kills, session metrics (every 2s per character) | -| `vitals` | Health/stamina/mana/vitae percentages | -| `character_stats` | Full attributes/skills/allegiance (every 10 min) | -| `inventory` / `full_inventory` | Complete inventory dump on login | -| `inventory_delta` | Incremental add/update/remove of a single item | -| `equipment_cantrip_state` | Equipped spell effects | -| `portal` | Discovered portal with coordinates | -| `spawn` | Monster spawn observation | -| `chat` | In-game chat line (any channel) | -| `quest` | Quest timer / progress | -| `rare` | Rare item find notification | -| `nearby_objects` | On-demand radar data (nearby entities) | -| `combat_stats` | Session combat snapshot (Mag-Tools parser output) | -| `share_*` | Cross-machine vital/debuff sharing envelopes | -| `dungeon_map` | Dungeon floor tile data for radar overlay | - -See `EVENT_FORMATS.json` for exact per-type schemas. - -### `/ws/live` (browser β†’ backend) - -Session-cookie authenticated (except for internal Docker network clients, which are trusted by IP). Clients can: - -- Send `{"type":"subscribe","message_types":["rare","chat"]}` to filter which events they receive. Without subscribing, all types are forwarded (browser default). -- Send `{"player_name":"Larsson","command":"/radar start"}` to route a command to that character's plugin client. -- Send `{"type":"request_dungeon_map","landblock":"..."}` to pull cached dungeon tile data. - -Backend pushes the same firehose (subject to subscription filter) to every browser client. - -## HTTP API Reference - -See `EVENT_FORMATS.json` for event schemas. Major HTTP endpoints: - -- `GET /live` β€” active players seen in the last 30s -- `GET /history?from=…&to=…` β€” historical telemetry snapshots -- `GET /trails` β€” recent player trails for the map -- `GET /spawns/heatmap?hours=N` β€” aggregated spawn density -- `GET /portals` β€” discovered portals within retention window -- `GET /inventory/{character}` β€” current inventory (proxied to inventory-service) -- `GET /character-stats/{character}` β€” full character attributes/skills -- `GET /combat-stats/{character}` β€” session + lifetime combat stats -- `GET /vital-sharing/peers` β€” currently-registered vital sharing peers -- `GET /api-version` β€” build version stamp -- `GET /server-health` β€” current Coldeve server status + player count - ## Frontend -### React v2 (primary, at `/`) -- Map-first layout with draggable/resizable windows -- Code-split bundles: one chunk per window type, lazy-loaded on open -- Window types: Chat, Stats, Inventory, Character, Radar, CombatStats, CombatPicker, Issues, VitalSharing, QuestStatus, PlayerDashboard -- Per-character inventory version counter β€” an open inventory window refreshes 2s after its own character's last `inventory_delta`, ignoring unrelated traffic -- Direct DOM pan/zoom on the map (no React state per frame) -- Service worker caches a small whitelist of static assets -- Version badge in the sidebar confirms which build is loaded - -### Classic v1 (preserved at `/classic`) -The original vanilla JS frontend with element-pooling optimization is kept for fallback and reference. - -## AI Assistant (Overlord Agent) - -A draggable chat window in the dashboard (πŸ€– Assistant button). Powered by `claude -p` running headless on the server, with read-only access to live game state via an MCP server. - -### Architecture -- **Host-side service** (`agent/`, systemd unit `overlord-agent`) runs OUTSIDE Docker because the `claude` CLI binary lives on the host (`/home/erik/.local/bin/claude`) and depends on host-side authentication credentials. -- **Dedicated UNIX user** (`overlord-agent`, system account, `/var/lib/overlord-agent` home, no shell) β€” kernel-level isolation from the operator's `erik` account. Cannot read `/home/erik/.claude`, `~/.ssh`, `.bash_history`, `.env`, etc. -- **MCP stdio server** (`agent/mcp_overlord.py`) exposes 12 tools that wrap the tracker's HTTP endpoints + read-only DB queries. Claude only sees these tools; no `Bash`, `Read`, `Write`, etc. -- **Frontend** (`AgentWindow.tsx`) β€” per-browser session UUID in localStorage, "New Chat" button, on-mount rehydration from `/agent/sessions/{id}/history`. - -### MCP tools available to the assistant -`get_live_players`, `get_player_state`, `get_combat_stats`, `get_equipment_cantrips`, `get_inventory`, `get_inventory_search`, `search_items` (cross-character), `get_recent_rares`, `get_quest_status`, `get_server_health`, `query_telemetry_db` (read-only SQL via sqlglot parser + GRANT-SELECT-only PG role), `suitbuilder_search`. Plus `WebFetch(domain:acpedia.org)` for AC info lookups. - -### Security stack (defense-in-depth) -1. **Cookie auth** on `/agent/ask` (same session cookie the tracker issues) -2. **Per-user rate limit** (60 req/h default) and **concurrency cap** (1 in-flight) -3. **JSONL audit log** at `/var/log/overlord-agent/audit.jsonl` (every prompt + result) -4. **CLI flags** β€” `--allowed-tools` (just our 12 MCP tools), `--disallowed-tools` (Bash, Write, Read, Edit, Agent, ToolSearch, Monitor, scheduling, Gmail/Drive/Calendar, etc.), `--permission-mode dontAsk` -5. **`/var/lib/overlord-agent/.claude/settings.json`** β€” strict deny rules (server-side only, NOT in repo) -6. **System-prompt scope rules** in `CLAUDE.md` β€” instruct the model not to probe, not to suggest workarounds -7. **SQL parser** (`sqlglot`) rejects any non-SELECT statement on `query_telemetry_db` -8. **Read-only PG role** `overlord_agent_ro` (GRANT SELECT only) β€” even a parser bypass can't mutate -9. **systemd hardening** β€” `ProtectSystem=strict`, `ProtectHome=read-only`, `InaccessiblePaths=/etc/shadow,/root,~/.ssh,…`, `NoNewPrivileges=true`, `CapabilityBoundingSet=` (empty), `PrivateTmp=true`, `PrivateDevices=true`, `RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6`, `SystemCallFilter=@system-service ~@privileged ~@reboot ~@mount`, `MemoryMax=512M`, `TasksMax=128` -10. **Secrets out of /home** β€” `/etc/overlord/agent.env` (root:overlord-agent 0640) for SECRET_KEY + AGENT_DB_DSN - -### Files - -| Path | What | -|------|------| -| `agent/service.py` | FastAPI app: `/agent/health`, `/agent/sessions/new`, `/agent/ask`, `/agent/sessions/{id}/history` | -| `agent/auth.py` | Session cookie validation (mirrors `main.py:1013-1019`) | -| `agent/claude_wrapper.py` | `asyncio.create_subprocess_exec("claude", "-p", …)` with allowed/disallowed-tools | -| `agent/tools.py` | Pure tool implementations | -| `agent/mcp_overlord.py` | MCP stdio server registering tools | -| `agent/sql/0001_overlord_agent_ro.sql` | Read-only PG role | -| `agent/overlord-agent.service` | systemd unit (the hardening directives) | -| `agent/install.sh` | venv + systemd setup | -| `agent/README.md` | Operator's deeper reference | -| `.mcp.json` (repo root) | Project-level MCP config Claude Code auto-loads | -| `CLAUDE.md` "Overlord Assistant Mode" section | System-prompt briefing | - -### Routing -nginx forwards `/api/agent/*` to `127.0.0.1:8767` (the host-side service) with a 300s read/send timeout (suitbuilder runs can be slow). Other `/api/*` continues to the dereth-tracker container at `127.0.0.1:8765`. - -### Cost / quota -Subscription auth (no API key); per-call cost is informational only. Each `/agent/ask` invocation = one `claude -p` subprocess with shared session cache. Reactive only β€” no background polling, no scheduled tasks. +- **Live Map**: `static/index.html` – Real-time player positions on a map. +- **Inventory Search**: `static/inventory.html` – Search and browse character inventories with advanced filtering. ## Database Schema -### Telemetry DB (`dereth`, TimescaleDB) +This service uses PostgreSQL with the TimescaleDB extension to store telemetry time-series data, +aggregate character statistics, and a separate inventory database for equipment management. -| Table | Type | Retention | Purpose | -|---|---|---|---| -| `telemetry_events` | hypertable | 30 days | Position/stats snapshots | -| `spawn_events` | hypertable | 7 days | Monster spawn observations (heatmap source) | -| `rare_events` | regular | forever | Rare find history | -| `portals` | regular | 1 hour | Discovered portals, dedup by rounded coords | -| `char_stats` | regular | forever | Per-character lifetime kill total | -| `rare_stats` | regular | forever | Per-character lifetime rare total | -| `rare_stats_sessions` | regular | forever | Per-session rare count | -| `combat_stats` | regular | forever | Lifetime combat accumulator | -| `combat_stats_sessions` | regular | forever | Per-session combat snapshots | -| `character_stats` | regular | forever | Latest full stats JSON per character | -| `server_status` | regular | forever | Current Coldeve server state (single row) | +### Telemetry Database Tables: -### Inventory DB (`inventory_db`, PostgreSQL) +- **telemetry_events** (hypertable): + - `id` (PK, serial) + - `character_name` (text, indexed) + - `char_tag` (text, nullable) + - `session_id` (text, indexed) + - `timestamp` (timestamptz, indexed) + - `ew`, `ns`, `z` (float) + - `kills`, `deaths`, `rares_found`, `prismatic_taper_count` (integer) + - `kills_per_hour` (float) + - `onlinetime`, `vt_state` (text) + - Optional metrics: `mem_mb`, `cpu_pct`, `mem_handles`, `latency_ms` (float) -Normalized schema: `items`, `item_combat_stats`, `item_requirements`, `item_enhancements`, `item_ratings`, `item_spells`, `item_raw_data`. +- **char_stats**: + - `character_name` (text, PK) + - `total_kills` (integer) -`items.container_id` stores the in-game ID of the container holding the item (0 = character body). The frontend groups items into packs by this ID. +- **rare_stats**: + - `character_name` (text, PK) + - `total_rares` (integer) -## Operations & Health +- **rare_stats_sessions**: + - `character_name`, `session_id` (composite PK) + - `session_rares` (integer) -### PostgreSQL tuning -`dereth-db` runs with explicit memory overrides in `docker-compose.yml`: -- `shared_buffers=8GB` (was 96GB via auto-tune on a 32GB host β€” caused thrashing) -- `effective_cache_size=16GB` -- `work_mem=16MB`, `maintenance_work_mem=1GB` -- `max_wal_size=4GB` +- **spawn_events**: + - `id` (PK, serial) + - `character_name` (text) + - `mob` (text) + - `timestamp` (timestamptz) + - `ew`, `ns`, `z` (float) -### Retention policies -- `telemetry_events`: 30-day drop, daily -- `spawn_events`: 7-day drop, daily -- `portals`: 1-hour cleanup (background task in `main.py`) -- `server_health_checks`: **removed** β€” was write-only, 850K rows of nothing +- **rare_events**: + - `id` (PK, serial) + - `character_name` (text) + - `name` (text) + - `timestamp` (timestamptz) + - `ew`, `ns`, `z` (float) -### Log levels -Both `dereth-tracker` and `inventory-service` run at `LOG_LEVEL=INFO`. Do not set to `DEBUG` in production β€” it dumps full inventory_delta payloads for every item update (hundreds of KB/sec). +- **portals**: + - `id` (PK, serial) + - `portal_name` (text) + - `ns`, `ew`, `z` (float coordinates) + - `discovered_at` (timestamptz, indexed) + - `discovered_by` (text) + - Unique constraint: `ROUND(ns::numeric, 1), ROUND(ew::numeric, 1)` -### Host (Proxmox VM) -- 6 vCPU, 32 GiB RAM (of which ~30 GiB is normally free under current load) -- Live host: `overlord.snakedesert.se` -- Reverse proxy: Nginx on the host terminates TLS and strips the `/api/` prefix before forwarding to port 8765 +### Inventory Database Tables: -### Debug commands -```bash -docker ps -docker logs mosswartoverlord-dereth-tracker-1 --tail 100 -docker logs mosswartoverlord-inventory-service-1 --tail 100 -docker logs mosswartoverlord-discord-rare-monitor-1 --tail 100 -docker exec dereth-db psql -U postgres -d dereth -``` +- **items**: + - `id` (PK, serial) + - `character_name` (text, indexed) + - `item_id` (bigint) + - `name` (text) + - `object_class` (integer) + - `icon`, `value`, `burden` (integer) + - `current_wielded_location`, `bonded`, `attuned`, `unique` (various) + - `timestamp` (timestamptz) + +- **item_combat_stats**: + - `item_id` (FK to items.id) + - `armor_level`, `max_damage` (integer) + - `damage_bonus`, `attack_bonus` (float) + - Various defense bonuses + +- **item_enhancements**: + - `item_id` (FK to items.id) + - `material` (varchar) + - `item_set` (varchar) + - `tinks`, `workmanship` (integer/float) + +- **item_spells**: + - `item_id` (FK to items.id) + - `spell_id` (integer) + - `spell_name` (text) + - `is_legendary`, `is_epic` (boolean) + +- **item_raw_data**: + - `item_id` (FK to items.id) + - `int_values`, `double_values`, `string_values`, `bool_values` (JSONB) + - `original_json` (JSONB) ## Contributing -Contributions welcome. Please: -- Keep cross-repo protocol changes additive (new optional fields > renames/removes) -- Update both this README and `CLAUDE.md` when workflows change -- Test end-to-end: plugin β†’ backend β†’ browser for any new event type +Contributions are welcome! Feel free to open issues or submit pull requests. -For detailed architecture notes and ongoing investigations, see `CLAUDE.md` and `docs/plans/`. +## Roadmap & TODO +For detailed tasks, migration steps, and future enhancements, see [TODO.md](TODO.md). + +### Local Development Database +This service uses PostgreSQL with the TimescaleDB extension. You can configure local development using the provided Docker Compose setup or connect to an external instance: + +1. PostgreSQL/TimescaleDB via Docker Compose (recommended): + - Pros: + - Reproducible, isolated environment out-of-the-box + - No need to install Postgres locally + - Aligns development with production setups + - Cons: + - Additional resource usage (memory, CPU) + - Slightly more complex Docker configuration + +2. External PostgreSQL instance: + - Pros: + - Leverages existing infrastructure + - No Docker overhead + - Cons: + - Requires manual setup and Timescale extension + - Less portable for new contributors diff --git a/agent/README.md b/agent/README.md deleted file mode 100644 index aa875178..00000000 --- a/agent/README.md +++ /dev/null @@ -1,146 +0,0 @@ -# Overlord Agent - -A small host-side Python service that gives Claude Code (running in -headless mode) access to live Overlord data so it can answer questions -from the dashboard chat window. - -## Why a separate service? - -`dereth-tracker` runs in Docker. The `claude` CLI binary at -`/home/erik/.local/bin/claude` depends on `~/.claude` credentials owned -by user `erik` on the host. The tracker container can't invoke it. - -So this service runs **outside** Docker, listens on `127.0.0.1:8767`, -and nginx routes `/api/agent/*` to it. It validates the same browser -session cookie the tracker issues (shared `SECRET_KEY`) and shells out -to `claude -p` with `cwd=/home/erik/MosswartOverlord`. - -## Architecture - -``` -Browser ──nginx──┬─► /api/* ──► dereth-tracker (Docker, 8765) - β”‚ - └─► /api/agent/* ──► overlord-agent (host, 8767) - β”‚ - β”œβ”€β–Ί subprocess: claude -p ... - β”‚ β”‚ - β”‚ └─► MCP stdio ──► mcp_overlord.py - β”‚ β”‚ - β”‚ └─► HTTP loopback to tracker - β”‚ └─► asyncpg to dereth-db - β”‚ - └─► validates "session" cookie -``` - -## Files - -| File | What | -|------|------| -| `service.py` | FastAPI app (`/agent/health`, `/agent/sessions/new`, `/agent/ask`, `/agent/sessions/{id}/history`) | -| `auth.py` | Session-cookie validation (mirrors `main.py:1013-1019`) | -| `claude_wrapper.py` | `asyncio.create_subprocess_exec("claude", "-p", ...)` | -| `tools.py` | Pure tool implementations (HTTP loopback + read-only DB) | -| `mcp_overlord.py` | MCP stdio server registering tools for Claude Code | -| `sql/0001_overlord_agent_ro.sql` | Read-only PG role for the SQL tool | -| `overlord-agent.service` | systemd unit | -| `install.sh` | One-shot installer (venv + pip install + systemd) | - -## Required env vars (in repo-root `.env`) - -``` -SECRET_KEY= -AGENT_DB_DSN=postgresql://overlord_agent_ro:@127.0.0.1:5432/dereth -TRACKER_URL=http://127.0.0.1:8765 # optional, this is the default -CLAUDE_BIN=/home/erik/.local/bin/claude # optional, this is the default -CLAUDE_CWD=/home/erik/MosswartOverlord # optional, this is the default -CLAUDE_TIMEOUT_S=120 # optional -``` - -## First-time setup on the server - -1. **Create the read-only DB role** (one-time): - ```bash - docker exec -i dereth-db psql -U postgres -d dereth \ - < /home/erik/MosswartOverlord/agent/sql/0001_overlord_agent_ro.sql - docker exec -it dereth-db psql -U postgres -d dereth \ - -c "ALTER ROLE overlord_agent_ro PASSWORD '';" - ``` -2. **Add `AGENT_DB_DSN`** to `/home/erik/MosswartOverlord/.env` with the - password you just set. -3. **Run the installer**: - ```bash - cd /home/erik/MosswartOverlord - bash agent/install.sh - ``` -4. **Update nginx**: edit `/etc/nginx/sites-enabled/overlord` to add the - `/api/agent/` location (already in `nginx/overlord.conf` in the repo β€” - just `sudo cp` and reload). - -## Day-to-day deploy - -After editing any agent file: - -```bash -# On dev: -git push - -# On server: -ssh erik@overlord.snakedesert.se -cd /home/erik/MosswartOverlord -git pull -sudo systemctl restart overlord-agent -journalctl -u overlord-agent -f # tail logs -``` - -For Python dependency changes: - -```bash -agent/.venv/bin/pip install -r agent/requirements.txt -sudo systemctl restart overlord-agent -``` - -## Smoke tests - -```bash -# 1. Service alive? -curl http://127.0.0.1:8767/agent/health - -# 2. Cookie required? -curl -X POST http://127.0.0.1:8767/agent/ask \ - -H 'Content-Type: application/json' \ - -d '{"session_id":"x","message":"hi"}' -# β‡’ 401 - -# 3. Direct claude invocation works? -echo "hello" | /home/erik/.local/bin/claude -p \ - --session-id 11111111-1111-1111-1111-111111111111 \ - --output-format json - -# 4. End-to-end via nginx (with cookie): -curl -X POST https://overlord.snakedesert.se/api/agent/ask \ - -b 'session=' \ - -H 'Content-Type: application/json' \ - -d '{"session_id":"","message":"How many characters are online?"}' -``` - -## Cost / rate-limit notes - -- Each `/agent/ask` shells out to `claude -p` once. -- We use the user's Claude subscription (no API key) β€” flat-rate, no - per-call billing, but subscription-tier rate limits still apply. -- **Reactive only**: there are no background loops or periodic ticks. - Each user message = one Claude turn (which may chain several tool - calls internally before producing a final answer). -- The SQL tool is hard-capped at 10s and 200 rows. -- `suitbuilder_search` is the only tool that can take minutes; nginx - read timeout is 180s for `/api/agent/`. - -## Adding a new MCP tool - -1. Implement `async def my_tool(...) -> dict` in `tools.py`. -2. Register it in `mcp_overlord.py` under `TOOL_DEFS`: - - description (the agent reads this to decide when to call) - - JSON schema for arguments - - lambda dispatching to `T.my_tool(...)` -3. `sudo systemctl restart overlord-agent`. Claude Code re-discovers the - tool list on each invocation. diff --git a/agent/__init__.py b/agent/__init__.py deleted file mode 100644 index 2cbfa0cf..00000000 --- a/agent/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -"""Overlord Agent β€” host-side service that shells out to claude -p. - -Runs OUTSIDE the dereth-tracker Docker container because the `claude` CLI -binary lives at /home/erik/.local/bin/claude on the host and depends on -~/.claude/ credentials owned by user erik. The container can't invoke it -directly, so this is a small standalone FastAPI service on port 8767. - -nginx routes /api/agent/* to here. The same browser session cookie that -dereth-tracker validates is reused (shared SECRET_KEY env var). -""" diff --git a/agent/auth.py b/agent/auth.py deleted file mode 100644 index 2928bed4..00000000 --- a/agent/auth.py +++ /dev/null @@ -1,51 +0,0 @@ -"""Session-cookie validation that mirrors main.py. - -Re-implements the verify path so this host-side service can authenticate -the same browser cookie that dereth-tracker issues. Both services must -share the SECRET_KEY env var. -""" - -from __future__ import annotations - -import os - -from fastapi import HTTPException, Request, status -from itsdangerous import BadSignature, SignatureExpired, URLSafeTimedSerializer - -# Mirror main.py:996-998 -SECRET_KEY = os.getenv("SECRET_KEY", "change-me-in-production-please") -SESSION_MAX_AGE = 30 * 24 * 3600 # 30 days -_serializer = URLSafeTimedSerializer(SECRET_KEY) - - -def verify_session_cookie(token: str) -> dict | None: - """Verify and decode a session token. Returns None if invalid/expired. - - Mirrors main.py:1013-1019 byte-for-byte so a cookie issued by the tracker - decodes here identically. - """ - try: - data = _serializer.loads(token, max_age=SESSION_MAX_AGE) - return {"username": data["u"], "is_admin": data["a"]} - except (BadSignature, SignatureExpired, KeyError): - return None - - -def require_user(request: Request) -> dict: - """FastAPI dependency: enforces a valid session cookie. - - Returns the decoded user dict on success; raises 401 otherwise. - """ - token = request.cookies.get("session") - if not token: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Not authenticated", - ) - user = verify_session_cookie(token) - if not user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, - detail="Session invalid or expired", - ) - return user diff --git a/agent/claude_wrapper.py b/agent/claude_wrapper.py deleted file mode 100644 index bbe48712..00000000 --- a/agent/claude_wrapper.py +++ /dev/null @@ -1,280 +0,0 @@ -"""Subprocess wrapper around `claude -p` (Claude Code in headless JSON mode). - -Run from cwd=/home/erik/MosswartOverlord so: - β€’ Sessions persist at ~/.claude/projects/-home-erik-MosswartOverlord/.jsonl - β€’ Project-level .mcp.json is auto-loaded - β€’ CLAUDE.md in the repo root briefs the agent - -The `--session-id` flag both creates a new session (first call) and resumes -an existing one (subsequent calls), so we don't need separate code paths. -""" - -from __future__ import annotations - -import asyncio -import json -import logging -import os -from dataclasses import dataclass -from pathlib import Path -from typing import Any - -logger = logging.getLogger(__name__) - -# These can be overridden via env vars for non-prod testing. -CLAUDE_BIN = os.getenv("CLAUDE_BIN", "/home/erik/.local/bin/claude") -CLAUDE_CWD = os.getenv("CLAUDE_CWD", "/home/erik/MosswartOverlord") -# Hard cap on how long a single agent turn may take. Claude Code can spin a -# while when chaining many tool calls; we don't want to leave a zombie -# subprocess if something gets stuck. -CLAUDE_TIMEOUT_S = int(os.getenv("CLAUDE_TIMEOUT_S", "240")) - - -@dataclass -class ClaudeResult: - result: str - session_id: str - duration_ms: int - num_turns: int - is_error: bool - raw: dict[str, Any] - - -class ClaudeError(RuntimeError): - """Raised when the claude CLI returns a non-zero exit or unparseable output.""" - - -def _session_exists(session_id: str) -> bool: - """True if Claude Code has already persisted a JSONL for this session. - - Claude Code stores sessions at ~/.claude/projects//.jsonl - where non-alphanumerics in the cwd are replaced with hyphens. - """ - encoded = "".join(c if c.isalnum() else "-" for c in CLAUDE_CWD) - path = Path.home() / ".claude" / "projects" / encoded / f"{session_id}.jsonl" - return path.is_file() - - -async def ask_claude(message: str, session_id: str) -> ClaudeResult: - """Send `message` to `claude -p` for `session_id`; return parsed result. - - On the FIRST message of a session uses `--session-id ` to create it. - On subsequent messages uses `--resume ` because claude rejects - `--session-id` on existing sessions ("Session ID ... is already in use"). - - Raises ClaudeError on subprocess failure, JSON parse failure, or timeout. - """ - if not Path(CLAUDE_BIN).exists(): - raise ClaudeError(f"claude binary not found at {CLAUDE_BIN}") - if not Path(CLAUDE_CWD).is_dir(): - raise ClaudeError(f"CLAUDE_CWD does not exist: {CLAUDE_CWD}") - - # Whitelist only our MCP tools so Claude Code can call them without - # human approval. Names follow the convention mcp____. - # We deliberately omit built-in tools (Bash, Write, Edit, Read, etc.) - # β€” the assistant doesn't need them for live-state Q&A and they'd be a - # security/permissions footgun on an unattended service. - allowed_tools = ",".join( - [ - "mcp__overlord__get_live_players", - "mcp__overlord__get_recent_rares", - "mcp__overlord__query_telemetry_db", - "mcp__overlord__get_player_state", - "mcp__overlord__get_inventory", - "mcp__overlord__get_inventory_search", - "mcp__overlord__search_items", - "mcp__overlord__get_combat_stats", - "mcp__overlord__get_equipment_cantrips", - "mcp__overlord__get_quest_status", - "mcp__overlord__get_server_health", - "mcp__overlord__suitbuilder_search", - ] - ) - - # CRITICAL: Claude Code's built-in meta-tools (ToolSearch, Monitor, etc.) - # bypass the --allowed-tools whitelist. They come from Anthropic's tool - # registry rather than from local MCP servers. We must explicitly DISALLOW - # them β€” confirmed by testing that ToolSearch was reachable even with - # `--permission-mode dontAsk` and a tight --allowed-tools list. - disallowed_tools = ",".join( - [ - # File / shell / search built-ins (defense in depth β€” already not - # in allow list, but if someone toggles permission-mode this - # belt-and-suspenders the deny side). - "Bash", - "Write", - "Edit", - "Read", - "Glob", - "Grep", - "NotebookEdit", - # Network built-ins - "WebSearch", - "WebFetch", # blocked here; settings.json re-allows acpedia.org - # Subagent spawning β€” the assistant must NEVER delegate to a - # general-purpose subagent (which would have its own tool set). - "Agent", - # Tool / session meta-tools β€” these can list, load, or chain - # into other tools and must NOT be reachable. - "ToolSearch", - "Monitor", - "TaskOutput", - "TaskStop", - "TodoWrite", - "Skill", - "EnterPlanMode", - "ExitPlanMode", - "EnterWorktree", - "ExitWorktree", - "AskUserQuestion", - "ListMcpResourcesTool", - "ReadMcpResourceTool", - "PushNotification", - # Scheduling / cron β€” the agent must never schedule itself. - "CronCreate", - "CronList", - "CronDelete", - "ScheduleWakeup", - "RemoteTrigger", - # Anthropic first-party connectors from the user's claude.ai - # account. These are off-mission for an Overlord assistant and - # would leak personal data outside the game-state domain. - "mcp__claude_ai_Gmail__create_draft", - "mcp__claude_ai_Gmail__create_label", - "mcp__claude_ai_Gmail__get_message", - "mcp__claude_ai_Gmail__get_thread", - "mcp__claude_ai_Gmail__list_drafts", - "mcp__claude_ai_Gmail__list_labels", - "mcp__claude_ai_Gmail__label_message", - "mcp__claude_ai_Gmail__label_thread", - "mcp__claude_ai_Gmail__search_messages", - "mcp__claude_ai_Gmail__search_threads", - "mcp__claude_ai_Gmail__send_message", - "mcp__claude_ai_Gmail__unlabel_message", - "mcp__claude_ai_Gmail__unlabel_thread", - "mcp__claude_ai_Google_Calendar__authenticate", - "mcp__claude_ai_Google_Drive__authenticate", - ] - ) - - # Pick --session-id (creates) vs --resume (continues) based on whether - # the session JSONL already exists on disk. - is_new = not _session_exists(session_id) - session_flag = "--session-id" if is_new else "--resume" - - args = [ - CLAUDE_BIN, - "-p", - session_flag, - session_id, - "--output-format", - "json", - "--allowed-tools", - allowed_tools, - # Built-in meta-tools that --allowed-tools does NOT block β€” must - # be explicitly listed here. - "--disallowed-tools", - disallowed_tools, - # CRITICAL: dontAsk auto-DENIES anything outside --allowed-tools. - # Do NOT use bypassPermissions here β€” that mode ignores the whitelist - # entirely and lets the model call Bash/Write/Edit/etc. (verified - # the hard way: it wrote /tmp/owned.sh when prompted to). - # See https://code.claude.com/docs/en/permission-modes.md - "--permission-mode", - "dontAsk", - ] - - logger.info( - "claude exec: session=%s mode=%s msg_len=%d cwd=%s", - session_id, - "new" if is_new else "resume", - len(message), - CLAUDE_CWD, - ) - - proc = await asyncio.create_subprocess_exec( - *args, - stdin=asyncio.subprocess.PIPE, - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE, - cwd=CLAUDE_CWD, - ) - - try: - stdout, stderr = await asyncio.wait_for( - proc.communicate(input=message.encode("utf-8")), - timeout=CLAUDE_TIMEOUT_S, - ) - except asyncio.TimeoutError: - try: - proc.kill() - except ProcessLookupError: - pass - raise ClaudeError(f"claude timed out after {CLAUDE_TIMEOUT_S}s") - - if proc.returncode != 0: - stderr_text = stderr.decode("utf-8", "replace") - # If we picked the wrong flag (e.g. JSONL deleted from disk between - # our check and exec, or a never-flushed session), claude prints - # "Session ID … is already in use." Re-issue with --resume. - if is_new and "already in use" in stderr_text: - logger.info("session %s actually exists; retrying with --resume", session_id) - args2 = list(args) - args2[2] = "--resume" - proc2 = await asyncio.create_subprocess_exec( - *args2, - stdin=asyncio.subprocess.PIPE, - stdout=asyncio.subprocess.PIPE, - stderr=asyncio.subprocess.PIPE, - cwd=CLAUDE_CWD, - ) - try: - stdout, stderr = await asyncio.wait_for( - proc2.communicate(input=message.encode("utf-8")), - timeout=CLAUDE_TIMEOUT_S, - ) - except asyncio.TimeoutError: - try: - proc2.kill() - except ProcessLookupError: - pass - raise ClaudeError(f"claude timed out after {CLAUDE_TIMEOUT_S}s") - if proc2.returncode != 0: - raise ClaudeError( - f"claude exited {proc2.returncode} after retry: " - f"{stderr.decode('utf-8', 'replace')[:500]}" - ) - else: - raise ClaudeError( - f"claude exited {proc.returncode}: {stderr_text[:500]}" - ) - - raw_text = stdout.decode("utf-8", "replace").strip() - if not raw_text: - raise ClaudeError("claude produced empty stdout") - - # In --output-format json mode the LAST line is the JSON envelope; some - # earlier lines may be progress. Be tolerant. - try: - envelope = json.loads(raw_text) - except json.JSONDecodeError: - # Try the last non-empty line - last = next( - (line for line in reversed(raw_text.splitlines()) if line.strip()), - "", - ) - try: - envelope = json.loads(last) - except json.JSONDecodeError as e: - raise ClaudeError( - f"claude stdout was not JSON: {raw_text[:500]}" - ) from e - - return ClaudeResult( - result=envelope.get("result", ""), - session_id=envelope.get("session_id", session_id), - duration_ms=int(envelope.get("duration_ms", 0)), - num_turns=int(envelope.get("num_turns", 0)), - is_error=bool(envelope.get("is_error", False)), - raw=envelope, - ) diff --git a/agent/install.sh b/agent/install.sh deleted file mode 100644 index f92a2c7a..00000000 --- a/agent/install.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash -# Install / re-install the Overlord Agent host-side service. -# -# Run as user `erik` from /home/erik/MosswartOverlord: -# bash agent/install.sh -# -# Requires sudo for the systemd parts (you'll be prompted once). - -set -euo pipefail - -REPO_DIR="/home/erik/MosswartOverlord" -AGENT_DIR="$REPO_DIR/agent" -VENV_DIR="$AGENT_DIR/.venv" -SERVICE_FILE="$AGENT_DIR/overlord-agent.service" -SYSTEMD_TARGET="/etc/systemd/system/overlord-agent.service" - -if [[ "$(pwd)" != "$REPO_DIR" ]]; then - echo "Run from $REPO_DIR (currently in $(pwd))" >&2 - exit 1 -fi - -echo "==> Creating/updating venv at $VENV_DIR" -if [[ ! -d "$VENV_DIR" ]]; then - python3 -m venv "$VENV_DIR" -fi -"$VENV_DIR/bin/pip" install --quiet --upgrade pip -"$VENV_DIR/bin/pip" install --quiet -r "$AGENT_DIR/requirements.txt" - -echo "==> Installing systemd unit" -sudo cp "$SERVICE_FILE" "$SYSTEMD_TARGET" -sudo systemctl daemon-reload - -echo "==> Enabling + starting overlord-agent" -sudo systemctl enable overlord-agent -sudo systemctl restart overlord-agent - -sleep 1 -echo "==> Status:" -sudo systemctl --no-pager status overlord-agent | head -15 - -echo "" -echo "==> Smoke test:" -curl -s http://127.0.0.1:8767/agent/health | python3 -m json.tool || true - -echo "" -echo "Done. Logs: journalctl -u overlord-agent -f" diff --git a/agent/mcp_overlord.py b/agent/mcp_overlord.py deleted file mode 100644 index 320f3131..00000000 --- a/agent/mcp_overlord.py +++ /dev/null @@ -1,293 +0,0 @@ -"""MCP stdio server exposing Overlord data to Claude Code. - -Configured via .mcp.json at the repo root, which Claude Code auto-loads -when invoked with cwd=/home/erik/MosswartOverlord. Tool implementations -live in tools.py β€” this file is just MCP protocol plumbing. - -Run directly with: - python3 /home/erik/MosswartOverlord/agent/mcp_overlord.py -""" - -from __future__ import annotations - -import asyncio -import json -import logging -from typing import Any - -from mcp.server import Server -from mcp.server.stdio import stdio_server -from mcp.types import TextContent, Tool - -from . import tools as T - -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(levelname)s mcp_overlord: %(message)s", -) -logger = logging.getLogger("mcp_overlord") - -server: Server = Server("overlord") - - -# ─── Tool registry ────────────────────────────────────────────────── -# -# Each entry: name β†’ (description, JSON schema, callable async fn). -# We register them with @server.list_tools / @server.call_tool below. - -TOOL_DEFS: dict[str, dict[str, Any]] = { - "get_live_players": { - "description": ( - "Return active characters seen in the last ~30 seconds with their " - "current position, kills, KPH, vitae, online time, and VTank state. " - "Use this for any 'who is online right now / what is X doing' question." - ), - "schema": {"type": "object", "properties": {}}, - "fn": lambda _args: T.get_live_players(), - }, - "get_recent_rares": { - "description": ( - "Return rare item finds from the last N hours, newest first. " - "Use for questions about recent drops, who is finding rares, or " - "rare-rate analysis. Defaults to 24 hours, max 30 days." - ), - "schema": { - "type": "object", - "properties": { - "hours": { - "type": "integer", - "minimum": 1, - "maximum": 720, - "default": 24, - }, - "limit": { - "type": "integer", - "minimum": 1, - "maximum": 200, - "default": 100, - }, - }, - }, - "fn": lambda args: T.get_recent_rares( - hours=int(args.get("hours", 24)), - limit=int(args.get("limit", 100)), - ), - }, - "query_telemetry_db": { - "description": ( - "Run a read-only SQL query against the telemetry database (TimescaleDB). " - "Only SELECT / WITH statements are accepted; any DML or DDL is rejected. " - "Useful for questions that aren't covered by the other tools β€” top-N " - "lists, custom aggregations, time-window comparisons. " - "Available tables include: telemetry_events (hypertable, 30d retention), " - "rare_events, spawn_events (hypertable, 7d retention), portals, " - "char_stats, rare_stats, rare_stats_sessions, character_stats, " - "combat_stats, combat_stats_sessions, server_status. " - "The query has a 10s timeout and returns at most 200 rows." - ), - "schema": { - "type": "object", - "required": ["sql"], - "properties": { - "sql": { - "type": "string", - "description": "A single PostgreSQL SELECT or WITH ... SELECT statement.", - } - }, - }, - "fn": lambda args: T.query_telemetry_db(str(args["sql"])), - }, - "get_player_state": { - "description": ( - "Combined snapshot for ONE character: live telemetry (if online) " - "+ full character stats (attributes, skills, augmentations). " - "Use this for questions like 'what is X doing right now' or 'show me X's stats'." - ), - "schema": { - "type": "object", - "required": ["character_name"], - "properties": { - "character_name": {"type": "string"}, - }, - }, - "fn": lambda args: T.get_player_state(str(args["character_name"])), - }, - "get_inventory": { - "description": ( - "Full inventory listing for one character β€” every item with name, " - "icon, container, equipped slot, spells, material, tinkers, etc. " - "Large response β€” prefer get_inventory_search for narrow queries." - ), - "schema": { - "type": "object", - "required": ["character_name"], - "properties": {"character_name": {"type": "string"}}, - }, - "fn": lambda args: T.get_inventory(str(args["character_name"])), - }, - "get_inventory_search": { - "description": ( - "Filtered inventory search for ONE character. Use search_items " - "instead when the user wants to find something across ALL chars." - ), - "schema": { - "type": "object", - "required": ["character_name"], - "properties": { - "character_name": {"type": "string"}, - "filters": { - "type": "object", - "description": "Query params dict, e.g. {\"name\": \"pearl\", \"armor_level_min\": 500}", - }, - }, - }, - "fn": lambda args: T.get_inventory_search( - str(args["character_name"]), args.get("filters") or {} - ), - }, - "search_items": { - "description": ( - "CROSS-CHARACTER item search β€” one query that scans every " - "character's inventory. Use this whenever the user asks " - "'find me an X on any of my chars'. **Do not** iterate " - "get_inventory per character β€” this single tool call is far " - "faster and avoids agent timeouts.\n\n" - "Filter keys (pass as `filters` object, all optional):\n" - " include_all_characters: true (default if no scope given)\n" - " character: 'Name' (single char)\n" - " characters: 'A,B,C' (specific list, comma-separated)\n" - " text: substring of item name/description\n" - " has_spell: 'Legendary Acid Ward' (exact spell name match)\n" - " spell_contains: 'Legendary' (substring)\n" - " legendary_cantrips: 'Foo,Bar'\n" - " equipment_status: 'equipped' | 'unequipped'\n" - " equipment_slot: int bitmask (4=chest, 2048=bracelet, 4096=ring)\n" - " slot_names: 'Bracelet,Ring'\n" - " armor_only / jewelry_only / weapon_only: bool\n" - " min_armor / max_armor / min_damage / max_damage: int\n" - ), - "schema": { - "type": "object", - "required": ["filters"], - "properties": { - "filters": { - "type": "object", - "description": "Query params dict β€” see tool description for keys.", - }, - }, - }, - "fn": lambda args: T.search_items_global(args.get("filters") or {}), - }, - "get_combat_stats": { - "description": ( - "Lifetime + session combat stats for one character. Includes total " - "damage given/received, per-element offense/defense breakdown, kill " - "counts, and aetheria surge counts." - ), - "schema": { - "type": "object", - "required": ["character_name"], - "properties": {"character_name": {"type": "string"}}, - }, - "fn": lambda args: T.get_combat_stats(str(args["character_name"])), - }, - "get_equipment_cantrips": { - "description": ( - "Currently-equipped items for a character along with their active " - "cantrip/spell state. Useful for 'what is X wearing' or 'is X " - "running their suit' questions." - ), - "schema": { - "type": "object", - "required": ["character_name"], - "properties": {"character_name": {"type": "string"}}, - }, - "fn": lambda args: T.get_equipment_cantrips(str(args["character_name"])), - }, - "get_quest_status": { - "description": ( - "Active quest timers and progress across ALL characters. Returns " - "for each character which quests are READY vs counting down." - ), - "schema": {"type": "object", "properties": {}}, - "fn": lambda _args: T.get_quest_status(), - }, - "get_server_health": { - "description": ( - "Current Coldeve game-server status: up/down, latency in ms, " - "current player count from TreeStats.net, total uptime. Updated " - "every 30 seconds in the background." - ), - "schema": {"type": "object", "properties": {}}, - "fn": lambda _args: T.get_server_health(), - }, - "suitbuilder_search": { - "description": ( - "Run a constraint-satisfaction armor optimization across all " - "characters' inventories ('mules'). Drives the same suitbuilder " - "the /suitbuilder.html page uses. Pass the same params dict the " - "page sends β€” see /suitbuilder.html JS for the schema. The search " - "is SSE-streaming on the backend; this tool collects until done " - "and returns the final suit(s) plus the last few phase events. " - "Can take up to 5 minutes for complex constraints β€” only call " - "when the user explicitly asks for an optimization run." - ), - "schema": { - "type": "object", - "required": ["params"], - "properties": { - "params": { - "type": "object", - "description": "Suitbuilder request body (characters, locked slots, set constraints, etc.)", - }, - }, - }, - "fn": lambda args: T.suitbuilder_search(args.get("params") or {}), - }, -} - - -# ─── MCP protocol wiring ──────────────────────────────────────────── - - -@server.list_tools() -async def list_tools() -> list[Tool]: - return [ - Tool(name=name, description=defn["description"], inputSchema=defn["schema"]) - for name, defn in TOOL_DEFS.items() - ] - - -@server.call_tool() -async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]: - if name not in TOOL_DEFS: - return [TextContent(type="text", text=f"unknown tool: {name}")] - - fn = TOOL_DEFS[name]["fn"] - try: - result = await fn(arguments or {}) - except T.SqlNotAllowed as e: - return [TextContent(type="text", text=f"REJECTED: {e}")] - except Exception as e: # noqa: BLE001 - logger.exception("tool %s failed", name) - return [TextContent(type="text", text=f"ERROR: {type(e).__name__}: {e}")] - - text = json.dumps(result, default=str, ensure_ascii=False, indent=2) - return [TextContent(type="text", text=text)] - - -async def _run() -> None: - logger.info("starting MCP stdio server (overlord)") - try: - async with stdio_server() as (reader, writer): - await server.run(reader, writer, server.create_initialization_options()) - finally: - await T.shutdown() - - -def main() -> None: - asyncio.run(_run()) - - -if __name__ == "__main__": - main() diff --git a/agent/overlord-agent.service b/agent/overlord-agent.service deleted file mode 100644 index 6f40f5dd..00000000 --- a/agent/overlord-agent.service +++ /dev/null @@ -1,113 +0,0 @@ -[Unit] -Description=Overlord Agent (Claude Code shell-out service) -After=network-online.target -Wants=network-online.target - -[Service] -Type=simple -# Dedicated unprivileged user β€” kernel-level isolation from `erik`. -# overlord-agent has NO access to /home/erik/.claude (mode 0700), -# /home/erik/.ssh, /home/erik/.bash_history, /home/erik/.gitconfig, etc. -# Its own claude state lives at /var/lib/overlord-agent/.claude/ and its -# claude session JSONLs land there β€” completely separate from any -# interactive Claude Code use by the human user. -User=overlord-agent -Group=overlord-agent -# Working directory: the repo root (group-readable to overlord-agent). -# claude session JSONLs path-encode this cwd so it's important to keep -# stable across restarts. -WorkingDirectory=/home/erik/MosswartOverlord -# HOME explicitly set so claude reads /var/lib/overlord-agent/.claude/* -# instead of trying /home/erik/.claude/* (which is now 0700, locked out). -Environment="HOME=/var/lib/overlord-agent" -# Secrets file (root:overlord-agent 0640). -EnvironmentFile=-/etc/overlord/agent.env -# Run inside the venv populated by install.sh. -ExecStart=/home/erik/MosswartOverlord/agent/.venv/bin/python -m agent.service -Restart=on-failure -RestartSec=3 -StandardOutput=journal -StandardError=journal - -# ─── Resource caps ───────────────────────────────────────────────── -MemoryMax=512M -CPUQuota=200% -TasksMax=128 - -# ─── Filesystem hardening ────────────────────────────────────────── -# /usr, /boot, /efi become read-only; /etc + /var get a writable overlay -# that's discarded on stop. Subprocesses inherit these protections. -ProtectSystem=strict -ProtectHome=read-only -# Allow writing only to the explicit paths claude / our service need. -# - ~/.claude β€” session JSONL files -# - .venv pycache β€” minor pip cache writes -ReadWritePaths=/var/lib/overlord-agent/.claude -ReadWritePaths=/home/erik/MosswartOverlord/agent/.venv -ReadWritePaths=/var/log/overlord-agent -# StateDirectory creates/owns /var/lib/overlord-agent automatically. -StateDirectory=overlord-agent -LogsDirectory=overlord-agent -LogsDirectoryMode=0755 -PrivateTmp=true -PrivateDevices=true -ProtectClock=true -ProtectKernelTunables=true -ProtectKernelModules=true -ProtectKernelLogs=true -ProtectControlGroups=true -ProtectHostname=true -ProtectProc=invisible -ProcSubset=pid - -# Hide sensitive host paths even if something in the python or claude -# subprocess tree tries to read them. -InaccessiblePaths=/etc/shadow -InaccessiblePaths=/etc/gshadow -InaccessiblePaths=/etc/ssh -InaccessiblePaths=/root -InaccessiblePaths=-/home/erik/.ssh -InaccessiblePaths=-/home/erik/.bash_history -InaccessiblePaths=-/home/erik/.zsh_history - -# ─── Privilege & capability hardening ────────────────────────────── -NoNewPrivileges=true -CapabilityBoundingSet= -AmbientCapabilities= -LockPersonality=true -RestrictRealtime=true -RestrictSUIDSGID=true -RemoveIPC=true -# MemoryDenyWriteExecute would break Node.js (V8 JIT requires W^X -# transitions via mprotect with PROT_EXEC on JITted code pages). Claude -# Code is a Node app, so omit this. Without JIT we'd lose all model -# performance. The other restrictions still prevent shellcode injection -# in practice (no Bash/Write tools, no shellcraft surface). -# MemoryDenyWriteExecute=true ← DO NOT enable; breaks Node V8 JIT -RestrictNamespaces=true - -# ─── Network family restriction ──────────────────────────────────── -# Block raw/packet sockets so even a kernel-LPE-class bug can't sniff -# traffic or forge packets. We don't IPAddressAllow-restrict because -# Anthropic's Cloudflare IPs shift and the whitelist would break claude. -# If you need true egress filtering, run nftables scoped to this -# service's cgroup β€” that's reliable in a way IPAddressAllow isn't. -RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 - -# ─── Syscall filter ──────────────────────────────────────────────── -# Use the standard @system-service preset which is what almost every -# hardened systemd unit uses. It already excludes the dangerous groups -# (privileged, mount, reboot, raw-io, etc.) by NOT including them, while -# being broad enough to host typical apps including Node.js. -# -# We tried adding extra "~@..." negations on top β€” they killed Claude -# (Node) with SIGSYS during startup. The default @system-service preset -# is the right balance; the rest of the hardening covers what we need. -SystemCallArchitectures=native -SystemCallFilter=@system-service -SystemCallFilter=~@privileged -SystemCallFilter=~@reboot -SystemCallFilter=~@mount - -[Install] -WantedBy=multi-user.target diff --git a/agent/requirements.txt b/agent/requirements.txt deleted file mode 100644 index c14e3454..00000000 --- a/agent/requirements.txt +++ /dev/null @@ -1,13 +0,0 @@ -fastapi>=0.110 -uvicorn[standard]>=0.30 -httpx>=0.27 -itsdangerous>=2.2 -pydantic>=2.6 -# MCP server SDK (used by mcp_overlord.py for the stdio MCP server) -mcp>=1.0 -# SQL safety: parses SQL to enforce read-only on the query_db tool -sqlglot>=25.0 -# Direct DB access for the read-only query tool and rare_events lookups -asyncpg>=0.29 -# .env loader -python-dotenv>=1.0 diff --git a/agent/service.py b/agent/service.py deleted file mode 100644 index d2b7d6a0..00000000 --- a/agent/service.py +++ /dev/null @@ -1,347 +0,0 @@ -"""Overlord Agent host-side FastAPI service. - -Runs OUTSIDE Docker (host-side) on port 8767. - -Endpoints: - GET /agent/health β€” liveness check - POST /agent/sessions/new β€” returns a fresh session UUID - POST /agent/ask β€” runs claude -p with given session - GET /agent/sessions/{session_id}/history - β€” replays a session's JSONL on disk - -Auth: every endpoint except /health requires the same browser session -cookie that dereth-tracker issues. -""" - -from __future__ import annotations - -import asyncio -import json -import logging -import os -import time -import uuid -from collections import deque -from pathlib import Path -from typing import Any - -from fastapi import Depends, FastAPI, HTTPException -from fastapi.responses import JSONResponse -from pydantic import BaseModel, Field - -from . import auth -from .claude_wrapper import CLAUDE_CWD, ClaudeError, ask_claude - -logging.basicConfig( - level=logging.INFO, - format="%(asctime)s %(levelname)s %(name)s: %(message)s", -) -logger = logging.getLogger("agent") - -# Audit log β€” every /agent/ask request gets a JSONL line here, separate -# from journald so the operator can grep without root. Set to /dev/null -# to disable. Rotated externally (logrotate) if it gets big. -AUDIT_LOG_PATH = Path(os.getenv("AGENT_AUDIT_LOG", "/var/log/overlord-agent/audit.jsonl")) -audit_logger = logging.getLogger("agent.audit") -try: - AUDIT_LOG_PATH.parent.mkdir(parents=True, exist_ok=True) - _h = logging.FileHandler(AUDIT_LOG_PATH) - _h.setFormatter(logging.Formatter("%(message)s")) - audit_logger.addHandler(_h) - audit_logger.propagate = False - audit_logger.setLevel(logging.INFO) -except OSError as e: - logger.warning("audit log path %s not writable (%s); logging only via journal", AUDIT_LOG_PATH, e) - -# Rate limit: per-user count over a rolling window. Defaults are generous -# for a single human at a keyboard but block automated abuse. -RATE_LIMIT_WINDOW_S = int(os.getenv("AGENT_RATE_WINDOW_S", "3600")) -RATE_LIMIT_MAX = int(os.getenv("AGENT_RATE_MAX", "60")) -# Per-user concurrent request cap (no fanning out 50 calls in parallel). -CONCURRENCY_LIMIT_PER_USER = int(os.getenv("AGENT_CONCURRENCY_PER_USER", "1")) - -# Rolling timestamps of recent /agent/ask calls per user. -_rate_state: dict[str, deque[float]] = {} -# Per-user semaphores so a single user can't run multiple concurrent claude -# subprocesses (each is expensive). -_user_semaphores: dict[str, asyncio.Semaphore] = {} - - -def _check_rate_limit(username: str) -> tuple[bool, int]: - """Return (allowed, retry_after_seconds).""" - now = time.monotonic() - window = _rate_state.setdefault(username, deque()) - cutoff = now - RATE_LIMIT_WINDOW_S - while window and window[0] < cutoff: - window.popleft() - if len(window) >= RATE_LIMIT_MAX: - retry_after = int(window[0] + RATE_LIMIT_WINDOW_S - now) + 1 - return False, retry_after - window.append(now) - return True, 0 - - -def _user_semaphore(username: str) -> asyncio.Semaphore: - sem = _user_semaphores.get(username) - if sem is None: - sem = asyncio.Semaphore(CONCURRENCY_LIMIT_PER_USER) - _user_semaphores[username] = sem - return sem - - -def _audit(event: dict[str, Any]) -> None: - """Emit one JSONL line to the audit log.""" - event["timestamp"] = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()) - try: - audit_logger.info(json.dumps(event, ensure_ascii=False)) - except Exception: # noqa: BLE001 - pass - - -app = FastAPI(title="Overlord Agent", version="0.1.0") - - -# ─── Models ────────────────────────────────────────────────────────── - - -class AskRequest(BaseModel): - session_id: str = Field( - ..., description="Stable per-conversation UUID stored in browser localStorage" - ) - message: str = Field(..., min_length=1, max_length=10_000) - - -class AskResponse(BaseModel): - result: str - session_id: str - duration_ms: int - num_turns: int - is_error: bool - - -class NewSessionResponse(BaseModel): - session_id: str - - -# ─── Helpers ───────────────────────────────────────────────────────── - - -def _encode_cwd(cwd: str) -> str: - """Match Claude Code's on-disk encoding for cwd β†’ directory name. - - Claude Code stores sessions at ~/.claude/projects//.jsonl - where non-alphanumerics in the cwd are replaced with hyphens. - Example: /home/erik/MosswartOverlord β†’ -home-erik-MosswartOverlord - """ - return "".join(c if c.isalnum() else "-" for c in cwd) - - -def _sessions_dir() -> Path: - return Path.home() / ".claude" / "projects" / _encode_cwd(CLAUDE_CWD) - - -# ─── Endpoints ─────────────────────────────────────────────────────── - - -@app.get("/agent/health") -async def health() -> dict: - """Liveness probe β€” no auth, used by deployment scripts.""" - return { - "status": "ok", - "claude_cwd": CLAUDE_CWD, - "sessions_dir_exists": _sessions_dir().exists(), - } - - -@app.post("/agent/sessions/new", response_model=NewSessionResponse) -async def new_session(_user: dict = Depends(auth.require_user)) -> NewSessionResponse: - """Generate a fresh session UUID. Doesn't touch disk β€” claude creates the - JSONL file when the first message lands.""" - return NewSessionResponse(session_id=str(uuid.uuid4())) - - -@app.post("/agent/ask", response_model=AskResponse) -async def agent_ask( - req: AskRequest, user: dict = Depends(auth.require_user) -) -> AskResponse: - """Forward a message to claude -p resuming the given session. - - Enforces: - * Per-user rate limit (60 requests/hour by default). - * Per-user concurrency cap (1 in-flight at a time by default). - * Audit log of every request (JSONL). - """ - username = user["username"] - - # Rate limit BEFORE acquiring the user semaphore β€” cheaper to reject. - allowed, retry_after = _check_rate_limit(username) - if not allowed: - _audit( - { - "event": "rate_limited", - "user": username, - "session_id": req.session_id, - "retry_after_s": retry_after, - } - ) - raise HTTPException( - status_code=429, - detail=f"Rate limit exceeded; retry in {retry_after}s", - headers={"Retry-After": str(retry_after)}, - ) - - sem = _user_semaphore(username) - if sem.locked(): - _audit( - { - "event": "concurrency_blocked", - "user": username, - "session_id": req.session_id, - } - ) - raise HTTPException( - status_code=429, detail="A previous question is still being processed" - ) - - started = time.monotonic() - async with sem: - _audit( - { - "event": "ask_start", - "user": username, - "session_id": req.session_id, - "message": req.message[:500], - "message_len": len(req.message), - } - ) - try: - result = await ask_claude(req.message, req.session_id) - except ClaudeError as e: - elapsed_ms = int((time.monotonic() - started) * 1000) - logger.warning( - "claude failed user=%s session=%s err=%s", username, req.session_id, e - ) - _audit( - { - "event": "ask_error", - "user": username, - "session_id": req.session_id, - "error": str(e)[:500], - "elapsed_ms": elapsed_ms, - } - ) - raise HTTPException(status_code=502, detail=str(e)) - - elapsed_ms = int((time.monotonic() - started) * 1000) - logger.info( - "ask user=%s session=%s turns=%d duration_ms=%d (subprocess=%dms)", - username, - result.session_id, - result.num_turns, - elapsed_ms, - result.duration_ms, - ) - _audit( - { - "event": "ask_ok", - "user": username, - "session_id": result.session_id, - "result_preview": (result.result or "")[:300], - "result_len": len(result.result or ""), - "turns": result.num_turns, - "elapsed_ms": elapsed_ms, - "subprocess_ms": result.duration_ms, - "is_error": result.is_error, - } - ) - - return AskResponse( - result=result.result, - session_id=result.session_id, - duration_ms=result.duration_ms, - num_turns=result.num_turns, - is_error=result.is_error, - ) - - -@app.get("/agent/sessions/{session_id}/history") -async def session_history( - session_id: str, _user: dict = Depends(auth.require_user) -) -> JSONResponse: - """Replay a session's JSONL from ~/.claude/projects/.../.jsonl. - - Returns a flat array of {role, text, timestamp} for the chat window. - Returns an empty array if the session file doesn't exist yet. - """ - # UUID sanity check to prevent path traversal β€” claude Code uses uuid4 - try: - uuid.UUID(session_id) - except ValueError: - raise HTTPException(status_code=400, detail="invalid session_id") - - path = _sessions_dir() / f"{session_id}.jsonl" - if not path.is_file(): - return JSONResponse({"messages": []}) - - messages: list[dict[str, Any]] = [] - try: - with path.open("r", encoding="utf-8") as f: - for line in f: - line = line.strip() - if not line: - continue - try: - obj = json.loads(line) - except json.JSONDecodeError: - continue - # Claude Code records turns with type=user / type=assistant. - # Tool-use traffic is verbose; skip it for the chat UI. - msg_type = obj.get("type") - if msg_type not in ("user", "assistant"): - continue - msg = obj.get("message") or {} - content = msg.get("content") - # `content` may be a string or list[{type,text}]. - if isinstance(content, str): - text = content - elif isinstance(content, list): - text = "".join( - part.get("text", "") - for part in content - if isinstance(part, dict) and part.get("type") == "text" - ) - else: - text = "" - if not text: - continue - messages.append( - { - "role": msg_type, - "text": text, - "timestamp": obj.get("timestamp"), - } - ) - except OSError as e: - logger.warning("failed to read session %s: %s", session_id, e) - raise HTTPException(status_code=500, detail="failed to read session") - - return JSONResponse({"messages": messages}) - - -# ─── Entrypoint ────────────────────────────────────────────────────── - - -def main() -> None: - """Run via `python -m agent.service` for local testing.""" - import uvicorn - - uvicorn.run( - "agent.service:app", - host="127.0.0.1", - port=8767, - log_level="info", - ) - - -if __name__ == "__main__": - main() diff --git a/agent/sql/0001_overlord_agent_ro.sql b/agent/sql/0001_overlord_agent_ro.sql deleted file mode 100644 index b87f9cce..00000000 --- a/agent/sql/0001_overlord_agent_ro.sql +++ /dev/null @@ -1,35 +0,0 @@ --- Read-only PG role for the Overlord Agent's `query_telemetry_db` MCP tool. --- --- This is the second line of defense (the first is the sqlglot parser in --- agent/tools.py:assert_read_only). Even a parser bypass cannot mutate --- because this role only has SELECT. --- --- Apply on the dereth-db container: --- docker exec dereth-db psql -U postgres -d dereth -f - < agent/sql/0001_overlord_agent_ro.sql --- (substitute the password before running, or keep as a placeholder and --- ALTER ROLE … PASSWORD '…' separately) - -DO $$ -BEGIN - IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'overlord_agent_ro') THEN - CREATE ROLE overlord_agent_ro NOINHERIT LOGIN PASSWORD 'change-me-set-via-alter-role'; - END IF; -END$$; - -GRANT CONNECT ON DATABASE dereth TO overlord_agent_ro; -GRANT USAGE ON SCHEMA public TO overlord_agent_ro; - --- Grant SELECT on all current public tables. -GRANT SELECT ON ALL TABLES IN SCHEMA public TO overlord_agent_ro; -GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO overlord_agent_ro; - --- And on any future tables created in public. -ALTER DEFAULT PRIVILEGES IN SCHEMA public - GRANT SELECT ON TABLES TO overlord_agent_ro; - --- TimescaleDB-internal schema (chunks live here). Read on hypertable chunks --- requires SELECT on _timescaledb_internal too. -GRANT USAGE ON SCHEMA _timescaledb_internal TO overlord_agent_ro; -GRANT SELECT ON ALL TABLES IN SCHEMA _timescaledb_internal TO overlord_agent_ro; -ALTER DEFAULT PRIVILEGES IN SCHEMA _timescaledb_internal - GRANT SELECT ON TABLES TO overlord_agent_ro; diff --git a/agent/tools.py b/agent/tools.py deleted file mode 100644 index c7b3b8fe..00000000 --- a/agent/tools.py +++ /dev/null @@ -1,451 +0,0 @@ -"""Tool implementations exposed to Claude via the MCP server. - -These are pure functions β€” the MCP server (mcp_overlord.py) only handles -the protocol wrapping. Keep tool logic here so it's easy to test in -isolation and reuse from elsewhere (e.g. /agent/ask shortcuts). - -Two flavors of data access: - * HTTP loopback to the dereth-tracker container (for endpoints that - already exist and have validated logic). - * Direct asyncpg to the read-only PG role for ad-hoc queries - (rare_events, telemetry, anything not exposed via HTTP). -""" - -from __future__ import annotations - -import asyncio -import json -import logging -import os -from typing import Any -from urllib.parse import quote - -import asyncpg -import httpx -import sqlglot -import sqlglot.errors -import sqlglot.expressions as exp - -logger = logging.getLogger(__name__) - -# The dereth-tracker FastAPI app, reachable from the host because Docker -# port-forwards 127.0.0.1:8765:8765 in docker-compose.yml. -TRACKER_URL = os.getenv("TRACKER_URL", "http://127.0.0.1:8765") - -# Read-only PG role; see deployment plan. -DB_DSN = os.getenv( - "AGENT_DB_DSN", - "postgresql://overlord_agent_ro@127.0.0.1:5432/dereth", -) - -# Hard caps for the SQL tool to keep the agent honest. -SQL_TIMEOUT_S = float(os.getenv("AGENT_SQL_TIMEOUT_S", "10")) -SQL_MAX_ROWS = int(os.getenv("AGENT_SQL_MAX_ROWS", "200")) - - -# ─── HTTP loopback helpers ────────────────────────────────────────── - - -_http_client: httpx.AsyncClient | None = None - - -async def _http() -> httpx.AsyncClient: - """Lazily create + reuse a single httpx client (connection pool).""" - global _http_client - if _http_client is None: - _http_client = httpx.AsyncClient(base_url=TRACKER_URL, timeout=30.0) - return _http_client - - -async def _get_json(path: str) -> Any: - client = await _http() - resp = await client.get(path) - resp.raise_for_status() - return resp.json() - - -# ─── DB helpers ───────────────────────────────────────────────────── - - -_db_pool: asyncpg.Pool | None = None - - -async def _db() -> asyncpg.Pool: - global _db_pool - if _db_pool is None: - _db_pool = await asyncpg.create_pool( - DB_DSN, min_size=1, max_size=4, command_timeout=SQL_TIMEOUT_S - ) - return _db_pool - - -# ─── SQL safety ───────────────────────────────────────────────────── - - -_ALLOWED_TOPLEVEL = tuple( - cls for cls in ( - getattr(exp, "Select", None), - getattr(exp, "With", None), - getattr(exp, "Union", None), - getattr(exp, "Subquery", None), - getattr(exp, "Intersect", None), - getattr(exp, "Except", None), - ) - if cls is not None -) - - -class SqlNotAllowed(ValueError): - """Raised when the agent attempts a non-read-only SQL statement.""" - - -def assert_read_only(sql: str) -> None: - """Parse `sql` and reject anything that isn't a read query. - - Belt-and-suspenders: the PG role is also read-only (GRANT SELECT only), - so even a parser bypass can't actually mutate. This is the first line - of defense β€” friendlier error messages and faster reject. - """ - try: - statements = sqlglot.parse(sql, read="postgres") - except sqlglot.errors.ParseError as e: - raise SqlNotAllowed(f"SQL parse error: {e}") from e - - if not statements: - raise SqlNotAllowed("empty SQL") - if len(statements) > 1: - raise SqlNotAllowed("only one statement allowed") - - stmt = statements[0] - if stmt is None: - raise SqlNotAllowed("empty parse result") - if not isinstance(stmt, _ALLOWED_TOPLEVEL): - raise SqlNotAllowed( - f"only SELECT / WITH allowed, got {type(stmt).__name__}" - ) - - # Walk the tree and reject any DML/DDL hidden inside (e.g. CTE with - # INSERT β€” yes, postgres allows that). Use getattr so version drift - # in sqlglot (renamed classes like AlterTableβ†’Alter) doesn't crash - # the whole tool. - _DENY_NAMES = ( - "Insert", "Update", "Delete", "Drop", "Create", "Merge", - "Alter", "AlterTable", "AlterColumn", "AlterDatabase", - "Truncate", "TruncateTable", - "Grant", "Revoke", - "Copy", # PostgreSQL COPY can write files - ) - deny_classes = tuple( - cls for cls in (getattr(exp, name, None) for name in _DENY_NAMES) - if cls is not None - ) - for node in stmt.walk(): - # walk() returns the node, then in some sqlglot versions a tuple of - # (node, parent, key). Normalize. - actual = node[0] if isinstance(node, tuple) else node - if isinstance(actual, deny_classes): - raise SqlNotAllowed( - f"writes/DDL not allowed (found {type(actual).__name__})" - ) - - -# ─── Tools ────────────────────────────────────────────────────────── - - -async def get_live_players() -> dict[str, Any]: - """Active characters (telemetry seen in the last ~30s). - - Returns the same shape as `GET /live`: - { "players": [ { character_name, ew, ns, z, kills, ... } ] } - """ - return await _get_json("/live") - - -async def get_recent_rares(hours: int = 24, limit: int = 100) -> dict[str, Any]: - """Rare item finds in the last N hours, newest first.""" - hours = max(1, min(int(hours), 24 * 30)) # cap at 30 days - limit = max(1, min(int(limit), SQL_MAX_ROWS)) - pool = await _db() - rows = await pool.fetch( - """ - SELECT timestamp, character_name, name, ew, ns, z - FROM rare_events - WHERE timestamp >= NOW() - ($1::int || ' hours')::interval - ORDER BY timestamp DESC - LIMIT $2 - """, - hours, - limit, - ) - return { - "hours": hours, - "count": len(rows), - "rares": [ - { - "timestamp": r["timestamp"].isoformat(), - "character_name": r["character_name"], - "name": r["name"], - "ew": r["ew"], - "ns": r["ns"], - "z": r["z"], - } - for r in rows - ], - } - - -async def query_telemetry_db(sql: str) -> dict[str, Any]: - """Run a read-only SQL statement against the telemetry DB. - - The query is parsed and any non-SELECT/WITH statement is rejected. - The connection role is also GRANT SELECT only (defense in depth). - - Useful for ad-hoc questions: "top 5 KPH today", "kill count by character - yesterday", etc. - """ - assert_read_only(sql) - pool = await _db() - try: - rows = await asyncio.wait_for(pool.fetch(sql), timeout=SQL_TIMEOUT_S) - except asyncio.TimeoutError: - raise SqlNotAllowed(f"query exceeded {SQL_TIMEOUT_S:.0f}s timeout") - - if len(rows) > SQL_MAX_ROWS: - rows = rows[:SQL_MAX_ROWS] - truncated = True - else: - truncated = False - - return { - "row_count": len(rows), - "truncated": truncated, - "rows": [ - {k: _json_safe(v) for k, v in dict(r).items()} for r in rows - ], - } - - -def _json_safe(v: Any) -> Any: - """Convert datetime / Decimal / etc. to JSON-friendly types.""" - from datetime import date, datetime, timedelta - from decimal import Decimal - - if v is None: - return None - if isinstance(v, (str, int, float, bool)): - return v - if isinstance(v, (datetime, date)): - return v.isoformat() - if isinstance(v, timedelta): - return v.total_seconds() - if isinstance(v, Decimal): - return float(v) - if isinstance(v, (list, tuple)): - return [_json_safe(x) for x in v] - if isinstance(v, dict): - return {k: _json_safe(x) for k, x in v.items()} - return str(v) - - -# ─── Per-character lookups (HTTP loopback) ────────────────────────── - - -async def get_player_state(character_name: str) -> dict[str, Any]: - """Combined snapshot for one character: live telemetry + character stats. - - Returns: - { - "character_name": str, - "telemetry": {...} | None, # from /live, or None if offline - "character_stats": {...} | None, # from /character-stats/ - "vitals": {...} | None, # last vitals from /live (subset) - "online": bool, # whether telemetry was found in /live - } - """ - name = character_name.strip() - live = await _get_json("/live") - players = live.get("players", []) if isinstance(live, dict) else [] - telemetry = next( - (p for p in players if p.get("character_name") == name), None - ) - - char_stats: dict[str, Any] | None = None - try: - client = await _http() - resp = await client.get(f"/character-stats/{quote(name, safe='')}") - if resp.status_code == 200: - char_stats = resp.json() - except Exception: - char_stats = None - - return { - "character_name": name, - "online": telemetry is not None, - "telemetry": telemetry, - "character_stats": char_stats, - } - - -async def get_inventory(character_name: str) -> dict[str, Any]: - """Full inventory for one character. Items only β€” for filtered queries - use get_inventory_search.""" - client = await _http() - resp = await client.get(f"/inventory/{quote(character_name, safe='')}") - resp.raise_for_status() - return resp.json() - - -async def get_inventory_search( - character_name: str, filters: dict[str, Any] | None = None -) -> dict[str, Any]: - """Filtered inventory search. `filters` is a dict of query params, e.g. - {"name": "pearl", "armor_level_min": 500}. - - Caller is expected to know the supported filters from the dereth-tracker - /inventory/{name}/search route β€” pass through opaquely. - """ - client = await _http() - resp = await client.get( - f"/inventory/{quote(character_name, safe='')}/search", - params=filters or {}, - ) - resp.raise_for_status() - return resp.json() - - -async def search_items_global(filters: dict[str, Any]) -> dict[str, Any]: - """Cross-character item search via the inventory service's /search/items. - - Use this INSTEAD of looping per-character when the user asks "find an X - on any of my chars" β€” one DB query vs. 60+ HTTP roundtrips. - - Common filter keys (passed straight through as query params): - include_all_characters: bool (set true to search every char) - character: str (single char) | characters: "A,B,C" - text: str (name/description substring) - has_spell: "Legendary Acid Ward" β€” exact spell name - spell_contains: "Legendary" β€” substring match - legendary_cantrips: "Foo,Bar" - equipment_status: "equipped" | "unequipped" - equipment_slot: int (bitmask: 4=chest, 2048=bracelet, 4096=ring, ...) - slot_names: "Bracelet,Ring" - armor_only / jewelry_only / weapon_only: bool - min_armor / max_armor / min_damage / max_damage: int - ...and many more β€” see /search/items endpoint docs. - """ - client = await _http() - # Default to all-character search if caller didn't scope; otherwise the - # endpoint refuses with a 400. - params = dict(filters or {}) - if not any( - k in params - for k in ("character", "characters", "include_all_characters") - ): - params["include_all_characters"] = True - resp = await client.get("/search/items", params=params) - resp.raise_for_status() - return resp.json() - - -async def get_combat_stats(character_name: str) -> dict[str, Any]: - """Lifetime + session combat stats for one character (per-element split, - monster encounters, surge counts).""" - client = await _http() - resp = await client.get(f"/combat-stats/{quote(character_name, safe='')}") - resp.raise_for_status() - return resp.json() - - -async def get_equipment_cantrips(character_name: str) -> dict[str, Any]: - """Currently-equipped items + their active cantrip/spell state.""" - client = await _http() - resp = await client.get( - f"/equipment-cantrip-state/{quote(character_name, safe='')}" - ) - resp.raise_for_status() - return resp.json() - - -async def get_quest_status() -> dict[str, Any]: - """All characters' active quest timers and progress.""" - return await _get_json("/quest-status") - - -async def get_server_health() -> dict[str, Any]: - """Coldeve server status: up/down, latency, current player count, uptime.""" - return await _get_json("/server-health") - - -async def suitbuilder_search( - params: dict[str, Any], max_phase_events: int = 50 -) -> dict[str, Any]: - """Drive a suitbuilder constraint search synchronously. - - The dereth-tracker /inv/suitbuilder/search endpoint is an SSE stream. - We collect events until the stream closes, drop intermediate phase - chatter (keeping the last N), and return: - - { "final_suits": [...], "phases": [...latest few...] } - - `params` is the JSON body the suitbuilder expects. Call it like the - /suitbuilder.html page does. - """ - client = await _http() - final: list[dict[str, Any]] = [] - phases: list[dict[str, Any]] = [] - - # Use a fresh long-timeout client for the SSE stream β€” don't tie up the - # shared pool for a 5-minute search. - async with httpx.AsyncClient( - base_url=TRACKER_URL, timeout=httpx.Timeout(300.0, connect=10.0) - ) as stream_client: - async with stream_client.stream( - "POST", - "/inv/suitbuilder/search", - json=params, - headers={"Content-Type": "application/json"}, - ) as resp: - event_name = "message" - data_lines: list[str] = [] - async for line_bytes in resp.aiter_lines(): - line = line_bytes.rstrip("\r") - if line.startswith("event:"): - event_name = line[6:].strip() - elif line.startswith("data:"): - data_lines.append(line[5:].strip()) - elif line == "": - # Dispatch - if data_lines: - try: - payload = json.loads("\n".join(data_lines)) - except json.JSONDecodeError: - payload = {"raw": "\n".join(data_lines)} - if event_name == "result" or event_name == "final": - final.append(payload) - elif event_name == "error": - phases.append({"event": "error", "data": payload}) - else: - phases.append({"event": event_name, "data": payload}) - phases = phases[-max_phase_events:] - data_lines = [] - event_name = "message" - - return { - "final_suits": final, - "phases": phases[-max_phase_events:], - "phase_count": len(phases), - } - - -# ─── Cleanup ──────────────────────────────────────────────────────── - - -async def shutdown() -> None: - """Close shared resources. Call from MCP server lifespan / on exit.""" - global _http_client, _db_pool - if _http_client is not None: - await _http_client.aclose() - _http_client = None - if _db_pool is not None: - await _db_pool.close() - _db_pool = None diff --git a/db_async.py b/db_async.py index f2c28ab7..998d6707 100644 --- a/db_async.py +++ b/db_async.py @@ -3,7 +3,6 @@ Defines table schemas via SQLAlchemy Core and provides an initialization function to set up TimescaleDB hypertable. """ - import os import sqlalchemy from datetime import datetime, timedelta, timezone @@ -11,12 +10,9 @@ from databases import Database from sqlalchemy import MetaData, Table, Column, Integer, String, Float, DateTime, text from sqlalchemy import Index, BigInteger, JSON, Boolean, UniqueConstraint from sqlalchemy.sql import func -import bcrypt as _bcrypt # Environment: Postgres/TimescaleDB connection URL -DATABASE_URL = os.getenv( - "DATABASE_URL", "postgresql://postgres:password@localhost:5432/dereth" -) +DATABASE_URL = os.getenv("DATABASE_URL", "postgresql://postgres:password@localhost:5432/dereth") # Async database client with explicit connection pool configuration and query timeout database = Database(DATABASE_URL, min_size=5, max_size=100, command_timeout=120) # Metadata for SQLAlchemy Core @@ -52,9 +48,9 @@ telemetry_events = Table( ) # Composite index to accelerate Grafana queries filtering by character_name then ordering by timestamp Index( - "ix_telemetry_events_char_ts", + 'ix_telemetry_events_char_ts', telemetry_events.c.character_name, - telemetry_events.c.timestamp, + telemetry_events.c.timestamp ) # Table for persistent total kills per character @@ -83,26 +79,6 @@ rare_stats_sessions = Table( Column("session_id", String, primary_key=True), Column("session_rares", Integer, nullable=False, default=0), ) -# Per-character persistent combat stats (lifetime accumulation, Mag-Tools style) -combat_stats = Table( - "combat_stats", - metadata, - Column("character_name", String, primary_key=True), - Column("timestamp", DateTime(timezone=True), nullable=False), - Column("stats_data", JSON, nullable=False), -) - -# Per-session combat stats snapshots (session history) -combat_stats_sessions = Table( - "combat_stats_sessions", - metadata, - Column("id", Integer, primary_key=True), - Column("character_name", String, nullable=False, index=True), - Column("session_id", String, nullable=False, index=True), - Column("timestamp", DateTime(timezone=True), nullable=False, index=True), - Column("stats_data", JSON, nullable=False), -) - # Table for recording spawn events (mob creates) for heatmap analysis spawn_events = Table( # Records individual mob spawn occurrences for heatmap and analysis @@ -165,8 +141,20 @@ portals = Table( Column("discovered_by", String, nullable=False), ) -# Server health monitoring: only current state is kept. -# Historical health checks were removed β€” nothing read from them. +# Server health monitoring tables +server_health_checks = Table( + # Time-series data for server health checks + "server_health_checks", + metadata, + Column("id", Integer, primary_key=True), + Column("server_name", String, nullable=False, index=True), + Column("server_address", String, nullable=False), + Column("timestamp", DateTime(timezone=True), nullable=False, default=sqlalchemy.func.now()), + Column("status", String(10), nullable=False), # 'up' or 'down' + Column("latency_ms", Float, nullable=True), + Column("player_count", Integer, nullable=True), +) + server_status = Table( # Current server status and uptime tracking "server_status", @@ -181,13 +169,18 @@ server_status = Table( Column("last_player_count", Integer, nullable=True), ) +# Index for efficient server health check queries +Index( + 'ix_server_health_checks_name_ts', + server_health_checks.c.server_name, + server_health_checks.c.timestamp.desc() +) + character_stats = Table( "character_stats", metadata, Column("character_name", String, primary_key=True, nullable=False), - Column( - "timestamp", DateTime(timezone=True), nullable=False, server_default=func.now() - ), + Column("timestamp", DateTime(timezone=True), nullable=False, server_default=func.now()), Column("level", Integer, nullable=True), Column("total_xp", BigInteger, nullable=True), Column("unassigned_xp", BigInteger, nullable=True), @@ -197,20 +190,6 @@ character_stats = Table( Column("stats_data", JSON, nullable=False), ) -# User accounts for app-level authentication -users = Table( - "users", - metadata, - Column("id", Integer, primary_key=True), - Column("username", String, nullable=False, unique=True), - Column("password_hash", String, nullable=False), - Column("is_admin", Boolean, nullable=False, default=False), - Column( - "created_at", DateTime(timezone=True), nullable=False, server_default=func.now() - ), -) - - async def init_db_async(): """Initialize PostgreSQL/TimescaleDB schema and hypertable. @@ -233,12 +212,10 @@ async def init_db_async(): print(f"Warning: failed to create extension timescaledb: {e}") # Convert to hypertable, migrating existing data and skipping default index creation try: - conn.execute( - text( - "SELECT create_hypertable('telemetry_events', 'timestamp', " - "if_not_exists => true, migrate_data => true, create_default_indexes => false)" - ) - ) + conn.execute(text( + "SELECT create_hypertable('telemetry_events', 'timestamp', " + "if_not_exists => true, migrate_data => true, create_default_indexes => false)" + )) except Exception as e: print(f"Warning: failed to create hypertable telemetry_events: {e}") except Exception as e: @@ -246,82 +223,44 @@ async def init_db_async(): # Ensure composite index exists for efficient time-series queries by character try: with engine.connect() as conn: - conn.execute( - text( - "CREATE INDEX IF NOT EXISTS ix_telemetry_events_char_ts " - "ON telemetry_events (character_name, timestamp)" - ) - ) + conn.execute(text( + "CREATE INDEX IF NOT EXISTS ix_telemetry_events_char_ts " + "ON telemetry_events (character_name, timestamp)" + )) except Exception as e: - print( - f"Warning: failed to create composite index ix_telemetry_events_char_ts: {e}" - ) + print(f"Warning: failed to create composite index ix_telemetry_events_char_ts: {e}") # Add retention and compression policies on the hypertable try: with engine.connect().execution_options(isolation_level="AUTOCOMMIT") as conn: # Retain only recent data (default 7 days or override via DB_RETENTION_DAYS) - days = int(os.getenv("DB_RETENTION_DAYS", "7")) - conn.execute( - text( - f"SELECT add_retention_policy('telemetry_events', INTERVAL '{days} days')" - ) - ) + days = int(os.getenv('DB_RETENTION_DAYS', '7')) + conn.execute(text( + f"SELECT add_retention_policy('telemetry_events', INTERVAL '{days} days')" + )) # Compress chunks older than 1 day - conn.execute( - text( - "SELECT add_compression_policy('telemetry_events', INTERVAL '1 day')" - ) - ) + conn.execute(text( + "SELECT add_compression_policy('telemetry_events', INTERVAL '1 day')" + )) except Exception as e: print(f"Warning: failed to set retention/compression policies: {e}") - - # Ensure spawn_events is a hypertable with a 7-day retention policy. - # This is idempotent β€” if already a hypertable, create_hypertable is a no-op - # when if_not_exists=TRUE. The existing 482M-row table needed a manual - # migration (see docs/plans/spawn_events_cleanup.md); this block keeps the - # policy alive on subsequent deploys. - try: - with engine.connect().execution_options(isolation_level="AUTOCOMMIT") as conn: - # Try to convert spawn_events to a hypertable if it isn't already. - # migrate_data=FALSE is safe because the manual migration handled it; - # if someone creates a fresh DB, the table is empty and this converts it. - conn.execute( - text( - "SELECT create_hypertable('spawn_events', 'timestamp', " - "if_not_exists => TRUE, migrate_data => FALSE, " - "chunk_time_interval => INTERVAL '1 day')" - ) - ) - # 7-day retention - conn.execute( - text( - "SELECT add_retention_policy('spawn_events', INTERVAL '7 days', if_not_exists => TRUE)" - ) - ) - except Exception as e: - print(f"Warning: failed to set spawn_events hypertable/retention: {e}") - + # Create unique constraint on rounded portal coordinates try: with engine.connect().execution_options(isolation_level="AUTOCOMMIT") as conn: # Drop old portal_discoveries table if it exists conn.execute(text("DROP TABLE IF EXISTS portal_discoveries CASCADE")) - + # Create unique constraint on rounded coordinates for the new portals table - conn.execute( - text( - """CREATE UNIQUE INDEX IF NOT EXISTS unique_portal_coords + conn.execute(text( + """CREATE UNIQUE INDEX IF NOT EXISTS unique_portal_coords ON portals (ROUND(ns::numeric, 2), ROUND(ew::numeric, 2))""" - ) - ) - + )) + # Create index on coordinates for efficient lookups - conn.execute( - text( - "CREATE INDEX IF NOT EXISTS idx_portals_coords ON portals (ns, ew)" - ) - ) - + conn.execute(text( + "CREATE INDEX IF NOT EXISTS idx_portals_coords ON portals (ns, ew)" + )) + print("Portal table indexes and constraints created successfully") except Exception as e: print(f"Warning: failed to create portal table constraints: {e}") @@ -329,8 +268,7 @@ async def init_db_async(): # Ensure character_stats table exists with JSONB column type try: with engine.connect().execution_options(isolation_level="AUTOCOMMIT") as conn: - conn.execute( - text(""" + conn.execute(text(""" CREATE TABLE IF NOT EXISTS character_stats ( character_name VARCHAR(255) PRIMARY KEY, timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(), @@ -342,60 +280,25 @@ async def init_db_async(): deaths INTEGER, stats_data JSONB NOT NULL ) - """) - ) + """)) print("character_stats table created/verified successfully") except Exception as e: print(f"Warning: failed to create character_stats table: {e}") - async def cleanup_old_portals(): """Clean up portals older than 1 hour.""" try: cutoff_time = datetime.now(timezone.utc) - timedelta(hours=1) - + # Delete old portals result = await database.execute( "DELETE FROM portals WHERE discovered_at < :cutoff_time", - {"cutoff_time": cutoff_time}, + {"cutoff_time": cutoff_time} ) - + print(f"Cleaned up {result} portals older than 1 hour") return result - + except Exception as e: print(f"Warning: failed to cleanup old portals: {e}") - return 0 - - -async def seed_users(): - """Seed default users if the users table is empty.""" - try: - count = await database.fetch_val("SELECT COUNT(*) FROM users") - if count > 0: - print(f"Users table already has {count} users, skipping seed") - return - - default_users = [ - {"username": "erik", "password": "erik123", "is_admin": True}, - {"username": "alex", "password": "AlexGillar100Killar", "is_admin": False}, - { - "username": "lundberg", - "password": "JohanGillar100Kvinnor", - "is_admin": False, - }, - ] - for u in default_users: - pw_hash = _bcrypt.hashpw(u["password"].encode(), _bcrypt.gensalt()).decode() - await database.execute( - "INSERT INTO users (username, password_hash, is_admin) VALUES (:username, :password_hash, :is_admin)", - { - "username": u["username"], - "password_hash": pw_hash, - "is_admin": u["is_admin"], - }, - ) - role = "admin" if u["is_admin"] else "user" - print(f"Seeded {role} user: {u['username']}") - except Exception as e: - print(f"Warning: failed to seed users: {e}") + return 0 \ No newline at end of file diff --git a/deploy-frontend.sh b/deploy-frontend.sh deleted file mode 100644 index 144f81ad..00000000 --- a/deploy-frontend.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash -# Build frontend and deploy to static/ β€” run from MosswartOverlord root -set -e - -echo "Building frontend..." -cd frontend && npm run build && cd .. - -echo "Syncing build output to static/..." -rm -rf static/assets/ -cp static/_build/index.html static/index.html -cp -r static/_build/assets/ static/assets/ -cp static/_build/sw.js static/sw.js 2>/dev/null || true -rm -rf static/_build/ - -echo "Done! $(ls static/assets/ | wc -l) asset files deployed." -echo "Run 'git add static/ && git commit && git push' to deploy to server." diff --git a/discord-rare-monitor/discord_rare_monitor.py b/discord-rare-monitor/discord_rare_monitor.py index 6d9ae66c..7063691c 100644 --- a/discord-rare-monitor/discord_rare_monitor.py +++ b/discord-rare-monitor/discord_rare_monitor.py @@ -293,15 +293,7 @@ class DiscordRareMonitor: # Send connection established message await self.post_status_to_aclog("πŸ”— WebSocket connection established") - - # Subscribe only to message types we care about (rare + chat) - # This dramatically reduces network traffic vs receiving the full firehose - await websocket.send(json.dumps({ - "type": "subscribe", - "message_types": ["rare", "chat"] - })) - logger.info("πŸ“‹ Subscribed to message types: rare, chat") - + # Simple message processing with comprehensive error handling try: message_count = 0 diff --git a/docker-compose.yml b/docker-compose.yml index 43ff02a5..1f04d940 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -26,10 +26,8 @@ services: DB_MAX_SQL_VARIABLES: "${DB_MAX_SQL_VARIABLES}" DB_WAL_AUTOCHECKPOINT_PAGES: "${DB_WAL_AUTOCHECKPOINT_PAGES}" SHARED_SECRET: "${SHARED_SECRET}" - SECRET_KEY: "${SECRET_KEY}" + LOG_LEVEL: "DEBUG" INVENTORY_SERVICE_URL: "http://inventory-service:8000" - DISCORD_ACLOG_WEBHOOK: "${DISCORD_ACLOG_WEBHOOK:-}" - LOG_LEVEL: "INFO" restart: unless-stopped logging: driver: "json-file" @@ -41,19 +39,6 @@ services: db: image: timescale/timescaledb:2.19.3-pg14 container_name: dereth-db - # Override PostgreSQL memory settings. The default timescaledb-tune values - # targeted a much larger machine β€” shared_buffers was set to 96GB on a - # 32GB host, causing the kernel to swap-thrash and leaving <100MB free. - # These values follow the standard recommendation: shared_buffers ~25% RAM, - # effective_cache_size ~50% RAM, work_mem modest to avoid multiplication - # blow-up across the ~20-connection pool. - command: > - postgres - -c shared_buffers=8GB - -c effective_cache_size=16GB - -c work_mem=16MB - -c maintenance_work_mem=1GB - -c max_wal_size=4GB environment: POSTGRES_DB: dereth POSTGRES_USER: postgres @@ -85,7 +70,7 @@ services: - "./inventory-service:/app" environment: DATABASE_URL: "postgresql://inventory_user:${INVENTORY_DB_PASSWORD}@inventory-db:5432/inventory_db" - LOG_LEVEL: "INFO" + LOG_LEVEL: "DEBUG" restart: unless-stopped logging: driver: "json-file" diff --git a/docs/suitbuilder.md b/docs/suitbuilder.md deleted file mode 100644 index 9a831346..00000000 --- a/docs/suitbuilder.md +++ /dev/null @@ -1,219 +0,0 @@ -# Suitbuilder Algorithm - -The suitbuilder finds optimal equipment loadouts across multiple characters' inventories. It fills 17 equipment slots (9 armor, 6 jewelry, 2 clothing) using a constraint satisfaction solver with depth-first search and branch pruning. - -## Search Pipeline - -The search runs in 5 phases, streamed to the browser via SSE: - -1. **Load items** - Fetch from inventory API (armor by set, jewelry by slot type, clothing DR3-only) -2. **Create buckets** - Group items into 17 slot buckets, expand multi-slot items -3. **Apply reductions** - Generate tailored variants of multi-coverage armor pieces -4. **Sort buckets** - Order buckets and items within them for optimal pruning -5. **Recursive search** - Depth-first search with backtracking, streaming top 10 results - -## Item Loading - -Items are fetched from the internal inventory API (`localhost:8000/search/items`) in four batches: - -| Batch | Filter | Notes | -|-------|--------|-------| -| Primary set armor | `item_set={name}` | All armor in user's primary set | -| Secondary set armor | `item_set={name}` | All armor in user's secondary set | -| Clothing | `shirt_only` / `pants_only` | Only DR3+ shirts and pants | -| Jewelry | `jewelry_only` + `slot_names={type}` | Rings, bracelets, necklaces, trinkets separately | - -After loading, a **domination pre-filter** removes items that are strictly worse than another item in the same slot with the same set. Item A is "surpassed" by item B when B has equal-or-better spells (Legendary > Epic > Major), equal-or-better ratings, equal-or-better armor, and is strictly better in at least one category. - -## Bucket Creation - -Each of the 17 slots gets a bucket. Items are assigned to buckets with special handling: - -- **Multi-slot items** (e.g., "Left Wrist, Right Wrist") are cloned into each applicable slot bucket -- **Generic jewelry** ("Ring" -> Left Ring + Right Ring, "Bracelet" -> Left Wrist + Right Wrist) -- **Robes** (6+ coverage areas) are excluded entirely - they can't be reduced to single slots - -All 17 buckets are created even if empty, allowing the search to produce incomplete suits when no valid item exists for a slot. - -## Armor Reduction (Tailoring) - -Multi-coverage armor can be tailored to fit a single slot. Only loot-generated items (those with a `material`) are eligible. Reduction patterns follow Mag-SuitBuilder logic: - -| Original Coverage | Reduces To | -|---|---| -| Upper Arms + Lower Arms | Upper Arms **or** Lower Arms | -| Upper Legs + Lower Legs | Upper Legs **or** Lower Legs | -| Lower Legs + Feet | Feet | -| Chest + Abdomen | Chest | -| Chest + Abdomen + Upper Arms | Chest | -| Chest + Upper Arms + Lower Arms | Chest | -| Chest + Upper Arms | Chest | -| Abdomen + Upper Legs + Lower Legs | Abdomen **or** Upper Legs **or** Lower Legs | -| Chest + Abdomen + Upper Arms + Lower Arms (hauberks) | Chest | -| Abdomen + Upper Legs | Abdomen | - -Reduced items are added to the target slot's bucket as `"Item Name (tailored to Slot)"`. - -## Bucket Sort Order - -### Bucket ordering (which slot to fill first) - -Buckets are searched in this priority: - -1. **Core armor** - Chest, Head, Hands, Feet, Upper Arms, Lower Arms, Abdomen, Upper Legs, Lower Legs -2. **Jewelry** - Neck, Left Ring, Right Ring, Left Wrist, Right Wrist, Trinket -3. **Clothing** - Shirt, Pants - -Within each category, buckets are further sorted by their position in the priority list (not by item count). This means armor slots are always filled before jewelry, and jewelry before clothing. - -### Item ordering within each bucket - -Items within a bucket are sorted to try the best candidates first. The sort depends on slot type: - -| Slot Type | Sort Priority (highest first) | -|-----------|-------------------------------| -| **Armor** | User's primary set > secondary set > others, then crit damage rating desc, then damage rating desc, then armor level desc | -| **Jewelry** | Spell count desc, then total ratings desc | -| **Clothing** (Shirt/Pants) | Damage rating desc, then spell count desc, then other ratings desc | - -All sorts include `(character_name, name)` as final tiebreakers for deterministic results. - -## Recursive Search - -The solver uses depth-first search with backtracking across the ordered buckets: - -``` -for each bucket (slot) in order: - for each item in bucket: - if item passes constraints: - add item to suit state - recurse to next bucket - remove item (backtrack) - if no items were accepted: - skip this slot (allow incomplete suits) - recurse to next bucket -``` - -When all buckets are processed, the suit is scored and kept if it ranks in the top N (default 10). - -### Branch Pruning - -Two pruning strategies cut off hopeless branches early: - -1. **Mag-SuitBuilder style**: If `current_items + 1 < highest_armor_count_seen - remaining_armor_buckets`, prune. This ensures we don't explore branches that can't produce suits with enough armor pieces. - -2. **Max-items pruning**: If `current_items + remaining_buckets < best_suit_item_count`, prune. The branch can't produce a suit with more items than the best found so far. - -### Item Acceptance Rules (`can_add_item`) - -An item must pass all of these checks: - -1. **Slot available** - The slot must not already be occupied in the current suit state -2. **Item uniqueness** - The same physical item (by ID) can't appear in multiple slots -3. **Set membership** (armor only): - - Primary set items: accepted up to effective limit (5 minus locked primary pieces) - - Secondary set items: accepted up to effective limit (4 minus locked secondary pieces) - - Other set items: **rejected** for armor slots, allowed for jewelry only if they contribute required spells - - No-set items: **rejected** for armor, allowed for clothing always, allowed for jewelry only if they contribute required spells -4. **Spell contribution** (when required spells are specified): - - Items with spells must contribute at least one **new** required spell not already covered by the current suit - - Items where all spells are duplicates of already-covered spells are **rejected**, even from the target sets - - Jewelry has an additional gate: it must contribute an uncovered required spell or it's rejected (empty slot preferred over useless jewelry) - -### Locked Slots - -Users can lock specific slots with a predetermined set and/or spells. Locked slots are: -- Removed from the bucket list (not searched) -- Their set contributions are subtracted from set requirements (e.g., 2 locked primary pieces means only 3 more needed) -- Their spells are counted as already fulfilled - -## Scoring - -The scoring system determines suit ranking. Points are awarded in this priority order: - -### 1. Set Completion (highest weight) - -| Condition | Points | -|-----------|--------| -| Primary set complete (found pieces >= effective need) | **+1000** | -| Secondary set complete | **+1000** | -| Missing primary piece | **-200** per missing piece | -| Missing secondary piece | **-200** per missing piece | -| Excess primary pieces (beyond 5) | **-500** per excess piece | -| Excess secondary pieces (beyond 4) | **-500** per excess piece | - -### 2. Crit Damage Rating (armor pieces) - -| Rating | Points | -|--------|--------| -| CD1 (crit_damage_rating = 1) | **+10** per piece | -| CD2 (crit_damage_rating = 2) | **+20** per piece | - -### 3. Damage Rating (clothing only - Shirt/Pants) - -| Rating | Points | -|--------|--------| -| DR1 | **+10** per piece | -| DR2 | **+20** per piece | -| DR3 | **+30** per piece | - -### 4. Spell Coverage - -| Condition | Points | -|-----------|--------| -| Each fulfilled required spell | **+100** | - -### 5. Base Item Score - -| Condition | Points | -|-----------|--------| -| Each item in the suit | **+5** | - -### 6. Armor Level (tiebreaker only) - -| Condition | Points | -|-----------|--------| -| Total armor level | **+1 per 100 AL** (e.g., 4500 AL = +45) | - -Score is floored at 0 (never negative). - -### Practical Effect of Scoring Weights - -The weights create this effective priority: - -1. **Complete sets matter most** - A suit with both sets complete (+2000) always beats one with a missing piece, regardless of other stats -2. **Spells matter second** - Each required cantrip/ward is worth +100, so 10 spells = +1000 (equivalent to one complete set) -3. **Crit damage and damage rating are tiebreakers** - CD2 on all 9 armor pieces = +180, DR3 on both clothes = +60 -4. **Armor level barely matters** - Only ~45 points for a full suit of 4500 AL; it only breaks ties between otherwise-equal suits - -## Frontend Display - -Results stream in as SSE events. The frontend maintains a sorted list of top 10 suits: - -- New suits are inserted in score-ordered position (highest first) -- If the list is full (10 suits) and the new suit scores lower than all existing ones, it's discarded -- Medals are assigned by position: gold/silver/bronze for top 3 - -### Score Display Classes - -| Score Range | CSS Class | -|-------------|-----------| -| >= 90 | `excellent` | -| >= 75 | `good` | -| >= 60 | `fair` | -| < 60 | `poor` | - -### Item Display - -Each suit shows a table with all 17 slots. Per item: -- **Armor pieces**: Show CD (crit damage) and CDR (crit damage resist) ratings -- **Clothing pieces**: Show DR (damage rating) and DRR (damage resist rating) -- **Spells**: Show up to 2 Legendary/Epic spells, then "+N more" -- **Multi-slot items** that need tailoring are marked with an asterisk (*) - -### Suit Selection - -Clicking a suit populates the right-panel equipment slots visual. Users can then: -- Lock slots (preserving set/spell info for re-searches) -- Copy suit summary to clipboard -- Clear individual slots diff --git a/frontend/.gitignore b/frontend/.gitignore deleted file mode 100644 index b9470778..00000000 --- a/frontend/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -dist/ diff --git a/frontend/index.html b/frontend/index.html deleted file mode 100644 index 80ddde45..00000000 --- a/frontend/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - Mosswart Overlord v2 - - - - - - -
- - - diff --git a/frontend/package-lock.json b/frontend/package-lock.json deleted file mode 100644 index 31e191b7..00000000 --- a/frontend/package-lock.json +++ /dev/null @@ -1,1827 +0,0 @@ -{ - "name": "mosswart-overlord-v2", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "mosswart-overlord-v2", - "version": "0.1.0", - "dependencies": { - "react": "^19.1.0", - "react-dom": "^19.1.0" - }, - "devDependencies": { - "@types/react": "^19.1.2", - "@types/react-dom": "^19.1.2", - "@vitejs/plugin-react": "^4.4.1", - "typescript": "~5.8.3", - "vite": "^6.3.3" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.28.5", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", - "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", - "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-module-transforms": "^7.28.6", - "@babel/helpers": "^7.28.6", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/traverse": "^7.29.0", - "@babel/types": "^7.29.0", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/generator": { - "version": "7.29.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", - "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.29.0", - "@babel/types": "^7.29.0", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", - "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", - "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", - "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", - "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", - "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", - "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.29.0" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", - "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", - "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", - "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.28.6", - "@babel/parser": "^7.28.6", - "@babel/types": "^7.28.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", - "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", - "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@rolldown/pluginutils": { - "version": "1.0.0-beta.27", - "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", - "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz", - "integrity": "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz", - "integrity": "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz", - "integrity": "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz", - "integrity": "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz", - "integrity": "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz", - "integrity": "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz", - "integrity": "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz", - "integrity": "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz", - "integrity": "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz", - "integrity": "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz", - "integrity": "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz", - "integrity": "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz", - "integrity": "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz", - "integrity": "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz", - "integrity": "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz", - "integrity": "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz", - "integrity": "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz", - "integrity": "sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz", - "integrity": "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-openbsd-x64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz", - "integrity": "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ] - }, - "node_modules/@rollup/rollup-openharmony-arm64": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz", - "integrity": "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz", - "integrity": "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz", - "integrity": "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz", - "integrity": "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz", - "integrity": "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.2" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "19.2.14", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", - "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "csstype": "^3.2.2" - } - }, - "node_modules/@types/react-dom": { - "version": "19.2.3", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", - "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@types/react": "^19.2.0" - } - }, - "node_modules/@vitejs/plugin-react": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", - "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.28.0", - "@babel/plugin-transform-react-jsx-self": "^7.27.1", - "@babel/plugin-transform-react-jsx-source": "^7.27.1", - "@rolldown/pluginutils": "1.0.0-beta.27", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.17.0" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" - } - }, - "node_modules/baseline-browser-mapping": { - "version": "2.10.18", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.18.tgz", - "integrity": "sha512-VSnGQAOLtP5mib/DPyg2/t+Tlv65NTBz83BJBJvmLVHHuKJVaDOBvJJykiT5TR++em5nfAySPccDZDa4oSrn8A==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/browserslist": { - "version": "4.28.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", - "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "peer": true, - "dependencies": { - "baseline-browser-mapping": "^2.10.12", - "caniuse-lite": "^1.0.30001782", - "electron-to-chromium": "^1.5.328", - "node-releases": "^2.0.36", - "update-browserslist-db": "^1.2.3" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001787", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001787.tgz", - "integrity": "sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/csstype": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", - "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.335", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.335.tgz", - "integrity": "sha512-q9n5T4BR4Xwa2cwbrwcsDJtHD/enpQ5S1xF1IAtdqf5AAgqDFmR/aakqH3ChFdqd/QXJhS3rnnXFtexU7rax6Q==", - "dev": true, - "license": "ISC" - }, - "node_modules/esbuild": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", - "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.12", - "@esbuild/android-arm": "0.25.12", - "@esbuild/android-arm64": "0.25.12", - "@esbuild/android-x64": "0.25.12", - "@esbuild/darwin-arm64": "0.25.12", - "@esbuild/darwin-x64": "0.25.12", - "@esbuild/freebsd-arm64": "0.25.12", - "@esbuild/freebsd-x64": "0.25.12", - "@esbuild/linux-arm": "0.25.12", - "@esbuild/linux-arm64": "0.25.12", - "@esbuild/linux-ia32": "0.25.12", - "@esbuild/linux-loong64": "0.25.12", - "@esbuild/linux-mips64el": "0.25.12", - "@esbuild/linux-ppc64": "0.25.12", - "@esbuild/linux-riscv64": "0.25.12", - "@esbuild/linux-s390x": "0.25.12", - "@esbuild/linux-x64": "0.25.12", - "@esbuild/netbsd-arm64": "0.25.12", - "@esbuild/netbsd-x64": "0.25.12", - "@esbuild/openbsd-arm64": "0.25.12", - "@esbuild/openbsd-x64": "0.25.12", - "@esbuild/openharmony-arm64": "0.25.12", - "@esbuild/sunos-x64": "0.25.12", - "@esbuild/win32-arm64": "0.25.12", - "@esbuild/win32-ia32": "0.25.12", - "@esbuild/win32-x64": "0.25.12" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/node-releases": { - "version": "2.0.37", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.37.tgz", - "integrity": "sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==", - "dev": true, - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "peer": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/postcss": { - "version": "8.5.9", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz", - "integrity": "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/react": { - "version": "19.2.5", - "resolved": "https://registry.npmjs.org/react/-/react-19.2.5.tgz", - "integrity": "sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "19.2.5", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.5.tgz", - "integrity": "sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag==", - "license": "MIT", - "peer": true, - "dependencies": { - "scheduler": "^0.27.0" - }, - "peerDependencies": { - "react": "^19.2.5" - } - }, - "node_modules/react-refresh": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", - "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/rollup": { - "version": "4.60.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz", - "integrity": "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.60.1", - "@rollup/rollup-android-arm64": "4.60.1", - "@rollup/rollup-darwin-arm64": "4.60.1", - "@rollup/rollup-darwin-x64": "4.60.1", - "@rollup/rollup-freebsd-arm64": "4.60.1", - "@rollup/rollup-freebsd-x64": "4.60.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", - "@rollup/rollup-linux-arm-musleabihf": "4.60.1", - "@rollup/rollup-linux-arm64-gnu": "4.60.1", - "@rollup/rollup-linux-arm64-musl": "4.60.1", - "@rollup/rollup-linux-loong64-gnu": "4.60.1", - "@rollup/rollup-linux-loong64-musl": "4.60.1", - "@rollup/rollup-linux-ppc64-gnu": "4.60.1", - "@rollup/rollup-linux-ppc64-musl": "4.60.1", - "@rollup/rollup-linux-riscv64-gnu": "4.60.1", - "@rollup/rollup-linux-riscv64-musl": "4.60.1", - "@rollup/rollup-linux-s390x-gnu": "4.60.1", - "@rollup/rollup-linux-x64-gnu": "4.60.1", - "@rollup/rollup-linux-x64-musl": "4.60.1", - "@rollup/rollup-openbsd-x64": "4.60.1", - "@rollup/rollup-openharmony-arm64": "4.60.1", - "@rollup/rollup-win32-arm64-msvc": "4.60.1", - "@rollup/rollup-win32-ia32-msvc": "4.60.1", - "@rollup/rollup-win32-x64-gnu": "4.60.1", - "@rollup/rollup-win32-x64-msvc": "4.60.1", - "fsevents": "~2.3.2" - } - }, - "node_modules/scheduler": { - "version": "0.27.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", - "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", - "license": "MIT" - }, - "node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.16", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz", - "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/vite": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.2.tgz", - "integrity": "sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==", - "dev": true, - "license": "MIT", - "peer": true, - "dependencies": { - "esbuild": "^0.25.0", - "fdir": "^6.4.4", - "picomatch": "^4.0.2", - "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.13" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", - "jiti": ">=1.21.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.16.0", - "tsx": "^4.8.1", - "yaml": "^2.4.2" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "jiti": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - }, - "tsx": { - "optional": true - }, - "yaml": { - "optional": true - } - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - } - } -} diff --git a/frontend/package.json b/frontend/package.json deleted file mode 100644 index 96d8553f..00000000 --- a/frontend/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "mosswart-overlord-v2", - "private": true, - "version": "0.1.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "tsc -b && vite build", - "preview": "vite preview" - }, - "dependencies": { - "react": "^19.1.0", - "react-dom": "^19.1.0" - }, - "devDependencies": { - "@types/react": "^19.1.2", - "@types/react-dom": "^19.1.2", - "@vitejs/plugin-react": "^4.4.1", - "typescript": "~5.8.3", - "vite": "^6.3.3" - } -} diff --git a/frontend/public/sw.js b/frontend/public/sw.js deleted file mode 100644 index 71839ee5..00000000 --- a/frontend/public/sw.js +++ /dev/null @@ -1,72 +0,0 @@ -// Service worker for MosswartOverlord v2 β€” caches static assets for instant repeat loads -const CACHE_NAME = 'mo-v2-cache-v1'; -const STATIC_ASSETS = [ - '/dereth.png', - '/dereth_highres.png', - '/prismatic-taper-icon.png', - '/icons/0600127E.png', - '/icons/06000133.png', - '/icons/06001080.png', -]; - -self.addEventListener('install', (event) => { - event.waitUntil( - caches.open(CACHE_NAME).then(cache => cache.addAll(STATIC_ASSETS)) - ); - self.skipWaiting(); -}); - -self.addEventListener('activate', (event) => { - event.waitUntil( - caches.keys().then(keys => - Promise.all(keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k))) - ) - ); - self.clients.claim(); -}); - -self.addEventListener('fetch', (event) => { - const url = new URL(event.request.url); - - // Cache icon images on first fetch - if (url.pathname.startsWith('/icons/') && event.request.method === 'GET') { - event.respondWith( - caches.match(event.request).then(cached => { - if (cached) return cached; - return fetch(event.request).then(response => { - if (response.ok) { - const clone = response.clone(); - caches.open(CACHE_NAME).then(cache => cache.put(event.request, clone)); - } - return response; - }); - }) - ); - return; - } - - // Cache dungeon_tiles.json (large, rarely changes) - if (url.pathname === '/dungeon_tiles.json') { - event.respondWith( - caches.match(event.request).then(cached => { - if (cached) return cached; - return fetch(event.request).then(response => { - if (response.ok) { - const clone = response.clone(); - caches.open(CACHE_NAME).then(cache => cache.put(event.request, clone)); - } - return response; - }); - }) - ); - return; - } - - // Cache static assets (map images etc) - if (STATIC_ASSETS.some(a => url.pathname === a)) { - event.respondWith( - caches.match(event.request).then(cached => cached || fetch(event.request)) - ); - return; - } -}); diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx deleted file mode 100644 index 5c9433a8..00000000 --- a/frontend/src/App.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { MapLayout } from './components/map/MapLayout'; -import { PlayerDashboardFullPage } from './components/PlayerDashboardFullPage'; -import { useLiveData } from './hooks/useLiveData'; -import './styles/map-layout.css'; - -/** - * Single SPA entry. Branches on `?view=` query param: - * /?view=dashboard β†’ fullscreen PlayerDashboardFullPage (new-tab target) - * / β†’ default map + sidebar layout - * - * We don't pull in react-router for one extra view β€” when a third view - * appears, swap this for proper routing. - */ -export default function App() { - const view = new URLSearchParams(window.location.search).get('view'); - if (view === 'dashboard') { - return ; - } - // Default: full app with map + sidebar. - return ; -} - -/** Default map-and-sidebar layout. Split out so the dashboard tab doesn't - * spin up useLiveData twice for the same render. */ -function DefaultApp() { - const data = useLiveData(); - return ; -} diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts deleted file mode 100644 index b79077dc..00000000 --- a/frontend/src/api/client.ts +++ /dev/null @@ -1,69 +0,0 @@ -// In production the browser hits /api/* and Nginx strips the prefix. -// In dev, Vite's proxy does the same stripping. -// So we always use /api/ as prefix β€” works both environments. -const API_BASE = '/api'; - -export async function apiFetch(path: string): Promise { - const res = await fetch(`${API_BASE}${path}`, { credentials: 'include' }); - if (!res.ok) throw new Error(`API ${path}: ${res.status}`); - return res.json(); -} - -/** - * POST JSON to an authenticated API endpoint. - * Sends `body` as JSON, includes session cookie, parses JSON response. - * Throws Error with HTTP status on non-2xx. - */ -export async function apiPost(path: string, body: unknown): Promise { - const res = await fetch(`${API_BASE}${path}`, { - method: 'POST', - credentials: 'include', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(body ?? {}), - }); - if (!res.ok) { - let detail = ''; - try { detail = (await res.json())?.detail ?? ''; } catch { /* ignore */ } - throw new Error(`API ${path}: ${res.status}${detail ? ` (${detail})` : ''}`); - } - return res.json(); -} - -/** - * PATCH JSON to an authenticated API endpoint. Same shape as apiPost. - */ -export async function apiPatch(path: string, body: unknown): Promise { - const res = await fetch(`${API_BASE}${path}`, { - method: 'PATCH', - credentials: 'include', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(body ?? {}), - }); - if (!res.ok) { - let detail = ''; - try { detail = (await res.json())?.detail ?? ''; } catch { /* ignore */ } - throw new Error(`API ${path}: ${res.status}${detail ? ` (${detail})` : ''}`); - } - return res.json(); -} - -/** - * DELETE an authenticated API endpoint. No body. Returns parsed JSON. - */ -export async function apiDelete(path: string): Promise { - const res = await fetch(`${API_BASE}${path}`, { - method: 'DELETE', - credentials: 'include', - }); - if (!res.ok) { - let detail = ''; - try { detail = (await res.json())?.detail ?? ''; } catch { /* ignore */ } - throw new Error(`API ${path}: ${res.status}${detail ? ` (${detail})` : ''}`); - } - return res.json(); -} - -export function wsUrl(): string { - const proto = location.protocol === 'https:' ? 'wss:' : 'ws:'; - return `${proto}//${location.host}/api/ws/live`; -} diff --git a/frontend/src/api/endpoints.ts b/frontend/src/api/endpoints.ts deleted file mode 100644 index 348677dd..00000000 --- a/frontend/src/api/endpoints.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { apiFetch, apiPost, apiPatch, apiDelete } from './client'; -import type { TelemetrySnapshot, CombatStatsMessage, ServerHealth } from '../types'; - -interface LiveResponse { - players: TelemetrySnapshot[]; -} - -interface CombatStatsResponse { - stats: CombatStatsMessage[]; -} - -// v1 response shapes: /total-rares β†’ { all_time, today }, /total-kills β†’ { total } -interface RaresResponse { all_time: number; today: number; } -interface KillsResponse { total: number; } - -export const getLive = () => apiFetch('/live'); -export const getCombatStats = () => apiFetch('/combat-stats'); -export const getServerHealth = () => apiFetch('/server-health'); -export const getTotalRares = () => apiFetch('/total-rares'); -export const getTotalKills = () => apiFetch('/total-kills'); -export const getCharacterStats = (name: string) => apiFetch>(`/character-stats/${encodeURIComponent(name)}`); - -// ─── Agent endpoints (host-side service via /api/agent/*) ────────────────── - -export interface AgentAskResponse { - result: string; - session_id: string; - duration_ms: number; - num_turns: number; - is_error: boolean; -} - -export interface AgentHistoryMessage { - role: 'user' | 'assistant'; - text: string; - timestamp?: string; -} - -export const agentAsk = (message: string, sessionId: string) => - apiPost('/agent/ask', { message, session_id: sessionId }); - -export const agentNewSession = () => - apiPost<{ session_id: string }>('/agent/sessions/new', {}); - -export const agentSessionHistory = (sessionId: string) => - apiFetch<{ messages: AgentHistoryMessage[] }>( - `/agent/sessions/${encodeURIComponent(sessionId)}/history`, - ); - -// ─── Auth / current user ─────────────────────────────────────────────────── - -export interface CurrentUser { - username: string; - is_admin: boolean; -} - -export const getCurrentUser = () => apiFetch('/me'); - -/** - * Log out by hitting /logout (which clears the cookie server-side and 302s - * to /login). We follow the redirect explicitly so the browser ends up on - * the login page with a fresh state. - */ -export async function logout(): Promise { - // /logout is a GET that returns a redirect. apiFetch would throw because - // the redirect target /login returns HTML, not JSON. Use a bare fetch. - await fetch('/api/logout', { credentials: 'include', redirect: 'manual' }); - // Force navigation regardless β€” the cookie is gone either way. - window.location.href = '/login'; -} - -// ─── Admin user CRUD ─────────────────────────────────────────────────────── - -export interface AdminUser { - id: number; - username: string; - is_admin: boolean; - created_at: string; -} - -export const listAdminUsers = () => - apiFetch<{ users: AdminUser[] }>('/api-admin/users'); - -export const createAdminUser = (username: string, password: string, isAdmin: boolean) => - apiPost<{ ok: boolean; username: string }>('/api-admin/users', { - username, password, is_admin: isAdmin, - }); - -export const updateAdminUser = ( - id: number, - body: { password?: string; is_admin?: boolean }, -) => - apiPatch<{ ok: boolean }>(`/api-admin/users/${id}`, body); - -export const deleteAdminUser = (id: number) => - apiDelete<{ ok: boolean }>(`/api-admin/users/${id}`); diff --git a/frontend/src/components/PlayerDashboardFullPage.tsx b/frontend/src/components/PlayerDashboardFullPage.tsx deleted file mode 100644 index a86f3958..00000000 --- a/frontend/src/components/PlayerDashboardFullPage.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { useLiveData } from '../hooks/useLiveData'; -import { PlayerDashboardContent } from './windows/PlayerDashboardWindow'; - -/** - * Fullscreen "Player Dashboard" page β€” rendered when the React app loads - * with `?view=dashboard` in the URL. Designed to be opened in a new tab - * by the sidebar's πŸ‘₯ Dashboard button so users can put the dashboard on - * a second monitor / its own window without occupying the map view. - * - * Each tab is its own React app instance with its own useLiveData - * (and therefore its own WebSocket to /ws/live). Independent of the main - * tab's lifecycle. - */ -export const PlayerDashboardFullPage: React.FC = () => { - const data = useLiveData(); - const [version, setVersion] = useState(''); - - // Set tab title. - useEffect(() => { - const prev = document.title; - document.title = 'Overlord Dashboard'; - return () => { document.title = prev; }; - }, []); - - // Fetch version stamp the same way MapLayout does. /api-version returns - // {version: "..."} where "..." is the BUILD_VERSION baked into the - // tracker container at image build time. - useEffect(() => { - fetch('/api/api-version', { credentials: 'include' }) - .then(r => r.json()) - .then(d => setVersion(d.version ?? '')) - .catch(() => { /* version is cosmetic β€” ignore failures */ }); - }, []); - - const count = Array.from(data.characters.values()).filter(c => c.telemetry).length; - - return ( -
-
- πŸ‘₯ Player Dashboard - {count} online - - {version && v{version}} -
-
- -
-
- ); -}; diff --git a/frontend/src/components/effects/DeathNotification.tsx b/frontend/src/components/effects/DeathNotification.tsx deleted file mode 100644 index 0644f6df..00000000 --- a/frontend/src/components/effects/DeathNotification.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import React, { useEffect, useState, useRef } from 'react'; - -interface DeathAlert { - character_name: string; - vitae: number; - timestamp: string; -} - -interface Props { - deathAlerts: DeathAlert[]; -} - -interface ActiveNotification { - key: number; - alert: DeathAlert; - exiting: boolean; -} - -let deathKey = 0; - -export const DeathNotification: React.FC = ({ deathAlerts }) => { - const [active, setActive] = useState([]); - const lastCount = useRef(0); - - useEffect(() => { - if (deathAlerts.length > lastCount.current && lastCount.current > 0) { - const newAlerts = deathAlerts.slice(lastCount.current); - for (const alert of newAlerts) { - const key = ++deathKey; - setActive(prev => [...prev, { key, alert, exiting: false }]); - // Sound - try { - const ctx = new AudioContext(); - const osc = ctx.createOscillator(); - const gain = ctx.createGain(); - osc.connect(gain); gain.connect(ctx.destination); - osc.frequency.value = 440; osc.type = 'sawtooth'; gain.gain.value = 0.2; - osc.start(); - gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.8); - osc.stop(ctx.currentTime + 0.8); - } catch {} - // Auto-dismiss after 8s - setTimeout(() => { - setActive(prev => prev.map(n => n.key === key ? { ...n, exiting: true } : n)); - setTimeout(() => setActive(prev => prev.filter(n => n.key !== key)), 500); - }, 8000); - } - } - lastCount.current = deathAlerts.length; - }, [deathAlerts.length]); // eslint-disable-line react-hooks/exhaustive-deps - - if (active.length === 0) return null; - - return ( -
- {active.map(n => ( -
-
☠️ CHARACTER DIED ☠️
-
{n.alert.character_name}
-
Vitae: {n.alert.vitae}%
-
- ))} -
- ); -}; diff --git a/frontend/src/components/effects/RareNotification.tsx b/frontend/src/components/effects/RareNotification.tsx deleted file mode 100644 index 5e843c33..00000000 --- a/frontend/src/components/effects/RareNotification.tsx +++ /dev/null @@ -1,109 +0,0 @@ -import React, { useEffect, useState, useCallback } from 'react'; -import type { RareMessage } from '../../types'; - -interface Props { - recentRares: RareMessage[]; -} - -interface ActiveNotification { - key: number; - charName: string; - rareName: string; - exiting: boolean; -} - -let notifKey = 0; - -export const RareNotification: React.FC = ({ recentRares }) => { - const [active, setActive] = useState([]); - const [lastCount, setLastCount] = useState(0); - const [fireworks, setFireworks] = useState }>>([]); - - // Detect new rares - useEffect(() => { - if (recentRares.length > lastCount && lastCount > 0) { - const newRares = recentRares.slice(0, recentRares.length - lastCount); - for (const r of newRares) { - const key = ++notifKey; - setActive(prev => [...prev, { key, charName: r.character_name, rareName: r.name, exiting: false }]); - // Trigger fireworks + sound - triggerFireworks(); - try { - // Simple beep using Web Audio API - const ctx = new AudioContext(); - const osc = ctx.createOscillator(); - const gain = ctx.createGain(); - osc.connect(gain); - gain.connect(ctx.destination); - osc.frequency.value = 880; - osc.type = 'sine'; - gain.gain.value = 0.3; - osc.start(); - gain.gain.exponentialRampToValueAtTime(0.001, ctx.currentTime + 0.5); - osc.stop(ctx.currentTime + 0.5); - } catch { /* audio not available */ } - // Auto-remove after 6s - setTimeout(() => { - setActive(prev => prev.map(n => n.key === key ? { ...n, exiting: true } : n)); - setTimeout(() => { - setActive(prev => prev.filter(n => n.key !== key)); - }, 500); - }, 6000); - } - } - setLastCount(recentRares.length); - }, [recentRares.length]); // eslint-disable-line react-hooks/exhaustive-deps - - const triggerFireworks = useCallback(() => { - const id = Date.now(); - const colors = ['#FFD700', '#FF4444', '#FF8800', '#AA44FF', '#4488FF']; - const particles = Array.from({ length: 30 }, (_, i) => { - const angle = (Math.PI * 2 * i) / 30 + (Math.random() - 0.5) * 0.5; - const velocity = 100 + Math.random() * 200; - return { - dx: Math.cos(angle) * velocity, - dy: Math.sin(angle) * velocity - 50, - color: colors[Math.floor(Math.random() * colors.length)], - }; - }); - setFireworks(prev => [...prev, { id, particles }]); - setTimeout(() => setFireworks(prev => prev.filter(f => f.id !== id)), 2200); - }, []); - - return ( - <> - {/* Notification banners */} -
- {active.map(n => ( -
-
πŸŽ† LEGENDARY RARE! πŸŽ†
-
{n.rareName}
-
found by
-
{n.charName}
-
- ))} -
- - {/* Fireworks particles */} -
- {fireworks.map(fw => ( - - {fw.particles.map((p, i) => ( -
- ))} - - ))} -
- - ); -}; diff --git a/frontend/src/components/map/HeatmapCanvas.tsx b/frontend/src/components/map/HeatmapCanvas.tsx deleted file mode 100644 index ee721776..00000000 --- a/frontend/src/components/map/HeatmapCanvas.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import React, { useRef, useEffect, useState } from 'react'; -import { worldToPx } from '../../utils/coordinates'; -import { apiFetch } from '../../api/client'; - -interface HeatmapPoint { - ew: number; - ns: number; - intensity: number; -} - -interface Props { - imgW: number; - imgH: number; - enabled: boolean; -} - -export const HeatmapCanvas: React.FC = ({ imgW, imgH, enabled }) => { - const canvasRef = useRef(null); - const [data, setData] = useState([]); - - useEffect(() => { - if (!enabled) return; - const fetch = async () => { - try { - const resp = await apiFetch<{ spawn_points: HeatmapPoint[] }>('/spawns/heatmap?hours=24&limit=50000'); - setData(resp.spawn_points ?? []); - } catch { /* ignore */ } - }; - fetch(); - }, [enabled]); - - useEffect(() => { - const canvas = canvasRef.current; - if (!canvas || !enabled || data.length === 0 || imgW === 0) return; - - canvas.width = imgW; - canvas.height = imgH; - const ctx = canvas.getContext('2d'); - if (!ctx) return; - - ctx.clearRect(0, 0, imgW, imgH); - - for (const point of data) { - const { x, y } = worldToPx(point.ew, point.ns, imgW, imgH); - const radius = Math.max(5, Math.min(12, 5 + Math.sqrt(point.intensity * 0.5))); - const gradient = ctx.createRadialGradient(x, y, 0, x, y, radius); - gradient.addColorStop(0, `rgba(255, 0, 0, ${Math.min(0.9, point.intensity / 40)})`); - gradient.addColorStop(0.6, `rgba(255, 100, 0, ${Math.min(0.4, point.intensity / 120)})`); - gradient.addColorStop(1, 'rgba(255, 150, 0, 0)'); - ctx.fillStyle = gradient; - ctx.fillRect(x - radius, y - radius, radius * 2, radius * 2); - } - }, [data, imgW, imgH, enabled]); - - if (!enabled) return null; - - return ; -}; diff --git a/frontend/src/components/map/MapLayout.tsx b/frontend/src/components/map/MapLayout.tsx deleted file mode 100644 index 73b11215..00000000 --- a/frontend/src/components/map/MapLayout.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import React, { useCallback, useState, useMemo, useEffect } from 'react'; -import { apiFetch } from '../../api/client'; -import { WindowManagerProvider, useWindowManager } from '../../contexts/WindowManagerContext'; -import { MapView } from './MapView'; -import { Sidebar } from './Sidebar'; -import { WindowRenderer } from '../windows/WindowRenderer'; -import { RareNotification } from '../effects/RareNotification'; -import { DeathNotification } from '../effects/DeathNotification'; -import { usePlayerColors } from '../../hooks/usePlayerColors'; -import type { DashboardState } from '../../hooks/useLiveData'; - -interface Props { - data: DashboardState; -} - -export const MapLayout: React.FC = ({ data }) => { - const getColor = usePlayerColors(); - const [showHeatmap, setShowHeatmap] = useState(false); - const [showPortals, setShowPortals] = useState(false); - const [selectedPlayer, setSelectedPlayer] = useState(null); - - const players = useMemo(() => - Array.from(data.characters.values()).filter(c => c.telemetry).map(c => c.telemetry!), - [data.characters]); - - const vitalsMap = useMemo(() => - new Map(Array.from(data.characters.values()).filter(c => c.vitals).map(c => [c.name, c.vitals!])), - [data.characters]); - - const [version, setVersion] = useState(''); - useEffect(() => { - // /api-version is the actual route β€” apiFetch adds /api prefix, so use raw fetch - fetch('/api/api-version', { credentials: 'include' }).then(r => r.json()).then(d => setVersion(d.version ?? '')).catch(() => {}); - }, []); - - const handleSelectPlayer = useCallback((name: string) => { - setSelectedPlayer(prev => prev === name ? null : name); - }, []); - - - return ( - -
- - - - - - -
-
- ); -}; diff --git a/frontend/src/components/map/MapView.tsx b/frontend/src/components/map/MapView.tsx deleted file mode 100644 index 8b9978b7..00000000 --- a/frontend/src/components/map/MapView.tsx +++ /dev/null @@ -1,161 +0,0 @@ -import React, { useRef, useState, useCallback, useEffect } from 'react'; -import { worldToPx, pxToWorld, formatCoord } from '../../utils/coordinates'; -import { PlayerDots } from './PlayerDots'; -import { TrailsSVG } from './TrailsSVG'; -import { HeatmapCanvas } from './HeatmapCanvas'; -import { PortalMarkers } from './PortalMarkers'; -import type { TelemetrySnapshot } from '../../types'; - -interface Props { - players: TelemetrySnapshot[]; - getColor: (name: string) => string; - onSelectPlayer: (name: string) => void; - showHeatmap: boolean; - showPortals: boolean; - selectedPlayer: string | null; -} - -const MAX_ZOOM = 20; -const MIN_ZOOM = 0.3; - -// Pan/zoom via direct DOM manipulation β€” bypasses React state entirely for smooth 60fps -export const MapView: React.FC = ({ players, getColor, onSelectPlayer, showHeatmap, showPortals, selectedPlayer }) => { - const containerRef = useRef(null); - const groupRef = useRef(null); - const [imgSize, setImgSize] = useState({ w: 0, h: 0 }); - const [tooltip, setTooltip] = useState<{ x: number; y: number; player: TelemetrySnapshot } | null>(null); - const coordRef = useRef(null); - - // Transform stored in ref, applied directly to DOM β€” no React re-render on pan/zoom - const txRef = useRef({ scale: 1, offX: 0, offY: 0 }); - const dragRef = useRef({ dragging: false, sx: 0, sy: 0, startOffX: 0, startOffY: 0 }); - - const applyTransform = useCallback(() => { - if (groupRef.current) { - const { scale, offX, offY } = txRef.current; - groupRef.current.style.transform = `translate(${offX}px, ${offY}px) scale(${scale})`; - } - }, []); - - const onImgLoad = useCallback((e: React.SyntheticEvent) => { - const img = e.currentTarget; - setImgSize({ w: img.naturalWidth, h: img.naturalHeight }); - if (containerRef.current) { - const cw = containerRef.current.clientWidth; - const ch = containerRef.current.clientHeight; - const scale = Math.min(cw / img.naturalWidth, ch / img.naturalHeight); - txRef.current = { scale, offX: (cw - img.naturalWidth * scale) / 2, offY: (ch - img.naturalHeight * scale) / 2 }; - applyTransform(); - } - }, [applyTransform]); - - // Wheel zoom β€” direct DOM - const onWheel = useCallback((e: React.WheelEvent) => { - e.preventDefault(); - const rect = containerRef.current?.getBoundingClientRect(); - if (!rect) return; - const tx = txRef.current; - const factor = e.deltaY < 0 ? 1.1 : 0.9; - const newScale = Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, tx.scale * factor)); - const ratio = newScale / tx.scale; - const cx = e.clientX - rect.left; - const cy = e.clientY - rect.top; - txRef.current = { - scale: newScale, - offX: cx - (cx - tx.offX) * ratio, - offY: cy - (cy - tx.offY) * ratio, - }; - applyTransform(); - }, [applyTransform]); - - // Pan drag β€” direct DOM - const onMouseDown = useCallback((e: React.MouseEvent) => { - if (e.button !== 0) return; - const tx = txRef.current; - dragRef.current = { dragging: true, sx: e.clientX, sy: e.clientY, startOffX: tx.offX, startOffY: tx.offY }; - }, []); - - useEffect(() => { - const onMouseMove = (e: MouseEvent) => { - const d = dragRef.current; - if (d.dragging) { - txRef.current.offX = d.startOffX + (e.clientX - d.sx); - txRef.current.offY = d.startOffY + (e.clientY - d.sy); - applyTransform(); - } - // Coordinate display β€” direct DOM write, no React state - if (containerRef.current && imgSize.w > 0 && coordRef.current) { - const rect = containerRef.current.getBoundingClientRect(); - const tx = txRef.current; - const coord = pxToWorld(e.clientX - rect.left, e.clientY - rect.top, tx.scale, tx.offX, tx.offY, imgSize.w, imgSize.h); - coordRef.current.textContent = formatCoord(coord.ns, coord.ew); - } - }; - const onMouseUp = () => { dragRef.current.dragging = false; }; - window.addEventListener('mousemove', onMouseMove); - window.addEventListener('mouseup', onMouseUp); - return () => { window.removeEventListener('mousemove', onMouseMove); window.removeEventListener('mouseup', onMouseUp); }; - }, [applyTransform, imgSize.w, imgSize.h]); - - // Zoom to selected player β€” fires once then releases - const lastZoomedRef = useRef(null); - useEffect(() => { - if (!selectedPlayer || imgSize.w === 0 || !containerRef.current) return; - if (lastZoomedRef.current === selectedPlayer) return; // already zoomed to this player - const player = players.find(p => p.character_name === selectedPlayer); - if (!player) return; - lastZoomedRef.current = selectedPlayer; - const { x, y } = worldToPx(player.ew, player.ns, imgSize.w, imgSize.h); - const rect = containerRef.current.getBoundingClientRect(); - const focusZoom = 3; - txRef.current = { - scale: Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, focusZoom)), - offX: rect.width / 2 - x * focusZoom, - offY: rect.height / 2 - y * focusZoom, - }; - applyTransform(); - }, [selectedPlayer, players, imgSize.w, imgSize.h, applyTransform]); - - // Reset zoom lock when player is deselected - useEffect(() => { - if (!selectedPlayer) lastZoomedRef.current = null; - }, [selectedPlayer]); - - const handleDotHover = useCallback((player: TelemetrySnapshot | null, x: number, y: number) => { - setTooltip(player ? { x, y, player } : null); - }, []); - - return ( -
-
- Dereth - {imgSize.w > 0 && ( - <> - - - - - - )} -
- - {tooltip && ( -
- {tooltip.player.character_name}
- {formatCoord(tooltip.player.ns, tooltip.player.ew)}
- {tooltip.player.kills_per_hour} kph · {tooltip.player.kills?.toLocaleString()} kills -
- )} - -
-
- ); -}; diff --git a/frontend/src/components/map/PlayerDots.tsx b/frontend/src/components/map/PlayerDots.tsx deleted file mode 100644 index a25d5fee..00000000 --- a/frontend/src/components/map/PlayerDots.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import React, { useMemo, useState, useEffect } from 'react'; -import { worldToPx } from '../../utils/coordinates'; -import { useWindowManager } from '../../contexts/WindowManagerContext'; -import type { TelemetrySnapshot } from '../../types'; - -interface Props { - players: TelemetrySnapshot[]; - imgW: number; - imgH: number; - getColor: (name: string) => string; - onHover: (player: TelemetrySnapshot | null, x: number, y: number) => void; - onSelect: (name: string) => void; - selectedPlayer: string | null; -} - -export const PlayerDots: React.FC = React.memo(({ players, imgW, imgH, getColor, onHover, onSelect, selectedPlayer }) => { - const { openWindow } = useWindowManager(); - const [contextMenu, setContextMenu] = useState<{ name: string; x: number; y: number } | null>(null); - - // Close context menu on any click - useEffect(() => { - const close = () => setContextMenu(null); - if (contextMenu) window.addEventListener('click', close); - return () => window.removeEventListener('click', close); - }, [contextMenu]); - const dots = useMemo(() => - players.filter(p => p.ew !== undefined && p.ns !== undefined).map(p => ({ - ...p, - pos: worldToPx(p.ew, p.ns, imgW, imgH), - color: getColor(p.character_name), - })), - [players, imgW, imgH, getColor]); - - return ( -
- {dots.map(d => ( -
{ - const rect = e.currentTarget.closest('.ml-map-container')?.getBoundingClientRect(); - if (rect) onHover(d, e.clientX - rect.left, e.clientY - rect.top); - }} - onMouseLeave={() => onHover(null, 0, 0)} - onClick={() => onSelect(d.character_name)} - onDoubleClick={() => openWindow(`chat-${d.character_name}`, `Chat: ${d.character_name}`, d.character_name)} - onContextMenu={(e) => { - e.preventDefault(); - const name = d.character_name; - const rect = e.currentTarget.closest('.ml-map-container')?.getBoundingClientRect(); - const x = rect ? e.clientX - rect.left : e.clientX; - const y = rect ? e.clientY - rect.top : e.clientY; - setContextMenu({ name, x, y }); - }} - /> - ))} - {contextMenu && ( -
- {[ - { label: 'Chat', id: 'chat' }, - { label: 'Stats', id: 'stats' }, - { label: 'Inventory', id: 'inv' }, - { label: 'Character', id: 'char' }, - { label: 'Combat', id: 'combat' }, - { label: 'Radar', id: 'radar' }, - ].map(item => ( -
{ openWindow(`${item.id}-${contextMenu.name}`, `${item.label}: ${contextMenu.name}`, contextMenu.name); setContextMenu(null); }} - style={{ padding: '4px 12px', cursor: 'pointer', color: '#ccc' }} - onMouseEnter={e => (e.currentTarget.style.background = '#333')} - onMouseLeave={e => (e.currentTarget.style.background = '')}> - {item.label} -
- ))} -
- )} -
- ); -}); - -PlayerDots.displayName = 'PlayerDots'; diff --git a/frontend/src/components/map/PortalMarkers.tsx b/frontend/src/components/map/PortalMarkers.tsx deleted file mode 100644 index ac60135c..00000000 --- a/frontend/src/components/map/PortalMarkers.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import React, { useEffect, useState, useMemo } from 'react'; -import { worldToPx } from '../../utils/coordinates'; -import { apiFetch } from '../../api/client'; - -interface Portal { - portal_name: string; - coordinates: { ns: number; ew: number; z: number }; - discovered_by: string; -} - -interface Props { - imgW: number; - imgH: number; - enabled: boolean; -} - -export const PortalMarkers: React.FC = ({ imgW, imgH, enabled }) => { - const [portals, setPortals] = useState([]); - - useEffect(() => { - if (!enabled) return; - const fetch = async () => { - try { - const data = await apiFetch<{ portals: Portal[] }>('/portals'); - setPortals(data.portals ?? []); - } catch { /* ignore */ } - }; - fetch(); - const id = setInterval(fetch, 60000); - return () => clearInterval(id); - }, [enabled]); - - const markers = useMemo(() => - portals.map(p => ({ - ...p, - pos: worldToPx(p.coordinates.ew, p.coordinates.ns, imgW, imgH), - })), - [portals, imgW, imgH]); - - if (!enabled || markers.length === 0) return null; - - return ( -
- {markers.map((p, i) => ( -
- ))} -
- ); -}; diff --git a/frontend/src/components/map/Sidebar.tsx b/frontend/src/components/map/Sidebar.tsx deleted file mode 100644 index 3fcc5511..00000000 --- a/frontend/src/components/map/Sidebar.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import React, { useState, useMemo, useDeferredValue } from 'react'; -import { PlayerList } from '../sidebar/PlayerList'; -import { SortButtons, type SortKey } from '../sidebar/SortButtons'; -import { SidebarWindowButtons } from '../sidebar/SidebarWindowButtons'; -import type { TelemetrySnapshot, VitalsMessage, ServerHealth } from '../../types'; - -interface Props { - players: TelemetrySnapshot[]; - vitals: Map; - serverHealth: ServerHealth | null; - totalRares: number; - totalKills: number; - getColor: (name: string) => string; - onSelectPlayer: (name: string) => void; - showHeatmap: boolean; - showPortals: boolean; - onToggleHeatmap: (v: boolean) => void; - onTogglePortals: (v: boolean) => void; - version?: string; - selectedPlayer?: string | null; -} - -export const Sidebar: React.FC = ({ - players, vitals, serverHealth, totalRares, totalKills, getColor, onSelectPlayer, - showHeatmap, showPortals, onToggleHeatmap, onTogglePortals, version, selectedPlayer, -}: Props) => { - const [sortKey, setSortKey] = useState('name'); - const [filter, setFilter] = useState(''); - - const serverKph = useMemo(() => - players.reduce((sum, p) => sum + (parseInt(p.kills_per_hour) || 0), 0), - [players]); - - const isOnline = serverHealth?.status?.toLowerCase() === 'online' || serverHealth?.status?.toLowerCase() === 'up'; - - // Defer player list rendering β€” sidebar stats don't need real-time updates - const deferredPlayers = useDeferredValue(players); - const deferredVitals = useDeferredValue(vitals); - - const sorted = useMemo(() => { - let list = [...deferredPlayers]; - if (filter) list = list.filter(p => p.character_name.toLowerCase().startsWith(filter.toLowerCase())); - switch (sortKey) { - case 'kph': list.sort((a, b) => (parseInt(b.kills_per_hour) || 0) - (parseInt(a.kills_per_hour) || 0)); break; - case 'skills': list.sort((a, b) => (b.kills || 0) - (a.kills || 0)); break; - case 'srares': list.sort((a, b) => (b.session_rares ?? 0) - (a.session_rares ?? 0)); break; - case 'tkills': list.sort((a, b) => (b.total_kills ?? 0) - (a.total_kills ?? 0)); break; - case 'kpr': list.sort((a, b) => { - const ar = (a.total_kills ?? 0) / Math.max(1, a.total_rares ?? 1); - const br = (b.total_kills ?? 0) / Math.max(1, b.total_rares ?? 1); - return ar - br; - }); break; - default: list.sort((a, b) => a.character_name.localeCompare(b.character_name)); - } - return list; - }, [deferredPlayers, sortKey, filter]); - - return ( -
- {version &&
v{version}
} -
- { - // 🎡 - const overlay = document.createElement('div'); - overlay.style.cssText = 'position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000;z-index:999999;display:flex;align-items:center;justify-content:center;'; - const video = document.createElement('video'); - video.src = '/rick.mp4'; - video.autoplay = true; - video.loop = true; - video.style.cssText = 'width:100vw;height:100vh;object-fit:cover;'; - overlay.appendChild(video); - document.body.appendChild(overlay); - // Violent shake for 1.5s then spin forever - document.body.style.animation = 'ml-shake 0.05s 30'; - const style = document.createElement('style'); - style.textContent = '@keyframes ml-shake{0%,100%{transform:translate(0) rotate(0)}25%{transform:translate(-15px,10px) rotate(-2deg)}50%{transform:translate(15px,-10px) rotate(2deg)}75%{transform:translate(-10px,-15px) rotate(-1deg)}} @keyframes ml-spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}'; - document.head.appendChild(style); - setTimeout(() => { overlay.style.animation = 'ml-spin 3s linear infinite'; }, 1500); - video.play().catch(() => {}); - }}>Active Mosswart Enjoyers ({players.length}) -
- -
- - Coldeve {isOnline ? 'Online' : 'Offline'} - {serverHealth?.player_count != null && πŸ‘₯ {serverHealth.player_count}} - {serverHealth?.latency_ms != null && {Math.round(serverHealth.latency_ms)}ms} - {serverHealth?.uptime_seconds != null && ( - Up: {Math.floor(serverHealth.uptime_seconds / 3600)}h - )} -
- -
-
{totalRares}Rares
-
5000 ? 'ultra' : ''}`}>{serverKph.toLocaleString()}Server KPH
-
{totalKills.toLocaleString()}Kills
-
- - {/* Tool links */} - - - - {/* Map toggles */} -
- - -
- -
- - setFilter(e.target.value)} - /> - - -
- ); -}; diff --git a/frontend/src/components/map/TrailsSVG.tsx b/frontend/src/components/map/TrailsSVG.tsx deleted file mode 100644 index c9e8c86d..00000000 --- a/frontend/src/components/map/TrailsSVG.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React, { useMemo, useEffect, useState } from 'react'; -import { worldToPx } from '../../utils/coordinates'; -import { apiFetch } from '../../api/client'; - -interface TrailPoint { - character_name: string; - ew: number; - ns: number; -} - -interface Props { - imgW: number; - imgH: number; - getColor: (name: string) => string; -} - -export const TrailsSVG: React.FC = React.memo(({ imgW, imgH, getColor }) => { - const [trails, setTrails] = useState([]); - - useEffect(() => { - const fetchTrails = async () => { - try { - const data = await apiFetch<{ trails: TrailPoint[] }>('/trails/?seconds=600'); - setTrails(data.trails ?? []); - } catch { /* ignore */ } - }; - fetchTrails(); - const id = setInterval(fetchTrails, 2000); - return () => clearInterval(id); - }, []); - - const polylines = useMemo(() => { - const byChar: Record = {}; - for (const pt of trails) { - const { x, y } = worldToPx(pt.ew, pt.ns, imgW, imgH); - if (!byChar[pt.character_name]) byChar[pt.character_name] = []; - byChar[pt.character_name].push(`${x},${y}`); - } - return Object.entries(byChar) - .filter(([, pts]) => pts.length >= 2) - .map(([name, pts]) => ({ name, points: pts.join(' ') })); - }, [trails, imgW, imgH]); - - return ( - - {polylines.map(p => ( - - ))} - - ); -}); - -TrailsSVG.displayName = 'TrailsSVG'; diff --git a/frontend/src/components/sidebar/PlayerList.tsx b/frontend/src/components/sidebar/PlayerList.tsx deleted file mode 100644 index 99060b19..00000000 --- a/frontend/src/components/sidebar/PlayerList.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React, { useRef, useState, useCallback } from 'react'; -import { PlayerRow } from './PlayerRow'; -import type { TelemetrySnapshot, VitalsMessage } from '../../types'; - -interface Props { - players: TelemetrySnapshot[]; - vitals: Map; - getColor: (name: string) => string; - onSelect: (name: string) => void; - selectedPlayer?: string | null; -} - -export const PlayerList: React.FC = ({ players, vitals, getColor, onSelect, selectedPlayer }) => { - const listRef = useRef(null); - const [showTop, setShowTop] = useState(false); - - const handleScroll = useCallback(() => { - if (listRef.current) setShowTop(listRef.current.scrollTop > 200); - }, []); - - return ( -
-
    - {players.map(p => ( - onSelect(p.character_name)} - isSelected={selectedPlayer === p.character_name} - /> - ))} -
- {showTop && ( - - )} -
- ); -}; diff --git a/frontend/src/components/sidebar/PlayerRow.tsx b/frontend/src/components/sidebar/PlayerRow.tsx deleted file mode 100644 index 404eede9..00000000 --- a/frontend/src/components/sidebar/PlayerRow.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import React from 'react'; -import { formatCoord } from '../../utils/coordinates'; -import { useWindowManager } from '../../contexts/WindowManagerContext'; -import type { TelemetrySnapshot, VitalsMessage } from '../../types'; - -interface Props { - player: TelemetrySnapshot; - vitals: VitalsMessage | null; - color: string; - onSelect: () => void; - isSelected?: boolean; -} - -export const PlayerRow: React.FC = React.memo(({ player: p, vitals: v, color, onSelect, isSelected }) => { - const { openWindow } = useWindowManager(); - const vtState = (p.vt_state || 'idle').toLowerCase(); - const isActive = vtState === 'combat' || vtState === 'hunt'; - const kpr = (p.total_rares ?? 0) > 0 - ? Math.round((p.total_kills ?? 0) / (p.total_rares ?? 1)).toLocaleString() - : null; - - const name = p.character_name; - - return ( -
  • -
    - {name} - {formatCoord(p.ns, p.ew)} -
    - -
    -
    -
    -
    -
    - -
    - βš”οΈ {p.kills?.toLocaleString() ?? 0} - πŸ† {(p.total_kills ?? 0).toLocaleString()} - {p.kills_per_hour ?? '0'} KPH - - πŸ’Ž {p.session_rares ?? 0} / {p.total_rares ?? 0} - {kpr ? <>πŸ“Š {kpr} KPR : ''} - {p.vt_state || 'idle'} - - πŸ• {p.onlinetime?.replace(/^00\./, '') ?? '--'} - ☠️ {p.deaths ?? '0'} - {p.prismatic_taper_count ?? '0'} -
    - -
    - - - - - - -
    -
  • - ); -}); - -PlayerRow.displayName = 'PlayerRow'; diff --git a/frontend/src/components/sidebar/SidebarWindowButtons.tsx b/frontend/src/components/sidebar/SidebarWindowButtons.tsx deleted file mode 100644 index 5344c42d..00000000 --- a/frontend/src/components/sidebar/SidebarWindowButtons.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import React, { useCallback } from 'react'; -import { useWindowManager } from '../../contexts/WindowManagerContext'; -import { useCurrentUser } from '../../hooks/useCurrentUser'; -import { logout } from '../../api/endpoints'; - -export const SidebarWindowButtons: React.FC = () => { - const { openWindow } = useWindowManager(); - const { user } = useCurrentUser(); - const isAdmin = !!user?.is_admin; - - const onLogout = useCallback(async () => { - if (!confirm('Log out?')) return; - try { await logout(); } catch { window.location.href = '/login'; } - }, []); - - return ( -
    - openWindow('agent', 'Overlord Assistant')}>πŸ€– Assistant - window.open('/?view=dashboard', '_blank', 'noopener')}>πŸ‘₯ Dashboard β†— - openWindow('queststatus', 'Quest Status')}>πŸ“œ Quests - openWindow('issues', 'Issues Board')}>πŸ“‹ Issues - openWindow('vitalsharing', 'Vital Sharing')}>🀝 Vitals - openWindow('combatpicker', 'Combat Stats')}>βš”οΈ Combat - {isAdmin && ( - openWindow('adminusers', 'Admin Β· Users')}>πŸ›‘οΈ Admin - )} - - πŸšͺ Log out{user ? ` (${user.username})` : ''} - -
    - ); -}; diff --git a/frontend/src/components/sidebar/SortButtons.tsx b/frontend/src/components/sidebar/SortButtons.tsx deleted file mode 100644 index d033da97..00000000 --- a/frontend/src/components/sidebar/SortButtons.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react'; - -export type SortKey = 'name' | 'kph' | 'skills' | 'srares' | 'tkills' | 'kpr'; - -const SORTS: { key: SortKey; label: string }[] = [ - { key: 'name', label: 'Name' }, - { key: 'kph', label: 'KPH' }, - { key: 'skills', label: 'S.Kills' }, - { key: 'srares', label: 'S.Rares' }, - { key: 'tkills', label: 'T.Kills' }, - { key: 'kpr', label: 'KPR' }, -]; - -interface Props { - value: SortKey; - onChange: (key: SortKey) => void; -} - -export const SortButtons: React.FC = ({ value, onChange }) => ( -
    - {SORTS.map(s => ( - - ))} -
    -); diff --git a/frontend/src/components/windows/AdminUsersWindow.tsx b/frontend/src/components/windows/AdminUsersWindow.tsx deleted file mode 100644 index 9518ab44..00000000 --- a/frontend/src/components/windows/AdminUsersWindow.tsx +++ /dev/null @@ -1,223 +0,0 @@ -import React, { useCallback, useEffect, useState } from 'react'; -import { DraggableWindow } from './DraggableWindow'; -import { - listAdminUsers, - createAdminUser, - updateAdminUser, - deleteAdminUser, - type AdminUser, -} from '../../api/endpoints'; -import { useCurrentUser } from '../../hooks/useCurrentUser'; - -interface Props { - id: string; - zIndex: number; -} - -function fmtCreated(iso: string): string { - try { - const d = new Date(iso); - return d.toISOString().slice(0, 10); - } catch { - return iso; - } -} - -export const AdminUsersWindow: React.FC = ({ id, zIndex }) => { - const { user: me } = useCurrentUser(); - const [users, setUsers] = useState([]); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - - // Add-user form state - const [newUsername, setNewUsername] = useState(''); - const [newPassword, setNewPassword] = useState(''); - const [newIsAdmin, setNewIsAdmin] = useState(false); - const [creating, setCreating] = useState(false); - - // Per-row "reset password" state - const [pwEditingId, setPwEditingId] = useState(null); - const [pwValue, setPwValue] = useState(''); - - const refresh = useCallback(async () => { - setLoading(true); - setError(null); - try { - const res = await listAdminUsers(); - setUsers(res.users ?? []); - } catch (e) { - setError(String(e)); - } finally { - setLoading(false); - } - }, []); - - useEffect(() => { void refresh(); }, [refresh]); - - const onCreate = useCallback(async (e: React.FormEvent) => { - e.preventDefault(); - if (!newUsername.trim() || newPassword.length < 4) { - setError('Username required and password must be at least 4 chars'); - return; - } - setCreating(true); - setError(null); - try { - await createAdminUser(newUsername.trim(), newPassword, newIsAdmin); - setNewUsername(''); setNewPassword(''); setNewIsAdmin(false); - await refresh(); - } catch (e) { - setError(String(e)); - } finally { - setCreating(false); - } - }, [newUsername, newPassword, newIsAdmin, refresh]); - - const onToggleAdmin = useCallback(async (u: AdminUser) => { - setError(null); - try { - await updateAdminUser(u.id, { is_admin: !u.is_admin }); - await refresh(); - } catch (e) { - setError(String(e)); - } - }, [refresh]); - - const onSavePassword = useCallback(async (id: number) => { - if (pwValue.length < 4) { - setError('Password must be at least 4 characters'); - return; - } - setError(null); - try { - await updateAdminUser(id, { password: pwValue }); - setPwEditingId(null); - setPwValue(''); - } catch (e) { - setError(String(e)); - } - }, [pwValue]); - - const onDelete = useCallback(async (u: AdminUser) => { - if (!confirm(`Delete user "${u.username}"? This cannot be undone.`)) return; - setError(null); - try { - await deleteAdminUser(u.id); - await refresh(); - } catch (e) { - setError(String(e)); - } - }, [refresh]); - - return ( - -
    - {error &&
    {error}
    } - -
    -

    Add user

    -
    - setNewUsername(e.target.value)} - disabled={creating} - autoComplete="off" - /> - setNewPassword(e.target.value)} - disabled={creating} - autoComplete="new-password" - /> - - -
    -
    - -
    -

    Users {loading && (loading…)}

    - - - - - - - - - - - - {users.map(u => { - const isMe = me != null && me.username.toLowerCase() === u.username.toLowerCase(); - return ( - - - - - - - - ); - })} - {users.length === 0 && !loading && ( - - )} - -
    IDUsernameAdminCreatedActions
    {u.id} - {u.username} - {isMe && (you)} - - - {fmtCreated(u.created_at)} - {pwEditingId === u.id ? ( - - setPwValue(e.target.value)} - autoFocus - /> - - - - ) : ( - <> - - {!isMe && ( - - )} - - )} -
    No users.
    -
    -
    -
    - ); -}; diff --git a/frontend/src/components/windows/AgentWindow.tsx b/frontend/src/components/windows/AgentWindow.tsx deleted file mode 100644 index 62e9dbc3..00000000 --- a/frontend/src/components/windows/AgentWindow.tsx +++ /dev/null @@ -1,180 +0,0 @@ -import React, { useCallback, useEffect, useRef, useState } from 'react'; -import { DraggableWindow } from './DraggableWindow'; -import { - agentAsk, - agentNewSession, - agentSessionHistory, - type AgentHistoryMessage, -} from '../../api/endpoints'; - -interface Props { - id: string; - zIndex: number; -} - -interface ChatMsg { - role: 'user' | 'assistant' | 'error'; - text: string; -} - -const SESSION_KEY = 'overlord_agent_session_id'; - -/** UUID is preferred but crypto.randomUUID is only available in secure contexts. */ -function newUuid(): string { - if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') { - return crypto.randomUUID(); - } - // RFC4122-ish fallback - const r = (n: number) => Math.floor(Math.random() * n); - return `${r(0x100000000).toString(16).padStart(8, '0')}-${r(0x10000).toString(16).padStart(4, '0')}-4${r(0x1000).toString(16).padStart(3, '0')}-${(8 + r(4)).toString(16)}${r(0x1000).toString(16).padStart(3, '0')}-${r(0x1000000000000).toString(16).padStart(12, '0')}`; -} - -function loadSessionId(): string { - try { - const stored = localStorage.getItem(SESSION_KEY); - if (stored) return stored; - } catch { /* ignore */ } - const fresh = newUuid(); - try { localStorage.setItem(SESSION_KEY, fresh); } catch { /* ignore */ } - return fresh; -} - -export const AgentWindow: React.FC = ({ id, zIndex }) => { - const [sessionId, setSessionId] = useState(() => loadSessionId()); - const [messages, setMessages] = useState([]); - const [input, setInput] = useState(''); - const [loading, setLoading] = useState(false); - const [hydrating, setHydrating] = useState(true); - const scrollRef = useRef(null); - - // Rehydrate from server-side session JSONL on mount / session change. - useEffect(() => { - let cancelled = false; - setHydrating(true); - agentSessionHistory(sessionId) - .then(res => { - if (cancelled) return; - const msgs: ChatMsg[] = (res.messages ?? []).map((m: AgentHistoryMessage) => ({ - role: m.role, - text: m.text, - })); - setMessages(msgs); - }) - .catch(() => { - if (!cancelled) setMessages([]); - }) - .finally(() => { - if (!cancelled) setHydrating(false); - }); - return () => { cancelled = true; }; - }, [sessionId]); - - // Auto-scroll to bottom on new messages. - useEffect(() => { - const el = scrollRef.current; - if (el) el.scrollTop = el.scrollHeight; - }, [messages.length, loading]); - - const send = useCallback(async () => { - const text = input.trim(); - if (!text || loading) return; - setInput(''); - setMessages(prev => [...prev, { role: 'user', text }]); - setLoading(true); - try { - const res = await agentAsk(text, sessionId); - setMessages(prev => [ - ...prev, - { role: res.is_error ? 'error' : 'assistant', text: res.result || '(no response)' }, - ]); - } catch (err) { - setMessages(prev => [ - ...prev, - { role: 'error', text: `Request failed: ${String(err)}` }, - ]); - } finally { - setLoading(false); - } - }, [input, loading, sessionId]); - - const newChat = useCallback(async () => { - if (loading) return; - let fresh = ''; - try { - const res = await agentNewSession(); - fresh = res.session_id; - } catch { - fresh = newUuid(); - } - try { localStorage.setItem(SESSION_KEY, fresh); } catch { /* ignore */ } - setSessionId(fresh); - setMessages([]); - setInput(''); - }, [loading]); - - const onKeyDown = useCallback((e: React.KeyboardEvent) => { - if (e.key === 'Enter' && !e.shiftKey) { - e.preventDefault(); - void send(); - } - }, [send]); - - return ( - -
    -
    - - {sessionId.slice(0, 8)}… -
    - -
    - {hydrating && messages.length === 0 && ( -
    Loading conversation…
    - )} - {!hydrating && messages.length === 0 && ( -
    - Ask anything about the live game state β€” players, kills, inventory, - suitbuilder, recent rares, etc. -
    - )} - {messages.map((m, i) => ( -
    -
    - {m.role === 'user' ? 'You' : m.role === 'assistant' ? 'Overlord' : 'Error'} -
    -
    {m.text}
    -
    - ))} - {loading && ( -
    -
    Overlord
    -
    Thinking…
    -
    - )} -
    - -
    { e.preventDefault(); void send(); }} - > - - -
    - `; - content.appendChild(form); - - // Add button handler - form.querySelector('#issueAddBtn').addEventListener('click', async () => { - const title = document.getElementById('issueTitle').value.trim(); - const desc = document.getElementById('issueDescription').value.trim(); - const cat = document.getElementById('issueCategory').value; - if (!title) return; - - await fetch('/issues', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ title, description: desc, category: cat }) - }); - document.getElementById('issueTitle').value = ''; - document.getElementById('issueDescription').value = ''; - refreshIssuesList(win); - }); - - refreshIssuesList(win); -} - -async function refreshIssuesList(win) { - const listDiv = win._issuesList; - if (!listDiv) return; - - try { - const resp = await fetch('/issues'); - const data = await resp.json(); - const issues = data.issues || []; - - if (issues.length === 0) { - listDiv.innerHTML = '
    No open issues
    '; - return; - } - - // Sort: unresolved first, then resolved - issues.sort((a, b) => (a.resolved ? 1 : 0) - (b.resolved ? 1 : 0)); - - listDiv.innerHTML = ''; - issues.forEach(issue => { - const cat = ISSUE_CATEGORIES[issue.category] || ISSUE_CATEGORIES.other; - const date = issue.created ? new Date(issue.created).toLocaleDateString('sv-SE') : ''; - const isResolved = !!issue.resolved; - const author = issue.author || 'User'; - const comments = issue.comments || []; - - const row = document.createElement('div'); - row.className = 'issue-row' + (isResolved ? ' issue-resolved' : ''); - - // Header line - const headerDiv = document.createElement('div'); - headerDiv.className = 'issue-header'; - headerDiv.innerHTML = ` - ${cat.label} - ${escapeHtml(issue.title)} - by ${escapeHtml(author)} - ${date} - `; - row.appendChild(headerDiv); - - // Description - if (issue.description) { - const descDiv = document.createElement('div'); - descDiv.className = 'issue-description'; - descDiv.textContent = issue.description; - row.appendChild(descDiv); - } - - // Action buttons - const actionsDiv = document.createElement('div'); - actionsDiv.className = 'issue-actions'; - - if (isResolved) { - const reopenBtn = document.createElement('button'); - reopenBtn.textContent = '\u21BA Reopen'; - reopenBtn.className = 'issue-reopen-btn'; - reopenBtn.addEventListener('click', async () => { - await fetch(`/issues/${issue.id}`, { - method: 'PATCH', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ resolved: false }) - }); - refreshIssuesList(win); - }); - actionsDiv.appendChild(reopenBtn); - - const deleteBtn = document.createElement('button'); - deleteBtn.textContent = '\uD83D\uDDD1 Delete'; - deleteBtn.className = 'issue-delete-btn'; - deleteBtn.addEventListener('click', async () => { - if (!confirm(`Delete issue "${issue.title}"?`)) return; - await fetch(`/issues/${issue.id}`, { method: 'DELETE' }); - refreshIssuesList(win); - }); - actionsDiv.appendChild(deleteBtn); - } else { - const resolveBtn = document.createElement('button'); - resolveBtn.textContent = '\u2713 Resolve'; - resolveBtn.className = 'issue-resolve-btn'; - resolveBtn.addEventListener('click', async () => { - await fetch(`/issues/${issue.id}`, { - method: 'PATCH', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ resolved: true }) - }); - refreshIssuesList(win); - }); - actionsDiv.appendChild(resolveBtn); - } - - // Edit button - const editBtn = document.createElement('button'); - editBtn.textContent = '\u270E Edit'; - editBtn.className = 'issue-edit-btn'; - editBtn.addEventListener('click', () => { - showEditIssueForm(row, issue, win); - }); - actionsDiv.appendChild(editBtn); - - row.appendChild(actionsDiv); - - // Comments section β€” always visible inline - showCommentsSection(row, issue, win); - - listDiv.appendChild(row); - }); - } catch (err) { - listDiv.innerHTML = '
    Failed to load issues
    '; - } -} - -function showEditIssueForm(row, issue, win) { - // Remove any existing edit form - const existing = row.querySelector('.issue-edit-form'); - if (existing) { existing.remove(); return; } - - const cat = issue.category || 'other'; - const form = document.createElement('div'); - form.className = 'issue-edit-form'; - form.innerHTML = ` -
    - - -
    -
    - -
    - - -
    -
    - `; - - form.querySelector('.edit-save-btn').addEventListener('click', async () => { - const title = form.querySelector('.edit-title').value.trim(); - const desc = form.querySelector('.edit-description').value.trim(); - const category = form.querySelector('.edit-category').value; - if (!title) return; - await fetch(`/issues/${issue.id}`, { - method: 'PATCH', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ title, description: desc, category }) - }); - refreshIssuesList(win); - }); - - form.querySelector('.edit-cancel-btn').addEventListener('click', () => { - form.remove(); - }); - - row.appendChild(form); -} - -function showCommentsSection(row, issue, win) { - const section = document.createElement('div'); - section.className = 'issue-comments-section'; - - const comments = issue.comments || []; - - // Render existing comments - const commentsListDiv = document.createElement('div'); - commentsListDiv.className = 'issue-comments-list'; - if (comments.length === 0) { - commentsListDiv.innerHTML = '
    No comments yet
    '; - } else { - comments.forEach(c => { - const cDiv = document.createElement('div'); - cDiv.className = 'issue-comment'; - const cDate = c.created ? new Date(c.created).toLocaleDateString('sv-SE') : ''; - cDiv.innerHTML = `${escapeHtml(c.author || 'Anonymous')} ${cDate}`; - const textDiv = document.createElement('div'); - textDiv.className = 'comment-text'; - textDiv.textContent = c.text; - cDiv.appendChild(textDiv); - commentsListDiv.appendChild(cDiv); - }); - } - section.appendChild(commentsListDiv); - - // Add comment form - const addDiv = document.createElement('div'); - addDiv.className = 'issue-comment-form'; - addDiv.innerHTML = ` -
    - - -
    - `; - - addDiv.querySelector('.comment-add-btn').addEventListener('click', async () => { - const text = addDiv.querySelector('.comment-text-input').value.trim(); - if (!text) return; - await fetch(`/issues/${issue.id}/comments`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ text }) - }); - refreshIssuesList(win); - }); - - section.appendChild(addDiv); - row.appendChild(section); -} - -// ─── Vital Sharing NetworkUI ─────────────────────────────────────────────── -// Live state fed by share_* WebSocket messages AND by /vital-sharing/peers -// polling. Keyed by character_name. -const vitalSharingPeers = {}; -let _vitalSharingPollTimer = null; - -function removeVitalSharingPeer(name) { - if (!name) return; - if (vitalSharingPeers[name]) { - delete vitalSharingPeers[name]; - renderVitalSharingWindow(); - } -} - -function updateVitalSharingPeer(msg) { - const name = msg.character_name; - if (!name) return; - const entry = vitalSharingPeers[name] || (vitalSharingPeers[name] = { - character_name: name, - tags: [], - vitals: null, - position: null, - last_update: null, - connected: true, - }); - entry.last_update = msg.timestamp || new Date().toISOString(); - if (Array.isArray(msg.tags)) entry.tags = msg.tags; - if (msg.type === 'share_vital_update') { - entry.vitals = { - current_health: msg.current_health, - max_health: msg.max_health, - current_stamina: msg.current_stamina, - max_stamina: msg.max_stamina, - current_mana: msg.current_mana, - max_mana: msg.max_mana, - }; - } else if (msg.type === 'share_position_update') { - entry.position = { - ew: msg.ew, ns: msg.ns, z: msg.z, heading: msg.heading, - }; - } - renderVitalSharingWindow(); -} - -function showVitalSharingWindow() { - const { win, content, isNew } = createWindow( - 'vitalSharingWindow', 'Vital Sharing Network', 'issues-window', - { onClose: () => { - if (_vitalSharingPollTimer) { - clearInterval(_vitalSharingPollTimer); - _vitalSharingPollTimer = null; - } - } - } - ); - - if (!isNew) { - refreshVitalSharingPeers(); - return; - } - - win.style.width = '520px'; - win.style.height = '500px'; - - const listDiv = document.createElement('div'); - listDiv.className = 'vital-sharing-list'; - listDiv.style.cssText = 'padding:6px;overflow-y:auto;flex:1;'; - content.appendChild(listDiv); - win._vitalSharingList = listDiv; - - refreshVitalSharingPeers(); - if (_vitalSharingPollTimer) clearInterval(_vitalSharingPollTimer); - _vitalSharingPollTimer = setInterval(refreshVitalSharingPeers, 5000); -} - -async function refreshVitalSharingPeers() { - try { - const resp = await fetch('/vital-sharing/peers'); - if (!resp.ok) return; - const data = await resp.json(); - const serverNames = new Set(); - (data.peers || []).forEach(p => { - serverNames.add(p.character_name); - const existing = vitalSharingPeers[p.character_name] || {}; - vitalSharingPeers[p.character_name] = { ...existing, ...p }; - }); - // Prune any local entries the server no longer knows about (unsubscribed - // or disconnected). This catches any race where the share_peer_removed - // broadcast didn't arrive. - Object.keys(vitalSharingPeers).forEach(name => { - if (!serverNames.has(name)) delete vitalSharingPeers[name]; - }); - } catch (e) { - // ignore transient errors - } - renderVitalSharingWindow(); -} - -function renderVitalSharingWindow() { - const win = document.getElementById('vitalSharingWindow'); - if (!win || win.style.display === 'none') return; - const listDiv = win._vitalSharingList; - if (!listDiv) return; - - const peers = Object.values(vitalSharingPeers).sort((a, b) => - (a.character_name || '').localeCompare(b.character_name || '') - ); - - if (peers.length === 0) { - listDiv.innerHTML = '
    No vital-sharing peers connected
    '; - return; - } - - listDiv.innerHTML = ''; - peers.forEach(p => { - const row = document.createElement('div'); - row.className = 'vital-sharing-peer'; - row.style.cssText = 'border:1px solid #444;background:#1f1f1f;padding:6px 8px;margin-bottom:5px;border-radius:3px;font-size:0.78rem;color:#ddd;'; - - const dot = p.plugin_connected - ? '●' - : '●'; - const subscribed = p.subscribed ? ' [subscribed]' : ''; - const tags = (p.tags || []).join(', ') || 'no tags'; - - let vitalsHtml = '(no vitals yet)'; - if (p.vitals && p.vitals.max_health) { - const v = p.vitals; - const pct = (cur, max) => max > 0 ? Math.max(0, Math.min(100, (cur / max) * 100)) : 0; - const bar = (label, cur, max, color) => ` -
    - ${label} -
    -
    -
    - ${cur ?? 0}/${max ?? 0} -
    `; - vitalsHtml = - bar('HP', v.current_health, v.max_health, 'linear-gradient(90deg, #ff4444, #ff6666)') + - bar('STA', v.current_stamina, v.max_stamina, 'linear-gradient(90deg, #ffaa00, #ffcc44)') + - bar('MANA', v.current_mana, v.max_mana, 'linear-gradient(90deg, #4488ff, #66aaff)'); - } - - let posHtml = ''; - if (p.position && p.position.ew !== undefined) { - const fmt = (n) => (typeof n === 'number' ? n.toFixed(1) : n); - posHtml = `
    - ${fmt(p.position.ns)}N, ${fmt(p.position.ew)}E z=${fmt(p.position.z)} -
    `; - } - - row.innerHTML = ` -
    - ${dot} - ${p.character_name} - ${subscribed} -
    -
    tags: ${tags}
    - ${vitalsHtml} - ${posHtml} - `; - listDiv.appendChild(row); - }); -} - -// ─── Combat Stats (Mag-Tools style) ─────────────────────────────────────── -const liveCombatStats = {}; -const combatStatsWindows = {}; -const DAMAGE_ELEMENTS = ['Typeless','Slash','Pierce','Bludgeon','Fire','Cold','Acid','Electric']; - -function showCombatStatsWindow(charName) { - // If called without a name, show a picker of all characters with data - if (!charName) { - const chars = Object.keys(liveCombatStats).sort(); - if (chars.length === 0) { - // Try fetching from API - fetch('/combat-stats').then(r => r.json()).then(data => { - if (data.stats && data.stats.length > 0) { - data.stats.forEach(s => { liveCombatStats[s.character_name] = s; }); - showCombatStatsPickerWindow(); - } else { - alert('No combat stats available yet. Kill some monsters first!'); - } - }); - return; - } - showCombatStatsPickerWindow(); - return; - } - - const windowId = `combatStatsWindow-${charName}`; - const { win, content, isNew } = createWindow(windowId, `Combat: ${charName}`, 'issues-window'); - - if (!isNew) { - renderCombatStatsContent(win, charName); - return; - } - - win.style.width = '620px'; - win.style.height = '560px'; - combatStatsWindows[charName] = win; - - // Session/Lifetime toggle - const controls = document.createElement('div'); - controls.style.cssText = 'padding:4px 8px;display:flex;gap:6px;align-items:center;border-bottom:1px solid #444;'; - const sessionBtn = document.createElement('button'); - sessionBtn.textContent = 'Session'; - sessionBtn.className = 'combat-stats-toggle active'; - sessionBtn.onclick = () => { win._combatMode = 'session'; sessionBtn.classList.add('active'); lifetimeBtn.classList.remove('active'); renderCombatStatsContent(win, charName); }; - const lifetimeBtn = document.createElement('button'); - lifetimeBtn.textContent = 'Lifetime'; - lifetimeBtn.className = 'combat-stats-toggle'; - lifetimeBtn.onclick = () => { win._combatMode = 'lifetime'; lifetimeBtn.classList.add('active'); sessionBtn.classList.remove('active'); renderCombatStatsContent(win, charName); }; - controls.appendChild(sessionBtn); - controls.appendChild(lifetimeBtn); - content.appendChild(controls); - - // Monster list (top) - const monsterDiv = document.createElement('div'); - monsterDiv.className = 'combat-monster-list'; - monsterDiv.style.cssText = 'height:180px;overflow-y:auto;border-bottom:1px solid #444;'; - content.appendChild(monsterDiv); - win._monsterList = monsterDiv; - - // Damage breakdown grid (bottom) - const breakdownDiv = document.createElement('div'); - breakdownDiv.className = 'combat-breakdown'; - breakdownDiv.style.cssText = 'flex:1;overflow-y:auto;padding:4px 6px;'; - content.appendChild(breakdownDiv); - win._breakdownGrid = breakdownDiv; - - win._combatMode = 'session'; - win._selectedMonster = null; // null = "All" - - renderCombatStatsContent(win, charName); -} - -function showCombatStatsPickerWindow() { - const { win, content, isNew } = createWindow('combatStatsPicker', 'Combat Stats β€” Select Character', 'issues-window'); - if (!isNew) { renderCombatStatsPicker(win); return; } - win.style.width = '320px'; - win.style.height = '400px'; - const listDiv = document.createElement('div'); - listDiv.style.cssText = 'padding:6px;overflow-y:auto;flex:1;'; - content.appendChild(listDiv); - win._pickerList = listDiv; - renderCombatStatsPicker(win); -} - -function renderCombatStatsPicker(win) { - const listDiv = win._pickerList; - if (!listDiv) return; - const chars = Object.keys(liveCombatStats).sort(); - listDiv.innerHTML = ''; - if (chars.length === 0) { - listDiv.innerHTML = '
    No combat data yet
    '; - return; - } - chars.forEach(name => { - const row = document.createElement('div'); - row.style.cssText = 'padding:4px 8px;cursor:pointer;border-bottom:1px solid #333;color:#ddd;font-size:0.85rem;'; - row.textContent = name; - row.onmouseenter = () => row.style.background = '#333'; - row.onmouseleave = () => row.style.background = ''; - row.onclick = () => { showCombatStatsWindow(name); }; - listDiv.appendChild(row); - }); -} - -function updateCombatStatsWindows(charName) { - const win = combatStatsWindows[charName]; - if (win && win.style.display !== 'none') { - renderCombatStatsContent(win, charName); - } -} - -function renderCombatStatsContent(win, charName) { - const data = liveCombatStats[charName]; - if (!data) return; - - const mode = win._combatMode || 'session'; - const stateData = data[mode]; - if (!stateData) return; - - const monsters = stateData.monsters || {}; - const monsterNames = Object.keys(monsters).filter(n => n !== '__cloak_surges__').sort(); - - // ── Monster list ── - const monsterDiv = win._monsterList; - if (monsterDiv) { - monsterDiv.innerHTML = ''; - - // Header row - const hdr = document.createElement('div'); - hdr.style.cssText = 'display:flex;gap:4px;padding:2px 6px;font-size:0.72rem;color:#888;border-bottom:1px solid #333;font-weight:bold;'; - hdr.innerHTML = `MonsterKillsDmg RecvDmg Given`; - monsterDiv.appendChild(hdr); - - // "All" row - const allRow = createMonsterRow('*', 'All', stateData.total_kills, stateData.total_damage_received, stateData.total_damage_given, win._selectedMonster === null); - allRow.onclick = () => { win._selectedMonster = null; renderCombatStatsContent(win, charName); }; - monsterDiv.appendChild(allRow); - - // Per-monster rows - monsterNames.forEach(name => { - const m = monsters[name]; - const selected = win._selectedMonster === name; - const row = createMonsterRow('', name, m.kill_count, m.damage_received, m.damage_given, selected); - row.onclick = () => { win._selectedMonster = name; renderCombatStatsContent(win, charName); }; - monsterDiv.appendChild(row); - }); - } - - // ── Breakdown grid ── - const grid = win._breakdownGrid; - if (!grid) return; - - // Gather stats for the selected monster or all - let offense = {}, defense = {}; - let totalAethSurges = 0, totalCloakSurges = 0; - - if (win._selectedMonster === null) { - // Aggregate all monsters - monsterNames.forEach(name => { - const m = monsters[name]; - mergeAttackStats(offense, m.offense || {}); - mergeAttackStats(defense, m.defense || {}); - totalAethSurges += m.aetheria_surges || 0; - totalCloakSurges += m.cloak_surges || 0; - }); - // Add cloak surges from the synthetic key - if (monsters['__cloak_surges__']) { - totalCloakSurges += monsters['__cloak_surges__'].cloak_surges || 0; - } - } else { - const m = monsters[win._selectedMonster]; - if (m) { - offense = m.offense || {}; - defense = m.defense || {}; - totalAethSurges = m.aetheria_surges || 0; - totalCloakSurges = m.cloak_surges || 0; - } - } - - // Compute aggregates for the right-side stats - const offAll = flattenStats(offense); - const defAll = flattenStats(defense); - const defMM = flattenStatsForType(defense, 'MeleeMissile'); - const defMag = flattenStatsForType(defense, 'Magic'); - - const totalAttacks = offAll.totalAttacks; - const failedAttacks = offAll.failedAttacks; - const hitRate = totalAttacks > 0 ? ((totalAttacks - failedAttacks) / totalAttacks * 100).toFixed(0) : '0'; - - const totalMeleeDefends = defMM.totalAttacks; - const totalEvades = defMM.failedAttacks; - const evadeRate = totalMeleeDefends > 0 ? (totalEvades / totalMeleeDefends * 100).toFixed(0) : '0'; - - const totalMagicDefends = defMag.totalAttacks; - const totalResists = defMag.failedAttacks; - const resistRate = totalMagicDefends > 0 ? (totalResists / totalMagicDefends * 100).toFixed(0) : '0'; - - const aethRate = totalAttacks > 0 ? (totalAethSurges / totalAttacks * 100).toFixed(1) : '0.0'; - const totalDefHits = (totalMeleeDefends - totalEvades) + (totalMagicDefends - totalResists); - const cloakRate = totalDefHits > 0 ? (totalCloakSurges / totalDefHits * 100).toFixed(1) : '0.0'; - - const crits = offAll.crits; - const hitsNonKill = totalAttacks - failedAttacks; - const critRate = hitsNonKill > 0 ? (crits / hitsNonKill * 100).toFixed(1) : '0.0'; - const normalHits = hitsNonKill - crits; - const avgNormal = normalHits > 0 ? Math.round(offAll.totalNormalDamage / normalHits) : 0; - const avgCrit = crits > 0 ? Math.round(offAll.totalCritDamage / crits) : 0; - - // Damage by element β€” offense (given) and defense (received) - const offDmgMM = {}, offDmgMag = {}, defDmgMM = {}, defDmgMag = {}; - let totalOffMM = 0, totalOffMag = 0, totalDefMM = 0, totalDefMag = 0; - DAMAGE_ELEMENTS.forEach(el => { - offDmgMM[el] = getDefDmg(offense, 'MeleeMissile', el); - offDmgMag[el] = getDefDmg(offense, 'Magic', el); - defDmgMM[el] = getDefDmg(defense, 'MeleeMissile', el); - defDmgMag[el] = getDefDmg(defense, 'Magic', el); - totalOffMM += offDmgMM[el]; - totalOffMag += offDmgMag[el]; - totalDefMM += defDmgMM[el]; - totalDefMag += defDmgMag[el]; - }); - - const totalDmgGiven = offAll.totalNormalDamage + offAll.totalCritDamage; - - // Build the grid HTML - const fmtN = n => n === 0 ? '' : n.toLocaleString(); - const rightCell = (text) => `${text}`; - const labelCell = (text) => `${text}`; - const headerCell = (text) => `${text}`; - const statLabel = (text) => `${text}`; - const sepCell = ``; - - let html = ''; - - // Column headers: Element | Dmg Given (M/M, Mag) | Dmg Recv (M/M, Mag) | Stats - html += `${headerCell('Given M/M')}${headerCell('Given Mag')}${sepCell}${headerCell('Recv M/M')}${headerCell('Recv Mag')}${sepCell}${statLabel('Attacks')}${rightCell(totalAttacks > 0 ? `${fmtN(totalAttacks)} (${hitRate}%)` : '')}`; - - // Stats to show on the right side of each element row - const rightStats = [ - ['Evades', () => totalMeleeDefends > 0 ? `${fmtN(totalMeleeDefends)} (${evadeRate}%)` : ''], - ['Resists', () => totalMagicDefends > 0 ? `${fmtN(totalMagicDefends)} (${resistRate}%)` : ''], - ['A.Surges', () => totalAethSurges > 0 ? `${fmtN(totalAethSurges)} (${aethRate}%)` : ''], - ['C.Surges', () => totalCloakSurges > 0 ? `${fmtN(totalCloakSurges)} (${cloakRate}%)` : ''], - ['', () => ''], - ['', () => ''], - ['Av/Mx', () => avgNormal > 0 ? `${fmtN(avgNormal)} / ${fmtN(offAll.maxNormalDamage)}` : ''], - ['Crits', () => crits > 0 ? `${fmtN(crits)} (${critRate}%)` : ''], - ]; - - for (let i = 0; i < DAMAGE_ELEMENTS.length; i++) { - const el = DAMAGE_ELEMENTS[i]; - const rs = rightStats[i] || ['', () => '']; - html += `${labelCell(el)}${rightCell(fmtN(offDmgMM[el]))}${rightCell(fmtN(offDmgMag[el]))}${sepCell}${rightCell(fmtN(defDmgMM[el]))}${rightCell(fmtN(defDmgMag[el]))}${sepCell}${rs[0] ? statLabel(rs[0]) : ''}${rightCell(rs[1]())}`; - } - - // Crit Avg/Max row - html += `${sepCell}${sepCell}${statLabel('Av/Mx')}${rightCell(avgCrit > 0 ? `${fmtN(avgCrit)} / ${fmtN(offAll.maxCritDamage)}` : '')}`; - - // Blank row - html += ``; - - // Total row - html += `${labelCell('Total')}${rightCell(fmtN(totalOffMM))}${rightCell(fmtN(totalOffMag))}${sepCell}${rightCell(fmtN(totalDefMM))}${rightCell(fmtN(totalDefMag))}${sepCell}${statLabel('Total')}${rightCell(fmtN(totalDmgGiven))}`; - - html += '
    '; - grid.innerHTML = html; -} - -function createMonsterRow(marker, name, kills, dmgRecv, dmgGiven, selected) { - const row = document.createElement('div'); - const bg = selected ? 'background:#2a3a4a;' : ''; - row.style.cssText = `display:flex;gap:4px;padding:2px 6px;font-size:0.78rem;cursor:pointer;border-bottom:1px solid #222;${bg}color:#ddd;`; - row.onmouseenter = () => { if (!selected) row.style.background = '#252525'; }; - row.onmouseleave = () => { if (!selected) row.style.background = ''; }; - const fmtN = n => (!n || n === 0) ? '' : Number(n).toLocaleString(); - row.innerHTML = `${marker}${name}${fmtN(kills)}${fmtN(dmgRecv)}${fmtN(dmgGiven)}`; - return row; -} - -// ── Helpers for aggregating nested combat data ── -function mergeAttackStats(target, source) { - for (const [atk, byEl] of Object.entries(source)) { - if (!target[atk]) target[atk] = {}; - for (const [el, stats] of Object.entries(byEl)) { - if (!target[atk][el]) target[atk][el] = { total_attacks:0, failed_attacks:0, crits:0, total_normal_damage:0, max_normal_damage:0, total_crit_damage:0, max_crit_damage:0 }; - const t = target[atk][el]; - t.total_attacks += stats.total_attacks || 0; - t.failed_attacks += stats.failed_attacks || 0; - t.crits += stats.crits || 0; - t.total_normal_damage += stats.total_normal_damage || 0; - t.max_normal_damage = Math.max(t.max_normal_damage, stats.max_normal_damage || 0); - t.total_crit_damage += stats.total_crit_damage || 0; - t.max_crit_damage = Math.max(t.max_crit_damage, stats.max_crit_damage || 0); - } - } -} - -function flattenStats(attackTypes) { - let r = { totalAttacks:0, failedAttacks:0, crits:0, totalNormalDamage:0, maxNormalDamage:0, totalCritDamage:0, maxCritDamage:0 }; - for (const byEl of Object.values(attackTypes)) { - for (const s of Object.values(byEl)) { - r.totalAttacks += s.total_attacks || 0; - r.failedAttacks += s.failed_attacks || 0; - r.crits += s.crits || 0; - r.totalNormalDamage += s.total_normal_damage || 0; - r.maxNormalDamage = Math.max(r.maxNormalDamage, s.max_normal_damage || 0); - r.totalCritDamage += s.total_crit_damage || 0; - r.maxCritDamage = Math.max(r.maxCritDamage, s.max_crit_damage || 0); - } - } - return r; -} - -function flattenStatsForType(attackTypes, type) { - let r = { totalAttacks:0, failedAttacks:0, crits:0, totalNormalDamage:0, maxNormalDamage:0, totalCritDamage:0, maxCritDamage:0 }; - const byEl = attackTypes[type]; - if (!byEl) return r; - for (const s of Object.values(byEl)) { - r.totalAttacks += s.total_attacks || 0; - r.failedAttacks += s.failed_attacks || 0; - r.crits += s.crits || 0; - r.totalNormalDamage += s.total_normal_damage || 0; - r.maxNormalDamage = Math.max(r.maxNormalDamage, s.max_normal_damage || 0); - r.totalCritDamage += s.total_crit_damage || 0; - r.maxCritDamage = Math.max(r.maxCritDamage, s.max_crit_damage || 0); - } - return r; -} - -function getDefDmg(defense, atkType, element) { - const byEl = defense[atkType]; - if (!byEl) return 0; - const s = byEl[element]; - if (!s) return 0; - return (s.total_normal_damage || 0) + (s.total_crit_damage || 0); -} diff --git a/static/classic/style-ac.css b/static/classic/style-ac.css deleted file mode 100644 index a25e1680..00000000 --- a/static/classic/style-ac.css +++ /dev/null @@ -1,739 +0,0 @@ -/* - * style-ac.css - Asheron's Call themed styles for Dereth Tracker - * - * Recreates the classic AC UI with stone textures, beveled edges, - * golden accents, and medieval fantasy aesthetics. - */ - -/* CSS Custom Properties for AC theme colors and sizing */ -:root { - --sidebar-width: 340px; - - /* AC Color Palette */ - --ac-black: #0a0a0a; - --ac-dark-stone: #1a1a1a; - --ac-medium-stone: #2a2a2a; - --ac-light-stone: #3a3a3a; - --ac-border-dark: #000; - --ac-border-light: #4a4a4a; - --ac-gold: #d4af37; - --ac-gold-bright: #ffd700; - --ac-gold-dark: #b8941f; - --ac-green: #00ff00; - --ac-cyan: #00ffff; - --ac-text: #e0e0e0; - --ac-text-dim: #a0a0a0; - - /* Backgrounds */ - --bg-main: var(--ac-black); - --bg-side: var(--ac-dark-stone); - --card: var(--ac-medium-stone); - --card-hov: var(--ac-light-stone); - --text: var(--ac-text); - --accent: var(--ac-gold); -} - -/* Placeholder text in chat input */ -.chat-input::placeholder { - color: var(--ac-text-dim); - opacity: 0.7; -} - -html { - margin: 0; - height: 100%; - width: 100%; -} - -body { - margin: 0; - height: 100%; - display: flex; - overflow: hidden; - font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif; - background: var(--bg-main); - color: var(--text); - background-image: - repeating-linear-gradient( - 45deg, - transparent, - transparent 10px, - rgba(255, 255, 255, 0.01) 10px, - rgba(255, 255, 255, 0.01) 20px - ); -} - -/* AC-style stone textured panels with beveled edges */ -.ac-panel { - background: linear-gradient(135deg, var(--ac-medium-stone) 0%, var(--ac-dark-stone) 100%); - border: 2px solid var(--ac-border-dark); - box-shadow: - inset 2px 2px 3px rgba(255, 255, 255, 0.1), - inset -2px -2px 3px rgba(0, 0, 0, 0.5), - 0 2px 5px rgba(0, 0, 0, 0.8); - border-radius: 0; -} - -/* Sort buttons - AC style */ -.sort-buttons { - display: flex; - gap: 3px; - margin: 12px 16px 8px; - padding: 8px; - background: var(--ac-dark-stone); - border: 1px solid var(--ac-border-dark); - box-shadow: inset 1px 1px 3px rgba(0, 0, 0, 0.5); -} - -.sort-buttons .btn { - flex: 1; - padding: 5px 8px; - background: linear-gradient(180deg, var(--ac-light-stone) 0%, var(--ac-medium-stone) 100%); - color: var(--ac-text-dim); - border: 1px solid var(--ac-border-dark); - border-radius: 2px; - text-align: center; - cursor: pointer; - user-select: none; - font-size: 0.75rem; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.5px; - transition: all 0.15s; - box-shadow: - 1px 1px 2px rgba(0, 0, 0, 0.5), - inset 1px 1px 2px rgba(255, 255, 255, 0.1); -} - -.sort-buttons .btn:hover { - background: linear-gradient(180deg, var(--ac-light-stone) 0%, var(--ac-light-stone) 100%); - color: var(--ac-gold-bright); - box-shadow: - 1px 1px 2px rgba(0, 0, 0, 0.5), - inset 1px 1px 2px rgba(255, 255, 255, 0.2), - 0 0 5px rgba(212, 175, 55, 0.3); -} - -.sort-buttons .btn:active { - box-shadow: - inset 2px 2px 3px rgba(0, 0, 0, 0.7), - inset -1px -1px 2px rgba(255, 255, 255, 0.1); -} - -.sort-buttons .btn.active { - background: linear-gradient(180deg, var(--ac-gold) 0%, var(--ac-gold-dark) 100%); - color: var(--ac-black); - border-color: var(--ac-gold-dark); - font-weight: 700; - position: relative; - box-shadow: - 1px 1px 2px rgba(0, 0, 0, 0.5), - inset 1px 1px 2px rgba(255, 255, 255, 0.3), - 0 0 10px rgba(212, 175, 55, 0.5); -} - -.sort-buttons .btn.active:hover { - background: linear-gradient(180deg, var(--ac-gold-bright) 0%, var(--ac-gold) 100%); - color: var(--ac-black); -} - -/* Sort direction indicators */ -.sort-buttons .btn.active::after { - content: ''; - position: absolute; - top: 3px; - right: 3px; - width: 0; - height: 0; - border-left: 3px solid transparent; - border-right: 3px solid transparent; -} - -/* Most sorts are descending (down arrow) */ -.sort-buttons .btn.active::after { - border-top: 4px solid var(--ac-black); -} - -/* Name and KPR are ascending (up arrow) */ -.sort-buttons .btn.active[data-value="name"]::after, -.sort-buttons .btn.active[data-value="kpr"]::after { - border-top: none; - border-bottom: 4px solid var(--ac-black); -} - -/* Sidebar - AC stone panel style */ -#sidebar { - width: var(--sidebar-width); - scrollbar-width: thin; - scrollbar-color: var(--ac-gold-dark) var(--ac-dark-stone); - background: linear-gradient(180deg, var(--ac-dark-stone) 0%, var(--ac-black) 100%); - border-right: 3px solid var(--ac-border-dark); - box-shadow: - inset -2px 0 5px rgba(0, 0, 0, 0.5), - 2px 0 5px rgba(0, 0, 0, 0.8); - box-sizing: border-box; - padding: 18px 16px; - overflow-y: auto; -} - -#sidebar h2 { - margin: 8px 0 12px; - font-size: 1.25rem; - color: var(--ac-gold); - text-shadow: - 2px 2px 3px rgba(0, 0, 0, 0.8), - 0 0 10px rgba(212, 175, 55, 0.3); - font-weight: 700; - text-transform: uppercase; - letter-spacing: 1px; -} - -#playerList { - list-style: none; - margin: 0; - padding: 0; -} - -/* Filter input - AC style */ -.player-filter { - width: 100%; - padding: 6px 10px; - margin-bottom: 12px; - background: var(--ac-dark-stone); - color: var(--ac-gold); - border: 2px solid var(--ac-border-dark); - border-radius: 2px; - font-size: 0.9rem; - box-sizing: border-box; - box-shadow: - inset 2px 2px 3px rgba(0, 0, 0, 0.5), - inset -1px -1px 2px rgba(255, 255, 255, 0.05); - font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif; -} - -.player-filter:focus { - outline: none; - border-color: var(--ac-gold-dark); - box-shadow: - inset 2px 2px 3px rgba(0, 0, 0, 0.5), - 0 0 5px rgba(212, 175, 55, 0.5); -} - -/* Map container */ -#mapContainer { - flex: 1; - position: relative; - overflow: hidden; - background: var(--bg-main); - box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.8); -} - -/* Player list items - AC stone panels */ -#playerList li { - display: grid; - grid-template-columns: 1fr auto auto auto auto auto; - grid-template-rows: auto auto auto auto; - grid-template-areas: - "name name name name name name" - "kills totalkills kph kph kph kph" - "rares kpr meta meta meta meta" - "onlinetime deaths tapers tapers tapers tapers"; - gap: 4px 8px; - margin: 6px 0; - padding: 10px 12px; - background: linear-gradient(135deg, var(--ac-medium-stone) 0%, var(--ac-dark-stone) 100%); - border: 2px solid var(--ac-border-dark); - border-left: 4px solid var(--ac-gold-dark); - transition: all 0.2s; - box-shadow: - 1px 1px 3px rgba(0, 0, 0, 0.5), - inset 1px 1px 2px rgba(255, 255, 255, 0.05); -} - -/* Grid assignments */ -.player-name { - grid-area: name; - font-weight: 700; - color: var(--ac-gold); - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8); -} -.coordinates-inline { - font-size: 0.75rem; - color: var(--ac-text-dim); - font-weight: 400; - margin-left: 8px; -} - -.stat.kills { grid-area: kills; } -.stat.total-kills { grid-area: totalkills; } -.stat.kph { grid-area: kph; } -.stat.rares { grid-area: rares; } -.stat.kpr { grid-area: kpr; } -.stat.meta { grid-area: meta; } -.stat.onlinetime { grid-area: onlinetime; } -.stat.deaths { grid-area: deaths; } -.stat.tapers { grid-area: tapers; } - -/* Stat pills - AC style */ -#playerList li .stat { - background: linear-gradient(180deg, rgba(0, 0, 0, 0.3) 0%, rgba(0, 0, 0, 0.5) 100%); - padding: 4px 8px; - border-radius: 2px; - display: inline-block; - font-size: 0.75rem; - white-space: nowrap; - color: var(--ac-text); - border: 1px solid rgba(0, 0, 0, 0.5); - box-shadow: - 1px 1px 2px rgba(0, 0, 0, 0.3), - inset 1px 1px 1px rgba(255, 255, 255, 0.05); -} - -/* Icons & suffixes */ -.stat.kills::before { content: "βš”οΈ "; } -.stat.total-kills::before { content: "πŸ† "; } -.stat.kph::after { content: " KPH"; font-size:0.7em; color: var(--ac-text-dim); } -.stat.rares::before { content: "πŸ’Ž "; } -.stat.rares::after { content: " Rares"; font-size:0.7em; color: var(--ac-text-dim); } -.stat.kpr::before { content: "πŸ“Š "; } -.stat.kpr::after { content: " KPR"; font-size:0.7em; color: var(--ac-text-dim); } - -/* Metastate pills */ -#playerList li .stat.meta { - background: linear-gradient(180deg, var(--ac-gold) 0%, var(--ac-gold-dark) 100%); - color: var(--ac-black); - border-color: var(--ac-gold-dark); -} - -#playerList li .stat.meta.green { - background: linear-gradient(180deg, #4ade80 0%, #22c55e 100%); - color: var(--ac-black); - border-color: #16a34a; -} - -#playerList li .stat.meta.red { - background: linear-gradient(180deg, #f87171 0%, #ef4444 100%); - color: #fff; - border-color: #dc2626; -} - -/* Chat/Stats/Inventory buttons - AC style */ -.chat-btn, .stats-btn, .inventory-btn { - margin-top: 4px; - margin-right: 4px; - padding: 3px 8px; - background: linear-gradient(180deg, var(--ac-gold) 0%, var(--ac-gold-dark) 100%); - color: var(--ac-black); - border: 1px solid var(--ac-gold-dark); - border-radius: 2px; - font-size: 0.75rem; - font-weight: 600; - cursor: pointer; - text-transform: uppercase; - letter-spacing: 0.5px; - box-shadow: - 1px 1px 2px rgba(0, 0, 0, 0.5), - inset 1px 1px 1px rgba(255, 255, 255, 0.3); - transition: all 0.15s; -} - -.chat-btn:hover, .stats-btn:hover, .inventory-btn:hover { - background: linear-gradient(180deg, var(--ac-gold-bright) 0%, var(--ac-gold) 100%); - box-shadow: - 1px 1px 2px rgba(0, 0, 0, 0.5), - inset 1px 1px 1px rgba(255, 255, 255, 0.4), - 0 0 5px rgba(212, 175, 55, 0.5); -} - -/* Windows - AC stone panel style */ -.chat-window, .stats-window, .inventory-window { - position: absolute; - top: 10px; - left: calc(var(--sidebar-width) + 10px); - width: 760px; - height: 300px; - background: linear-gradient(135deg, var(--ac-medium-stone) 0%, var(--ac-dark-stone) 100%); - border: 3px solid var(--ac-border-dark); - display: flex; - flex-direction: column; - z-index: 10000; - box-shadow: - 0 5px 20px rgba(0, 0, 0, 0.8), - inset 2px 2px 3px rgba(255, 255, 255, 0.05); - border-radius: 2px; -} - -.window-content { - flex: 1; - display: flex; - flex-direction: column; - overflow: hidden; - min-height: 0; -} - -.chat-header { - display: flex; - justify-content: space-between; - align-items: center; - padding: 10px 15px; - background: linear-gradient(180deg, var(--ac-light-stone) 0%, var(--ac-medium-stone) 100%); - border-bottom: 2px solid var(--ac-border-dark); - color: var(--ac-gold); - font-weight: 700; - text-transform: uppercase; - letter-spacing: 1px; - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8); - box-shadow: 0 2px 3px rgba(0, 0, 0, 0.5); -} - -.chat-close-btn { - background: linear-gradient(180deg, #ef4444 0%, #dc2626 100%); - color: #fff; - border: 1px solid #991b1b; - border-radius: 2px; - padding: 2px 8px; - font-size: 1rem; - cursor: pointer; - font-weight: 700; - box-shadow: - 1px 1px 2px rgba(0, 0, 0, 0.5), - inset 1px 1px 1px rgba(255, 255, 255, 0.3); -} - -.chat-close-btn:hover { - background: linear-gradient(180deg, #f87171 0%, #ef4444 100%); - box-shadow: - 1px 1px 2px rgba(0, 0, 0, 0.5), - inset 1px 1px 1px rgba(255, 255, 255, 0.4), - 0 0 5px rgba(239, 68, 68, 0.5); -} - -.chat-messages { - flex: 1; - padding: 10px 15px; - overflow-y: auto; - background: rgba(0, 0, 0, 0.3); - color: var(--ac-green); - font-family: "Courier New", Courier, monospace; - font-size: 0.9rem; - line-height: 1.4; - box-shadow: inset 2px 2px 5px rgba(0, 0, 0, 0.5); -} - -.chat-messages::-webkit-scrollbar { - width: 10px; -} - -.chat-messages::-webkit-scrollbar-track { - background: var(--ac-dark-stone); - box-shadow: inset 1px 1px 2px rgba(0, 0, 0, 0.5); -} - -.chat-messages::-webkit-scrollbar-thumb { - background: var(--ac-gold-dark); - border-radius: 2px; - box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); -} - -.chat-form { - display: flex; - padding: 10px 15px; - background: var(--ac-dark-stone); - border-top: 2px solid var(--ac-border-dark); - box-shadow: 0 -2px 3px rgba(0, 0, 0, 0.5); -} - -.chat-input { - flex: 1; - padding: 6px 10px; - background: rgba(0, 0, 0, 0.5); - color: var(--ac-green); - border: 2px solid var(--ac-border-dark); - border-radius: 2px; - font-family: "Courier New", Courier, monospace; - font-size: 0.9rem; - box-shadow: inset 2px 2px 3px rgba(0, 0, 0, 0.5); -} - -.chat-input:focus { - outline: none; - border-color: var(--ac-gold-dark); - box-shadow: - inset 2px 2px 3px rgba(0, 0, 0, 0.5), - 0 0 5px rgba(212, 175, 55, 0.3); -} - -/* Map elements */ -#mapGroup { - transform-origin: top left; - position: relative; -} - -#map { - display: block; - user-select: none; - -webkit-user-drag: none; - filter: brightness(0.9) contrast(1.1); -} - -.dot { - position: absolute; - width: 10px; - height: 10px; - border-radius: 50%; - transform: translate(-50%, -50%); - pointer-events: auto; - cursor: pointer; - z-index: 10; - box-shadow: - 0 0 5px rgba(0, 0, 0, 0.8), - 0 0 10px currentColor; - border: 1px solid rgba(0, 0, 0, 0.5); -} - -.dot.highlight { - animation: pulse 2s infinite; - z-index: 20; -} - -@keyframes pulse { - 0% { box-shadow: 0 0 5px rgba(0, 0, 0, 0.8), 0 0 10px currentColor; } - 50% { box-shadow: 0 0 10px rgba(0, 0, 0, 0.8), 0 0 20px currentColor, 0 0 30px currentColor; } - 100% { box-shadow: 0 0 5px rgba(0, 0, 0, 0.8), 0 0 10px currentColor; } -} - -/* Tooltip - AC style */ -.tooltip { - position: absolute; - display: none; - background: linear-gradient(135deg, rgba(26, 26, 26, 0.95) 0%, rgba(10, 10, 10, 0.95) 100%); - color: var(--ac-gold); - padding: 6px 10px; - border: 2px solid var(--ac-gold-dark); - border-radius: 2px; - font-size: 0.8rem; - pointer-events: none; - white-space: nowrap; - z-index: 1000; - box-shadow: - 0 2px 10px rgba(0, 0, 0, 0.8), - inset 1px 1px 2px rgba(255, 255, 255, 0.1); - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8); -} - -/* Coordinate display - AC style */ -.coordinates { - position: absolute; - display: none; - background: linear-gradient(135deg, rgba(0, 50, 100, 0.95) 0%, rgba(0, 30, 60, 0.95) 100%); - color: var(--ac-cyan); - padding: 4px 8px; - border: 2px solid rgba(0, 100, 150, 0.8); - border-radius: 2px; - font-size: 0.75rem; - font-family: "Courier New", Courier, monospace; - font-weight: 700; - pointer-events: none; - white-space: nowrap; - z-index: 999; - box-shadow: - 0 2px 8px rgba(0, 0, 0, 0.8), - inset 1px 1px 2px rgba(255, 255, 255, 0.1); - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8); -} - -/* Hover states */ -#playerList li:hover { - background: linear-gradient(135deg, var(--ac-light-stone) 0%, var(--ac-medium-stone) 100%); - border-left-color: var(--ac-gold-bright); - box-shadow: - 2px 2px 5px rgba(0, 0, 0, 0.5), - inset 1px 1px 2px rgba(255, 255, 255, 0.1), - 0 0 10px rgba(212, 175, 55, 0.2); -} - -#playerList li.selected { - background: linear-gradient(135deg, var(--ac-gold-dark) 0%, var(--ac-medium-stone) 100%); - border-left-color: var(--ac-gold-bright); - box-shadow: - 2px 2px 5px rgba(0, 0, 0, 0.5), - inset 1px 1px 2px rgba(255, 255, 255, 0.2), - 0 0 15px rgba(212, 175, 55, 0.3); -} - -/* Trail paths */ -#trails { - position: absolute; - top: 0; - left: 0; - pointer-events: none; - opacity: 0.7; -} - -.trail-path { - stroke-width: 2; - stroke-opacity: 0.8; - filter: drop-shadow(0 0 3px rgba(0, 0, 0, 0.8)); -} - -/* Stats window specific */ -.stats-window { - height: auto; -} - -.stats-window .chat-messages { - display: grid; - grid-template-columns: repeat(2, 1fr); - grid-auto-rows: auto; - gap: 10px; - padding: 10px; - overflow: visible; - background: var(--ac-dark-stone); - color: var(--ac-text); -} - -.stats-window iframe { - width: 350px; - height: 200px; - border: 2px solid var(--ac-border-dark); - box-shadow: - inset 2px 2px 3px rgba(0, 0, 0, 0.5), - 1px 1px 2px rgba(0, 0, 0, 0.3); - background: var(--ac-black); -} - -/* Stats time controls - AC style */ -.stats-controls { - display: flex; - gap: 8px; - padding: 10px 15px; - background: var(--ac-medium-stone); - border-bottom: 2px solid var(--ac-border-dark); - box-shadow: 0 2px 3px rgba(0, 0, 0, 0.5); -} - -.time-range-btn { - padding: 6px 12px; - background: linear-gradient(180deg, var(--ac-light-stone) 0%, var(--ac-medium-stone) 100%); - color: var(--ac-text-dim); - border: 1px solid var(--ac-border-dark); - border-radius: 2px; - font-size: 0.85rem; - font-weight: 600; - cursor: pointer; - transition: all 0.2s; - text-transform: uppercase; - letter-spacing: 0.5px; - box-shadow: - 1px 1px 2px rgba(0, 0, 0, 0.5), - inset 1px 1px 2px rgba(255, 255, 255, 0.1); -} - -.time-range-btn:hover { - background: linear-gradient(180deg, var(--ac-light-stone) 0%, var(--ac-light-stone) 100%); - color: var(--ac-gold); - box-shadow: - 1px 1px 2px rgba(0, 0, 0, 0.5), - inset 1px 1px 2px rgba(255, 255, 255, 0.2), - 0 0 5px rgba(212, 175, 55, 0.2); -} - -.time-range-btn.active { - background: linear-gradient(180deg, var(--ac-gold) 0%, var(--ac-gold-dark) 100%); - color: var(--ac-black); - border-color: var(--ac-gold-dark); - font-weight: 700; - box-shadow: - 1px 1px 2px rgba(0, 0, 0, 0.5), - inset 1px 1px 2px rgba(255, 255, 255, 0.3), - 0 0 10px rgba(212, 175, 55, 0.4); -} - -/* Inventory window */ -.inventory-content { - flex: 1; - padding: 15px; - background: var(--ac-dark-stone); - color: var(--ac-text); - overflow-y: auto; - box-shadow: inset 2px 2px 5px rgba(0, 0, 0, 0.5); -} - -.inventory-placeholder { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - font-size: 1.1rem; - color: var(--ac-text-dim); - font-style: italic; - text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8); -} - -.stat.onlinetime::before { content: "πŸ•‘ "; } -.stat.deaths::before { content: "πŸ’€ "; } -.stat.tapers::before { - content: ""; - display: inline-block; - width: 16px; - height: 16px; - background-image: url('prismatic-taper-icon.png'); - background-size: contain; - background-repeat: no-repeat; - margin-right: 4px; - vertical-align: text-bottom; -} - -/* Disable text selection during drag */ -.noselect { - user-select: none !important; -} - -/* Custom scrollbar for sidebar */ -#sidebar::-webkit-scrollbar { - width: 12px; -} - -#sidebar::-webkit-scrollbar-track { - background: var(--ac-dark-stone); - box-shadow: inset 2px 2px 3px rgba(0, 0, 0, 0.5); -} - -#sidebar::-webkit-scrollbar-thumb { - background: linear-gradient(180deg, var(--ac-gold) 0%, var(--ac-gold-dark) 100%); - border-radius: 2px; - border: 1px solid var(--ac-gold-dark); - box-shadow: - 1px 1px 2px rgba(0, 0, 0, 0.5), - inset 1px 1px 1px rgba(255, 255, 255, 0.3); -} - -#sidebar::-webkit-scrollbar-thumb:hover { - background: linear-gradient(180deg, var(--ac-gold-bright) 0%, var(--ac-gold) 100%); -} - -/* Map container special effects */ -#mapContainer.dragging { - cursor: move; -} - -/* Additional hover effects */ -.player-item { - position: relative; - overflow: hidden; -} - -.player-item::before { - content: ''; - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient(90deg, transparent 0%, rgba(212, 175, 55, 0.2) 50%, transparent 100%); - transition: left 0.5s; -} - -.player-item:hover::before { - left: 100%; -} \ No newline at end of file diff --git a/static/classic/style.css b/static/classic/style.css deleted file mode 100644 index 471da663..00000000 --- a/static/classic/style.css +++ /dev/null @@ -1,2890 +0,0 @@ -/* - * style.css - Core styles for Dereth Tracker Single-Page Application - * - * Defines CSS variables for theming, layout rules for sidebar and map, - * interactive element styling (buttons, inputs), and responsive considerations. - */ -/* CSS Custom Properties for theme colors and sizing */ -:root { - --sidebar-width: 400px; - --bg-main: #111; - --bg-side: #1a1a1a; - --card: #222; - --card-hov:#333; - --text: #eee; - --accent: #88f; -} -/* - * style.css - Styling for Dereth Tracker SPA frontend. - * Defines layout, theming variables, and component styles (sidebar, map, controls). - */ -/* Placeholder text in chat input should be white */ -.chat-input::placeholder { - color: #fff; - opacity: 0.7; -} - -html { - margin: 0; - height: 100%; - width: 100%; -} - -body { - margin: 0; - height: 100%; - display: flex; - overflow: hidden; - font-family: "Segoe UI", sans-serif; - background: var(--bg-main); - color: var(--text); - position: relative; -} - -.sort-buttons { - /* Container for sorting controls; uses flex layout to distribute buttons equally */ - display: flex; - gap: 2px; - margin: 12px 16px 8px; -} -.sort-buttons .btn { - /* Compact styling for sort buttons to fit 6 options */ - flex: 1; - padding: 4px 6px; - background: #333; - color: #ccc; - border: 1px solid #666; - border-radius: 3px; - text-align: center; - cursor: pointer; - user-select: none; - font-size: 0.75rem; - font-weight: 500; - transition: all 0.15s; - min-width: 0; - white-space: nowrap; - overflow: hidden; -} -.sort-buttons .btn:hover { - background: #444; - color: #fff; - border-color: #777; -} - -.sort-buttons .btn.active { - /* Active sort button highlighted with accent color */ - background: var(--accent); - color: #111; - border-color: var(--accent); - position: relative; -} - -.sort-buttons .btn.active:hover { - background: var(--accent); - color: #111; -} - -/* Sort direction indicators */ -.sort-buttons .btn.active::after { - content: ''; - position: absolute; - top: 2px; - right: 2px; - width: 0; - height: 0; - border-left: 3px solid transparent; - border-right: 3px solid transparent; -} - -/* Most sorts are descending (down arrow) */ -.sort-buttons .btn.active::after { - border-top: 4px solid #111; -} - -/* Name and KPR are ascending (up arrow) */ -.sort-buttons .btn.active[data-value="name"]::after, -.sort-buttons .btn.active[data-value="kpr"]::after { - border-top: none; - border-bottom: 4px solid #111; -} - -/* ---------- sidebar --------------------------------------------- */ -#sidebar { - width: var(--sidebar-width); - scrollbar-width: none; - background: var(--bg-side); - border-right: 2px solid #333; - box-sizing: border-box; - padding: 18px 16px; - overflow-y: auto; - display: flex; - flex-direction: column; -} -#sidebar h2 { - margin: 8px 0 12px; - font-size: 1.25rem; - color: var(--accent); -} - -.total-rares-counter { - margin: 0 0 12px 0; - padding: 8px 12px; - background: linear-gradient(135deg, #2a2a2a, #1a1a1a); - border: 1px solid #444; - border-radius: 6px; - font-size: 0.95rem; - font-weight: 600; - color: #ffd700; - text-align: center; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); -} - -.total-rares-counter #totalRaresCount { - color: #fff; - margin-left: 4px; -} - -.server-kph-counter { - margin: 0 0 12px 0; - padding: 9px 12px; - background: linear-gradient(135deg, #2a2a44, #1a1a33); - border: 2px solid #4466aa; - border-radius: 6px; - font-size: 1rem; - font-weight: 600; - color: #aaccff; - text-align: center; - box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4); - position: relative; - animation: kph-border-glow 4s ease-in-out infinite; -} - -@keyframes kph-border-glow { - 0%, 100% { border-color: #4466aa; box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4); } - 50% { border-color: #6688cc; box-shadow: 0 3px 12px rgba(102, 136, 204, 0.3); } -} - -.server-kph-counter #serverKphCount { - color: #fff; - margin-left: 4px; - font-size: 1.1rem; - font-weight: 700; - text-shadow: 0 0 8px rgba(255, 255, 255, 0.3); - animation: kph-pulse 3s ease-in-out infinite; -} - -@keyframes kph-pulse { - 0%, 100% { transform: scale(1); } - 50% { transform: scale(1.02); } -} - -/* ULTRA MODE for KPH > 5000 */ -.server-kph-counter.ultra-epic { - background: linear-gradient(135deg, #6644ff, #4422cc, #6644ff); - background-size: 200% 200%; - animation: kph-border-glow 4s ease-in-out infinite, ultra-background 3s ease-in-out infinite; - border-color: #8866ff; - color: #eeeeff; - box-shadow: 0 4px 12px rgba(102, 68, 255, 0.5); -} - -@keyframes ultra-background { - 0% { background-position: 0% 50%; } - 50% { background-position: 100% 50%; } - 100% { background-position: 0% 50%; } -} - -.server-kph-counter.ultra-epic #serverKphCount { - font-size: 1.3rem; - color: #ffffff; - text-shadow: 0 0 12px rgba(255, 255, 255, 0.7); - animation: kph-pulse 3s ease-in-out infinite, ultra-glow 2s ease-in-out infinite alternate; -} - -@keyframes ultra-glow { - from { text-shadow: 0 0 12px rgba(255, 255, 255, 0.7); } - to { text-shadow: 0 0 18px rgba(255, 255, 255, 0.9), 0 0 25px rgba(136, 102, 255, 0.5); } -} - -/* Server Status Styling */ -.server-status-container { - margin: 0 0 16px 0; - padding: 12px; - background: linear-gradient(135deg, #2a4a2a, #1a3a1a); - border: 2px solid #44aa44; - border-radius: 8px; - box-shadow: 0 3px 8px rgba(0, 0, 0, 0.4); -} - -.server-status-container h3 { - margin: 0 0 10px 0; - font-size: 1.1rem; - color: #aaffaa; - text-align: center; - font-weight: 600; -} - -.status-indicator { - display: flex; - align-items: center; - justify-content: center; - margin-bottom: 8px; - font-weight: 600; - font-size: 1rem; -} - -.status-dot { - width: 12px; - height: 12px; - border-radius: 50%; - margin-right: 8px; - box-shadow: 0 0 6px rgba(0, 0, 0, 0.3); -} - -.status-dot.status-up { - background-color: #44ff44; - box-shadow: 0 0 8px rgba(68, 255, 68, 0.6); - animation: status-pulse-up 2s ease-in-out infinite; -} - -.status-dot.status-down { - background-color: #ff4444; - box-shadow: 0 0 8px rgba(255, 68, 68, 0.6); - animation: status-pulse-down 2s ease-in-out infinite; -} - -.status-dot.status-unknown, -.status-dot.status-error { - background-color: #ffaa44; - box-shadow: 0 0 8px rgba(255, 170, 68, 0.6); -} - -@keyframes status-pulse-up { - 0%, 100% { - box-shadow: 0 0 8px rgba(68, 255, 68, 0.6); - } - 50% { - box-shadow: 0 0 16px rgba(68, 255, 68, 0.9); - } -} - -@keyframes status-pulse-down { - 0%, 100% { - box-shadow: 0 0 8px rgba(255, 68, 68, 0.6); - } - 50% { - box-shadow: 0 0 16px rgba(255, 68, 68, 0.9); - } -} - -.status-details { - font-size: 0.85rem; - color: #ccc; - line-height: 1.6; - display: grid; - grid-template-columns: 1fr 1fr; - gap: 8px 16px; -} - -.status-details div { - display: flex; - align-items: center; - white-space: nowrap; -} - -.status-details span { - color: #fff; - font-weight: 500; - margin-left: 6px; -} - -.total-kills-counter { - margin: 0 0 12px 0; - padding: 8px 12px; - background: linear-gradient(135deg, #2a2a2a, #1a1a1a); - border: 1px solid #555; - border-radius: 6px; - font-size: 0.95rem; - font-weight: 600; - color: #ff6666; - text-align: center; - box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); -} - -.total-kills-counter #totalKillsCount { - color: #fff; - margin-left: 4px; -} -#playerList { - list-style: none; - margin: 0; - padding: 0; -} -/* Filter input in sidebar for player list */ -.player-filter { - width: 100%; - padding: 6px 8px; - margin-bottom: 12px; - background: var(--card); - color: var(--text); - border: 1px solid #555; - border-radius: 4px; - font-size: 0.9rem; - box-sizing: border-box; -} -#playerList li { - margin: 4px 0; - padding: 6px 8px; - background: var(--card); - border-left: 4px solid #555; - cursor: pointer; -} -#playerList li:hover { - background: var(--card-hov); -} -#playerList li.selected { - background: #454545; -} - -/* ---------- map container --------------------------------------- */ -#mapContainer { - flex: 1; - min-width: 0; - min-height: 0; - position: relative; - overflow: hidden; - background: #000; - cursor: grab; -} -#mapContainer.dragging { - cursor: grabbing; -} -#mapGroup { - position: absolute; - top: 0; - left: 0; - transform-origin: 0 0; -} -#map { - display: block; - user-select: none; - pointer-events: none; -} - -/* ---------- dots ------------------------------------------------ */ -#dots { - position: absolute; - top: 0; - left: 0; - pointer-events: none; -} -.dot { - position: absolute; - width: 6px; - height: 6px; - border-radius: 50%; - border: 1px solid #000; - transform: translate(-50%, -50%); - - /* enable events on each dot */ - pointer-events: auto; - cursor: pointer; -} -.dot.highlight { - width: 10px; - height: 10px; - animation: blink 0.6s step-end infinite; -} -@keyframes blink { - 50% { opacity: 0; } -} - -/* ---------- tooltip --------------------------------------------- */ -.tooltip { - position: absolute; - display: none; - background: rgba(0, 0, 0, 0.8); - color: #fff; - padding: 4px 8px; - border-radius: 4px; - font-size: 0.8rem; - pointer-events: none; - white-space: nowrap; - z-index: 1000; -} - -/* ---------- coordinate display ---------------------------------- */ -.coordinates { - position: absolute; - display: none; - background: rgba(0, 50, 100, 0.9); - color: #fff; - padding: 3px 6px; - border-radius: 3px; - font-size: 0.75rem; - font-family: monospace; - pointer-events: none; - white-space: nowrap; - z-index: 999; - border: 1px solid rgba(100, 150, 200, 0.5); -} -/* make each row a flex container */ -/* 2-column flex layout for each player row */ -/* make each row a flex container */ -/* make each row a vertical stack */ -/* make each player row into a 3Γ—2 grid */ -#playerList li { - display: grid; - grid-template-columns: 1fr auto auto auto auto auto; - grid-template-rows: auto auto auto auto auto auto; - grid-template-areas: - "name name name name name name" - "vitals vitals vitals vitals vitals vitals" - "kills totalkills kph kph kph kph" - "rares kpr meta meta meta meta" - "onlinetime deaths tapers tapers tapers tapers" - "buttons buttons buttons buttons buttons buttons"; - gap: 4px 8px; - margin: 4px 0; - padding: 6px 10px; - background: var(--card); - border-left: 4px solid transparent; - transition: none; - font-size: 0.85rem; -} - -/* assign each span into its grid cell */ -.player-name { grid-area: name; font-weight: 600; color: var(--text); } -.coordinates-inline { font-size: 0.75rem; color: #aaa; font-weight: 400; margin-left: 8px; } - -.stat.kills { grid-area: kills; } -.stat.total-kills { grid-area: totalkills; } -.stat.kph { grid-area: kph; } -.stat.rares { grid-area: rares; } -.stat.kpr { grid-area: kpr; } -.stat.meta { grid-area: meta; } -.stat.onlinetime { grid-area: onlinetime; } -.stat.deaths { grid-area: deaths; } -.stat.tapers { grid-area: tapers; } - -.player-vitals { grid-area: vitals; } - -/* pill styling */ -#playerList li .stat { - background: rgba(255,255,255,0.1); - padding: 2px 6px; - border-radius: 10px; - display: inline-block; - font-size: 0.7rem; - white-space: nowrap; - color: var(--text); -} - -/* icons & suffixes */ -.stat.kills::before { content: "βš”οΈ "; } -.stat.total-kills::before { content: "πŸ† "; } -.stat.kph::after { content: " KPH"; font-size:0.7em; color:#aaa; } -.stat.rares::before { content: "πŸ’Ž "; } -.stat.rares::after { content: " Rares"; font-size:0.7em; color:#aaa; } -.stat.kpr::before { content: "πŸ“Š "; } -.stat.kpr::after { content: " KPR"; font-size:0.7em; color:#aaa; } -/* metastate pill colors are assigned dynamically: green for β€œgood” states, red otherwise */ -#playerList li .stat.meta { - /* fallback */ - background: var(--accent); - color: #111; -} - -#playerList li .stat.meta.green { - background: #2ecc71; /* pleasant green */ - color: #111; -} - -#playerList li .stat.meta.red { - background: #e74c3c; /* vivid red */ - color: #fff; -} - -/* ---------- player item buttons ------------------------------- */ -.chat-btn, .stats-btn, .inventory-btn, .char-btn, .radar-btn { - padding: 1px 5px; - border: 1px solid #666; - border-radius: 3px; - font-size: 0.65rem; - cursor: pointer; - white-space: nowrap; -} - -.chat-btn, .stats-btn, .inventory-btn { - background: var(--accent); - color: #111; - border-color: var(--accent); -} - -/* Element pooling optimization containers */ -.grid-content { - display: contents; /* Makes container invisible to CSS Grid */ -} - -.buttons-container { - grid-area: buttons; - display: flex; - gap: 3px; - flex-wrap: wrap; -} - -.chat-window, .stats-window, .inventory-window, .character-window, .radar-window, .issues-window { - position: absolute; - top: 10px; - /* position window to start just right of the sidebar */ - left: calc(var(--sidebar-width) + 10px); - /* increase default size for better usability */ - width: 760px; /* increased width for larger terminal area */ - height: 300px; - background: var(--card); - border: 1px solid #555; - display: flex; - flex-direction: column; - z-index: 10000; -} - -.window-content { - flex: 1; - display: flex; - flex-direction: column; - overflow: hidden; - min-height: 0; -} - -.chat-header { - display: flex; - justify-content: space-between; - align-items: center; - background: var(--accent); - padding: 4px; - color: #111; - cursor: move; /* indicates the header is draggable */ -} - -.chat-close-btn { - background: transparent; - border: none; - font-size: 1.2rem; - line-height: 1; - cursor: pointer; -} - -.chat-messages { - flex: 1; - overflow-y: auto; - padding: 4px; - font-size: 0.85rem; - color: #fff; - /* reserve space so messages aren't hidden behind the input */ - padding-bottom: 40px; -} - -.chat-form { - display: flex; - border-top: 1px solid #333; - /* fix input area to the bottom of the chat window */ - position: absolute; - left: 0; - right: 0; - bottom: 0; - background: #333; - z-index: 10; -} - -.chat-input { - flex: 1; - padding: 4px 6px; - border: none; - background: #333; - color: #fff; - outline: none; -} - -/* Prevent text selection while dragging chat windows */ -body.noselect, body.noselect * { - user-select: none !important; -} -.stat.onlinetime::before { content: "πŸ•‘ "} -.stat.deaths::before { content: "πŸ’€ "} -.stat.tapers::before { - content: ""; - display: inline-block; - width: 16px; - height: 16px; - background-image: url('prismatic-taper-icon.png'); - background-size: contain; - background-repeat: no-repeat; - margin-right: 4px; - vertical-align: text-bottom; -} - -/* hover & selected states */ -#playerList li:hover { background: var(--card-hov); } -#playerList li.selected { background: #454545; } -/* trails paths */ -#trails { - position: absolute; - top: 0; - left: 0; - pointer-events: none; -} - -#portals { - position: absolute; - top: 0; - left: 0; - pointer-events: none; -} - -.portal-icon { - position: absolute; - width: 6px; - height: 6px; - font-size: 6px; - line-height: 1; - transform: translate(-50%, -50%); - z-index: 50; - opacity: 0.9; - text-shadow: 0 0 2px rgba(0, 0, 0, 0.8); -} - -.portal-icon::before { - content: 'πŸŒ€'; - display: block; -} -.trail-path { - fill: none; - stroke-width: 2px; - stroke-opacity: 0.7; - stroke-linecap: round; - stroke-linejoin: round; -} -/* -------------------------------------------------------- */ -/* Stats window: 2Γ—2 iframe grid and flexible height */ -.stats-window { - /* allow height to expand to fit two rows of panels */ - height: auto; -} -.stats-window .chat-messages { - display: grid; - grid-template-columns: repeat(2, 1fr); - grid-auto-rows: auto; - gap: 10px; - padding: 10px; - overflow: visible; - background: #f7f7f7; - color: #000; -} -.stats-window iframe { - width: 350px; - height: 200px; - border: none; -} - -/* ---------- stats window time controls --------------------------- */ -.stats-controls { - display: flex; - gap: 8px; - padding: 10px 15px; - background: #333; - border-bottom: 1px solid #555; -} - -.time-range-btn { - padding: 6px 12px; - background: #444; - color: #ccc; - border: 1px solid #666; - border-radius: 4px; - font-size: 0.85rem; - cursor: pointer; - transition: all 0.2s; -} - -.time-range-btn:hover { - background: #555; - color: #fff; -} - -.time-range-btn.active { - background: var(--accent); - color: #111; - border-color: var(--accent); -} - -/* ---------- inventory window styling (AC Layout) ----------------------------- */ -.inventory-content { - flex: 1; - display: flex; - flex-direction: row; - background: none; - color: var(--ac-text); - overflow: hidden; - padding: 8px; - gap: 20px; -} - -.inv-left-column { - display: flex; - flex-direction: column; - width: 316px; - flex: none; - min-height: 0; - overflow: hidden; -} - -.inventory-placeholder { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - font-size: 1.1rem; - color: #888; - font-style: italic; -} - -/* Inventory window specific styles */ -.inventory-window { - position: fixed; - top: 100px; - left: 400px; - width: 572px; - height: 720px; - background: rgba(20, 20, 20, 0.92); - backdrop-filter: blur(2px); - border: 2px solid var(--ac-gold); - border-radius: 4px; - display: flex; - flex-direction: column; - box-shadow: inset 0 0 10px #000, 0 4px 15px rgba(0, 0, 0, 0.8); - z-index: 1000; - font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif; - overflow: hidden; -} - -.inventory-loading { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - font-size: 1.1rem; - color: var(--ac-text-dim); -} - -.inv-equipment-grid { - position: relative; - width: 308px; - height: 264px; -} - -.inv-equip-slot { - position: absolute; - width: 36px; - height: 36px; - background: var(--ac-medium-stone); - border-top: 2px solid #3d4b5f; - border-left: 2px solid #3d4b5f; - border-bottom: 2px solid #12181a; - border-right: 2px solid #12181a; - box-sizing: border-box; - display: flex; - align-items: center; - justify-content: center; -} - -.inv-equip-slot.equipped { - border: 2px solid var(--ac-cyan); - box-shadow: 0 0 5px var(--ac-cyan), inset 0 0 5px var(--ac-cyan); -} - -.inv-equip-slot.empty::before { - content: ""; - display: block; - width: 28px; - height: 28px; - background-image: url('/icons/06000133.png'); - background-size: contain; - opacity: 0.15; - filter: grayscale(100%); -} - -.inv-equip-slot .inventory-slot { - width: 100%; - height: 100%; -} - -.inv-sidebar { - width: 38px; - display: flex; - flex-direction: column; - align-items: center; - gap: 2px; - overflow: visible; - flex-shrink: 0; -} - -.inv-burden-bar { - width: 14px; - height: 40px; - background: #111; - border: 1px solid var(--ac-border-light); - position: relative; - overflow: hidden; - margin-bottom: 2px; - flex-shrink: 0; -} - -.inv-burden-fill { - width: 100%; - position: absolute; - left: 0; - right: 0; - bottom: 0; - height: 0%; - transition: height 0.3s ease, background-color 0.3s ease; -} - -.inv-burden-label { - text-align: center; - font-size: 9px; - color: #ccc; - white-space: nowrap; - margin-bottom: 2px; -} - -.inv-pack-list { - display: flex; - flex-direction: column; - gap: 2px; - width: 100%; - align-items: center; - flex: 1; - min-height: 0; - overflow: visible; -} - -.inv-pack-icon { - width: 32px; - height: 32px; - position: relative; - cursor: pointer; - border: 1px solid transparent; - display: flex; - align-items: center; - justify-content: center; - background: #000; - flex-shrink: 0; - margin-right: 0; -} - -.inv-pack-icon.active { - border: 1px solid var(--ac-green); - box-shadow: 0 0 4px var(--ac-green); -} - -.inv-pack-icon.active::before { - content: "β–Ά"; - position: absolute; - left: -14px; - top: 10px; - color: var(--ac-gold); - font-size: 12px; -} - -.inv-pack-fill-container { - position: absolute; - bottom: -6px; - left: -1px; - width: 36px; - height: 4px; - background: #000; - border: 1px solid #333; -} - -.inv-pack-fill { - height: 100%; - background: var(--ac-green); - width: 0%; -} - -.inv-pack-icon img { - width: 28px; - height: 28px; - object-fit: contain; - image-rendering: pixelated; -} - -.inv-contents-header { - color: var(--ac-gold); - font-size: 14px; - margin-bottom: 4px; - text-align: center; - border-bottom: 1px solid var(--ac-border-light); - padding-bottom: 2px; -} - -.inv-item-grid { - display: grid; - grid-template-columns: repeat(6, 36px); - grid-auto-rows: 36px; - gap: 2px; - background: var(--ac-black); - padding: 4px; - border: 1px solid var(--ac-border-light); - flex: 1; - overflow-y: auto; - min-height: 0; - align-content: start; - justify-content: start; -} - -.inv-mana-panel { - width: 162px; - min-width: 162px; - display: flex; - flex-direction: column; - background: rgba(6, 10, 18, 0.92); - border: 1px solid var(--ac-border-light); - padding: 3px; - min-height: 0; - flex-shrink: 0; - overflow: hidden; -} - -.inv-mana-header { - color: var(--ac-gold); - font-size: 14px; - text-align: center; - border-bottom: 1px solid var(--ac-border-light); - padding-bottom: 2px; -} - -.inv-mana-summary { - color: var(--ac-text-dim); - font-size: 9px; - line-height: 1.2; - padding: 2px 0; - border-bottom: 1px solid rgba(255,255,255,0.08); - margin-bottom: 3px; -} - -.inv-mana-list { - flex: 1; - min-height: 0; - overflow: hidden; - display: flex; - flex-direction: column; - gap: 2px; -} - -.inv-mana-row { - display: grid; - grid-template-columns: 18px 1fr 14px; - grid-template-rows: auto auto; - gap: 1px 4px; - align-items: center; - background: rgba(18, 24, 34, 0.9); - border: 1px solid rgba(255,255,255,0.08); - padding: 1px 2px; - min-height: 20px; -} - -.inv-mana-icon { - grid-row: 1 / span 2; - width: 16px; - height: 16px; -} - -.inv-mana-icon .inventory-slot { - width: 16px; - height: 16px; -} - -.inv-mana-icon .inventory-slot.mana-slot { - width: 16px; - height: 16px; -} - -.inv-mana-icon .inventory-slot.mana-slot .item-icon-composite { - width: 14px; - height: 14px; -} - -.inv-mana-icon .inventory-slot.mana-slot .icon-underlay, -.inv-mana-icon .inventory-slot.mana-slot .icon-base, -.inv-mana-icon .inventory-slot.mana-slot .icon-overlay { - width: 14px; - height: 14px; -} - -.inv-mana-name { - color: #f2e6c9; - font-size: 9px; - line-height: 1.05; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - grid-column: 2; - grid-row: 1; -} - -.inv-mana-value, -.inv-mana-time { - font-size: 9px; - line-height: 1.1; -} - -.inv-mana-value { - color: #98d7ff; - grid-column: 2; - grid-row: 2; -} - -.inv-mana-time { - color: #cfe6a0; - grid-column: 3; - grid-row: 2; - text-align: right; - min-width: 34px; -} - -.inv-mana-state-dot { - grid-column: 3; - grid-row: 1; - width: 10px; - height: 10px; - border-radius: 50%; - justify-self: end; - align-self: start; - background: #97a1ad; - border: 1px solid rgba(0,0,0,0.65); - box-shadow: inset 0 0 1px rgba(255,255,255,0.2); -} - -.mana-state-active { - background: #76d17f; -} - -.mana-state-not_active { - background: #ff8e6f; -} - -.mana-state-unknown { - background: #d4c27a; -} - -.mana-state-not_activatable { - background: #97a1ad; -} - -.inv-mana-empty { - color: var(--ac-text-dim); - font-size: 11px; - text-align: center; - padding: 12px 6px; -} - -.inv-item-grid::-webkit-scrollbar { - width: 12px; -} -.inv-item-grid::-webkit-scrollbar-track { - background: #0a0a0a; - border: 1px solid #333; -} -.inv-item-grid::-webkit-scrollbar-thumb { - background: #0022cc; - border-top: 2px solid var(--ac-gold); - border-bottom: 2px solid var(--ac-gold); -} - -.inv-item-slot { - width: 36px; - height: 36px; - background: #0a0a0a; - border: 1px solid #222; - box-sizing: border-box; - display: flex; - align-items: center; - justify-content: center; -} - -.inv-item-slot.occupied { - background: linear-gradient(135deg, #3d007a 0%, #1a0033 100%); - border: 1px solid #4a148c; -} - -/* Base slot styling used by createInventorySlot */ -.inventory-slot { - width: 36px; - height: 36px; - background: transparent; - border: none; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - padding: 0; - margin: 0; -} - -.inventory-slot:hover { - background: rgba(136, 136, 255, 0.3); -} - -.inventory-icon { - width: 36px; - height: 36px; - object-fit: contain; - image-rendering: pixelated; - border: none; - outline: none; -} - -/* Icon compositing */ -.item-icon-composite { - position: relative; - width: 36px; - height: 36px; - display: block; - background: transparent; - padding: 0; - margin: 0; -} - -.icon-underlay, -.icon-base, -.icon-overlay { - position: absolute; - top: 0; - left: 0; - width: 36px; - height: 36px; - border: none; - outline: none; - background: transparent; - padding: 0; - margin: 0; -} - -.icon-underlay { z-index: 1; } -.icon-base { z-index: 2; } -.icon-overlay { z-index: 3; } - -/* Item count (hidden in new AC layout, kept for compatibility) */ -.inventory-count { - display: none; -} - -/* Inventory tooltip */ -.inventory-tooltip { - position: fixed; - background: rgba(0, 0, 0, 0.95); - border: 1px solid #555; - border-radius: 4px; - padding: 10px; - pointer-events: none; - z-index: 20000; - display: none; - min-width: 200px; - max-width: 350px; - font-size: 0.9rem; -} - -.tooltip-name { - font-weight: bold; - color: var(--accent); - margin-bottom: 8px; - font-size: 1rem; -} - -.tooltip-section { - margin-bottom: 6px; -} - -.tooltip-section-title { - font-weight: bold; - color: #ffd700; - margin-bottom: 3px; - font-size: 0.85rem; - text-transform: uppercase; -} - -.tooltip-stats { - display: flex; - flex-direction: column; - gap: 3px; - font-size: 0.9rem; -} - -.tooltip-stat, -.tooltip-requirement, -.tooltip-property { - color: #ddd; - font-size: 0.85rem; - margin-left: 8px; -} - -.tooltip-requirement { - color: #ffaa00; -} - -.tooltip-property { - color: #88ff88; -} - -.tooltip-string { - color: #add8e6; - font-size: 0.8rem; - margin-left: 8px; -} - -.tooltip-spell { - color: #dda0dd; - font-size: 0.8rem; - margin-left: 8px; - margin-bottom: 2px; -} - -.spell-name { - color: #4a90e2; - font-weight: 500; -} - -.spell-school { - font-size: 11px; - color: #888; - font-style: italic; -} - -.tooltip-info { - color: #f0e68c; - font-size: 0.8rem; - margin-left: 8px; -} - -.tooltip-description { - color: #ccc; - font-style: italic; - margin-top: 8px; - padding-top: 8px; - border-top: 1px solid #444; -} - -.tooltip-value { - color: #4CAF50; -} - -.tooltip-burden { - color: #FFC107; -} - -.tooltip-source { - font-size: 10px; - color: #888; - margin-top: 4px; - text-align: center; -} - -/* ---------- inline vitals bars ---------------------------------- */ -.player-vitals { - grid-column: 1 / -1; - margin: 2px 0 4px 0; - display: flex; - flex-direction: column; - gap: 2px; -} - -.vital-bar-inline { - height: 5px; - background: #222; - border-radius: 3px; - overflow: hidden; - position: relative; -} - -.vitae-indicator { - font-size: 0.75rem; - color: #ff6666; - margin-left: 8px; - font-weight: 500; -} - -.vital-fill { - height: 100%; - transition: width 0.3s ease-out; - border-radius: 2px; -} - -.vital-fill.health { - background: linear-gradient(90deg, #ff4444, #ff6666); -} - -.vital-fill.stamina { - background: linear-gradient(90deg, #ffaa00, #ffcc44); -} - -.vital-fill.mana { - background: linear-gradient(90deg, #4488ff, #66aaff); -} - -/* Pulsing effects for low vitals */ -.vital-bar-inline.low-vital { - animation: pulse-bar-low 2s ease-in-out infinite; -} - -.vital-bar-inline.critical-vital { - animation: pulse-bar-critical 1s ease-in-out infinite; -} - -@keyframes pulse-bar-low { - 0%, 100% { background: #222; } - 50% { background: #332200; } -} - -@keyframes pulse-bar-critical { - 0%, 100% { background: #222; } - 50% { background: #440000; } -} - -/* ---------- epic rare notifications ------------------------------ */ -.rare-notifications { - position: fixed; - top: 20px; - left: 50%; - transform: translateX(-50%); - z-index: 10001; - pointer-events: none; -} - -.rare-notification { - background: linear-gradient(135deg, #ffd700, #ffed4e, #ffd700); - border: 3px solid #ff6600; - border-radius: 12px; - padding: 20px 30px; - margin-bottom: 10px; - text-align: center; - box-shadow: 0 8px 32px rgba(255, 215, 0, 0.5); - animation: notification-slide-in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55), - epic-glow 2s ease-in-out infinite; - position: relative; - overflow: hidden; -} - -@keyframes notification-slide-in { - from { - transform: translateY(-100px); - opacity: 0; - } - to { - transform: translateY(0); - opacity: 1; - } -} - -@keyframes epic-glow { - 0%, 100% { - box-shadow: 0 8px 32px rgba(255, 215, 0, 0.5); - } - 50% { - box-shadow: 0 8px 48px rgba(255, 215, 0, 0.8); - } -} - -.rare-notification-title { - font-size: 1.2rem; - font-weight: 800; - color: #ff0044; - text-transform: uppercase; - margin-bottom: 8px; - text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); - animation: epic-text-pulse 1s ease-in-out infinite; -} - -@keyframes epic-text-pulse { - 0%, 100% { transform: scale(1); } - 50% { transform: scale(1.05); } -} - -.rare-notification-mob { - font-size: 1.5rem; - font-weight: 700; - color: #1a0033; - margin-bottom: 4px; - text-shadow: 2px 2px 4px rgba(255, 255, 255, 0.5); -} - -.rare-notification-finder { - font-size: 1rem; - color: #333; - font-style: italic; - margin-bottom: 4px; -} - -.rare-notification-character { - font-size: 1.3rem; - font-weight: 700; - color: #ff0044; - text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3); -} - -/* Shine effect overlay */ -.rare-notification::before { - content: ''; - position: absolute; - top: -50%; - left: -50%; - width: 200%; - height: 200%; - background: linear-gradient(45deg, - transparent 30%, - rgba(255, 255, 255, 0.5) 50%, - transparent 70% - ); - transform: rotate(45deg); - animation: notification-shine 3s infinite; -} - -@keyframes notification-shine { - 0% { transform: translateX(-100%) translateY(-100%) rotate(45deg); } - 100% { transform: translateX(100%) translateY(100%) rotate(45deg); } -} - -/* ---------- fireworks particles ---------------------------------- */ -.fireworks-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; - z-index: 9999; -} - -.firework-particle { - position: absolute; - width: 6px; - height: 6px; - border-radius: 50%; - pointer-events: none; - animation: firework-fly 2s cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards; -} - -@keyframes firework-fly { - 0% { - transform: translate(0, 0) scale(1); - opacity: 1; - } - 100% { - opacity: 0; - } -} - -/* Different particle colors */ -.particle-gold { background: #ffd700; box-shadow: 0 0 6px #ffd700; } -.particle-red { background: #ff4444; box-shadow: 0 0 6px #ff4444; } -.particle-orange { background: #ff8800; box-shadow: 0 0 6px #ff8800; } -.particle-purple { background: #cc00ff; box-shadow: 0 0 6px #cc00ff; } -.particle-blue { background: #00ccff; box-shadow: 0 0 6px #00ccff; } - -/* Character glow effect in player list */ -.player-item.rare-finder-glow { - animation: rare-finder-highlight 5s ease-in-out; - border-left-color: #ffd700 !important; - border-left-width: 6px !important; -} - -@keyframes rare-finder-highlight { - 0%, 100% { - background: var(--card); - box-shadow: none; - } - 50% { - background: rgba(255, 215, 0, 0.2); - box-shadow: 0 0 20px rgba(255, 215, 0, 0.5); - } -} - -/* ---------- milestone celebration overlay ------------------------ */ -.milestone-overlay { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: radial-gradient(ellipse at center, rgba(255, 215, 0, 0.3), rgba(0, 0, 0, 0.8)); - z-index: 20000; - display: flex; - align-items: center; - justify-content: center; - animation: milestone-fade-in 0.5s ease-out; -} - -@keyframes milestone-fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } -} - -.milestone-content { - text-align: center; - animation: milestone-zoom 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55); -} - -@keyframes milestone-zoom { - from { - transform: scale(0); - } - to { - transform: scale(1); - } -} - -.milestone-number { - font-size: 8rem; - font-weight: 900; - color: #ffd700; - text-shadow: - 0 0 30px #ffd700, - 0 0 60px #ff6600, - 0 0 90px #ff0044, - 0 0 120px #ff0044; - margin-bottom: 20px; - animation: milestone-pulse 1s ease-in-out infinite alternate; -} - -@keyframes milestone-pulse { - from { - transform: scale(1); - text-shadow: - 0 0 30px #ffd700, - 0 0 60px #ff6600, - 0 0 90px #ff0044, - 0 0 120px #ff0044; - } - to { - transform: scale(1.1); - text-shadow: - 0 0 40px #ffd700, - 0 0 80px #ff6600, - 0 0 120px #ff0044, - 0 0 160px #ff0044; - } -} - -.milestone-text { - font-size: 3rem; - font-weight: 700; - color: #fff; - text-transform: uppercase; - letter-spacing: 0.2em; - text-shadow: 0 0 20px rgba(255, 255, 255, 0.8); - animation: milestone-text-glow 2s ease-in-out infinite; -} - -@keyframes milestone-text-glow { - 0%, 100% { - opacity: 0.8; - } - 50% { - opacity: 1; - } -} - -.milestone-subtitle { - font-size: 1.5rem; - color: #ffcc00; - margin-top: 20px; - font-style: italic; - animation: milestone-subtitle-slide 1s ease-out; -} - -@keyframes milestone-subtitle-slide { - from { - transform: translateY(50px); - opacity: 0; - } - to { - transform: translateY(0); - opacity: 1; - } -} - -/* Milestone firework burst - larger particles */ -.milestone-particle { - position: absolute; - width: 12px; - height: 12px; - border-radius: 50%; - pointer-events: none; - background: #ffd700; - box-shadow: 0 0 12px #ffd700; -} - -/* Screen shake effect */ -@keyframes screen-shake { - 0%, 100% { transform: translate(0, 0); } - 10% { transform: translate(-5px, -5px); } - 20% { transform: translate(5px, -5px); } - 30% { transform: translate(-5px, 5px); } - 40% { transform: translate(5px, 5px); } - 50% { transform: translate(-3px, -3px); } - 60% { transform: translate(3px, -3px); } - 70% { transform: translate(-3px, 3px); } - 80% { transform: translate(3px, 3px); } - 90% { transform: translate(-1px, -1px); } -} - -.screen-shake { - animation: screen-shake 0.5s ease-in-out; -} - -/* ---------- Heat Map Canvas Layer ---------- */ -#heatmapCanvas { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; - opacity: 0.85; - mix-blend-mode: screen; /* Additive blending for nice heat map effect */ -} - -/* Trails and dots use default positioning - no changes needed for layering */ - -/* Heat map toggle styling */ -.heatmap-toggle { - margin: 0 0 12px; - padding: 6px 12px; - background: var(--card); - border: 1px solid var(--accent); - border-radius: 4px; - font-size: 0.9rem; -} - -.heatmap-toggle input { - margin-right: 8px; - cursor: pointer; -} - -.heatmap-toggle label { - cursor: pointer; - user-select: none; -} - -.portal-toggle { - margin: 0 0 12px; - padding: 6px 12px; - background: var(--card); - border: 1px solid #9c4aff; - border-radius: 4px; - font-size: 0.9rem; -} - -.portal-toggle input { - margin-right: 8px; - cursor: pointer; -} - -.portal-toggle label { - cursor: pointer; - user-select: none; -} - -/* Inventory search link styling */ -.inventory-search-link { - margin: 0 0 12px; - padding: 8px 12px; - background: var(--card); - border: 1px solid #4a9eff; - border-radius: 4px; - text-align: center; -} - -.inventory-search-link a { - color: #4a9eff; - text-decoration: none; - font-size: 0.9rem; - font-weight: 500; - display: block; - cursor: pointer; - user-select: none; - transition: all 0.2s ease; -} - -.inventory-search-link a:hover { - color: #fff; - background: rgba(74, 158, 255, 0.1); - border-radius: 2px; - padding: 2px 4px; - margin: -2px -4px; -} - -.suitbuilder-link { - margin: 0 0 12px; - padding: 8px 12px; - background: var(--card); - border: 1px solid #ff6b4a; - border-radius: 4px; - text-align: center; -} - -.suitbuilder-link a { - color: #ff6b4a; - text-decoration: none; - font-size: 0.9rem; - font-weight: 500; - display: block; - cursor: pointer; - user-select: none; - transition: all 0.2s ease; -} - -.suitbuilder-link a:hover { - color: #fff; - background: rgba(255, 107, 74, 0.1); - border-radius: 2px; - padding: 2px 4px; - margin: -2px -4px; -} - -.debug-link { - margin: 0 0 12px; - padding: 8px 12px; - background: var(--card); - border: 1px solid #4aff6b; - border-radius: 4px; - text-align: center; -} - -.debug-link a { - color: #4aff6b; - text-decoration: none; - font-size: 0.9rem; - font-weight: 500; - display: block; - cursor: pointer; - user-select: none; - transition: all 0.2s ease; -} - -.debug-link a:hover { - color: #fff; - background: rgba(74, 255, 107, 0.1); - border-radius: 2px; - padding: 2px 4px; - margin: -2px -4px; -} - -.quest-status-link { - margin: 0 0 12px; - padding: 8px 12px; - background: var(--card); - border: 1px solid #ffab4a; - border-radius: 4px; - text-align: center; -} - -.quest-status-link a { - color: #ffab4a; - text-decoration: none; - font-size: 0.9rem; - font-weight: 500; - display: block; - cursor: pointer; - user-select: none; - transition: all 0.2s ease; -} - -.quest-status-link a:hover { - color: #fff; - background: rgba(255, 171, 74, 0.1); - border-radius: 2px; - padding: 2px 4px; - margin: -2px -4px; -} - -.player-dashboard-link { - margin: 0 0 12px; - padding: 8px 12px; - background: var(--card); - border: 1px solid #88f; - border-radius: 4px; - text-align: center; -} - -.player-dashboard-link a { - color: #88f; - text-decoration: none; - font-size: 0.9rem; - font-weight: 500; - display: block; - cursor: pointer; - user-select: none; - transition: all 0.2s ease; -} - -.player-dashboard-link a:hover { - color: #fff; - background: rgba(136, 136, 255, 0.1); - border-radius: 2px; - padding: 2px 4px; - margin: -2px -4px; -} - -/* Sortable column styles for inventory tables */ -.sortable { - cursor: pointer; - user-select: none; - position: relative; - padding-right: 20px \!important; -} - -.sortable:hover { - background-color: rgba(255, 255, 255, 0.1); -} - -.results-table { - width: 100%; - border-collapse: collapse; - margin-top: 10px; -} - -.results-table th, -.results-table td { - padding: 8px 12px; - border-bottom: 1px solid #333; - text-align: left; -} - -.results-table th { - background-color: #222; - font-weight: bold; - color: #eee; -} - -.results-table tr:hover { - background-color: rgba(255, 255, 255, 0.05); -} - -.text-right { - text-align: right \!important; -} - -.results-info { - margin-bottom: 10px; - color: #ccc; - font-size: 14px; -} - -/* Spell/Cantrip column styling */ -.spells-cell { - font-size: 10px; - line-height: 1.2; - max-width: 200px; - word-wrap: break-word; - vertical-align: top; -} - -.legendary-cantrip { - color: #ffd700; - font-weight: bold; -} - -.regular-spell { - color: #88ccff; -} - -/* Error Toast */ -.error-toast { - position: fixed; - bottom: 20px; - right: 20px; - background: rgba(220, 38, 38, 0.9); - color: white; - padding: 12px 20px; - border-radius: 8px; - font-size: 13px; - z-index: 99999; - animation: toastFadeIn 0.3s ease; - max-width: 400px; -} - -@keyframes toastFadeIn { - from { opacity: 0; transform: translateY(10px); } - to { opacity: 1; transform: translateY(0); } -} - -/* ============================================ - Character Window - AC Game UI Replica - ============================================ */ -/* === TreeStats-themed Character Window === */ -.character-window { - width: 740px !important; - height: auto !important; - min-height: 300px; - max-height: 90vh; -} -.character-window .window-content { - background-color: #000022; - color: #fff; - font: 14px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; - overflow-y: auto; - padding: 10px 15px 15px; -} - -/* -- Character header (name, level, title, server, XP/Lum) -- */ -.ts-character-header { - margin-bottom: 10px; -} -.ts-character-header h1 { - margin: 0 0 2px; - font-size: 28px; - color: #fff; - font-weight: bold; -} -.ts-character-header h1 span.ts-level { - font-size: 200%; - color: #fff27f; - float: right; -} -.ts-character-header .ts-subtitle { - font-size: 85%; - color: gold; -} -.ts-xplum { - font-size: 85%; - margin: 6px 0 10px; - display: grid; - grid-template-columns: 1fr 1fr; - gap: 0 20px; -} -.ts-xplum .ts-left { text-align: left; } -.ts-xplum .ts-right { text-align: right; } - -/* -- Tab containers (two side-by-side) -- */ -.ts-tabrow { - display: flex; - gap: 13px; - flex-wrap: wrap; -} -.ts-tabcontainer { - width: 320px; - margin-bottom: 15px; -} -.ts-tabbar { - height: 30px; - display: flex; -} -.ts-tab { - float: left; - display: block; - padding: 5px 5px; - height: 18px; - font-size: 12px; - font-weight: bold; - color: #fff; - text-align: center; - cursor: pointer; - user-select: none; -} -.ts-tab.active { - border-top: 2px solid #af7a30; - border-right: 2px solid #af7a30; - border-left: 2px solid #af7a30; - border-bottom: none; - background-color: rgba(0, 100, 0, 0.4); -} -.ts-tab.inactive { - border-top: 2px solid #000022; - border-right: 2px solid #000022; - border-left: 2px solid #000022; - border-bottom: none; -} -.ts-box { - background-color: black; - color: #fff; - border: 2px solid #af7a30; - max-height: 400px; - overflow-x: hidden; - overflow-y: auto; -} -.ts-box.active { display: block; } -.ts-box.inactive { display: none; } - -/* -- Tables inside boxes -- */ -table.ts-char { - width: 100%; - font-size: 13px; - border-collapse: collapse; - border-spacing: 0; -} -table.ts-char td { - padding: 2px 6px; - white-space: nowrap; -} -table.ts-char tr.ts-colnames td { - background-color: #222; - font-weight: bold; - font-size: 12px; -} - -/* Attribute cells */ -table.ts-char td.ts-headerleft { - background-color: rgba(0, 100, 0, 0.4); -} -table.ts-char td.ts-headerright { - background-color: rgba(0, 0, 100, 0.4); -} -table.ts-char td.ts-creation { - color: #ccc; -} - -/* Skill rows */ -table.ts-char td.ts-specialized { - background: linear-gradient(to right, #392067, #392067, black); -} -table.ts-char td.ts-trained { - background: linear-gradient(to right, #0f3c3e, #0f3c3e, black); -} - -/* Section headers inside boxes */ -.ts-box .ts-section-title { - background-color: #222; - padding: 4px 8px; - font-weight: bold; - font-size: 13px; - border-bottom: 1px solid #af7a30; -} - -/* Titles list */ -.ts-titles-list { - padding: 6px 10px; - font-size: 13px; -} -.ts-titles-list div { - padding: 1px 0; -} - -/* Properties (augmentations, ratings, other) */ -table.ts-props { - width: 100%; - font-size: 13px; - border-collapse: collapse; -} -table.ts-props td { - padding: 2px 6px; -} -table.ts-props tr.ts-colnames td { - background-color: #222; - font-weight: bold; -} - -/* -- Live vitals bars (inside Attributes tab) -- */ -.ts-vitals { - padding: 6px 8px; - display: flex; - flex-direction: column; - gap: 8px; - border-bottom: 2px solid #af7a30; -} -.ts-vital { - display: flex; - align-items: center; - gap: 6px; -} -.ts-vital-label { - width: 55px; - font-size: 12px; - color: #ccc; -} -.ts-vital-bar { - flex: 1; - height: 14px; - overflow: hidden; - position: relative; - border: 1px solid #af7a30; -} -.ts-vital-fill { - height: 100%; - transition: width 0.5s ease; -} -.ts-health-bar .ts-vital-fill { background: #cc3333; width: 0%; } -.ts-stamina-bar .ts-vital-fill { background: #ccaa33; width: 0%; } -.ts-mana-bar .ts-vital-fill { background: #3366cc; width: 0%; } -.ts-vital-text { - width: 80px; - text-align: right; - font-size: 12px; - color: #ccc; -} - -/* -- Allegiance section (below tabs) -- */ -.ts-allegiance-section { - margin-top: 5px; - border: 2px solid #af7a30; - background-color: black; - padding: 0; -} -.ts-allegiance-section .ts-section-title { - background-color: #222; - padding: 4px 8px; - font-weight: bold; - font-size: 13px; - border-bottom: 1px solid #af7a30; -} -table.ts-allegiance { - width: 100%; - font-size: 13px; - border-collapse: collapse; -} -table.ts-allegiance td { - padding: 2px 6px; -} -table.ts-allegiance td:first-child { - color: #ccc; - width: 100px; -} - -/* Awaiting data placeholder */ -.ts-placeholder { - color: #666; - font-style: italic; - padding: 10px; - text-align: center; -} - -/* Scrollbar styling for ts-box */ -.ts-box::-webkit-scrollbar { width: 8px; } -.ts-box::-webkit-scrollbar-track { background: #000; } -.ts-box::-webkit-scrollbar-thumb { background: #af7a30; } - -.char-btn { - background: #000022; - color: #af7a30; - border-color: #af7a30; -} -.char-btn:hover { - background: rgba(0, 100, 0, 0.4); -} - - -/* ============================================== - Inventory Window Visual Fixes - AC Game Match - ============================================== */ - -.inventory-window, -.inventory-window * { - font-family: "Times New Roman", Times, serif !important; - text-shadow: 1px 1px 0 #000 !important; -} - -.inventory-window .chat-header { - background: #0e0c08 !important; - border-bottom: 1px solid #8a7a44 !important; - color: #d4af37 !important; - padding: 4px 6px !important; - box-shadow: none !important; - font-size: 11px !important; - font-weight: bold !important; - height: 22px !important; - box-sizing: border-box !important; - display: flex !important; - align-items: center !important; -} - -.inventory-window .window-content { - background: linear-gradient(180deg, #1a1814 0%, #0e0c0a 100%) !important; - border: 2px solid #8a7a44 !important; - padding: 4px !important; -} - -.inv-equipment-grid { - background: - radial-gradient(ellipse at 20% 50%, rgba(30, 28, 25, 0.6) 0%, transparent 70%), - radial-gradient(ellipse at 80% 30%, rgba(25, 23, 20, 0.4) 0%, transparent 60%), - radial-gradient(ellipse at 50% 80%, rgba(35, 30, 25, 0.5) 0%, transparent 50%), - linear-gradient(180deg, #0e0c0a 0%, #141210 50%, #0c0a08 100%) !important; -} - -.inv-equip-slot { - width: 36px !important; - height: 36px !important; - border-top: 1px solid #2a2a30 !important; - border-left: 1px solid #2a2a30 !important; - border-bottom: 1px solid #0a0a0e !important; - border-right: 1px solid #0a0a0e !important; - background: #14141a !important; -} - -.inv-equip-slot.equipped { - border: 1px solid #222 !important; - background: #14141a !important; - box-shadow: none !important; -} - -/* Equipment slot color categories - matching real AC - Real AC uses clearly visible colored borders AND tinted backgrounds per slot type */ -.inv-equip-slot.slot-purple { - border: 1px solid #8040a8 !important; - background: #2a1538 !important; -} -.inv-equip-slot.slot-blue { - border: 1px solid #3060b0 !important; - background: #141e38 !important; -} -.inv-equip-slot.slot-teal { - border: 1px solid #309898 !important; - background: #0e2828 !important; -} -.inv-equip-slot.slot-darkblue { - border: 1px solid #1e3060 !important; - background: #0e1428 !important; -} -/* Brighter tint when equipped (item present) */ -.inv-equip-slot.equipped.slot-purple { - border: 1px solid #9050b8 !important; - background: #341a44 !important; -} -.inv-equip-slot.equipped.slot-blue { - border: 1px solid #4070c0 !important; - background: #1a2844 !important; -} -.inv-equip-slot.equipped.slot-teal { - border: 1px solid #40a8a8 !important; - background: #143030 !important; -} -.inv-equip-slot.equipped.slot-darkblue { - border: 1px solid #283870 !important; - background: #141a30 !important; -} - -.inv-equip-slot.empty::before { - opacity: 0.15 !important; - filter: grayscale(100%) !important; -} - -.inv-item-grid { - background: #1a1208 !important; - gap: 2px !important; -} - -.inv-item-slot.occupied { - background: #442c1e !important; - border: 1px solid #5a3c28 !important; -} - -.inv-item-slot { - background: #2a1c14 !important; - border: 1px solid #3a2818 !important; -} - -.inv-contents-header { - font-size: 10px !important; - font-family: "Times New Roman", Times, serif !important; - color: #ffffff !important; - border-bottom: none !important; - text-align: center !important; - padding-bottom: 2px !important; - margin-bottom: 2px !important; - text-transform: none !important; - letter-spacing: 0 !important; -} - -.inventory-content { - gap: 13px !important; -} - -.inv-left-column { - width: 316px !important; - flex: none !important; -} - -.inv-sidebar { - width: 38px !important; - align-items: center !important; -} - -.inv-pack-icon { - width: 32px !important; - height: 32px !important; - border: 1px solid #1a1a1a !important; - margin-bottom: 2px !important; - overflow: visible !important; - margin-right: 8px !important; -} - -.inv-pack-icon img { - width: 28px !important; - height: 28px !important; -} - -.inv-pack-icon.active { - border: 1px solid #8a7a44 !important; - position: relative !important; - box-shadow: none !important; -} - -.inv-pack-icon.active::before { - content: '' !important; - position: absolute !important; - left: -8px !important; - top: 50% !important; - transform: translateY(-50%) !important; - width: 0 !important; - height: 0 !important; - border-top: 6px solid transparent !important; - border-bottom: 6px solid transparent !important; - border-left: 7px solid #d4af37 !important; - display: block !important; -} - -.inv-pack-fill-container { - position: absolute !important; - right: -6px !important; - top: 0 !important; - bottom: auto !important; - left: auto !important; - width: 4px !important; - height: 32px !important; - background: #000 !important; - border: 1px solid #333 !important; - display: flex !important; - flex-direction: column-reverse !important; -} - -.inv-pack-fill { - width: 100% !important; - background: #00ff00 !important; - transition: height 0.3s ease !important; -} - -.inv-item-grid::-webkit-scrollbar { - width: 14px; -} -.inv-item-grid::-webkit-scrollbar-track { - background: #0e0a04; - border: 1px solid #8a7a44; -} -.inv-item-grid::-webkit-scrollbar-thumb { - background: linear-gradient(180deg, #2244aa 0%, #1a3399 50%, #2244aa 100%); - border: 1px solid #8a7a44; -} -.inv-item-grid::-webkit-scrollbar-button:vertical:start:decrement, -.inv-item-grid::-webkit-scrollbar-button:vertical:end:increment { - background: #8a2020; - border: 1px solid #b89a30; - height: 14px; - display: block; -} - - - -.inventory-count { - display: block !important; - position: absolute; - top: 1px; - right: 1px; - bottom: auto; - left: auto; - font-size: 8px !important; - color: #fff !important; - background: #1a3399 !important; - padding: 0 2px !important; - line-height: 12px !important; - min-width: 8px !important; - text-align: center !important; - pointer-events: none; - z-index: 10; - text-shadow: none !important; -} - -.inventory-window { - border: 2px solid #8a7a44 !important; - background: #0e0c08 !important; - resize: none !important; - width: 572px !important; - min-height: 720px !important; -} - -.inv-mana-panel { - width: 162px !important; - min-width: 162px !important; - background: #111014 !important; - border: 1px solid #5a4a24 !important; - overflow: hidden !important; -} - -.inv-mana-header { - font-size: 10px !important; - color: #ffffff !important; - border-bottom: none !important; - padding-bottom: 2px !important; -} - -.inv-mana-summary { - font-size: 9px !important; - color: #d4af37 !important; -} - -.inv-mana-row { - grid-template-columns: 18px 1fr 14px !important; - grid-template-rows: auto auto !important; - gap: 1px 4px !important; - padding: 1px 2px !important; - background: #1a1208 !important; - border: 1px solid #3a2818 !important; -} - -.inv-mana-icon { - grid-row: 1 / span 2 !important; - width: 16px !important; - height: 16px !important; -} - -.inv-mana-icon .inventory-slot { - width: 16px !important; - height: 16px !important; -} - -.inv-mana-icon .inventory-slot.mana-slot .item-icon-composite, -.inv-mana-icon .inventory-slot.mana-slot .icon-underlay, -.inv-mana-icon .inventory-slot.mana-slot .icon-base, -.inv-mana-icon .inventory-slot.mana-slot .icon-overlay { - width: 14px !important; - height: 14px !important; -} - -.inv-mana-name { - font-size: 9px !important; - line-height: 1.05 !important; - white-space: nowrap !important; - overflow: hidden !important; - text-overflow: ellipsis !important; -} - -.inv-mana-value, -.inv-mana-time { - font-size: 9px !important; -} - -.inv-mana-state-dot { - width: 10px !important; - height: 10px !important; -} - -/* Custom resize grip for inventory window */ -.inv-resize-grip { - position: absolute; - bottom: 0; - left: 0; - right: 0; - height: 6px; - cursor: ns-resize; - z-index: 100; - background: transparent; - border-top: 1px solid #8a7a44; -} - -.inv-resize-grip::after { - content: ''; - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); - width: 30px; - height: 2px; - border-top: 1px solid #5a4a24; - border-bottom: 1px solid #5a4a24; -} - -/* ─── Radar Window ─── */ - -.radar-window { - width: 360px; - height: 560px; -} - -.radar-window .window-content { - display: flex; - flex-direction: column; - overflow: hidden; -} - -.radar-controls { - display: flex; - align-items: center; - gap: 12px; - padding: 4px 8px; - background: #1a1a1a; - border-bottom: 1px solid #333; - font-size: 0.8rem; -} - -.radar-controls label { - display: flex; - align-items: center; - gap: 4px; - color: #ccc; -} - -.radar-range-display { - color: #aaa; - font-size: 0.75rem; -} - -.radar-zoom-hint { - color: #555; - font-size: 0.7rem; - font-style: italic; -} - -.radar-canvas { - display: block; - margin: 0 auto; - border-bottom: 1px solid #333; - flex-shrink: 0; -} - -.radar-entity-list { - flex: 1; - overflow-y: auto; - font-size: 0.75rem; - min-height: 0; -} - -.radar-entity-header, -.radar-entity-row { - display: flex; - align-items: center; - padding: 2px 6px; - gap: 4px; -} - -.radar-entity-header { - background: #1a1a1a; - color: #888; - font-weight: bold; - border-bottom: 1px solid #333; - position: sticky; - top: 0; -} - -.radar-entity-row { - border-bottom: 1px solid #222; -} - -.radar-entity-row:hover { - background: #1a1a2a; - cursor: pointer; -} - -.radar-entity-selected { - background: #1a2a3a; - border-left: 2px solid #4488ff; -} - -.radar-entity-selected:hover { - background: #1a2a3a; -} - -.re-color { - width: 8px; - height: 8px; - border-radius: 50%; - flex-shrink: 0; - display: inline-block; -} - -.re-name { - flex: 1; - min-width: 0; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - color: #ddd; -} - -.re-type { - width: 60px; - flex-shrink: 0; - color: #888; -} - -.re-dist { - width: 45px; - flex-shrink: 0; - text-align: right; - color: #aaa; -} - -.re-dir { - width: 24px; - flex-shrink: 0; - text-align: center; - color: #888; -} - -.radar-btn { - background: #553388; - color: #fff; - border-color: #774499; -} - -.radar-btn:hover { - background: #664499; -} - -/* ─── Issues Board ─── */ - -.issues-window { - width: 540px; - height: 520px; -} - -.issues-window .window-content { - display: flex; - flex-direction: column; - overflow: hidden; -} - -.issues-list { - flex: 1; - overflow-y: auto; - min-height: 0; - padding: 4px; -} - -.issue-row { - padding: 6px 8px; - border-bottom: 1px solid #333; - border-left: 3px solid transparent; - color: #ddd; -} - -.issue-row:hover { - background: #1a1a2a; -} - -.issue-header { - display: flex; - align-items: center; - gap: 6px; -} - -.issue-author { - color: #8a8a6a; - font-size: 0.65rem; - font-style: italic; -} - -.issue-row .issue-description { - color: #aaa; - font-size: 0.75rem; - margin-top: 2px; - padding-left: 4px; -} - -.issue-row.issue-resolved { - background: rgba(74, 170, 74, 0.12); - border-left-color: #4a4; -} - -.issue-row.issue-resolved strong { - text-decoration: line-through; - color: #888; -} - -.issue-row.issue-resolved .issue-description { - color: #666; -} - -.issue-category { - display: inline-block; - padding: 1px 6px; - border-radius: 3px; - color: #fff; - font-size: 0.65rem; - font-weight: bold; - text-transform: uppercase; -} - -.issue-actions { - display: flex; - gap: 4px; - margin-top: 4px; -} - -.issue-resolve-btn, -.issue-reopen-btn, -.issue-delete-btn, -.issue-edit-btn { - padding: 1px 6px; - font-size: 0.65rem; - background: transparent; - cursor: pointer; - border-radius: 3px; -} - -.issue-resolve-btn { - color: #4a4; - border: 1px solid #4a4; -} - -.issue-resolve-btn:hover { - background: #4a4; - color: #fff; -} - -.issue-reopen-btn { - color: #88a; - border: 1px solid #88a; -} - -.issue-reopen-btn:hover { - background: #88a; - color: #fff; -} - -.issue-delete-btn { - color: #c44; - border: 1px solid #c44; -} - -.issue-delete-btn:hover { - background: #c44; - color: #fff; -} - -.issue-edit-btn { - color: #ca4; - border: 1px solid #ca4; -} - -.issue-edit-btn:hover { - background: #ca4; - color: #fff; -} - -.issues-form { - padding: 6px 8px; - border-top: 1px solid #444; - background: #1a1a1a; -} - -/* Edit form */ -.issue-edit-form { - margin-top: 6px; - padding: 6px; - background: #1a1a2a; - border: 1px solid #444; - border-radius: 3px; -} - -/* Comments section */ -.issue-comments-section { - margin-top: 6px; - padding: 6px; - background: #151520; - border: 1px solid #333; - border-radius: 3px; -} - -.issue-comments-list { - max-height: 120px; - overflow-y: auto; - margin-bottom: 4px; -} - -.issue-comment { - padding: 3px 0; - border-bottom: 1px solid #2a2a2a; -} - -.issue-comment:last-child { - border-bottom: none; -} - -.comment-author { - color: #8a8a6a; - font-size: 0.7rem; - font-weight: bold; -} - -.comment-date { - color: #555; - font-size: 0.6rem; -} - -.comment-text { - color: #bbb; - font-size: 0.75rem; - padding-left: 4px; - margin-top: 1px; -} - -.issue-comment-form { - margin-top: 4px; -} - -/* ---------- User info section (sidebar bottom) ---------- */ -.user-info { - margin-top: auto; - padding: 10px 0 0; - border-top: 1px solid #333; - display: flex; - align-items: center; - gap: 8px; - font-size: 0.75rem; - flex-shrink: 0; -} - -.user-info-name { - color: #d4af37; - font-weight: bold; -} - -.user-info-admin { - color: #8a7a44; - text-decoration: none; - font-size: 0.7rem; -} - -.user-info-admin:hover { - color: #d4af37; -} - -.user-info-logout { - margin-left: auto; - color: #888; - text-decoration: none; - font-size: 0.7rem; -} - -.user-info-logout:hover { - color: #ff6b6b; -} - -/* ---------- Combat Stats window ---------- */ -.combat-stats-toggle { - padding: 2px 10px; - font-size: 0.75rem; - background: #2a2a2a; - color: #aaa; - border: 1px solid #555; - cursor: pointer; - border-radius: 3px; -} -.combat-stats-toggle.active { - background: #3a5070; - color: #fff; - border-color: #5588bb; -} diff --git a/static/dereth_highres.png b/static/dereth_highres.png deleted file mode 100644 index a3495056..00000000 Binary files a/static/dereth_highres.png and /dev/null differ diff --git a/static/dungeon_tiles.json b/static/dungeon_tiles.json deleted file mode 100644 index cd820967..00000000 --- a/static/dungeon_tiles.json +++ /dev/null @@ -1 +0,0 @@ -{"2":"data:image/bmp;base64,Qk14AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEIBAADDDgAAww4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAAAAA==","12":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","19":"data:image/bmp;base64,Qk14AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEIBAAASCwAAEgsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwB/PwB/PwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Afz8Afz8Afz8Afz8Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f38/AH8/AH8/AH8/AH8/AH8/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAAAAA==","58":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","68":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","70":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABCSURBVChTfYyxEQAwCALZ3NEymikSuKjR4gvgFYB5wNYh9+MY+rfokDjJ3BWyQLiF8EPieVsFwn2USBF1fWnFDphvsrDDe/g19dwAAAAASUVORK5CYII=","72":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAH8/AAC/fwAA/79/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEDAwAAAAACAgEBAQICAwAAAAACAgIBAgICAwAAAAMDAQICAgICAwAAAAICAQICAgICAwAAAAICAgICAgICAwAAAAMDAgICAgICAwAAAAADAgICAgICAwAAAAADAwMDAwMDAwAAAAAAAAAAAAAAAAAAAA==","74":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAH8/AAC/fwAA/79/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAgEBAQEBAgIAAAADAgIBAQECAgEAAAADAgICAQICAgEAAAADAgICAgICAQEAAAADAgICAgIBAQEAAAADAgICAgICAQEAAAADAgICAgICAwAAAAADAgICAgICAwAAAAADAwMDAwMDAwAAAAAAAAAAAAAAAAAAAA==","76":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwD/v39/PwB/AAAAAH8AAP+/f79/AL9/AL9/AL9/AP+/f38/AH8/AH8AAAAAfwAA/79/v38Av38Av38A/79/fz8Afz8Av38AfwAAAAB/AAD/v3+/fwC/fwD/v39/PwB/PwC/fwC/fwB/AAAAAH8AAP+/f/+/f/+/f38/AH8/AL9/AL9/AL9/AH8AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","78":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAH8/AAC/fwAA/79/AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAgICAgICAwAAAAADAgICAgICAwAAAAADAgICAgICAwAAAAADAgICAgICAwAAAAADAgICAgICAwAAAAABAgICAgICAwAAAAACAQICAgICAwAAAAACAgECAgICAwAAAAAAAAAAAwMDAwAAAAQEBAQEAAAAAAAAAA==","81":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","82":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f38/AH8/AH8/AH8/AH8/AH8/AP+/f38AAAAAfwAA/79/fz8Afz8Afz8Afz8Afz8Afz8A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","83":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","84":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgAAAAEBAQEBAQEBAgAAAAEBAQEBAQEBAgAAAAICAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAgICAgICAgAAAAAAAAAAAAAAAAAAAA==","86":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","87":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgAAAAEBAQEBAQEBAgAAAAEBAQEBAQEBAgAAAAICAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAgIBAQICAgAAAAAAAAIBAQIAAAAAAA==","88":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgAAAAEBAQEBAQEBAgAAAAEBAQEBAQEBAgAAAAICAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAgIBAQICAgAAAAAAAAIBAQIAAAAAAA==","89":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","92":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3//v3+/fwC/fwC/fwC/fwD/v3//v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","94":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgIAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAgIAAAACAQEBAQEBAgAAAAACAgIBAQICAgAAAAAAAAIBAQIAAAAAAA==","95":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIBAQIAAAAAAAACAgIBAQICAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgIAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAgIAAAACAQEBAQEBAgAAAAACAgIBAQICAgAAAAAAAAIBAQIAAAAAAA==","96":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIBAQIAAAAAAAACAgIBAQICAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgIAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAgIAAAACAQEBAQEBAgAAAAACAgIBAQICAgAAAAAAAAIBAQIAAAAAAA==","97":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIBAQIAAAAAAAACAgIBAQICAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgIAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAgIAAAACAQEBAQEBAgAAAAACAgIBAQICAgAAAAAAAAIBAQIAAAAAAA==","101":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAA=","103":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABBSURBVChTlY1BCgAgCAT9uU/zaUak5coWdBhxGEERNd+I8n05CIKtyIsYPE7Oh5B+kGQDYXwdLkhkNEGwFbliPgC4OtDpPRgaQAAAAABJRU5ErkJggg==","105":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAv38Av38Av38Afz8Afz8Afz8Afz8Av38Av38Av38AAAC/fwC/fwC/fwB/PwB/PwB/PwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfz8Afz8Av38Av38Av38Av38Av38Av38Av38Av38AAAB/PwB/PwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8/AH8/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfz8Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAA=","108":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwB/PwB/PwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AH8/AH8/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Afz8Afz8Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwB/PwB/PwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AH8/AH8/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Afz8Afz8Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwB/PwB/PwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AH8/AH8/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAA=","112":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","116":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAA/79/v38Afz8Afz8Afz8Afz8Av38Av38Av38AAAB/AAD/v3+/fwB/PwB/PwB/PwB/PwC/fwC/fwC/fwAAAH8AAP+/f79/AH8/AH8/AH8/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Afz8Afz8AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwB/PwB/PwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AH8/AH8/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Afz8AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","118":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAH8/AAC/fwAA/79/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAgICAgICAgIAAAADAgICAgICAgIAAAADAgICAgICAgIAAAMDAgICAgICAgIAAAICAgICAgICAgIAAAICAgICAgICAgIAAAMDAgICAgICAgIAAAADAgIBAgICAgIAAAADAwMBAQMDAwMAAAAAAAAAAAAAAAAAAA==","122":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAB/AAD/v3//v3//v3+/fwC/fwD/v3//v3//v3//v38AAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwAAAH8AAH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAA=","125":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAASCwAAEgsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f/+/fwAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","128":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA7SURBVChTY2BgqP+Pguv3QzC6OIokPkwDhdgEsWEkBqYkMgYrIMZ6DEW4NKFIwNjYFKNIYtMExvv/AwCiqM6sVI0OwwAAAABJRU5ErkJggg==","130":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAH8/AAC/fwAA/79/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAgEBAQECAgIAAAADAgIBAQECAgIAAAADAgICAQICAgIAAAADAgICAgICAQEAAAADAgICAgIBAQEAAAADAgICAgICAQEAAAADAgICAgICAgEAAAADAgICAgICAgIAAAADAwMCAgMDAwMAAAAAAAMCAgMAAAAAAA==","136":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAAfz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8AAAB/AAB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwAAAH8AAH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f/+/fwAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","138":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f/+/fwAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","148":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","150":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAA/79/v38Afz8Afz8Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwB/PwB/PwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AH8/AH8/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Afz8Afz8Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwB/PwB/PwC/fwC/fwC/fwC/fwC/fwAAAH8AAH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AAAAfwAAfz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8AAAB/AAD/v3+/fwB/PwB/PwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f38/AH8/AP+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","152":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAH8/AAC/fwAA/79/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAgICAgICAgIAAAADAgICAgICAgIAAAADAgICAgICAgIAAAABAgICAgICAgIAAAABAQICAgICAgIAAAABAQICAgICAgIAAAABAgICAgICAgIAAAADAgICAgICAgIAAAADAwMDAwMDAwMAAAAAAAAAAAAAAAAAAA==","154":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAA/79/v38Afz8Afz8Afz8Afz8Av38Av38Av38AAAB/AAD/v3+/fwB/PwB/PwB/PwB/PwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AH8/AH8/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Afz8Afz8AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwB/PwB/PwB/PwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AH8/AH8/AH8/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Afz8Afz8AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","156":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA+SURBVChTY2BgqP+Pguv3QzC6OIokTAEyDRdHFwALYtGMVSEyBisipBBZjigTwTQhhSAMUkOUQhCmssL9/wGJe8xv27gQiAAAAABJRU5ErkJggg==","158":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v3//v38AAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAH8/AP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAAfz8Afz8A/79/v38Av38Av38Av38Av38Av38AAAB/AAC/fwB/PwB/PwD/v3+/fwC/fwC/fwC/fwC/fwAAAH8AAL9/AL9/AH8/AH8/AP+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","161":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAv38Av38Av38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAv38Av38Av38Av38Av38Av38Av38Av38A/79/fwAAAAB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/AAAAAH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8AAAAAv38Av38Av38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","163":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAD/v3//v3//v3//v3//v3//v3//v3//v3//v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8AfwAAAAB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAv38Av38Av38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAv38Av38Av38Av38Av38Av38Av38Av38A/79/fwAAAAA=","165":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAA=","166":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgAAAAEBAQEBAQEBAgAAAAEBAQEBAQEBAgAAAAICAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAA==","169":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAH8/AAC/fwAA/79/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAgEBAQEBAgAAAAADAgIBAQECAgAAAAADAgICAQICAgAAAAMDAgICAgICAQEAAAICAgICAgIBAQEAAAICAgICAgICAQEAAAMDAgICAgICAwAAAAADAgICAgICAwAAAAADAgICAgICAwAAAAADAgICAgICAwAAAA==","171":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAH8/AAC/fwAA/79/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAgICAgICAwAAAAADAgICAgICAwAAAAADAgICAgICAwAAAAMDAgICAgICAwAAAAICAgICAgICAQEAAAICAgICAgIBAQEAAAMDAgICAgIBAQAAAAADAgICAQICAgAAAAADAgIBAQECAgAAAAADAgEBAQEBAgAAAA==","174":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgAAAAEBAQEBAQEBAgAAAAEBAQEBAQEBAgAAAAICAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAA==","175":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQAAAAABAgAAAAACAQAAAAABAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgAAAAEBAQEBAQEBAgAAAAEBAQEBAQEBAgAAAAICAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQAAAAABAgAAAAACAQABAQABAgAAAA==","178":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAA=","179":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgIAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAgIAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAA==","185":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgIAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAgIAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAA==","186":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQAAAAABAgAAAAACAQAAAAABAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgIAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAgIAAAACAQEBAQEBAgAAAAACAQAAAAABAgAAAAACAQABAQABAgAAAA==","189":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAA=","190":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAA==","191":"data:image/bmp;base64,Qk14AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEIBAAASCwAAEgsAAAAAAAAAAAAAv38Av38A/79/fwAAfwAAfwAAfwAA/79/v38Av38AAAC/fwC/fwD/v3//v3//v3//v3//v3//v3+/fwC/fwAAAP+/f/+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f/+/fwAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAD/v3//v3+/fwC/fwC/fwC/fwC/fwC/fwD/v3//v38AAL9/AL9/AP+/f/+/f/+/f/+/f/+/f/+/f79/AL9/AAAAv38Av38A/79/fwAAfwAAfwAAfwAA/79/v38Av38AAAAAAA==","193":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAH8/AAC/fwAA/79/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAECAQEBAQECAwAAAAECAgEBAQICAwAAAAECAgIBAgICAwAAAAMBAgICAgICAwAAAAICAQICAgICAwAAAAICAgICAgICAwAAAAMDAgICAgICAwAAAAADAgICAgICAwAAAAADAgICAgICAwAAAAADAgICAgICAwAAAA==","195":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAH8/AAC/fwAA/79/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAgEBAQEBAgEAAAADAgIBAQECAgEAAAADAgICAQICAgEAAAADAgICAgICAQEAAAADAgICAgIBAQEAAAADAgICAgICAQEAAAADAgICAgICAwAAAAADAgICAgICAwAAAAADAgICAgICAwAAAAADAgICAgICAwAAAA==","198":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAD/v3//v3//v3//v3//v3//v3//v3//v3//v3//v38AAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8AAAB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwAAAH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AAAAfz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","200":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAAfz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8AfwAAAAB/AAB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/AAAAAH8AAH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8AAAAAfwAAfz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8AfwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAA=","203":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAA=","207":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAwSURBVChTY2BgqP/PUL+fMB4ghSA1WCWQMcwgDAlkjGwbCgcXBltNVYUgTJzC/f8B+7XWIgqQc5AAAAAASUVORK5CYII=","209":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAv38Av38Av38Afz8Afz8Afz8Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwB/PwB/PwB/PwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AH8/AH8/AH8/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Afz8Afz8Afz8Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwB/PwB/PwB/PwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AH8/AH8/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Afz8AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAP+/f/+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f/+/fwAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","212":"data:image/bmp;base64,Qk14AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEIBAAASCwAAEgsAAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAP///////////////////////////////////////wAA/79//79//79//79//79//79//79//79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79//79//79//79//79//79//79//79/AAD///////////////////////////////////////8AAP///////////////////////////////////////wAA////////////////////////////////////////AAAAAA==","213":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAA/79/v38Afz8Afz8Afz8Afz8Av38Av38Av38AAAB/AAD/v3+/fwB/PwB/PwB/PwB/PwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AH8/AH8/AH8/AH8/AL9/AL9/AL9/AAAAfwAA/79/v38Afz8Afz8Afz8Afz8Av38Av38Av38AAAA=","216":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAA=","218":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABESURBVChTfYxRDgAwBEPd3NEczZJZBcPHS9r0QUSsxGJM+fY6RkZxo72OYPdSBYAtlQ4X7e0vAOyrFEmiXz9WscssegBlFclzwf+xywAAAABJRU5ErkJggg==","220":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfz8Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAB/PwB/PwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8/AH8/AH8/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Afz8Afz8Afz8Av38Av38Av38Av38Av38Av38AAAC/fwC/fwB/PwB/PwB/PwC/fwC/fwC/fwC/fwC/fwAAAP+/f/+/f/+/f38/AH8/AH8/AP+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfz8Afz8Afz8AfwAAfwAAfwAAAAA=","222":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAv38Av38Av38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfz8A/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/PwB/PwD/v3+/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8/AH8/AH8/AP+/f79/AL9/AL9/AL9/AP+/f38AAAAA/79/fz8Afz8Afz8A/79/v38Av38Av38A/79/fwAAAAC/fwD/v39/PwB/PwB/PwD/v3+/fwC/fwD/v39/AAAAAL9/AL9/AP+/f38/AH8/AH8/AP+/f79/AP+/f38AAAAAv38Av38Av38A/79/fz8Afz8Afz8A/79//79/fwAAAAA=","224":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAD/v3//v3//v3//v3//v3//v3//v3//v3//v3//v38AAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79/v38Av38Av38Av38Av38Av38Av38Av38Av38AAAB/PwD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8/AH8/AP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79/fz8Afz8A/79/v38Av38Av38Av38Av38Av38AAAC/fwD/v39/PwB/PwD/v3+/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AP+/f38/AH8/AP+/f79/AL9/AL9/AL9/AAAAv38Av38Av38A/79/fz8Afz8A/79/v38Av38Av38AAAA=","226":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfz8Afz8Av38Av38Av38Av38Av38Av38Av38Av38AAAB/PwB/PwB/PwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAH8/AH8/AH8/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/fz8Afz8Afz8Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwB/PwB/PwB/PwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AH8/AH8/AH8/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Afz8Afz8Afz8Av38Av38AAAA=","230":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAA/79/v38Afz8Afz8Afz8Afz8Av38Av38Av38AAAB/AAD/v3+/fwB/PwB/PwB/PwB/PwC/fwC/fwC/fwAAAH8AAP+/f79/AH8/AH8/AH8/AH8/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwB/PwB/PwB/PwB/PwC/fwC/fwC/fwAAAH8AAP+/f79/AH8/AH8/AH8/AH8/AL9/AL9/AL9/AAAAfwAA/79/v38Afz8Afz8Afz8Afz8Av38Av38Av38AAAA=","232":"data:image/bmp;base64,Qk14AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEIBAADDDgAAww4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38A/yZ/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/AH8AAP+/f/+/f79/AL9/AL9/AL9/AL9/AP+/f/+/f/8FfwAAfwAA/79/v38Av38Av38Av38Av38A/79/fwAA/zP///9/AAD/v3+/fwC/fwC/fwC/fwC/fwD/v39/AAD/Tf///38AAP+/f79/AL9/AL9/AL9/AL9/AP+/f38AAP9JfwAAfwAA/79/v38Av38Av38Av38Av38A/79/fwAA/zN/AAD/v3//v3+/fwC/fwC/fwC/fwC/fwD/v3//v3//Xn8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP9afwAA/79/v38Av38Av38Av38Av38Av38Av38Av38A/wAAAA==","234":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAhSURBVChTY2BgqP9PHAYR9fvx41GFeDFcITJGkYTh+v8APePGd/udBzcAAAAASUVORK5CYII=","236":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAH8AAH8AAH8AAP+/f79/AL9/AP+/f38AAH8AAH8AAAAA/79//79//79//79/v38Av38A/79//79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79//79/v38Av38A/79//79//79//79/AAB/AAB/AAB/AAD/v3+/fwC/fwD/v39/AAB/AAB/AAAAAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","238":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAH8AAP///////////////////////////////////wAA/79/fwAA////////////////////////////////AAC/fwD/v39/AAD///////////////////////////8AAL9/AL9/AP+/f38AAP///////////////////////wAA/79/v38Av38A/79/fwAA////////////////////AAB/AAD/v3+/fwC/fwD/v39/AAD///////////////8AAP///38AAP+/f79/AL9/AP+/f38AAP///////////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","240":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAP///////////////////////////////////////wAA////////////////////////////////////////AAD///////////////////////////////////////8AAP///////38AAH8AAH8AAH8AAH8AAH8AAP///////wAA////////fwAA/79//79//79//79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","253":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////////fwAAfwAAfwAAfwAA////////////AAD///////9/AAB/PwD/v3//v39/PwB/AAD///////8AAP///38AAP+/f79/AH8/AL9/AH8/AP+/f38AAH8AAAAAfwAA/79/v38Afz8Av38Afz8Afz8A/79//79//79/AAB/AAD/v3+/fwC/fwB/PwB/PwB/PwC/fwC/fwC/fwAAAH8AAP+/f79/AH8/AH8/AH8/AH8/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Afz8Afz8Afz8A/79//79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwB/AAB/AAB/AAAAAP///38AAP+/f79/AL9/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","254":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////////fwAAfwAAfwAAfwAA////////////AAD///////9/AAD/v3//v3//v3//v39/AAD///////8AAP///38AAP+/f79/AL9/AL9/AL9/AP+/f38AAH8AAAAAfwAA/79/v38Av38A/79//79//79/v38A/79//79/AAB/AAD/v3+/fwD/v39/AAB/AAB/AAD/v3+/fwC/fwAAAH8AAP+/f79/AP+/f38AAP///////38AAP+/f79/AAAAfwAA/79/v38A/79/fwAA////////////fwAA/79/AAB/AAD/v3+/fwC/fwD/v39/AAD///////////9/AAAAAP///38AAP+/f79/AL9/AP+/f38AAP///////////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","255":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAH8AAH8AAP+/f79/AL9/AL9/AP+/f38AAP///////wAA/79//79/v38Av38Av38Av38A/79/fwAA////////AAC/fwC/fwC/fwC/fwC/fwD/v39/AAD///////////8AAL9/AL9/AL9/AL9/AP+/f38AAP///////////////wAA/79//79//79//79/fwAA////////////////////AAB/AAB/AAB/AAB/AAD///////////////////////8AAP///////////////////////////////////////wAA////////////////////////////////////////AAA=","256":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAH8AAH8AAP+/f79/AL9/AL9/AL9/AP+/f38AAH8AAAAA/79//79/v38Av38A/79//79/v38Av38A/79//79/AAC/fwC/fwC/fwD/v39/AAB/AAD/v3+/fwC/fwC/fwAAAL9/AL9/AP+/f/+/f38AAH8AAP+/f/+/f79/AL9/AAAA/79//79//79/fwAA////////fwAA/79//79//79/AAB/AAB/AAB/AAB/AAD///////9/AAB/AAB/AAB/AAAAAP///////////////////////////////////////wAA////////////////////////////////////////AAA=","257":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","258":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///9/AAB/AAD/v3+/fwC/fwD/v39/AAB/AAD///8AAH8AAH8AAP+/f/+/f79/AL9/AP+/f/+/f38AAH8AAAAA/79//79//79/v38Av38Av38Av38A/79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79/v38Av38Av38Av38A/79//79//79/AAB/AAB/AAD/v3//v3+/fwC/fwD/v3//v39/AAB/AAAAAP///38AAH8AAP+/f79/AL9/AP+/f38AAH8AAP///wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","259":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","260":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAB/AAD/v3//v3//v3+/fwC/fwD/v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Afz8Afz8Afz8Afz8Av38A/79/fwAAAAB/AAD/v3+/fwB/PwB/PwB/PwB/PwC/fwD/v39/AAAAAH8AAP+/f79/AH8/AH8/AH8/AH8/AL9/AP+/f38AAAAAfwAA/79/v38Afz8Afz8Afz8Afz8Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","261":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","263":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","264":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/7t5fz8Afz8A/7t5fwAA////////AAD///////9/AAD/u3m/fwC/fwD/u3l/AAD///////8AAP///////38AAP+7eX8/AH8/AP+7eX8AAP///////wAA////////fwAA/7t5v38Av38A/7t5fwAA////////AAD///////9/AAD/u3l/PwB/PwD/u3l/AAD///////8AAP///////38AAP+7eb9/AL9/AP+7eX8AAP///////wAA////////fwAAfz8Afz8Afz8Afz8AfwAA////////AAD///////9/AAD/u3m/fwC/fwD/u3l/AAD///////8AAP///////38AAH8/AH8/AH8/AH8/AH8AAP///////wAA////////fwAA/7t5v38Av38A/7t5fwAA////////AAA=","266":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///9/AAD/v3+/fwC/fwC/fwC/fwD/v39/AAD///8AAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79/v38Av38Av38Av38Av38Av38Av38Av38A/79/AAC/fwC/fwD/v3+/fwC/fwC/fwC/fwD/v3+/fwC/fwAAAL9/AP+/f38AAP+/f79/AL9/AP+/f38AAP+/f79/AAAA/79/fwAAfwAA/79/v38Av38A/79/fwAAfwAA/79/AAB/AAD///9/AAD/v3+/fwC/fwD/v39/AAD///9/AAAAAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","268":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///9/AAD/v3+/fwC/fwC/fwD/v39/AAD///////8AAH8AAP+/f79/AL9/AL9/AL9/AP+/f38AAP///////wAA/79/v38Av38Av38Av38Av38A/79/fwAA////////AAC/fwC/fwD/v3//v3+/fwC/fwD/v39/AAD///////8AAL9/AP+/f38AAP+/f79/AL9/AP+/f38AAP///////wAA/79/fwAAfwAA/79/v38Av38A/79/fwAA////////AAB/AAD///9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","270":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwC/fwD/v39/AAD///8AAP///////38AAP+/f79/AL9/AL9/AL9/AP+/f38AAAAA////////fwAA/79/v38Av38Av38Av38Av38A/79/AAD///////9/AAD/v3+/fwC/fwD/v3//v3+/fwC/fwAAAP///////38AAP+/f79/AL9/AP+/f38AAP+/f79/AAAA////////fwAA/79/v38Av38A/79/fwAAfwAA/79/AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///9/AAAAAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","272":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAAAA/79//79//79//79//79//79//79//79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79//79/v38Av38A/79//79//79//79/AAB/AAB/AAB/AAD/v3+/fwC/fwD/v39/AAB/AAB/AAAAAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","273":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAP///////wAA/79//79//79//79//79//79//79/fwAA////////AAC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAD///////8AAL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAP///////wAA/79//79//79//79/v38Av38A/79/fwAA////////AAB/AAB/AAB/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","275":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAP///////wAA/79//79/fz8A/79//79//79//79/fwAA////////AAB/PwC/fwB/PwC/fwC/fwC/fwD/v39/AAD///////8AAH8/AL9/AH8/AL9/AL9/AL9/AP+/f38AAP///////wAA/79//79/fz8A/79/v38Av38A/79/fwAA////////AAB/AAB/AAB/AAD/v39/PwB/PwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAAfz8Afz8Afz8Afz8AfwAA////////AAA=","277":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAP///////38AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAAAA////////fwAA/79//79//79//79//79//79//79/AAD///////9/AAD/v3+/fwC/fwC/fwB/PwC/fwB/PwAAAP///////38AAP+/f79/AL9/AL9/AH8/AL9/AH8/AAAA////////fwAA/79/v38Av38A/79//79//79//79/AAD///////9/AAD/v39/PwB/PwD/v39/AAB/AAB/AAAAAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/fz8Afz8A/79/fwAA////////AAA=","279":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAAAA/79//79/fz8A/79//79//79//79/fz8A/79//79/AAB/PwC/fwB/PwC/fwC/fwC/fwC/fwB/PwC/fwB/PwAAAH8/AL9/AH8/AL9/AL9/AL9/AL9/AH8/AL9/AH8/AAAA/79//79/fz8A/79/v38Av38A/79/fz8A/79//79/AAB/AAB/AAB/AAD/v3+/fwC/fwD/v39/AAB/AAB/AAAAAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAAfz8Afz8Afz8Afz8AfwAA////////AAA=","282":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAH8AAH8AAH8AAH8AAP///////38AAH8AAH8AAH8AAAAA/79//79//79/fwAA////////fwAA/79//79//79/AAC/fwC/fwD/v3//v39/AAB/AAD/v3//v3+/fwC/fwAAAL9/AL9/AL9/AP+/f38AAH8AAP+/f79/AL9/AL9/AAAA/79//79/v38Av38A/79//79/v38Av38A/79//79/AAB/AAB/AAD/v3+/fwC/fwC/fwC/fwD/v39/AAB/AAAAAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","283":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","284":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgADAwMAAgEAAAACAQIAAwACAQIAAAACAQECAAIBAgAAAAICAQEBAQECAAMAAAEBAQEBAQEAAwMAAAEBAQEBAQECAAMAAAICAQEBAQEBAgAAAAACAQEBAQEBAQIAAAACAgIBAQICAgIAAAAAAAIBAQIAAAAAAA==","293":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///9/AAB/AAD/v3+/fwC/fwD/v39/AAD///////8AAH8AAH8AAP+/f/+/f79/AP+/f/+/f38AAP///////wAA/79//79//79/v38Av38A/79/fwAAfwAA////////AAC/fwC/fwC/fwC/fwD/v3//v39/AAD///////////8AAL9/AL9/AP+/f/+/f/+/f38AAH8AAP///////////wAA/79//79//79/fwAAfwAAfwAA////////////////AAB/AAB/AAB/AAB/AAD///////////////////////8AAP///////////////////////////////////////wAA////////////////////////////////////////AAA=","294":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAH8AAH8AAH8AAP+/f79/AL9/AP+/f38AAH8AAH8AAAAA/79//79//79/v38Av38Av38Av38A/79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79/v38Av38Av38Av38A/79//79//79/AAB/AAB/AAB/AAD/v3+/fwC/fwD/v39/AAB/AAB/AAAAAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","296":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAH8AAP///////////////////////////////////wAA/79/fwAA////////////////////////////////AAC/fwD/v39/AAD///////////////////////////8AAL9/AL9/AP+/f38AAP///////////////////////wAA/79/v38Av38A/79/fwAA////////////////////AAB/AAD/v3+/fwC/fwD/v39/AAD///////////////8AAP///38AAP+/f79/AL9/AP+/f38AAP///////////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","297":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","298":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/fz8Afz8A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f38/AH8/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v39/PwB/PwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAAfz8Afz8Afz8Afz8AfwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAH8/AH8/AH8/AH8/AH8AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","325":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA7SURBVChTY2BgqP9PHAYR9fvxYxopxCaBjGEGYUggY2TbUDjYMMRaHArRxbAqhPGRxTEUYkhC+Qz1/wGyxsc237HzAAAAAABJRU5ErkJggg==","326":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAH8/AAC/fwAA/79/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAgICAgICAwAAAAADAgICAgICAwAAAAADAgICAgICAwAAAAMDAgICAgICAwAAAAICAgICAgICAQAAAAMDAgICAgIBAwAAAAADAgICAgECAwAAAAADAgICAQICAwAAAAADAwMBAwMDAwAAAAAAAAAAAAAAAAAAAA==","327":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAzSURBVChTY2BgqP+Pguv3QzC6OF5JFHFkAVyYNIXYJNAxaQqJtposhWABJIxXIVZ2/X8ARWHGd05f21oAAAAASUVORK5CYII=","328":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA+SURBVChTY2BgqP+Pguv3QzC6OIokLkwjhdgk0DGKQnwmw63GpwiE4QrRBZH5MDEUCRgbm2YUSWQFKOz6/wBDS8f1ZrHv1QAAAABJRU5ErkJggg==","329":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA4SURBVChTY2BgqP+Pguv3QzC6OIokLjxACmHyeBUiyxFlIhhjU4guhlUhjI8sjqEQQxLKZ6j/DwCrSMc2hj4LjwAAAABJRU5ErkJggg==","330":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAAfz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8AfwAAAAB/AAB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/AAAAAH8AAH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8AAAAAfwAAfz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8AfwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","331":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","333":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAH8/AAC/fwAA/79/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAgICAgICAwAAAAADAgICAgICAwAAAAADAgICAgICAwAAAAADAgICAgICAwMAAAEDAgICAgICAgIAAAEBAgICAgICAwMAAAABAQICAgICAwAAAAACAQECAgICAwAAAAACAgEBAwMDAwAAAAAAAAABAQAAAAAAAA==","334":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAvSURBVChTY2BgqP9PHAYR9fshGF0SRRxZABemvkIQpq5Coq3GUAgWQMKkK6z/DwCrMsN7fLF5eQAAAABJRU5ErkJggg==","335":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgAAAAEBAQEBAQEBAgAAAAEBAQEBAQEBAgAAAAICAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAgIBAQICAgAAAAAAAAIBAQIAAAAAAA==","337":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgIAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAgIAAAACAQEBAQEBAgAAAAACAgIBAQICAgAAAAAAAAIBAQIAAAAAAA==","339":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","340":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAzSURBVChTY2BgqP9PHAYR9fshGF0SRRxZABcmTSE2CWwYqyA2TLzVZCkECyBh0hXW/wcA+ELE+Y6G6xYAAAAASUVORK5CYII=","366":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAD///9/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAP///////38AAP+/f79/AL9/AL9/AL9/AL9/AL9/AAAA////////////fwAA/79/v38Av38Av38Av38Av38AAAD///////////////9/AAD/v3+/fwC/fwC/fwC/fwAAAP///////////////////38AAP+/f79/AL9/AL9/AAAA////////////////////////fwAA/79/v38Av38AAAD///////////////////////////9/AAD/v3+/fwAAAP///////////////////////////////38AAP+/fwAA////////////////////////////////////fwAAAAA=","368":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAbSURBVChTY/wPBAxEACYoTRCMKsQLiFTIwAAAaZoEEKBEepAAAAAASUVORK5CYII=","369":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38A/79/fwAA////////////AAD///////////9/AAD/v3+/fwD/v39/AAD///////8AAH8AAP///////////38AAP+/f79/AP+/f38AAP///wAA/79/fwAA////////////fwAA/79/v38A/79/fwAAAAC/fwD/v39/AAD///////////9/AAD/v3+/fwD/v38AAP+/f79/AP+/f38AAP///////////38AAP+/f79/AAAAfwAA/79/v38A/79/fwAA////////////fwAA/79/AAD///9/AAD/v3+/fwD/v39/AAD///////////9/AAAAAP///////38AAP+/f79/AP+/f38AAP///////////wAA////////////fwAA/79/v38A/79/fwAA////////AAA=","383":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","385":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAH8AAH8AAH8AAP+/f79/AL9/AP+/f38AAH8AAH8AAAAA/79//79//79//79/v38Av38A/79//79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79//79//79//79//79//79//79//79/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAAAAP///////////////////////////////////////wAA////////////////////////////////////////AAA=","387":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///9/AAB/AAD/v3+/fwC/fwD/v39/AAB/AAD///8AAH8AAH8AAP+/f/+/f79/AL9/AP+/f/+/f38AAH8AAAAA/79//79//79/v38Av38Av38Av38A/79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79//79//79//79//79//79//79//79/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAAAAP///////////////////////////////////////wAA////////////////////////////////////////AAA=","400":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAH8AAH8AAP+/f79/AL9/AL9/AL9/AP+/f38AAH8AAAAA/79//79/v38Av38A/79//79/v38Av38A/79//79/AAC/fwC/fwC/fwD/v39/AAB/AAD/v3+/fwC/fwC/fwAAAL9/AL9/AP+/f/+/f38AAH8AAP+/f/+/f79/AL9/AAAA/79//79//79/fwAA////////fwAA/79//79//79/AAB/AAB/AAB/AAB/AAD///////9/AAB/AAB/AAB/AAAAAP///////////////////////////////////////wAA////////////////////////////////////////AAA=","401":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAH8AAH8AAH8AAP+/f79/AL9/AP+/f38AAH8AAH8AAAAA/79//79//79/v38Av38Av38Av38A/79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79/v38Av38Av38Av38A/79//79//79/AAB/AAB/AAB/AAD/v3+/fwC/fwD/v39/AAB/AAB/AAAAAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","402":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////////9/AAD/v3+/fwC/fwD/v39/AAD///8AAP///////////////38AAP+/f79/AL9/AP+/f38AAAAA////////////////////fwAA/79/v38Av38A/79/AAD///////////////////////9/AAD/v3+/fwC/fwAAAP///////////////////////////38AAP+/f79/AAAA////////////////////////////////fwAA/79/AAD///////////////////////////////////9/AAAAAP///////////////////////////////////////wAA////////////////////////////////////////AAA=","403":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38A/79/fwAA////////////AAD///////////9/AAD/v3+/fwD/v39/AAD///////8AAH8AAP///////////38AAP+/f79/AP+/f38AAP///wAA/79/fwAA////////////fwAA/79/v38A/79/fwAAAAC/fwD/v39/AAD///////////9/AAD/v3+/fwD/v38AAP+/f79/AP+/f38AAP///////////38AAP+/f79/AAAAfwAA/79/v38A/79/fwAA////////////fwAA/79/AAD///9/AAD/v3+/fwD/v39/AAD///////////9/AAAAAP///////38AAP+/f79/AP+/f38AAP///////////wAA////////////fwAA/79/v38A/79/fwAA////////AAA=","404":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAASCwAAEgsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","405":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAH8AAH8AAH8AAP+/f79/AL9/AP+/f38AAH8AAH8AAAAA/79//79//79//79/v38Av38A/79//79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79//79//79//79//79//79//79//79/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAAAAP///////////////////////////////////////wAA////////////////////////////////////////AAA=","406":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///8/AAB/AAD/v3+/fwC/fwD/v39/AAA/AAD///8AAP///38AAP+/f/+/f79/AL9/AP+/f/+/f38AAH8AAAAA////fwAA/79/v38Av38Av38Av38A/79//79//79/AAD///9/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAP///38AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AAAA////fwAA/79/v38Av38Av38Av38A/79//79//79/AAD///9/AAD/v3//v3//v3//v3//v3//v39/AAB/AAAAAP///z8AAH8AAH8AAH8AAH8AAH8AAH8AAD8AAP///wAA////////////////////////////////////////AAA=","407":"data:image/bmp;base64,Qk14AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEIBAADDDgAAww4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAAAAA==","409":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","411":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","413":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","415":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAA////fwAA/79/v38Av38Av38Av38A/79/fwAA////AAD///9/AAD/v3+/fwC/fwC/fwC/fwD/v39/AAD///8AAH8AAH8AAP+/f79/AL9/AL9/AL9/AP+/f38AAH8AAAAA/79//79//79/v38Av38Av38Av38A/79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","417":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","419":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/pk4A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgIAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAgIAAAACAgIBAQICAgAAAAAAAAIBAQIAAAAAAAMDAAIBAQIAAwMAAA==","429":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAH8AAH8AAH8AAP+/f79/AL9/AP+/f38AAH8AAH8AAAAA/79//79//79/v38Av38Av38Av38A/79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79/v38Av38Av38Av38A/79//79//79/AAB/AAB/AAB/AAD/v3+/fwC/fwD/v39/AAB/AAB/AAAAAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","431":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","433":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f/+/fwAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","435":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f/+/fwAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","437":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAA=","439":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAICAQEBAQEBAgIAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAgIAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAA==","441":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAASCwAAEgsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAA=","443":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","445":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","447":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","449":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAArSURBVChTY2BgqP8Px/X7UTGyHFYF6Jg0hdgk0PFAKwQR2CSRMQ0U1v8HAL+40OkXw2Q9AAAAAElFTkSuQmCC","451":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAzSURBVChTY2BgqP9PHAYR9fvxY9IUYpPAhrEKYsNYBbFhrILYMNih2CSQMWm+Jkph/X8AY0TQ6Sx6FqAAAAAASUVORK5CYII=","453":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAlSURBVChTY2BgqP8Px/X7UTGyHFYF6Jj6CkF4sCsEqaGywvr/AFRI0Omz5LUIAAAAAElFTkSuQmCC","455":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA3SURBVChTY2BgqP8Px/X7UTGyHFYF6Jg0hdgksGGsgtgwVkFsGKsgNgx2KDYJZEyar4lSWP8fAO5o0+UItGCKAAAAAElFTkSuQmCC","457":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","465":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAB/AAD/v3//v3+/fwC/fwC/fwC/fwD/v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79/v38Av38Av38Av38Av38Av38Av38Av38A/79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79/v38Av38Av38Av38Av38Av38Av38Av38A/79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f79/AL9/AL9/AL9/AP+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","467":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","469":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f/+/fwAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","471":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAB/AAD/v3//v3//v3+/fwC/fwD/v3//v3//v3//v38AAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAA=","473":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAnSURBVChTY2BgqP/PUL8fPwapoYFCbBLoeKAVgghsksiYBgrr/wMASuvT5QcEYVYAAAAASUVORK5CYII=","475":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAzSURBVChTY2BgqP/PUL8fPwapoYFCbBLYMFZBbBirIDaMVRAbBjsUmwQyJs3XRCms/w8AeZvW4WhKBJIAAAAASUVORK5CYII=","477":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAA=","479":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA/SURBVChTY0AF9f8Z6vdDMIiNHYAk0BViVYykCEUxDCDrxqoQjtEkcWGsgtgwlIBgTEkkDAe4FGIAqihkYAAA5DSTuyLEeI4AAAAASUVORK5CYII=","480":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA7SURBVChTY0AF9f8Z6vdDMIiNHYAk0BViVYykCEUxBsClEIbhAItCZIwAlCiEWwvCcIBLIQagikIGBgCA94HThImZIgAAAABJRU5ErkJggg==","481":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA2SURBVChTYyAD1P/HjjEAULB+PypGUQgXwKUQjtEkcWGsgtgwlIBgTEkkDAe4FGIAqihkYAAAh9uKx/DXimsAAAAASUVORK5CYII=","482":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTY0AF9f8Z6vdDMIiNHYAk0BViVYykCEUxDCDrJqgQFyZfIVFWwwF9FTIwAADJfYNRDTCQ/gAAAABJRU5ErkJggg==","483":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAwSURBVChTYyAD1P/HjjEAULB+PyomTSEMwwEWhcgYAShRCLcWhOEAl0IMQBWFDAwAJJ5438W8+5AAAAAASUVORK5CYII=","484":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAoSURBVChTY0AF9f8Z6vdDMIiNGwyQQpAEukKsipEUoSjGAINUIQMDAAT/Y/toSyRcAAAAAElFTkSuQmCC","485":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAApSURBVChTYyAD1P/HjjEAULB+PypGUQgXIEYhLky+QqKshgP6KmRgAABtJHpdq2zXoQAAAABJRU5ErkJggg==","486":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3//v3//v3//v39/AAD///////8AAP///////38AAH8AAH8AAH8AAH8AAH8AAP///////wAA////////////////////////////////////////AAD///////////////////////////////////////8AAP///////////////////////////////////////wAA////////////////////////////////////////AAA=","487":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AH8/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Afz8Av38Afz8Av38Av38Av38Av38AAAC/fwC/fwB/PwC/fwC/fwC/fwB/PwC/fwC/fwC/fwAAAL9/AL9/AH8/AL9/AH8/AL9/AH8/AL9/AL9/AL9/AAAAv38Av38Afz8Av38Av38Av38Afz8Av38Av38Av38AAAC/fwC/fwB/PwB/PwB/PwB/PwB/PwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAA=","492":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f38AAP+/f79/AL9/AP+/f38AAL9/AL9/AAAAfwAA/79/fwAA/79/v38Av38A/79/fwAAv38Av38AAAB/AAD/v39/AAD/v3+/fwC/fwD/v39/AAD/pk7/pk4AAH8AAP+/f38AAP+/f79/AL9/AP+/f38AAP+/f/+/fwAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","493":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79//6ZOv38Av38Av38Av38A/6ZO/79/fwAAAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwD/pk7/v38AAH8AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AP+mTgAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f38AAP+/f79/AL9/AP+/f38AAL9/AL9/AAAAfwAA/79/fwAA/79/v38Av38A/79/fwAAv38Av38AAAB/AAD/v39/AAD/v3+/fwC/fwD/v39/AAD/pk7/pk4AAH8AAP+/f38AAP+/f79/AL9/AP+/f38AAP+/f/+/fwAAfwAA/79/fwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","494":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAH8AAH8AAH8AAH8AAL9/AL9/AL9/AL9/AL9/AAAA/79//79//79//79//79/v38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79//79//79/v38Av38Av38Av38Av38AAAB/AAB/AAB/AAB/AAB/AAD/pk7/pk7/pk7/pk7/pk4AAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","495":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAA/79//6ZOv38Av38Av38Av38A/6RL/7t5fwAAAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwD/pEv/u3kAAH8AAH8AAH8AAH8AAH8AAL9/AL9/AL9/AL9/AP+kSwAA/79//79//79//79//79/v38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79//79//79/v38Av38Av38Av38Av38AAAB/AAB/AAB/AAB/AAB/AAD/pk7/pk7/pk7/pk7/pk4AAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","496":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAA=","497":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","498":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTY2Co3/8fBTPUQzCmOIbA4FcIEcQmhiaAC2MVxIaxCmLDWAUx8P7/ACaa16DUABFOAAAAAElFTkSuQmCC","499":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTY2Co3/8fBTPUQzCmOIbA4FcIEcQmhiaAC2MVxIaxCmLDWAUx8P7/ACaa16DUABFOAAAAAElFTkSuQmCC","500":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTdcihAQAgCAAwPuc0TsNgEmZYWURWPyKv/SN+mMIUpjCFKUxhCnOpPmFQ3lfGuxmAAAAAAElFTkSuQmCC","501":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTdcihAQAgCAAwPuc0TsNgEmZYWURWPyKv/SN+mMIUpjCFKUxhCnOpPmFQ3lfGuxmAAAAAAElFTkSuQmCC","502":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAv38Av38Av38Av38Av38Av38Av38Av38Av38A/7t5AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Afz8Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwB/PwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AH8/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Afz8Av38Av38Av38Av38Av38AAAA=","503":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","504":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTY2Co3/8fBTPUQzCmOIYAtRXiwlgFsWGsgtgwVkFsGIsABGOKYwhQonD/fwB5m9bhFwFd0AAAAABJRU5ErkJggg==","505":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAv38Av38Av38Av38Av38Afz8Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwB/PwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AH8/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwB/PwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AH8/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Afz8Av38Av38Av38Av38AAAA=","506":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTY2Co3/8fBTPUQzCmOIYAtRXiwlgFsWGsgtgwVkFsGIsABGOKYwhQonD/fwB5m9bhFwFd0AAAAABJRU5ErkJggg==","507":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA1SURBVChTjcqxDQBACMPAbM5ojMYXVHyMROHmZCmyRorO/YMtRAqRAujcDY7jFiKFSCFaWQ/82dtbZrzkNwAAAABJRU5ErkJggg==","508":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA2SURBVChTjcqxDQBACMNANmc0RuOLVBAjfeHm5IisHkUq9wVXiBQiBaDcDT7HK0QKkQJQw6sf3gPZ3XgYYYoAAAAASUVORK5CYII=","509":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAv38Av38Av38Av38Afz8Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwB/PwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AH8/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Afz8Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwB/PwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AH8/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Afz8Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwB/PwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AH8/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Afz8Av38Av38Av38Av38Av38AAAA=","510":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAhSURBVChTY2Co3/8fBTPUQzCmOIbAqEJkcQwBShTu/w8AsLzQ6fWSopcAAAAASUVORK5CYII=","511":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAhSURBVChTY2Co3/8fBTPUQzCmOIbAqEJkcQwBShTu/w8AsLzQ6fWSopcAAAAASUVORK5CYII=","512":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAhSURBVChTY2Co3/8fBTPUQzCmOIbAqEJkcQwBShTu/w8AsLzQ6fWSopcAAAAASUVORK5CYII=","513":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAkSURBVChTY2BgqP/PUL+fMB5IhdgEsWGsgtjwQHqGKIX7/wMAcpPZ3YF3jnkAAAAASUVORK5CYII=","519":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAmSURBVChTY2BgqP/PUL+fMB5IhdgFsWGiFAExiEBXjA0PlML9/wE219Gou8qsKQAAAABJRU5ErkJggg==","521":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEAAAEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAICAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAA==","523":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAICAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAA==","527":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAICAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAA==","529":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAAEBAQEAAAACAQEBAAEBAQEAAAACAQEBAAEBAQEAAAICAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAQEAAAACAQEBAAEBAQEAAAACAQEBAAEBAQEAAAACAQEBAAEBAQEAAA==","531":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAICAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAA==","532":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAICAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAA==","533":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEAAQEBAQEAAAACAQEAAQEBAQEAAAACAQEAAQEBAQEAAAICAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAQEBAQEBAQEAAAACAQEAAQEBAQEAAAACAQEAAQEBAQEAAAACAQEAAQEBAQEAAA==","541":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAICAQEAAAEBAQEAAAEBAQEAAAEBAQEAAAEBAQEAAAEBAQEAAAICAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAA==","543":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAICAQEAAAEBAQEAAAEBAQEAAAEBAQEAAAEBAQEAAAEBAQEAAAICAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAA==","545":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAICAQEAAAEBAQEAAAEBAQEAAAEBAQEAAAEBAQEAAAEBAQEAAAICAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAA==","547":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAICAQEAAAEBAQEAAAEBAQEAAAEBAQEAAAEBAQEAAAEBAQEAAAICAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAA==","549":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAA==","551":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAAAAAAAAAEBAQEAAAACAQEBAAEBAQEAAAACAQEBAAEBAQEAAAACAQEBAAEBAQEAAAACAQEBAAEBAQEAAAACAQEBAAEBAQEAAA==","553":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAAEBAQEAAAACAQEBAAEBAQEAAAACAQEBAAEBAQEAAAACAQEBAAEBAQEAAAACAQEBAAEBAQEAAAAAAAAAAAEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAA==","555":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/pk4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAA==","556":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAA==","557":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/pk4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEAAAAAAAAAAAACAQEBAAAAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAA==","558":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEAAAAAAAAAAAACAQEBAAAAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAA==","559":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/7t5v38Av38Afz8Av38Av38Av38Av38Av38AAAB/AAD/u3m/fwC/fwB/PwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+7eb9/AL9/AH8/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/7t5v38Av38Afz8Av38Av38Av38Av38Av38AAAB/AAD/u3m/fwC/fwB/PwB/PwB/PwB/PwB/PwB/PwAAAH8AAP+7eb9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/7t5v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/u3m/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+7eb9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/7t5v38Av38Av38Av38Av38Av38Av38Av38AAAA=","561":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAA/79/v38Av38Av38AfwAAv38Av38Av38Av38AAAB/AAD/v3+/fwC/fwD/fwD/v3//fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AP9/AP+/f/9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38A/38A/79//38Av38Av38Av38AAAB/AAD/v3//fwD/fwC/fwB/AAC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f38AAH8AAL9/AL9/AL9/AL9/AAAAfwAA/79//38A/38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAA=","564":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/7t5v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/u3m/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+7eb9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/7t5v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/u3m/fwC/fwB/PwB/PwB/PwB/PwB/PwB/PwAAAH8AAP+7eb9/AL9/AH8/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/7t5v38Av38Afz8Av38Av38Av38Av38Av38AAAB/AAD/u3m/fwC/fwB/PwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+7eb9/AL9/AH8/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/7t5v38Av38Afz8Av38Av38Av38Av38Av38AAAA=","565":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTdcihAQAgCAAwPuc0TsNgEmZYWURWPyKv/SN+mMIUpjCFKUxhCnOpPmFQ3lfGuxmAAAAAAElFTkSuQmCC","571":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAA==","576":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAA==","579":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAA==","581":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAA==","583":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v3//v38AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAAAAfwAA/79//79//79//79//79//79//79//79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAA=","585":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/pk4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAAACAQEAAAEBAQEAAA==","587":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f79/AL9/AL9/AP+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAv38Av38Av38AfwAAfwAAfwAAfwAAAAB/AAD/v3//v3+/fwC/fwC/fwD/v3//v3//v3//v38AAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAA=","589":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAnSURBVChTY2BgqP/PUL8fgUF8dDGwOO0V4sKDSSGIj00zlRXu/w8A+C3Pa5NwyAYAAAAASUVORK5CYII=","591":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAAAAAEBAQEAAAAAAAAAAAEBAQEAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAA==","595":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v34AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAAAAAEBAQEAAAAAAAAAAAEBAQEAAAAAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAAACAQEBAQEBAQEAAA==","597":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAA/79/v38Av38Av38AfwAAv38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwB/AAC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AH8AAL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38AfwAAv38Av38Av38Av38AAAA=","599":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwB/PwB/PwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAA=","603":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwB/PwB/PwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAA=","605":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAgSURBVChTY2BgqP/PUL8fgUF8dDGw+KhCsAB9FO7/DwAvXclzC37p3wAAAABJRU5ErkJggg==","607":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v3//v38AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAAAAfwAA/79//79//79//79//79//79//79//79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAA=","609":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v3//v38AAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAA=","611":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAgSURBVChTY2BgqP/PUL8fgUF8dDGw+KhCsAB9FO7/DwAvXclzC37p3wAAAABJRU5ErkJggg==","613":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAlSURBVChTY2BgqP/PUL+fMB5ohURhrILYMIjAZhU6HiiF+/8DAHxtyvEV56OMAAAAAElFTkSuQmCC","615":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAgSURBVChTY2BgqP/PUL8fgUF8dDGw+KhCsAB9FO7/DwAvXclzC37p3wAAAABJRU5ErkJggg==","617":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAlSURBVChTY2BgqP/PUL+fMB5ohURhrILYMIjAZhU6HiiF+/8DAHxtyvEV56OMAAAAAElFTkSuQmCC","619":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTY2Co3/8fBTPUQzCmOIYAtRXiwlgFsWGsgtgwVkFsGIsABGOKYwhQonD/fwB5m9bhFwFd0AAAAABJRU5ErkJggg==","622":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/7t5v38Av38Afz8Av38Av38Av38Av38Av38AAAB/AAD/u3m/fwC/fwB/PwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+7eb9/AL9/AH8/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/7t5v38Av38Afz8Av38Av38Av38Av38Av38AAAB/AAD/u3m/fwC/fwB/PwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+7eb9/AL9/AH8/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/7t5v38Av38Afz8Av38Av38Av38Av38Av38AAAB/AAD/u3m/fwC/fwB/PwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+7eb9/AL9/AH8/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/7t5v38Av38Afz8Av38Av38Av38Av38Av38AAAA=","624":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTY2Co3/8fBTPUQzCmOIbA4FcIEcQmhiaAC2MVxIaxCmLDWAUx8P7/ACaa16DUABFOAAAAAElFTkSuQmCC","627":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79//38A/38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//v3//v39/AAB/AAC/fwC/fwC/fwC/fwAAAH8AAP+/f/9/AP9/AL9/AH8AAL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38A/38A/79//38Av38Av38Av38AAAB/AAD/v3+/fwC/fwD/fwD/v3//fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AP9/AP+/f/9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38AfwAAv38Av38Av38Av38AAAA=","628":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAD/v3//v3//v3//v3//v3+/fwC/fwC/fwC/fwC/fwAAAH8AAH8AAH8AAH8AAP+/f79/AL9/AL9/AL9/AL9/AAAA/79//79//79/fwAA/79/v38Av38Av38Av38Av38AAAC/fwC/fwD/v39/AAD/v3+/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AP+/f38AAP+/f79/AL9/AL9/AL9/AL9/AAAAv38Av38A/79/fwAA/79/v38Av38Av38Av38Av38AAAA=","630":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAD/pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAP+7ef+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/7t5/6ZOv38Av38Av38Av38Av38Av38Av38AAAA=","635":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAv38Av38Av38Av38Av38Av38Av38A/6ZO/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/pk7/v38AAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+mTgAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAD/pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAA=","640":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAA=","643":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79//6ZOv38Av38Av38Av38A/6ZO/79/fwAAAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwD/pk7/v38AAH8AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AP+mTgAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk7/pk7/pk7/pk7/pk7/pk7/pk7/pk4AAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","645":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk7/pk7/pk7/pk7/pk7/pk7/pk7/pk4AAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","648":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/z8A/38A/5Yt/6ZO/79//79//79//79//79/AAB/AAD/PwD/fwD/li3/pk7/v3//v3//v3//v3//v38AAH8AAH8AAH8AAH8AAH8AAH8AAP+/f/+/f/+/f/+/fwAA/79//79//79//79//79//79//79//79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwD/v3//v3//v3//v38AAL9/AL9/AL9/AL9/AL9/AL9/AP+/f/+/f/+/f/+/fwAA/79//79//79//79//79//79//79//79//79//6ZOAAB/AAB/AAB/AAB/AAB/AAB/AAD/v3//v3//pk7/li0AAH8AAP8/AP9/AP+WLf+mTv+/f/+/f/+mTv+WLf9/AAAAfwAA/z8A/38A/5Yt/6ZO/79//6ZO/5Yt/38A/z8AAAA=","649":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAA/z8A/38A/5Yt/6ZO/7t5/6ZO/5Yt/38A/yYAAAB/AAD/PwD/fwD/li3/pk7/u3n/v3//pk7/li3/fwAAAH8AAH8AAH8AAH8AAH8AAH8AAP+/f/+/f/+mTv+WLQAA/79//79//79//79//79//79//79//79//79//6ZOAAC/fwC/fwC/fwC/fwC/fwC/fwD/v3//v3//v3//v38AAL9/AL9/AL9/AL9/AL9/AL9/AP+/f/+/f/+/f/+/fwAA/79//79//79//79//79//79//79//79//79//79/AAB/AAB/AAB/AAB/AAB/AAB/AAD/v3//v3//v3//v38AAH8AAP8/AP9/AP+WLf+mTv+/f/+/f/+/f/+/f/+/fwAAfwAA/z8A/38A/5Yt/6ZO/79//79//79//79//79/AAA=","650":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","651":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79+/6ZO/6ZOv38Av38Av38Av38Av38Av38AAAB/AAD/v37/v37/v36/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAH8AAH8AAH8AAL9/AL9/AL9/AL9/AL9/AL9/AAAA/79+/79+/79+/79+v38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79+/79+/79+/79+v38Av38Av38Av38Av38Av38AAAB/AAB/AAB/AAB/AAC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/fv+/fv+/fr9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79+/6ZO/6ZOv38Av38Av38Av38Av38Av38AAAA=","656":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAA/79+/6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v37/pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/fv+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79+/6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v37/pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/fv+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79+/6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v37/pk6/fwC/fwC/fwC/fwC/fwC/fwD/pEsAAH8AAP+/fv+mTr9/AL9/AL9/AL9/AL9/AP+kS/+7eQAAfwAA/79+/6ZOv38Av38Av38Av38A/6RL/7t5fwAAAAA=","657":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79+/6ZOv38Av38Av38Av38A/6RL/7t5fwAAAAB/AAD/v37/pk6/fwC/fwC/fwC/fwC/fwD/pEv/u3kAAH8AAP+/fv+mTr9/AL9/AL9/AL9/AL9/AL9/AP+kSwAAfwAA/79+/6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v37/pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/fv+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79+/6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v37/pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/fv+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79+/6ZOv38Av38Av38Av38Av38Av38Av38AAAA=","658":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////fwAA/79//6ZOv38Av38Av38Av38Av38Av38AAAD///9/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwAAAP///38AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AAAA////fwAA/79//6ZOv38Av38Av38Av38Av38Av38AAAD///9/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwAAAP///38AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AAAA////fwAA/79//6ZOv38Av38Av38Av38Av38Av38AAAD///9/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwD/pk4AAP///38AAP+/f/+mTr9/AL9/AL9/AL9/AP+mTv+/fwAA////fwAA/79//6ZOv38Av38Av38A/6ZO/79/fwAAAAA=","660":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAA=","661":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79+/6ZOv38Av38Av38Av38A/6RL/7t5fwAAAAB/AAD/v37/pk6/fwC/fwC/fwC/fwC/fwD/pEv/u3kAAH8AAP+/fv+mTr9/AL9/AL9/AL9/AL9/AL9/AP+kSwAAfwAA/79+/6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v37/pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/fv+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79+/6ZOv38Av38Av38Av38Av38Av38Av38AAAD///9/AAD/v37/pk7/pk7/pk7/pk7/pk7/pk7/pk4AAP///////38AAP+/fv+/fv+/fv+/fv+/fv+/fv+/fgAA////////////fwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","663":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79//6ZO/6ZOv38Av38Av38Av38Av38Av38AAAD///9/AAD/v3//pk7/pk7/pk7/pk7/pk7/pk7/pk4AAP///////38AAP+/f/+/f/+/f/+/f/+/f/+/f/+/fwAA////////////fwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","671":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAAAA/79//79//79//79//79//79//79//79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79//79//79//79//79//79//79//79/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAAAAP///////////////////////////////////////wAA////////////////////////////////////////AAA=","672":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAzSURBVChTY/wPBAxEACYoTRAwMjDUE2UiY/1+4qxmZACqhLLxAuLdSLzVxHqGyuHIwAAA+GoTtwlSuyAAAAAASUVORK5CYII=","675":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAfSURBVChTY2BgqP9PHAYR9fsxMbr4qEJUCbIU7v8PAEnRyvE49eReAAAAAElFTkSuQmCC","676":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAeSURBVChTY2BgqP/PUL8fE6OLjypElaBIIUFc/x8A5MHK8SKg3A0AAAAASUVORK5CYII=","677":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAiSURBVChTY2BgqP+Pguv3QzC6OIokMkYXH1WIKkGWwv3/AY9jzG8xmAtDAAAAAElFTkSuQmCC","678":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAhSURBVChTY2BgqP/PUL8fE6OLjypElaBIITJGVgjH9f8BA6bMb9QE30YAAAAASUVORK5CYII=","679":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAAAAAAAAAgAAAgAAAAICAAIAAAACAAIAAgIAAAMDAwADA3MAA8MqmAAAgQAAAIGAAACCAAAAgoAAAIMAAACDgAABAAAAAQCAAAEBAAABAYAAAQIAAAECgAABAwAAAQOAAAGAAAABgIAAAYEAAAGBgAABggAAAYKAAAGDAAABg4AAAgAAAAIAgAACAQAAAgGAAAICAAACAoAAAgMAAAIDgAACgAAAAoCAAAKBAAACgYAAAoIAAAKCgAACgwAAAoOAAAMAAAADAIAAAwEAAAMBgAADAgAAAwKAAAMDAAADA4AAA4AAAAOAgAADgQAAA4GAAAOCAAADgoAAA4MAAAODgAEAAAABAACAAQABAAEAAYABAAIAAQACgAEAAwABAAOAAQCAAAEAgIABAIEAAQCBgAEAggABAIKAAQCDAAEAg4ABAQAAAQEAgAEBAQABAQGAAQECAAEBAoABAQMAAQEDgAEBgAABAYCAAQGBAAEBgYABAYIAAQGCgAEBgwABAYOAAQIAAAECAIABAgEAAQIBgAECAgABAgKAAQIDAAECA4ABAoAAAQKAgAECgQABAoGAAQKCAAECgoABAoMAAQKDgAEDAAABAwCAAQMBAAEDAYABAwIAAQMCgAEDAwABAwOAAQOAAAEDgIABA4EAAQOBgAEDggABA4KAAQODAAEDg4ACAAAAAgAAgAIAAQACAAGAAgACAAIAAoACAAMAAgADgAIAgAACAICAAgCBAAIAgYACAIIAAgCCgAIAgwACAIOAAgEAAAIBAIACAQEAAgEBgAIBAgACAQKAAgEDAAIBA4ACAYAAAgGAgAIBgQACAYGAAgGCAAIBgoACAYMAAgGDgAICAAACAgCAAgIBAAICAYACAgIAAgICgAICAwACAgOAAgKAAAICgIACAoEAAgKBgAICggACAoKAAgKDAAICg4ACAwAAAgMAgAIDAQACAwGAAgMCAAIDAoACAwMAAgMDgAIDgAACA4CAAgOBAAIDgYACA4IAAgOCgAIDgwACA4OAAwAAAAMAAIADAAEAAwABgAMAAgADAAKAAwADAAMAA4ADAIAAAwCAgAMAgQADAIGAAwCCAAMAgoADAIMAAwCDgAMBAAADAQCAAwEBAAMBAYADAQIAAwECgAMBAwADAQOAAwGAAAMBgIADAYEAAwGBgAMBggADAYKAAwGDAAMBg4ADAgAAAwIAgAMCAQADAgGAAwICAAMCAoADAgMAAwIDgAMCgAADAoCAAwKBAAMCgYADAoIAAwKCgAMCgwADAoOAAwMAAAMDAIADAwEAAwMBgAMDAgADAwKAA8Pv/AKSgoACAgIAAAAD/AAD/AAAA//8A/wAAAP8A/wD//wAA////AP////////////8AAP////////////8AAAQEBAQEBAQEBAQAAAkJCQkJCQkJCQkAAODg4ODg4ODg4OAAAODg4ODg4ODg4OAAAAkJCQkJCQkJCQkAAAQEBAQEBAQEBAQAAP////////////8AAP////////////8AAA==","680":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVChTjcyxDQAgCEVBNnc0RkNt8WIornnhE7GyRhiFUc7lvZ7AWhilvf/BWhiF8ZG1AbC80OmCmuBBAAAAAElFTkSuQmCC","681":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAwSURBVChTY2BgqP9PHAYR9fvxY9IVEoexmIANYxXEhtGMx4NBBDYTkDHpCgni+v8A8be8BQ3jaQIAAAAASUVORK5CYII=","682":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAwSURBVChTY2BgqP9PHAYR9fvxY9IVEoexmIANYxXEhtGMx4NBBDYTkDHpCgni+v8A8be8BQ3jaQIAAAAASUVORK5CYII=","683":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAH8AAH8/AH8/AH8AAH8/AH8/AH8AAH8/AH8/AH8AAAAA/79//79//79//79//79//79//79//79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79//79//79//79//79//79//79//79/AAB/AAB/PwB/PwB/AAB/PwB/PwB/AAB/PwB/PwB/AAAAAP///////////////////////////////////////wAA////////////////////////////////////////AAA=","684":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAvSURBVChTY2BgqP9PHAYR9fvxY9IVEoexmIANYxXEhtGMx4NBBDYTkDENFNb/BwBtHsH9cnI7gQAAAABJRU5ErkJggg==","716":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","735":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","737":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAH8AAH8AAH8AAP+/f79/AL9/AP+/f38AAH8AAH8AAAAA/79//79//79/v38Av38Av38Av38A/79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79/v38Av38Av38Av38A/79//79//79/AAB/AAB/AAB/AAD/v3+/fwC/fwD/v39/AAB/AAB/AAAAAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","738":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAH8AAP///////////////////////////////////wAA/79/fwAA////////////////////////////////AAC/fwD/v39/AAD///////////////////////////8AAL9/AL9/AP+/f38AAP///////////////////////wAAv38Av38Av38A/79/fwAA////////////////////AAD/v3+/fwC/fwC/fwD/v39/AAD///////////////8AAH8AAP+/f79/AL9/AL9/AP+/f38AAP///////////wAA////fwAA/79/v38Av38Av38A/79/fwAA////////AAA=","739":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38A/79/fwAA////////////AAD///////////9/AAD/v3+/fwD/v39/AAD///////8AAH8AAP///////////38AAP+/f79/AP+/f38AAP///wAA/79/fwAA////////////fwAA/79/v38A/79/fwAAAAC/fwD/v39/AAD///////////9/AAD/v3+/fwD/v38AAP+/f79/AP+/f38AAP///////////38AAP+/f79/AAAAfwAA/79/v38A/79/fwAA////////////fwAA/79/AAD///9/AAD/v3+/fwD/v39/AAD///////////9/AAAAAP///////38AAP+/f79/AP+/f38AAP///////////wAA////////////fwAA/79/v38A/79/fwAA////////AAA=","740":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAA==","741":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3//v3//v3//v39/AAD///////8AAP///////38AAH8AAH8AAH8AAH8AAH8AAP///////wAA////////////////////////////////////////AAA=","742":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAH8AAH8AAH8AAP+/f79/AL9/AP+/f38AAP///////wAA/79//79//79//79/v38Av38A/79/fwAA////////AAC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAD///////8AAL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAP///////wAA/79//79//79//79//79//79//79/fwAA////////AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAD///////8AAP///////////////////////////////////////wAA////////////////////////////////////////AAA=","745":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","746":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79//79//79//79//79//79//79//79/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAB/AAAAAP///////////////////////////////////////wAA////////////////////////////////////////AAA=","748":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAH8AAH8AAH8AAP+/f79/AL9/AP+/f38AAH8AAH8AAAAA/79/fz8Afz8A/79/v38Av38A/79/fz8Afz8A/79/AAC/fwB/PwB/PwC/fwC/fwC/fwC/fwB/PwB/PwC/fwAAAL9/AH8/AH8/AL9/AL9/AL9/AL9/AH8/AH8/AL9/AAAA/79/fz8Afz8A/79/v38Av38A/79/fz8Afz8A/79/AAB/AAB/AAB/AAD/v3+/fwC/fwD/v39/AAB/AAB/AAAAAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","751":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","752":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVChTY2BgqP8PJIgA9fuBColRDFKIoRibRphCmGIMTTAwCBSiSOJSiFUCAxCjiIEBAEu4SR8ggTEkAAAAAElFTkSuQmCC","754":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZSURBVChTY6AFqP8PZeABYDXDSiFVAQMDAERMEemUdBZPAAAAAElFTkSuQmCC","760":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAA=","761":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAmSURBVChTY2BgqP9PHAYR9fsJ4wFSSLQbiVYIwnQ0EWwKTG7/fwCQWc3tCBAUWwAAAABJRU5ErkJggg==","762":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTjcjBCQAgDATB6zylWVr0I/gYgo+BZZNUj2rdPvGDUziFUziFUziFU54YVG//ydMmMlZF7QAAAABJRU5ErkJggg==","763":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAgICAgICAgIAAAAAAAAAAAAAAAAAAA==","772":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/fwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","773":"data:image/bmp;base64,Qk14AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEIBAAASCwAAEgsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwBlcn8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f/+/f3RlfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAARmkAAA==","775":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79/v38Av38Av38Av38Av38Av38Av38Av38AAAA=","795":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAB/AAD/v3//v3//v3+/fwC/fwD/v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","819":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTY2BgqP9PENfvB9IwBi5MtEIYJt9EEB8d41aIFQysQphiGBsDMDAAAGAukADiU8frAAAAAElFTkSuQmCC","829":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAwSURBVChTjcqxDQAwCAQxNme0jPZJektQuDldVXWWTlYYhVEYhVEYhVEY5Z3/HnQusLzQ6bzO2EcAAAAASUVORK5CYII=","840":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAvSURBVChTY4CA+v8M9fuxY5AcAgwHhWAM5aArQMdQArskCMNNJMpqOIDpwoUZGAD44aodel/ttwAAAABJRU5ErkJggg==","845":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA4SURBVChTfclBCgAgCEVBb+7RPJpBbYyGFg9lfkRW7yLPnU0jyogyouwafhHVeDTOHygjyoiPVS8VM9PlMktgAQAAAABJRU5ErkJggg==","846":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA4SURBVChTY2BgqP/PUL8fPwapwSqBDUNVE4GxCmLDIAKbVciYdIVEYayCWDEWq7BhrILomKH+PwAOn7zEphwYswAAAABJRU5ErkJggg==","847":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAsSURBVChTY2BgqP/PUL8fPwapGWiFRGGsglgxFquQMUgRhEaTQMc0Urj/PwA+Gsf1tWawMQAAAABJRU5ErkJggg==","853":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA2SURBVChTjcxBCgAgCEVBb+7ROppBK4OhXDyQ+WBEZA1bNYqo2qGx30AZUUaUXcMrojrvv2Vt593K8YvvzWcAAAAASUVORK5CYII=","866":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABFSURBVChTlYrJDQAwCMPYnNEYjaqHSKD00YdRZCwi6i1qGRofIT8qNDIc7X8MlthwMVhiw51H5RlC5AB+nZsr7KJJCs0Hv77EOv5+qb8AAAAASUVORK5CYII=","867":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","868":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","869":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTY2Co3/8fjHEBuDztFBLCWAWxYayC2DBWQWwYwcABaKRw/38AVuiPQVdeMFEAAAAASUVORK5CYII=","870":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcixDQAACMOwfs5pnAYPeGgkL0nf7FU4hVM4hVM4hVM4pSt57DSzEdlMDxoAAAAASUVORK5CYII=","871":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAxSURBVChTncqxDQAgEIDA39zRHE1DDYXxEjrm3donk5pIaiKpiaQmkppIaiKpif7MXB1Ja3GMjO+VAAAAAElFTkSuQmCC","872":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZSURBVChTY6AM1O//j4GxglGFeBViAAYGAPdbWYmh3IgQAAAAAElFTkSuQmCC","873":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZSURBVChTY6AM1O//j4GxglGFeBViAAYGAPdbWYmh3IgQAAAAAElFTkSuQmCC","874":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZSURBVChTY6AM1O//j4GxglGFeBViAAYGAPdbWYmh3IgQAAAAAElFTkSuQmCC","900":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVChTY2BgqP9PHAYR9fsJY+oohFsLwoQUwtmEFCIAOQrBEugYDoAc7CagA2IUMjAAAHT9n6tSdoLbAAAAAElFTkSuQmCC","932":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAkSURBVChTY4CA+v8M9fvxYxIUAhUNH4UgQFWFEAK7JBzv/w8AOA/LsOcgMhwAAAAASUVORK5CYII=","933":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA9SURBVChTY0CA+v8M9fsRGMTHDggqBAlAMbpCMA0DyJLYMBxgk0TGcIBNEhkjAA43YiqEAmyKQJhGgIEBAFubdSSgVIj2AAAAAElFTkSuQmCC","934":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAnSURBVChTY2BgqP9PHAYR9fvxY6IVgjB1TaSRQmwS6Jh0qwni+v8AUUHGd41hY48AAAAASUVORK5CYII=","935":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA+SURBVChTY2BgqP/PUL//P5yGYRAfjsEATQE6Jl0hNklkDDMIQwIdk66QGDdCaDQJdAxSCAEgBiFMNGBgAAAC2axabYaP+QAAAABJRU5ErkJggg==","936":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTY0CA+v8M9fsRGMTHBNRTBAREKQIBohSBAFGKwIAoRQMHGBgAj3wwgJmu5qwAAAAASUVORK5CYII=","937":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVChTY0CA+v8M9fsRGMTHBOQqAtPoAJsivArRTQaLIQNcisDiKACoCBlgVzRwgIEBAFunT9ayQ7IWAAAAAElFTkSuQmCC","938":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAbSURBVChTY0CA+v8M9fsRGMTHDkYV0l4hAwMAICNg/3UTD9EAAAAASUVORK5CYII=","939":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAiSURBVChTY0CA+v8M9fsRGMTHDqiuEFnRYFUIkqCjQgYGAKJjY/s8NM0ZAAAAAElFTkSuQmCC","940":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTY6AhqN//HwNjBaMKMRQyMAAA0l1ZifCanCwAAAAASUVORK5CYII=","941":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTY2Co3/8fBeMEZCnED+qhioA0OkA1BFkhGkZRiMxBCA6YQmwYhyCaifv/AwDtq6Bq+eWuYAAAAABJRU5ErkJggg==","945":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA2SURBVChTY2Co3/+fAQzqgTQ2DJKCqQEJgDjYMEwxXkUwDFE8rBSC1GKRRMYoAJsCEAYDBgYA/TW6h76HO3cAAAAASUVORK5CYII=","946":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA4SURBVChTY2Co3/8fAzPUYxNDE4AIYhPDEMCF0RSA2VgBTAeIiVMREMBMxKsIBAaBQpiHsAIGBgA+FWzvHdK5SwAAAABJRU5ErkJggg==","947":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAjSURBVChTY2Co3/8fK2aoB2JkgE0RCI8qBANsikCYPIUMDADs3pU5rl0VJQAAAABJRU5ErkJggg==","948":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","951":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAVSURBVChTYyAf1O//D8ajgAaAgQEAFswEewPE0XcAAAAASUVORK5CYII=","952":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAVSURBVChTYyAf1O//D8ajgAaAgQEAFswEewPE0XcAAAAASUVORK5CYII=","953":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxjsoH7/fyiLACBa4ZAADAwA+zIEe55ozWUAAAAASUVORK5CYII=","959":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAeSURBVChTY2BgqP9PHAYR9fvx41GFeDFcIUFc/x8AHw3E+bIVr9gAAAAASUVORK5CYII=","961":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA2SURBVChTjdAxCgAgDATB/DxP82mnhYXgFCkGwnJVqqoztDLCKIzCKIzCKIzCKGd5j+/Bj84GypnRqOG19msAAAAASUVORK5CYII=","963":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA7SURBVChTjdDLCQAgDATRdJ7SLM1PRPDwQANzmZ1TYl/2yGbW9owOFWsQlIJSUApKQSlm6eHm65cVRQy4sNDpPZ3VtgAAAABJRU5ErkJggg==","975":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA1SURBVChTY2Co3/+fAR2AxNAxVoBdYT2QIAqj64RKYIpjCAy4QkyMphCGwZIwQIxCMLv+PwBwrrAV1DkLuAAAAABJRU5ErkJggg==","979":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","980":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhyoH7/fzjGC4hWOBgBAwMA1GsNb8i2m3kAAAAASUVORK5CYII=","982":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAzSURBVChTrcmxCQAgFMTQ29zRHE3BIlwRfuWDVMmz9hmDzQ42O9jsYLODzQ42OzXOf5IL8lOB06VsYuwAAAAASUVORK5CYII=","990":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTY6ARqN//Hy+GA2ySyBgOsEkiYzhAEayHYBQxGEARJFYhNkwDwMAAANeBaHU2ygqnAAAAAElFTkSuQmCC","991":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA1SURBVChTjcmxCQAxFIDQv3lGu9ESSCEWEu6BlXOtbz9DTYeaDjUdajrUdKjpUNOhpvtv5gCKBaEpDJQ7FAAAAABJRU5ErkJggg==","993":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTYyAT1P9HxdhA/f7/GBhTMVAAm0IQRlU8gAqBgChFcACSQMYkAwYGADHpZvdbd05EAAAAAElFTkSuQmCC","994":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAwSURBVChTY2Co3/+fKIxVEBvGKogNYxXEhrEKYsNYBbFhrILYMBhgk0DHVFa4/z8AlcvZHs8CftMAAAAASUVORK5CYII=","995":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAeSURBVChTYyAR1P/Hj+EAyKnfjx0Pb4V4MdGAgQEAl+N6XdbJCXoAAAAASUVORK5CYII=","996":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA1SURBVChTjcqxCQAgFMTQv7mjOZp2IUIKH6S6m8fah5IPFWp0qNGhRocaHWp0qNGhRvdv5gKXf5X4C3CF9AAAAABJRU5ErkJggg==","997":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYwCD+v3/CeJRhXgxlRXu/w8ANpjJc58kEjIAAAAASUVORK5CYII=","998":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAiSURBVChTYyAR1P/Hj+EAyKnfjx0Pb4V4MTYANwmZzcAAABNKg1FNh5pyAAAAAElFTkSuQmCC","1003":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAoSURBVChTYyAB1P8njJEV1u/HjhEKQWCQK4Rx0BXAMIZCvJhowMAAAFnEgdOP2Ir5AAAAAElFTkSuQmCC","1010":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA6SURBVChTlcqxDQAgDAPBbM5ojBZkiiiRn4KTvrLjWjufGTopQyc10KFXaOwVGnsDHZShkzJ0Un8iDnkEiIoodHoyAAAAAElFTkSuQmCC","1012":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA1SURBVChTjcmxCQAwEMNAb57RMtoHUhgVKl5wlZJzZ+Vng5pNajap2aRmk5pNajap2aR9yQNW0KWjmjeLmQAAAABJRU5ErkJggg==","1013":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhyoH7/fzjGC4hWOBgBAwMA1GsNb8i2m3kAAAAASUVORK5CYII=","1016":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVChTYyAf1O//D8Y4AUwBOsYA2BSBMAbApgiEMQA2RSCMAbApAmEMgE0RCNMIMDAAAGbGVQ8RDFXPAAAAAElFTkSuQmCC","1025":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1026":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTY6ARqN//Hy+GA2ySyBgOsEkiYzhAEayHYBQxGEARJFYhNkwDwMAAANeBaHU2ygqnAAAAAElFTkSuQmCC","1029":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA3SURBVChTjYmxDQAgDMP6Oaf1tDJ0wcVCDJZiJ2JlfaHRGEL4QXy3Q3y3Qwi/Q15oNDQaGi+yNgp41uE3ZVpxAAAAAElFTkSuQmCC","1052":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f/+/f/+/f/+/f38AAP///////wAA////////fwAAfwAAfwAAfwAAfwAAfwAA////////AAD///////////////////////////////////////8AAP///////////////////////////////////////wAA////////////////////////////////////////AAD///////////////////////////////////////8AAP///////////////////////////////////////wAA////////////////////////////////////////AAA=","1053":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8Afz8AAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AH8/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwB/PwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAv38Av38Av38Av38Av38Av38Av38Av38Av38Av38AAAA=","1054":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk6/fwC/fwC/fwB/PwB/PwB/PwB/PwAAAH8AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79//6ZOv38Av38Afz8Afz8Afz8Afz8Afz8AAAB/AAD/v3//pk6/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAH8AAP+/f/+mTr9/AH8/AH8/AH8/AH8/AH8/AH8/AAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAB/AAD/v3//pk6/fwB/PwB/PwB/PwB/PwB/PwB/PwAAAH8AAP+/f/+mTr9/AL9/AL9/AL9/AL9/AL9/AL9/AAAAfwAA/79//6ZOv38Av38Av38Av38Av38Av38Av38AAAA=","1055":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAAv38Av38Av38Av38Av38Av38Av38A/6ZO/79/fwAAAAB/PwB/PwB/PwC/fwC/fwC/fwC/fwD/pk7/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+mTv+/f38AAAAAfz8Afz8Afz8Afz8Afz8Av38Av38A/6ZO/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/pk7/v39/AAAAAH8/AH8/AH8/AH8/AH8/AH8/AL9/AP+mTv+/f38AAAAAv38Av38Av38Av38Av38Av38Av38A/6ZO/79/fwAAAAB/PwB/PwB/PwB/PwB/PwB/PwB/PwD/pk7/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+mTv+/f38AAAAAv38Av38Av38Av38Av38Av38Av38A/6ZO/79/fwAAAAA=","1059":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA3SURBVChTjYmxDQAgDMP6Oaf1tDJ0wcVCDJZiJ2JlfaHRGEL4QXy3Q3y3Qwi/Q15oNDQaGi+yNgp41uE3ZVpxAAAAAElFTkSuQmCC","1060":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1061":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAAATCwAAEwsAAAAAAAAAAAAA////////fwAA/79//79//79//79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f/+/f/+/f/+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3//v3//v3//v39/AAD///////8AAP///////38AAP+/f/+/f/+/f/+/f38AAP///////wAA////////fwAAv38Av38Av38Av38AfwAA////////AAD///////9/AAD/v3//v3//v3//v39/AAD///////8AAP///////38AAL9/AL9/AL9/AL9/AH8AAP///////wAA////////fwAA/79//79//79//79/fwAA////////AAA=","1078":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAvSURBVChTY4CA+v8M9fuxY5AcAgwHhWAM5aArQMdQArskCMNNJMpqOIDpwoUZGAD44aodel/ttwAAAABJRU5ErkJggg==","1079":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTY6ARqN//Hy+GA2ySyBgOsEkiYzhAEayHYBQxGEARJFYhNkwDwMAAANeBaHU2ygqnAAAAAElFTkSuQmCC","1095":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1096":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1097":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1102":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxgSoH7/fzAmCIhWONgBAwMAti0I9aoN6EsAAAAASUVORK5CYII=","1103":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1111":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1112":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAeSURBVChTYyAR1P/Hj+EAyKnfjx0Pb4V4MdGAgQEAl+N6XdbJCXoAAAAASUVORK5CYII=","1115":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhyoH7/fzjGC4hWOBgBAwMA1GsNb8i2m3kAAAAASUVORK5CYII=","1116":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAzSURBVChTrcmxCQAgFMTQ29zRHE3BIlwRfuWDVMmz9hmDzQ42O9jsYLODzQ42OzXOf5IL8lOB06VsYuwAAAAASUVORK5CYII=","1122":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZSURBVChTY8AA9fv/gzFBQLTCUUA6YGAAAOOICPXabXJcAAAAAElFTkSuQmCC","1123":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1124":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1125":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1126":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1128":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAjSURBVChTY2Co3/+fKIxVEBvGKogNYxXEhrEKYsPDBzAwAAAmEm/rR8cEJQAAAABJRU5ErkJggg==","1129":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAeSURBVChTYyAI6vf/B2OCgGiFIDDyFIIUEa9w/38A89sfV4mAUBoAAAAASUVORK5CYII=","1131":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAeSURBVChTYxgFWEH9/v9gDGcQwlgFsWGsghh4/38AKzxHoWF5eHAAAAAASUVORK5CYII=","1132":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAdSURBVChTY2Co3/+fKIxVEBsGA2wSyHgU4AcMDADh7z6tT80QwwAAAABJRU5ErkJggg==","1133":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1134":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAcSURBVChTY8AL6vf/h2O8YFQhToCsiHiF+/8DAIbAR6GR1CAJAAAAAElFTkSuQmCC","1135":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1136":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAdSURBVChTY2Co3/8fjAkCmEKCikcV4gVEKWJgAACGaz6tt/I5YAAAAABJRU5ErkJggg==","1143":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1144":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1146":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAeSURBVChTY2Co3/8fjAkCkhQSBYadQqIUE6WQgQEAFJ4fV6O8mrkAAAAASUVORK5CYII=","1147":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAaSURBVChTY2Co3/8fBeMEZCnEC0YV4gQMDADRs0ehRaye7wAAAABJRU5ErkJggg==","1148":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1149":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAVSURBVChTYyAK1O//D2WNAvoABgYAP64CPmyBA3AAAAAASUVORK5CYII=","1151":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1152":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1153":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAWSURBVChTYxgF9Ab1+/9DWbhB/f7/AFoiBHu3JCQEAAAAAElFTkSuQmCC","1154":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1155":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTY6AjqN//H4wJAqIVDl/AwAAAvZMI9bsBlpIAAAAASUVORK5CYII=","1156":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZSURBVChTYxgFpIH6/f/BmCAgWiFWwMAAANlmCPU7Mz5JAAAAAElFTkSuQmCC","1157":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTY2Co3/+fgRAgRs0ooCZgYAAAzlYEewTZ8z0AAAAASUVORK5CYII=","1159":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAUSURBVChTY2Co3/+fYRQMNsDAAACQQgI+ZgXpHAAAAABJRU5ErkJggg==","1160":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTY6AjqN//H4wJAqIVDl/AwAAAvZMI9bsBlpIAAAAASUVORK5CYII=","1161":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAVSURBVChTYxgF9Ab1+/9DWXgAAwMAVigCPnZQE4cAAAAASUVORK5CYII=","1162":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAfSURBVChTY2Co3/+fKIxVEBvGKogNEwREKxx+gIEBAJ33R6GE4k7MAAAAAElFTkSuQmCC","1164":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAdSURBVChTY8AJ6vf/R8E4AdEKQWBUIV4AV7j/PwBDakehgW/+YwAAAABJRU5ErkJggg==","1165":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1166":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1168":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAfSURBVChTY2Co3/+fgSgwiBSC+Fg1k60QJxgghQwMAJc3H1dgBLeuAAAAAElFTkSuQmCC","1169":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1171":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhMoH7/fzAmCIhWOGQBAwMAlhAI9UQaQmsAAAAASUVORK5CYII=","1172":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAmSURBVChTY2Co3/+fKIxVEBvGKogNYxXEhrEKYsNYBbHhQQ8YGAA4coZN7cTTJAAAAABJRU5ErkJggg==","1173":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1174":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1176":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhMoH7/fzAmCIhWOGQBAwMAlhAI9UQaQmsAAAAASUVORK5CYII=","1177":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1181":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZSURBVChTY0AB9fv/o2CcgGiFo4A8wMAAAMWFEen+31v0AAAAAElFTkSuQmCC","1182":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1183":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1187":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAbSURBVChTYxgF+EH9/v9EYayC2DBWQQy8/z8A84lDJ6C8aGMAAAAASUVORK5CYII=","1191":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAVSURBVChTYxgF9Ab1+/9DWXgAAwMAVigCPnZQE4cAAAAASUVORK5CYII=","1198":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1214":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxgSoH7/fzjGC4hWONgBAwMAdaINbzTcu4MAAAAASUVORK5CYII=","1215":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxgSoH7/fzjGC4hWONgBAwMAdaINbzTcu4MAAAAASUVORK5CYII=","1216":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxgSoH7/fzjGC4hWONgBAwMAdaINbzTcu4MAAAAASUVORK5CYII=","1217":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxgSoH7/fzjGC4hWONgBAwMAdaINbzTcu4MAAAAASUVORK5CYII=","1219":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAArSURBVChTnchBCQAACAAxmxvNaFpggniwz8WvrF5xCqdwCqdwCqdwyqmsHnJhrpfnm2h7AAAAAElFTkSuQmCC","1220":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxgSoH7/fzjGC4hWONgBAwMAdaINbzTcu4MAAAAASUVORK5CYII=","1221":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAArSURBVChTnchBCQAACAAxmxvNaFpggniwz8WvrF5xCqdwCqdwCqdwyqmsHnJhrpfnm2h7AAAAAElFTkSuQmCC","1222":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAzSURBVChTjcixDQAwDAJBNvdoHi0pEeILI33B6b7Zdwogv70gv70gvx2QQqQQKUSqgSZ9r0y5yDFy75oAAAAASUVORK5CYII=","1223":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAArSURBVChTY6AhqN//Hy+GA2ySyJgoRSBMI4UggE0SGcMBNklkTBSo3/8fAEDxhk3Jnoq8AAAAAElFTkSuQmCC","1224":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxgSoH7/fzjGC4hWONgBAwMAdaINbzTcu4MAAAAASUVORK5CYII=","1225":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxgSoH7/fzjGC4hWONgBAwMAdaINbzTcu4MAAAAASUVORK5CYII=","1229":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAtSURBVChTY2Co3/8fjhnqoTQ2MFQVYsNoHFRJZIzGQZVExlgFsWGsghh4/38A4uCh6EwqJeMAAAAASUVORK5CYII=","1230":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTjcmhEQAACAMxNmc0RisOFUHvYr5VPXlhFEZhFEZhFEZhFEa56TyTBQa621v2YrLVAAAAAElFTkSuQmCC","1231":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABISURBVChTlY7BCQAgDAOzeUdzNEVraYz1oXAQkqMIWOtPYJxpUKaYFELwdTEzDcolcsH434JdqKT9VTCH6GfPkcl+h4olzwcMns7K8R/JrX0AAAAASUVORK5CYII=","1232":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA5SURBVChTYyAK1O//D2URAGCFEAI/hivEh0lSCMFYJLFhrILImHQ3ItyAKokuDgcwRXDFSKB+/38AbLmdbsz70z0AAAAASUVORK5CYII=","1233":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA3SURBVChTY2Co3/+fAR2AxNAxVoBdYT2QIAqj64RKYIpjCNBNIUyCMEbTCcNgSRggRiGYXf8fABprrRny0bqHAAAAAElFTkSuQmCC","1234":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAhSURBVChTY2BgqP9PHAYR9fvx41GFeDFcITKGSyDj+v8AL/bFuClhkjcAAAAASUVORK5CYII=","1235":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVChTY2BgqP9PHAYR9fsJY+oohFsLwoQUwtmEFCIAOQrBEugYDoAc7CagA2IUMjAAAHT9n6tSdoLbAAAAAElFTkSuQmCC","1236":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcixDQAACMOwfs5pnAYPeGgkL0nf7FU4hVM4hVM4hVM4pSt57DSzEdlMDxoAAAAASUVORK5CYII=","1237":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTY2Co3/8fjHEBuDztFBLCWAWxYayC2DBWQWwYwcABaKRw/38AVuiPQVdeMFEAAAAASUVORK5CYII=","1238":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA4SURBVChTfclBCgAgCEVBb+7RPJpBbYyGFg9lfkRW7yLPnU0jyogyouwafhHVeDTOHygjyoiPVS8VM9PlMktgAQAAAABJRU5ErkJggg==","1239":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhMoH7/fzAmCAZQIZ0AAwMATEAR6aJJabEAAAAASUVORK5CYII=","1240":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA4SURBVChTjctBDgBABENRN3c0RzNh1U7+guQtWkRk9ckXfKl2eQPfBEuCJcGSYEmwHDOWNSg7rH4MxtMm6WHRUgAAAABJRU5ErkJggg==","1243":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAwSURBVChTY2BgqP/PUL+fMB5ohegYLIEhDtOBJEhQIYyNLAYTRxGEsZHFaKRw/38ATCfH9Q5rlUgAAAAASUVORK5CYII=","1244":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTYyAe1O//TxTGKogNYxXEhrEKYsNYBbFhrILYMFZBbJhgEKEAbApgGAwYGADIobwFoGtjMwAAAABJRU5ErkJggg==","1248":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAiSURBVChTY2Co3/+fKIxVEBvGKogNYxXEhtE4ePCwAQwMAKqLarK8FWkwAAAAAElFTkSuQmCC","1249":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAjSURBVChTY2Co3/+fKIxVEBvGKogNYxXEhrEKYsPDBzAwAAAmEm/rR8cEJQAAAABJRU5ErkJggg==","1253":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZSURBVChTYyAP1O//D8d4AdEKRwEKYGAAAEiuDW8QcSu7AAAAAElFTkSuQmCC","1254":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhyoH7/fzjGC4hWOBgBAwMA1GsNb8i2m3kAAAAASUVORK5CYII=","1255":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzjGC4hWONgAAwMAnrMNb48d9E8AAAAASUVORK5CYII=","1256":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZSURBVChTY6AM1O//D8d4AdEKRwEYMDAAAN0vDW+6LvgwAAAAAElFTkSuQmCC","1259":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZSURBVChTYxgF5IH6/f9RME5AtEIUwMAAANpSEemkBsnnAAAAAElFTkSuQmCC","1260":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA6SURBVChTY2Co3/+fKIxFAJWPEMcQwIXRFOLCWAWxYayC2DBWQWwYqyA2DAYoAkAfIvPh4kQp3P8fAB4W1KQU8gU1AAAAAElFTkSuQmCC","1261":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZSURBVChTYxgF+EH9/v8oGCcgWiFRgIEBAIgwEeksAOtaAAAAAElFTkSuQmCC","1263":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAxSURBVChTjcqxDQAwCANBb85oGS0RDdUhxdI1D0md+4VRGIVRGIVRGIVRZjq2dXxIHiRxxPn9SsZ9AAAAAElFTkSuQmCC","1267":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA5SURBVChTbcrBCcAwEMTA69ylpTQH5yEUrAG9dudnPfsKNTrU6FCjQ40ONTrU6FCjQ43uUqfTZ+YFhz+n4HcmWjgAAAAASUVORK5CYII=","1268":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAcSURBVChTYyAN1O//TxCPKsSJ4QCbJAjDAQMDAD7PrFrVNnQgAAAAAElFTkSuQmCC","1269":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAwSURBVChTjcqxEQAwCAMxb85oGQ0qqFTEd2oeknr9hVEYhVEYhVEYhVFuOi6OD8kAq/rJc30dKzMAAAAASUVORK5CYII=","1270":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA5SURBVChTYyAK1O//D2URAGCFEAI/hivEh0lSCMFYJLFhrILImHQ3ItyAKokuDgcwRXDFSKB+/38AbLmdbsz70z0AAAAASUVORK5CYII=","1271":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAArSURBVChTnchBCQAACAAxmxvNaFpggniwz8WvrF5xCqdwCqdwCqdwyqmsHnJhrpfnm2h7AAAAAElFTkSuQmCC","1272":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAArSURBVChTY6AhqN//Hy+GA2ySyJgoRSBMI4UggE0SGcMBNklkTBSo3/8fAEDxhk3Jnoq8AAAAAElFTkSuQmCC","1273":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAzSURBVChTjcixDQAwDAJBNvdoHi0pEeILI33B6b7Zdwogv70gv70gvx2QQqQQKUSqgSZ9r0y5yDFy75oAAAAASUVORK5CYII=","1274":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAaSURBVChTYxgsoH7/fyiLAAApJFrxkAUMDABiZga4OZudRwAAAABJRU5ErkJggg==","1277":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAzSURBVChTjcqxDQAgDANBb85ojBYEVYpDiqVrPknWrhFGYRRGYRRGYZQ3Hbr509330JcceH/JcztPYcYAAAAASUVORK5CYII=","1286":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1289":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAvSURBVChTxcqxDQAgEIDA39zRHE1DYwO9l9Axz9onk5pIaiKpiaQmkppIaqLfZi6gXV4DAnWt7QAAAABJRU5ErkJggg==","1292":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1293":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAgSURBVChTYyAd1O//jxVjBUQpggGiFIHAUFBIGWBgAAAO0SzFK7tPfgAAAABJRU5ErkJggg==","1294":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAArSURBVChTrcgxDQAACASxd440pIGBDgxc0uWS6jnhFE7hFE7hFE7hlOeSBZt3sxFuoDEfAAAAAElFTkSuQmCC","1302":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTjcqxDQAgDANBb57RGA0EXaIrsHTNy0mt/YVRGIVRGIVRGIVRGKc2Ha635ACWBNSkIvWfbAAAAABJRU5ErkJggg==","1304":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1305":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1306":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1307":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVChTYyAf1O//D8Y4AUwBOsYA2BSBMAbApgiEMQA2RSCMAbApAmEMgE0RCNMIMDAAAGbGVQ8RDFXPAAAAAElFTkSuQmCC","1308":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1310":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1311":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1312":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1320":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1322":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAbSURBVChTYwCD+v3/8WIMQFABDIxMhZQDBgYAPxxQlRw08ogAAAAASUVORK5CYII=","1324":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA3SURBVChTjYmxDQAgDMP6Oaf1tDJ0wcVCDJZiJ2JlfaHRGEL4QXy3Q3y3Qwi/Q15oNDQaGi+yNgp41uE3ZVpxAAAAAElFTkSuQmCC","1326":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAUSURBVChTY2Co3/8fjEfBYAIMDAAWBQR71PfdMAAAAABJRU5ErkJggg==","1328":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAeSURBVChTY2BgqP9PHAYR9fvx41GFeDFcIUFc/x8AHw3E+bIVr9gAAAAASUVORK5CYII=","1329":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA7SURBVChTjdDLCQAgDATRdJ7SLM1PRPDwQANzmZ1TYl/2yGbW9owOFWsQlIJSUApKQSlm6eHm65cVRQy4sNDpPZ3VtgAAAABJRU5ErkJggg==","1338":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1339":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhsoH7/fzAmCIhWOCQBAwMAckAI9bXV6bgAAAAASUVORK5CYII=","1340":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1341":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1342":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1343":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1344":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1345":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1347":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1348":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1351":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTjcqxDQAgDANBb57RGA0EXaIrsHTNy0mt/YVRGIVRGIVRGIVRGKc2Ha635ACWBNSkIvWfbAAAAABJRU5ErkJggg==","1353":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1367":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAvSURBVChTzcqxDcAwAITA3zyjeTRH1DCAka5jr/Sdm1RNUDVB1QRVE1RNUDVh2w/6nl4Dwe09NgAAAABJRU5ErkJggg==","1377":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxgsoH7/fxSME1Bf4WAEDAwAmE8a3fzcP4QAAAAASUVORK5CYII=","1378":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1381":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1383":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1398":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAgSURBVChTYxheoH7/f6IwVkFsGKsgNoxVEBsmDjAwAADHpFmJZ2ioqwAAAABJRU5ErkJggg==","1399":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxisoH7/fzjGC4hWOKQAAwMAJEcNb7pKATUAAAAASUVORK5CYII=","1401":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1404":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA6SURBVChTY2Co3/+fKAwl8GMUhTCd6BirQpgJMIxXIYjGJoZVEJsYhiAyxqkQG8ZQiA/DFRLE+/8DALqWwf08RQSGAAAAAElFTkSuQmCC","1407":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/pk4A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgAAAAACAQEBAQEBAgAAAAACAQMDAwMBAgAAAAACAQMDAwMBAgAAAAACAQMDAwMBAgAAAAACAQMDAwMBAgAAAAACAQEBAQEBAgAAAAACAgIBAQICAgAAAAAAAAIBAQIAAAAAAA==","1410":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/pk4A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgAAAAACAQEBAQEBAgAAAAICAQMDAwMBAgAAAAEBAQMDAwMBAgAAAAEBAQMDAwMBAgAAAAICAQMDAwMBAgAAAAACAQEBAQEBAgAAAAACAgIBAQICAgAAAAAAAAIBAQIAAAAAAA==","1411":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/pk4A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgAAAAACAQEBAQEBAgAAAAICAQMDAwMBAgIAAAEBAQMDAwMBAQEAAAEBAQMDAwMBAQEAAAICAQMDAwMBAgIAAAACAQEBAQEBAgAAAAACAgIBAQICAgAAAAAAAAIBAQIAAAAAAA==","1412":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/pk4A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIBAQIAAAAAAAACAgIBAQICAgAAAAACAQEBAQEBAgAAAAICAQMDAwMBAgIAAAEBAQMDAwMBAQEAAAEBAQMDAwMBAQEAAAICAQMDAwMBAgIAAAACAQEBAQEBAgAAAAACAgIBAQICAgAAAAAAAAIBAQIAAAAAAA==","1413":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/pk4A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgAAAAACAQEBAQEBAgAAAAACAQMDAwMBAgAAAAACAQMDAwMBAgAAAAACAQMDAwMBAgAAAAACAQMDAwMBAgAAAAACAQEBAQEBAgAAAAACAgICAgICAgAAAAAAAAAAAAAAAAAAAA==","1414":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","1415":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAB/AAD/v3//v3//v3+/fwC/fwD/v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","1416":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","1417":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","1418":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAB/AAD/v3//v3//v3+/fwC/fwD/v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79/v38Av38Av38Av38Av38Av38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","1419":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","1420":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAB/AAD/v3//v3//v3+/fwC/fwD/v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38A////////////////v38A/79/fwAAAAB/AAD/v3+/fwD///////////////+/fwD/v39/AAAAAH8AAP+/f79/AP///////////////79/AP+/f38AAAAAfwAA/79/v38A////////////////v38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","1421":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADEDgAAxA4AAAAAAAAAAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAB/AAD/v3//v3//v3+/fwC/fwD/v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38A////////////////v38A/79/fwAAAAB/AAD/v3+/fwD///////////////+/fwD/v39/AAAAAH8AAP+/f79/AP///////////////79/AP+/f38AAAAAfwAA/79/v38A////////////////v38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","1422":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38A////////////////v38A/79/fwAAAAC/fwC/fwC/fwD///////////////+/fwD/v39/AAAAAL9/AL9/AL9/AP///////////////79/AP+/f38AAAAA/79//79/v38A////////////////v38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","1423":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38A////////////////v38A/79//79/AAC/fwC/fwC/fwD///////////////+/fwC/fwC/fwAAAL9/AL9/AL9/AP///////////////79/AL9/AL9/AAAA/79//79/v38A////////////////v38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","1424":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAB/AAD/v3//v3//v3+/fwC/fwD/v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAA/79//79/v38A////////////////v38A/79//79/AAC/fwC/fwC/fwD///////////////+/fwC/fwC/fwAAAL9/AL9/AL9/AP///////////////79/AL9/AL9/AAAA/79//79/v38A////////////////v38A/79//79/AAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f79/AL9/AP+/f/+/f/+/f38AAAAAfwAAfwAAfwAA/79/v38Av38A/79/fwAAfwAAfwAAAAA=","1425":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/pk4A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAgICAgICAgAAAAACAQEBAQEBAgAAAAACAQMDAwMBAgAAAAACAQMDAwMBAgAAAAACAQMDAwMBAgAAAAACAQMDAwMBAgAAAAACAQEBAQEBAgAAAAACAgICAgICAgAAAAAAAAAAAAAAAAAAAA==","1426":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAAAA/79//79//79//79//79//79//79//79//79//79/AAC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwC/fwAAAL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AL9/AAAA/79//79//79//79/v38Av38A/79//79//79//79/AAB/AAB/AAB/AAD/v3+/fwC/fwD/v39/AAB/AAB/AAAAAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","1427":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAAAAAAIBAQIAAAAAAAICAgIBAQICAgIAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAICAgIBAQICAgIAAAAAAAIBAQIAAAAAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAA==","1428":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAH8/AAC/fwAA/79/AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAMBAQMABAQAAAQEAAMCAgMABAQAAAQEAAMBAQMABAQAAAQEAAMCAgMABAQAAAQEAAMBAQMABAQAAAQEAAMCAgMABAQAAAQEAAMBAQMABAQAAAQEAAMCAgMABAQAAAQEAAMCAgMABAQAAAQEAAEBAQEABAQAAA==","1430":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAP+/fwD///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICAgICAgICAgIAAAICAgICAgICAgIAAAICAgICAgICAgIAAAICAgICAgICAgIAAAICAgICAgICAgIAAAICAgICAgICAgIAAAICAgICAgICAgIAAAICAgICAgICAgIAAAICAAAAAAAAAgIAAAICAAEBAQEAAgIAAA==","1431":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAD///////9/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","1432":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAAIBAQIAAwMAAAMDAAABAQAAAwMAAAMDAwABAQADAwMAAAMDAwABAQADAwMAAAMDAAABAQAAAwMAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAAMDAAIBAQIAAwMAAA==","1433":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAA////////////////////////////////////////AAD///////////////////////////////////////8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAH8AAP///////wAA/79//79//79//79//79//79//79/fwAA////////AAC/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAD///////8AAL9/AL9/AL9/AL9/AL9/AL9/AP+/f38AAP///////wAA/79//79//79//79/v38Av38A/79/fwAA////////AAB/AAB/AAB/AAD/v3+/fwC/fwD/v39/AAD///////8AAP///////38AAP+/f79/AL9/AP+/f38AAP///////wAA////////fwAA/79/v38Av38A/79/fwAA////////AAA=","1434":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA1SURBVChTncrBCQAgEAPB69zSLE1/YeUWEQf2ldSfMVfrYAcWNrKwkYWNLGxkYSNrnk5XVRtyIIHT23ufhQAAAABJRU5ErkJggg==","1435":"data:image/bmp;base64,Qk12AQAAAAAAADYAAAAoAAAACgAAAAoAAAABABgAAAAAAEABAADDDgAAww4AAAAAAAAAAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAB/AAD/v3//v3//v3//v3//v3//v3//v3//v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f79/AL9/AL9/AL9/AL9/AL9/AP+/f38AAAAAfwAA/79/v38Av38Av38Av38Av38Av38A/79/fwAAAAB/AAD/v3+/fwC/fwC/fwC/fwC/fwC/fwD/v39/AAAAAH8AAP+/f/+/f/+/f/+/f/+/f/+/f/+/f/+/f38AAAAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAfwAAAAA=","1437":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1438":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxjyoH7/fzAmCIhWOBgAAwMAu24I9RojsOgAAAAASUVORK5CYII=","1446":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAlSURBVChTY0AF9f8Z6vdDMIiNGwwRhSgYLyBKERDAraYtYGAAAGjgMr0oY257AAAAAElFTkSuQmCC","1447":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxgsoH7/fxSME1Bf4WAEDAwAmE8a3fzcP4QAAAAASUVORK5CYII=","1448":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxgsoH7/fxSMEwygQjoCBgYAluYj0YhFZHsAAAAASUVORK5CYII=","1449":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAsSURBVChTYxisoH7/fygLBwApQMcYAJsiEIYDbJLImChFIEy8QmyCGHj/fwDGkGtxAe30jQAAAABJRU5ErkJggg==","1450":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZSURBVChTY8AK6vf/h2O8gPoKRwEYMDAAAOgOFCYaPeRDAAAAAElFTkSuQmCC","1451":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhIUL//P5RFAAygwgECDAwAyBUI9WzGitkAAAAASUVORK5CYII=","1452":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhIUL//P5RFAAygwgECDAwAyBUI9WzGitkAAAAASUVORK5CYII=","1453":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhIUL//P5RFAAygwgECDAwAyBUI9WzGitkAAAAASUVORK5CYII=","1454":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhIUL//P5RFAAygwgECDAwAyBUI9WzGitkAAAAASUVORK5CYII=","1455":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAXSURBVChTY6ARqN//nyAeMgoHADAwAACtWmS6ArUvtAAAAABJRU5ErkJggg==","1456":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAXSURBVChTY6ARqN//nyAeMgoHADAwAACtWmS6ArUvtAAAAABJRU5ErkJggg==","1457":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAXSURBVChTY6ABqN//nyAeMgoHCDAwAABAXGS6irdT8QAAAABJRU5ErkJggg==","1458":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAXSURBVChTY6ABqN//nyAeMgoHCDAwAABAXGS6irdT8QAAAABJRU5ErkJggg==","1459":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1460":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1461":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1462":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1463":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1464":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1465":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1466":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxjyoH7/fzAmCIhWOBgAAwMAu24I9RojsOgAAAAASUVORK5CYII=","1468":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZSURBVChTY0AB9fv/o2CcgGiFo4A8wMAAAMWFEen+31v0AAAAAElFTkSuQmCC","1469":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1470":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAzSURBVChTjcmxCQAgFEPBbO5ojqZg8UlxhYFrXpK1zxdGYRRGYRRGYZQ3HW2ms810tiQXdn/SZ/pKvOkAAAAASUVORK5CYII=","1471":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1472":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAUSURBVChTYxgF9Ab1+/8Txvv/AwC8URZjDrlzMgAAAABJRU5ErkJggg==","1473":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAcSURBVChTYxgFlIP6/f+hLDwApIigQpii+v3/AaxpDW+kj07EAAAAAElFTkSuQmCC","1474":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAdSURBVChTYxgF+EH9/v9QFgEAUkiUYphCvIoZGABIXw1v6Fv0EAAAAABJRU5ErkJggg==","1481":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAApSURBVChTY2Co3/+fKIxVEBvGKogNYxXEhrEKYsPYBbEB6iukLmBgAAAwmZF+/lB5agAAAABJRU5ErkJggg==","1482":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAtSURBVChTY2Co3/8fAzPUY/JRBJAl0PlwQYguPHjIA6I9A1QADyK8AKZw/38AwPpJ3l6cuTsAAAAASUVORK5CYII=","1486":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA3SURBVChTY0CA+v/YMQYACtbvR8UUKAQJ4FIIwzCF6IqQMYpCfIoRCkEAi0KYARgKsWLaAAYGAJ0Aba6qv6RiAAAAAElFTkSuQmCC","1512":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAiSURBVChTYyAR1P/Hj+EAyKnfjx0Pb4V4MTYANwmZzcAAABNKg1FNh5pyAAAAAElFTkSuQmCC","1513":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTlcmxCQAxFIDQv3lGy2iXTiwkXB5YOW/W/q6hpkNNh5oONR1qOtR0qOn+mzlW6I9BE7bLuAAAAABJRU5ErkJggg==","1514":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVChTYyAf1O//D8Y4AUwBOsYA2BSBMAbApgiEMQA2RSCMAbApAmEMgE0RCNMIMDAAAGbGVQ8RDFXPAAAAAElFTkSuQmCC","1515":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAhSURBVChTY4CA+v8M9fuxY5AcAowUhSCMADSxGi9mYAAA+kqgakSl3/0AAAAASUVORK5CYII=","1520":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhSoH7/fzAmCIhWOFgBAwMAbo0I9cM4hAQAAAAASUVORK5CYII=","1523":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxgSoH7/fzAmCIhWONgBAwMAti0I9aoN6EsAAAAASUVORK5CYII=","1525":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTY2Co3/8fK8YA2BSBMAbApgiEMQA2RSCMAbApAmEMQJQiEBjsChkYAAdRexyScPBfAAAAAElFTkSuQmCC","1526":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA5SURBVChTjcrBCQAwCATB69zSUloEQTnDPrIwn1Mpzv2CI8GR4EhwfFV0cBMd3URHt6KHtqKHVkkJUqzCvNZIuR4AAAAASUVORK5CYII=","1527":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAwSURBVChTY2Co3/+fIAYDbBLomI4KsQJsCmEYBWBTAMMoAJsCGEYB2BTAMOmAgQEAWWiaclvez+EAAAAASUVORK5CYII=","1528":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA2SURBVChTY0AB9fv/Y2AMgE0RDMMBNklkTJQiGMYqiA1jFcSGsQpiw1gFsWGiPIQBcCpiYAAA7925yBGQa2wAAAAASUVORK5CYII=","1529":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1530":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1531":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVChTY2Co3/+fKIxVEBvGKogNgwE2CXRMI4UggE0SGcMBNklkjAGwKQJhnABF4f7/AHEuucjULyfwAAAAAElFTkSuQmCC","1532":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1533":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1534":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1535":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1536":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1537":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1538":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1539":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTjcjBCQAgDATB6zylWVr0I/gYgo+BZZNUj2rdPvGDUziFUziFUziFU54YVG//ydMmMlZF7QAAAABJRU5ErkJggg==","1540":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYyAd1O//j4GxggFUOOQBAwMAbWosxU2/QzUAAAAASUVORK5CYII=","1541":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhyoH7/fzjGC6ivkI6AgQEAoM4UJkM3TwEAAAAASUVORK5CYII=","1542":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTlcmxCQAxFIDQv3lGy2iXTiwkXB5YOW/W/q6hpkNNh5oONR1qOtR0qOn+mzlW6I9BE7bLuAAAAABJRU5ErkJggg==","1543":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTlcmxCQAxFIDQv3lGy2iXTiwkXB5YOW/W/q6hpkNNh5oONR1qOtR0qOn+mzlW6I9BE7bLuAAAAABJRU5ErkJggg==","1544":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTlcmxCQAxFIDQv3lGy2iXTiwkXB5YOW/W/q6hpkNNh5oONR1qOtR0qOn+mzlW6I9BE7bLuAAAAABJRU5ErkJggg==","1545":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAXSURBVChTYyAe1O//D8d4wahCygEDAwDRyTW5dT3fEAAAAABJRU5ErkJggg==","1546":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAXSURBVChTYyAe1O//D8d4wahCygEDAwDRyTW5dT3fEAAAAABJRU5ErkJggg==","1547":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxhyoH7/fzjGC6ivkI6AgQEAoM4UJkM3TwEAAAAASUVORK5CYII=","1548":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTlcmxCQAxFIDQv3lGy2iXTiwkXB5YOW/W/q6hpkNNh5oONR1qOtR0qOn+mzlW6I9BE7bLuAAAAABJRU5ErkJggg==","1549":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTlcmxCQAxFIDQv3lGy2iXTiwkXB5YOW/W/q6hpkNNh5oONR1qOtR0qOn+mzlW6I9BE7bLuAAAAABJRU5ErkJggg==","1550":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1553":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVChTlcqxDQAgEIDA39zRHE1DYwONl9Axz9onk5pIaiKpiaQmkppIaiKpiaQm+jNzASfueN/G2YMUAAAAAElFTkSuQmCC","1554":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1555":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1556":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzAmCIhWONgAAwMAJu0I9SG53x0AAAAASUVORK5CYII=","1557":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAuSURBVChTY4CD+v3/sWIMgE0RCGMAbIpAGANgUwTCGACbIhDGANgUgfCQAQwMACKCUJULO+w9AAAAAElFTkSuQmCC","1558":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1559":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAhSURBVChTYxhMoH7/fygLDwApgmG8gChFMEC0QjoBBgYA2RQPrNxQ8mAAAAAASUVORK5CYII=","1560":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA2SURBVChTY0AF9f8xMQqACtbvx8QIxTgUIGOI4qGgEATwKEYoAgEQB4diVIUwANWAgkGAgQEA8LWnITGRWvQAAAAASUVORK5CYII=","1563":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA0SURBVChTlcqxDQAgEIDA39zRHE1DYwONl9Axz9onk5pIaiKpiaQmkppIaiKpiaQm+jNzASfueN/G2YMUAAAAAElFTkSuQmCC","1564":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA8SURBVChTY0AF9f8Z6vdDMIgNxigAKghThIwRinEoQMYQxUNBIQjgUYxQBAIgDg7FqAphAKoBBYMAAwMANlaon8pLQKoAAAAASUVORK5CYII=","1565":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA3SURBVChTY0AF9f8Z6vdDMIgNxigAqyAUwMVxKUAGYDVDQSEKAwtAkQNxcCnGKg7TgIxBgIEBAI17K0farsc3AAAAAElFTkSuQmCC","1566":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAVSURBVChTYxgF+EH9/v8omE6AgQEA/G8I9bd9mioAAAAASUVORK5CYII=","1569":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzjGC4hWONgAAwMAnrMNb48d9E8AAAAASUVORK5CYII=","1570":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxiSoH7/fzjGC4hWONgAAwMAnrMNb48d9E8AAAAASUVORK5CYII=","1571":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAXSURBVChTYxgFNAL1+/+DMUGAVSEDAwBqQwj10WRavgAAAABJRU5ErkJggg==","1574":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/u3kA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwAAAAADAwMAAAMDAAICAgIAAwMAAAMAAgEBAQECAAMAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAACAQEBAQEBAgAAAAMAAgEBAQECAAMAAAMDAAIBAQIAAwMAAA==","1575":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAA6SURBVChTYyAO1P+HMvABoKL6/YQUQhXhV4ikCLdCNEXYFWJRhKkQhyIQRgA8ikCYKEUgTJSi+v3/AdBJc6asVsIrAAAAAElFTkSuQmCC","1576":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABDSURBVChTjY4BCgAgCMT8uU/raYVnosIVDgZhC5OObtHl2hk27jCiasaPoOrxNGQXTDpkzleDT5yRgc9OwqDE8RiIHLmUrRm+5OcYAAAAAElFTkSuQmCC","1577":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABDSURBVChTlY0LCgAgCMW8uUfraIU/9EWFDQaVkwjhSTxMOauAP0ZUzfgSVC3uhqfB7l/Y/lp5xBkJcrnEGAa+AApEC4Nmqh3/63oRAAAAAElFTkSuQmCC","1582":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxjyoH7/fzAmCIhWOBgAAwMAu24I9RojsOgAAAAASUVORK5CYII=","1583":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1584":"data:image/bmp;base64,Qk2uBAAAAAAAADYEAAAoAAAACgAAAAoAAAABAAgAAAAAAHgAAADDDgAAww4AAAAAAAAAAAAAfwAAAL9/AAD/v38A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwAAAAAAAwMAAAMAAAICAgICAAMAAAAAAgEBAQECAAMAAAICAQEBAQEBAgAAAAEBAQEBAQEBAQEAAAEBAQEBAQEBAQEAAAIBAQEBAQEBAgAAAAACAgEBAQEBAgAAAAMAAAIBAQICAAMAAAMDAwABAQAAAwMAAA==","1586":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYSURBVChTYxjeoH7/fzjGC4hWSCfAwAAAd/cNbwv2e0AAAAAASUVORK5CYII=","1587":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAVSURBVChTYxgF+EH9/v9gTGfAwAAAEPQEe2i5XnQAAAAASUVORK5CYII=","1588":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAVSURBVChTYxgF9Ab1+/+DMV7AwAAAocIEewrNWSQAAAAASUVORK5CYII=","1589":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAySURBVChTjcqxDQAgDANBb57RGA0EXaIrsHTNy0mt/YVRGIVRGIVRGIVRGKc2Ha635ACWBNSkIvWfbAAAAABJRU5ErkJggg==","1590":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAqSURBVChTjcghAQAACAMwmhONaCcAE4iZVfXkhSlMYQpTmMIUpjCFeUwWpuLf1aKwjJQAAAAASUVORK5CYII=","1591":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAeSURBVChTY2BgqP9PHAYR9fvx41GFeDFcIUFc/x8AHw3E+bIVr9gAAAAASUVORK5CYII="} \ No newline at end of file diff --git a/static/index.html b/static/index.html index c5724333..066658b7 100644 --- a/static/index.html +++ b/static/index.html @@ -1,18 +1,130 @@ + - - - - Mosswart Overlord v2 - - - - - - - - - -
    - + + + Dereth Tracker + + + + + + + + + +
    + + +
    + + +
    +
    + Dereth map + + +
    +
    +
    +
    +
    +
    + + + + diff --git a/static/inventory.html b/static/inventory.html index a69d73ff..ad23112e 100644 --- a/static/inventory.html +++ b/static/inventory.html @@ -281,25 +281,6 @@ user-select: none; } - .results-table th .th-label { - cursor: pointer; - } - - .results-table th .th-hide { - display: inline-block; - margin-left: 3px; - color: #999; - cursor: pointer; - font-size: 10px; - font-weight: normal; - line-height: 1; - vertical-align: middle; - } - - .results-table th .th-hide:hover { - color: #c00; - } - /* Resizable column handle */ .results-table th .resize-handle { position: absolute; @@ -557,34 +538,12 @@ Pants Only - -
    -
    - - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    - - -
    -
    Item Properties
    -
    -
    - - -
    -
    - - - - - -
    -
    - - - - - -
    -
    -
    -
    - - - - - -
    -
    - - -
    -
    -
    - - -
    -
    Item State & Spell Search
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    @@ -1109,6 +985,7 @@ +
    @@ -1157,10 +1034,21 @@
    - -
    - - -
    -
    - - -
    diff --git a/static/suitbuilder.js b/static/suitbuilder.js index f523134b..2954443d 100644 --- a/static/suitbuilder.js +++ b/static/suitbuilder.js @@ -29,8 +29,6 @@ const COMMON_CANTRIPS = [ 'Legendary Creature Enchantment Aptitude', 'Legendary Item Enchantment Aptitude', 'Legendary Life Magic Aptitude', - 'Legendary Healing Prowess', - 'Legendary Summoning Prowess', // Defense 'Legendary Magic Resistance', 'Legendary Invulnerability', diff --git a/static/sw.js b/static/sw.js deleted file mode 100644 index 71839ee5..00000000 --- a/static/sw.js +++ /dev/null @@ -1,72 +0,0 @@ -// Service worker for MosswartOverlord v2 β€” caches static assets for instant repeat loads -const CACHE_NAME = 'mo-v2-cache-v1'; -const STATIC_ASSETS = [ - '/dereth.png', - '/dereth_highres.png', - '/prismatic-taper-icon.png', - '/icons/0600127E.png', - '/icons/06000133.png', - '/icons/06001080.png', -]; - -self.addEventListener('install', (event) => { - event.waitUntil( - caches.open(CACHE_NAME).then(cache => cache.addAll(STATIC_ASSETS)) - ); - self.skipWaiting(); -}); - -self.addEventListener('activate', (event) => { - event.waitUntil( - caches.keys().then(keys => - Promise.all(keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k))) - ) - ); - self.clients.claim(); -}); - -self.addEventListener('fetch', (event) => { - const url = new URL(event.request.url); - - // Cache icon images on first fetch - if (url.pathname.startsWith('/icons/') && event.request.method === 'GET') { - event.respondWith( - caches.match(event.request).then(cached => { - if (cached) return cached; - return fetch(event.request).then(response => { - if (response.ok) { - const clone = response.clone(); - caches.open(CACHE_NAME).then(cache => cache.put(event.request, clone)); - } - return response; - }); - }) - ); - return; - } - - // Cache dungeon_tiles.json (large, rarely changes) - if (url.pathname === '/dungeon_tiles.json') { - event.respondWith( - caches.match(event.request).then(cached => { - if (cached) return cached; - return fetch(event.request).then(response => { - if (response.ok) { - const clone = response.clone(); - caches.open(CACHE_NAME).then(cache => cache.put(event.request, clone)); - } - return response; - }); - }) - ); - return; - } - - // Cache static assets (map images etc) - if (STATIC_ASSETS.some(a => url.pathname === a)) { - event.respondWith( - caches.match(event.request).then(cached => cached || fetch(event.request)) - ); - return; - } -});