/ concept-collection / turing-surface-cache
Sign in
concept-collection / turing-surface-cache
turing-surface-cache / index.html
174 lines · 7.8 KBBlameHistoryRaw
1<!doctype html>
2<html lang="en">
3 <head>
4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1" />
6 <link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><circle cx=%2250%22 cy=%2250%22 r=%2245%22 fill=%22%232a5f7f%22/><circle cx=%2235%22 cy=%2238%22 r=%2211%22 fill=%22%23f5d547%22/><circle cx=%2265%22 cy=%2258%22 r=%229%22 fill=%22%23f5d547%22/><circle cx=%2248%22 cy=%2274%22 r=%227%22 fill=%22%23f5d547%22/><circle cx=%2268%22 cy=%2230%22 r=%226%22 fill=%22%23f5d547%22/></svg>" />
7 <title>turing-surface-cache — reaction-diffusion solutions from a shared cloud cache</title>
8 <style>
9 :root {
10 --bg: #ffffff;
11 --ink: #1f2328;
12 --ink-2: #57606a;
13 --line: #d0d7de;
14 --accent: #0969da;
15 --ok: #1a7f37;
16 --sphere-bg: #f4f6f8;
17 color-scheme: light dark;
18 }
19 @media (prefers-color-scheme: dark) {
20 :root {
21 --bg: #14171a;
22 --ink: #e6e9ec;
23 --ink-2: #9aa4af;
24 --line: #333b44;
25 --accent: #58a6ff;
26 --ok: #3fb950;
27 --sphere-bg: #14161c;
28 }
29 }
30 body {
31 margin: 0;
32 background: var(--bg);
33 color: var(--ink);
34 font: 15px/1.5 system-ui, -apple-system, sans-serif;
35 }
36 main { max-width: 1100px; margin: 0 auto; padding: 20px 16px 48px; }
37 h1 { font-size: 20px; margin: 0 0 2px; }
38 .sub { color: var(--ink-2); margin: 0 0 12px; font-size: 13px; }
39 .sub a { color: var(--accent); }
40 .controls {
41 display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center;
42 padding: 6px 0;
43 }
44 .controls[hidden] { display: none; }
45 .controls label { color: var(--ink-2); font-size: 13px; white-space: nowrap; }
46 select, input[type="password"], button {
47 font: inherit; font-size: 13px;
48 color: var(--ink); background: var(--bg);
49 border: 1px solid var(--line); border-radius: 6px;
50 padding: 4px 8px;
51 }
52 button { cursor: pointer; }
53 button:hover { border-color: var(--accent); }
54 button.primary { border-color: var(--accent); color: var(--accent); font-weight: 600; min-width: 8em; }
55 button:disabled { opacity: 0.5; cursor: default; }
56 #cachenote { font-size: 13px; color: var(--ink-2); }
57 #cachenote b { color: var(--ok); font-weight: 600; }
58 #status { margin-top: 10px; font-size: 13.5px; }
59 #status b { font-weight: 600; }
60 #panels { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 12px; }
61 .panel {
62 flex: 1 1 320px; min-width: 280px;
63 border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
64 display: flex;
65 }
66 .sphere-box { flex: 1; aspect-ratio: 1 / 1; max-height: 70vh; position: relative; }
67 .species-tag {
68 position: absolute; top: 8px; left: 10px; z-index: 2;
69 font-size: 15px; font-weight: 600; color: #fff;
70 background: rgba(0, 0, 0, 0.45);
71 padding: 1px 10px; border-radius: 12px;
72 pointer-events: none;
73 }
74 .colorbar {
75 display: flex; flex-direction: column; align-items: center; justify-content: center;
76 gap: 4px; padding: 8px 4px; background: var(--sphere-bg);
77 width: 52px; flex: none; box-sizing: border-box;
78 }
79 .colorbar canvas { border: 1px solid var(--line); border-radius: 2px; }
80 .colorbar-label { font-size: 11px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
81 .stats { margin-top: 10px; font-size: 13px; color: var(--ink-2); font-variant-numeric: tabular-nums; }
82 .stats b { color: var(--ink); font-weight: 600; }
83 .cloud {
84 margin-top: 14px; border: 1px solid var(--line); border-radius: 8px;
85 padding: 8px 12px; font-size: 13px; color: var(--ink-2);
86 }
87 .cloud .controls { padding: 2px 0 0; }
88 /* The same walk, spelled as a command for a machine with no browser on
89 it. The key is masked here and real in the clipboard, so the command
90 is paste-and-go without the key ending up in a screenshot. */
91 #clicmd {
92 font: 12.5px/1.6 ui-monospace, SFMono-Regular, Menlo, monospace;
93 color: var(--ink); background: var(--sphere-bg);
94 border: 1px solid var(--line); border-radius: 6px;
95 padding: 3px 8px; max-width: 100%;
96 overflow-x: auto; white-space: nowrap;
97 }
98 #clicopied { color: var(--ok); }
99 #err { color: #b35900; white-space: pre-wrap; font-size: 13px; }
100 </style>
101 </head>
102 <body>
103 <main>
104 <h1>turing-surface-cache</h1>
105 <p class="sub">
106 Reaction-diffusion (Turing patterns) on curved surfaces, evaluated at a
107 chosen end time. Every setting is a choice from a short list, so each
108 combination names one exact solution. Solutions already in the shared
109 cloud cache load by themselves as you browse the choices; a
110 combination no one has computed shows empty surfaces until you press
111 <b>Compute solution</b>, which runs it here (with WebGPU, via
112 <a href="https://github.com/concept-collection/turing-surface">turing-surface</a>'s
113 spectral solver). Drag to rotate.
114 </p>
115 <div class="controls">
116 <label title="The reaction-diffusion system being solved">model
117 <select id="model"></select>
118 </label>
119 <span id="params" class="controls" style="padding: 0"></span>
120 </div>
121 <div class="controls">
122 <label title="The surface the pattern is solved on">geometry
123 <select id="geometry"></select>
124 </label>
125 <span id="geomparams" class="controls" style="padding: 0"></span>
126 </div>
127 <div class="controls">
128 <label title="Which random initial perturbation to start from">seed
129 <select id="seed"></select>
130 </label>
131 <label title="The solution is reported at this simulation time">end time
132 <select id="tend"></select>
133 </label>
134 <button id="solve" class="primary"
135 title="Compute the selected solution in your browser. Cached solutions load by themselves as you change the selection.">Compute solution</button>
136 <button id="stop" hidden>Stop</button>
137 <button id="reset" title="Set every selection back to its default">Reset to defaults</button>
138 <span id="cachenote"></span>
139 </div>
140 <p id="status"></p>
141 <div id="panels"></div>
142 <div class="controls">
143 <button id="resetview">Reset view</button>
144 <a id="download" hidden download>Download .h5</a>
145 </div>
146 <p class="stats" id="stats"></p>
147 <div class="cloud">
148 <span>Solutions computed here can be contributed back to the shared
149 cache, so the next visitor gets them instantly. Contributing
150 requires an upload API key.</span>
151 <div class="controls">
152 <label>upload API key
153 <input id="apikey" type="password" autocomplete="off" placeholder="(optional)" />
154 </label>
155 <span id="uploadnote"></span>
156 </div>
157 <div class="controls" id="autobar" hidden>
158 <button id="auto"
159 title="Work through the parameter space on this machine, nearest the defaults first, computing and uploading whatever is not cached yet. Runs until stopped.">Auto-fill the cache</button>
160 <span id="autonote"></span>
161 </div>
162 <div class="controls" id="clibar" hidden>
163 <span>or on a machine with no browser on it:</span>
164 <code id="clicmd"></code>
165 <button id="clicopy"
166 title="Copies the command with your key in it. The key is masked here so that it stays out of screenshots.">Copy command (includes your key)</button>
167 <span id="clicopied"></span>
168 </div>
169 </div>
170 <p id="err"></p>
171 </main>
172 <script type="module" src="/src/main.ts"></script>
173 </body>
174</html>
moveopenescclose