112 lines
6.7 KiB
HTML
112 lines
6.7 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Colony</title>
|
|
<script>
|
|
/* The Android app asks for ?theme=dark: a WebView reports the theme of its host app, not the phone's setting. */
|
|
const theme = new URLSearchParams(location.search).get("theme");
|
|
if (theme === "dark" || theme === "light") document.documentElement.dataset.theme = theme;
|
|
</script>
|
|
<link rel="stylesheet" href="/static/style.css">
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<div class="headline">
|
|
<h1>Colony</h1>
|
|
<p id="summary" class="summary">Loading...</p>
|
|
<div id="bell-wrap" class="bell-wrap" hidden>
|
|
<button id="bell" type="button" class="bell" aria-expanded="false" aria-controls="inbox-panel" aria-label="Messages" title="Messages">
|
|
<svg viewBox="0 0 20 20" aria-hidden="true"><path d="M5 14V9a5 5 0 0 1 10 0v5l1.5 1.5h-13zM8.2 17.5a2 2 0 0 0 3.6 0"/></svg>
|
|
<span id="bell-count" class="bell-count" hidden></span>
|
|
</button>
|
|
<div id="toasts" class="toasts" aria-live="polite"></div>
|
|
<section id="inbox-panel" class="inbox-panel" aria-labelledby="inbox-title" hidden>
|
|
<div class="inbox-head">
|
|
<h2 id="inbox-title">Messages</h2>
|
|
<button id="inbox-read" type="button">Mark all read</button>
|
|
</div>
|
|
<ol id="inbox-list" class="inbox-list"></ol>
|
|
<p id="inbox-empty" class="inbox-empty muted" hidden>No messages yet.</p>
|
|
<button id="notify" type="button" class="notify" hidden>Turn on desktop notifications</button>
|
|
</section>
|
|
</div>
|
|
</div>
|
|
<div id="alerts" class="alerts"></div>
|
|
<p id="error" class="error" hidden></p>
|
|
<p id="viewpoint" class="route-line"></p>
|
|
<p id="ondemand" class="muted"></p>
|
|
</header>
|
|
|
|
<main id="stage">
|
|
<svg id="map" class="lod2" role="group" aria-labelledby="map-title" aria-describedby="map-help">
|
|
<title id="map-title">Map of the networks, the nodes in them, and the gateways that connect them</title>
|
|
<desc id="map-help">Tab to a node, arrow keys move between nodes, Enter pins it. Plus and minus zoom, 0 fits everything, n cycles networks, Alt with arrows moves the focused item, Escape releases.</desc>
|
|
<defs>
|
|
<marker id="arrow-0" class="arrow n0" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0 L10 5 L0 10 z"/></marker>
|
|
<marker id="arrow-1" class="arrow n1" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0 L10 5 L0 10 z"/></marker>
|
|
<marker id="arrow-2" class="arrow n2" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0 L10 5 L0 10 z"/></marker>
|
|
<marker id="arrow-3" class="arrow n3" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0 L10 5 L0 10 z"/></marker>
|
|
<marker id="arrow-4" class="arrow n4" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0 L10 5 L0 10 z"/></marker>
|
|
<marker id="arrow-5" class="arrow n5" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0 0 L10 5 L0 10 z"/></marker>
|
|
</defs>
|
|
<g id="world">
|
|
<g id="layer-spokes"></g>
|
|
<g id="layer-regions"></g>
|
|
<g id="layer-ports"></g>
|
|
<g id="layer-ends"></g>
|
|
<g id="layer-legs"></g>
|
|
<g id="layer-nodes"></g>
|
|
</g>
|
|
</svg>
|
|
|
|
<div class="controls" role="group" aria-label="Map view">
|
|
<button id="reset" type="button" class="text" hidden title="Forget the arrangement you made and lay the map out again">Reset layout</button>
|
|
<button id="zoom-in" type="button" aria-label="Zoom in" title="Zoom in (+)"><svg viewBox="0 0 20 20" aria-hidden="true"><path d="M10 4v12M4 10h12"/></svg></button>
|
|
<button id="zoom-out" type="button" aria-label="Zoom out" title="Zoom out (-)"><svg viewBox="0 0 20 20" aria-hidden="true"><path d="M4 10h12"/></svg></button>
|
|
<button id="fit" type="button" aria-label="Fit everything" title="Fit everything (0)"><svg viewBox="0 0 20 20" aria-hidden="true"><path d="M3 7V3h4M13 3h4v4M17 13v4h-4M7 17H3v-4"/></svg></button>
|
|
</div>
|
|
|
|
<div id="legend" class="legend">
|
|
<button id="legend-close" type="button" aria-label="Hide the legend" title="Hide the legend"><svg viewBox="0 0 20 20" aria-hidden="true"><path d="M5 5l10 10M15 5L5 15"/></svg></button>
|
|
<ul>
|
|
<li><span class="swatch network"></span>network, each in its own colour</li>
|
|
<li><span class="swatch node"></span>node</li>
|
|
<li><span class="swatch gateway"></span>gateway, on the edge of its network</li>
|
|
<li><span class="swatch flow"></span>route through a gateway</li>
|
|
<li><span class="swatch none"></span>no recent contact (not the same as unreachable)</li>
|
|
</ul>
|
|
<p>Drag the background to move, wheel or pinch to zoom. Drag a node, a gateway or a network's title to rearrange.</p>
|
|
</div>
|
|
<button id="legend-open" type="button" class="legend-open" aria-label="Show the legend" title="Show the legend" hidden>?</button>
|
|
<p id="updated" class="muted stamp"></p>
|
|
|
|
<aside id="chat" class="chat" aria-labelledby="chat-title" hidden>
|
|
<div class="chat-head">
|
|
<h2 id="chat-title"></h2>
|
|
<button id="chat-ignore" type="button" class="chat-ignore" aria-pressed="false" hidden>Ignore</button>
|
|
<button id="chat-close" type="button" aria-label="Close the chat" title="Close the chat (Escape)"><svg viewBox="0 0 20 20" aria-hidden="true"><path d="M5 5l10 10M15 5L5 15"/></svg></button>
|
|
</div>
|
|
<p id="chat-status" class="chat-status" hidden></p>
|
|
<ol id="chat-log" class="chat-log" role="log" aria-label="Messages" tabindex="0"></ol>
|
|
<p id="chat-empty" class="chat-empty muted" hidden>No messages yet.</p>
|
|
<p id="chat-error" class="error chat-error" role="alert" hidden></p>
|
|
<form id="chat-form" class="chat-form">
|
|
<label for="chat-input" class="sr-only">Message</label>
|
|
<input id="chat-input" type="text" maxlength="4000" autocomplete="off" placeholder="Message">
|
|
<button id="chat-send" type="submit">Send</button>
|
|
</form>
|
|
</aside>
|
|
</main>
|
|
<div id="chat-live" class="sr-only" aria-live="polite"></div>
|
|
|
|
<div id="live" class="sr-only" role="status" aria-live="polite"></div>
|
|
<ul id="reader" class="sr-only" aria-label="Networks and their nodes"></ul>
|
|
<script src="/static/model.js"></script>
|
|
<script src="/static/layout.js"></script>
|
|
<script src="/static/viewport.js"></script>
|
|
<script src="/static/app.js"></script>
|
|
</body>
|
|
</html>
|