code wiki / _hdl_build / nx_library_page.nx
nx_library_page.nx source
↩ module page · 95 lines · 5506 B
1// nx_library_page.nx -- MLIB-007 (CALLOUT-012). The ENDPOINT: emit the nishi-library UI via the
2// PROVEN nx_web_builder (responsive CSS baked in -> the browser-exceeds-desktop / responsive
3// desktop+TV+mobile surface). v1: ONE unified mixed-media grid (auto-fit responsive grid) over
4// ALL pillars (video/photos+gifs/audio/books+manga/3D-STL/games) + search + trust signals; UX
5// gated by wb_ux_compliant. Writes knowledge/nishi-library.html, then READS IT BACK and asserts
6// the markers (no blind emit, rule 5). Live playback / GPU decode / cast / scrub-latency ride the
7// browser RUNTIME = the next slice (MLIB-008). Self-validating gate (LIBPAGEGATE). license_tier: ORIGINAL
8import "nx_syscalls.nx"
9import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
10import "nx_web_builder.nx"
11const LP_MAGIC_60000: i64 = 60000
12
13const LP_OUT: *u8 = "knowledge/nishi-library.html"
14
15func lp_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
16// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
17// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
18// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
19// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
20func lp_putn(v: i64) -> i64 { nxi_out(v); return 0 }
21
22func lp_readfile(path: *u8, buf: *u8, cap: i64) -> i64 {
23 let fd: i64 = sys_openat_rd(path)
24 if fd < 0 { return 0 - 1 }
25 var tot: i64 = 0
26 var r: i64 = 1
27 while r > 0 { let dst: *u8 = ((buf as i64) + tot) as *u8; r = sys_read(fd, dst, cap - tot); if r > 0 { tot = tot + r } }
28 sys_close(fd)
29 return tot
30}
31func lp_contains(buf: *u8, n: i64, needle: *u8) -> i64 {
32 var m: i64 = 0; while needle[m] != (0 as u8) { m = m + 1 }
33 if m == 0 { return 0 }
34 var i: i64 = 0
35 while i + m <= n { var j: i64 = 0; var ok: i64 = 1; while j < m { if buf[i + j] != needle[j] { ok = 0; j = m } else { j = j + 1 } } if ok == 1 { return 1 } i = i + 1 }
36 return 0
37}
38
39func main() -> i64 {
40 let fd: i64 = sys_openat_wr(LP_OUT, 420)
41 if fd < 0 { lp_puts("LIBPAGEGATE verdict=RED reason=out-unwritable\n" as *u8); return 1 }
42
43 wb_doc_open(fd, "Nishi Library" as *u8)
44 wb_header(fd, "Nishi Library" as *u8, "Add source" as *u8, "#sources" as *u8)
45 wb_hero(fd, "Every kind of media. One library." as *u8, "Find what you want fast. Remove what you do not, faster." as *u8, "Browse all" as *u8, "#all" as *u8)
46 wb_search(fd, "/library/search" as *u8, "Search video, photos, gifs, audio, books, manga, 3D/STL, games..." as *u8)
47 wb_cards_open(fd, "All media -- one view" as *u8)
48 wb_card(fd, "Video & TV" as *u8, "transcode + cast + chapter-scrub + resume. Jellyfin/Plex/Emby class." as *u8)
49 wb_card(fd, "Photos & GIFs" as *u8, "perceptual dedup + face/EXIF/timeline + bulk keyboard triage. Hydrus/immich class." as *u8)
50 wb_card(fd, "Audio" as *u8, "lossless gapless + smart playlists + fingerprint dedup. Navidrome/Plexamp class." as *u8)
51 wb_card(fd, "Books & Manga" as *u8, "EPUB/PDF/CBZ reader + TOC fulltext search + reader modes. Calibre/Komga class." as *u8)
52 wb_card(fd, "3D / STL" as *u8, "mesh viewer + dims + printability check. No incumbent has a local library -- exceed lane." as *u8)
53 wb_card(fd, "Games" as *u8, "unified launcher + emulation + DRM-free ingest + save-state. Playnite/LaunchBox class." as *u8)
54 wb_cards_close(fd)
55 let trust: *i64 = sys_mmap(8 * 4) as *i64
56 trust[0] = ("DRM-free -- your own purchases, never circumvention" as *u8) as i64
57 trust[1] = ("Sovereign -- runs on your hardware, content-addressed" as *u8) as i64
58 trust[2] = ("Nothing deleted -- soft-delete only, provenance tracked" as *u8) as i64
59 wb_trust(fd, trust, 3)
60 wb_footer(fd, "Nishi Library -- one uniform record for every medium; find-fast, remove-fast, provenance on every item." as *u8)
61 wb_doc_close(fd)
62 sys_close(fd)
63
64 let ux: i64 = wb_ux_compliant(1, 1, 1, 3)
65
66 let buf: *u8 = sys_mmap(LP_MAGIC_60000)
67 let n: i64 = lp_readfile(LP_OUT, buf, LP_MAGIC_60000)
68 let has_brand: i64 = lp_contains(buf, n, "Nishi Library" as *u8)
69 let has_stl: i64 = lp_contains(buf, n, "3D / STL" as *u8)
70 let has_games: i64 = lp_contains(buf, n, "Games" as *u8)
71 let has_search: i64 = lp_contains(buf, n, "Search video" as *u8)
72 let resp_vp: i64 = lp_contains(buf, n, "viewport" as *u8)
73 let resp_md: i64 = lp_contains(buf, n, "@media" as *u8)
74 let resp_grid: i64 = lp_contains(buf, n, "auto-fit" as *u8)
75
76 lp_puts("LIBPAGEGATE bytes=" as *u8); lp_putn(n)
77 lp_puts(" ux_compliant=" as *u8); lp_putn(ux)
78 lp_puts(" brand=" as *u8); lp_putn(has_brand); lp_puts(" stl_card=" as *u8); lp_putn(has_stl); lp_puts(" games_card=" as *u8); lp_putn(has_games)
79 lp_puts(" search=" as *u8); lp_putn(has_search)
80 lp_puts(" responsive[viewport=" as *u8); lp_putn(resp_vp); lp_puts(" media=" as *u8); lp_putn(resp_md); lp_puts(" grid=" as *u8); lp_putn(resp_grid); lp_puts("]" as *u8)
81
82 var ok: i64 = 1
83 if n <= 0 { ok = 0 }
84 if ux != 1 { ok = 0 }
85 if has_brand != 1 { ok = 0 }
86 if has_stl != 1 { ok = 0 }
87 if has_games != 1 { ok = 0 }
88 if has_search != 1 { ok = 0 }
89 if resp_vp != 1 { ok = 0 }
90 if resp_md != 1 { ok = 0 }
91 if resp_grid != 1 { ok = 0 }
92 if ok == 1 { lp_puts(" verdict=GREEN\n" as *u8); return 0 }
93 lp_puts(" verdict=RED\n" as *u8)
94 return 1
95}