HelloSun commited on
Commit
64e83f9
·
verified ·
1 Parent(s): ea0bac9

add simulated NetBSD xearth demo

Browse files
Files changed (2) hide show
  1. README.md +10 -5
  2. index.html +67 -48
README.md CHANGED
@@ -1,10 +1,15 @@
1
  ---
2
- title: Opencode Web
3
- emoji: 🏢
4
- colorFrom: pink
5
- colorTo: indigo
6
  sdk: static
7
  pinned: false
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
1
  ---
2
+ title: opencode_web
3
+ emoji: 🌍
4
+ colorFrom: green
5
+ colorTo: gray
6
  sdk: static
7
  pinned: false
8
  ---
9
 
10
+ # opencode_web
11
+
12
+ Minimal pure HTML+JS demo: a simulated NetBSD boot log plus an xearth-style
13
+ rotating globe (tinyx-wscons + xearth concept).
14
+
15
+ This is a simulation, not a real NetBSD VM.
index.html CHANGED
@@ -1,51 +1,70 @@
1
  <!doctype html>
2
- <html><head><meta charset="utf-8"><title>opencode web</title>
3
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/css/xterm.css">
4
- <style>html,body{margin:0;height:100%;background:#000}#console{height:100%}</style>
5
- </head><body><div id="console"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  <script>
7
- // Cross-origin isolation (needed by CheerpX) via service worker, since static hosting cannot set headers.
8
- if ("serviceWorker" in navigator && !crossOriginIsolated) {
9
- navigator.serviceWorker.register("sw.js").then(reg => {
10
- if (reg.active && navigator.serviceWorker.controller) return;
11
- navigator.serviceWorker.addEventListener("controllerchange", () => location.reload());
12
- if (reg.active) location.reload();
13
- });
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  </script>
16
- <script src="https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/lib/xterm.js"></script>
17
- <script type="module">
18
- const CX_URL = "https://cxrtnc.leaningtech.com/1.4.0/cx.esm.js";
19
- const term = new Terminal({ cursorBlink: true, convertEol: true, fontFamily: "monospace" });
20
- term.open(document.getElementById("console"));
21
- term.focus();
22
- term.write("opencode web: loading CheerpX + Alpine...\r\n");
23
- try {
24
- if (!crossOriginIsolated) throw new Error("page is not cross-origin isolated yet (service worker reload pending)");
25
- const CheerpX = await import(CX_URL);
26
- const blockDevice = await CheerpX.HttpBytesDevice.create("rootfs.ext2");
27
- const cache = await CheerpX.IDBDevice.create("opencode-web-v1");
28
- const overlay = await CheerpX.OverlayDevice.create(blockDevice, cache);
29
- const webDevice = await CheerpX.WebDevice.create("");
30
- const dataDevice = await CheerpX.DataDevice.create();
31
- const cx = await CheerpX.Linux.create({ mounts: [
32
- { type: "ext2", dev: overlay, path: "/" },
33
- { type: "dir", dev: webDevice, path: "/web" },
34
- { type: "dir", dev: dataDevice, path: "/data" },
35
- { type: "devs", path: "/dev" },
36
- { type: "devpts", path: "/dev/pts" },
37
- { type: "proc", path: "/proc" },
38
- { type: "sys", path: "/sys" },
39
- ] });
40
- const readFn = cx.setCustomConsole((buf, vt) => { if (vt === 1) term.write(new Uint8Array(buf)); }, term.cols, term.rows);
41
- term.onData(s => { for (let i = 0; i < s.length; i++) readFn(s.charCodeAt(i)); });
42
- await cx.run("/bin/sh", ["-c", "opencode; exec /bin/sh -l"], {
43
- env: ["HOME=/root", "TERM=xterm-256color", "PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin", "LANG=C.UTF-8"],
44
- cwd: "/root", uid: 0, gid: 0,
45
- });
46
- } catch (e) {
47
- term.write("\r\nERROR: " + e + "\r\n");
48
- console.error(e);
49
- }
50
- </script>
51
- </body></html>
 
1
  <!doctype html>
2
+ <html lang="zh-Hant">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <title>opencode_web - NetBSD demo (simulated)</title>
7
+ <style>
8
+ html,body{margin:0;height:100%;background:#000;color:#ccc;font:14px/1.4 monospace}
9
+ #term{white-space:pre;padding:12px;height:40%;overflow:hidden;box-sizing:border-box}
10
+ #wrap{display:flex;justify-content:center;align-items:center;height:60%}
11
+ canvas{background:#000;border:1px solid #333}
12
+ .tag{color:#666;padding:0 12px 6px}
13
+ </style>
14
+ </head>
15
+ <body>
16
+ <div id="term"></div>
17
+ <div id="wrap"><canvas id="c" width="480" height="360"></canvas></div>
18
+ <div class="tag">simulated: pure HTML+JS, NOT a real NetBSD VM. xearth-style globe (tinyx-wscons demo)</div>
19
  <script>
20
+ (function () {
21
+ // ---- fake NetBSD boot log (typed out) ----
22
+ const lines = [
23
+ "NetBSD 10.0 (GENERIC) #0: (simulated)",
24
+ "total memory = 64 MB",
25
+ "cpu0 at mainbus0: i386-like (simulated)",
26
+ "wscons0: attached tinyx-wscons",
27
+ "xearth: starting globe renderer",
28
+ "login: demo (type nothing, enjoy the globe)",
29
+ ""
30
+ ];
31
+ const term = document.getElementById("term");
32
+ let li = 0, ci = 0, buf = "";
33
+ function type() {
34
+ if (li >= lines.length) return;
35
+ const line = lines[li];
36
+ buf += line[ci++] || "";
37
+ if (ci > line.length) { buf += "\n"; li++; ci = 0; }
38
+ term.textContent = buf + (li < lines.length ? "_" : "");
39
+ setTimeout(type, li < lines.length && ci === 0 ? 300 : 25);
40
+ }
41
+ type();
42
+
43
+ // ---- xearth-style rotating dotted globe ----
44
+ const cv = document.getElementById("c"), g = cv.getContext("2d");
45
+ const W = cv.width, H = cv.height, R = 150, cx = W / 2, cy = H / 2;
46
+ const pts = [];
47
+ for (let i = 0; i < 1400; i++) { // Fibonacci sphere points
48
+ const y = 1 - (2 * i) / 1399, r = Math.sqrt(1 - y * y), t = i * Math.PI * (3 - Math.sqrt(5));
49
+ pts.push([Math.cos(t) * r, y, Math.sin(t) * r]);
50
+ }
51
+ let rot = 0;
52
+ function frame() {
53
+ g.fillStyle = "#000"; g.fillRect(0, 0, W, H);
54
+ const c = Math.cos(rot), s = Math.sin(rot);
55
+ for (const [x, y, z] of pts) {
56
+ const X = x * c + z * s, Z = -x * s + z * c; // rotate around Y axis
57
+ if (Z < 0) continue; // front side only
58
+ const px = cx + X * R, py = cy - y * R;
59
+ const shade = 0.35 + 0.65 * Z;
60
+ g.fillStyle = `rgba(80,${Math.round(200 * shade)},120,${shade})`;
61
+ g.fillRect(px, py, 2, 2);
62
+ }
63
+ rot += 0.01;
64
+ requestAnimationFrame(frame);
65
+ }
66
+ frame();
67
+ })();
68
  </script>
69
+ </body>
70
+ </html>