LingSys
↓ 0 downloadsYour machine's memory, GPU, motherboard and network, drawn and played in the Ling design system: LingSys, a small build for USB liquid-cooler displays, LingNet for IPv4/IPv6, DNS and packets, and a LingOS edition. 64-bit and 32-bit Windows builds included.
Keywords system-monitor, visualization, network, ipv6, gpu, lcd, lingos, ling
lingfu install LingSysCode / Files (48)
hatchmini.ling
# ══════════════════════════════════════════════════════════════════════════════
# HatchSYS: the machine's memory, GPU, motherboard and network, drawn and played
# in the Ling design system.
#
# GENERATED FILE: edit the parts in src/ and run `python tools/build.py`.
# (One file on purpose: the Ling JIT does not see top-level bindings of `use`d modules.)
#
# Line work only: circles, squares, Daemon tiles, Chesilin rings, crosshatch.
# circle = something comes in (a page read, a packet received, a frame drawn)
# square = something goes out (a page written, a packet sent, a copy)
# The same numbers drive an additive synth: seven channels x four partials plus four
# shimmer partials, 32 audio_tone slots in all, and a short chime for every pulse.
#
# Sections: MAIN (system overview) | MEMORY | GPU | BOARD | NETWORK
# Keys: 0 main, 1-4 section, LEFT/RIGHT section, TAB or SPACE next view, UP/DOWN pick GPU,
# A auto-cycle, H hud, M mute, ESC back (quit on MAIN), Q quit. The bottom menu is clickable.
# Run: ling run hatchsys.ling (run.ps1 starts the samplers for live data first)
# Args: full (borderless fullscreen) | sim (ignore the .snap files) | shot (save a screenshot per view, quit)
# ══════════════════════════════════════════════════════════════════════════════
bind TAU = 6.283185307179586
bind HUE = [357.0, 28.0, 46.0, 140.0, 215.0, 247.0, 285.0]
bind CAT_NAME = ["KERNEL", "STANDBY", "DATA", "MODIFIED", "MAPPED", "COMPRESSED", "FREE"]
bind CAT_LET = "ALBCKFM"
bind ANG1 = [0.785, 0.52, 1.05, 0.0, 2.09, 1.31, 0.26]
bind ORDER = [0, 2, 4, 5, 3, 1, 6]
bind RATIO = [1.0, 1.5, 2.0, 2.25, 3.0, 3.75, 4.5]
bind READ_W = [0.15, 0.9, 0.5, 0.0, 0.8, 0.2, 0.0]
bind WRITE_W = [0.1, 0.0, 0.7, 1.0, 0.2, 0.5, 0.0]
# sections and their views
bind SEC_NAME = ["MAIN", "MEMORY", "GPU", "BOARD", "NETWORK"]
bind SEC_HUE = [2, 4, 3, 1, 6]
bind SEC_LET = "HMGBN"
bind SUB_NAME = [["OVERVIEW"], ["RINGS", "TILES", "ORBITS", "WEAVE"], ["ENGINES", "VRAM", "DIALS", "FLEET"], ["LAYOUT", "CORES", "SIGNALS"], ["FLOW", "LINKS", "TRACES"]]
# the seven channels of every section: ring names, lane names, pulse categories (same order as the Ling hues)
bind CH_GPU = ["3D", "COMPUTE", "COPY", "DECODE", "ENCODE", "VRAM", "POWER"]
bind CH_BRD = ["CORES", "MEMBUS", "PCIE", "CHIPSET", "STORAGE", "NETWORK", "THERMAL"]
bind CH_NET = ["RX", "TX", "PKT IN", "PKT OUT", "TCP", "UDP", "RETRANS"]
bind CH_MAIN = ["MEMORY", "GPU", "CPU", "NETWORK", "VRAM", "DISK", "HEAT"]
bind CH_ALL = [CAT_NAME, CH_MAIN, CH_GPU, CH_BRD, CH_NET]
bind IDM = [0, 1, 2, 3, 4, 5, 6]
bind CH_LET_GPU = "3CPDEVW"
bind CH_LET_BRD = "CMPSDNT"
bind CH_LET_NET = "RTIOUDX"
bind CH_LET_MAIN = "MGCNVDH"
# state list Z, built once per frame and handed to the views and the synth
bind Z_T = 0
bind Z_ROT = 1
bind Z_HS = 2
bind Z_SAT = 3
bind Z_W = 4
bind Z_H = 5
bind Z_CATS = 6
bind Z_TOTAL = 7
bind Z_ACT = 8
bind Z_RD = 9
bind Z_WR = 10
bind Z_FLT = 11
bind Z_EV = 12
bind Z_NAME = 13
bind Z_WS = 14
bind Z_PRIV = 15
bind Z_IOR = 16
bind Z_IOW = 17
bind Z_HIST = 18
bind Z_USED = 19
bind Z_ENERGY = 20
bind Z_HIL = 21
bind Z_LIVE = 22
bind Z_FH = 23
bind Z_D = 24
bind Z_STAT = 25
bind Z_MX = 26
bind Z_MY = 27
bind Z_SEC = 28
bind Z_VIEW = 29
bind Z_FRAC = 30
bind Z_LAB = 31
bind Z_ALERT = 32
# section data pack D: the smoothed readings of all four sections plus the history strips
bind D_GPU = 0
bind D_BRD = 1
bind D_NET = 2
bind D_HS = 3
bind D_MEM = 4
bind D_LIVE = 5
# GPU pack: [n, names, drivers, vecs, engs, procs, sel]; one vec per GPU
bind GV_TEMP = 0
bind GV_FAN = 1
bind GV_POWER = 2
bind GV_PLIM = 3
bind GV_CLK = 4
bind GV_CLKMAX = 5
bind GV_MCLK = 6
bind GV_MCLKMAX = 7
bind GV_UTIL = 8
bind GV_MUTIL = 9
bind GV_VUSED = 10
bind GV_VTOTAL = 11
bind GV_PGEN = 12
bind GV_PW = 13
bind GV_THP = 14
bind GV_THT = 15
bind GV_LEN = 16
# board pack: [info, bv, cutil, cfreq, dimms, disks, dio, sens]
bind BV_UTIL = 0
bind BV_MHZ = 1
bind BV_PMAX = 2
bind BV_TEMP = 3
bind BV_INTR = 4
bind BV_DPC = 5
bind BV_CTX = 6
bind BV_SYSC = 7
bind BV_PROCS = 8
bind BV_THR = 9
bind BV_UP = 10
bind BV_DRD = 11
bind BV_DWR = 12
bind BV_DBUSY = 13
bind BV_DQ = 14
bind BV_LEN = 15
# net pack: [adapters, nv, nodes, procs]
bind NV_RX = 0
bind NV_TX = 1
bind NV_PRX = 2
bind NV_PTX = 3
bind NV_BW = 4
bind NV_EST = 5
bind NV_RETX = 6
bind NV_UDP = 7
bind NV_RTT = 8
bind NV_LISTEN = 9
bind NV_TW = 10
bind NV_CW = 11
bind NV_SYN = 12
bind NV_LOOP = 13
bind NV_FAIL = 14
bind NV_LEN = 15
# history strips: 120 samples, half a second apart, each already scaled to 0..1
bind HS_N = 120
bind HS_GPU = 0
bind HS_BRD = 32
bind HS_NET = 40
bind HS_MEM = 48
bind HS_COUNT = 50
# ---- BEGIN GLYPHS ----
# generated by tools/gen_glyphs.py from the Ling design system bundle; do not edit by hand
bind DAEMON_CH = "!#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~"
bind DAEMON = [
[212,699,[[0,611,6,577,26,548,54,529,88,523,122,529,150,548,170,577,176,611,170,645,150,674,122,693,88,699,54,693,26,674,6,645],[212,0,133,368,65,368,88,0]]],
[729,751,[[393,1,294,2,235,205,293,1],[172,420,206,304,173,420],[76,751,144,518,77,751],[634,0,535,1,500,120,534,0],[317,750,385,518,318,750],[487,508,387,508,410,430,510,430],[247,508,147,508,169,430,269,430],[147,508,0,508,0,430,169,430],[387,508,247,508,269,430,410,430],[672,430,672,508,487,508,510,430],[550,293,450,293,472,215,572,215],[309,293,209,293,232,215,332,215],[209,293,48,293,48,215,232,215],[450,293,309,293,332,215,472,215],[720,215,720,293,550,293,572,215],[535,1,634,1,575,205,729,205,729,303,547,303,513,420,681,420,681,518,485,518,418,750,318,750,387,508,487,508,417,750,318,750,418,750,485,518,681,518,681,420,513,420,547,303,729,303,729,205,575,205,634,1,572,215,472,215,500,120],[447,304,450,293,550,293,510,430,410,430,413,420],[294,2,393,2,332,215,232,215,234,205],[172,420,209,293,309,293,269,430,169,430],[77,751,147,508,247,508,176,751]]],
[500,749,[[400,283,394,192,370,136,351,119,292,103,210,103,151,119,131,136,116,160,101,248,102,333,116,401,151,437,177,446,292,450,351,437,384,401,398,333],[0,286,7,188,16,149,28,115,63,62,85,42,140,14,250,0,356,14,411,40,433,59,470,113,482,146,495,208,500,282,493,380,484,417,473,449,438,498,416,516,361,540,251,551,140,540,110,530,62,498,43,476,16,417,7,380,0,287],[175,279,183,340,190,351,214,363,272,365,301,358,318,340,324,305,318,217,311,206,288,193,230,191,200,198,183,217,176,253],[125,283,128,235,139,198,156,172,180,154,250,140,320,154,344,172,361,198,372,235,375,283,368,348,358,371,326,402,279,414,220,414,174,402,142,371,127,319],[175,285,183,345,190,355,214,364,301,361,318,345,324,311,318,222,311,210,288,195,230,192,200,201,183,222,176,259],[125,283,139,199,156,172,181,155,212,144,251,141,289,144,321,155,344,172,361,199,372,236,375,283,368,348,358,371,327,402,280,414,221,414,174,402,143,371,127,319],[1,30,79,30,79,749,1,749]]],
[569,751,[[50,139,57,77,74,58,88,54,125,51,176,58,193,77,199,113,193,201,186,212,162,224,104,225,74,219,57,201,51,165],[0,144,3,96,14,59,31,32,55,15,87,4,125,1,163,4,195,15,219,32,236,59,247,96,250,144,248,180,233,232,201,263,154,275,95,275,49,263,17,232,2,180],[50,146,57,205,64,215,88,224,176,221,193,205,199,172,193,82,176,61,162,55,104,52,74,61,57,82,51,120],[0,144,3,96,14,59,31,32,55,15,87,4,125,1,163,4,195,15,219,32,236,59,247,96,250,144,248,180,233,232,201,263,154,275,95,275,49,263,17,232,2,180],[369,614,376,552,406,529,465,527,494,534,512,552,518,588,516,660,512,676,494,694,444,701,394,694,376,676,370,640],[319,619,322,571,333,534,350,508,374,490,444,476,482,479,514,490,538,508,555,534,566,571,569,619,562,684,552,707,520,738,473,750,414,750,368,738,336,707,321,655],[369,621,376,680,406,700,494,696,512,680,518,647,512,557,504,544,482,530,423,527,394,536,376,557,370,595],[319,619,322,571,333,534,350,508,374,490,444,476,482,479,514,490,538,508,555,534,566,571,569,619,562,684,552,707,520,738,473,750,414,750,368,738,336,707,321,655],[343,0,443,0,226,750,126,750]]],
[428,583,[[341,582,259,583,18,0,94,0,341,583],[302,283,78,283,80,458,428,280,428,370,0,583,0,208,221,205,220,82,80,88,40,0,303,0]]],
[208,164,[[208,0,193,43,149,107,98,149,68,164,0,164,41,113,70,63,84,0]]],
[445,806,[[405,0,445,2,445,89,387,89,301,104,233,134,194,164,157,200,120,259,93,349,88,403,94,464,112,527,126,558,165,615,218,663,285,698,380,718,445,719,445,806,355,805,284,790,202,761,134,718,73,652,46,605,20,537,0,437,0,368,20,266,38,212,86,134,143,82,209,42,275,18,374,1]]],
[445,806,[[71,1,170,18,236,42,302,82,359,134,394,186,425,266,445,368,445,437,425,537,399,605,372,652,311,718,243,761,162,790,90,805,0,806,0,719,66,718,160,698,228,663,280,615,319,558,333,527,356,433,357,379,337,290,304,220,252,164,212,134,144,104,58,89,0,89,0,2,40,0]]],
[334,334,[[334,138,334,196,0,196,0,138],[138,0,196,0,196,334,138,334],[264,28,306,70,70,306,28,264],[28,70,70,28,306,264,264,306]]],
[445,445,[[445,183,445,261,0,261,0,183],[184,0,262,0,262,445,184,445]]],
[176,266,[[88,0,123,6,151,26,170,54,176,103,165,154,145,190,68,266,0,266,38,220,66,174,37,161,16,140,0,88,6,54,26,26,54,6]]],
[445,78,[[445,0,445,78,0,78,0,0]]],
[176,176,[[0,88,6,54,26,26,54,6,88,0,122,6,150,26,170,54,176,88,170,122,150,150,122,170,88,176,54,170,26,150,6,122]]],
[317,750,[[0,750,217,0,317,0,100,750]]],
[500,745,[[400,370,394,265,370,180,351,147,325,122,292,106,251,101,210,106,177,122,151,147,116,219,101,333,107,476,130,564,150,597,176,623,209,640,250,645,291,640,324,623,350,597,370,564,387,508,399,407],[0,373,4,293,16,222,28,180,63,106,85,75,140,28,173,12,250,0,289,2,353,20,405,52,446,96,475,162,484,201,492,242,500,369,496,450,484,521,457,603,438,638,416,669,360,716,290,742,250,745,209,742,139,716,84,669,62,638,43,603,16,521,4,450,0,374]]],
[456,749,[[23,381,16,585,0,749,68,749,147,381],[356,169,355,112,345,81,281,100,230,106,202,105,113,81,104,96,100,136,102,224,104,238,113,248,179,216,230,209,281,216,345,248,353,238,356,201],[0,172,1,120,12,54,29,24,52,8,83,1,229,5,344,0,390,6,410,15,445,52,454,73,456,106,451,256,435,302,406,320,230,309,72,322,35,314,12,283,1,220,0,173]]],
[456,749,[[23,381,16,585,0,749,68,749,147,381],[356,169,355,112,345,81,281,100,230,106,202,105,113,81,104,96,100,136,102,224,104,238,113,248,179,216,230,209,281,216,345,248,353,238,356,201],[0,172,1,120,12,54,29,24,52,8,83,1,229,5,344,0,390,6,410,15,445,52,454,73,456,106,451,256,435,302,406,320,230,309,72,322,35,314,12,283,1,220,0,173],[177,381,170,585,154,749,222,749,301,381]]],
[456,749,[[23,381,16,585,0,749,68,749,147,381],[331,381,324,585,308,749,376,749,455,381],[356,169,355,112,345,81,281,100,230,106,202,105,113,81,104,96,100,136,102,224,104,238,113,248,179,216,230,209,281,216,345,248,353,238,356,201],[0,172,1,120,12,54,29,24,52,8,83,1,229,5,344,0,390,6,410,15,445,52,454,73,456,106,451,256,435,302,406,320,230,309,72,322,35,314,12,283,1,220,0,173],[177,381,170,585,154,749,222,749,301,381]]],
[455,742,[[23,374,16,578,0,742,68,742,147,374],[0,192,455,192,455,292,0,292],[230,0,286,10,331,38,348,58,368,108,369,191,267,193,266,127,246,105,229,102,212,105,193,128,191,194,90,191,91,117,110,67,147,23,213,1]]],
[455,742,[[23,374,16,578,0,742,68,742,147,374],[0,192,455,192,455,292,0,292],[230,0,286,10,331,38,348,58,368,108,369,191,267,193,266,127,246,105,229,102,212,105,193,128,191,194,90,191,91,117,110,67,147,23,213,1],[177,374,170,578,154,742,222,742,301,374]]],
[455,742,[[23,374,16,578,0,742,68,742,147,374],[0,192,455,192,455,292,0,292],[230,0,286,10,331,38,348,58,368,108,369,191,267,193,266,127,246,105,229,102,212,105,193,128,191,194,90,191,91,117,110,67,147,23,213,1],[331,374,324,578,308,742,376,742,455,374],[177,374,170,578,154,742,222,742,301,374]]],
[455,750,[[23,382,16,586,0,750,68,750,147,382],[0,200,455,200,455,300,0,300],[0,0,455,0,455,100,0,100]]],
[455,750,[[23,382,16,586,0,750,68,750,147,382],[0,200,455,200,455,300,0,300],[0,0,455,0,455,100,0,100],[177,382,170,586,154,750,222,750,301,382]]],
[455,751,[[23,383,16,587,0,751,68,751,147,383],[0,201,455,201,455,301,0,301],[0,1,455,1,455,101,0,101,0,0],[331,383,324,587,308,751,376,751,455,383],[177,383,170,587,154,751,222,751,301,383]]],
[176,399,[[0,311,6,277,26,248,54,229,88,223,122,229,150,248,170,277,176,311,170,345,150,374,122,393,88,399,54,393,26,374,6,345],[0,88,6,54,26,26,54,6,88,0,122,6,150,26,170,54,176,88,170,122,150,150,122,170,88,176,54,170,26,150,6,122]]],
[176,491,[[0,88,6,54,26,26,54,6,88,0,122,6,150,26,170,54,176,88,170,122,150,150,122,170,88,176,54,170,26,150,6,122],[88,225,123,232,151,251,170,280,176,328,165,378,145,415,68,491,0,491,38,445,66,399,37,386,16,364,0,313,6,279,26,250,54,231]]],
[448,804,[[361,2,448,2,448,82,424,191,410,232,364,311,309,364,246,403,327,457,394,542,436,660,447,727,447,804,360,804,356,715,329,617,299,569,234,504,188,478,140,460,88,450,0,448,0,359,82,358,164,338,226,309,296,242,328,188,350,132,358,90,361,0]]],
[455,301,[[0,201,455,201,455,301,0,301],[0,1,455,1,455,101,0,101,0,0]]],
[448,801,[[87,49,98,130,119,186,151,239,195,286,221,306,283,335,365,355,448,356,448,445,359,447,307,458,237,486,191,521,149,567,119,615,92,713,88,801,1,801,1,725,8,672,47,553,79,501,120,455,202,401,158,376,100,328,51,256,23,189,0,80,0,0,87,0]]],
[226,701,[[0,613,6,579,26,551,54,532,88,525,122,532,150,551,170,579,176,613,170,647,150,676,122,695,88,701,54,695,26,676,6,647],[0,132,0,1,49,0,125,9,166,25,196,47,215,74,226,140,213,210,182,286,133,370,65,370,113,245,120,191,118,171,105,144,80,128,43,126]]],
[500,551,[[102,327,112,391,130,423,150,438,194,449,297,450,351,438,386,429,494,380,481,430,463,469,430,507,364,539,293,551,202,551,143,541,107,529,72,507,41,476,17,425,1,327],[178,327,192,354,222,366,297,363,310,354,323,327,466,327,432,357,378,390,351,403,295,416,221,416,184,409,156,389,137,360,127,327],[1,327,7,192,28,116,45,86,83,43,112,25,222,0,292,1,350,12,400,32,438,64,467,105,485,147,500,231,500,283,466,327,323,327,325,257,308,206,270,192,222,194,196,206,178,238,178,327,127,327,127,252,139,201,168,164,217,144,284,145,336,166,361,196,368,217,375,305,398,279,391,183,377,150,355,123,285,103,219,103,152,120,124,147,111,182,101,241,102,327]]],
[500,750,[[166,750,0,0,100,0,250,650,401,0,500,0,333,750]]],
[500,750,[[100,407,400,407,400,97,0,97,0,0,500,0,500,503,200,503,200,750,100,750]]],
[500,750,[[200,653,200,0,300,0,300,653,500,653,500,749,0,750,0,654]]],
[500,750,[[100,318,100,0,200,0,200,221,500,221,500,750,0,750,0,653,400,653,400,318]]],
[500,745,[[0,447,0,303,500,0,500,134,100,377,498,613,498,745]]],
[500,750,[[0,0,500,0,500,100,100,100,100,650,500,650,500,750,0,750,0,726]]],
[500,750,[[0,0,100,0,100,648,400,648,400,0,500,0,500,750,0,750]]],
[500,750,[[0,0,500,0,500,750,0,750,0,650,400,650,400,100,0,100]]],
[500,750,[[166,0,333,0,500,750,400,750,250,100,100,750,0,750]]],
[500,750,[[0,0,500,0,500,100,100,99,100,750,0,750]]],
[500,750,[[100,100,99,750,0,750,0,0,500,0,500,750,400,750,400,100]]],
[500,750,[[400,650,100,650,100,750,0,750,0,0,500,0,500,750,400,750],[400,550,400,100,101,100,100,550]]],
[500,751,[[368,750,0,750,0,650,365,650,400,441,400,425,0,425,0,325,400,325,400,100,0,100,0,0,500,0,500,441,450,751]]],
[500,750,[[350,750,394,425,0,425,0,325,400,325,400,100,0,100,0,0,500,0,500,441,450,750]]],
[500,750,[[500,425,454,421,416,429,385,447,340,503,324,540,306,618,300,750,200,750,189,583,168,520,152,493,107,452,42,429,0,425,0,325,77,307,133,277,161,252,197,194,212,130,210,62,200,0,300,0,314,125,303,203,276,271,230,326,200,348,125,375,166,391,205,418,235,457,250,505,284,406,310,372,340,346,374,330,412,322,500,325,500,375]]],
[500,749,[[415,350,100,350,100,650,500,650,500,749,1,749,0,250,315,250,315,0,415,0,415,340]]],
[500,750,[[100,325,500,325,500,425,100,425,100,750,0,750,0,0,100,0]]],
[500,750,[[300,650,450,650,450,750,50,750,50,650,200,650,200,100,0,100,0,0,500,0,500,100,300,100]]],
[500,750,[[0,0,500,0,500,100,100,100,100,325,500,325,500,750,0,750,0,650,400,650,400,425,0,425]]],
[500,750,[[300,100,300,750,200,750,200,100,0,100,0,0,500,0,500,100]]],
[500,750,[[500,325,500,425,0,750,0,650,400,373,0,100,0,0]]],
[500,750,[[100,100,500,100,500,200,350,200,350,400,250,400,250,200,100,200,100,750,0,750,0,0,100,0]]],
[500,750,[[100,425,100,675,0,675,0,75,100,75,100,326,400,326,400,0,500,0,500,750,400,750,400,425]]],
[500,750,[[0,0,100,0,100,650,200,650,200,0,500,0,500,750,400,750,400,100,300,100,300,750,0,750,0,18]]],
[500,750,[[100,100,100,650,500,650,500,750,0,750,0,0,500,0,500,100,350,100,350,400,250,400,250,100]]],
[500,750,[[500,0,500,750,400,750,400,100,0,100,0,0]]],
[200,783,[[0,0,200,0,200,98,98,98,98,686,200,686,200,783,0,783]]],
[200,783,[[200,0,200,783,0,783,0,686,102,686,102,98,0,98,0,0]]],
[804,448,[[802,361,802,448,722,448,613,424,572,410,493,364,440,309,401,246,347,327,262,394,144,436,77,447,0,447,0,360,89,356,187,329,235,299,300,234,326,188,344,140,354,88,356,0,445,0,446,82,466,164,495,226,562,296,616,328,672,350,714,358,804,361]]],
[672,96,[[672,22,672,96,0,95,0,0,672,0]]],
[211,164,[[124,0,126,38,150,100,187,146,211,164,143,164,105,141,50,88,0,0]]],
[503,499,[[298,499,210,499,0,0,104,0,254,375,404,0,503,0]]],
[500,500,[[194,266,400,266,400,95,0,95,0,0,500,0,500,363,200,363,200,500,100,500,100,266]]],
[500,496,[[300,399,500,399,500,496,0,496,0,399,200,398,200,0,300,0]]],
[500,500,[[208,230,111,230,111,0,211,0,211,130,500,130,500,500,0,500,0,400,400,400,400,230]]],
[499,503,[[0,298,0,210,499,0,499,104,124,254,499,404,499,503]]],
[500,500,[[0,0,500,0,500,100,97,100,97,400,495,400,495,500,0,500]]],
[500,500,[[0,500,0,0,99,0,99,402,403,402,403,0,500,0,499,500]]],
[500,500,[[500,500,0,500,0,400,400,400,400,100,0,100,0,0,500,0]]],
[503,499,[[205,0,293,0,503,499,399,499,249,124,99,499,0,499]]],
[500,500,[[0,0,500,0,500,100,99,101,100,500,0,500]]],
[500,500,[[500,0,500,500,400,500,402,96,100,100,100,500,0,500,0,0]]],
[500,499,[[400,399,100,400,100,499,0,499,0,0,500,0,500,499,400,499],[400,299,400,99,100,99,100,299]]],
[503,500,[[400,200,400,100,0,100,0,0,503,0,500,500,0,500,0,400,400,400,400,300,0,300,0,200]]],
[500,500,[[400,500,400,300,0,300,0,200,400,200,400,100,0,100,0,0,500,0,500,500]]],
[500,500,[[0,291,0,191,84,184,150,151,190,100,203,43,205,0,305,0,300,96,279,158,240,210,213,228,174,241,208,255,231,274,255,320,276,274,294,252,348,212,409,194,500,191,500,291,402,301,370,315,346,334,316,384,308,416,305,500,205,500,201,418,182,366,132,319,102,304,40,292]]],
[500,500,[[317,230,100,230,100,399,500,400,500,500,0,500,0,129,315,130,315,0,415,0,415,230]]],
[500,500,[[100,300,100,500,0,500,0,0,100,0,100,200,500,200,500,300]]],
[503,500,[[301,100,301,400,503,400,503,500,1,500,1,400,201,400,201,100,0,100,0,0,501,0,501,100]]],
[500,500,[[0,1,500,0,500,100,105,100,107,200,500,200,500,500,0,500,0,405,400,405,400,300,0,300]]],
[500,500,[[200,100,0,100,0,0,500,0,500,100,300,100,300,500,200,500]]],
[499,503,[[499,205,499,293,0,503,0,399,375,249,0,99,0,0]]],
[499,500,[[99,100,499,100,499,200,349,200,349,350,249,350,249,200,99,200,99,500,0,500,0,0,99,0]]],
[500,500,[[400,300,100,300,100,500,0,500,0,0,100,0,100,200,400,200,400,0,500,0,500,500,400,500]]],
[500,500,[[0,500,0,0,100,0,100,400,200,400,200,0,500,0,500,500,400,500,400,100,300,100,300,500]]],
[500,500,[[250,100,100,100,100,400,500,400,500,500,0,500,0,0,500,0,500,100,350,100,350,300,250,300]]],
[500,500,[[500,0,500,500,400,500,400,100,0,100,0,0]]],
[340,806,[[158,0,245,0,245,74,236,143,212,218,180,284,148,326,238,356,340,359,340,446,244,450,148,480,186,534,212,586,240,688,245,731,245,805,157,806,150,690,127,620,95,566,1,469,48,430,95,403,48,376,0,337,89,249,117,206,148,122,158,51]]],
[100,750,[[100,750,0,750,0,0,100,0]]],
[340,808,[[182,53,192,124,223,207,251,251,340,339,292,378,245,405,292,432,339,471,245,568,213,622,189,698,183,808,95,808,96,714,112,638,144,552,192,482,96,452,0,448,0,360,86,359,192,328,160,286,128,220,104,145,95,76,95,0,182,1]]],
[409,161,[[126,0,160,6,161,0,230,0,234,59,246,76,283,89,309,83,332,65,337,0,409,0,409,48,392,104,355,141,326,156,299,161,179,161,175,102,162,86,124,72,90,86,76,102,72,161,0,161,1,103,20,54,59,15,113,0]]]
]
bind CHESILIN_CH = "!,.0123456789?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
bind CHESILIN = [
[97,844,[[47,0,97,0,62,218,46,250,0,250,34,42],[47,595,97,595,64,806,46,842,0,844,34,637]]],
[432,844,[[424,0,432,12,432,92,422,195,399,306,376,370,345,428,304,476,279,495,220,518,96,514,50,494,16,455,0,393,3,87,16,27,28,4,39,2,44,14,40,306,47,354,70,385,97,403,202,420,276,408,302,394,356,328,382,239,395,58,417,2],[54,590,336,590,321,751,310,798,299,830,286,844,24,844,30,714,42,632]]],
[317,844,[[30,0,317,0,294,169,276,239,262,254,0,254,2,168,26,10],[30,591,317,591,294,759,276,829,262,844,0,844,2,758,26,601]]],
[362,664,[[362,0,361,68,341,93,225,93,225,567,362,567,361,640,341,664,0,664,2,609,22,571,133,571,133,93,0,93,2,38,22,0]]],
[264,659,[[264,0,264,638,214,659,174,659,174,94,0,94,2,39,22,0]]],
[263,662,[[263,0,263,623,242,662,0,662,2,602,27,566,173,566,173,21,225,5]]],
[262,658,[[262,0,262,636,220,658,177,658,177,372,0,372,0,323,27,274,170,275,170,21,233,4]]],
[362,663,[[195,0,235,0,235,565,362,565,361,638,340,663,0,663,1,607,22,570,144,570,144,21,184,1]]],
[362,659,[[362,0,361,70,340,94,223,94,223,637,173,659,132,659,132,93,0,93,1,38,22,0]]],
[368,664,[[27,0,368,0,368,642,314,662,277,658,277,96,6,96,0,70,16,18]]],
[366,663,[[116,0,366,0,366,69,350,98,95,98,95,642,47,663,0,663,0,27,26,14,108,0]]],
[364,663,[[51,0,91,0,91,568,364,568,362,638,342,663,0,663,0,22,40,2]]],
[367,663,[[367,0,367,624,346,663,0,663,2,603,27,567,277,567,277,22,338,4]]],
[432,844,[[425,0,432,6,430,120,399,308,345,430,304,478,251,511,184,522,92,512,49,494,20,461,0,383,2,104,9,46,30,4,40,3,45,15,41,315,52,361,72,388,119,409,182,420,244,418,285,403,323,376,363,315,382,238,393,65,418,2],[166,595,216,595,186,795,168,840,120,844,153,637]]],
[78,321,[[45,0,78,0,78,276,61,321,42,321,42,102,7,103,0,91,8,38,32,3]]],
[290,1006,[[189,531,142,542,110,590,93,650,91,743,106,806,132,864,180,906,216,919,214,531],[271,0,287,7,290,985,281,994,234,1006,218,1004,215,989,187,997,121,986,63,944,38,910,8,830,0,725,14,644,34,588,53,560,131,490,188,462,214,458,212,24,228,10,266,0],[189,531,142,542,110,590,93,650,91,743,106,806,132,864,180,906,216,919,214,531],[271,0,287,7,290,985,281,994,234,1006,218,1004,215,989,187,997,121,986,63,944,38,910,8,830,0,725,14,644,34,588,53,560,131,490,188,462,214,458,212,24,228,10,266,0]]],
[290,1005,[[77,314,76,709,140,696,164,674,190,621,200,551,197,479,179,406,154,363,106,324],[63,0,78,4,78,237,138,239,175,252,231,295,251,322,280,393,290,445,290,517,286,556,264,625,212,701,136,757,74,775,74,981,59,995,15,1005,0,998,4,23,19,10,58,0],[77,314,76,709,140,696,164,674,190,621,200,551,197,479,179,406,154,363,106,324],[63,0,78,4,78,237,138,239,175,252,231,295,251,322,280,393,290,445,290,517,286,556,264,625,212,701,136,757,74,775,74,981,59,995,15,1005,0,998,4,23,19,10,58,0]]],
[289,1006,[[215,75,154,89,125,112,103,160,89,233,94,322,120,397,151,440,213,472],[274,0,289,5,286,982,268,996,231,1006,211,999,213,548,168,549,127,540,87,518,51,484,14,409,0,333,0,278,18,178,69,94,144,34,270,0],[215,75,154,89,125,112,103,160,89,233,94,322,120,397,151,440,213,472],[274,0,289,5,286,982,268,996,231,1006,211,999,213,548,168,549,127,540,87,518,51,484,14,409,0,333,0,278,18,178,69,94,144,34,270,0]]],
[109,270,[[54,0,95,30,108,60,108,102,79,207,55,270,18,235,1,206,45,26]]],
[393,1006,[[78,534,76,931,169,909,235,877,284,824,298,790,303,750,284,670,238,611,176,569,81,534],[64,0,80,4,77,457,138,459,211,479,317,544,319,24,326,14,354,4,393,5,393,706,389,748,356,824,332,857,268,914,158,974,14,1006,0,999,5,21,59,0],[78,534,76,931,169,909,235,877,284,824,298,790,303,750,284,670,238,611,176,569,81,534],[64,0,80,4,77,457,138,459,211,479,317,544,319,24,326,14,354,4,393,5,393,706,389,748,356,824,332,857,268,914,158,974,14,1006,0,999,5,21,59,0]]],
[392,1005,[[75,84,77,474,152,468,221,440,285,376,303,308,292,242,257,182,197,132,105,91],[59,0,72,2,75,17,99,8,157,14,264,58,333,112,368,160,384,198,392,229,392,984,375,996,335,1005,318,1001,315,427,226,495,157,526,77,548,79,980,44,1001,5,1000,0,22,53,0],[75,84,77,474,152,468,221,440,285,376,303,308,292,242,257,182,197,132,105,91],[59,0,72,2,75,17,99,8,157,14,264,58,333,112,368,160,384,198,392,229,392,984,375,996,335,1005,318,1001,315,427,226,495,157,526,77,548,79,980,44,1001,5,1000,0,22,53,0]]],
[288,997,[[272,0,286,4,288,505,258,522,145,541,112,586,91,666,93,750,109,820,125,853,174,904,209,919,250,924,259,933,251,962,194,996,151,994,95,972,38,910,8,830,0,719,22,617,52,561,130,490,188,462,214,458,211,24,266,1]]],
[180,82,[[0,0,143,0,180,55,180,82,54,82,22,58,0,23]]],
[291,1006,[[78,535,75,931,134,918,174,882,201,773,196,687,171,612,141,570,80,535],[64,0,80,4,77,457,163,467,221,504,266,568,280,606,291,678,282,800,240,889,172,956,87,993,14,1006,0,1000,5,21,59,1],[78,535,75,931,134,918,174,882,201,773,196,687,171,612,141,570,80,535],[64,0,80,4,77,457,163,467,221,504,266,568,280,606,291,678,282,800,240,889,172,956,87,993,14,1006,0,1000,5,21,59,1]]],
[290,1005,[[77,314,76,709,140,696,164,674,190,621,200,551,197,479,179,406,154,363,106,324],[63,0,78,4,78,237,138,239,175,252,231,295,251,322,280,393,290,445,290,517,286,556,264,625,212,701,136,757,74,775,74,981,59,995,15,1005,0,998,4,23,19,10,58,0],[77,314,76,709,140,696,164,674,190,621,200,551,197,479,179,406,154,363,106,324],[63,0,78,4,78,237,138,239,175,252,231,295,251,322,280,393,290,445,290,517,286,556,264,625,212,701,136,757,74,775,74,981,59,995,15,1005,0,998,4,23,19,10,58,0]]],
[487,1009,[[187,77,160,81,139,94,110,133,92,207,90,266,100,334,129,402,162,441,207,463,209,77,192,77],[282,548,280,934,333,929,352,916,388,848,397,784,396,723,370,629,355,601,300,555],[268,0,284,5,282,472,345,472,383,488,442,543,476,615,487,748,468,842,421,923,347,982,294,1002,242,1009,205,999,207,540,155,541,127,533,70,496,44,466,10,393,0,265,28,151,43,121,90,65,178,12,266,0],[187,77,160,81,139,94,110,133,92,207,90,266,100,334,129,402,162,441,207,463,209,77,192,77],[282,548,280,934,333,929,352,916,388,848,397,784,396,723,370,629,355,601,300,555],[268,0,284,5,282,472,345,472,383,488,442,543,476,615,487,748,468,842,421,923,347,982,294,1002,242,1009,205,999,207,540,155,541,127,533,70,496,44,466,10,393,0,265,28,151,43,121,90,65,178,12,266,0]]],
[333,1005,[[238,530,202,534,146,564,110,614,91,702,100,768,128,828,180,880,260,918,258,530,241,530],[60,0,75,3,77,559,148,501,222,467,295,455,332,466,333,982,316,996,280,1005,262,1002,259,992,217,996,174,986,116,957,57,904,8,812,0,748,1,23,19,9,54,0],[238,530,202,534,146,564,110,614,91,702,100,768,128,828,180,880,260,918,258,530,241,530],[60,0,75,3,77,559,148,501,222,467,295,455,332,466,333,982,316,996,280,1005,262,1002,259,992,217,996,174,986,116,957,57,904,8,812,0,748,1,23,19,9,54,0]]],
[288,997,[[103,0,148,6,186,22,243,77,277,149,288,272,285,312,264,383,215,460,140,518,74,538,76,974,30,996,2,994,0,495,27,477,143,456,180,406,198,315,190,218,164,150,116,96,81,79,31,68,38,34,95,1]]],
[181,228,[[29,0,142,97,176,143,180,177,164,228,52,138,7,88,2,45,20,6]]],
[392,1006,[[318,74,226,96,159,128,110,180,95,215,90,257,104,322,144,386,214,436,316,472],[377,0,392,5,388,981,372,995,329,1005,314,1000,316,547,240,544,183,527,126,500,76,461,75,983,38,1002,1,1002,0,299,4,257,37,182,62,148,126,90,236,31,366,1],[318,74,226,96,159,128,110,180,95,215,90,257,104,322,144,386,214,436,316,472],[377,0,392,5,388,981,372,995,329,1005,314,1000,316,547,240,544,183,527,126,500,76,461,75,983,38,1002,1,1002,0,299,4,257,37,182,62,148,126,90,236,31,366,1]]],
[290,1005,[[77,314,76,709,140,696,164,674,190,621,200,551,197,479,179,406,154,363,106,324],[63,0,78,4,78,237,138,239,175,252,231,295,251,322,280,393,290,445,290,517,286,556,264,625,212,701,136,757,74,775,74,981,59,995,15,1005,0,998,4,23,19,10,58,0],[77,314,76,709,140,696,164,674,190,621,200,551,197,479,179,406,154,363,106,324],[63,0,78,4,78,237,138,239,175,252,231,295,251,322,280,393,290,445,290,517,286,556,264,625,212,701,136,757,74,775,74,981,59,995,15,1005,0,998,4,23,19,10,58,0]]],
[289,997,[[63,0,77,4,75,458,137,460,173,472,229,514,265,574,278,613,289,673,289,728,269,830,216,916,140,975,81,995,51,997,31,990,40,956,82,928,146,910,175,876,190,835,199,771,192,678,168,608,147,578,120,552,87,536,28,532,0,520,3,24,57,0]]],
[332,1006,[[74,88,76,474,147,464,194,433,226,384,243,310,228,221,200,170,155,124,76,88],[59,0,70,2,74,13,98,8,160,17,216,44,263,82,292,117,327,194,332,984,318,995,275,1006,258,1002,255,446,187,503,149,523,74,546,29,549,2,542,0,22,52,0],[74,88,76,474,147,464,194,433,226,384,243,310,228,221,200,170,155,124,76,88],[59,0,70,2,74,13,98,8,160,17,216,44,263,82,292,117,327,194,332,984,318,995,275,1006,258,1002,255,446,187,503,149,523,74,546,29,549,2,542,0,22,52,0]]],
[291,1005,[[76,86,76,475,136,470,155,456,182,413,200,341,200,261,184,195,153,134,108,98],[59,0,72,4,76,17,106,8,151,14,188,30,246,85,280,157,291,288,287,326,265,395,216,472,168,514,110,541,77,547,80,981,62,996,25,1005,5,999,0,24,11,12,55,0],[76,86,76,475,136,470,155,456,182,413,200,341,200,261,184,195,153,134,108,98],[59,0,72,4,76,17,106,8,151,14,188,30,246,85,280,157,291,288,287,326,265,395,216,472,168,514,110,541,77,547,80,981,62,996,25,1005,5,999,0,24,11,12,55,0]]],
[202,364,[[143,0,202,12,202,30,145,56,145,336,92,363,75,364,47,347,10,312,0,288,19,258,38,256,50,270,50,28,120,2]]],
[392,1006,[[77,510,77,579,166,510,392,510,392,985,374,998,335,1006,321,1002,318,989,288,998,258,996,161,966,73,906,28,850,3,784,0,748,2,510],[317,531,242,538,152,581,105,637,90,707,95,748,110,786,159,846,220,887,319,921],[2,510,1,24,18,10,54,0,75,4,77,510],[392,510,166,510,242,476,317,458,315,25,342,6,379,0,389,8],[317,531,242,538,152,581,105,637,90,707,95,748,110,786,159,846,220,887,319,921],[60,0,75,4,77,579,136,529,196,494,317,458,315,25,342,6,388,4,392,985,374,998,335,1006,321,1002,318,989,288,998,258,996,194,980,100,929,28,850,3,784,1,24,18,10,54,0]]],
[333,1006,[[259,78,186,93,148,118,106,174,91,233,96,306,128,382,171,428,257,470],[320,0,333,4,332,522,321,533,277,546,200,546,127,520,77,482,75,984,58,997,22,1006,1,999,0,301,11,225,42,158,114,77,209,26,315,0],[259,78,186,93,148,118,106,174,91,233,96,306,128,382,171,428,257,470],[320,0,333,4,332,522,321,533,277,546,200,546,127,520,77,482,75,984,58,997,22,1006,1,999,0,301,11,225,42,158,114,77,209,26,315,0]]],
[487,1009,[[277,81,280,473,335,462,360,441,387,381,396,317,389,217,371,166,341,120,280,81],[205,539,149,549,114,588,96,640,90,722,96,789,122,860,166,910,207,929],[262,0,334,6,371,18,427,60,463,120,476,159,487,219,487,274,474,354,436,435,371,502,313,531,279,539,282,983,255,1000,195,1009,156,1007,102,987,44,932,11,860,0,736,12,656,50,576,114,510,205,471,203,24,219,10,256,0],[277,81,280,473,335,462,360,441,387,381,396,317,389,217,371,166,341,120,280,81],[205,539,149,549,114,588,96,640,90,722,96,789,122,860,166,910,207,929],[262,0,334,6,371,18,427,60,463,120,476,159,487,219,487,274,474,354,436,435,371,502,313,531,279,539,282,983,255,1000,195,1009,156,1007,102,987,44,932,11,860,0,736,12,656,50,576,114,510,205,471,203,24,219,10,256,0]]],
[487,1008,[[278,81,280,464,339,452,360,435,385,385,397,320,394,238,375,175,344,123,295,87],[263,0,340,7,380,22,440,75,476,146,487,278,484,317,456,397,390,478,307,524,233,544,153,554,126,574,106,607,90,695,91,743,98,795,117,848,151,895,178,916,225,932,270,935,277,948,255,985,192,1008,109,990,58,950,19,881,0,791,0,736,12,658,28,617,69,556,142,500,205,480,203,23,220,10,257,0],[278,81,280,464,339,452,360,435,385,385,397,320,394,238,375,175,344,123,295,87],[263,0,340,7,380,22,440,75,476,146,487,278,484,317,456,397,390,478,307,524,233,544,153,554,126,574,106,607,90,695,91,743,98,795,117,848,151,895,178,916,225,932,270,935,277,948,255,985,192,1008,109,990,58,950,19,881,0,791,0,736,12,658,28,617,69,556,142,500,205,480,203,23,220,10,257,0]]],
[480,1009,[[199,544,135,560,106,592,91,632,83,748,110,850,150,901,202,927],[287,0,333,5,372,20,433,73,454,107,477,183,480,280,466,356,449,396,407,456,334,510,274,529,276,986,230,1008,161,1006,112,993,47,944,0,842,0,678,33,592,100,522,182,480,328,453,355,432,374,400,390,293,384,228,361,156,314,98,280,80,208,72,203,60,225,23,278,1],[199,544,135,560,106,592,91,632,83,748,110,850,150,901,202,927],[287,0,333,5,372,20,433,73,454,107,477,183,480,280,466,356,449,396,407,456,334,510,274,529,276,986,230,1008,161,1006,112,993,47,944,0,842,0,678,33,592,100,522,182,480,328,453,355,432,374,400,390,293,384,228,361,156,314,98,280,80,208,72,203,60,225,23,278,1]]],
[78,321,[[45,0,78,0,78,276,61,321,42,321,42,102,7,103,0,91,8,38,32,3]]],
[290,1006,[[189,531,142,542,110,590,93,650,91,743,106,806,132,864,180,906,216,919,214,531],[271,0,287,7,290,985,281,994,234,1006,218,1004,215,989,187,997,121,986,63,944,38,910,8,830,0,725,14,644,34,588,53,560,131,490,188,462,214,458,212,24,228,10,266,0],[189,531,142,542,110,590,93,650,91,743,106,806,132,864,180,906,216,919,214,531],[271,0,287,7,290,985,281,994,234,1006,218,1004,215,989,187,997,121,986,63,944,38,910,8,830,0,725,14,644,34,588,53,560,131,490,188,462,214,458,212,24,228,10,266,0]]],
[290,1005,[[77,314,76,709,140,696,164,674,190,621,200,551,197,479,179,406,154,363,106,324],[63,0,78,4,78,237,138,239,175,252,231,295,251,322,280,393,290,445,290,517,286,556,264,625,212,701,136,757,74,775,74,981,59,995,15,1005,0,998,4,23,19,10,58,0],[77,314,76,709,140,696,164,674,190,621,200,551,197,479,179,406,154,363,106,324],[63,0,78,4,78,237,138,239,175,252,231,295,251,322,280,393,290,445,290,517,286,556,264,625,212,701,136,757,74,775,74,981,59,995,15,1005,0,998,4,23,19,10,58,0]]],
[289,1006,[[215,75,154,89,125,112,103,160,89,233,94,322,120,397,151,440,213,472],[274,0,289,5,286,982,268,996,231,1006,211,999,213,548,168,549,127,540,87,518,51,484,14,409,0,333,0,278,18,178,69,94,144,34,270,0],[215,75,154,89,125,112,103,160,89,233,94,322,120,397,151,440,213,472],[274,0,289,5,286,982,268,996,231,1006,211,999,213,548,168,549,127,540,87,518,51,484,14,409,0,333,0,278,18,178,69,94,144,34,270,0]]],
[109,270,[[54,0,95,30,108,60,108,102,79,207,55,270,18,235,1,206,45,26]]],
[395,1006,[[78,534,76,931,169,909,235,877,284,824,298,790,303,750,284,670,238,611,176,569,81,534],[64,0,80,4,77,457,138,459,211,479,317,544,319,24,326,14,355,4,395,5,394,690,389,748,376,787,332,857,302,887,232,938,158,974,14,1006,0,999,5,21,59,0],[78,534,76,931,169,909,235,877,284,824,298,790,303,750,284,670,238,611,176,569,81,534],[64,0,80,4,77,457,138,459,211,479,317,544,319,24,326,14,355,4,395,5,394,690,389,748,376,787,332,857,302,887,232,938,158,974,14,1006,0,999,5,21,59,0]]],
[392,1005,[[75,84,77,474,152,468,221,440,285,376,303,308,292,242,257,182,197,132,105,91],[59,0,72,2,75,17,99,8,157,14,264,58,333,112,368,160,384,198,392,229,392,984,375,996,335,1005,318,1001,315,427,226,495,157,526,77,548,79,980,44,1001,5,1000,0,22,53,0],[75,84,77,474,152,468,221,440,285,376,303,308,292,242,257,182,197,132,105,91],[59,0,72,2,75,17,99,8,157,14,264,58,333,112,368,160,384,198,392,229,392,984,375,996,335,1005,318,1001,315,427,226,495,157,526,77,548,79,980,44,1001,5,1000,0,22,53,0]]],
[288,997,[[272,0,286,4,288,505,258,522,145,541,112,586,91,666,93,750,109,820,125,853,174,904,209,919,250,924,259,933,251,962,194,996,151,994,95,972,38,910,8,830,0,719,22,617,52,561,130,490,188,462,214,458,211,24,266,1]]],
[180,82,[[0,0,143,0,180,55,180,82,54,82,22,58,0,23]]],
[291,1006,[[78,535,75,931,134,918,174,882,201,773,196,687,171,612,141,570,80,535],[64,0,80,4,77,457,163,467,221,504,266,568,280,606,291,678,282,800,240,889,172,956,87,993,14,1006,0,1000,5,21,59,1],[78,535,75,931,134,918,174,882,201,773,196,687,171,612,141,570,80,535],[64,0,80,4,77,457,163,467,221,504,266,568,280,606,291,678,282,800,240,889,172,956,87,993,14,1006,0,1000,5,21,59,1]]],
[290,1005,[[77,314,76,709,140,696,164,674,190,621,200,551,197,479,179,406,154,363,106,324],[63,0,78,4,78,237,138,239,175,252,231,295,251,322,280,393,290,445,290,517,286,556,264,625,212,701,136,757,74,775,74,981,59,995,15,1005,0,998,4,23,19,10,58,0],[77,314,76,709,140,696,164,674,190,621,200,551,197,479,179,406,154,363,106,324],[63,0,78,4,78,237,138,239,175,252,231,295,251,322,280,393,290,445,290,517,286,556,264,625,212,701,136,757,74,775,74,981,59,995,15,1005,0,998,4,23,19,10,58,0]]],
[487,1009,[[187,77,160,81,139,94,110,133,92,207,90,266,100,334,129,402,162,441,207,463,209,77,192,77],[282,548,280,934,333,929,352,916,388,848,397,784,396,723,370,629,355,601,300,555],[268,0,284,5,282,472,345,472,383,488,442,543,476,615,487,748,468,842,421,923,347,982,294,1002,242,1009,205,999,207,540,155,541,127,533,70,496,44,466,10,393,0,265,28,151,43,121,90,65,178,12,266,0],[187,77,160,81,139,94,110,133,92,207,90,266,100,334,129,402,162,441,207,463,209,77,192,77],[282,548,280,934,333,929,352,916,388,848,397,784,396,723,370,629,355,601,300,555],[268,0,284,5,282,472,345,472,383,488,442,543,476,615,487,748,468,842,421,923,347,982,294,1002,242,1009,205,999,207,540,155,541,127,533,70,496,44,466,10,393,0,265,28,151,43,121,90,65,178,12,266,0]]],
[333,1005,[[238,530,202,534,146,564,110,614,91,702,100,768,128,828,180,880,260,918,258,530,241,530],[60,0,75,3,77,559,148,501,222,467,295,455,332,466,333,982,316,996,280,1005,262,1002,259,992,217,996,174,986,116,957,57,904,8,812,0,748,1,23,19,9,54,0],[238,530,202,534,146,564,110,614,91,702,100,768,128,828,180,880,260,918,258,530,241,530],[60,0,75,3,77,559,148,501,222,467,295,455,332,466,333,982,316,996,280,1005,262,1002,259,992,217,996,174,986,116,957,57,904,8,812,0,748,1,23,19,9,54,0]]],
[288,997,[[103,0,148,6,186,22,243,77,277,149,288,272,285,312,264,383,215,460,140,518,74,538,76,974,30,996,2,994,0,495,27,477,143,456,180,406,198,315,190,218,164,150,116,96,81,79,31,68,38,34,95,1]]],
[181,228,[[29,0,142,97,176,143,180,177,164,228,52,138,7,88,2,45,20,6]]],
[392,1006,[[318,74,226,96,159,128,110,180,95,215,90,257,104,322,144,386,214,436,316,472],[377,0,392,5,388,981,372,995,329,1005,314,1000,316,547,240,544,183,527,126,500,76,461,75,983,38,1002,1,1002,0,299,4,257,37,182,62,148,126,90,236,31,366,1],[318,74,226,96,159,128,110,180,95,215,90,257,104,322,144,386,214,436,316,472],[377,0,392,5,388,981,372,995,329,1005,314,1000,316,547,240,544,183,527,126,500,76,461,75,983,38,1002,1,1002,0,299,4,257,37,182,62,148,126,90,236,31,366,1]]],
[290,1005,[[77,314,76,709,140,696,164,674,190,621,200,551,197,479,179,406,154,363,106,324],[63,0,78,4,78,237,138,239,175,252,231,295,251,322,280,393,290,445,290,517,286,556,264,625,212,701,136,757,74,775,74,981,59,995,15,1005,0,998,4,23,19,10,58,0],[77,314,76,709,140,696,164,674,190,621,200,551,197,479,179,406,154,363,106,324],[63,0,78,4,78,237,138,239,175,252,231,295,251,322,280,393,290,445,290,517,286,556,264,625,212,701,136,757,74,775,74,981,59,995,15,1005,0,998,4,23,19,10,58,0]]],
[289,997,[[63,0,77,4,75,458,137,460,173,472,229,514,265,574,278,613,289,673,289,728,269,830,216,916,140,975,81,995,51,997,31,990,40,956,82,928,146,910,175,876,190,835,199,771,192,678,168,608,147,578,120,552,87,536,28,532,0,520,3,24,57,0]]],
[332,1006,[[74,88,76,474,147,464,194,433,226,384,243,310,228,221,200,170,155,124,76,88],[59,0,70,2,74,13,98,8,160,17,216,44,263,82,292,117,327,194,332,984,318,995,275,1006,258,1002,255,446,187,503,149,523,74,546,29,549,2,542,0,22,52,0],[74,88,76,474,147,464,194,433,226,384,243,310,228,221,200,170,155,124,76,88],[59,0,70,2,74,13,98,8,160,17,216,44,263,82,292,117,327,194,332,984,318,995,275,1006,258,1002,255,446,187,503,149,523,74,546,29,549,2,542,0,22,52,0]]],
[291,1005,[[76,86,76,475,136,470,155,456,182,413,200,341,200,261,184,195,153,134,108,98],[59,0,72,4,76,17,106,8,151,14,188,30,246,85,280,157,291,288,287,326,265,395,216,472,168,514,110,541,77,547,80,981,62,996,25,1005,5,999,0,24,11,12,55,0],[76,86,76,475,136,470,155,456,182,413,200,341,200,261,184,195,153,134,108,98],[59,0,72,4,76,17,106,8,151,14,188,30,246,85,280,157,291,288,287,326,265,395,216,472,168,514,110,541,77,547,80,981,62,996,25,1005,5,999,0,24,11,12,55,0]]],
[202,364,[[143,0,202,12,202,30,145,56,145,336,92,363,75,364,47,347,10,312,0,288,19,258,38,256,50,270,50,28,120,2]]],
[392,1006,[[77,510,77,579,166,510,392,510,392,985,374,998,335,1006,321,1002,318,989,288,998,258,996,161,966,73,906,28,850,3,784,0,748,2,510],[317,531,242,538,152,581,105,637,90,707,95,748,110,786,159,846,220,887,319,921],[2,510,1,24,18,10,54,0,75,4,77,510],[166,510,242,476,317,458,315,25,332,10,369,0,389,8,392,510],[317,531,242,538,152,581,105,637,90,707,95,748,110,786,159,846,220,887,319,921],[60,0,75,4,77,579,136,529,196,494,317,458,315,25,342,6,388,4,392,985,374,998,335,1006,321,1002,318,989,288,998,258,996,194,980,100,929,28,850,3,784,1,24,18,10,54,0]]],
[333,1006,[[259,78,186,93,148,118,106,174,91,233,96,306,128,382,171,428,257,470],[320,0,333,4,332,522,321,533,277,546,200,546,127,520,77,482,75,984,58,997,22,1006,1,999,0,301,11,225,42,158,114,77,209,26,315,0],[259,78,186,93,148,118,106,174,91,233,96,306,128,382,171,428,257,470],[320,0,333,4,332,522,321,533,277,546,200,546,127,520,77,482,75,984,58,997,22,1006,1,999,0,301,11,225,42,158,114,77,209,26,315,0]]],
[487,1009,[[277,81,280,473,335,462,360,441,387,381,396,317,389,217,371,166,341,120,280,81],[205,539,149,549,114,588,96,640,90,722,96,789,122,860,166,910,207,929],[262,0,334,6,371,18,427,60,463,120,476,159,487,219,487,274,474,354,436,435,371,502,313,531,279,539,282,983,255,1000,195,1009,156,1007,102,987,44,932,11,860,0,736,12,656,50,576,114,510,205,471,203,24,219,10,256,0],[277,81,280,473,335,462,360,441,387,381,396,317,389,217,371,166,341,120,280,81],[205,539,149,549,114,588,96,640,90,722,96,789,122,860,166,910,207,929],[262,0,334,6,371,18,427,60,463,120,476,159,487,219,487,274,474,354,436,435,371,502,313,531,279,539,282,983,255,1000,195,1009,156,1007,102,987,44,932,11,860,0,736,12,656,50,576,114,510,205,471,203,24,219,10,256,0]]],
[487,1008,[[278,81,280,464,339,452,360,435,385,385,397,320,394,238,375,175,344,123,295,87],[263,0,340,7,380,22,440,75,476,146,487,278,484,317,456,397,390,478,307,524,233,544,153,554,126,574,106,607,90,695,91,743,98,795,117,848,151,895,178,916,225,932,270,935,277,948,255,985,192,1008,109,990,58,950,19,881,0,791,0,736,12,658,28,617,69,556,142,500,205,480,203,23,220,10,257,0],[278,81,280,464,339,452,360,435,385,385,397,320,394,238,375,175,344,123,295,87],[263,0,340,7,380,22,440,75,476,146,487,278,484,317,456,397,390,478,307,524,233,544,153,554,126,574,106,607,90,695,91,743,98,795,117,848,151,895,178,916,225,932,270,935,277,948,255,985,192,1008,109,990,58,950,19,881,0,791,0,736,12,658,28,617,69,556,142,500,205,480,203,23,220,10,257,0]]],
[480,1009,[[199,544,135,560,106,592,91,632,83,748,110,850,150,901,202,927],[287,0,333,5,372,20,433,73,454,107,477,183,480,280,466,356,449,396,407,456,334,510,274,529,276,986,230,1008,161,1006,112,993,47,944,0,842,0,678,33,592,100,522,182,480,328,453,355,432,374,400,390,293,384,228,361,156,314,98,280,80,208,72,203,60,225,23,278,1],[199,544,135,560,106,592,91,632,83,748,110,850,150,901,202,927],[287,0,333,5,372,20,433,73,454,107,477,183,480,280,466,356,449,396,407,456,334,510,274,529,276,986,230,1008,161,1006,112,993,47,944,0,842,0,678,33,592,100,522,182,480,328,453,355,432,374,400,390,293,384,228,361,156,314,98,280,80,208,72,203,60,225,23,278,1]]]
]
# ---- END GLYPHS ----
# ───────────────────────────── small helpers ─────────────────────────────────
fn mix(a, b, k) { return a + (b - a) * k }
fn pos_mod(a, m) {
bind r = a % m
if r < 0.0 { bind r = r + m }
return r
}
# set the pen to Ling hue k; shift is the global hue drift in degrees
fn col(k, sat, lit, shift) {
set_color_hsl(pos_mod(HUE[k] + shift, 360.0), clamp(sat, 0.0, 100.0), clamp(lit, 0.0, 100.0))
}
fn ink(lit) { set_color_hsl(214.0, 14.0, clamp(lit, 0.0, 100.0)) }
fn px(cx, r, a) { return cx + r * sin(a) }
fn py(cy, r, a) { return cy - r * cos(a) }
fn pline(cx, cy, r0, a0, r1, a1) {
draw_line(px(cx, r0, a0), py(cy, r0, a0), px(cx, r1, a1), py(cy, r1, a1))
}
# square of half-size h centred on (x, y), turned by a
fn square(x, y, h, a) {
bind c = cos(a)
bind s = sin(a)
bind x0 = x - h * c + h * s
bind y0 = y - h * s - h * c
bind x1 = x + h * c + h * s
bind y1 = y + h * s - h * c
bind x2 = x + h * c - h * s
bind y2 = y + h * s + h * c
bind x3 = x - h * c - h * s
bind y3 = y - h * s + h * c
draw_line(x0, y0, x1, y1)
draw_line(x1, y1, x2, y2)
draw_line(x2, y2, x3, y3)
draw_line(x3, y3, x0, y0)
}
# hatch inside a circle: parallel chords at angle a, spacing sp
fn hatch_disc(cx, cy, r, a, sp) {
bind nx = cos(a + 1.5708)
bind ny = sin(a + 1.5708)
bind tx = cos(a)
bind ty = sin(a)
bind d = 0.0 - r + sp * 0.5
while d < r {
bind h = sqrt(max(r * r - d * d, 0.0))
draw_line(cx + nx * d - tx * h, cy + ny * d - ty * h, cx + nx * d + tx * h, cy + ny * d + ty * h)
bind d = d + sp
}
}
# hatch inside an axis-aligned square [x, x+s] x [y, y+s], lines at 45 degrees
fn hatch_box(x, y, s, sp) {
bind d = sp
while d < 2.0 * s {
bind ax = x
bind ay = y + d
bind bx = x + d
bind by = y
if d > s {
bind ax = x + d - s
bind ay = y + s
bind bx = x + s
bind by = y + d - s
}
draw_line(ax, ay, bx, by)
bind d = d + sp
}
}
fn fmt_mb(v) {
if v >= 1024.0 { return num_str(round(v / 102.4) / 10.0) + "G" }
return num_str(round(v)) + "M"
}
fn fmt_rate(v) {
if v >= 10000.0 { return num_str(round(v / 1000.0)) + "K" }
if v >= 1000.0 { return num_str(round(v / 100.0) / 10.0) + "K" }
return num_str(round(v))
}
# ───────────────────────────── glyph drawing ─────────────────────────────────
# Outlines come from the Ling bundle. Contours are closed, y runs down.
# Daemon glyph fitted into a bw x bh box centred on (x, y), turned by a
fn daemon_glyph(ch, x, y, bw, bh, a) {
bind i = str_find(DAEMON_CH, ch)
if i < 0 { return 0 }
bind g = DAEMON[i]
bind sc = min(bw / g[0], bh / g[1])
bind gw = g[0] * sc
bind gh = g[1] * sc
bind c = cos(a)
bind s = sin(a)
bind polys = g[2]
bind p = 0
while p < len(polys) {
bind pts = polys[p]
bind n = len(pts) / 2
bind j = 0
while j < n {
bind k = (j + 1) % n
bind ux = pts[j * 2] * sc - gw / 2.0
bind uy = pts[j * 2 + 1] * sc - gh / 2.0
bind vx = pts[k * 2] * sc - gw / 2.0
bind vy = pts[k * 2 + 1] * sc - gh / 2.0
draw_line(x + ux * c - uy * s, y + ux * s + uy * c, x + vx * c - vy * s, y + vx * s + vy * c)
bind j = j + 1
}
bind p = p + 1
}
return 1
}
# a run of Daemon letters, h tall, left-aligned at (x, y) where y is the vertical centre
fn daemon_text(str, x, y, h) {
bind n = str_len(str)
bind i = 0
while i < n {
bind ch = str_slice(str, i, 1)
if ch != " " { daemon_glyph(ch, x + i * h * 0.74 + h * 0.3, y, h * 0.62, h, 0.0) }
bind i = i + 1
}
}
fn text_w(str, h) { return str_len(str) * h * 0.74 }
# Chesilin glyph bent round a ring: radius rm, centred on angle ac (radians, clockwise from up)
fn chesilin_glyph(ch, cx, cy, rm, ac, bw, bh) {
bind i = str_find(CHESILIN_CH, ch)
if i < 0 { return 0 }
bind g = CHESILIN[i]
bind sc = min(bw / g[0], bh / g[1])
bind gw = g[0] * sc
bind gh = g[1] * sc
bind polys = g[2]
bind p = 0
while p < len(polys) {
bind pts = polys[p]
bind n = len(pts) / 2
bind j = 0
while j < n {
bind k = (j + 1) % n
bind ux = pts[j * 2] * sc - gw / 2.0
bind uy = pts[j * 2 + 1] * sc - gh / 2.0
bind vx = pts[k * 2] * sc - gw / 2.0
bind vy = pts[k * 2 + 1] * sc - gh / 2.0
bind m = 1 + floor(abs(vx - ux) / (rm * 0.05))
bind q = 0
while q < m {
bind f0 = q / m
bind f1 = (q + 1) / m
pline(cx, cy, rm - mix(uy, vy, f0), ac + mix(ux, vx, f0) / rm, rm - mix(uy, vy, f1), ac + mix(ux, vx, f1) / rm)
bind q = q + 1
}
bind j = j + 1
}
bind p = p + 1
}
return 1
}
# ring text: the string repeats round the whole ring in n cells, turned by spin
fn ring_text(str, cx, cy, r0, r1, spin, lit, k, sat, hs) {
bind band = r1 - r0
bind rm = (r0 + r1) / 2.0
bind sl = str_len(str)
bind n = floor(TAU * rm / (band * 0.62))
bind da = TAU / n
col(k, sat, lit, hs)
bind i = 0
while i < n {
bind ch = str_slice(str, i % sl, 1)
if ch != " " { chesilin_glyph(ch, cx, cy, rm, spin + (i + 0.5) * da, rm * da * 0.72, band * 0.62) }
bind i = i + 1
}
}
# a Daemon tile: frame, corner brackets, letter, optional hatch
fn tile(ch, x, y, s, lit, k, sat, hs, fillk) {
col(k, sat, lit, hs)
draw_line(x, y, x + s, y)
draw_line(x + s, y, x + s, y + s)
draw_line(x + s, y + s, x, y + s)
draw_line(x, y + s, x, y)
bind a = s * 0.055
bind b = s * 0.21
draw_line(x + a, y + a + b, x + a, y + a)
draw_line(x + a, y + a, x + a + b, y + a)
draw_line(x + s - a - b, y + a, x + s - a, y + a)
draw_line(x + s - a, y + a, x + s - a, y + a + b)
draw_line(x + s - a, y + s - a - b, x + s - a, y + s - a)
draw_line(x + s - a, y + s - a, x + s - a - b, y + s - a)
draw_line(x + a + b, y + s - a, x + a, y + s - a)
draw_line(x + a, y + s - a, x + a, y + s - a - b)
if fillk > 0.0 {
col(k, sat * 0.8, lit * 0.45, hs)
hatch_box(x + a, y + a, s - 2.0 * a, max(2.5, s * 0.07) / fillk)
}
col(k, sat, min(lit + 16.0, 92.0), hs)
daemon_glyph(ch, x + s / 2.0, y + s / 2.0, s * 0.6, s * 0.6, 0.0)
}
# ───────────────────────────── generic snapshot helpers ──────────────────────
# The *.snap files are written by sampler.ps1 (memory) and sampler_hw.ps1 (gpu, board, net).
# One record per line, fields split by '|'. A row is a list of strings.
fn nf(row, i) {
if i < len(row) { return to_number(row[i]) }
return 0.0
}
fn sf(row, i) {
if i < len(row) { return row[i] }
return ""
}
fn nums(row, from) {
bind out = []
bind i = from
while i < len(row) {
bind out = list_push(out, to_number(row[i]))
bind i = i + 1
}
return out
}
fn zeros(n) {
bind out = []
bind i = 0
while i < n {
bind out = list_push(out, 0.0)
bind i = i + 1
}
return out
}
fn pad_to(l, n) {
bind out = l
while len(out) < n {
bind out = list_push(out, 0.0)
}
return out
}
fn snap_rows(text) {
bind lines = split(text, "\n")
bind out = []
bind i = 0
while i < len(lines) {
bind ln = trim(lines[i])
if str_len(ln) > 2 { bind out = list_push(out, split(ln, "|")) }
bind i = i + 1
}
return out
}
# the sampler's wall-clock stamp: if it stops changing, the sampler has stopped
fn snap_time(rows) {
bind i = 0
while i < len(rows) {
bind r = rows[i]
if r[0] == "t" { return nf(r, 1) }
bind i = i + 1
}
return 0.0
}
# glide a list of numbers (or a list of such lists) toward its target
fn glide(cur, tgt, k) {
if len(cur) != len(tgt) { return tgt }
bind out = []
bind i = 0
while i < len(cur) {
bind out = list_push(out, mix(cur[i], tgt[i], k))
bind i = i + 1
}
return out
}
fn glide_ll(cur, tgt, k) {
if len(cur) != len(tgt) { return tgt }
bind out = []
bind i = 0
while i < len(cur) {
bind out = list_push(out, glide(cur[i], tgt[i], k))
bind i = i + 1
}
return out
}
# log scale to 0..1: full is log10 of the value that fills the strip
fn lg(x, full) { return clamp(log10(1.0 + max(x, 0.0)) / full, 0.0, 1.0) }
fn fmt_bytes(v) {
if v >= 1000000000.0 { return num_str(round(v / 100000000.0) / 10.0) + "G" }
if v >= 1000000.0 { return num_str(round(v / 100000.0) / 10.0) + "M" }
if v >= 1000.0 { return num_str(round(v / 1000.0)) + "K" }
return num_str(round(v))
}
fn fmt_up(s) {
bind d = floor(s / 86400.0)
bind h = floor((s - d * 86400.0) / 3600.0)
bind m = floor((s - d * 86400.0 - h * 3600.0) / 60.0)
if d > 0 { return num_str(d) + "D " + num_str(h) + "H" }
return num_str(h) + "H " + num_str(m) + "M"
}
fn pct(x) { return num_str(round(x)) }
fn short_gpu(name) {
bind s = str_replace(name, "NVIDIA ", "")
bind s = str_replace(s, "GEFORCE ", "")
bind s = str_replace(s, "AMD ", "")
bind s = str_replace(s, "RADEON ", "")
bind s = str_replace(s, "INTEL(R) ", "")
return str_slice(s, 0, 14)
}
# ───────────────────────────── history strips ────────────────────────────────
fn hs_new() {
bind hs = []
bind i = 0
while i < HS_COUNT {
bind hs = list_push(hs, zeros(HS_N))
bind i = i + 1
}
return hs
}
fn hs_push(hs, id, v) {
bind old = hs[id]
bind nw = []
bind i = 1
while i < len(old) {
bind nw = list_push(nw, old[i])
bind i = i + 1
}
bind nw = list_push(nw, clamp(v, 0.0, 1.0))
return list_set(hs, id, nw)
}
# ───────────────────────────── GPU ───────────────────────────────────────────
# pack GP: [good, n, names, drvs, vecs, engs, procs, sel]
bind GP_N = 1
bind GP_NAME = 2
bind GP_DRV = 3
bind GP_VEC = 4
bind GP_ENG = 5
bind GP_PROC = 6
bind GP_SEL = 7
fn parse_gpu(text) {
bind rows = snap_rows(text)
bind n = 0
bind i = 0
while i < len(rows) {
bind r = rows[i]
if r[0] == "n" { bind n = max(n, floor(nf(r, 1)) + 1) }
bind i = i + 1
}
bind n = min(n, 8)
bind names = []
bind drvs = []
bind vecs = []
bind engs = []
bind procs = []
bind g = 0
while g < n {
bind names = list_push(names, "GPU")
bind drvs = list_push(drvs, "")
bind vecs = list_push(vecs, zeros(GV_LEN))
bind engs = list_push(engs, zeros(6))
bind procs = list_push(procs, [[], [], [], []])
bind g = g + 1
}
bind i = 0
while i < len(rows) {
bind r = rows[i]
bind tag = r[0]
bind g = floor(nf(r, 1))
if g >= 0 {
if g < n {
if tag == "n" {
bind names = list_set(names, g, str_upper(sf(r, 2)))
bind drvs = list_set(drvs, g, sf(r, 3))
}
if tag == "v" { bind vecs = list_set(vecs, g, pad_to(nums(r, 2), GV_LEN)) }
if tag == "e" { bind engs = list_set(engs, g, pad_to(nums(r, 2), 6)) }
if tag == "a" {
bind pg = procs[g]
bind pg = [list_push(pg[0], str_upper(sf(r, 2))), list_push(pg[1], nf(r, 4)), list_push(pg[2], nf(r, 5)), list_push(pg[3], nf(r, 6))]
bind procs = list_set(procs, g, pg)
}
}
}
bind i = i + 1
}
bind good = 0
if n > 0 { bind good = 1 }
return [good, n, names, drvs, vecs, engs, procs, 0, snap_time(rows)]
}
bind SIM_NAMES = ["chrome", "code", "firefox", "explorer", "python", "node", "slack", "spotify", "ling", "audiodg",
"svchost", "dwm", "teams", "steam", "obs", "docker", "mysqld", "discord", "winword", "excel"]
fn sim_gpu(t) {
bind names = []
bind drvs = []
bind vecs = []
bind engs = []
bind procs = []
bind g = 0
while g < 4 {
bind u = 22.0 + 20.0 * sin(t * 0.31 + g * 2.0) + 55.0 * pow(abs(sin(t * 0.07 + g * 1.3)), 4.0)
bind u = clamp(u, 1.0, 100.0)
bind vu = 9000.0 + 5000.0 * sin(t * 0.05 + g) + 40.0 * u
bind names = list_push(names, "SIM GPU " + num_str(g))
bind drvs = list_push(drvs, "0.0")
bind vecs = list_push(vecs, [36.0 + 0.4 * u, 28.0 + 0.55 * u, 18.0 + 4.1 * u, 450.0, 210.0 + 28.0 * u, 3105.0, 405.0 + 100.0 * u, 10501.0, u, u * 0.4, vu, 24564.0, 4.0, 16.0, 0.0, 0.0])
bind engs = list_push(engs, [u * 0.95, u * 0.3 * (1.0 + sin(t * 0.4)), 12.0 * pow(abs(sin(t * 0.21 + g)), 3.0), 6.0 * pow(abs(sin(t * 0.13)), 5.0), 25.0 * pow(abs(sin(t * 0.09 + g)), 6.0), 3.0])
bind pn = []
bind pd = []
bind ps = []
bind pu = []
bind q = 0
while q < 8 {
bind pn = list_push(pn, str_upper(SIM_NAMES[(q + g * 5) % 20]))
bind pd = list_push(pd, vu * 0.5 / (1.0 + q * 0.9))
bind ps = list_push(ps, 30.0 / (1.0 + q))
bind pu = list_push(pu, u * 0.7 / (1.0 + q))
bind q = q + 1
}
bind procs = list_push(procs, [pn, pd, ps, pu])
bind g = g + 1
}
return [1, 4, names, drvs, vecs, engs, procs, 0, 0.0]
}
# ───────────────────────────── board ─────────────────────────────────────────
# pack BP: [good, info, bv, cutil, cfreq, dimms, disks, dio, sens, t]
bind BP_INFO = 1
bind BP_BV = 2
bind BP_CU = 3
bind BP_CF = 4
bind BP_DIMM = 5
bind BP_DISK = 6
bind BP_DIO = 7
bind BP_SENS = 8
# info: [maker, product, bios vendor, bios version, bios date, cpu, cores, threads, max MHz, sockets, dimm slots, max GB]
bind BI_MAKER = 0
bind BI_PROD = 1
bind BI_BIOSV = 2
bind BI_BIOSVER = 3
bind BI_BIOSDATE = 4
bind BI_CPU = 5
bind BI_CORES = 6
bind BI_THR = 7
bind BI_MHZ = 8
bind BI_SOCK = 9
bind BI_SLOTS = 10
bind BI_MAXGB = 11
fn parse_board(text) {
bind rows = snap_rows(text)
bind info = ["", "", "", "", "", "", 0, 0, 0, 1, 0, 0]
bind bv = []
bind nc = 0
bind i = 0
while i < len(rows) {
bind r = rows[i]
if r[0] == "k" { bind nc = max(nc, floor(nf(r, 1)) + 1) }
bind i = i + 1
}
bind nc = min(nc, 128)
bind cu = zeros(nc)
bind cf = zeros(nc)
bind dimms = []
bind disks = []
bind dio = []
bind sens = []
bind i = 0
while i < len(rows) {
bind r = rows[i]
bind tag = r[0]
if tag == "b" {
bind info = list_set(info, BI_MAKER, str_upper(sf(r, 1)))
bind info = list_set(info, BI_PROD, str_upper(sf(r, 2)))
}
if tag == "i" {
bind info = list_set(info, BI_BIOSV, str_upper(sf(r, 1)))
bind info = list_set(info, BI_BIOSVER, sf(r, 2))
bind info = list_set(info, BI_BIOSDATE, sf(r, 3))
}
if tag == "c" {
bind info = list_set(info, BI_CPU, str_upper(sf(r, 1)))
bind info = list_set(info, BI_CORES, nf(r, 2))
bind info = list_set(info, BI_THR, nf(r, 3))
bind info = list_set(info, BI_MHZ, nf(r, 4))
bind info = list_set(info, BI_SOCK, nf(r, 5))
}
if tag == "y" {
bind info = list_set(info, BI_SLOTS, nf(r, 1))
bind info = list_set(info, BI_MAXGB, nf(r, 2))
}
if tag == "m" { bind dimms = list_push(dimms, [str_upper(sf(r, 1)), nf(r, 2), nf(r, 3)]) }
if tag == "d" { bind disks = list_push(disks, [str_upper(sf(r, 1)), nf(r, 2)]) }
if tag == "l" { bind bv = pad_to(nums(r, 1), BV_LEN) }
if tag == "k" {
bind c = floor(nf(r, 1))
if c >= 0 {
if c < nc {
bind cu = list_set(cu, c, nf(r, 2))
bind cf = list_set(cf, c, nf(r, 3))
}
}
}
if tag == "s" { bind dio = list_push(dio, [str_upper(sf(r, 1)), nf(r, 2), nf(r, 3), nf(r, 4)]) }
if tag == "h" { bind sens = list_push(sens, [sf(r, 1), str_upper(sf(r, 2)), nf(r, 3)]) }
bind i = i + 1
}
bind good = 0
if len(bv) >= BV_LEN {
if nc > 0 { bind good = 1 }
}
return [good, info, bv, cu, cf, dimms, disks, dio, sens, snap_time(rows)]
}
fn sim_board(t) {
bind u = clamp(30.0 + 25.0 * sin(t * 0.3) + 35.0 * pow(abs(sin(t * 0.11)), 5.0), 2.0, 100.0)
bind info = ["SIMCORP", "HATCH SIM Z999", "SIM BIOS", "1.0", "2030-01-01", "SIM CORE 16", 8, 16, 4800, 1, 4, 128]
bind bv = [u, 2800.0 + 2000.0 * u / 100.0, 100.0, 32.0 + 28.0 * u / 100.0, 18000.0 + 160000.0 * u / 100.0, 2000.0 + 30000.0 * pow(abs(sin(t * 0.4)), 4.0),
90000.0 + 600000.0 * u / 100.0, 800000.0 + 6000000.0 * u / 100.0, 420.0, 5200.0, 86400.0 * 3.0 + t,
1000000.0 * pow(abs(sin(t * 0.23)), 6.0) * 300.0, 1000000.0 * pow(abs(sin(t * 0.19 + 1.0)), 6.0) * 200.0,
30.0 * pow(abs(sin(t * 0.2)), 3.0), 1.0]
bind cu = []
bind cf = []
bind i = 0
while i < 16 {
bind ci = clamp(u + 45.0 * sin(t * 0.5 + i * 0.9) - 15.0, 0.0, 100.0)
bind cu = list_push(cu, ci)
bind cf = list_push(cf, 1200.0 + 3600.0 * ci / 100.0)
bind i = i + 1
}
bind dimms = [["DIMM_A1", 16.0, 5600.0], ["DIMM_B1", 16.0, 5600.0]]
bind disks = [["SIM NVME 1000", 1000.0], ["SIM SATA 2000", 2000.0]]
bind dio = [["0 C:", bv[BV_DRD], bv[BV_DWR], bv[BV_DBUSY]], ["1 D:", 0.0, 0.0, 0.0]]
return [1, info, bv, cu, cf, dimms, disks, dio, [], 0.0]
}
# ───────────────────────────── network ───────────────────────────────────────
# pack NP: [good, adapters, nv, nodes, procs, t]; adapter [name, rx, tx, bits/s, pkts in, pkts out, errors];
# node [hash 0..1, port, state 0 est / 1 syn, process]; proc [name, connections]
bind NP_AD = 1
bind NP_NV = 2
bind NP_NODE = 3
bind NP_PROC = 4
# remote port -> one of the seven classes (= the seven Ling hues)
fn port_class(p) {
if p == 443 { return 0 }
if p == 80 { return 1 }
if p == 8080 { return 1 }
if p == 8000 { return 1 }
if p == 53 { return 2 }
if p == 5353 { return 2 }
if p == 22 { return 3 }
if p == 3389 { return 3 }
if p == 5900 { return 3 }
if p == 25 { return 4 }
if p == 110 { return 4 }
if p == 143 { return 4 }
if p == 465 { return 4 }
if p == 587 { return 4 }
if p == 993 { return 4 }
if p == 995 { return 4 }
if p >= 1024 { return 5 }
return 6
}
bind PORT_NAME = ["HTTPS", "HTTP", "DNS", "REMOTE", "MAIL", "HIGH", "OTHER"]
fn parse_net(text) {
bind rows = snap_rows(text)
bind ads = []
bind nodes = []
bind procs = []
bind kk = [0.0, 0.0, 0.0, 0.0, 0.0]
bind cc = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
bind rtt = 0.0 - 1.0
bind i = 0
while i < len(rows) {
bind r = rows[i]
bind tag = r[0]
if tag == "i" { bind ads = list_push(ads, [sf(r, 1), nf(r, 2), nf(r, 3), nf(r, 4), nf(r, 5), nf(r, 6), nf(r, 7)]) }
if tag == "k" { bind kk = pad_to(nums(r, 1), 5) }
if tag == "r" { bind rtt = nf(r, 1) }
if tag == "c" { bind cc = pad_to(nums(r, 1), 7) }
if tag == "x" { bind procs = list_push(procs, [str_upper(sf(r, 1)), nf(r, 3)]) }
if tag == "d" {
bind st = 0
if sf(r, 3) != "ESTABLISHED" { bind st = 1 }
bind nodes = list_push(nodes, [nf(r, 1), nf(r, 2), st, str_upper(sf(r, 4))])
}
bind i = i + 1
}
bind rx = 0.0
bind tx = 0.0
bind prx = 0.0
bind ptx = 0.0
bind bw = 0.0
bind a = 0
while a < len(ads) {
bind ad = ads[a]
bind rx = rx + ad[1]
bind tx = tx + ad[2]
bind prx = prx + ad[4]
bind ptx = ptx + ad[5]
if a == 0 { bind bw = ad[3] }
bind a = a + 1
}
bind nv = [rx, tx, prx, ptx, bw, kk[0], kk[1], kk[4], rtt, cc[1], cc[2], cc[3], cc[4], cc[6], kk[2]]
bind good = 0
if len(ads) > 0 { bind good = 1 }
return [good, ads, nv, nodes, procs, snap_time(rows)]
}
fn sim_net(t) {
bind b1 = pow(abs(sin(t * 0.21)), 5.0)
bind b2 = pow(abs(sin(t * 0.33 + 1.0)), 6.0)
bind rx = 40000.0 + 90000.0 * (1.0 + sin(t * 0.5)) + 40000000.0 * b1
bind tx = 8000.0 + 20000.0 * (1.0 + sin(t * 0.4)) + 6000000.0 * b2
bind ads = [["SIM ETHERNET", rx, tx, 1000000000.0, rx / 1200.0, tx / 900.0, 0.0]]
bind nodes = []
bind ports = [443, 443, 443, 80, 53, 22, 8333, 25565, 443, 993, 443, 3389, 8080, 51820]
bind i = 0
while i < 28 {
bind nodes = list_push(nodes, [fract(i * 0.6180339 + 0.1), ports[i % 14], 0, str_upper(SIM_NAMES[(i * 7) % 20])])
bind i = i + 1
}
bind procs = []
bind i = 0
while i < 8 {
bind procs = list_push(procs, [str_upper(SIM_NAMES[i]), 12.0 - i])
bind i = i + 1
}
bind nv = [rx, tx, rx / 1200.0, tx / 900.0, 1000000000.0, 90.0 + 20.0 * sin(t * 0.2), 2.0 + 30.0 * b2, 15.0 + 60.0 * b1, 8.0 + 10.0 * b2, 12.0, 6.0, 2.0, 0.0, 40.0, 3.0]
return [1, ads, nv, nodes, procs, 0.0]
}
# ───────────────────────────── history sampling ──────────────────────────────
# push one 0..1 sample into every strip; GP, BP, NP are the smoothed packs
fn hs_sample(hs, GP, BP, NP, memUsed, memFlt) {
bind g = 0
while g < min(GP[GP_N], 8) {
bind v = GP[GP_VEC][g]
bind b = HS_GPU + g * 4
bind hs = hs_push(hs, b, v[GV_UTIL] / 100.0)
bind hs = hs_push(hs, b + 1, v[GV_TEMP] / 100.0)
bind hs = hs_push(hs, b + 2, v[GV_POWER] / max(v[GV_PLIM], 1.0))
bind hs = hs_push(hs, b + 3, v[GV_VUSED] / max(v[GV_VTOTAL], 1.0))
bind g = g + 1
}
bind bv = BP[BP_BV]
bind hs = hs_push(hs, HS_BRD, bv[BV_UTIL] / 100.0)
bind hs = hs_push(hs, HS_BRD + 1, bv[BV_TEMP] / 100.0)
bind hs = hs_push(hs, HS_BRD + 2, lg(bv[BV_INTR], 6.0))
bind hs = hs_push(hs, HS_BRD + 3, lg(bv[BV_DPC], 5.0))
bind hs = hs_push(hs, HS_BRD + 4, lg(bv[BV_CTX], 6.5))
bind hs = hs_push(hs, HS_BRD + 5, lg(bv[BV_DRD], 9.0))
bind hs = hs_push(hs, HS_BRD + 6, lg(bv[BV_DWR], 9.0))
bind nv = NP[NP_NV]
bind hs = hs_push(hs, HS_NET, lg(nv[NV_RX], 9.0))
bind hs = hs_push(hs, HS_NET + 1, lg(nv[NV_TX], 9.0))
bind hs = hs_push(hs, HS_NET + 2, lg(nv[NV_PRX], 6.0))
bind hs = hs_push(hs, HS_NET + 3, lg(nv[NV_PTX], 6.0))
bind hs = hs_push(hs, HS_NET + 4, lg(nv[NV_EST], 3.5))
bind hs = hs_push(hs, HS_NET + 5, lg(nv[NV_UDP], 4.0))
bind rt = 0.0
if nv[NV_RTT] > 0.0 { bind rt = nv[NV_RTT] / 500.0 }
bind hs = hs_push(hs, HS_NET + 6, rt)
bind hs = hs_push(hs, HS_NET + 7, lg(nv[NV_RETX], 3.0))
bind hs = hs_push(hs, HS_MEM, memUsed)
bind hs = hs_push(hs, HS_MEM + 1, lg(memFlt, 6.0))
return hs
}
# ───────────────────────────── data ──────────────────────────────────────────
# mem.snap, see sampler.ps1. Returns [good, g, r, private_all, names, ws, priv, ior, iow]
fn parse_snap(text) {
bind g = []
bind r = []
bind pall = 0.0
bind names = []
bind ws = []
bind priv = []
bind ior = []
bind iow = []
bind lines = split(text, "\n")
bind i = 0
while i < len(lines) {
bind f = split(trim(lines[i]), "|")
bind tag = f[0]
if tag == "g" {
bind g = []
bind j = 1
while j < len(f) {
bind g = list_push(g, to_number(f[j]))
bind j = j + 1
}
}
if tag == "r" {
bind r = []
bind j = 1
while j < len(f) {
bind r = list_push(r, to_number(f[j]))
bind j = j + 1
}
}
if tag == "t" { bind ts = to_number(f[1]) }
if tag == "s" { bind pall = to_number(f[1]) }
if tag == "p" {
if len(f) >= 8 {
bind names = list_push(names, f[1])
bind ws = list_push(ws, to_number(f[3]))
bind priv = list_push(priv, to_number(f[4]))
bind ior = list_push(ior, to_number(f[5]))
bind iow = list_push(iow, to_number(f[6]))
}
}
bind i = i + 1
}
bind good = 0
if len(g) >= 11 {
if len(r) >= 8 { bind good = 1 }
}
return [good, g, r, pall, names, ws, priv, ior, iow, ts]
}
# the seven category sizes in MB, from the sampler's counters
fn categories(g, pall) {
bind total = g[0]
bind avail = g[1]
bind free = g[2]
bind standby = g[3]
bind modified = g[4]
bind kernel = g[5] + g[6]
bind comp = g[7]
bind inuse = max(total - avail - modified, 0.0)
bind data = clamp(pall - comp, 0.0, max(inuse - kernel - comp, 0.0))
bind mapped = max(inuse - kernel - comp - data, 0.0)
return [kernel, standby, data, modified, mapped, comp, free]
}
# a made-up machine for when there is no sampler: 16 GB, breathing, with bursts of paging
fn sim_cats(t) {
bind total = 16384.0
bind kernel = 900.0 + 150.0 * sin(t * 0.13)
bind standby = 4200.0 + 1600.0 * sin(t * 0.05 + 1.0)
bind data = 5200.0 + 2200.0 * sin(t * 0.031 + 2.0) + 600.0 * sin(t * 0.21)
bind modified = 130.0 + 110.0 * (sin(t * 0.4) + 1.0)
bind comp = 700.0 + 300.0 * sin(t * 0.07)
bind mapped = 1500.0 + 500.0 * sin(t * 0.09 + 3.0)
bind free = max(total - kernel - standby - data - modified - comp - mapped, 200.0)
return [kernel, standby, data, modified, mapped, comp, free]
}
fn sim_rates(t) {
bind b1 = pow(abs(sin(t * 0.37)), 6.0)
bind b2 = pow(abs(sin(t * 0.23 + 1.0)), 8.0)
bind b3 = pow(abs(sin(t * 0.51 + 2.0)), 5.0)
return [3000.0 + 2500.0 * sin(t * 0.7) + 40000.0 * b3, 40.0 + 4000.0 * b1, 20.0 + 3000.0 * b2]
}
# weighted pick: w is a list of weights, u in [0,1)
fn pick(w, u) {
bind sum = 0.0
bind i = 0
while i < len(w) {
bind sum = sum + w[i]
bind i = i + 1
}
bind v = u * sum
bind i = 0
while i < len(w) - 1 {
if v < w[i] { return i }
bind v = v - w[i]
bind i = i + 1
}
return len(w) - 1
}
# Hilbert curve table for a 32 x 32 page map: flat [x0, y0, x1, y1, ...]
fn hilbert_table(n) {
bind out = []
bind d = 0
while d < n * n {
bind t = d
bind x = 0
bind y = 0
bind s = 1
while s < n {
bind rx = floor(t / 2) % 2
bind ry = (t % 2 + rx) % 2
if ry == 0 {
if rx == 1 {
bind x = s - 1 - x
bind y = s - 1 - y
}
bind tmp = x
bind x = y
bind y = tmp
}
bind x = x + s * rx
bind y = y + s * ry
bind t = floor(t / 4)
bind s = s * 2
}
bind out = list_push(out, x)
bind out = list_push(out, y)
bind d = d + 1
}
return out
}
# ───────────────────────────── pulses ────────────────────────────────────────
# EV is flat, six numbers per pulse: kind (0 read circle, 1 write square), category,
# born, seed, magnitude, process index.
fn ev_add(ev, kind, cat, born, seed, mag, proc) {
bind ev = list_push(ev, kind)
bind ev = list_push(ev, cat)
bind ev = list_push(ev, born)
bind ev = list_push(ev, seed)
bind ev = list_push(ev, mag)
bind ev = list_push(ev, proc)
return ev
}
fn ev_cull(ev, t, life) {
bind out = []
bind i = 0
while i < len(ev) {
if t - ev[i + 2] < life {
bind j = 0
while j < 6 {
bind out = list_push(out, ev[i + j])
bind j = j + 1
}
}
bind i = i + 6
}
return out
}
# ───────────────────────────── view 1: RINGS ─────────────────────────────────
fn ring_geom(c, R) {
bind r1 = R * (1.0 - c * 0.1)
bind band = R * 0.082
return [r1, r1 - band, band]
}
fn ring_spin(Z, c) {
bind dir = 1.0
if c % 2 == 1 { bind dir = 0.0 - 1.0 }
return Z[Z_ROT] * dir * (0.35 + 0.12 * c) + Z[Z_T] * dir * 0.03 * (c + 1)
}
fn view_rings(Z) {
bind W = Z[Z_W]
bind H = Z[Z_H]
bind cx = W / 2.0
bind cy = H / 2.0
bind R = min(W, H) * 0.5 - 16.0
bind t = Z[Z_T]
bind hs = Z[Z_HS]
bind sat = Z[Z_SAT]
bind cats = Z[Z_CATS]
bind total = Z[Z_TOTAL]
bind en = Z[Z_ENERGY]
bind c = 0
while c < 7 {
bind gm = ring_geom(c, R)
bind r1 = gm[0]
bind r0 = gm[1]
bind band = gm[2]
bind frac = cats[c] / total
bind spin = ring_spin(Z, c)
bind e = en[c]
# the two rails
col(c, sat * 0.7, 26.0 + 14.0 * e, hs)
draw_circle(cx, cy, r1)
draw_circle(cx, cy, r0)
# crosshatch over the occupied sector, a second angle once the ring is busy
bind sweep = max(frac * TAU, 0.03)
bind da = 0.0215
bind n = floor(sweep / da)
bind k = 0
col(c, sat, 36.0 + 26.0 * e, hs)
while k < n {
bind a = spin + k * da
pline(cx, cy, r0, a, r1, a + 0.05 + 0.05 * e)
bind k = k + 1
}
if e > 0.35 {
bind k = 0
col(c, sat, 30.0 + 22.0 * e, hs)
while k < n {
bind a = spin + k * da
pline(cx, cy, r0, a + 0.05, r1, a)
bind k = k + 2
}
}
col(c, sat, 62.0 + 28.0 * e, hs)
pline(cx, cy, r0 - 4.0, spin, r1 + 4.0, spin)
pline(cx, cy, r0 - 4.0, spin + sweep, r1 + 4.0, spin + sweep)
# ring text: name, size, share
bind label = CAT_NAME[c] + " " + fmt_mb(cats[c]) + " " + num_str(round(frac * 1000.0) / 10.0) + "% "
ring_text(label, cx, cy, r0 + band * 0.06, r1 - band * 0.06, spin * 0.6 + 1.0, 74.0 + 20.0 * e, c, sat, hs)
bind c = c + 1
}
# hub: used share in Daemon, ticks turning
bind hr = R * 0.3 - 6.0
ink(34.0)
draw_circle(cx, cy, hr)
bind k = 0
while k < 60 {
bind a = k * TAU / 60.0 + Z[Z_ROT] * 0.5
bind tl = 5.0
if k % 5 == 0 { bind tl = 11.0 }
pline(cx, cy, hr - tl, a, hr, a)
bind k = k + 1
}
bind used = num_str(round(Z[Z_USED] * 100.0)) + "%"
col(2, sat, 78.0, hs)
daemon_text(used, cx - text_w(used, hr * 0.5) / 2.0, cy - hr * 0.08, hr * 0.5)
ink(55.0)
daemon_text("USED", cx - text_w("USED", hr * 0.2) / 2.0, cy + hr * 0.4, hr * 0.2)
# pulses ride their ring
bind ev = Z[Z_EV]
bind i = 0
while i < len(ev) {
bind age = t - ev[i + 2]
bind p = age / 1.8
bind cc = ev[i + 1]
bind gm = ring_geom(cc, R)
bind rm = (gm[0] + gm[1]) / 2.0
bind a = ring_spin(Z, cc) + ev[i + 3] * TAU
bind x = px(cx, rm, a)
bind y = py(cy, rm, a)
col(cc, sat, (1.0 - p) * (55.0 + 40.0 * ev[i + 4]), hs)
if ev[i] == 0 {
draw_circle(x, y, gm[2] * (0.25 + 1.5 * p))
draw_circle(x, y, gm[2] * (0.1 + 0.9 * p))
} else {
square(x, y, gm[2] * (1.1 - 0.8 * p), a + p * 2.0)
square(x, y, gm[2] * (0.6 - 0.4 * p), a - p * 2.0)
}
bind i = i + 6
}
}
# ───────────────────────────── view 2: TILES ─────────────────────────────────
fn cell_cat(i, cum) {
bind k = 0
while k < 6 {
if i < cum[k] { return ORDER[k] }
bind k = k + 1
}
return ORDER[6]
}
fn view_tiles(Z) {
bind W = Z[Z_W]
bind H = Z[Z_H]
bind t = Z[Z_T]
bind hs = Z[Z_HS]
bind sat = Z[Z_SAT]
bind cats = Z[Z_CATS]
bind total = Z[Z_TOTAL]
bind en = Z[Z_ENERGY]
bind hil = Z[Z_HIL]
bind S = min(H * 0.76, W * 0.5)
bind cs = S / 32.0
bind mx = W * 0.36
bind my = H * 0.5
bind tilt = 0.09 * sin(t * 0.07) + 0.07 * sin(Z[Z_ROT] * 0.8)
bind ca = cos(tilt)
bind sa = sin(tilt)
# cumulative cell counts along the curve, in ORDER
bind cum = []
bind run = 0.0
bind k = 0
while k < 7 {
bind run = run + cats[ORDER[k]] / total * 1024.0
bind cum = list_push(cum, round(run))
bind k = k + 1
}
bind i = 0
while i < 1024 {
bind c = cell_cat(i, cum)
bind gx = hil[i * 2] - 15.5
bind gy = hil[i * 2 + 1] - 15.5
bind x = mx + (gx * ca - gy * sa) * cs
bind y = my + (gx * sa + gy * ca) * cs
bind hv = fract(sin(i * 12.9898) * 43758.5453)
bind hv = fract(hv + 0.18 * sin(t * 0.6 + i * 0.37) + 1.0)
bind e = en[c]
bind h = cs * 0.46
col(c, sat * 0.8, 20.0 + 16.0 * hv + 14.0 * e, hs + (hv - 0.5) * 10.0)
square(x, y, h, tilt)
if c != 6 {
bind nl = 1 + floor(hv * 3.0 + e * 2.0)
bind m = 0
col(c, sat, 30.0 + 26.0 * hv + 22.0 * e, hs + (hv - 0.5) * 10.0)
while m < nl {
bind u = (m + 0.5) / nl
bind s0 = (u * 2.0 - 1.0) * h
bind an = tilt + ANG1[c]
bind dx = cos(an) * h * 0.9
bind dy = sin(an) * h * 0.9
bind ox = (0.0 - sin(an)) * s0
bind oy = cos(an) * s0
draw_line(x + ox - dx, y + oy - dy, x + ox + dx, y + oy + dy)
bind m = m + 1
}
} else {
col(6, sat * 0.5, 18.0, hs)
draw_pixel(x, y)
}
bind i = i + 1
}
ink(30.0)
square(mx, my, S * 0.5 + cs * 0.9, tilt)
# pulses: read = circles leaving a cell, write = squares closing on it
bind ev = Z[Z_EV]
bind j = 0
while j < len(ev) {
bind age = t - ev[j + 2]
bind p = age / 1.8
bind c = ev[j + 1]
bind kk = 0
while kk < 7 {
if ORDER[kk] == c {
bind lo = 0
if kk > 0 { bind lo = cum[kk - 1] }
bind span = max(cum[kk] - lo, 1.0)
bind idx = min(floor(lo + ev[j + 3] * span), 1023)
bind gx = hil[idx * 2] - 15.5
bind gy = hil[idx * 2 + 1] - 15.5
bind x = mx + (gx * ca - gy * sa) * cs
bind y = my + (gx * sa + gy * ca) * cs
col(c, sat, (1.0 - p) * (60.0 + 35.0 * ev[j + 4]), hs)
if ev[j] == 0 {
draw_circle(x, y, cs * (0.5 + 3.5 * p))
draw_circle(x, y, cs * (0.3 + 1.6 * p))
} else {
square(x, y, cs * (2.6 - 2.1 * p), tilt + p * 3.0)
square(x, y, cs * 0.5, tilt)
if p < 0.35 { draw_disc(x, y, cs * 0.35) }
}
}
bind kk = kk + 1
}
bind j = j + 6
}
# legend: seven Daemon tiles
bind lx = W * 0.68
bind ts = min(H * 0.095, 62.0)
bind c = 0
while c < 7 {
bind ly = H * 0.1 + c * (ts + H * 0.03)
bind e = en[c]
tile(str_slice(CAT_LET, c, 1), lx, ly, ts, 52.0 + 30.0 * e, c, sat, hs, 0.6 + e)
col(c, sat, 68.0, hs)
daemon_text(CAT_NAME[c], lx + ts + 14.0, ly + ts * 0.3, ts * 0.3)
ink(62.0)
daemon_text(fmt_mb(cats[c]) + " " + num_str(round(cats[c] / total * 1000.0) / 10.0) + "%", lx + ts + 14.0, ly + ts * 0.68, ts * 0.26)
bind bw = W * 0.28
bind bx = lx + ts + 14.0
bind by = ly + ts * 0.95
col(c, sat * 0.8, 40.0, hs)
draw_line(bx, by, bx + bw, by)
bind fw = bw * cats[c] / total
col(c, sat, 60.0 + 20.0 * e, hs)
bind u = 0.0
while u < fw {
draw_line(bx + u, by, bx + u + 4.0, by - 5.0)
bind u = u + 3.0
}
bind c = c + 1
}
}
# ───────────────────────────── view 3: ORBITS ────────────────────────────────
fn name_hue(name) {
bind h = 0
bind i = 0
while i < str_len(name) {
bind h = (h * 31 + str_find(DAEMON_CH, str_slice(name, i, 1)) + 1) % 7919
bind i = i + 1
}
return h % 7
}
fn view_orbits(Z) {
bind W = Z[Z_W]
bind H = Z[Z_H]
bind cx = W / 2.0
bind cy = H / 2.0
bind R = min(W, H) * 0.5 - 20.0
bind t = Z[Z_T]
bind hs = Z[Z_HS]
bind sat = Z[Z_SAT]
bind names = Z[Z_NAME]
bind ws = Z[Z_WS]
bind pv = Z[Z_PRIV]
bind ior = Z[Z_IOR]
bind iow = Z[Z_IOW]
bind np = min(min(len(names), len(ior)), 22)
bind i = 0
while i < np {
ink(14.0)
draw_circle(cx, cy, R * (0.24 + 0.74 * i / max(np - 1, 1)))
bind i = i + 1
}
# the sun: memory in use
bind used = num_str(round(Z[Z_USED] * 100.0)) + "%"
col(2, sat, 70.0, hs)
draw_circle(cx, cy, R * 0.12)
draw_circle(cx, cy, R * 0.1)
daemon_text(used, cx - text_w(used, R * 0.09) / 2.0, cy, R * 0.09)
bind k = 0
while k < 36 {
bind a = k * TAU / 36.0 - Z[Z_ROT] * 0.7
pline(cx, cy, R * 0.12, a, R * 0.12 + 5.0 + 4.0 * (k % 3), a)
bind k = k + 1
}
# bodies: circle = working set, square = private bytes
bind pos = []
bind i = 0
while i < np {
bind orr = R * (0.24 + 0.74 * i / max(np - 1, 1))
bind dir = 1.0
if i % 2 == 1 { bind dir = 0.0 - 1.0 }
bind io = clamp(log10(1.0 + ior[i] + iow[i]) / 4.0, 0.0, 1.0)
bind a = i * 2.399 + Z[Z_ROT] * dir * (0.8 / sqrt(1.0 + i)) * (1.0 + 2.0 * io)
bind x = px(cx, orr, a)
bind y = py(cy, orr, a)
bind pos = list_push(pos, x)
bind pos = list_push(pos, y)
bind k = name_hue(names[i])
bind r = clamp(4.0 + sqrt(ws[i]) * 0.3, 5.0, R * 0.11)
col(k, sat, 48.0 + 24.0 * io, hs)
draw_circle(x, y, r)
draw_circle(x, y, r * 0.86)
col(k, sat, 32.0 + 22.0 * io, hs)
hatch_disc(x, y, r * 0.84, ANG1[k] + Z[Z_ROT] * 0.5, max(2.6, r * 0.12))
bind sh = r * 0.7 * sqrt(clamp(pv[i] / max(ws[i], 1.0), 0.05, 1.0))
col(k, sat, 78.0, hs)
square(x, y, sh, t * 0.6 * dir + i)
if r > 15.0 {
col(k, sat, 88.0, hs)
daemon_glyph(str_upper(str_slice(names[i], 0, 1)), x, y, r * 0.5, r * 0.6, 0.0)
}
if r > 11.0 {
bind nm = str_upper(str_slice(names[i], 0, 10))
bind m = str_len(nm)
bind rm2 = r + 9.0
bind da = 11.0 / rm2
bind q = 0
col(k, sat * 0.9, 70.0, hs)
while q < m {
bind ch = str_slice(nm, q, 1)
if ch != " " { chesilin_glyph(ch, x, y, rm2, (q - (m - 1) / 2.0) * da, 9.0, 8.0) }
bind q = q + 1
}
}
bind i = i + 1
}
# pulses leave their process
bind ev = Z[Z_EV]
bind j = 0
while j < len(ev) {
bind pidx = ev[j + 5]
if pidx < np {
bind p = (t - ev[j + 2]) / 1.8
bind x = pos[pidx * 2]
bind y = pos[pidx * 2 + 1]
bind k = name_hue(names[pidx])
bind r = clamp(4.0 + sqrt(ws[pidx]) * 0.3, 5.0, R * 0.11)
col(k, sat, (1.0 - p) * (60.0 + 38.0 * ev[j + 4]), hs)
if ev[j] == 0 {
draw_circle(x, y, r * (1.0 + 1.1 * p))
draw_circle(x, y, r * (1.0 + 0.5 * p))
} else {
square(x, y, r * (1.9 - 0.8 * p), p * 2.5)
square(x, y, r * (1.4 - 0.6 * p), 0.0 - p * 2.5)
}
}
bind j = j + 6
}
}
# ───────────────────────────── view 4: WEAVE ─────────────────────────────────
# Seven strings, one per category, each a sine at that category's partial ratio and
# loudness: the picture of the additive synth. The bottom trace is their sum. Notes
# (every read and write) are born at the playhead and scroll left.
fn lane_y(c, H) { return H * 0.14 + c * H * 0.095 }
fn view_weave(Z) {
bind W = Z[Z_W]
bind H = Z[Z_H]
bind t = Z[Z_T]
bind hs = Z[Z_HS]
bind sat = Z[Z_SAT]
bind cats = Z[Z_CATS]
bind total = Z[Z_TOTAL]
bind en = Z[Z_ENERGY]
bind x0 = W * 0.12
bind x1 = W * 0.9
bind xph = W * 0.86
bind sw = 8.0
bind amp = H * 0.042
bind c = 0
while c < 7 {
bind y = lane_y(c, H)
bind e = en[c]
bind a = amp * (0.12 + 0.88 * sqrt(cats[c] / total)) * (0.7 + 0.5 * e)
col(c, sat * 0.6, 14.0, hs)
draw_line(x0, y, x1, y)
col(c, sat, 40.0 + 36.0 * e, hs)
bind x = x0
bind prevy = y + a * sin(0.0 - t * RATIO[c] * 1.3)
while x < x1 {
bind u = (x + sw - x0) / (x1 - x0)
bind ny = y + a * sin(u * TAU * RATIO[c] * 2.0 - t * RATIO[c] * 1.3)
draw_line(x, prevy, x + sw, ny)
bind prevy = ny
bind x = x + sw
}
tile(str_slice(CAT_LET, c, 1), W * 0.03, y - H * 0.035, H * 0.07, 40.0 + 40.0 * e, c, sat, hs, 0.3 + e)
col(c, sat, 40.0 + 40.0 * e, hs)
bind dr = H * 0.033
draw_circle(W * 0.095, y, dr)
pline(W * 0.095, y, 0.0, 0.0, dr, t * RATIO[c] * 0.6 + c)
bind c = c + 1
}
# the sum of the seven strings
bind ys = H * 0.86
ink(18.0)
draw_line(x0, ys, x1, ys)
col(2, sat * 0.4, 86.0, hs)
bind x = x0
bind prevy = ys
bind first = 1
while x < x1 {
bind u = (x - x0) / (x1 - x0)
bind s = 0.0
bind k = 0
while k < 7 {
bind s = s + sqrt(cats[k] / total) * sin(u * TAU * RATIO[k] * 2.0 - t * RATIO[k] * 1.3)
bind k = k + 1
}
bind ny = ys + s * H * 0.045
if first == 0 { draw_line(x - 3.0, prevy, x, ny) }
bind prevy = ny
bind first = 0
bind x = x + 3.0
}
ink(70.0)
draw_line(xph, H * 0.05, xph, H * 0.95)
draw_line(xph + 6.0, H * 0.05, xph + 6.0, H * 0.95)
# notes: four numbers each, kind, category, born, magnitude
bind hist = Z[Z_HIST]
bind i = 0
while i < len(hist) {
bind age = t - hist[i + 2]
bind x = xph - age * (xph - x0) / 14.0
bind c = hist[i + 1]
bind y = lane_y(c, H)
bind r = H * 0.011 + H * 0.014 * hist[i + 3]
bind lit = 78.0 - age * 4.0
if age < 0.4 { bind lit = 96.0 }
col(c, sat, lit, hs)
if hist[i] == 0 {
draw_circle(x, y, r)
if age < 0.9 { draw_circle(x, y, r * (1.0 + age * 3.0)) }
} else {
square(x, y, r, age * 0.4)
if age < 0.9 { square(x, y, r * (1.0 + age * 2.0), age * 2.0) }
}
bind i = i + 4
}
}
# ───────────────────────────── shared views ──────────────────────────────────
# Used by every section: a stack of Chesilin rings (any number of rings) and a scrolling
# seven-lane scope. The Memory views in 40_memory.ling keep their own copies of this.
bind D_HT = 6
fn fit_h(str, maxw, h) { return min(h, maxw / (max(str_len(str), 1) * 0.74)) }
fn ring_geom2(c, R, nr) {
bind step = 0.7 / nr
bind r1 = R * (1.0 - c * step)
bind band = R * step * 0.82
return [r1, r1 - band, band]
}
# nr rings, one per channel: fr[c] is how much of the ring is crosshatched, labels[c] runs round it.
# The hub shows `big` (Daemon) and `small`. Pulses (Z_EV, category = ring) ride the rings.
fn ring_stack(Z, nr, hm, labels, fr, big, small, bigk) {
ring_stack_at(Z, Z[Z_W] / 2.0, Z[Z_H] / 2.0, min(Z[Z_W], Z[Z_H]) * 0.5 - 16.0, nr, hm, labels, fr, big, small, bigk)
}
# the same, centred on (cx, cy) with outer radius R
fn ring_stack_at(Z, cx, cy, R, nr, hm, labels, fr, big, small, bigk) {
bind t = Z[Z_T]
bind hs = Z[Z_HS]
bind sat = Z[Z_SAT]
bind en = Z[Z_ENERGY]
bind c = 0
while c < nr {
bind gm = ring_geom2(c, R, nr)
bind r1 = gm[0]
bind r0 = gm[1]
bind band = gm[2]
bind frac = clamp(fr[c], 0.0, 1.0)
bind spin = ring_spin(Z, c)
bind e = en[c]
col(hm[c], sat * 0.7, 26.0 + 14.0 * e, hs)
draw_circle(cx, cy, r1)
draw_circle(cx, cy, r0)
bind sweep = max(frac * TAU, 0.03)
bind da = 0.0215
bind n = floor(sweep / da)
bind k = 0
col(hm[c], sat, 36.0 + 26.0 * e, hs)
while k < n {
bind a = spin + k * da
pline(cx, cy, r0, a, r1, a + 0.05 + 0.05 * e)
bind k = k + 1
}
if e > 0.35 {
bind k = 0
col(hm[c], sat, 30.0 + 22.0 * e, hs)
while k < n {
bind a = spin + k * da
pline(cx, cy, r0, a + 0.05, r1, a)
bind k = k + 2
}
}
col(hm[c], sat, 62.0 + 28.0 * e, hs)
pline(cx, cy, r0 - 4.0, spin, r1 + 4.0, spin)
pline(cx, cy, r0 - 4.0, spin + sweep, r1 + 4.0, spin + sweep)
ring_text(labels[c], cx, cy, r0 + band * 0.06, r1 - band * 0.06, spin * 0.6 + 1.0, 74.0 + 20.0 * e, hm[c], sat, hs)
bind c = c + 1
}
bind hr = R * 0.3 - 6.0
ink(34.0)
draw_circle(cx, cy, hr)
bind k = 0
while k < 60 {
bind a = k * TAU / 60.0 + Z[Z_ROT] * 0.5
bind tl = 5.0
if k % 5 == 0 { bind tl = 11.0 }
pline(cx, cy, hr - tl, a, hr, a)
bind k = k + 1
}
bind bh = fit_h(big, hr * 1.5, hr * 0.5)
col(bigk, sat, 78.0, hs)
daemon_text(big, cx - text_w(big, bh) / 2.0, cy - hr * 0.08, bh)
bind sh = fit_h(small, hr * 1.5, hr * 0.2)
ink(55.0)
daemon_text(small, cx - text_w(small, sh) / 2.0, cy + hr * 0.4, sh)
bind ev = Z[Z_EV]
bind i = 0
while i < len(ev) {
bind cc = ev[i + 1]
if cc < nr {
bind age = t - ev[i + 2]
bind p = age / 1.8
bind gm = ring_geom2(cc, R, nr)
bind rm = (gm[0] + gm[1]) / 2.0
bind a = ring_spin(Z, cc) + ev[i + 3] * TAU
bind x = px(cx, rm, a)
bind y = py(cy, rm, a)
col(hm[cc], sat, (1.0 - p) * (55.0 + 40.0 * ev[i + 4]), hs)
if ev[i] == 0 {
draw_circle(x, y, gm[2] * (0.25 + 1.5 * p))
draw_circle(x, y, gm[2] * (0.1 + 0.9 * p))
} else {
square(x, y, gm[2] * (1.1 - 0.8 * p), a + p * 2.0)
square(x, y, gm[2] * (0.6 - 0.4 * p), a - p * 2.0)
}
}
bind i = i + 6
}
}
# seven lanes, each a Daemon tile, a name, a current value and the last minute as a trace.
# ids are history strip numbers (hs_push), vals are the current readings as text.
# Notes (every pulse) are born at the playhead and scroll left at the trace's speed.
fn scope(Z, titles, letters, ids, vals) {
bind W = Z[Z_W]
bind H = Z[Z_H]
bind t = Z[Z_T]
bind hs = Z[Z_HS]
bind sat = Z[Z_SAT]
bind en = Z[Z_ENERGY]
bind D = Z[Z_D]
bind hst = D[D_HS]
bind x0 = W * 0.22
bind xph = W * 0.9
bind dx = (xph - x0) / (HS_N - 1.0)
bind sh = clamp((t - D[D_HT]) / 0.5, 0.0, 1.0) * dx
bind amp = H * 0.05
bind ts = H * 0.075
bind c = 0
while c < 7 {
bind y = H * 0.15 + c * H * 0.118
bind e = en[c]
bind yb = y + amp
bind ser = hst[ids[c]]
col(c, sat * 0.6, 14.0, hs)
draw_line(x0, yb, xph, yb)
draw_line(x0, yb - amp * 2.0, xph, yb - amp * 2.0)
bind k = 0
bind ox = x0 - sh
bind oy = yb - ser[0] * amp * 2.0
while k < HS_N - 1 {
bind nx = x0 + (k + 1) * dx - sh
bind ny = yb - ser[k + 1] * amp * 2.0
if ox >= x0 - 0.5 {
col(c, sat * 0.8, 20.0 + 18.0 * ser[k + 1], hs)
draw_line(nx, yb, nx, ny)
col(c, sat, 44.0 + 36.0 * e, hs)
draw_line(ox, oy, nx, ny)
}
bind ox = nx
bind oy = ny
bind k = k + 1
}
col(c, sat, 60.0 + 30.0 * e, hs)
draw_line(ox, oy, xph, oy)
tile(str_slice(letters, c, 1), W * 0.02, y - ts * 0.5, ts, 40.0 + 40.0 * e, c, sat, hs, 0.3 + e)
col(c, sat, 68.0 + 20.0 * e, hs)
daemon_text(titles[c], W * 0.02 + ts + 12.0, y - ts * 0.14, ts * 0.3)
ink(62.0)
daemon_text(vals[c], W * 0.02 + ts + 12.0, y + ts * 0.3, ts * 0.3)
bind c = c + 1
}
ink(70.0)
draw_line(xph, H * 0.04, xph, H * 0.97)
draw_line(xph + 6.0, H * 0.04, xph + 6.0, H * 0.97)
bind hist = Z[Z_HIST]
bind i = 0
while i < len(hist) {
bind age = t - hist[i + 2]
bind x = xph - age * dx * 2.0
bind c = hist[i + 1]
if c < 7 {
if x > x0 {
bind y = H * 0.15 + c * H * 0.118
bind r = H * 0.009 + H * 0.012 * hist[i + 3]
bind lit = 78.0 - age * 4.0
if age < 0.4 { bind lit = 96.0 }
col(c, sat, lit, hs)
if hist[i] == 0 {
draw_circle(x, y, r)
if age < 0.9 { draw_circle(x, y, r * (1.0 + age * 3.0)) }
} else {
square(x, y, r, age * 0.4)
if age < 0.9 { square(x, y, r * (1.0 + age * 2.0), age * 2.0) }
}
}
}
bind i = i + 4
}
}
# the last n samples of a strip in a w x h box with its top-left at (x, y)
fn spark(x, y, w, h, ser, n, k, sat, lit, hs) {
bind s0 = len(ser) - n
bind dx = w / (n - 1.0)
col(k, sat * 0.6, 18.0, hs)
draw_line(x, y + h, x + w, y + h)
bind i = 0
while i < n - 1 {
bind a = ser[s0 + i]
bind b = ser[s0 + i + 1]
col(k, sat * 0.8, 22.0 + 14.0 * b, hs)
draw_line(x + (i + 1) * dx, y + h, x + (i + 1) * dx, y + h - b * h)
col(k, sat, lit, hs)
draw_line(x + i * dx, y + h - a * h, x + (i + 1) * dx, y + h - b * h)
bind i = i + 1
}
}
# a hatched bar: rail, then diagonal strokes for the filled part
fn hbar(x, y, w, frac, k, sat, lit, hs) {
col(k, sat * 0.8, 38.0, hs)
draw_line(x, y, x + w, y)
draw_line(x, y - 6.0, x, y)
draw_line(x + w, y - 6.0, x + w, y)
bind fw = w * clamp(frac, 0.0, 1.0)
col(k, sat, lit, hs)
bind u = 0.0
while u < fw {
draw_line(x + u, y, x + u + 4.0, y - 6.0)
bind u = u + 3.0
}
}
fn bline(x0, y0, S, u0, v0, u1, v1) {
draw_line(x0 + u0 * S, y0 + v0 * S, x0 + u1 * S, y0 + v1 * S)
}
# an axis-aligned rectangle in board units
fn brect(x0, y0, S, u0, v0, u1, v1) {
bline(x0, y0, S, u0, v0, u1, v0)
bline(x0, y0, S, u1, v0, u1, v1)
bline(x0, y0, S, u1, v1, u0, v1)
bline(x0, y0, S, u0, v1, u0, v0)
}
# diagonal hatch inside a board-unit rectangle; spacing in pixels
fn bhatch(x0, y0, S, u0, v0, u1, v1, sp) {
bind w = (u1 - u0) * S
bind h = (v1 - v0) * S
bind xa = x0 + u0 * S
bind ya = y0 + v0 * S
bind d = sp
while d < w + h {
bind ax = xa
bind ay = ya + d
if d > h {
bind ax = xa + d - h
bind ay = ya + h
}
bind bx = xa + d
bind by = ya
if d > w {
bind bx = xa + w
bind by = ya + d - w
}
draw_line(ax, ay, bx, by)
bind d = d + sp
}
}
# ───────────────────────────── alerts ────────────────────────────────────────
# When the machine "sounds" irregular, an alarm plays whatever section you are in, and a banner names it.
# Absolute limits (memory nearly full, GPU hot or out of VRAM, hot CPU zone, a sampler gone stale,
# heavy retransmits) and sudden jumps against a slow running average (CPU load, GPU load, gateway latency).
# Each kind can fire at most once every 25 s.
bind AL_TEXT = ["MEMORY NEARLY FULL", "GPU RUNNING HOT", "GPU MEMORY FULL", "CPU ZONE HOT", "SAMPLER STALE", "GPU LOAD SPIKE", "CPU LOAD SPIKE", "LATENCY SPIKE", "PACKET RETRANSMITS"]
bind AL_SEC = [1, 2, 2, 3, 0, 2, 3, 4, 4]
bind AL_COOL = 25.0
# m = [cpu, gpu, net] as 0..1, base = their running averages plus the gateway latency average
# returns the alert number (an index into AL_TEXT) or -1
fn alert_check(m, base, bvS, gpv, lives, usedM, nvS) {
if usedM >= 0.93 { return 0 }
bind g = 0
while g < len(gpv) {
bind v = gpv[g]
if v[GV_THT] > 0.5 { return 1 }
if v[GV_TEMP] >= 88.0 { return 1 }
if v[GV_VUSED] >= 0.97 * max(v[GV_VTOTAL], 1.0) {
if v[GV_VTOTAL] > 0.0 { return 2 }
}
bind g = g + 1
}
if bvS[BV_TEMP] >= 85.0 { return 3 }
bind i = 0
while i < 4 {
if lives[i] == 2 { return 4 }
bind i = i + 1
}
if m[1] - base[1] > 0.5 { return 5 }
if m[0] - base[0] > 0.5 { return 6 }
if nvS[NV_RTT] > 0.0 {
if base[3] > 0.0 {
if nvS[NV_RTT] > 3.0 * base[3] + 150.0 { return 7 }
}
}
if lg(nvS[NV_RETX], 3.0) > 0.85 { return 8 }
return 0 - 1
}
# one beep of an alarm; left counts down. Serious alerts (0-4) are a square wave and higher.
fn alert_beep(code, left) {
bind f = 700.0
bind wave = "tri"
if left % 2 == 0 { bind f = 520.0 }
if code <= 4 {
bind wave = "square"
bind f = 1200.0
if left % 2 == 0 { bind f = 900.0 }
}
audio_sfx(0.0, 0.0, 6.0, 1.0, f, 0.12, 0.16, wave)
}
# the banner, top centre, flashing for 8 s: Z[Z_ALERT] = [text, born, section]
fn alert_banner(Z) {
bind a = Z[Z_ALERT]
bind age = Z[Z_T] - a[1]
if age < 8.0 {
if str_len(a[0]) > 0 {
bind W = Z[Z_W]
bind blink = 0.0
if floor(age * 3.0) % 2 == 0 { bind blink = 1.0 }
bind msg = "! " + a[0]
bind h = 16.0
bind w = text_w(msg, h) + 36.0
bind x = (W - w) / 2.0
col(0, 90.0, 50.0 + 30.0 * blink, 0.0)
brect(x, 10.0, 1.0, 0.0, 0.0, w, 34.0)
brect(x + 3.0, 13.0, 1.0, 0.0, 0.0, w - 6.0, 28.0)
col(0, 90.0, 66.0 + 28.0 * blink, 0.0)
daemon_text(msg, x + 18.0, 27.0, h)
}
}
}
# ───────────────────────────── MINI ──────────────────────────────────────────
# A small build for a liquid-cooler LCD (or any small screen): four rings (memory, GPU, CPU, network)
# and four stat rows, nothing else. No menu, no sound. Same samplers, same design system.
# ling run --interp hatchmini.ling [WxH] [sim] [shot] e.g. 320x240, 240x320, 480x480
# Landscape (W >= H): rings on the left, rows down the right. Portrait: rings on top, rows in a 2 x 2 grid.
bind MINI_HM = [4, 3, 1, 6]
bind MINI_LET = "MGCN"
# [cx, cy, R, xs, ys, row w, row h]
fn mini_layout(W, H) {
if W >= H {
bind R = min(H * 0.5 - 6.0, W * 0.36)
bind cx = R + 6.0
bind x0 = cx + R + 10.0
bind rh = (H - 12.0) / 4.0
return [cx, H / 2.0, R, [x0, x0, x0, x0], [6.0, 6.0 + rh, 6.0 + 2.0 * rh, 6.0 + 3.0 * rh], W - x0 - 6.0, rh]
}
bind R = W * 0.5 - 6.0
bind cw = (W - 18.0) / 2.0
bind y1 = 2.0 * R + 18.0
bind rh = (H - y1 - 6.0) / 2.0
return [W / 2.0, R + 6.0, R, [6.0, 12.0 + cw, 6.0, 12.0 + cw], [y1, y1, y1 + rh, y1 + rh], cw, rh]
}
fn mini_row(i, x, y, w, h, val, sub, frac, k, sat, hs, e) {
bind ts = min(h * 0.46, w * 0.34)
tile(str_slice(MINI_LET, i, 1), x, y + h * 0.06, ts, 56.0 + 24.0 * e, k, sat, hs, 0.4 + e)
bind tw = w - ts - 6.0
bind vh = fit_h(val, tw, h * 0.32)
col(k, sat, 84.0, hs)
daemon_text(val, x + ts + 6.0, y + h * 0.06 + vh * 0.55, vh)
bind sh = fit_h(sub, tw, h * 0.17)
ink(60.0)
daemon_text(sub, x + ts + 6.0, y + h * 0.06 + vh * 1.4 + sh * 0.5, sh)
hbar(x, y + h * 0.82, w - 2.0, frac, k, sat, 58.0 + 22.0 * e, hs)
}
bind start = do {
bind args = get_args()
bind forceSim = 0
bind shot = 0
bind W = 320
bind H = 240
bind ai = 0
while ai < len(args) {
bind a = args[ai]
if a == "sim" { bind forceSim = 1 }
if a == "shot" { bind shot = 1 }
bind pr = split(a, "x")
if len(pr) == 2 {
if to_number(pr[0]) > 0 {
if to_number(pr[1]) > 0 {
bind W = floor(to_number(pr[0]))
bind H = floor(to_number(pr[1]))
}
}
}
bind ai = ai + 1
}
open_window(W, H, "LingSys Mini")
bind W = get_width()
bind H = get_height()
set_blend(1)
set_frame_blur(0.45)
bind lay = mini_layout(W, H)
bind t0 = time_now()
bind tprev = 0.0
bind lastRead = 0.0 - 10.0
bind shotN = 0
bind liveM = 0
bind liveG = 0
bind liveB = 0
bind liveN = 0
bind tsM = 0.0
bind tsG = 0.0
bind tsB = 0.0
bind tsN = 0.0
bind chgM = 0.0
bind chgG = 0.0
bind chgB = 0.0
bind chgN = 0.0
bind cats = sim_cats(0.0)
bind tgtCats = cats
bind total = 16384.0
bind rates = [0.0, 0.0, 0.0, 0.0]
bind tgtRates = rates
bind tgtGP = sim_gpu(0.0)
bind gpv = tgtGP[GP_VEC]
bind tgtBP = sim_board(0.0)
bind bvS = tgtBP[BP_BV]
bind tgtNP = sim_net(0.0)
bind nvS = tgtNP[NP_NV]
bind energy = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
bind rot = 0.0
bind act = 0.0
bind hueShift = 0.0
bind alBase = [0.0, 0.0, 0.0, 0.0]
bind alLast = [0.0 - 100.0, 0.0 - 100.0, 0.0 - 100.0, 0.0 - 100.0, 0.0 - 100.0, 0.0 - 100.0, 0.0 - 100.0, 0.0 - 100.0, 0.0 - 100.0]
bind alText = ""
bind alBorn = 0.0 - 100.0
while window_is_open() {
bind t = time_now() - t0
bind dt = clamp(t - tprev, 0.001, 0.1)
bind tprev = t
if key_pressed("escape") { close_window() }
if key_pressed("q") { close_window() }
if shot == 1 {
bind shotN = shotN + 1
if shotN == 240 {
screenshot("hatchmini_" + num_str(W) + "x" + num_str(H))
close_window()
}
}
# ---- data, about twice a second (same snapshots as the full program)
if t - lastRead > 0.5 {
bind lastRead = t
bind liveM = 0
bind liveG = 0
bind liveB = 0
bind liveN = 0
if forceSim == 0 {
if file_exists("mem.snap") {
bind snap = parse_snap(read_file("mem.snap"))
if snap[0] == 1 {
bind liveM = 1
bind g = snap[1]
bind r = snap[2]
bind total = g[0]
bind tgtCats = categories(g, snap[3])
bind tgtRates = [r[0], r[1] + r[3], r[2] + r[4] + r[7], r[5]]
if snap[9] != tsM {
bind tsM = snap[9]
bind chgM = t
}
if t - chgM > 8.0 { bind liveM = 2 }
}
}
if file_exists("gpu.snap") {
bind gn = parse_gpu(read_file("gpu.snap"))
if gn[0] == 1 {
bind tgtGP = gn
bind liveG = 1
if gn[8] != tsG {
bind tsG = gn[8]
bind chgG = t
}
if t - chgG > 8.0 { bind liveG = 2 }
}
}
if file_exists("board.snap") {
bind bn = parse_board(read_file("board.snap"))
if bn[0] == 1 {
bind tgtBP = bn
bind liveB = 1
if bn[9] != tsB {
bind tsB = bn[9]
bind chgB = t
}
if t - chgB > 8.0 { bind liveB = 2 }
}
}
if file_exists("net.snap") {
bind nn = parse_net(read_file("net.snap"))
if nn[0] == 1 {
bind tgtNP = nn
bind liveN = 1
if nn[5] != tsN {
bind tsN = nn[5]
bind chgN = t
}
if t - chgN > 8.0 { bind liveN = 2 }
}
}
}
if liveM == 0 {
bind total = 16384.0
bind tgtCats = sim_cats(t)
bind sr = sim_rates(t)
bind tgtRates = [sr[0], sr[1], sr[2], sr[0] * 0.2]
}
if liveG == 0 { bind tgtGP = sim_gpu(t) }
if liveB == 0 { bind tgtBP = sim_board(t) }
if liveN == 0 { bind tgtNP = sim_net(t) }
}
bind k = clamp(dt * 2.5, 0.0, 1.0)
bind cats = glide(cats, tgtCats, k)
bind rates = glide(rates, tgtRates, clamp(dt * 3.0, 0.0, 1.0))
bind gpv = glide_ll(gpv, tgtGP[GP_VEC], k)
bind bvS = glide(bvS, tgtBP[BP_BV], k)
bind nvS = glide(nvS, tgtNP[NP_NV], k)
# ---- the four numbers
bind usedM = clamp(1.0 - (cats[6] + cats[1]) / total, 0.0, 1.0)
bind gm = 0.0
bind gt = 0.0
bind gvu = 0.0
bind g = 0
while g < len(gpv) {
bind gm = max(gm, gpv[g][GV_UTIL])
bind gt = max(gt, gpv[g][GV_TEMP])
bind gvu = max(gvu, gpv[g][GV_VUSED] / max(gpv[g][GV_VTOTAL], 1.0))
bind g = g + 1
}
bind cpu = bvS[BV_UTIL]
bind netA = lg(nvS[NV_RX] + nvS[NV_TX], 9.0)
bind tmax = max(gt, bvS[BV_TEMP])
bind fr = [usedM, gm / 100.0, cpu / 100.0, netA, gvu, bvS[BV_DBUSY] / 100.0, clamp((tmax - 20.0) / 60.0, 0.0, 1.0)]
bind ne = []
bind i = 0
while i < 7 {
bind ne = list_push(ne, mix(energy[i], fr[i], clamp(dt * 3.0, 0.0, 1.0)))
bind i = i + 1
}
bind energy = ne
# ---- alerts: the same checks as the full program, shown as a banner (the display has no speaker)
bind alM = [cpu / 100.0, gm / 100.0, netA]
bind lives = [liveM, liveG, liveB, liveN]
if t > 12.0 {
bind code = alert_check(alM, alBase, bvS, gpv, lives, usedM, nvS)
if code >= 0 {
if t - alLast[code] > AL_COOL {
bind alLast = list_set(alLast, code, t)
bind alText = AL_TEXT[code]
bind alBorn = t
}
}
}
bind ar = clamp(dt * 0.15, 0.0, 1.0)
bind alBase = [mix(alBase[0], alM[0], ar), mix(alBase[1], alM[1], ar), mix(alBase[2], alM[2], ar), alBase[3]]
if nvS[NV_RTT] > 0.0 {
if alBase[3] <= 0.0 {
bind alBase = list_set(alBase, 3, nvS[NV_RTT])
} else {
bind alBase = list_set(alBase, 3, mix(alBase[3], nvS[NV_RTT], ar))
}
}
# ---- look
bind act = (usedM + cpu / 100.0 + gm / 100.0) / 3.0
bind rot = rot + dt * (0.06 + 0.9 * act)
bind hueShift = 10.0 * sin(t * 0.05)
bind sat = 52.0 + 40.0 * act
bind Z = [t, rot, hueShift, sat, W, H, [], 1.0, act, 0, 0, 0, [], [], [], [], [], [], [], act, energy, [], 1, H, [], "", 0, 0, 0, 0, fr, [], [alText, alBorn, 0]]
fill(0, 0, 0)
bind labels = ["MEMORY " + pct(usedM * 100.0) + " ", "GPU " + pct(gm) + " ", "CPU " + pct(cpu) + " ", "NET " + fmt_bytes(nvS[NV_RX] + nvS[NV_TX]) + " "]
ring_stack_at(Z, lay[0], lay[1], lay[2], 4, MINI_HM, labels, fr, pct(tmax) + "C", "HEAT", 1)
bind rs = "---"
if nvS[NV_RTT] > 0.0 { bind rs = num_str(round(nvS[NV_RTT])) + "MS" }
bind vals = [pct(usedM * 100.0) + "%", pct(gm) + "%", pct(cpu) + "%", fmt_bytes(nvS[NV_RX] + nvS[NV_TX])]
bind subs = [fmt_mb(usedM * total) + " OF " + fmt_mb(total), pct(gt) + "C " + fmt_mb(gvu * gpv[0][GV_VTOTAL]) + " V", num_str(round(bvS[BV_MHZ] / 100.0) / 10.0) + " GHZ", "PER S " + rs]
bind xs = lay[3]
bind ys = lay[4]
bind q = 0
while q < 4 {
mini_row(q, xs[q], ys[q], lay[5], lay[6], vals[q], subs[q], fr[q], MINI_HM[q], sat, hueShift, energy[q])
bind q = q + 1
}
alert_banner(Z)
present()
}
}