whispering-fractal-veins-3z8n/exploration.html

73 lines
No EOL
7.7 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Whispering Fractal Veins — exploration</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #0a0a0f; color: #3a3a4a; font-family: ui-monospace, monospace; overflow: hidden; }
#grid { padding: 20px; font-size: 12px; line-height: 1.4; white-space: pre; }
.c { display: inline-block; transition: all 0.3s; }
.c.active { color: #fde68a; text-shadow: 0 0 6px rgba(253,230,138,0.5); }
.c.strong { color: #34d399; text-shadow: 0 0 10px rgba(52,211,153,0.6); font-weight: bold; }
.c.dead { color: #1a1a2a; }
#info { position: fixed; bottom: 10px; left: 20px; color: #3a3a4a; font-size: 11px; }
#controls { position: fixed; top: 10px; right: 20px; color: #666; font-size: 11px; }
#controls span { cursor: pointer; margin-left: 12px; color: #fde68a; }
</style>
</head>
<body>
<div id="grid"></div>
<div id="info">neurameba · physarum exploration</div>
<div id="controls"><span id="play-btn">play</span><span id="reset-btn">reset</span></div>
<script>
const text = "# Telegram Bridge\n\nConnect your motd account to Telegram. Receive bookmarked content on your phone. Message motd users from Telegram.\n\n---\n\n## Connect Your Account\n\nIn the motd terminal:\n\n```\n> /connect telegram\n\nConnect Telegram:\n\n https://t.me/motdsocial_bot?start=yourname_a8f3k2\n\n Click the link. Tap Start in Telegram. Done.\n```\n\nClick the link. It opens Telegram with the motd bot. Tap Start. Your accounts are linked.\n\nThe link expires after 10 minutes. Type `/connect telegram` again for a fresh one.\n\n## Disconnect\n\n```\n> /disconnect telegram\n\n✓ Telegram disconnected.\n```\n\n---\n\n## Messaging from Telegram\n\n### Send a message to a motd user\n\nIn Telegram, message the bot:\n\n```\n/msg mika hey, saw your project — looks great\n```\n\nThe message appears as a public post in the motd feed with the `[telegram]` tag.\n\nIf you have a connected motd account, it's posted under your motd username. If not, it shows as `telegram:yourname`.\n\n### Rate limits\n\n- Non-motd Telegram users: 5 messages per hour\n- Connected motd users: 30 messages per hour\n- Same 500 character limit as motd\n\n---\n\n## Receiving on Telegram\n\nWhen your Telegram is connected, the bot forwards:\n\n- New posts from users you bookmarked\n- New posts matching tags you bookmarked\n- Replies to your posts\n- Posts that @mention you\n\n**Not forwarded:**\n- The entire feed\n- Posts from killed/filtered users\n- Posts from users with high filter scores\n\n### Replying from Telegram\n\nReply to a forwarded message in Telegram (using Telegram's reply feature) and it creates a threaded reply on motd.\n\n---\n\n## Notification Settings\n\nIn `/settings`, connected users see:\n\n```\nTelegram notifications: on\n Notify on: bookmarked users/tags, mentions/replies\n```\n\nToggle each notification type on or off.\n\n---\n\n## Bot Commands\n\nIn Telegram:\n\n| Command | What it does |\n|---------|-------------|\n| `/start` | Welcome message |\n| `/msg [user] [message]` | Message a motd user |\n| `/feed` | Last 5 posts from your bookmarks |\n| `/help` | Show commands |\n\n---\n\n## Notes\n\n- Only text posts bridge between motd and Telegram. Media is not forwarded.\n- Posts from Telegram follow the normal 30-day lifecycle.\n- The `[telegram]` tag is auto-added to all bridge posts. You can bookmark or kill it.\n- Your kill list applies to Telegram — filtered users won't appear in your Telegram notifications.\n";
const passes = [{"t":0,"r":28,"c":0,"a":"died","s":0,"ps":8,"e":100,"pr":1},{"t":0,"r":23,"c":0,"a":"died","s":0,"ps":8,"e":100,"pr":1},{"t":0,"r":20,"c":11,"a":"extend","s":0.3911976748471942,"ps":9,"e":71.24570697914429,"pr":1.1},{"t":0,"r":24,"c":2,"a":"hold","s":0.19605680003087445,"ps":9,"e":100.218454400247,"pr":1.1},{"t":0,"r":68,"c":30,"a":"hold","s":0.22686515197104895,"ps":9,"e":100.46492121576838,"pr":1.1},{"t":1,"r":20,"c":11,"a":"extend","s":0.3674102749230988,"ps":8,"e":51.08949242497035,"pr":1.05},{"t":1,"r":24,"c":2,"a":"hold","s":0.20819780672123422,"ps":8,"e":100.68403685401687,"pr":1.05},{"t":1,"r":68,"c":30,"a":"hold","s":0.2799421485904893,"ps":9,"e":101.3544584044923,"pr":1.1},{"t":1,"r":20,"c":12,"a":"hold","s":0.2563739769710335,"ps":5,"e":31.83486623540153,"pr":1.2000000000000002},{"t":2,"r":20,"c":11,"a":"extend","s":0.3911976748471942,"ps":7,"e":37.218351676623534,"pr":1},{"t":2,"r":24,"c":2,"a":"retracted","s":0.1911181715645417,"ps":7,"e":101.1629822265332,"pr":1},{"t":2,"r":68,"c":30,"a":"retracted","s":0.2799421485904893,"ps":8,"e":102.39399559321622,"pr":1.05},{"t":2,"r":20,"c":12,"a":"hold","s":0.26400902010173866,"ps":4,"e":33.34693839621544,"pr":1.1500000000000001},{"t":2,"r":20,"c":10,"a":"hold","s":0.11649991599023861,"ps":5,"e":22.07749608148063,"pr":1.1500000000000001},{"t":3,"r":20,"c":11,"a":"extend","s":0.4050785570279987,"ps":7,"e":27.586286092993266,"pr":1},{"t":3,"r":20,"c":12,"a":"retracted","s":0.24653459321350477,"ps":4,"e":34.71921514192348,"pr":1.1},{"t":3,"r":20,"c":10,"a":"hold","s":0.1965953628587594,"ps":5,"e":22.900258984350703,"pr":1.1500000000000001},{"t":4,"r":20,"c":11,"a":"extend","s":0.4050785570279987,"ps":6,"e":20.948840184452077,"pr":0.95},{"t":4,"r":20,"c":10,"a":"retracted","s":0.19399907696118046,"ps":4,"e":23.852251600040148,"pr":1.1},{"t":5,"r":20,"c":11,"a":"hold","s":0.2998105536217799,"ps":6,"e":22.447324613426318,"pr":0.95},{"t":5,"r":20,"c":12,"a":"hold","s":0.19098939651592062,"ps":5,"e":9.75598953689254,"pr":1.05},{"t":6,"r":20,"c":11,"a":"hold","s":0.2998105536217799,"ps":5,"e":24.095809042400557,"pr":0.8999999999999999},{"t":6,"r":20,"c":12,"a":"hold","s":0.2807245083969484,"ps":5,"e":11.251785604068129,"pr":1.05},{"t":7,"r":20,"c":11,"a":"retracted","s":0.2637156939312262,"ps":6,"e":25.305534593850368,"pr":0.9999999999999999},{"t":7,"r":20,"c":12,"a":"retracted","s":0.2807245083969484,"ps":4,"e":12.897581671243715,"pr":1}];
const lines = text.split('\n');
const gridEl = document.getElementById('grid');
const charEls = [];
for (let r = 0; r < lines.length; r++) {
const row = [];
for (let c = 0; c < lines[r].length; c++) {
const s = document.createElement('span');
s.className = 'c';
s.textContent = lines[r][c];
row.push(s);
gridEl.appendChild(s);
}
charEls.push(row);
gridEl.appendChild(document.createTextNode('\n'));
}
let tick = -1, playing = false, iv;
function apply(t) {
for (const r of charEls) for (const e of r) e.className = 'c';
const active = new Map();
for (const p of passes) {
if (p.t > t) break;
const k = p.r+','+p.c;
if (p.a === 'died' || p.a === 'retracted') active.set(k, 'dead');
else if (p.ps > 16) active.set(k, 'strong');
else active.set(k, 'active');
}
for (const [k, cls] of active) {
const [r, c] = k.split(',').map(Number);
if (charEls[r]?.[c]) charEls[r][c].className = 'c ' + cls;
}
document.getElementById('info').textContent = 'tick ' + t + ' · ' + [...active.values()].filter(v=>v!=='dead').length + ' alive';
}
function play() {
if (playing) return;
playing = true;
document.getElementById('play-btn').textContent = 'pause';
const max = passes.length > 0 ? passes[passes.length-1].t : 0;
iv = setInterval(() => { tick++; if (tick > max) { pause(); return; } apply(tick); }, 900);
}
function pause() { playing = false; clearInterval(iv); document.getElementById('play-btn').textContent = 'play'; }
function reset() { pause(); tick = -1; for (const r of charEls) for (const e of r) e.className = 'c'; document.getElementById('info').textContent = 'neurameba'; }
document.getElementById('play-btn').addEventListener('click', () => playing ? pause() : play());
document.getElementById('reset-btn').addEventListener('click', reset);
setTimeout(play, 1000);
</script>
</body>
</html>