@idle-screens/schema 2.3.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FORMAT.md +24 -9
- package/dist/index.d.ts +70 -16
- package/dist/index.js +477 -283
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/saver-spec.schema.json +7 -1
package/dist/index.js
CHANGED
|
@@ -250,8 +250,15 @@ function validateLayer(layer, path, err, warn, spec) {
|
|
|
250
250
|
}
|
|
251
251
|
}
|
|
252
252
|
if (layer.spin !== void 0) {
|
|
253
|
-
if (
|
|
254
|
-
|
|
253
|
+
if (isRange(layer.spin)) {
|
|
254
|
+
if (Math.abs(layer.spin[0]) > LIMITS.maxSpin || Math.abs(layer.spin[1]) > LIMITS.maxSpin) {
|
|
255
|
+
err(`${path}.spin`, `each end of the range must be within \xB1${LIMITS.maxSpin} deg/sec`);
|
|
256
|
+
}
|
|
257
|
+
} else if (!isNum(layer.spin)) {
|
|
258
|
+
err(`${path}.spin`, "must be a number or a [min,max] range (degrees/sec)");
|
|
259
|
+
} else if (Math.abs(layer.spin) > LIMITS.maxSpin) {
|
|
260
|
+
err(`${path}.spin`, `must be within \xB1${LIMITS.maxSpin} deg/sec`);
|
|
261
|
+
}
|
|
255
262
|
}
|
|
256
263
|
if (layer.grow !== void 0) {
|
|
257
264
|
if (!isObj(layer.grow)) err(`${path}.grow`, "must be an object");
|
|
@@ -749,8 +756,10 @@ function buildEntities(layer, rng, w, h, scale = 1, countScale = 1) {
|
|
|
749
756
|
pulsePeriod: layer.pulse?.period ?? 1e3,
|
|
750
757
|
pulsePhase: layer.pulse ? rng.range(0, Math.PI * 2) : 0,
|
|
751
758
|
// New draws AFTER pulsePhase — guarded so existing specs keep identical streams.
|
|
752
|
-
|
|
753
|
-
//
|
|
759
|
+
// Scalar spin: no draw here, one phase draw below (unchanged). Range spin
|
|
760
|
+
// (new): one seeded speed draw here, then the phase draw — array form is new
|
|
761
|
+
// so the extra draw can't perturb any existing spec's entity stream.
|
|
762
|
+
spinSpeed: typeof layer.spin === "number" ? layer.spin * Math.PI / 180 : Array.isArray(layer.spin) ? rng.range(layer.spin[0], layer.spin[1]) * Math.PI / 180 : 0,
|
|
754
763
|
spinPhase: layer.spin ? rng.range(0, Math.PI * 2) : 0,
|
|
755
764
|
growAmp: layer.grow?.amp ?? 0,
|
|
756
765
|
growPeriod: layer.grow?.period ?? 1e3,
|
|
@@ -1178,6 +1187,11 @@ function hexToRgba(hex, alpha) {
|
|
|
1178
1187
|
return `rgba(${n >> 16 & 255},${n >> 8 & 255},${n & 255},${alpha})`;
|
|
1179
1188
|
}
|
|
1180
1189
|
var FONT_PREFIX_RE = /^((?:(?:italic|oblique|bold|bolder|lighter|normal|\d{3})\s+)+)/;
|
|
1190
|
+
var FONT_PX_RE = /(\d*\.?\d+)px/;
|
|
1191
|
+
function scaleFontPx(font, factor) {
|
|
1192
|
+
if (factor === 1) return font;
|
|
1193
|
+
return font.replace(FONT_PX_RE, (_m, n) => `${(Number(n) * factor).toFixed(2)}px`);
|
|
1194
|
+
}
|
|
1181
1195
|
function composeFontShorthand(sz, font) {
|
|
1182
1196
|
const m = FONT_PREFIX_RE.exec(font);
|
|
1183
1197
|
if (m) return `${m[1].trim()} ${sz}px ${font.slice(m[0].length)}`;
|
|
@@ -1249,6 +1263,11 @@ var SpecInstance = class {
|
|
|
1249
1263
|
/** Active glide between two resolved specs (live setParam/applyTrack). */
|
|
1250
1264
|
transition = null;
|
|
1251
1265
|
lastStructural = "";
|
|
1266
|
+
/** Viewport factor for absolute px sizes — 1 for `units: 'px'` specs. */
|
|
1267
|
+
fontScale() {
|
|
1268
|
+
if (this.effSpec.units === "px") return 1;
|
|
1269
|
+
return Math.min(this.w, this.h) / (this.effSpec.referenceViewport ?? LIMITS.referenceViewport);
|
|
1270
|
+
}
|
|
1252
1271
|
sizeCanvas() {
|
|
1253
1272
|
const dpr = Math.min(this.saverCtx.dpr, 2);
|
|
1254
1273
|
this.canvas.width = Math.max(1, Math.round(this.w * dpr));
|
|
@@ -1463,7 +1482,7 @@ var SpecInstance = class {
|
|
|
1463
1482
|
} else {
|
|
1464
1483
|
ctx.textAlign = sprite.align ?? "center";
|
|
1465
1484
|
ctx.textBaseline = sprite.baseline ?? "middle";
|
|
1466
|
-
ctx.font = sprite.font ?
|
|
1485
|
+
ctx.font = sprite.font ? FONT_PX_RE.test(sprite.font) ? scaleFontPx(sprite.font, this.fontScale()) : composeFontShorthand(sz, sprite.font) : `${sz}px system-ui, sans-serif`;
|
|
1467
1486
|
ctx.fillStyle = sprite.color ?? "#e6e8ef";
|
|
1468
1487
|
const idx = spriteIndexAt(e, t, sprite.strings.length);
|
|
1469
1488
|
const text = sprite.strings[idx] ?? sprite.strings[0];
|
|
@@ -1875,6 +1894,8 @@ function describeScene(spec, options = {}) {
|
|
|
1875
1894
|
|
|
1876
1895
|
// src/perceive.ts
|
|
1877
1896
|
import { createRng as createRng4 } from "@idle-screens/core";
|
|
1897
|
+
var GLOW_SPREAD = 2.4;
|
|
1898
|
+
var LINE_SALIENCE = 3.5;
|
|
1878
1899
|
function buildScene(spec, opts) {
|
|
1879
1900
|
const { width: w, height: h } = opts.viewport ?? { width: 1920, height: 1080 };
|
|
1880
1901
|
const seed = opts.seed ?? spec.seed ?? 42;
|
|
@@ -2013,12 +2034,16 @@ function luminanceGrid(spec, opts = {}) {
|
|
|
2013
2034
|
halfX = box.halfX;
|
|
2014
2035
|
halfY = box.halfY;
|
|
2015
2036
|
}
|
|
2016
|
-
const c0 = Math.max(0, Math.floor((centerX - halfX) / cellW));
|
|
2017
|
-
const c1 = Math.min(cols - 1, Math.floor((centerX + halfX) / cellW));
|
|
2018
|
-
const r0 = Math.max(0, Math.floor((centerY - halfY) / cellH));
|
|
2019
|
-
const r1 = Math.min(rows - 1, Math.floor((centerY + halfY) / cellH));
|
|
2020
2037
|
const circular = s.kind === "circle" || s.kind === "ring";
|
|
2021
|
-
const soft = s.kind === "circle" && s.soft;
|
|
2038
|
+
const soft = s.kind === "circle" && !!s.soft;
|
|
2039
|
+
const additive = layer.blend === "lighter" || layer.blend === "screen";
|
|
2040
|
+
const glow = soft && additive;
|
|
2041
|
+
const reachX = glow ? halfX * GLOW_SPREAD : halfX;
|
|
2042
|
+
const reachY = glow ? halfY * GLOW_SPREAD : halfY;
|
|
2043
|
+
const c0 = Math.max(0, Math.floor((centerX - reachX) / cellW));
|
|
2044
|
+
const c1 = Math.min(cols - 1, Math.floor((centerX + reachX) / cellW));
|
|
2045
|
+
const r0 = Math.max(0, Math.floor((centerY - reachY) / cellH));
|
|
2046
|
+
const r1 = Math.min(rows - 1, Math.floor((centerY + reachY) / cellH));
|
|
2022
2047
|
const inkWeight = s.kind === "text" || s.kind === "emoji" ? 0.55 : 1;
|
|
2023
2048
|
for (let r = r0; r <= r1; r++) {
|
|
2024
2049
|
for (let c = c0; c <= c1; c++) {
|
|
@@ -2026,12 +2051,23 @@ function luminanceGrid(spec, opts = {}) {
|
|
|
2026
2051
|
const dy = (r + 0.5) * cellH - centerY;
|
|
2027
2052
|
if (circular) {
|
|
2028
2053
|
const d = Math.sqrt(dx * dx + dy * dy);
|
|
2029
|
-
|
|
2054
|
+
const reach = glow ? reachX : halfX;
|
|
2055
|
+
if (d > reach + Math.min(cellW, cellH) / 2) continue;
|
|
2030
2056
|
if (s.kind === "ring") {
|
|
2031
2057
|
const strokeW = (s.width ?? (scale === 1 ? 2 : 2e-3)) * scale;
|
|
2032
2058
|
if (d < halfX - strokeW) continue;
|
|
2033
2059
|
}
|
|
2034
|
-
|
|
2060
|
+
let wgt;
|
|
2061
|
+
if (glow) {
|
|
2062
|
+
const core = halfX;
|
|
2063
|
+
if (d <= core) wgt = 1;
|
|
2064
|
+
else {
|
|
2065
|
+
const f = Math.max(0, 1 - (d - core) / Math.max(reachX - core, 1e-6));
|
|
2066
|
+
wgt = f * f;
|
|
2067
|
+
}
|
|
2068
|
+
} else {
|
|
2069
|
+
wgt = soft ? Math.max(0.1, 1 - d / Math.max(halfX, 1e-6)) : 1;
|
|
2070
|
+
}
|
|
2035
2071
|
compose(r * cols + c, lum, a * wgt, layer.blend);
|
|
2036
2072
|
} else {
|
|
2037
2073
|
compose(r * cols + c, lum, a * inkWeight, layer.blend);
|
|
@@ -2107,11 +2143,14 @@ var DOT_BIT = [
|
|
|
2107
2143
|
[4, 32],
|
|
2108
2144
|
[64, 128]
|
|
2109
2145
|
];
|
|
2110
|
-
function
|
|
2146
|
+
function autoExpose(grid) {
|
|
2111
2147
|
const sorted = [...grid.cells].sort((a, b) => a - b);
|
|
2112
2148
|
const lo = sorted[0];
|
|
2113
2149
|
const hi = Math.max(sorted[Math.floor(sorted.length * 0.98)], lo + 0.08);
|
|
2114
|
-
|
|
2150
|
+
return (v) => Math.pow(Math.max(0, Math.min(1, (v - lo) / (hi - lo))), 0.8);
|
|
2151
|
+
}
|
|
2152
|
+
function renderBrailleMap(grid) {
|
|
2153
|
+
const expose = autoExpose(grid);
|
|
2115
2154
|
const outRows = [];
|
|
2116
2155
|
for (let br = 0; br < Math.floor(grid.rows / 4); br++) {
|
|
2117
2156
|
let line = "";
|
|
@@ -2129,6 +2168,34 @@ function renderBrailleMap(grid) {
|
|
|
2129
2168
|
}
|
|
2130
2169
|
return outRows.join("\n");
|
|
2131
2170
|
}
|
|
2171
|
+
var DENSITY_RAMP = " .:-=+*#%@";
|
|
2172
|
+
function renderDensityMap(grid) {
|
|
2173
|
+
const expose = autoExpose(grid);
|
|
2174
|
+
const ramp = DENSITY_RAMP;
|
|
2175
|
+
const lines = [];
|
|
2176
|
+
for (let r = 0; r < grid.rows; r++) {
|
|
2177
|
+
let line = "";
|
|
2178
|
+
for (let c = 0; c < grid.cols; c++) {
|
|
2179
|
+
const v = expose(grid.cells[r * grid.cols + c]);
|
|
2180
|
+
line += ramp[Math.min(ramp.length - 1, Math.floor(v * ramp.length))];
|
|
2181
|
+
}
|
|
2182
|
+
lines.push(line);
|
|
2183
|
+
}
|
|
2184
|
+
return lines.join("\n");
|
|
2185
|
+
}
|
|
2186
|
+
function textSprites(spec, opts = {}) {
|
|
2187
|
+
const scene = buildScene(spec, opts);
|
|
2188
|
+
const t = opts.t ?? 5e3;
|
|
2189
|
+
const out = [];
|
|
2190
|
+
scene.layers.forEach(({ layer, entities }, layerIndex) => {
|
|
2191
|
+
if (layer.sprite.kind !== "text") return;
|
|
2192
|
+
const s = layer.sprite;
|
|
2193
|
+
const m = s.font ? /(\d+(?:\.\d+)?)px/.exec(s.font) : null;
|
|
2194
|
+
const sizePx = m ? Number(m[1]) : entities[0] ? sizeAt(entities[0], t) : 0;
|
|
2195
|
+
out.push({ layerIndex, key: layer.key, strings: [...s.strings], count: entities.length, sizePx: Math.round(sizePx) });
|
|
2196
|
+
});
|
|
2197
|
+
return out;
|
|
2198
|
+
}
|
|
2132
2199
|
function dominanceRanking(spec, opts = {}) {
|
|
2133
2200
|
const scene = buildScene(spec, opts);
|
|
2134
2201
|
const t = opts.t ?? 5e3;
|
|
@@ -2148,8 +2215,8 @@ function dominanceRanking(spec, opts = {}) {
|
|
|
2148
2215
|
const s = layer.sprite;
|
|
2149
2216
|
let entArea;
|
|
2150
2217
|
if (s.kind === "circle") entArea = Math.PI * (sz / 2) * (sz / 2);
|
|
2151
|
-
else if (s.kind === "ring") entArea = Math.PI * sz * ((s.width ?? (scale === 1 ? 2 : 2e-3)) * scale);
|
|
2152
|
-
else if (s.kind === "streak") entArea = sz * ((s.width ?? (scale === 1 ? 2 : 2e-3)) * scale);
|
|
2218
|
+
else if (s.kind === "ring") entArea = Math.PI * sz * ((s.width ?? (scale === 1 ? 2 : 2e-3)) * scale) * LINE_SALIENCE;
|
|
2219
|
+
else if (s.kind === "streak") entArea = sz * ((s.width ?? (scale === 1 ? 2 : 2e-3)) * scale) * LINE_SALIENCE;
|
|
2153
2220
|
else if (s.kind === "rect") {
|
|
2154
2221
|
const h2 = e.size2 !== void 0 ? e.size2 * (e.size > 0 ? sz / e.size : 1) : sz;
|
|
2155
2222
|
entArea = sz * h2;
|
|
@@ -2166,7 +2233,7 @@ function dominanceRanking(spec, opts = {}) {
|
|
|
2166
2233
|
const edges = linkEdges(layer.links, positions, layer.links.maxDist * scale, layer.wrap !== false && motionWraps, w, h);
|
|
2167
2234
|
const la = (layer.links.alpha ?? 0.6) * lifeA;
|
|
2168
2235
|
const lw = (layer.links.width ?? 1) * scale;
|
|
2169
|
-
for (const edge of edges) area += edge.dist * lw * la;
|
|
2236
|
+
for (const edge of edges) area += edge.dist * lw * la * LINE_SALIENCE;
|
|
2170
2237
|
}
|
|
2171
2238
|
const meanLuma = entities.length ? lumAcc / entities.length : 0;
|
|
2172
2239
|
const contrast = Math.abs(meanLuma - bgMean) + 0.1;
|
|
@@ -2274,6 +2341,7 @@ function perceiveScene(spec, opts = {}) {
|
|
|
2274
2341
|
return {
|
|
2275
2342
|
t: opts.t ?? 5e3,
|
|
2276
2343
|
braille: renderBrailleMap(grid),
|
|
2344
|
+
density: renderDensityMap(grid),
|
|
2277
2345
|
coverage: grid.coverage,
|
|
2278
2346
|
meanLuminance: grid.meanLuminance,
|
|
2279
2347
|
centroid: grid.centroid,
|
|
@@ -2281,6 +2349,7 @@ function perceiveScene(spec, opts = {}) {
|
|
|
2281
2349
|
colProfile: grid.colProfile,
|
|
2282
2350
|
dominance: dominanceRanking(spec, opts),
|
|
2283
2351
|
motion: motionStats(spec, opts),
|
|
2352
|
+
text: textSprites(spec, opts),
|
|
2284
2353
|
advisories: adviseSpec(spec, opts.viewport ?? { width: 1920, height: 1080 })
|
|
2285
2354
|
};
|
|
2286
2355
|
}
|
|
@@ -2494,84 +2563,113 @@ var DASHBOARD_SPEC = {
|
|
|
2494
2563
|
background: {
|
|
2495
2564
|
type: "gradient",
|
|
2496
2565
|
stops: [
|
|
2497
|
-
{ at: 0, color: "#
|
|
2498
|
-
{ at: 0.
|
|
2499
|
-
{ at: 1, color: "#
|
|
2566
|
+
{ at: 0, color: "#05070d" },
|
|
2567
|
+
{ at: 0.55, color: "#080b14" },
|
|
2568
|
+
{ at: 1, color: "#0a0d18" }
|
|
2500
2569
|
]
|
|
2501
2570
|
},
|
|
2502
2571
|
layers: [
|
|
2503
|
-
//
|
|
2504
|
-
{
|
|
2505
|
-
key: "dust",
|
|
2506
|
-
count: 40,
|
|
2507
|
-
sprite: { kind: "circle", radius: [1852e-7, 7407e-7], color: "#1a2538" },
|
|
2508
|
-
alpha: [0.1, 0.25],
|
|
2509
|
-
motion: { type: "drift", speed: [2778e-7, 1111e-6], bob: 2778e-7 }
|
|
2510
|
-
},
|
|
2572
|
+
// ---- ambient: the LED wall behind everything ----
|
|
2511
2573
|
{
|
|
2512
2574
|
key: "led-wall",
|
|
2513
|
-
count:
|
|
2514
|
-
sprite: { kind: "circle", radius: [
|
|
2515
|
-
alpha: [0.
|
|
2516
|
-
layout: { type: "grid", columns:
|
|
2517
|
-
|
|
2518
|
-
pulse: { amp: 0.3, period: 5e3, wave: { wavelength: 0.35, angle: 20 } },
|
|
2575
|
+
count: 240,
|
|
2576
|
+
sprite: { kind: "circle", radius: [7e-4, 11e-4], color: "#22344c" },
|
|
2577
|
+
alpha: [0.04, 0.1],
|
|
2578
|
+
layout: { type: "grid", columns: 24, jitter: 0.1 },
|
|
2579
|
+
pulse: { amp: 0.3, period: 6200, wave: { wavelength: 0.4, angle: 24 } },
|
|
2519
2580
|
motion: { type: "static" }
|
|
2520
2581
|
},
|
|
2521
|
-
//
|
|
2582
|
+
// ---- frame chrome (boots first) ----
|
|
2583
|
+
{
|
|
2584
|
+
key: "rule-header",
|
|
2585
|
+
count: 1,
|
|
2586
|
+
position: { x: 0.5, y: 0.085 },
|
|
2587
|
+
sprite: { kind: "rect", width: [0.93, 0.93], aspect: [12e-4, 12e-4], color: "#24384f" },
|
|
2588
|
+
alpha: [0.8, 0.8],
|
|
2589
|
+
motion: { type: "static" },
|
|
2590
|
+
life: { enter: 100, fade: 400 }
|
|
2591
|
+
},
|
|
2592
|
+
{
|
|
2593
|
+
key: "rule-footer",
|
|
2594
|
+
count: 1,
|
|
2595
|
+
position: { x: 0.5, y: 0.915 },
|
|
2596
|
+
sprite: { kind: "rect", width: [0.93, 0.93], aspect: [12e-4, 12e-4], color: "#24384f" },
|
|
2597
|
+
alpha: [0.8, 0.8],
|
|
2598
|
+
motion: { type: "static" },
|
|
2599
|
+
life: { enter: 100, fade: 400 }
|
|
2600
|
+
},
|
|
2601
|
+
{
|
|
2602
|
+
key: "rule-col-left",
|
|
2603
|
+
count: 1,
|
|
2604
|
+
position: { x: 0.265, y: 0.5 },
|
|
2605
|
+
sprite: { kind: "rect", width: [9e-4, 9e-4], aspect: [620, 620], color: "#1c2c40" },
|
|
2606
|
+
alpha: [0.7, 0.7],
|
|
2607
|
+
motion: { type: "static" },
|
|
2608
|
+
life: { enter: 100, fade: 400 }
|
|
2609
|
+
},
|
|
2610
|
+
{
|
|
2611
|
+
key: "rule-col-right",
|
|
2612
|
+
count: 1,
|
|
2613
|
+
position: { x: 0.645, y: 0.5 },
|
|
2614
|
+
sprite: { kind: "rect", width: [9e-4, 9e-4], aspect: [620, 620], color: "#1c2c40" },
|
|
2615
|
+
alpha: [0.7, 0.7],
|
|
2616
|
+
motion: { type: "static" },
|
|
2617
|
+
life: { enter: 100, fade: 400 }
|
|
2618
|
+
},
|
|
2619
|
+
// ---- header band ----
|
|
2522
2620
|
{
|
|
2523
2621
|
key: "title",
|
|
2524
2622
|
count: 1,
|
|
2525
|
-
position: { x: 0.
|
|
2623
|
+
position: { x: 0.035, y: 0.052 },
|
|
2526
2624
|
sprite: {
|
|
2527
2625
|
kind: "text",
|
|
2528
|
-
strings: ["
|
|
2529
|
-
color: "#
|
|
2626
|
+
strings: ["VIREO-9 \xB7 TRANS-LUNAR RELAY \xB7 OPS WALL 03"],
|
|
2627
|
+
color: "#7f93ab",
|
|
2530
2628
|
font: "600 13px 'SF Mono', monospace",
|
|
2531
|
-
align: "
|
|
2629
|
+
align: "left"
|
|
2532
2630
|
},
|
|
2533
2631
|
motion: { type: "static" },
|
|
2534
2632
|
life: { enter: 200, fade: 600 }
|
|
2535
2633
|
},
|
|
2536
2634
|
{
|
|
2537
|
-
key: "
|
|
2635
|
+
key: "clock",
|
|
2538
2636
|
count: 1,
|
|
2539
|
-
position: { x: 0.
|
|
2637
|
+
position: { x: 0.5, y: 0.058 },
|
|
2540
2638
|
sprite: {
|
|
2541
2639
|
kind: "text",
|
|
2542
|
-
strings: ["
|
|
2543
|
-
color: "#
|
|
2544
|
-
font: "
|
|
2545
|
-
align: "
|
|
2640
|
+
strings: ["04:17:26 UTC"],
|
|
2641
|
+
color: "#c8d4e4",
|
|
2642
|
+
font: "600 20px 'SF Mono', monospace",
|
|
2643
|
+
align: "center"
|
|
2546
2644
|
},
|
|
2547
|
-
pulse: { amp: 0.2, period: 2400 },
|
|
2548
2645
|
motion: { type: "static" },
|
|
2549
2646
|
life: { enter: 200, fade: 600 }
|
|
2550
2647
|
},
|
|
2551
2648
|
{
|
|
2552
|
-
key: "
|
|
2649
|
+
key: "status",
|
|
2553
2650
|
count: 1,
|
|
2554
|
-
position: { x: 0.
|
|
2651
|
+
position: { x: 0.965, y: 0.052 },
|
|
2555
2652
|
sprite: {
|
|
2556
2653
|
kind: "text",
|
|
2557
|
-
strings: ["
|
|
2558
|
-
color: "#
|
|
2559
|
-
font: "bold
|
|
2560
|
-
align: "
|
|
2654
|
+
strings: ["\u25CF UPLINK LOCKED \xB7 WATCH C"],
|
|
2655
|
+
color: "#46d17a",
|
|
2656
|
+
font: "bold 11px 'SF Mono', monospace",
|
|
2657
|
+
align: "right"
|
|
2561
2658
|
},
|
|
2659
|
+
pulse: { amp: 0.18, period: 2600 },
|
|
2562
2660
|
motion: { type: "static" },
|
|
2563
2661
|
life: { enter: 200, fade: 600 }
|
|
2564
2662
|
},
|
|
2565
|
-
//
|
|
2663
|
+
// ---- left column: arrays (boots second) ----
|
|
2566
2664
|
{
|
|
2567
|
-
key: "
|
|
2665
|
+
key: "dish1",
|
|
2568
2666
|
count: 1,
|
|
2569
|
-
position: { x: 0.
|
|
2667
|
+
position: { x: 0.035, y: 0.148 },
|
|
2570
2668
|
sprite: {
|
|
2571
2669
|
kind: "text",
|
|
2572
|
-
strings: ["
|
|
2573
|
-
color: "#
|
|
2574
|
-
font: "
|
|
2670
|
+
strings: ["DSA-1 EAST AZ 214.6\xB0 EL 38.2\xB0"],
|
|
2671
|
+
color: "#9fb2c8",
|
|
2672
|
+
font: "11px 'SF Mono', monospace",
|
|
2575
2673
|
align: "left",
|
|
2576
2674
|
baseline: "top"
|
|
2577
2675
|
},
|
|
@@ -2579,267 +2677,245 @@ var DASHBOARD_SPEC = {
|
|
|
2579
2677
|
life: { enter: 700, fade: 600 }
|
|
2580
2678
|
},
|
|
2581
2679
|
{
|
|
2582
|
-
key: "
|
|
2583
|
-
count:
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
font: "bold 26px monospace",
|
|
2590
|
-
align: "left",
|
|
2591
|
-
baseline: "top"
|
|
2592
|
-
},
|
|
2680
|
+
key: "dish1-bars",
|
|
2681
|
+
count: 14,
|
|
2682
|
+
sprite: { kind: "rect", width: [38e-4, 38e-4], aspect: [0.5, 2.6], color: "#2ee6c8" },
|
|
2683
|
+
alpha: [0.3, 0.65],
|
|
2684
|
+
layout: { type: "grid", columns: 14 },
|
|
2685
|
+
region: { x: [0.035, 0.15], y: [0.183, 0.203] },
|
|
2686
|
+
pulse: { amp: 0.42, period: 1500, wave: { wavelength: 0.09, angle: 0 } },
|
|
2593
2687
|
motion: { type: "static" },
|
|
2594
2688
|
life: { enter: 700, fade: 600 }
|
|
2595
2689
|
},
|
|
2596
2690
|
{
|
|
2597
|
-
key: "
|
|
2691
|
+
key: "dish2",
|
|
2598
2692
|
count: 1,
|
|
2599
|
-
position: { x: 0.
|
|
2693
|
+
position: { x: 0.035, y: 0.243 },
|
|
2600
2694
|
sprite: {
|
|
2601
2695
|
kind: "text",
|
|
2602
|
-
strings: ["
|
|
2603
|
-
color: "#
|
|
2604
|
-
font: "
|
|
2696
|
+
strings: ["DSA-2 WEST AZ 097.1\xB0 EL 61.7\xB0"],
|
|
2697
|
+
color: "#9fb2c8",
|
|
2698
|
+
font: "11px 'SF Mono', monospace",
|
|
2605
2699
|
align: "left",
|
|
2606
2700
|
baseline: "top"
|
|
2607
2701
|
},
|
|
2608
2702
|
motion: { type: "static" },
|
|
2609
|
-
life: { enter:
|
|
2703
|
+
life: { enter: 850, fade: 600 }
|
|
2610
2704
|
},
|
|
2611
2705
|
{
|
|
2612
|
-
key: "
|
|
2613
|
-
count:
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
font: "bold 26px monospace",
|
|
2620
|
-
align: "left",
|
|
2621
|
-
baseline: "top"
|
|
2622
|
-
},
|
|
2706
|
+
key: "dish2-bars",
|
|
2707
|
+
count: 14,
|
|
2708
|
+
sprite: { kind: "rect", width: [38e-4, 38e-4], aspect: [0.5, 2.2], color: "#44aaff" },
|
|
2709
|
+
alpha: [0.3, 0.6],
|
|
2710
|
+
layout: { type: "grid", columns: 14 },
|
|
2711
|
+
region: { x: [0.035, 0.15], y: [0.278, 0.298] },
|
|
2712
|
+
pulse: { amp: 0.4, period: 1900, wave: { wavelength: 0.11, angle: 0 } },
|
|
2623
2713
|
motion: { type: "static" },
|
|
2624
|
-
life: { enter:
|
|
2714
|
+
life: { enter: 850, fade: 600 }
|
|
2625
2715
|
},
|
|
2626
2716
|
{
|
|
2627
|
-
key: "
|
|
2717
|
+
key: "dish3",
|
|
2628
2718
|
count: 1,
|
|
2629
|
-
position: { x: 0.
|
|
2719
|
+
position: { x: 0.035, y: 0.338 },
|
|
2630
2720
|
sprite: {
|
|
2631
2721
|
kind: "text",
|
|
2632
|
-
strings: ["
|
|
2633
|
-
color: "#
|
|
2634
|
-
font: "
|
|
2722
|
+
strings: ["DSA-3 POLAR AZ 002.4\xB0 EL 12.9\xB0 \u25B3 WIND"],
|
|
2723
|
+
color: "#5d7089",
|
|
2724
|
+
font: "11px 'SF Mono', monospace",
|
|
2635
2725
|
align: "left",
|
|
2636
2726
|
baseline: "top"
|
|
2637
2727
|
},
|
|
2638
2728
|
motion: { type: "static" },
|
|
2639
|
-
life: { enter:
|
|
2729
|
+
life: { enter: 1e3, fade: 600 }
|
|
2640
2730
|
},
|
|
2641
2731
|
{
|
|
2642
|
-
key: "
|
|
2643
|
-
count:
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
font: "bold 26px monospace",
|
|
2650
|
-
align: "left",
|
|
2651
|
-
baseline: "top"
|
|
2652
|
-
},
|
|
2732
|
+
key: "dish3-bars",
|
|
2733
|
+
count: 14,
|
|
2734
|
+
sprite: { kind: "rect", width: [38e-4, 38e-4], aspect: [0.4, 1.1], color: "#5d7089" },
|
|
2735
|
+
alpha: [0.2, 0.4],
|
|
2736
|
+
layout: { type: "grid", columns: 14 },
|
|
2737
|
+
region: { x: [0.035, 0.15], y: [0.373, 0.393] },
|
|
2738
|
+
pulse: { amp: 0.3, period: 2600, wave: { wavelength: 0.14, angle: 0 } },
|
|
2653
2739
|
motion: { type: "static" },
|
|
2654
|
-
life: { enter:
|
|
2740
|
+
life: { enter: 1e3, fade: 600 }
|
|
2655
2741
|
},
|
|
2656
2742
|
{
|
|
2657
|
-
key: "
|
|
2743
|
+
key: "dish-leds",
|
|
2744
|
+
count: 3,
|
|
2745
|
+
sprite: { kind: "circle", radius: [4e-3, 4e-3], color: "#46d17a" },
|
|
2746
|
+
alpha: [0.9, 0.9],
|
|
2747
|
+
layout: { type: "grid", columns: 1 },
|
|
2748
|
+
region: { x: [0.238, 0.246], y: [0.15, 0.35] },
|
|
2749
|
+
pulse: { amp: 0.25, period: 2100 },
|
|
2750
|
+
motion: { type: "static" },
|
|
2751
|
+
life: { enter: 1e3, fade: 600 }
|
|
2752
|
+
},
|
|
2753
|
+
// carrier + doppler + station env
|
|
2754
|
+
{
|
|
2755
|
+
key: "carrier-wave",
|
|
2756
|
+
count: 30,
|
|
2757
|
+
sprite: { kind: "rect", width: [32e-4, 32e-4], aspect: [0.4, 3.6], color: "#2ee6c8" },
|
|
2758
|
+
alpha: [0.25, 0.6],
|
|
2759
|
+
layout: { type: "grid", columns: 30 },
|
|
2760
|
+
region: { x: [0.035, 0.245], y: [0.47, 0.5] },
|
|
2761
|
+
pulse: { amp: 0.5, period: 2100, wave: { wavelength: 0.16, angle: 0 } },
|
|
2762
|
+
motion: { type: "static" },
|
|
2763
|
+
life: { enter: 1150, fade: 600 }
|
|
2764
|
+
},
|
|
2765
|
+
{
|
|
2766
|
+
key: "doppler",
|
|
2658
2767
|
count: 1,
|
|
2659
|
-
position: { x: 0.
|
|
2768
|
+
position: { x: 0.035, y: 0.535 },
|
|
2660
2769
|
sprite: {
|
|
2661
2770
|
kind: "text",
|
|
2662
|
-
strings: ["
|
|
2663
|
-
color: "#
|
|
2664
|
-
font: "
|
|
2771
|
+
strings: ["CARRIER X-BAND \xB7 DOPPLER +2.114 kHz \xB7 DRIFT 0.03"],
|
|
2772
|
+
color: "#9fb2c8",
|
|
2773
|
+
font: "10px 'SF Mono', monospace",
|
|
2665
2774
|
align: "left",
|
|
2666
2775
|
baseline: "top"
|
|
2667
2776
|
},
|
|
2668
2777
|
motion: { type: "static" },
|
|
2669
|
-
life: { enter:
|
|
2778
|
+
life: { enter: 1150, fade: 600 }
|
|
2670
2779
|
},
|
|
2671
2780
|
{
|
|
2672
|
-
key: "
|
|
2781
|
+
key: "env-line",
|
|
2673
2782
|
count: 1,
|
|
2674
|
-
position: { x: 0.
|
|
2783
|
+
position: { x: 0.035, y: 0.6 },
|
|
2675
2784
|
sprite: {
|
|
2676
2785
|
kind: "text",
|
|
2677
|
-
strings: ["
|
|
2678
|
-
color: "#
|
|
2679
|
-
font: "
|
|
2786
|
+
strings: ["STATION \xB7 PWR 28.1 V \xB7 THERM 312 K \xB7 GYRO NOM \xB7 PROP 81%"],
|
|
2787
|
+
color: "#5d7089",
|
|
2788
|
+
font: "10px 'SF Mono', monospace",
|
|
2680
2789
|
align: "left",
|
|
2681
2790
|
baseline: "top"
|
|
2682
2791
|
},
|
|
2683
2792
|
motion: { type: "static" },
|
|
2684
|
-
life: { enter:
|
|
2793
|
+
life: { enter: 1300, fade: 600 }
|
|
2685
2794
|
},
|
|
2686
|
-
//
|
|
2795
|
+
// ---- center: the orbital plot (boots third) ----
|
|
2687
2796
|
{
|
|
2688
|
-
key: "
|
|
2797
|
+
key: "moon",
|
|
2689
2798
|
count: 1,
|
|
2690
|
-
position: { x: 0.
|
|
2691
|
-
sprite: { kind: "
|
|
2692
|
-
alpha: [0.
|
|
2799
|
+
position: { x: 0.455, y: 0.4 },
|
|
2800
|
+
sprite: { kind: "circle", radius: [0.028, 0.028], color: "#8fa3bd", soft: true },
|
|
2801
|
+
alpha: [0.9, 0.9],
|
|
2693
2802
|
motion: { type: "static" },
|
|
2694
2803
|
life: { enter: 1200, fade: 700 }
|
|
2695
2804
|
},
|
|
2696
2805
|
{
|
|
2697
|
-
key: "
|
|
2698
|
-
count:
|
|
2699
|
-
|
|
2700
|
-
|
|
2806
|
+
key: "orbit-guides",
|
|
2807
|
+
count: 3,
|
|
2808
|
+
// All three guides pin to the plot centre; the seeded radius range
|
|
2809
|
+
// spreads them into concentric orbits (`position` is count:1-only).
|
|
2810
|
+
region: { x: [0.455, 0.455], y: [0.4, 0.4] },
|
|
2811
|
+
sprite: { kind: "ring", radius: [0.075, 0.185], color: "#1e3a52", width: 11e-4 },
|
|
2701
2812
|
alpha: [0.55, 0.55],
|
|
2702
|
-
blend: "lighter",
|
|
2703
|
-
pulse: { amp: 0.25, period: 4e3 },
|
|
2704
|
-
grow: { amp: 0.05, period: 4e3 },
|
|
2705
2813
|
motion: { type: "static" },
|
|
2706
2814
|
life: { enter: 1200, fade: 700 }
|
|
2707
2815
|
},
|
|
2708
2816
|
{
|
|
2709
|
-
key: "
|
|
2710
|
-
count:
|
|
2711
|
-
position: { x: 0.4, y: 0.29 },
|
|
2817
|
+
key: "fleet",
|
|
2818
|
+
count: 5,
|
|
2712
2819
|
sprite: {
|
|
2713
|
-
kind: "
|
|
2714
|
-
|
|
2715
|
-
color: "#445566",
|
|
2716
|
-
font: "9px monospace",
|
|
2717
|
-
align: "center"
|
|
2718
|
-
},
|
|
2719
|
-
motion: { type: "static" },
|
|
2720
|
-
life: { enter: 1200, fade: 700 }
|
|
2721
|
-
},
|
|
2722
|
-
{
|
|
2723
|
-
key: "gauge-value",
|
|
2724
|
-
count: 1,
|
|
2725
|
-
position: { x: 0.4, y: 0.375 },
|
|
2726
|
-
sprite: {
|
|
2727
|
-
kind: "text",
|
|
2728
|
-
strings: ["73%"],
|
|
2729
|
-
color: "#2ee6c8",
|
|
2730
|
-
font: "bold 34px monospace",
|
|
2731
|
-
align: "center"
|
|
2732
|
-
},
|
|
2733
|
-
motion: { type: "static" },
|
|
2734
|
-
life: { enter: 1200, fade: 700 }
|
|
2735
|
-
},
|
|
2736
|
-
{
|
|
2737
|
-
key: "equalizer",
|
|
2738
|
-
count: 22,
|
|
2739
|
-
sprite: {
|
|
2740
|
-
kind: "rect",
|
|
2741
|
-
width: [5e-3, 5e-3],
|
|
2742
|
-
aspect: [0.6, 3.4],
|
|
2820
|
+
kind: "circle",
|
|
2821
|
+
radius: [45e-4, 65e-4],
|
|
2743
2822
|
color: "#2ee6c8",
|
|
2744
|
-
colors: ["#2ee6c8", "#44aaff", "#aa88ff"]
|
|
2745
|
-
colorWeights: [3, 2, 1]
|
|
2823
|
+
colors: ["#2ee6c8", "#44aaff", "#ffd166", "#aa88ff", "#ff9f43"]
|
|
2746
2824
|
},
|
|
2747
|
-
alpha: [0.
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
life: { enter:
|
|
2825
|
+
alpha: [0.85, 0.95],
|
|
2826
|
+
blend: "lighter",
|
|
2827
|
+
motion: { type: "orbit", speed: [4, 11], radius: [0.075, 0.185], center: { x: 0.455, y: 0.4 } },
|
|
2828
|
+
trail: { length: 9, fade: 0.75 },
|
|
2829
|
+
// The relay web: each craft holds a comm chain to its neighbours.
|
|
2830
|
+
links: { k: 2, maxDist: 0.5, color: "#2ee6c8", alpha: 0.2, width: 12e-4, mode: "chain" },
|
|
2831
|
+
life: { enter: 1350, fade: 700 }
|
|
2754
2832
|
},
|
|
2755
|
-
// --- right column: agenda + devices (boots fourth) ---
|
|
2756
2833
|
{
|
|
2757
|
-
key: "
|
|
2834
|
+
key: "fleet-legend",
|
|
2758
2835
|
count: 1,
|
|
2759
|
-
position: { x: 0.
|
|
2836
|
+
position: { x: 0.455, y: 0.63 },
|
|
2760
2837
|
sprite: {
|
|
2761
2838
|
kind: "text",
|
|
2762
|
-
strings: ["
|
|
2763
|
-
color: "#
|
|
2764
|
-
font: "9px monospace",
|
|
2765
|
-
align: "
|
|
2839
|
+
strings: ["TRACKING 5 \xB7 KESTREL TIDE-2 LIMELIGHT CATWALK-1 SLIPSTREAM"],
|
|
2840
|
+
color: "#5d7089",
|
|
2841
|
+
font: "9px 'SF Mono', monospace",
|
|
2842
|
+
align: "center",
|
|
2766
2843
|
baseline: "top"
|
|
2767
2844
|
},
|
|
2768
2845
|
motion: { type: "static" },
|
|
2769
|
-
life: { enter:
|
|
2846
|
+
life: { enter: 1500, fade: 700 }
|
|
2770
2847
|
},
|
|
2848
|
+
// pass schedule under the plot
|
|
2771
2849
|
{
|
|
2772
|
-
key: "
|
|
2850
|
+
key: "pass-label",
|
|
2773
2851
|
count: 1,
|
|
2774
|
-
position: { x: 0.
|
|
2852
|
+
position: { x: 0.3, y: 0.69 },
|
|
2775
2853
|
sprite: {
|
|
2776
2854
|
kind: "text",
|
|
2777
|
-
strings: ["
|
|
2778
|
-
color: "#
|
|
2779
|
-
font: "
|
|
2855
|
+
strings: ["PASS SCHEDULE"],
|
|
2856
|
+
color: "#41536b",
|
|
2857
|
+
font: "9px 'SF Mono', monospace",
|
|
2780
2858
|
align: "left",
|
|
2781
|
-
baseline: "top"
|
|
2782
|
-
maxWidth: 0.2593
|
|
2859
|
+
baseline: "top"
|
|
2783
2860
|
},
|
|
2784
2861
|
motion: { type: "static" },
|
|
2785
|
-
life: { enter:
|
|
2862
|
+
life: { enter: 1650, fade: 600 }
|
|
2786
2863
|
},
|
|
2787
2864
|
{
|
|
2788
|
-
key: "
|
|
2865
|
+
key: "pass-1",
|
|
2789
2866
|
count: 1,
|
|
2790
|
-
position: { x: 0.
|
|
2867
|
+
position: { x: 0.3, y: 0.72 },
|
|
2791
2868
|
sprite: {
|
|
2792
2869
|
kind: "text",
|
|
2793
|
-
strings: ["
|
|
2794
|
-
color: "#
|
|
2795
|
-
font: "11px monospace",
|
|
2870
|
+
strings: ["04:41 CATWALK-1 ACQUIRE \xB7 DSA-1 \u25B2 12 MIN"],
|
|
2871
|
+
color: "#c8d4e4",
|
|
2872
|
+
font: "11px 'SF Mono', monospace",
|
|
2796
2873
|
align: "left",
|
|
2797
|
-
baseline: "top"
|
|
2798
|
-
maxWidth: 0.2593
|
|
2874
|
+
baseline: "top"
|
|
2799
2875
|
},
|
|
2800
2876
|
motion: { type: "static" },
|
|
2801
|
-
life: { enter:
|
|
2877
|
+
life: { enter: 1650, fade: 600 }
|
|
2802
2878
|
},
|
|
2803
2879
|
{
|
|
2804
|
-
key: "
|
|
2880
|
+
key: "pass-2",
|
|
2805
2881
|
count: 1,
|
|
2806
|
-
position: { x: 0.
|
|
2882
|
+
position: { x: 0.3, y: 0.757 },
|
|
2807
2883
|
sprite: {
|
|
2808
2884
|
kind: "text",
|
|
2809
|
-
strings: ["
|
|
2810
|
-
color: "#
|
|
2811
|
-
font: "11px monospace",
|
|
2885
|
+
strings: ["05:03 TIDE-2 OCCULT EXIT \xB7 DSA-2"],
|
|
2886
|
+
color: "#7f93ab",
|
|
2887
|
+
font: "11px 'SF Mono', monospace",
|
|
2812
2888
|
align: "left",
|
|
2813
|
-
baseline: "top"
|
|
2814
|
-
maxWidth: 0.2593
|
|
2889
|
+
baseline: "top"
|
|
2815
2890
|
},
|
|
2816
2891
|
motion: { type: "static" },
|
|
2817
|
-
life: { enter:
|
|
2892
|
+
life: { enter: 1750, fade: 600 }
|
|
2818
2893
|
},
|
|
2819
2894
|
{
|
|
2820
|
-
key: "
|
|
2895
|
+
key: "pass-3",
|
|
2821
2896
|
count: 1,
|
|
2822
|
-
position: { x: 0.
|
|
2897
|
+
position: { x: 0.3, y: 0.794 },
|
|
2823
2898
|
sprite: {
|
|
2824
2899
|
kind: "text",
|
|
2825
|
-
strings: ["
|
|
2826
|
-
color: "#
|
|
2827
|
-
font: "
|
|
2900
|
+
strings: ["05:47 KESTREL RANGING \xB7 DSA-1+2"],
|
|
2901
|
+
color: "#7f93ab",
|
|
2902
|
+
font: "11px 'SF Mono', monospace",
|
|
2828
2903
|
align: "left",
|
|
2829
2904
|
baseline: "top"
|
|
2830
2905
|
},
|
|
2831
2906
|
motion: { type: "static" },
|
|
2832
|
-
life: { enter:
|
|
2907
|
+
life: { enter: 1850, fade: 600 }
|
|
2833
2908
|
},
|
|
2909
|
+
// ---- right column: telemetry (boots fourth) ----
|
|
2834
2910
|
{
|
|
2835
|
-
key: "
|
|
2911
|
+
key: "signal-label",
|
|
2836
2912
|
count: 1,
|
|
2837
|
-
position: { x: 0.
|
|
2913
|
+
position: { x: 0.665, y: 0.115 },
|
|
2838
2914
|
sprite: {
|
|
2839
2915
|
kind: "text",
|
|
2840
|
-
strings: ["
|
|
2841
|
-
color: "#
|
|
2842
|
-
font: "
|
|
2916
|
+
strings: ["PRIMARY CARRIER \xB7 CATWALK-1"],
|
|
2917
|
+
color: "#41536b",
|
|
2918
|
+
font: "9px 'SF Mono', monospace",
|
|
2843
2919
|
align: "left",
|
|
2844
2920
|
baseline: "top"
|
|
2845
2921
|
},
|
|
@@ -2847,14 +2923,14 @@ var DASHBOARD_SPEC = {
|
|
|
2847
2923
|
life: { enter: 1700, fade: 600 }
|
|
2848
2924
|
},
|
|
2849
2925
|
{
|
|
2850
|
-
key: "
|
|
2926
|
+
key: "signal-value",
|
|
2851
2927
|
count: 1,
|
|
2852
|
-
position: { x: 0.
|
|
2928
|
+
position: { x: 0.665, y: 0.14 },
|
|
2853
2929
|
sprite: {
|
|
2854
2930
|
kind: "text",
|
|
2855
|
-
strings: ["
|
|
2856
|
-
color: "#
|
|
2857
|
-
font: "
|
|
2931
|
+
strings: ["-112.4 dBm"],
|
|
2932
|
+
color: "#ffd166",
|
|
2933
|
+
font: "bold 30px 'SF Mono', monospace",
|
|
2858
2934
|
align: "left",
|
|
2859
2935
|
baseline: "top"
|
|
2860
2936
|
},
|
|
@@ -2862,130 +2938,130 @@ var DASHBOARD_SPEC = {
|
|
|
2862
2938
|
life: { enter: 1700, fade: 600 }
|
|
2863
2939
|
},
|
|
2864
2940
|
{
|
|
2865
|
-
key: "
|
|
2941
|
+
key: "telemetry-row",
|
|
2866
2942
|
count: 1,
|
|
2867
|
-
position: { x: 0.
|
|
2943
|
+
position: { x: 0.665, y: 0.215 },
|
|
2868
2944
|
sprite: {
|
|
2869
2945
|
kind: "text",
|
|
2870
|
-
strings: ["
|
|
2871
|
-
color: "#
|
|
2872
|
-
font: "11px monospace",
|
|
2946
|
+
strings: ["RANGE 1.28 LS DOWNLINK 2.048 Mb/s BUFFER 38%"],
|
|
2947
|
+
color: "#9fb2c8",
|
|
2948
|
+
font: "11px 'SF Mono', monospace",
|
|
2873
2949
|
align: "left",
|
|
2874
2950
|
baseline: "top"
|
|
2875
2951
|
},
|
|
2876
2952
|
motion: { type: "static" },
|
|
2877
|
-
life: { enter:
|
|
2953
|
+
life: { enter: 1800, fade: 600 }
|
|
2878
2954
|
},
|
|
2955
|
+
// event log
|
|
2879
2956
|
{
|
|
2880
|
-
key: "
|
|
2957
|
+
key: "feed-1",
|
|
2881
2958
|
count: 1,
|
|
2882
|
-
position: { x: 0.
|
|
2959
|
+
position: { x: 0.665, y: 0.3 },
|
|
2883
2960
|
sprite: {
|
|
2884
2961
|
kind: "text",
|
|
2885
|
-
strings: ["
|
|
2886
|
-
color: "#
|
|
2887
|
-
font: "
|
|
2962
|
+
strings: ["04:15:02 DSA-1 LOCK RE-ACQUIRED"],
|
|
2963
|
+
color: "#9fb2c8",
|
|
2964
|
+
font: "10px 'SF Mono', monospace",
|
|
2888
2965
|
align: "left",
|
|
2889
2966
|
baseline: "top"
|
|
2890
2967
|
},
|
|
2891
2968
|
motion: { type: "static" },
|
|
2892
|
-
life: { enter:
|
|
2969
|
+
life: { enter: 1950, fade: 600 }
|
|
2893
2970
|
},
|
|
2894
|
-
// --- bottom: activity feed (boots last) ---
|
|
2895
2971
|
{
|
|
2896
|
-
key: "feed-
|
|
2972
|
+
key: "feed-2",
|
|
2897
2973
|
count: 1,
|
|
2898
|
-
position: { x: 0.
|
|
2974
|
+
position: { x: 0.665, y: 0.334 },
|
|
2899
2975
|
sprite: {
|
|
2900
2976
|
kind: "text",
|
|
2901
|
-
strings: ["
|
|
2902
|
-
color: "#
|
|
2903
|
-
font: "
|
|
2977
|
+
strings: ["04:12:47 CATWALK-1 WHEEL DESAT OK"],
|
|
2978
|
+
color: "#7f93ab",
|
|
2979
|
+
font: "10px 'SF Mono', monospace",
|
|
2904
2980
|
align: "left",
|
|
2905
2981
|
baseline: "top"
|
|
2906
2982
|
},
|
|
2907
2983
|
motion: { type: "static" },
|
|
2908
|
-
life: { enter:
|
|
2984
|
+
life: { enter: 2050, fade: 600 }
|
|
2909
2985
|
},
|
|
2910
2986
|
{
|
|
2911
|
-
key: "feed-
|
|
2987
|
+
key: "feed-3",
|
|
2912
2988
|
count: 1,
|
|
2913
|
-
position: { x: 0.
|
|
2989
|
+
position: { x: 0.665, y: 0.368 },
|
|
2914
2990
|
sprite: {
|
|
2915
2991
|
kind: "text",
|
|
2916
|
-
strings: ["
|
|
2917
|
-
color: "#
|
|
2918
|
-
font: "10px monospace",
|
|
2992
|
+
strings: ["04:09:31 RANGING RESIDUAL 0.4 m"],
|
|
2993
|
+
color: "#5d7089",
|
|
2994
|
+
font: "10px 'SF Mono', monospace",
|
|
2919
2995
|
align: "left",
|
|
2920
|
-
baseline: "top"
|
|
2921
|
-
maxWidth: 0.5556
|
|
2996
|
+
baseline: "top"
|
|
2922
2997
|
},
|
|
2923
2998
|
motion: { type: "static" },
|
|
2924
|
-
life: { enter:
|
|
2999
|
+
life: { enter: 2150, fade: 600 }
|
|
2925
3000
|
},
|
|
3001
|
+
// alert + relay load
|
|
2926
3002
|
{
|
|
2927
|
-
key: "
|
|
3003
|
+
key: "alert",
|
|
2928
3004
|
count: 1,
|
|
2929
|
-
position: { x: 0.
|
|
3005
|
+
position: { x: 0.665, y: 0.49 },
|
|
2930
3006
|
sprite: {
|
|
2931
3007
|
kind: "text",
|
|
2932
|
-
strings: ["
|
|
2933
|
-
color: "#
|
|
2934
|
-
font: "
|
|
3008
|
+
strings: ["\u25B3 SOLAR FLUX ELEVATED \u2014 MONITORING"],
|
|
3009
|
+
color: "#ff9f43",
|
|
3010
|
+
font: "bold 11px 'SF Mono', monospace",
|
|
2935
3011
|
align: "left",
|
|
2936
|
-
baseline: "top"
|
|
2937
|
-
maxWidth: 0.5556
|
|
3012
|
+
baseline: "top"
|
|
2938
3013
|
},
|
|
3014
|
+
pulse: { amp: 0.22, period: 3400 },
|
|
2939
3015
|
motion: { type: "static" },
|
|
2940
|
-
life: { enter:
|
|
3016
|
+
life: { enter: 2450, fade: 600 }
|
|
2941
3017
|
},
|
|
2942
3018
|
{
|
|
2943
|
-
key: "
|
|
2944
|
-
count:
|
|
2945
|
-
position: { x: 0.06, y: 0.86 },
|
|
3019
|
+
key: "load-bars",
|
|
3020
|
+
count: 24,
|
|
2946
3021
|
sprite: {
|
|
2947
|
-
kind: "
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
maxWidth: 0.5556
|
|
3022
|
+
kind: "rect",
|
|
3023
|
+
width: [42e-4, 42e-4],
|
|
3024
|
+
aspect: [0.5, 3.2],
|
|
3025
|
+
color: "#aa88ff",
|
|
3026
|
+
colors: ["#aa88ff", "#44aaff", "#2ee6c8"],
|
|
3027
|
+
colorWeights: [2, 2, 3]
|
|
2954
3028
|
},
|
|
3029
|
+
alpha: [0.3, 0.65],
|
|
3030
|
+
layout: { type: "grid", columns: 24 },
|
|
3031
|
+
region: { x: [0.665, 0.965], y: [0.58, 0.615] },
|
|
3032
|
+
pulse: { amp: 0.45, period: 1800, wave: { wavelength: 0.12, angle: 0 } },
|
|
2955
3033
|
motion: { type: "static" },
|
|
2956
|
-
life: { enter:
|
|
3034
|
+
life: { enter: 2550, fade: 600 }
|
|
2957
3035
|
},
|
|
2958
3036
|
{
|
|
2959
|
-
key: "
|
|
3037
|
+
key: "load-note",
|
|
2960
3038
|
count: 1,
|
|
2961
|
-
position: { x: 0.
|
|
3039
|
+
position: { x: 0.665, y: 0.65 },
|
|
2962
3040
|
sprite: {
|
|
2963
3041
|
kind: "text",
|
|
2964
|
-
strings: ["
|
|
2965
|
-
color: "#
|
|
2966
|
-
font: "10px monospace",
|
|
3042
|
+
strings: ["RELAY LOAD \xB7 QUEUE 14 FRAMES \xB7 NOMINAL"],
|
|
3043
|
+
color: "#5d7089",
|
|
3044
|
+
font: "10px 'SF Mono', monospace",
|
|
2967
3045
|
align: "left",
|
|
2968
|
-
baseline: "top"
|
|
2969
|
-
maxWidth: 0.5556
|
|
3046
|
+
baseline: "top"
|
|
2970
3047
|
},
|
|
2971
3048
|
motion: { type: "static" },
|
|
2972
|
-
life: { enter:
|
|
3049
|
+
life: { enter: 2550, fade: 600 }
|
|
2973
3050
|
},
|
|
3051
|
+
// ---- footer band ----
|
|
2974
3052
|
{
|
|
2975
|
-
key: "
|
|
3053
|
+
key: "footer",
|
|
2976
3054
|
count: 1,
|
|
2977
|
-
position: { x: 0.
|
|
3055
|
+
position: { x: 0.035, y: 0.95 },
|
|
2978
3056
|
sprite: {
|
|
2979
3057
|
kind: "text",
|
|
2980
|
-
strings: ["
|
|
2981
|
-
color: "#
|
|
2982
|
-
font: "
|
|
2983
|
-
align: "left"
|
|
2984
|
-
baseline: "top",
|
|
2985
|
-
maxWidth: 0.5556
|
|
3058
|
+
strings: ["NET STATE GREEN \xB7 3 ARRAYS \xB7 5 CARRIERS \xB7 DSN HANDOVER 23:34 \xB7 NEXT WINDOW 04:41:00"],
|
|
3059
|
+
color: "#41536b",
|
|
3060
|
+
font: "9px 'SF Mono', monospace",
|
|
3061
|
+
align: "left"
|
|
2986
3062
|
},
|
|
2987
3063
|
motion: { type: "static" },
|
|
2988
|
-
life: { enter:
|
|
3064
|
+
life: { enter: 2750, fade: 600 }
|
|
2989
3065
|
}
|
|
2990
3066
|
]
|
|
2991
3067
|
};
|
|
@@ -3123,6 +3199,120 @@ var MATRIX_RAIN_SPEC = {
|
|
|
3123
3199
|
]
|
|
3124
3200
|
};
|
|
3125
3201
|
|
|
3202
|
+
// src/examples/nostalghia-candle.ts
|
|
3203
|
+
var NOSTALGHIA_CANDLE_SPEC = {
|
|
3204
|
+
schemaVersion: 1,
|
|
3205
|
+
id: "nostalghia-candle",
|
|
3206
|
+
label: "Nostalghia's Candle",
|
|
3207
|
+
seed: 1983,
|
|
3208
|
+
motionIntensity: "calm",
|
|
3209
|
+
background: {
|
|
3210
|
+
type: "gradient",
|
|
3211
|
+
stops: [
|
|
3212
|
+
{ at: 0, color: "#050302" },
|
|
3213
|
+
{ at: 0.55, color: "#0a0704" },
|
|
3214
|
+
{ at: 1, color: "#120c08" }
|
|
3215
|
+
]
|
|
3216
|
+
},
|
|
3217
|
+
layers: [
|
|
3218
|
+
{
|
|
3219
|
+
key: "halo",
|
|
3220
|
+
count: 1,
|
|
3221
|
+
position: { x: 0.5, y: 0.52 },
|
|
3222
|
+
sprite: {
|
|
3223
|
+
kind: "circle",
|
|
3224
|
+
radius: [0.11, 0.11],
|
|
3225
|
+
color: "#c4782a",
|
|
3226
|
+
soft: true
|
|
3227
|
+
},
|
|
3228
|
+
// Base 0.04 + amp 0.02 → breathes ~0.02..0.06; never clamps to 0.
|
|
3229
|
+
// (pulse.amp is ADDED to alpha, not multiplied.) Kept subordinate to the flame.
|
|
3230
|
+
alpha: [0.04, 0.04],
|
|
3231
|
+
blend: "lighter",
|
|
3232
|
+
pulse: { amp: 0.02, period: 1e4 },
|
|
3233
|
+
grow: { amp: 0.08, period: 1e4 },
|
|
3234
|
+
motion: { type: "static" }
|
|
3235
|
+
},
|
|
3236
|
+
{
|
|
3237
|
+
key: "smoke",
|
|
3238
|
+
count: 3,
|
|
3239
|
+
sprite: {
|
|
3240
|
+
kind: "circle",
|
|
3241
|
+
radius: [0.01, 0.022],
|
|
3242
|
+
color: "#6a6258",
|
|
3243
|
+
soft: true
|
|
3244
|
+
},
|
|
3245
|
+
alpha: [0.02, 0.04],
|
|
3246
|
+
blend: "lighter",
|
|
3247
|
+
region: { x: [0.46, 0.54], y: [0.36, 0.48] },
|
|
3248
|
+
pulse: { amp: 0.015, period: 4500 },
|
|
3249
|
+
motion: { type: "rise", speed: [2e-3, 4e-3], sway: 8e-3 }
|
|
3250
|
+
},
|
|
3251
|
+
{
|
|
3252
|
+
key: "flame-glow",
|
|
3253
|
+
count: 1,
|
|
3254
|
+
sprite: {
|
|
3255
|
+
kind: "circle",
|
|
3256
|
+
radius: [0.028, 0.028],
|
|
3257
|
+
color: "#ffb040",
|
|
3258
|
+
soft: true
|
|
3259
|
+
},
|
|
3260
|
+
alpha: [0.32, 0.32],
|
|
3261
|
+
blend: "lighter",
|
|
3262
|
+
pulse: { amp: 0.12, period: 1400 },
|
|
3263
|
+
grow: { amp: 0.4, period: 1600 },
|
|
3264
|
+
// Tiny orbit = positional lean without drifting off-center (wander has vx).
|
|
3265
|
+
motion: {
|
|
3266
|
+
type: "orbit",
|
|
3267
|
+
speed: [18, 18],
|
|
3268
|
+
radius: [3e-3, 3e-3],
|
|
3269
|
+
center: { x: 0.5, y: 0.52 }
|
|
3270
|
+
}
|
|
3271
|
+
},
|
|
3272
|
+
{
|
|
3273
|
+
key: "flame-core",
|
|
3274
|
+
count: 1,
|
|
3275
|
+
sprite: {
|
|
3276
|
+
kind: "circle",
|
|
3277
|
+
radius: [0.014, 0.014],
|
|
3278
|
+
color: "#fff6e0",
|
|
3279
|
+
soft: true
|
|
3280
|
+
},
|
|
3281
|
+
alpha: [0.95, 0.95],
|
|
3282
|
+
blend: "lighter",
|
|
3283
|
+
pulse: { amp: 0.25, period: 900 },
|
|
3284
|
+
grow: { amp: 0.55, period: 1100 },
|
|
3285
|
+
motion: {
|
|
3286
|
+
type: "orbit",
|
|
3287
|
+
speed: [22, 22],
|
|
3288
|
+
radius: [25e-4, 25e-4],
|
|
3289
|
+
center: { x: 0.5, y: 0.52 }
|
|
3290
|
+
}
|
|
3291
|
+
},
|
|
3292
|
+
{
|
|
3293
|
+
key: "embers",
|
|
3294
|
+
count: 7,
|
|
3295
|
+
sprite: {
|
|
3296
|
+
kind: "circle",
|
|
3297
|
+
radius: [18e-4, 4e-3],
|
|
3298
|
+
color: "#e08a34",
|
|
3299
|
+
soft: true
|
|
3300
|
+
},
|
|
3301
|
+
alpha: [0.4, 0.8],
|
|
3302
|
+
blend: "lighter",
|
|
3303
|
+
region: { x: [0.35, 0.65], y: [0.4, 0.7] },
|
|
3304
|
+
pulse: { amp: 0.2, period: 2200 },
|
|
3305
|
+
trail: { length: 2200, fade: 1 },
|
|
3306
|
+
motion: {
|
|
3307
|
+
type: "drift",
|
|
3308
|
+
speed: [4e-3, 0.012],
|
|
3309
|
+
angle: 270,
|
|
3310
|
+
bob: 8e-3
|
|
3311
|
+
}
|
|
3312
|
+
}
|
|
3313
|
+
]
|
|
3314
|
+
};
|
|
3315
|
+
|
|
3126
3316
|
// src/examples/polygons.ts
|
|
3127
3317
|
var POLYGONS_SPEC = {
|
|
3128
3318
|
schemaVersion: 1,
|
|
@@ -3568,7 +3758,8 @@ var SCHEMA_EXAMPLES = [
|
|
|
3568
3758
|
{ id: "warp-tunnel", label: "Warp Tunnel", spec: WARP_TUNNEL_SPEC },
|
|
3569
3759
|
{ id: "polygons", label: "Polygons", spec: POLYGONS_SPEC },
|
|
3570
3760
|
{ id: "matrix-rain", label: "Matrix Rain", spec: MATRIX_RAIN_SPEC },
|
|
3571
|
-
{ id: "procession", label: "Night Procession", spec: PROCESSION_SPEC }
|
|
3761
|
+
{ id: "procession", label: "Night Procession", spec: PROCESSION_SPEC },
|
|
3762
|
+
{ id: "nostalghia-candle", label: "Nostalghia's Candle", spec: NOSTALGHIA_CANDLE_SPEC }
|
|
3572
3763
|
];
|
|
3573
3764
|
var EXAMPLE_SPECS = SCHEMA_EXAMPLES.map((e) => e.spec);
|
|
3574
3765
|
var EXAMPLE_BY_ID = Object.fromEntries(
|
|
@@ -3585,6 +3776,7 @@ export {
|
|
|
3585
3776
|
LANTERNS_SPEC,
|
|
3586
3777
|
LIMITS,
|
|
3587
3778
|
MATRIX_RAIN_SPEC,
|
|
3779
|
+
NOSTALGHIA_CANDLE_SPEC,
|
|
3588
3780
|
ORRERY_SPEC,
|
|
3589
3781
|
POLYGONS_SPEC,
|
|
3590
3782
|
PROCESSION_SPEC,
|
|
@@ -3616,6 +3808,7 @@ export {
|
|
|
3616
3808
|
perceiveScene,
|
|
3617
3809
|
positionAt,
|
|
3618
3810
|
renderBrailleMap,
|
|
3811
|
+
renderDensityMap,
|
|
3619
3812
|
resolveSpecPath,
|
|
3620
3813
|
rotationAt,
|
|
3621
3814
|
sizeAt,
|
|
@@ -3623,6 +3816,7 @@ export {
|
|
|
3623
3816
|
spriteVariants,
|
|
3624
3817
|
steerablePaths,
|
|
3625
3818
|
structuralSignature,
|
|
3819
|
+
textSprites,
|
|
3626
3820
|
validateSpec
|
|
3627
3821
|
};
|
|
3628
3822
|
//# sourceMappingURL=index.js.map
|