Compare commits
No commits in common. "output" and "main" have entirely different histories.
13 changed files with 827 additions and 2 deletions
62
.github/workflows/demon.yml
vendored
Normal file
62
.github/workflows/demon.yml
vendored
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
name: Maxwell's Demon
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types: [opened]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: demon-state
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
sort:
|
||||||
|
if: "startsWith(github.event.issue.title, 'demon: sort 12 bits')"
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Sort 12 bits into the lattice
|
||||||
|
run: |
|
||||||
|
python3 - <<'EOF'
|
||||||
|
import datetime
|
||||||
|
import json
|
||||||
|
|
||||||
|
path = "state/demon.json"
|
||||||
|
with open(path) as fh:
|
||||||
|
state = json.load(fh)
|
||||||
|
state["bits_sorted"] += 12
|
||||||
|
state["generation"] += 1
|
||||||
|
state["demons"] += 1
|
||||||
|
state["last_sorted_at"] = datetime.datetime.now(
|
||||||
|
datetime.timezone.utc
|
||||||
|
).isoformat(timespec="seconds")
|
||||||
|
with open(path, "w") as fh:
|
||||||
|
json.dump(state, fh, indent=2)
|
||||||
|
fh.write("\n")
|
||||||
|
EOF
|
||||||
|
python3 engine/generate_entropy_svg.py
|
||||||
|
|
||||||
|
- name: Commit lowered entropy
|
||||||
|
env:
|
||||||
|
AUTHOR: ${{ github.event.issue.user.login }}
|
||||||
|
run: |
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "41898470+github-actions[bot]@users.noreply.github.com"
|
||||||
|
git add state/demon.json assets/entropy.svg
|
||||||
|
git commit -m "chore: demon sorted 12 bits (S lowered by @${AUTHOR})"
|
||||||
|
git pull --rebase origin "${GITHUB_REF_NAME}"
|
||||||
|
git push
|
||||||
|
|
||||||
|
- name: Thank the demon and close the gate
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ github.token }}
|
||||||
|
ISSUE: ${{ github.event.issue.number }}
|
||||||
|
run: |
|
||||||
|
gh issue comment "$ISSUE" --repo "$GITHUB_REPOSITORY" --body \
|
||||||
|
"12 bits sorted. Entropy of this README decreased by 34.4 zJ (12 × kT ln 2 at 300 K). The second law remains statistical. Thank you, demon."
|
||||||
|
gh issue edit "$ISSUE" --repo "$GITHUB_REPOSITORY" --add-label demon
|
||||||
|
gh issue close "$ISSUE" --repo "$GITHUB_REPOSITORY"
|
||||||
37
.github/workflows/nightly.yml
vendored
Normal file
37
.github/workflows/nightly.yml
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
name: Nightly Telemetry
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "17 6 * * *"
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: demon-state
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
refresh:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Refresh feed, stats, featured cards, entropy field
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ github.token }}
|
||||||
|
run: python3 engine/nightly.py
|
||||||
|
|
||||||
|
- name: Commit if changed
|
||||||
|
run: |
|
||||||
|
if git diff --quiet; then
|
||||||
|
echo "no changes"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
git config user.name "github-actions[bot]"
|
||||||
|
git config user.email "41898470+github-actions[bot]@users.noreply.github.com"
|
||||||
|
git add README.md state/demon.json assets/entropy.svg
|
||||||
|
git commit -m "chore: nightly telemetry refresh"
|
||||||
|
git pull --rebase origin "${GITHUB_REF_NAME}"
|
||||||
|
git push
|
||||||
31
.github/workflows/snake.yml
vendored
Normal file
31
.github/workflows/snake.yml
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
name: Generate Snake
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
# Runs every 12 hours
|
||||||
|
- cron: "0 */12 * * *"
|
||||||
|
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
generate:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Generate Snake
|
||||||
|
uses: Platane/snk/svg-only@v3
|
||||||
|
with:
|
||||||
|
github_user_name: developtheweb
|
||||||
|
outputs: |
|
||||||
|
dist/github-contribution-grid-snake.svg
|
||||||
|
dist/github-contribution-grid-snake-dark.svg?palette=github-dark
|
||||||
|
|
||||||
|
- name: Push to output branch
|
||||||
|
uses: crazy-max/ghaction-github-pages@v4
|
||||||
|
with:
|
||||||
|
target_branch: output
|
||||||
|
build_dir: dist
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
.DS_Store
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
36
CLAUDE.md
Normal file
36
CLAUDE.md
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||||
|
|
||||||
|
## Repository Overview
|
||||||
|
|
||||||
|
This is the GitHub profile repository for @developtheweb. Its README renders on the profile page and is a live system, not a static page: an animated entropy-reversal SVG whose state is lowered by visitors ("Maxwell's demon"), plus nightly-refreshed telemetry. Do not reintroduce third-party rendering services (capsule-render, readme-typing-svg, komarev, vercel stats/quotes apps) — everything renders from this repo, GitHub, or stevenmilanese.com assets.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
```
|
||||||
|
README.md profile page; contains marker-fenced generated sections
|
||||||
|
engine/generate_entropy_svg.py SMIL-animated assets/entropy.svg from state/demon.json (stdlib only)
|
||||||
|
engine/nightly.py refreshes README marker sections + bumps entropy generation (stdlib only)
|
||||||
|
state/demon.json bits_sorted / generation / demons / last_sorted_at
|
||||||
|
assets/entropy.svg generated — never hand-edit; regenerate via the engine
|
||||||
|
.github/workflows/demon.yml issues:opened, title "demon: sort 12 bits" → +12 bits, regen SVG, commit, comment, close
|
||||||
|
.github/workflows/nightly.yml cron 17 6 * * * → engine/nightly.py, commit if changed
|
||||||
|
.github/workflows/snake.yml cron every 12h → contribution snake SVGs on the `output` branch
|
||||||
|
```
|
||||||
|
|
||||||
|
## README marker sections (machine-written — edit the generators, not the sections)
|
||||||
|
|
||||||
|
- `<!-- FEED:START/END -->` — 4 newest Strange Quarks articles (RSS `/feed.xml` if populated, else parsed from https://stevenmilanese.com/blog HTML)
|
||||||
|
- `<!-- STATS:START/END -->` — telemetry row with live star/repo totals
|
||||||
|
- `<!-- FEATURED:START/END -->` — featured cards (anthropic-certs, slTrain, meowchi-releases, mpl) with live star counts
|
||||||
|
|
||||||
|
`engine/nightly.py` is fail-safe per section: on fetch/parse failure it leaves that section untouched and exits 0.
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- Conventional commit messages (`feat:`, `fix:`, `chore:`, `ci:`). No attribution footers of any kind.
|
||||||
|
- Contact is `rev@moonfactory.dev` only — the old Telegram link and the old level-host email address are retired and must not reappear.
|
||||||
|
- Entropy formula: `S = max(12.7, 100 − 0.0002·bits_sorted)`; 12 bits per demon click = 34.4 zJ (12 × kT ln 2 at 300 K).
|
||||||
|
- SVG regeneration is deterministic for a given `generation` — diffs stay reviewable.
|
||||||
|
- Test locally with `python3 engine/generate_entropy_svg.py` and `GITHUB_TOKEN=$(gh auth token) python3 engine/nightly.py` (both stdlib-only; no pip installs).
|
||||||
142
README.md
Normal file
142
README.md
Normal file
|
|
@ -0,0 +1,142 @@
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
# Reversing the irreversible
|
||||||
|
|
||||||
|
*Rev. Steven Milanese — the second law is statistical, not sacred. The demon pays its bills in bits.*
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<img src="assets/entropy.svg" width="100%" alt="Entropy-reversal field: particles converging from chaos into a (2,5) torus-knot lattice"/>
|
||||||
|
|
||||||
|
[⚡ Be the demon — sort 12 bits](https://github.com/developtheweb/developtheweb/issues/new?title=demon%3A+sort+12+bits&body=One+tap.+Submit+to+sort.)
|
||||||
|
|
||||||
|
<sub>Each click opens a one-tap issue; an Action sorts the field, recommits the SVG, closes the issue. This README's state is community-lowered entropy.</sub>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## About the Reverend
|
||||||
|
|
||||||
|
```
|
||||||
|
Reverend ≔ Physicist ⊗ Minister ⊗ Systems_Alchemist
|
||||||
|
domain : ℝ³·¹ ⊗ CY₃(χ = ±6)
|
||||||
|
axiom : complexity ⟼ elegance
|
||||||
|
method : ∀ p ∈ Inconceivable — solve(p) ∨ pose(better_p)
|
||||||
|
runtime : Arch Linux, btw
|
||||||
|
```
|
||||||
|
|
||||||
|
*Written in MPL — the author's own language. Ordained minister, autodidactic polymath, natural philosopher. The ministry and the physics are the same inquiry conducted at different energy scales.*
|
||||||
|
|
||||||
|
## The mission — goals inconceivable by design
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td width="50%" valign="top">
|
||||||
|
|
||||||
|
**Reverse the irreversible**
|
||||||
|
|
||||||
|
Maxwell's demon on GitHub's own infrastructure, funded in Landauer's currency. *(running above)*
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td width="50%" valign="top">
|
||||||
|
|
||||||
|
**Derive the three generations**
|
||||||
|
|
||||||
|
Calabi–Yau compactifications, χ = ±6. [ORCID](https://orcid.org/0009-0008-0442-208X) · [OSF](https://osf.io/3tsd4/) · [companion essays](https://stevenmilanese.com/blog/tag/calabi-yau-manifolds)
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="50%" valign="top">
|
||||||
|
|
||||||
|
**Cognitive universality**
|
||||||
|
|
||||||
|
[MPL](https://github.com/developtheweb/mpl): if you can write the equation, you can run it.
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td width="50%" valign="top">
|
||||||
|
|
||||||
|
**Planetary intelligence**
|
||||||
|
|
||||||
|
Earth as information processor, argued in full on [Strange Quarks](https://stevenmilanese.com/blog/planetary-intelligence-earth-as-information-processor).
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- STATS:START -->
|
||||||
|
<div align="center">
|
||||||
|
|
||||||
|
`10¹⁰⁶ yr until heat death — the deadline` · `2.9 zJ of order per bit sorted (kT ln 2, 300 K)` · `★ 27 stars across 14 public repos`
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- STATS:END -->
|
||||||
|
|
||||||
|
## Beneath the physics — the verified inventory
|
||||||
|
|
||||||
|
<!-- FEATURED:START -->
|
||||||
|
<div align="center">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td width="50%" valign="top">
|
||||||
|
<h3 align="center"><a href="https://github.com/developtheweb/anthropic-certs">anthropic-certs</a></h3>
|
||||||
|
<p align="center"><code>★ 11</code></p>
|
||||||
|
<p align="center">Verified Anthropic certifications — Claude, API, Claude Code CLI, MCP.</p>
|
||||||
|
</td>
|
||||||
|
<td width="50%" valign="top">
|
||||||
|
<h3 align="center"><a href="https://github.com/developtheweb/slTrain">slTrain</a></h3>
|
||||||
|
<p align="center"><code>★ 4</code></p>
|
||||||
|
<p align="center">A steam locomotive for your terminal, smoke trail included.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td width="50%" valign="top">
|
||||||
|
<h3 align="center"><a href="https://github.com/developtheweb/meowchi-releases">meowchi-releases</a></h3>
|
||||||
|
<p align="center"><code>★ 4</code></p>
|
||||||
|
<p align="center">A desktop pet that evolves when you actually get work done.</p>
|
||||||
|
</td>
|
||||||
|
<td width="50%" valign="top">
|
||||||
|
<h3 align="center"><a href="https://github.com/developtheweb/mpl">mpl</a></h3>
|
||||||
|
<p align="center"><code>★ 2</code></p>
|
||||||
|
<p align="center">Mathematics Programming Language — write the equation, run the equation.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<!-- FEATURED:END -->
|
||||||
|
|
||||||
|
## Latest from Strange Quarks
|
||||||
|
|
||||||
|
<!-- FEED:START -->
|
||||||
|
| Article | |
|
||||||
|
|:---|---:|
|
||||||
|
| [THE MAJORITY THAT VOTED FOR HEMLOCK - Plato's Republic, Exegesis and Judgment](https://stevenmilanese.com/blog/the-majority-that-voted-for-hemlock-platos-republic-exegesis-and-judgment) | Sep 15, 2026 · 204 min read |
|
||||||
|
| [What Survives the Reset](https://stevenmilanese.com/blog/what-survives-the-reset) | Aug 31, 2026 · 12 min read |
|
||||||
|
| [The Invisible Hand's Blind Spot: A Demand Externality in Competitive Automation](https://stevenmilanese.com/blog/the-invisible-hands-blind-spot-a-demand-externality-in-competitive-automation) | Aug 19, 2026 · 61 min read |
|
||||||
|
| [Mathematical Programming Language: A Vision for Cognitive Universality Through Unicode-Based Syntax](https://stevenmilanese.com/blog/mathematical-programming-language-a-vision-for-cognitive-universality-through-unicode-based-syntax) | Jul 28, 2025 · 19 min read |
|
||||||
|
<!-- FEED:END -->
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<br>
|
||||||
|
<picture>
|
||||||
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/developtheweb/developtheweb/output/github-contribution-grid-snake-dark.svg" />
|
||||||
|
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/developtheweb/developtheweb/output/github-contribution-grid-snake.svg" />
|
||||||
|
<img alt="Snake animation" src="https://raw.githubusercontent.com/developtheweb/developtheweb/output/github-contribution-grid-snake.svg" />
|
||||||
|
</picture>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<table width="100%">
|
||||||
|
<tr>
|
||||||
|
<td align="left">
|
||||||
|
|
||||||
|
*Founder, [MoonFactory](https://moonfactory.dev) — development and consulting.*
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td align="right">
|
||||||
|
|
||||||
|
[stevenmilanese.com](https://stevenmilanese.com) · [Strange Quarks](https://stevenmilanese.com/blog) · [X](https://x.com/developtheweb) · [LinkedIn](https://www.linkedin.com/in/stevenmilanese/) · [ORCID](https://orcid.org/0009-0008-0442-208X) · [OSF](https://osf.io/3tsd4/) · [rev@moonfactory.dev](mailto:rev@moonfactory.dev)
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
126
assets/entropy.svg
Normal file
126
assets/entropy.svg
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="880" height="260" viewBox="0 0 880 260" role="img" aria-label="Entropy-reversal field: S = 100.0 k-bits">
|
||||||
|
<rect x="0.5" y="0.5" width="879" height="259" rx="8" fill="#010409" stroke="#21262d"/>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="854.4" cy="239.9"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="854.4;612.1;612.1;854.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="239.9;130.0;130.0;239.9"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="844.9" cy="58.7"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="844.9;609.3;609.3;844.9"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="58.7;141.8;141.8;58.7"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="655.0" cy="239.4"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="655.0;601.4;601.4;655.0"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="239.4;152.7;152.7;239.4"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="408.5" cy="65.3"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="408.5;588.9;588.9;408.5"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="65.3;162.2;162.2;65.3"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="275.9" cy="216.9"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="275.9;572.9;572.9;275.9"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="216.9;169.7;169.7;216.9"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="778.5" cy="232.3"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="778.5;554.8;554.8;778.5"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="232.3;175.0;175.0;232.3"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="822.0" cy="34.8"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="822.0;535.8;535.8;822.0"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="34.8;178.1;178.1;34.8"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="273.3" cy="175.7"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="273.3;517.3;517.3;273.3"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="175.7;179.3;179.3;175.7"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="688.2" cy="139.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="688.2;500.2;500.2;688.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="139.5;179.1;179.1;139.5"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="166.9" cy="121.1"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="166.9;485.4;485.4;166.9"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="121.1;178.1;178.1;121.1"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="782.6" cy="133.8"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="782.6;472.9;472.9;782.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="133.8;177.2;177.2;133.8"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="748.5" cy="228.8"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="748.5;462.6;462.6;748.5"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="228.8;176.9;176.9;228.8"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="174.8" cy="72.3"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="174.8;454.0;454.0;174.8"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="72.3;177.8;177.8;72.3"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="766.7" cy="146.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="766.7;446.2;446.2;766.7"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="146.2;180.2;180.2;146.2"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="857.5" cy="84.3"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="857.5;438.1;438.1;857.5"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="84.3;184.2;184.2;84.3"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="728.9" cy="39.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="728.9;429.0;429.0;728.9"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="39.5;189.5;189.5;39.5"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="519.2" cy="124.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="519.2;417.8;417.8;519.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="124.6;195.7;195.7;124.6"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="465.2" cy="154.9"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="465.2;404.3;404.3;465.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="154.9;202.1;202.1;154.9"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="507.7" cy="58.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="507.7;388.2;388.2;507.7"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="58.2;207.9;207.9;58.2"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="618.8" cy="120.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="618.8;369.9;369.9;618.8"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="120.2;212.3;212.3;120.2"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="164.4" cy="69.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="164.4;350.2;350.2;164.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="69.5;214.6;214.6;69.5"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="619.4" cy="40.1"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="619.4;330.1;330.1;619.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="40.1;214.4;214.4;40.1"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="664.4" cy="102.7"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="664.4;311.0;311.0;664.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="102.7;211.2;211.2;102.7"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="295.4" cy="200.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="295.4;294.2;294.2;295.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="200.5;205.2;205.2;200.5"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="520.8" cy="179.8"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="520.8;280.8;280.8;520.8"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="179.8;196.7;196.7;179.8"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="828.4" cy="71.9"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="828.4;271.9;271.9;828.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="71.9;186.2;186.2;71.9"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="114.9" cy="142.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="114.9;267.9;267.9;114.9"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="142.2;174.5;174.5;142.2"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="166.5" cy="234.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="166.5;269.0;269.0;166.5"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="234.2;162.2;162.2;234.2"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="830.8" cy="58.0"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="830.8;274.8;274.8;830.8"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="58.0;150.3;150.3;58.0"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="299.6" cy="36.7"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="299.6;284.5;284.5;299.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="36.7;139.4;139.4;36.7"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="69.5" cy="165.7"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="69.5;296.9;296.9;69.5"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="165.7;130.0;130.0;165.7"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="609.6" cy="61.8"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="609.6;310.8;310.8;609.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="61.8;122.3;122.3;61.8"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="160.6" cy="146.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="160.6;324.8;324.8;160.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="146.2;116.3;116.3;146.2"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="543.4" cy="120.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="543.4;337.7;337.7;543.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="120.5;111.6;111.6;120.5"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="567.5" cy="82.0"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="567.5;348.7;348.7;567.5"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="82.0;107.8;107.8;82.0"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="202.4" cy="116.3"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="202.4;357.3;357.3;202.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="116.3;104.4;104.4;116.3"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="505.6" cy="167.3"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="505.6;363.4;363.4;505.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="167.3;100.5;100.5;167.3"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="843.8" cy="199.9"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="843.8;367.5;367.5;843.8"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="199.9;95.7;95.7;199.9"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="460.2" cy="219.3"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="460.2;370.2;370.2;460.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="219.3;89.5;89.5;219.3"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="195.7" cy="39.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="195.7;372.6;372.6;195.7"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="39.6;81.9;81.9;39.6"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="627.2" cy="28.1"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="627.2;375.7;375.7;627.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="28.1;72.8;72.8;28.1"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="434.9" cy="32.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="434.9;380.6;380.6;434.9"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="32.5;62.7;62.7;32.5"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="95.7" cy="31.9"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="95.7;388.2;388.2;95.7"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="31.9;52.1;52.1;31.9"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="97.1" cy="75.4"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="97.1;398.8;398.8;97.1"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="75.4;41.9;41.9;75.4"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="603.5" cy="73.3"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="603.5;412.5;412.5;603.5"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="73.3;32.8;32.8;73.3"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="856.7" cy="177.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="856.7;429.0;429.0;856.7"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="177.6;25.7;25.7;177.6"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="320.8" cy="49.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="320.8;447.4;447.4;320.8"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="49.6;21.3;21.3;49.6"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="562.3" cy="222.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="562.3;466.7;466.7;562.3"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="222.6;20.0;20.0;222.6"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="771.2" cy="168.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="771.2;485.5;485.5;771.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="168.6;22.0;22.0;168.6"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="69.7" cy="215.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="69.7;502.7;502.7;69.7"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="215.2;27.3;27.3;215.2"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="580.8" cy="117.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="580.8;517.1;517.1;580.8"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="117.6;35.3;35.3;117.6"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="320.0" cy="48.4"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="320.0;527.8;527.8;320.0"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="48.4;45.6;45.6;48.4"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="283.0" cy="149.8"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="283.0;534.4;534.4;283.0"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="149.8;57.4;57.4;149.8"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="357.4" cy="30.0"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="357.4;536.9;536.9;357.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="30.0;69.7;69.7;30.0"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="507.9" cy="88.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="507.9;535.8;535.8;507.9"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="88.6;81.9;81.9;88.6"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="845.7" cy="61.9"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="845.7;531.9;531.9;845.7"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="61.9;93.2;93.2;61.9"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="235.2" cy="94.1"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="235.2;526.3;526.3;235.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="94.1;103.1;103.1;94.1"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="343.2" cy="38.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="343.2;520.2;520.2;343.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="38.5;111.6;111.6;38.5"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="842.7" cy="163.3"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="842.7;514.9;514.9;842.7"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="163.3;118.7;118.7;163.3"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="312.6" cy="136.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="312.6;511.2;511.2;312.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="136.2;124.6;124.6;136.2"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="778.2" cy="218.8"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="778.2;510.0;510.0;778.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="218.8;130.0;130.0;218.8"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="122.1" cy="118.3"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="122.1;511.2;511.2;122.1"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="118.3;135.4;135.4;118.3"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="109.3" cy="62.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="109.3;514.9;514.9;109.3"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="62.6;141.3;141.3;62.6"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="631.9" cy="141.3"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="631.9;520.2;520.2;631.9"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="141.3;148.4;148.4;141.3"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="566.7" cy="110.1"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="566.7;526.3;526.3;566.7"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="110.1;156.9;156.9;110.1"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="568.5" cy="226.0"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="568.5;531.9;531.9;568.5"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="226.0;166.8;166.8;226.0"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="800.4" cy="149.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="800.4;535.8;535.8;800.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="149.2;178.1;178.1;149.2"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="705.9" cy="188.8"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="705.9;536.9;536.9;705.9"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="188.8;190.3;190.3;188.8"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="325.3" cy="44.7"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="325.3;534.4;534.4;325.3"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="44.7;202.6;202.6;44.7"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="607.8" cy="228.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="607.8;527.8;527.8;607.8"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="228.2;214.4;214.4;228.2"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="118.5" cy="82.9"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="118.5;517.1;517.1;118.5"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="82.9;224.7;224.7;82.9"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="214.7" cy="195.1"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="214.7;502.7;502.7;214.7"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="195.1;232.7;232.7;195.1"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="640.6" cy="167.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="640.6;485.5;485.5;640.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="167.5;238.0;238.0;167.5"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="566.8" cy="177.0"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="566.8;466.7;466.7;566.8"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="177.0;240.0;240.0;177.0"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="205.2" cy="116.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="205.2;447.4;447.4;205.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="116.2;238.7;238.7;116.2"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="394.2" cy="116.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="394.2;429.0;429.0;394.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="116.5;234.3;234.3;116.5"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="511.0" cy="189.0"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="511.0;412.5;412.5;511.0"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="189.0;227.2;227.2;189.0"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="98.8" cy="87.9"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="98.8;398.8;398.8;98.8"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="87.9;218.1;218.1;87.9"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="615.3" cy="129.8"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="615.3;388.2;388.2;615.3"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="129.8;207.9;207.9;129.8"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="820.6" cy="184.9"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="820.6;380.6;380.6;820.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="184.9;197.3;197.3;184.9"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="383.7" cy="30.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="383.7;375.7;375.7;383.7"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="30.6;187.2;187.2;30.6"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="507.6" cy="166.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="507.6;372.6;372.6;507.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="166.5;178.1;178.1;166.5"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="507.2" cy="164.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="507.2;370.2;370.2;507.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="164.2;170.5;170.5;164.2"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="109.5" cy="73.3"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="109.5;367.5;367.5;109.5"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="73.3;164.3;164.3;73.3"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="571.0" cy="176.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="571.0;363.4;363.4;571.0"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="176.6;159.5;159.5;176.6"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="669.9" cy="24.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="669.9;357.3;357.3;669.9"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="24.6;155.6;155.6;24.6"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="350.1" cy="219.3"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="350.1;348.7;348.7;350.1"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="219.3;152.2;152.2;219.3"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="418.9" cy="35.7"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="418.9;337.7;337.7;418.9"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="35.7;148.4;148.4;35.7"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="214.8" cy="219.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="214.8;324.8;324.8;214.8"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="219.2;143.7;143.7;219.2"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="695.6" cy="207.4"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="695.6;310.8;310.8;695.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="207.4;137.7;137.7;207.4"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="653.6" cy="121.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="653.6;296.9;296.9;653.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="121.5;130.0;130.0;121.5"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="613.6" cy="189.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="613.6;284.5;284.5;613.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="189.5;120.6;120.6;189.5"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="37.4" cy="173.1"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="37.4;274.8;274.8;37.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="173.1;109.7;109.7;173.1"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="206.3" cy="59.8"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="206.3;269.0;269.0;206.3"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="59.8;97.8;97.8;59.8"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="682.2" cy="221.9"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="682.2;267.9;267.9;682.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="221.9;85.5;85.5;221.9"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="406.0" cy="41.4"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="406.0;271.9;271.9;406.0"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="41.4;73.8;73.8;41.4"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="468.0" cy="79.4"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="468.0;280.8;280.8;468.0"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="79.4;63.3;63.3;79.4"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="325.4" cy="156.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="325.4;294.2;294.2;325.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="156.6;54.8;54.8;156.6"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="713.8" cy="26.4"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="713.8;311.0;311.0;713.8"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="26.4;48.8;48.8;26.4"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="478.5" cy="41.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="478.5;330.1;330.1;478.5"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="41.2;45.6;45.6;41.2"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="62.5" cy="23.3"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="62.5;350.2;350.2;62.5"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="23.3;45.4;45.4;23.3"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="155.4" cy="187.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="155.4;369.9;369.9;155.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="187.6;47.7;47.7;187.6"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="752.4" cy="76.8"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="752.4;388.2;388.2;752.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="76.8;52.1;52.1;76.8"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="810.6" cy="208.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="810.6;404.3;404.3;810.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="208.2;57.9;57.9;208.2"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="517.3" cy="232.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="517.3;417.8;417.8;517.3"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="232.6;64.3;64.3;232.6"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="811.5" cy="129.1"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="811.5;429.0;429.0;811.5"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="129.1;70.5;70.5;129.1"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="761.6" cy="90.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="761.6;438.1;438.1;761.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="90.2;75.8;75.8;90.2"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="91.4" cy="110.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="91.4;446.2;446.2;91.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="110.5;79.8;79.8;110.5"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="411.6" cy="182.9"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="411.6;454.0;454.0;411.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="182.9;82.2;82.2;182.9"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="472.8" cy="92.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="472.8;462.6;462.6;472.8"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="92.5;83.1;83.1;92.5"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="311.8" cy="40.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="311.8;472.9;472.9;311.8"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="40.5;82.8;82.8;40.5"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="269.2" cy="163.7"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="269.2;485.4;485.4;269.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="163.7;81.9;81.9;163.7"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="570.1" cy="158.2"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="570.1;500.2;500.2;570.1"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="158.2;80.9;80.9;158.2"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="729.4" cy="179.7"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="729.4;517.3;517.3;729.4"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="179.7;80.7;80.7;179.7"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="197.6" cy="62.1"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="197.6;535.8;535.8;197.6"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="62.1;81.9;81.9;62.1"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="837.2" cy="56.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="837.2;554.8;554.8;837.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="56.6;85.0;85.0;56.6"/></circle>
|
||||||
|
<circle r="3" fill="#1d6f7d" cx="88.2" cy="135.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="88.2;572.9;572.9;88.2"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="135.5;90.3;90.3;135.5"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="23.7" cy="37.1"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="23.7;588.9;588.9;23.7"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="37.1;97.8;97.8;37.1"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="85.1" cy="133.6"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="85.1;601.4;601.4;85.1"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="133.6;107.3;107.3;133.6"/></circle>
|
||||||
|
<circle r="3" fill="#4dd4e8" cx="561.3" cy="70.5"><animate attributeName="cx" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="561.3;609.3;609.3;561.3"/><animate attributeName="cy" dur="11s" repeatCount="indefinite" calcMode="spline" keyTimes="0;0.64;0.82;1" keySplines="0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1" values="70.5;118.2;118.2;70.5"/></circle>
|
||||||
|
<text x="16" y="26" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="14" fill="#4dd4e8">S = 100.0 k·bits</text>
|
||||||
|
<text x="864" y="26" text-anchor="end" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="14" fill="#7ee2a8">dS/dt < 0</text>
|
||||||
|
<text x="864" y="246" text-anchor="end" font-family="ui-monospace,SFMono-Regular,Menlo,monospace" font-size="11" fill="#8b949e">bits sorted by visitors: 12</text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 52 KiB |
BIN
banner.jpeg
Normal file
BIN
banner.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
120
engine/generate_entropy_svg.py
Normal file
120
engine/generate_entropy_svg.py
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Generate assets/entropy.svg — a SMIL-animated entropy-reversal field.
|
||||||
|
|
||||||
|
120 particles loop from a seeded chaos cloud into a (2,5) torus-knot
|
||||||
|
lattice, hold, and scatter back. State (bits sorted by visitors, chaos
|
||||||
|
generation) comes from state/demon.json. Stdlib only; deterministic for
|
||||||
|
a given generation so regenerated output is diffable.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
STATE_PATH = os.path.join(ROOT, "state", "demon.json")
|
||||||
|
OUT_PATH = os.path.join(ROOT, "assets", "entropy.svg")
|
||||||
|
|
||||||
|
WIDTH, HEIGHT = 880, 260
|
||||||
|
MARGIN = 20
|
||||||
|
N_PARTICLES = 120
|
||||||
|
KNOT_R, KNOT_r = 150, 58
|
||||||
|
DUR = "11s"
|
||||||
|
KEY_TIMES = "0;0.64;0.82;1"
|
||||||
|
KEY_SPLINES = "0.25 0.1 0.25 1;0 0 1 1;0.55 0 0.45 1"
|
||||||
|
|
||||||
|
BG = "#010409"
|
||||||
|
BORDER = "#21262d"
|
||||||
|
CYAN = "#4dd4e8"
|
||||||
|
DEEP = "#1d6f7d"
|
||||||
|
GREEN = "#7ee2a8"
|
||||||
|
MUTED = "#8b949e"
|
||||||
|
|
||||||
|
|
||||||
|
def seeded_unit(index, generation, channel):
|
||||||
|
"""Deterministic float in [0, 1) from particle index + generation."""
|
||||||
|
digest = hashlib.sha256(f"{index}:{generation}:{channel}".encode()).digest()
|
||||||
|
return int.from_bytes(digest[:8], "big") / 2**64
|
||||||
|
|
||||||
|
|
||||||
|
def knot_points(n):
|
||||||
|
"""(2,5) torus knot sampled at n points, scaled/centered to the canvas."""
|
||||||
|
raw = []
|
||||||
|
for i in range(n):
|
||||||
|
t = 2 * math.pi * i / n
|
||||||
|
rad = KNOT_R + KNOT_r * math.cos(5 * t)
|
||||||
|
raw.append((rad * math.cos(2 * t), 0.62 * rad * math.sin(2 * t)))
|
||||||
|
xs, ys = [p[0] for p in raw], [p[1] for p in raw]
|
||||||
|
span_x, span_y = max(xs) - min(xs), max(ys) - min(ys)
|
||||||
|
scale = min((WIDTH - 2 * MARGIN) / span_x, (HEIGHT - 2 * MARGIN) / span_y)
|
||||||
|
cx, cy = (max(xs) + min(xs)) / 2, (max(ys) + min(ys)) / 2
|
||||||
|
return [
|
||||||
|
(WIDTH / 2 + (x - cx) * scale, HEIGHT / 2 + (y - cy) * scale)
|
||||||
|
for x, y in raw
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with open(STATE_PATH) as fh:
|
||||||
|
state = json.load(fh)
|
||||||
|
bits = int(state.get("bits_sorted", 0))
|
||||||
|
generation = int(state.get("generation", 0))
|
||||||
|
entropy = max(12.7, 100 - 0.0002 * bits)
|
||||||
|
s_label = f"{entropy:.1f}"
|
||||||
|
|
||||||
|
lattice = knot_points(N_PARTICLES)
|
||||||
|
parts = [
|
||||||
|
f'<svg xmlns="http://www.w3.org/2000/svg" width="{WIDTH}" height="{HEIGHT}" '
|
||||||
|
f'viewBox="0 0 {WIDTH} {HEIGHT}" role="img" '
|
||||||
|
f'aria-label="Entropy-reversal field: S = {s_label} k-bits">',
|
||||||
|
f'<rect x="0.5" y="0.5" width="{WIDTH - 1}" height="{HEIGHT - 1}" '
|
||||||
|
f'rx="8" fill="{BG}" stroke="{BORDER}"/>',
|
||||||
|
]
|
||||||
|
|
||||||
|
for i, (lx, ly) in enumerate(lattice):
|
||||||
|
chaos_x = MARGIN + seeded_unit(i, generation, "x") * (WIDTH - 2 * MARGIN)
|
||||||
|
chaos_y = MARGIN + seeded_unit(i, generation, "y") * (HEIGHT - 2 * MARGIN)
|
||||||
|
fill = DEEP if seeded_unit(i, generation, "depth") < 0.3 else CYAN
|
||||||
|
cxv = f"{chaos_x:.1f};{lx:.1f};{lx:.1f};{chaos_x:.1f}"
|
||||||
|
cyv = f"{chaos_y:.1f};{ly:.1f};{ly:.1f};{chaos_y:.1f}"
|
||||||
|
parts.append(
|
||||||
|
f'<circle r="3" fill="{fill}" cx="{chaos_x:.1f}" cy="{chaos_y:.1f}">'
|
||||||
|
f'<animate attributeName="cx" dur="{DUR}" repeatCount="indefinite" '
|
||||||
|
f'calcMode="spline" keyTimes="{KEY_TIMES}" keySplines="{KEY_SPLINES}" '
|
||||||
|
f'values="{cxv}"/>'
|
||||||
|
f'<animate attributeName="cy" dur="{DUR}" repeatCount="indefinite" '
|
||||||
|
f'calcMode="spline" keyTimes="{KEY_TIMES}" keySplines="{KEY_SPLINES}" '
|
||||||
|
f'values="{cyv}"/>'
|
||||||
|
f'</circle>'
|
||||||
|
)
|
||||||
|
|
||||||
|
font = 'font-family="ui-monospace,SFMono-Regular,Menlo,monospace"'
|
||||||
|
parts.append(
|
||||||
|
f'<text x="16" y="26" {font} font-size="14" fill="{CYAN}">'
|
||||||
|
f'S = {s_label} k·bits</text>'
|
||||||
|
)
|
||||||
|
parts.append(
|
||||||
|
f'<text x="{WIDTH - 16}" y="26" text-anchor="end" {font} '
|
||||||
|
f'font-size="14" fill="{GREEN}">dS/dt < 0</text>'
|
||||||
|
)
|
||||||
|
parts.append(
|
||||||
|
f'<text x="{WIDTH - 16}" y="{HEIGHT - 14}" text-anchor="end" {font} '
|
||||||
|
f'font-size="11" fill="{MUTED}">bits sorted by visitors: {bits}</text>'
|
||||||
|
)
|
||||||
|
parts.append("</svg>")
|
||||||
|
|
||||||
|
svg = "\n".join(parts) + "\n"
|
||||||
|
os.makedirs(os.path.dirname(OUT_PATH), exist_ok=True)
|
||||||
|
with open(OUT_PATH, "w") as fh:
|
||||||
|
fh.write(svg)
|
||||||
|
size = os.path.getsize(OUT_PATH)
|
||||||
|
print(f"wrote {OUT_PATH} ({size} bytes, S={s_label}, bits={bits}, gen={generation})")
|
||||||
|
if size > 200 * 1024:
|
||||||
|
print("error: SVG exceeds 200 KB budget", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
264
engine/nightly.py
Normal file
264
engine/nightly.py
Normal file
|
|
@ -0,0 +1,264 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Nightly telemetry refresh for the profile README.
|
||||||
|
|
||||||
|
Updates the marker-fenced sections of README.md:
|
||||||
|
FEED — 4 newest Strange Quarks articles (RSS if populated, else the
|
||||||
|
server-rendered blog HTML)
|
||||||
|
STATS — telemetry row with live star/repo totals
|
||||||
|
FEATURED — star counts on the featured project cards
|
||||||
|
and bumps the entropy field's chaos generation so the field differs daily.
|
||||||
|
|
||||||
|
Every section is fail-safe: if a fetch or parse fails, that section is left
|
||||||
|
untouched and the script still exits 0. Stdlib only.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import html as htmllib
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import urllib.request
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
|
||||||
|
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
README = os.path.join(ROOT, "README.md")
|
||||||
|
STATE_PATH = os.path.join(ROOT, "state", "demon.json")
|
||||||
|
|
||||||
|
SITE = "https://stevenmilanese.com"
|
||||||
|
# The real feed. /feed.xml was a guess that 404'd for weeks while the HTML
|
||||||
|
# fallback silently matched nothing, so the FEED table quietly froze; it now
|
||||||
|
# also 301s here, but point at the canonical URL rather than lean on that.
|
||||||
|
FEED_URL = f"{SITE}/rss.xml"
|
||||||
|
BLOG_URL = f"{SITE}/blog"
|
||||||
|
# The site publishes read-time in its own namespace — valid for strict parsers,
|
||||||
|
# unambiguous for this one.
|
||||||
|
MANUSCRIPT_NS = "https://stevenmilanese.com/ns/manuscript"
|
||||||
|
|
||||||
|
FEATURED_REPOS = [
|
||||||
|
("anthropic-certs", "Verified Anthropic certifications — Claude, API, Claude Code CLI, MCP."),
|
||||||
|
("slTrain", "A steam locomotive for your terminal, smoke trail included."),
|
||||||
|
("meowchi-releases", "A desktop pet that evolves when you actually get work done."),
|
||||||
|
("mpl", "Mathematics Programming Language — write the equation, run the equation."),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def fetch(url, accept=None):
|
||||||
|
req = urllib.request.Request(url, headers={"User-Agent": "developtheweb-nightly/1.0"})
|
||||||
|
if accept:
|
||||||
|
req.add_header("Accept", accept)
|
||||||
|
token = os.environ.get("GITHUB_TOKEN")
|
||||||
|
if token and url.startswith("https://api.github.com"):
|
||||||
|
req.add_header("Authorization", f"Bearer {token}")
|
||||||
|
with urllib.request.urlopen(req, timeout=30) as resp:
|
||||||
|
return resp.read().decode("utf-8", errors="replace")
|
||||||
|
|
||||||
|
|
||||||
|
def gh_api(path):
|
||||||
|
return json.loads(fetch(f"https://api.github.com{path}", accept="application/vnd.github+json"))
|
||||||
|
|
||||||
|
|
||||||
|
def replace_section(text, marker, body):
|
||||||
|
start, end = f"<!-- {marker}:START -->", f"<!-- {marker}:END -->"
|
||||||
|
if start not in text or end not in text:
|
||||||
|
raise ValueError(f"missing {marker} markers")
|
||||||
|
pre = text.split(start)[0]
|
||||||
|
post = text.split(end)[1]
|
||||||
|
return f"{pre}{start}\n{body}\n{end}{post}"
|
||||||
|
|
||||||
|
|
||||||
|
def articles_from_rss():
|
||||||
|
"""Primary source: the site's real feed.
|
||||||
|
|
||||||
|
The feed carries read-time in the site's own namespace, so the meta column
|
||||||
|
comes from the publisher rather than being scraped back out of a page.
|
||||||
|
"""
|
||||||
|
root = ET.fromstring(fetch(FEED_URL))
|
||||||
|
items = []
|
||||||
|
for item in root.iter("item"):
|
||||||
|
title = (item.findtext("title") or "").strip()
|
||||||
|
link = (item.findtext("link") or "").strip()
|
||||||
|
pub = (item.findtext("pubDate") or "").strip()
|
||||||
|
date = None
|
||||||
|
try:
|
||||||
|
date = datetime.datetime.strptime(pub[:16].strip(), "%a, %d %b %Y")
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
mins = (item.findtext(f"{{{MANUSCRIPT_NS}}}readingMinutes") or "").strip()
|
||||||
|
meta = f"{mins} min read" if mins.isdigit() else ""
|
||||||
|
if title and link:
|
||||||
|
items.append({"title": title, "url": link, "date": date, "meta": meta})
|
||||||
|
return items
|
||||||
|
|
||||||
|
|
||||||
|
def articles_from_html():
|
||||||
|
"""Fallback: parse the blog index.
|
||||||
|
|
||||||
|
Written against the Manuscript's markup, which is regular enough not to
|
||||||
|
need heuristics — each entry is a `row` div holding one anchor and one
|
||||||
|
`meta` span:
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<a href="/blog/<slug>">Title</a>
|
||||||
|
<span class="meta"> JUL 28, 2025 · 19 MIN </span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
The previous version looked for a thumbnail `alt=` attribute and a
|
||||||
|
Title-Case date. The redesign has neither — no feature images on the index
|
||||||
|
and uppercase abbreviated months — so it matched nothing and silently
|
||||||
|
returned an empty list for weeks.
|
||||||
|
"""
|
||||||
|
page = fetch(BLOG_URL)
|
||||||
|
skip = ("/blog/tag/", "/blog/author/")
|
||||||
|
articles, seen = [], set()
|
||||||
|
|
||||||
|
row_re = re.compile(
|
||||||
|
r'<a[^>]+href="(/blog/[a-z0-9][a-z0-9-]*)"[^>]*>(.*?)</a>'
|
||||||
|
r'.{0,400}?<span[^>]*class="meta"[^>]*>(.*?)</span>',
|
||||||
|
re.S,
|
||||||
|
)
|
||||||
|
for m in row_re.finditer(page):
|
||||||
|
slug, raw_title, raw_meta = m.group(1), m.group(2), m.group(3)
|
||||||
|
if slug.startswith(skip) or slug in seen:
|
||||||
|
continue
|
||||||
|
|
||||||
|
title = htmllib.unescape(re.sub(r"<[^>]+>", "", raw_title)).strip()
|
||||||
|
meta_text = htmllib.unescape(re.sub(r"<[^>]+>", " ", raw_meta))
|
||||||
|
meta_text = re.sub(r"\s+", " ", meta_text).strip()
|
||||||
|
|
||||||
|
# "JUL 28, 2025" — uppercase, abbreviated month.
|
||||||
|
date_m = re.search(r"([A-Za-z]{3,}) (\d{1,2}), (\d{4})", meta_text)
|
||||||
|
if not (title and date_m):
|
||||||
|
continue
|
||||||
|
month, day, year = date_m.groups()
|
||||||
|
date = None
|
||||||
|
for fmt in ("%b %d %Y", "%B %d %Y"):
|
||||||
|
try:
|
||||||
|
date = datetime.datetime.strptime(f"{month.title()} {day} {year}", fmt)
|
||||||
|
break
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
if date is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
mins_m = re.search(r"(\d+)\s*MIN", meta_text, re.I)
|
||||||
|
seen.add(slug)
|
||||||
|
articles.append({
|
||||||
|
"title": title,
|
||||||
|
"url": f"{SITE}{slug}",
|
||||||
|
"date": date,
|
||||||
|
"meta": f"{mins_m.group(1)} min read" if mins_m else "",
|
||||||
|
})
|
||||||
|
return articles
|
||||||
|
|
||||||
|
|
||||||
|
def update_feed(text):
|
||||||
|
articles = []
|
||||||
|
try:
|
||||||
|
articles = articles_from_rss()
|
||||||
|
except Exception as exc:
|
||||||
|
print(f"::warning title=nightly FEED rss::rss unusable ({exc}); falling back to html")
|
||||||
|
if not articles:
|
||||||
|
print("::warning title=nightly FEED fallback::rss yielded nothing; scraping /blog")
|
||||||
|
articles = articles_from_html()
|
||||||
|
dated = [a for a in articles if a["date"]]
|
||||||
|
dated.sort(key=lambda a: a["date"], reverse=True)
|
||||||
|
newest = dated[:4]
|
||||||
|
if len(newest) < 4:
|
||||||
|
raise ValueError(f"only {len(newest)} parseable articles")
|
||||||
|
rows = ["| Article | |", "|:---|---:|"]
|
||||||
|
for a in newest:
|
||||||
|
title = a["title"].replace("|", "\\|")
|
||||||
|
when = a["date"].strftime("%b %d, %Y").replace(" 0", " ")
|
||||||
|
meta = f"{when} · {a['meta']}" if a["meta"] else when
|
||||||
|
rows.append(f"| [{title}]({a['url']}) | {meta} |")
|
||||||
|
return replace_section(text, "FEED", "\n".join(rows))
|
||||||
|
|
||||||
|
|
||||||
|
def update_stats(text):
|
||||||
|
repos = gh_api("/users/developtheweb/repos?per_page=100&type=owner")
|
||||||
|
public = [r for r in repos if not r["private"]]
|
||||||
|
stars = sum(r["stargazers_count"] for r in public)
|
||||||
|
line = (
|
||||||
|
"<div align=\"center\">\n\n"
|
||||||
|
"`10¹⁰⁶ yr until heat death — the deadline` · "
|
||||||
|
"`2.9 zJ of order per bit sorted (kT ln 2, 300 K)` · "
|
||||||
|
f"`★ {stars} stars across {len(public)} public repos`\n\n"
|
||||||
|
"</div>"
|
||||||
|
)
|
||||||
|
return replace_section(text, "STATS", line)
|
||||||
|
|
||||||
|
|
||||||
|
def update_featured(text):
|
||||||
|
cards = []
|
||||||
|
for name, blurb in FEATURED_REPOS:
|
||||||
|
repo = gh_api(f"/repos/developtheweb/{name}")
|
||||||
|
cards.append(
|
||||||
|
f'<td width="50%" valign="top">\n'
|
||||||
|
f'<h3 align="center"><a href="{repo["html_url"]}">{name}</a></h3>\n'
|
||||||
|
f'<p align="center"><code>★ {repo["stargazers_count"]}</code></p>\n'
|
||||||
|
f'<p align="center">{blurb}</p>\n'
|
||||||
|
f'</td>'
|
||||||
|
)
|
||||||
|
table = (
|
||||||
|
'<div align="center">\n<table>\n'
|
||||||
|
f'<tr>\n{cards[0]}\n{cards[1]}\n</tr>\n'
|
||||||
|
f'<tr>\n{cards[2]}\n{cards[3]}\n</tr>\n'
|
||||||
|
'</table>\n</div>'
|
||||||
|
)
|
||||||
|
return replace_section(text, "FEATURED", table)
|
||||||
|
|
||||||
|
|
||||||
|
def bump_entropy():
|
||||||
|
with open(STATE_PATH) as fh:
|
||||||
|
state = json.load(fh)
|
||||||
|
state["generation"] += 1
|
||||||
|
with open(STATE_PATH, "w") as fh:
|
||||||
|
json.dump(state, fh, indent=2)
|
||||||
|
fh.write("\n")
|
||||||
|
subprocess.run(
|
||||||
|
[sys.executable, os.path.join(ROOT, "engine", "generate_entropy_svg.py")],
|
||||||
|
check=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def warn(label, exc):
|
||||||
|
"""Fail-safe, but never quiet.
|
||||||
|
|
||||||
|
Every section still degrades to 'leave it alone and exit 0' — a broken
|
||||||
|
fetch must not wedge the profile. What changed is visibility: a section
|
||||||
|
that stops updating now announces itself as a GitHub Actions warning
|
||||||
|
annotation, which surfaces in the run summary instead of scrolling past in
|
||||||
|
a log nobody opens. The FEED table sat frozen for 37 days precisely
|
||||||
|
because a silent skip and a successful run looked identical.
|
||||||
|
"""
|
||||||
|
print(f"::warning title=nightly {label} skipped::{label} left untouched — {exc}")
|
||||||
|
print(f"{label}: left untouched ({exc})", file=sys.stderr)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
with open(README) as fh:
|
||||||
|
text = fh.read()
|
||||||
|
failures = 0
|
||||||
|
for label, fn in (("FEED", update_feed), ("STATS", update_stats), ("FEATURED", update_featured)):
|
||||||
|
try:
|
||||||
|
text = fn(text)
|
||||||
|
print(f"{label}: updated")
|
||||||
|
except Exception as exc:
|
||||||
|
failures += 1
|
||||||
|
warn(label, exc)
|
||||||
|
with open(README, "w") as fh:
|
||||||
|
fh.write(text)
|
||||||
|
try:
|
||||||
|
bump_entropy()
|
||||||
|
print("ENTROPY: regenerated")
|
||||||
|
except Exception as exc:
|
||||||
|
failures += 1
|
||||||
|
warn("ENTROPY", exc)
|
||||||
|
if failures:
|
||||||
|
print(f"::warning title=nightly incomplete::{failures} of 4 sections did not update")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 62 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 62 KiB |
6
state/demon.json
Normal file
6
state/demon.json
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"bits_sorted": 12,
|
||||||
|
"generation": 53,
|
||||||
|
"demons": 1,
|
||||||
|
"last_sorted_at": "2026-07-08T02:02:03+00:00"
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue