From eecfbcdf8a63d5a825f870cf695816ea41d34777 Mon Sep 17 00:00:00 2001 From: ruv Date: Sun, 26 Apr 2026 21:10:55 -0400 Subject: [PATCH] deploy(nvsim): wire all rail buttons + Ghost Murmur view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inspector and Witness rail buttons now switch the inspector tab; Ghost Murmur button opens a new research view summarising the publicly- reported April 2026 CIA program and RuView's 3-tier mesh equivalent. Verified end-to-end with agent-browser. ADR-092 §14b. --- nvsim/assets/index-BWlL4FHH.js | 1733 ++++++++++++++++++++++++++++ nvsim/assets/index-BWlL4FHH.js.map | 1 + nvsim/index.html | 2 +- nvsim/sw.js | 2 +- nvsim/sw.js.map | 2 +- 5 files changed, 1737 insertions(+), 3 deletions(-) create mode 100644 nvsim/assets/index-BWlL4FHH.js create mode 100644 nvsim/assets/index-BWlL4FHH.js.map diff --git a/nvsim/assets/index-BWlL4FHH.js b/nvsim/assets/index-BWlL4FHH.js new file mode 100644 index 00000000..c4b6cd43 --- /dev/null +++ b/nvsim/assets/index-BWlL4FHH.js @@ -0,0 +1,1733 @@ +import{f as Ye,u as Xe,i as m,a as b,b as c,w as V}from"./lit-BS7WqYd5.js";import{y as o,g as Qe,j as y}from"./signals-SG45zFCj.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))r(a);new MutationObserver(a=>{for(const i of a)if(i.type==="childList")for(const n of i.addedNodes)n.tagName==="LINK"&&n.rel==="modulepreload"&&r(n)}).observe(document,{childList:!0,subtree:!0});function s(a){const i={};return a.integrity&&(i.integrity=a.integrity),a.referrerPolicy&&(i.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?i.credentials="include":a.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function r(a){if(a.ep)return;a.ep=!0;const i=s(a);fetch(a.href,i)}})();/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */const h=e=>(t,s)=>{s!==void 0?s.addInitializer(()=>{customElements.define(e,t)}):customElements.define(e,t)};/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */const Je={attribute:!0,type:String,converter:Xe,reflect:!1,hasChanged:Ye},Ze=(e=Je,t,s)=>{const{kind:r,metadata:a}=s;let i=globalThis.litPropertyMetadata.get(a);if(i===void 0&&globalThis.litPropertyMetadata.set(a,i=new Map),r==="setter"&&((e=Object.create(e)).wrapped=!0),i.set(s.name,e),r==="accessor"){const{name:n}=s;return{set(d){const p=t.get.call(this);t.set.call(this,d),this.requestUpdate(n,p,e,!0,d)},init(d){return d!==void 0&&this.C(n,void 0,e,d),d}}}if(r==="setter"){const{name:n}=s;return function(d){const p=this[n];t.call(this,d),this.requestUpdate(n,p,e,!0,d)}}throw Error("Unsupported decorator location: "+r)};function Ae(e){return(t,s)=>typeof s=="object"?Ze(e,t,s):((r,a,i)=>{const n=a.hasOwnProperty(i);return a.constructor.createProperty(i,r),n?Object.getOwnPropertyDescriptor(a,i):void 0})(e,t,s)}/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */function u(e){return Ae({...e,state:!0,attribute:!1})}/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */const et=(e,t,s)=>(s.configurable=!0,s.enumerable=!0,Reflect.decorate&&typeof t!="object"&&Object.defineProperty(e,t,s),s);/** + * @license + * Copyright 2017 Google LLC + * SPDX-License-Identifier: BSD-3-Clause + */function He(e,t){return(s,r,a)=>{const i=n=>n.renderRoot?.querySelector(e)??null;return et(s,r,{get(){return i(this)}})}}var tt=Object.defineProperty,at=Object.getOwnPropertyDescriptor,Le=(e,t,s,r)=>{for(var a=r>1?void 0:r?at(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=(r?n(t,s,a):n(a))||a);return r&&a&&tt(t,s,a),a};let ne=class extends b{constructor(){super(...arguments),this.view="scene"}navigate(e){this.dispatchEvent(new CustomEvent("navigate",{detail:e}))}render(){return c` + + + + + + +
+ + `}};ne.styles=m` + :host { + display: flex; + flex-direction: column; + align-items: center; + padding: 10px 0; + gap: 4px; + background: var(--bg-1); + border-right: 1px solid var(--line); + } + .logo { + width: 36px; height: 36px; + border-radius: 10px; + background: linear-gradient(135deg, oklch(0.78 0.14 70) 0%, oklch(0.55 0.16 30) 100%); + display: grid; place-items: center; + color: #1a0f00; + font-weight: 700; + font-family: var(--mono); + font-size: 11px; + margin-bottom: 14px; + box-shadow: 0 4px 12px -2px oklch(0.55 0.16 30 / 0.35); + } + .btn { + width: 36px; height: 36px; + border-radius: 8px; + background: transparent; + border: 1px solid transparent; + color: var(--ink-3); + display: grid; place-items: center; + transition: all 0.15s; + position: relative; + cursor: pointer; + } + .btn:hover { color: var(--ink); background: var(--bg-2); } + .btn.active { + color: var(--ink); + background: var(--bg-3); + border-color: var(--line-2); + } + .btn.active::before { + content: ''; position: absolute; left: -10px; top: 8px; bottom: 8px; + width: 2px; background: var(--accent); border-radius: 2px; + } + .btn.ghost.active::before { background: var(--accent-3); } + .spacer { flex: 1; } + svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; } + `;Le([Ae()],ne.prototype,"view",2);ne=Le([h("nv-rail")],ne);const S=o("wasm"),xe=o("");o(!1);o(null);const v=o(!1);o(!0);o(1);const st=o(0),$e=o(0n),U=o(0xCAFEBABEn),Z=o(1e4),ee=o(1e3),te=o(1),ae=o(!0),g=o("dark"),w=o("default"),$=o(!1),se=o(!0),oe=o([0,0,0]),O=o(0),E=o(0),k=o(0),C=o(""),f=o("idle"),D=o(""),Se=o(null),le=o([]),ce=o([]),de=o([]),pe=o([]),Re=o("rebar-walkby-01"),rt=o(""),W=o(!1),we=o("all"),Ee=Qe(()=>S.value==="wasm"?"wasm":"ws");let Fe=null;function it(e){Fe=e}function P(){return Fe}const _=o([]),nt=200;function l(e,t){if(W.value)return;const s=_.value.slice();for(s.push({ts:Date.now(),level:e,msg:t});s.length>nt;)s.shift();_.value=s}function ot(e){const s=le.value.slice();s.push(e[0]),s.length>200&&s.shift();const r=ce.value.slice();r.push(e[1]),r.length>200&&r.shift();const a=de.value.slice();a.push(e[2]),a.length>200&&a.shift(),le.value=s,ce.value=r,de.value=a}function lt(e){const s=pe.value.slice();for(s.push(Math.max(0,Math.min(1,e)));s.length>48;)s.shift();pe.value=s}var ct=Object.getOwnPropertyDescriptor,dt=(e,t,s,r)=>{for(var a=r>1?void 0:r?ct(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=n(a)||a);return a};let _e=class extends b{connectedCallback(){super.connectedCallback(),y(()=>{k.value,Ee.value,U.value,g.value,Re.value,v.value,this.requestUpdate()})}async toggleRun(){const e=P();e&&(v.value?(await e.pause(),v.value=!1):(await e.run(),v.value=!0))}async reset(){const e=P();e&&await e.reset()}toggleTheme(){g.value=g.value==="dark"?"light":"dark"}render(){const e=U.value.toString(16).toUpperCase().padStart(8,"0");return c` +
+ RuView/ + nvsim/ + ${Re.value} +
+
+ + + ${k.value>0?(k.value/1e3).toFixed(2)+" kHz":"idle"} + + ${Ee.value} + seed: 0x${e} + + + + `}};_e.styles=m` + :host { + display: flex; align-items: center; + padding: 0 16px; gap: 12px; + background: var(--bg-1); + border-bottom: 1px solid var(--line); + z-index: 10; + } + .crumbs { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ink-3); } + .crumbs .sep { color: var(--ink-4); } + .crumbs .cur { color: var(--ink); font-weight: 500; } + .spacer { flex: 1; } + .pill { + display: inline-flex; align-items: center; gap: 6px; + padding: 5px 10px; + background: var(--bg-2); border: 1px solid var(--line); + border-radius: 999px; + font-size: 12px; color: var(--ink-2); + font-family: var(--mono); font-weight: 500; + } + .pill .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 6px var(--ok); animation: pulse 2s infinite; } + .pill.wasm .dot { background: var(--accent-2); box-shadow: 0 0 6px var(--accent-2); } + .pill.seed { color: var(--ink-3); } + .pill.seed b { color: var(--accent); font-weight: 600; } + button { + display: inline-flex; align-items: center; gap: 6px; + padding: 6px 12px; + background: var(--bg-2); border: 1px solid var(--line); + border-radius: 8px; + font-size: 12.5px; font-weight: 500; color: var(--ink); + cursor: pointer; + transition: all 0.15s; + } + button:hover { border-color: var(--line-2); background: var(--bg-3); } + button.primary { background: var(--accent); border-color: var(--accent); color: #1a0f00; } + button.primary:hover { filter: brightness(1.08); } + button.ghost { background: transparent; } + `;_e=dt([h("nv-topbar")],_e);var pt=Object.getOwnPropertyDescriptor,ut=(e,t,s,r)=>{for(var a=r>1?void 0:r?pt(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=n(a)||a);return a};let Ce=class extends b{connectedCallback(){super.connectedCallback(),y(()=>{Z.value,ee.value,te.value,ae.value,v.value,this.requestUpdate()})}render(){return c` +
+
Scene 4 sources
+
+ + rebar.steel.coil + χ=5000 +
+
+ + heart_proxy + 1e-6 A·m² +
+
+ + mains_60Hz + 2 A · 60 Hz +
+
+ + door.steel + eddy +
+
+ +
+
NV sensor COTS
+
V1 mm³
+
N1e12 NV
+
C0.030
+
T₂*200 ns
+
δB1.18 pT/√Hz
+
+ +
+
Tunables
+
+
Sample rate${(Z.value/1e3).toFixed(1)} kHz
+ Z.value=+e.target.value} /> +
+
+
Lockin f_mod${(ee.value/1e3).toFixed(3)} kHz
+ ee.value=+e.target.value} /> +
+
+
Integration t${te.value.toFixed(1)} ms
+ te.value=+e.target.value} /> +
+
+
Shot noise${ae.value?"ON":"OFF"}
+ ae.value=e.target.value==="1"} /> +
+
+ +
+
Pipeline
+
+ scene + + B-S + + prop + + NV + + ADC + + frame +
+
+ `}};Ce.styles=m` + :host { + display: flex; flex-direction: column; gap: 14px; + padding: 14px; overflow-y: auto; + background: var(--bg-1); border-right: 1px solid var(--line); + } + .panel { + background: var(--bg-2); border: 1px solid var(--line); + border-radius: var(--radius); padding: 12px; + } + .panel-h { + display: flex; align-items: center; justify-content: space-between; + font-size: 11px; font-weight: 600; color: var(--ink-3); + text-transform: uppercase; letter-spacing: 0.08em; + margin-bottom: 10px; + } + .count { + background: var(--bg-3); color: var(--ink-2); + padding: 1px 6px; border-radius: 999px; + font-family: var(--mono); font-size: 10px; + text-transform: none; letter-spacing: 0; + } + .scene-item { + display: flex; align-items: center; gap: 10px; + padding: 8px 10px; + border-radius: var(--radius-sm); + cursor: pointer; + transition: background 0.15s; + border: 1px solid transparent; + } + .scene-item:hover { background: var(--bg-3); } + .scene-item .swatch { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; } + .scene-item .name { font-size: 13px; flex: 1; } + .scene-item .meta { font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); } + .field-row { + display: flex; align-items: center; justify-content: space-between; + padding: 6px 0; font-size: 12.5px; + border-bottom: 1px solid var(--line); + } + .field-row:last-child { border-bottom: 0; } + .field-row .lbl { color: var(--ink-3); } + .field-row .val { font-family: var(--mono); color: var(--ink); font-size: 12px; } + .slider-row { padding: 8px 0; border-bottom: 1px solid var(--line); } + .slider-row:last-child { border-bottom: 0; padding-bottom: 0; } + .slider-row .top { display: flex; justify-content: space-between; margin-bottom: 6px; font-size: 12px; } + .slider-row .top .lbl { color: var(--ink-3); } + .slider-row .top .val { font-family: var(--mono); color: var(--ink); } + input[type="range"] { + -webkit-appearance: none; appearance: none; + width: 100%; height: 4px; + background: var(--bg-3); border-radius: 2px; outline: none; + } + input[type="range"]::-webkit-slider-thumb { + -webkit-appearance: none; appearance: none; + width: 14px; height: 14px; border-radius: 50%; + background: var(--accent); cursor: pointer; + border: 2px solid var(--bg-2); + box-shadow: 0 0 0 1px var(--line-2); + } + .pipeline { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; margin-top: 6px; } + .stage { + flex: 1; min-width: 50px; + padding: 4px 6px; + background: var(--bg-3); border: 1px solid var(--line); + border-radius: 6px; font-size: 9.5px; text-align: center; + color: var(--ink-2); font-family: var(--mono); + } + .stage.live { border-color: var(--accent-2); color: var(--accent-2); } + .stage-arrow { color: var(--ink-4); font-size: 10px; } + `;Ce=ut([h("nv-sidebar")],Ce);var vt=Object.defineProperty,gt=Object.getOwnPropertyDescriptor,be=(e,t,s,r)=>{for(var a=r>1?void 0:r?gt(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=(r?n(t,s,a):n(a))||a);return r&&a&&vt(t,s,a),a};let I=class extends b{constructor(){super(...arguments),this.items=[{id:"rebar",x:740,y:240,color:"oklch(0.72 0.18 330)",name:"rebar.steel"},{id:"heart",x:220,y:180,color:"oklch(0.78 0.14 195)",name:"heart_proxy"},{id:"mains",x:180,y:380,color:"oklch(0.72 0.18 330)",name:"mains_60Hz"},{id:"door",x:800,y:470,color:"oklch(0.78 0.14 145)",name:"door.steel"}],this.dragging=null,this.selected=null,this.dragOffset={dx:0,dy:0},this.onDown=(e,t)=>{t.preventDefault(),this.dragging=e,this.selected=e;const s=this.items.find(i=>i.id===e);if(!s)return;const r=this.renderRoot.querySelector("svg");if(!r)return;const a=this.toSvg(t,r);this.dragOffset={dx:a.x-s.x,dy:a.y-s.y}},this.onPointerMove=e=>{if(!this.dragging)return;const t=this.renderRoot.querySelector("svg");if(!t)return;const s=this.toSvg(e,t);this.items=this.items.map(r=>r.id===this.dragging?{...r,x:s.x-this.dragOffset.dx,y:s.y-this.dragOffset.dy}:r)},this.onPointerUp=()=>{this.dragging=null}}connectedCallback(){super.connectedCallback(),y(()=>{oe.value,O.value,k.value,E.value,$.value,this.requestUpdate()}),window.addEventListener("pointermove",this.onPointerMove),window.addEventListener("pointerup",this.onPointerUp)}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener("pointermove",this.onPointerMove),window.removeEventListener("pointerup",this.onPointerUp)}toSvg(e,t){const s=t.getBoundingClientRect(),r=(e.clientX-s.left)/s.width*1e3,a=(e.clientY-s.top)/s.height*600;return{x:r,y:a}}render(){const e=oe.value,t=[e[0]*1e9,e[1]*1e9,e[2]*1e9],s=O.value*1e9,r=$.value?"":"anim";return c` +
+ + + + + + + + + + + ${this.items.map(a=>V` + + `)} + + + ${this.items.map(a=>V` + this.onDown(a.id,i)}> + + + ${a.name} + + `)} + + + + + + + + + + sensor · 〈111〉 NV + + + B_in: [${t[0].toFixed(2)}, ${t[1].toFixed(2)}, ${t[2].toFixed(2)}] nT + + + + +
+
+
|B|
+
${s.toFixed(3)} nT
+
+
+
FPS
+
${k.value>0?Math.round(k.value):"—"}
+
+
+
SNR
+
${E.value>0?E.value.toFixed(1):"—"}
+
+
+ `}};I.styles=m` + :host { + display: block; height: 100%; width: 100%; + background: radial-gradient(ellipse at 50% 30%, var(--bg-2) 0%, var(--bg-0) 70%); + position: relative; overflow: hidden; + border-bottom: 1px solid var(--line); + } + .grid { + position: absolute; inset: 0; + background-image: + linear-gradient(var(--grid) 1px, transparent 1px), + linear-gradient(90deg, var(--grid) 1px, transparent 1px); + background-size: 32px 32px; + pointer-events: none; + mask-image: radial-gradient(ellipse at center, black 40%, transparent 100%); + } + svg { position: absolute; inset: 0; width: 100%; height: 100%; } + .stat-card { + background: rgba(13,17,23,0.7); + backdrop-filter: blur(8px); + border: 1px solid var(--line); + border-radius: var(--radius-sm); + padding: 8px 12px; + font-size: 11px; + min-width: 96px; + } + [data-theme="light"] .stat-card { background: rgba(255,255,255,0.85); } + .stat-card .lbl { + color: var(--ink-3); + text-transform: uppercase; font-weight: 600; letter-spacing: 0.06em; font-size: 9.5px; + } + .stat-card .val { font-family: var(--mono); font-size: 16px; font-weight: 600; margin-top: 2px; } + .stat-card .val.amber { color: var(--accent); } + .stat-card .val.cyan { color: var(--accent-2); } + .stat-card .val.mint { color: var(--accent-4); } + .scene-readout { + position: absolute; top: 14px; right: 14px; + display: flex; gap: 8px; z-index: 5; + } + .draggable { cursor: grab; transition: filter 0.15s; } + .draggable:hover { filter: brightness(1.15) drop-shadow(0 0 6px currentColor); } + .draggable.dragging { cursor: grabbing; filter: brightness(1.25) drop-shadow(0 0 10px currentColor); } + .field-line { stroke-dasharray: 4 6; } + @keyframes dash { to { stroke-dashoffset: -200; } } + .field-line.anim { animation: dash 4s linear infinite; } + @keyframes spin { + 0% { transform: rotateY(0) rotateX(8deg); } + 100% { transform: rotateY(360deg) rotateX(8deg); } + } + .crystal { transform-origin: center; transform-box: fill-box; } + .crystal.anim { animation: spin 12s linear infinite; } + .label { + font-family: var(--mono); font-size: 11px; fill: var(--ink-2); + pointer-events: none; + } + `;be([u()],I.prototype,"items",2);be([u()],I.prototype,"dragging",2);be([u()],I.prototype,"selected",2);I=be([h("nv-scene")],I);var mt=Object.defineProperty,bt=Object.getOwnPropertyDescriptor,Me=(e,t,s,r)=>{for(var a=r>1?void 0:r?bt(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=(r?n(t,s,a):n(a))||a);return r&&a&&mt(t,s,a),a};let K=class extends b{constructor(){super(...arguments),this.tab="signal",this.pinTab=null}connectedCallback(){super.connectedCallback(),y(()=>{le.value,ce.value,de.value,pe.value,Se.value,C.value,f.value,oe.value,O.value,this.requestUpdate()})}updated(e){e.has("pinTab")&&this.pinTab&&(this.tab=this.pinTab)}async verify(){const e=P();if(e){f.value="pending",l("info","verifying witness over 256 frames…");try{const t=D.value,s=new Uint8Array(32);for(let a=0;a<32;a++)s[a]=parseInt(t.slice(a*2,a*2+2),16);const r=await e.verifyWitness(s);if(r.ok)f.value="ok",C.value=t,l("ok",`witness ${t.slice(0,16)}… matches · determinism gate ✓`);else{f.value="fail";const a=Array.from(r.actual).map(i=>i.toString(16).padStart(2,"0")).join("");C.value=a,l("err",`WITNESS MISMATCH actual=${a.slice(0,16)}…`)}}catch(t){f.value="fail",l("err",`verify failed: ${t.message}`)}}}renderSignalTab(){const i=n=>{let d="";return n.forEach((p,R)=>{const fe=R/Math.max(1,199)*320,ye=65-p*22;d+=(R===0?"M":"L")+` ${fe.toFixed(1)} ${ye.toFixed(1)} `}),d};return c` +
+
+ B-vector trace + 3-axis · nT +
+ + + ${V``} + ${V``} + ${V``} + +
+ +
+
+ Frame stream + live +
+
+ ${pe.value.map(n=>c`
`)} +
+
+ `}renderFrameTab(){const e=Se.value,t=e?.raw;let s="";return t&&(s=Array.from(t).map(a=>a.toString(16).padStart(2,"0")).slice(0,60).join(" ")),c` +
+
+ MagFrame v1 fields + 60 B +
+ + + + + + + + + + + +
magic${e?"0x"+e.magic.toString(16).toUpperCase():"—"}
version${e?.version??"—"}
flags0x${(e?.flags??0).toString(16).padStart(4,"0")}
sensor_id${e?.sensorId??"—"}
t_us${e?e.tUs.toString():"—"}
b_pT[0]${e?e.bPt[0].toFixed(1):"—"}
b_pT[1]${e?e.bPt[1].toFixed(1):"—"}
b_pT[2]${e?e.bPt[2].toFixed(1):"—"}
noise_floor${e?e.noiseFloorPtSqrtHz.toFixed(2):"—"}
temp_K${e?e.temperatureK.toFixed(1):"—"}
+
+
+
+ Hex dump + LE +
+
${s||"—"}
+
+ `}renderWitnessTab(){const e=f.value,t=e==="ok"?"ok":e==="fail"?"fail":"",s=e==="pending"?"Verifying…":e==="ok"?"✓ Witness verified · determinism gate":e==="fail"?"✗ Witness mismatch · audit required":"Verify witness";return c` +
+
+ Expected (Proof::EXPECTED_WITNESS_HEX) + SHA-256 +
+
${D.value||"(loading…)"}
+
+
+
+ Actual (last verify) + SHA-256 +
+
${C.value||"(not verified yet)"}
+ +
+ `}render(){return c` +
+ + + +
+
+ ${this.tab==="signal"?this.renderSignalTab():this.tab==="frame"?this.renderFrameTab():this.renderWitnessTab()} +
+ `}};K.styles=m` + :host { + display: flex; flex-direction: column; + background: var(--bg-1); + border-left: 1px solid var(--line); + overflow: hidden; + height: 100%; + } + .tabs { + display: flex; border-bottom: 1px solid var(--line); + } + .tab { + flex: 1; + padding: 11px 8px; + background: transparent; border: none; + font-size: 11.5px; font-weight: 500; + color: var(--ink-3); + border-bottom: 2px solid transparent; + cursor: pointer; transition: color 0.15s, border-color 0.15s; + } + .tab.active { color: var(--ink); border-bottom-color: var(--accent); } + .tab:hover { color: var(--ink-2); } + .body { padding: 14px; flex: 1; overflow-y: auto; } + + .card { + background: var(--bg-2); border: 1px solid var(--line); + border-radius: var(--radius); padding: 12px; + margin-bottom: 12px; + } + .card-h { + display: flex; justify-content: space-between; align-items: center; + margin-bottom: 8px; + } + .card-h .ttl { font-size: 12px; font-weight: 600; } + .badge { + font-family: var(--mono); font-size: 10px; + padding: 2px 6px; + background: oklch(0.78 0.14 195 / 0.12); + color: var(--accent-2); + border-radius: 4px; + border: 1px solid oklch(0.78 0.14 195 / 0.3); + } + svg { width: 100%; height: 130px; } + .frame-strip { + height: 28px; + display: flex; align-items: flex-end; gap: 1px; + padding: 4px 0; + } + .bar { + flex: 1; + background: linear-gradient(to top, var(--accent-2), var(--accent)); + border-radius: 1px; + min-height: 2px; + } + table { width: 100%; border-collapse: collapse; font-family: var(--mono); font-size: 10.5px; } + td { padding: 4px 0; border-bottom: 1px solid var(--line); } + td:first-child { color: var(--ink-3); } + td:last-child { text-align: right; color: var(--ink); } + .hex { + background: var(--bg-3); + border: 1px solid var(--line); + border-radius: var(--radius-sm); + padding: 10px; + font-family: var(--mono); + font-size: 10.5px; + color: var(--ink-2); + line-height: 1.6; + overflow-x: auto; + white-space: nowrap; + } + .hex .magic { color: var(--accent); font-weight: 600; } + .witness-box { + font-family: var(--mono); + font-size: 11px; + color: var(--ink-2); + background: var(--bg-3); + border: 1px solid var(--line); + border-radius: 6px; + padding: 8px 10px; + word-break: break-all; + line-height: 1.5; + } + .verify-btn { + margin-top: 10px; + width: 100%; + padding: 8px; + border: 1px solid var(--line); + background: var(--bg-3); + color: var(--ink); + border-radius: 8px; + cursor: pointer; + font-family: var(--mono); + font-size: 12px; + } + .verify-btn:hover { border-color: var(--accent); } + .verify-btn.ok { border-color: var(--ok); color: var(--ok); } + .verify-btn.fail { border-color: var(--bad); color: var(--bad); } + `;Me([u()],K.prototype,"tab",2);Me([Ae({attribute:!1})],K.prototype,"pinTab",2);K=Me([h("nv-inspector")],K);var ht=Object.defineProperty,ft=Object.getOwnPropertyDescriptor,Be=(e,t,s,r)=>{for(var a=r>1?void 0:r?ft(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=(r?n(t,s,a):n(a))||a);return r&&a&&ht(t,s,a),a};let ue=class extends b{constructor(){super(...arguments),this.history=[],this.hIdx=-1,this.onKey=e=>{e.key==="Enter"?(this.exec(this.inputEl.value),this.inputEl.value=""):e.key==="ArrowUp"?this.history.length&&(this.hIdx=Math.max(0,this.hIdx-1),this.inputEl.value=this.history[this.hIdx]??"",e.preventDefault()):e.key==="ArrowDown"&&this.history.length&&(this.hIdx=Math.min(this.history.length,this.hIdx+1),this.inputEl.value=this.history[this.hIdx]??"",e.preventDefault())}}connectedCallback(){super.connectedCallback(),y(()=>{_.value,we.value,W.value,this.requestUpdate()})}updated(){const e=this.renderRoot.querySelector(".body");e&&(e.scrollTop=e.scrollHeight)}counts(){const e={info:0,warn:0,err:0,dbg:0,ok:0};for(const t of _.value)e[t.level]=(e[t.level]??0)+1;return e.all=_.value.length,e}async exec(e){if(e=e.trim(),!e)return;l("info",`nvsim> ${e}`),this.history.push(e),this.hIdx=this.history.length;const[t,...s]=e.split(/\s+/),r=s.join(" "),a=P();switch(t){case"help":l("info","commands: help · scene.list · sensor.config · run · pause · seed · proof.verify · clear · theme · status");break;case"scene.list":l("info","scene rebar-walkby-01:"),l("info"," rebar.steel.coil @ [+2.7, 0.0, +0.3] m χ=5000"),l("info"," dipole.heart_proxy @ [-1.4, +0.2, +0.4] m m=1.0e-6 A·m²"),l("info"," loop.mains_60Hz @ [-1.6, -0.4, 0.0] m I=2 A"),l("info"," eddy.door_steel @ [+0.0, +1.8, +0.4] m σ=1e6 S/m");break;case"sensor.config":l("info","NvSensor::cots_defaults() {"),l("info"," pos=[0,0,0], V=1mm³, N=1e12, C=0.03, T2*=200ns"),l("info"," D=2.870 GHz, γe=28 GHz/T, Γ=1.0 MHz, axes=4×〈111〉"),l("info"," δB ≈ 1.18 pT/√Hz (Barry 2020 §III.A) }");break;case"run":a&&(await a.run(),v.value=!0,l("ok","pipeline RUN"));break;case"pause":a&&(await a.pause(),v.value=!1,l("warn","pipeline PAUSED"));break;case"reset":a&&(await a.reset(),l("info","pipeline reset · t=0"));break;case"seed":{if(!r){l("info",`current seed = 0x${U.value.toString(16).toUpperCase()}`);break}const i=BigInt(r.startsWith("0x")?r:"0x"+r);U.value=i,a&&await a.setSeed(i),l("ok",`seed → 0x${i.toString(16).toUpperCase()}`);break}case"proof.verify":{if(!a)break;l("dbg","computing SHA-256 over 256 frames…");try{const i=D.value,n=new Uint8Array(32);for(let p=0;p<32;p++)n[p]=parseInt(i.slice(p*2,p*2+2),16);(await a.verifyWitness(n)).ok?(f.value="ok",C.value=i,l("ok",`witness ${i.slice(0,16)}… matches · determinism gate ✓`)):(f.value="fail",l("err","WITNESS MISMATCH"))}catch(i){l("err",`verify failed: ${i.message}`)}break}case"clear":_.value=[];break;case"theme":{const i=(r||"").toLowerCase();i==="light"||i==="dark"?(g.value=i,l("ok",`theme → ${i}`)):l("info","theme [light|dark]");break}case"status":l("info",`running=${v.value} seed=0x${U.value.toString(16).toUpperCase()} verified=${f.value}`);break;default:l("err",`unknown command: ${t} · try help`)}}render(){const e=this.counts(),t=we.value,s=_.value.filter(r=>t==="all"||r.level===t);return c` +
+ ${["all","info","warn","err","dbg"].map(r=>c` + + `)} + +
+ + +
+
+
+ ${s.map(r=>{const a=new Date(r.ts),i=`${String(a.getSeconds()).padStart(2,"0")}.${String(a.getMilliseconds()).padStart(3,"0")}`;return c`
+
${i}
+
${r.level}
+
+
`})} +
+
+ nvsim> + +
+ `}};ue.styles=m` + :host { + display: flex; flex-direction: column; + background: var(--bg-1); + overflow: hidden; + } + .tabs { + display: flex; align-items: center; + border-bottom: 1px solid var(--line); + padding: 0 10px; + gap: 2px; + } + .tab { + padding: 8px 12px; + background: transparent; border: none; + font-size: 11.5px; color: var(--ink-3); + font-family: var(--mono); + border-bottom: 2px solid transparent; + cursor: pointer; + margin-bottom: -1px; + } + .tab.active { color: var(--ink); border-bottom-color: var(--accent); } + .tab .cnt { + background: var(--bg-3); padding: 1px 5px; border-radius: 999px; + font-size: 9.5px; color: var(--ink-2); margin-left: 4px; + } + .spacer { flex: 1; } + .tools { display: flex; gap: 4px; padding: 4px 0; } + .tools button { + width: 24px; height: 24px; + background: transparent; border: 1px solid var(--line); + border-radius: 6px; + color: var(--ink-3); + font-size: 11px; cursor: pointer; + } + .tools button:hover { color: var(--ink); border-color: var(--line-2); } + + .body { + flex: 1; overflow-y: auto; + font-family: var(--mono); + font-size: 11.5px; + padding: 6px 0; + background: var(--bg-0); + } + .line { + display: grid; + grid-template-columns: 70px 60px 1fr; + gap: 12px; + padding: 2px 12px; + color: var(--ink-2); + border-left: 2px solid transparent; + } + .line:hover { background: var(--bg-1); } + .ts { color: var(--ink-4); font-size: 10.5px; padding-top: 1px; } + .lvl { + font-size: 10px; font-weight: 600; + text-transform: uppercase; letter-spacing: 0.04em; padding-top: 1px; + } + .line.info .lvl { color: var(--accent-2); } + .line.warn .lvl { color: var(--warn); } + .line.warn { border-left-color: var(--warn); background: oklch(0.7 0.18 35 / 0.04); } + .line.err .lvl { color: var(--bad); } + .line.err { border-left-color: var(--bad); background: oklch(0.65 0.22 25 / 0.05); } + .line.dbg .lvl { color: var(--ink-3); } + .line.ok .lvl { color: var(--ok); } + .msg { color: var(--ink); white-space: pre-wrap; word-break: break-word; } + + .input { + display: flex; align-items: center; + border-top: 1px solid var(--line); + background: var(--bg-0); + padding: 0 10px; + height: 32px; gap: 8px; + } + .prompt { color: var(--accent); font-family: var(--mono); font-size: 12px; } + input[type="text"] { + flex: 1; background: transparent; border: none; outline: none; + color: var(--ink); font-family: var(--mono); font-size: 12px; + height: 100%; + } + input::placeholder { color: var(--ink-4); } + `;Be([He("#console-input")],ue.prototype,"inputEl",2);ue=Be([h("nv-console")],ue);const j=[{id:"nvsim",name:"nvsim — NV-diamond magnetometer",category:"sim",crate:"nvsim",summary:"Deterministic forward simulator: scene → Biot–Savart → NV ensemble → ADC → MagFrame stream + SHA-256 witness.",budget:"L",active:!0,status:"available",tags:["quantum","magnetometer","simulator","witness","wasm"],adr:"ADR-089"},{id:"gesture",name:"Gesture (DTW)",category:"sig",crate:"wifi-densepose-wasm-edge",summary:"Dynamic-Time-Warping gesture classifier from CSI motion templates.",events:[1],budget:"M",status:"available",tags:["hci","csi","classifier","dtw"],adr:"ADR-014"},{id:"coherence",name:"Coherence gate",category:"sig",crate:"wifi-densepose-wasm-edge",summary:"Z-score coherence scoring + Accept/PredictOnly/Reject/Recalibrate gate.",events:[2],budget:"S",status:"available",tags:["gate","csi","coherence","drift"],adr:"ADR-029"},{id:"adversarial",name:"Adversarial-signal detector",category:"ais",crate:"wifi-densepose-wasm-edge",summary:"Physically-impossible-signal detector — multi-link consistency, used to flag spoofed CSI.",events:[3],budget:"M",status:"available",tags:["security","csi","spoofing","mesh"],adr:"ADR-032"},{id:"rvf",name:"RVF — Rust Verified Feature stream",category:"sig",crate:"wifi-densepose-wasm-edge",summary:"Verified-frame builder with SHA-256 hash + version metadata for the feature stream.",budget:"S",status:"available",tags:["witness","csi","hash"],adr:"ADR-040"},{id:"occupancy",name:"Occupancy estimator",category:"bld",crate:"wifi-densepose-wasm-edge",summary:"Through-wall presence + person-count via CSI amplitude perturbation.",events:[300,301,302],budget:"S",status:"available",tags:["csi","building","presence"]},{id:"vital_trend",name:"Vital-trend monitor",category:"med",crate:"wifi-densepose-wasm-edge",summary:"HR + BR trend tracking with bradycardia/tachycardia/apnea events.",events:[100,101,102,103,104,105],budget:"S",status:"available",tags:["medical","vitals","csi"],adr:"ADR-021"},{id:"intrusion",name:"Intrusion detector",category:"sec",crate:"wifi-densepose-wasm-edge",summary:"Zone-based intrusion alert from CSI motion patterns.",events:[200,201],budget:"S",status:"available",tags:["security","zone","csi"]},{id:"med_sleep_apnea",name:"Sleep-apnea detector",category:"med",crate:"wifi-densepose-wasm-edge",summary:"Episodic respiratory pause detection during sleep cycles.",events:[105],budget:"S",status:"available",tags:["medical","sleep","breathing"]},{id:"med_cardiac_arrhythmia",name:"Cardiac arrhythmia",category:"med",crate:"wifi-densepose-wasm-edge",summary:"Beat-to-beat irregularity classifier from cardiac micro-Doppler.",events:[103,104],budget:"M",status:"available",tags:["medical","cardiac","arrhythmia"]},{id:"med_respiratory_distress",name:"Respiratory distress",category:"med",crate:"wifi-densepose-wasm-edge",summary:"Distress signature: rapid shallow breathing + accessory-muscle motion.",events:[101,102],budget:"S",status:"available",tags:["medical","breathing","icu"]},{id:"med_gait_analysis",name:"Gait analysis",category:"med",crate:"wifi-densepose-wasm-edge",summary:"Stride length, cadence, asymmetry from through-wall CSI pose tracking.",budget:"M",status:"available",tags:["medical","gait","pose"]},{id:"med_seizure_detect",name:"Seizure detector",category:"med",crate:"wifi-densepose-wasm-edge",summary:"Tonic-clonic seizure motion signature.",budget:"M",status:"beta",tags:["medical","neuro"]},{id:"sec_perimeter_breach",name:"Perimeter breach",category:"sec",crate:"wifi-densepose-wasm-edge",summary:"Approach/departure detection at user-defined boundary segments.",events:[210,211,212,213],budget:"S",status:"available",tags:["security","perimeter"]},{id:"sec_weapon_detect",name:"Metal anomaly / weapon",category:"sec",crate:"wifi-densepose-wasm-edge",summary:"Metal-perturbation flag in CSI; potential weapon presence (research).",events:[220,221,222],budget:"M",status:"research",tags:["security","metal","csi"]},{id:"sec_tailgating",name:"Tailgating detector",category:"sec",crate:"wifi-densepose-wasm-edge",summary:"Detect 2+ persons crossing a single-passage threshold.",events:[230,231,232],budget:"S",status:"available",tags:["security","access-control"]},{id:"sec_loitering",name:"Loitering detector",category:"sec",crate:"wifi-densepose-wasm-edge",summary:"Stationary occupancy past a configurable dwell threshold.",events:[240,241,242],budget:"S",status:"available",tags:["security","dwell"]},{id:"sec_panic_motion",name:"Panic motion",category:"sec",crate:"wifi-densepose-wasm-edge",summary:"High-energy distress motion: struggle / fleeing pattern.",events:[250,251,252],budget:"S",status:"beta",tags:["security","distress"]},{id:"bld_hvac_presence",name:"HVAC presence",category:"bld",crate:"wifi-densepose-wasm-edge",summary:"Occupied/activity-level/departure-countdown for HVAC zones.",events:[310,311,312],budget:"S",status:"available",tags:["hvac","building","energy"]},{id:"bld_lighting_zones",name:"Lighting zones",category:"bld",crate:"wifi-densepose-wasm-edge",summary:"Per-zone light on/dim/off cues from occupancy.",events:[320,321,322],budget:"S",status:"available",tags:["lighting","building"]},{id:"bld_elevator_count",name:"Elevator count",category:"bld",crate:"wifi-densepose-wasm-edge",summary:"Person count inside elevator car from CSI.",events:[330],budget:"S",status:"available",tags:["elevator","building"]},{id:"bld_meeting_room",name:"Meeting-room utilization",category:"bld",crate:"wifi-densepose-wasm-edge",summary:"Meeting size + duration analytics for booking systems.",budget:"S",status:"available",tags:["meeting","analytics"]},{id:"bld_energy_audit",name:"Energy audit",category:"bld",crate:"wifi-densepose-wasm-edge",summary:"Continuous occupancy-vs-HVAC-state audit for energy savings.",budget:"M",status:"available",tags:["energy","audit"]},{id:"ret_queue_length",name:"Queue length",category:"ret",crate:"wifi-densepose-wasm-edge",summary:"Live queue-length tracking for checkout / kiosks.",budget:"S",status:"available",tags:["retail","queue"]},{id:"ret_dwell_heatmap",name:"Dwell heatmap",category:"ret",crate:"wifi-densepose-wasm-edge",summary:"Per-zone dwell time accumulation; analytics-only export.",budget:"M",status:"available",tags:["retail","heatmap"]},{id:"ret_customer_flow",name:"Customer flow",category:"ret",crate:"wifi-densepose-wasm-edge",summary:"Origin-destination flow graph through a store layout.",budget:"M",status:"available",tags:["retail","flow"]},{id:"ret_table_turnover",name:"Table turnover",category:"ret",crate:"wifi-densepose-wasm-edge",summary:"Restaurant table seat / vacate transitions.",budget:"S",status:"available",tags:["retail","restaurant"]},{id:"ret_shelf_engagement",name:"Shelf engagement",category:"ret",crate:"wifi-densepose-wasm-edge",summary:"Reach-to-shelf gestures and dwell at product zones.",budget:"M",status:"available",tags:["retail","shelf"]},{id:"ind_forklift_proximity",name:"Forklift proximity",category:"ind",crate:"wifi-densepose-wasm-edge",summary:"Worker-near-forklift safety alert.",budget:"S",status:"available",tags:["industrial","safety"]},{id:"ind_confined_space",name:"Confined-space monitor",category:"ind",crate:"wifi-densepose-wasm-edge",summary:"Last-person-out detection + presence audit for OSHA confined-space entries.",budget:"S",status:"available",tags:["industrial","osha"]},{id:"ind_clean_room",name:"Clean-room PPE / motion",category:"ind",crate:"wifi-densepose-wasm-edge",summary:"Motion patterns consistent with proper PPE-clad movement.",budget:"M",status:"beta",tags:["industrial","cleanroom"]},{id:"ind_livestock_monitor",name:"Livestock monitor",category:"ind",crate:"wifi-densepose-wasm-edge",summary:"Vital-sign + activity tracking for stall-bound livestock.",budget:"M",status:"beta",tags:["agriculture","livestock"]},{id:"ind_structural_vibration",name:"Structural vibration",category:"ind",crate:"wifi-densepose-wasm-edge",summary:"Building/equipment micro-vibration via CSI phase derivative.",budget:"M",status:"research",tags:["industrial","vibration"]},{id:"sig_coherence_gate",name:"Coherence gate (extended)",category:"sig",crate:"wifi-densepose-wasm-edge",summary:"Hysteresis + multi-state coherence gate driving downstream apps.",budget:"S",status:"available",tags:["gate","csi"]},{id:"sig_flash_attention",name:"Flash attention (CSI)",category:"sig",crate:"wifi-densepose-wasm-edge",summary:"Edge-friendly attention block for CSI subcarrier weighting.",budget:"M",status:"beta",tags:["attention","csi"]},{id:"sig_temporal_compress",name:"Temporal-tensor compress",category:"sig",crate:"wifi-densepose-wasm-edge",summary:"RuVector temporal-tensor compression on the CSI buffer.",budget:"M",status:"available",tags:["compress","tensor"]},{id:"sig_sparse_recovery",name:"Sparse recovery",category:"sig",crate:"wifi-densepose-wasm-edge",summary:"114→56 subcarrier sparse interpolation via L1 solver.",budget:"M",status:"available",tags:["sparse","csi"]},{id:"sig_mincut_person_match",name:"Mincut person-match",category:"sig",crate:"wifi-densepose-wasm-edge",summary:"Min-cut person assignment across multistatic frames.",budget:"M",status:"available",tags:["mincut","matching"]},{id:"sig_optimal_transport",name:"Optimal transport",category:"sig",crate:"wifi-densepose-wasm-edge",summary:"OT-based feature alignment between mesh nodes.",budget:"M",status:"beta",tags:["ot","alignment"]},{id:"lrn_dtw_gesture_learn",name:"DTW gesture learn",category:"lrn",crate:"wifi-densepose-wasm-edge",summary:"On-device template learning for personalized gesture libraries.",budget:"M",status:"beta",tags:["lifelong","gesture"]},{id:"lrn_anomaly_attractor",name:"Anomaly attractor",category:"lrn",crate:"wifi-densepose-wasm-edge",summary:"Novelty detector with dynamic-attractor recall.",budget:"M",status:"research",tags:["novelty","lifelong"]},{id:"lrn_meta_adapt",name:"Meta-adapt",category:"lrn",crate:"wifi-densepose-wasm-edge",summary:"Meta-learning adapter for fast site-to-site transfer.",budget:"L",status:"research",tags:["meta-learning"]},{id:"lrn_ewc_lifelong",name:"EWC++ lifelong",category:"lrn",crate:"wifi-densepose-wasm-edge",summary:"Elastic-weight-consolidation gate to avoid catastrophic forgetting.",budget:"M",status:"beta",tags:["lifelong","ewc"]},{id:"spt_pagerank_influence",name:"PageRank influence",category:"spt",crate:"wifi-densepose-wasm-edge",summary:"Graph-influence ranking on the multistatic mesh.",budget:"M",status:"beta",tags:["graph","pagerank"]},{id:"spt_micro_hnsw",name:"µHNSW vector index",category:"spt",crate:"wifi-densepose-wasm-edge",summary:"Tiny HNSW index for AETHER re-ID embeddings on-device.",budget:"M",status:"available",tags:["hnsw","reid"]},{id:"spt_spiking_tracker",name:"Spiking tracker",category:"spt",crate:"wifi-densepose-wasm-edge",summary:"Spiking-network multi-target tracker.",budget:"L",status:"research",tags:["snn","tracker"]},{id:"tmp_pattern_sequence",name:"Pattern sequence",category:"tmp",crate:"wifi-densepose-wasm-edge",summary:"Sequence-of-events pattern matcher (e.g. ingress→linger→egress).",budget:"M",status:"available",tags:["temporal","pattern"]},{id:"tmp_temporal_logic_guard",name:"Temporal logic guard",category:"tmp",crate:"wifi-densepose-wasm-edge",summary:"LTL/MTL safety-property guard over event streams.",budget:"M",status:"beta",tags:["ltl","safety"]},{id:"tmp_goap_autonomy",name:"GOAP autonomy",category:"tmp",crate:"wifi-densepose-wasm-edge",summary:"Goal-oriented action planning for adaptive routines.",budget:"L",status:"research",tags:["planning","autonomy"]},{id:"ais_prompt_shield",name:"Prompt shield",category:"ais",crate:"wifi-densepose-wasm-edge",summary:"Edge-side LLM prompt-injection guard for on-device assistants.",budget:"M",status:"beta",tags:["security","llm"]},{id:"ais_behavioral_profiler",name:"Behavioral profiler",category:"ais",crate:"wifi-densepose-wasm-edge",summary:"Anomalous-behaviour profiler (drift in motion habits).",budget:"M",status:"beta",tags:["anomaly","behaviour"]},{id:"qnt_quantum_coherence",name:"Quantum coherence",category:"qnt",crate:"wifi-densepose-wasm-edge",summary:"Coherence diagnostics adapted for quantum-sensor signals.",budget:"M",status:"research",tags:["quantum","coherence"]},{id:"qnt_interference_search",name:"Interference search",category:"qnt",crate:"wifi-densepose-wasm-edge",summary:"Interferometric anomaly search across mesh viewpoints.",budget:"L",status:"research",tags:["quantum","interference"]},{id:"aut_psycho_symbolic",name:"Psycho-symbolic agent",category:"aut",crate:"wifi-densepose-wasm-edge",summary:"Symbolic-rule + neural-feature hybrid for low-power autonomy loops.",budget:"L",status:"research",tags:["autonomy","symbolic"]},{id:"aut_self_healing_mesh",name:"Self-healing mesh",category:"aut",crate:"wifi-densepose-wasm-edge",summary:"Mesh-topology repair with per-node health gossip.",budget:"M",status:"beta",tags:["mesh","health"]},{id:"exo_ghost_hunter",name:"Ghost hunter (anomaly)",category:"exo",crate:"wifi-densepose-wasm-edge",summary:"Empty-room CSI anomaly detector — impulsive/periodic/drift/random + hidden-presence sub-detector.",events:[650,651,652,653],budget:"S",status:"available",tags:["anomaly","paranormal","csi"],adr:"ADR-041"},{id:"exo_breathing_sync",name:"Breathing sync",category:"exo",crate:"wifi-densepose-wasm-edge",summary:"Multi-person breathing synchrony analytics.",budget:"M",status:"beta",tags:["breathing","sync"]},{id:"exo_dream_stage",name:"Dream-stage classifier",category:"exo",crate:"wifi-densepose-wasm-edge",summary:"NREM/REM stage classification from breathing + micro-motion.",budget:"M",status:"research",tags:["sleep","rem"]},{id:"exo_emotion_detect",name:"Emotion detector",category:"exo",crate:"wifi-densepose-wasm-edge",summary:"Coarse arousal/valence from breathing + heart-rate variability.",budget:"M",status:"research",tags:["affect"]},{id:"exo_gesture_language",name:"Gesture language",category:"exo",crate:"wifi-densepose-wasm-edge",summary:"Sign-language pattern recognition.",budget:"L",status:"research",tags:["hci","sign"]},{id:"exo_happiness_score",name:"Happiness score",category:"exo",crate:"wifi-densepose-wasm-edge",summary:"Aggregate well-being score from co-occupancy + activity dynamics.",budget:"M",status:"research",tags:["affect","wellbeing"]},{id:"exo_hyperbolic_space",name:"Hyperbolic space embed",category:"exo",crate:"wifi-densepose-wasm-edge",summary:"Hyperbolic embeddings for hierarchical scene structure.",budget:"L",status:"research",tags:["embedding","hyperbolic"]},{id:"exo_music_conductor",name:"Music conductor",category:"exo",crate:"wifi-densepose-wasm-edge",summary:"Map gesture energy to MIDI tempo/dynamics.",budget:"M",status:"research",tags:["midi","art"]},{id:"exo_plant_growth",name:"Plant-growth tracker",category:"exo",crate:"wifi-densepose-wasm-edge",summary:"Slow CSI drift tracking for greenhouse foliage growth.",budget:"L",status:"research",tags:["agriculture"]},{id:"exo_rain_detect",name:"Rain detector",category:"exo",crate:"wifi-densepose-wasm-edge",summary:"Outdoor CSI signature of rainfall.",budget:"M",status:"research",tags:["weather"]},{id:"exo_time_crystal",name:"Time-crystal periodicity",category:"exo",crate:"wifi-densepose-wasm-edge",summary:"Periodicity diagnostics with anti-aliasing harmonics.",budget:"M",status:"research",tags:["periodicity"]}],F={sim:{label:"Simulators",color:"oklch(0.78 0.14 70)",range:"—"},med:{label:"Medical & Health",color:"oklch(0.65 0.22 25)",range:"100–199"},sec:{label:"Security & Safety",color:"oklch(0.7 0.18 35)",range:"200–299"},bld:{label:"Smart Building",color:"oklch(0.78 0.12 195)",range:"300–399"},ret:{label:"Retail & Hospitality",color:"oklch(0.78 0.14 145)",range:"400–499"},ind:{label:"Industrial",color:"oklch(0.72 0.18 330)",range:"500–599"},sig:{label:"Signal Processing",color:"oklch(0.78 0.14 70)",range:"600–619"},lrn:{label:"Online Learning",color:"oklch(0.78 0.12 260)",range:"620–639"},spt:{label:"Spatial / Graph",color:"oklch(0.7 0.18 100)",range:"640–659"},tmp:{label:"Temporal / Planning",color:"oklch(0.7 0.16 50)",range:"660–679"},ais:{label:"AI Safety",color:"oklch(0.65 0.22 25)",range:"700–719"},qnt:{label:"Quantum",color:"oklch(0.72 0.18 290)",range:"720–739"},aut:{label:"Autonomy",color:"oklch(0.78 0.14 145)",range:"740–759"},exo:{label:"Exotic / Research",color:"oklch(0.72 0.18 330)",range:"650–699"}};function yt(){return j.map(e=>({id:e.id,active:e.active===!0,eventCount:0}))}function xt(e,t){if(!e)return 1;const s=e.toLowerCase();let r=0;return t.id.toLowerCase().includes(s)&&(r+=3),t.name.toLowerCase().includes(s)&&(r+=3),t.summary.toLowerCase().includes(s)&&(r+=1),t.tags?.some(a=>a.toLowerCase().includes(s))&&(r+=2),t.category===s&&(r+=5),r}const wt="nvsim",kt=1,H="kv";let re=null;function Ne(){return re||(re=new Promise((e,t)=>{const s=indexedDB.open(wt,kt);s.onupgradeneeded=()=>{const r=s.result;r.objectStoreNames.contains(H)||r.createObjectStore(H)},s.onsuccess=()=>e(s.result),s.onerror=()=>t(s.error)}),re)}async function q(e){const t=await Ne();return await new Promise((s,r)=>{const i=t.transaction(H,"readonly").objectStore(H).get(e);i.onsuccess=()=>s(i.result),i.onerror=()=>r(i.error)})}async function G(e,t){const s=await Ne();return await new Promise((r,a)=>{const i=s.transaction(H,"readwrite");i.objectStore(H).put(t,e),i.oncomplete=()=>r(),i.onerror=()=>a(i.error)})}var $t=Object.defineProperty,St=Object.getOwnPropertyDescriptor,We=(e,t,s,r)=>{for(var a=r>1?void 0:r?St(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=(r?n(t,s,a):n(a))||a);return r&&a&&$t(t,s,a),a};const M=o(yt()),B=o(""),A=o("all"),x=o("all");(async()=>{const e=await q("app-activations");e&&(M.value=e)})();y(()=>{const e=M.value;e.length>0&&G("app-activations",e)});let ve=class extends b{constructor(){super(...arguments),this.renderTick=0}connectedCallback(){super.connectedCallback(),y(()=>{M.value,B.value,A.value,x.value,this.renderTick++})}isActive(e){return M.value.find(t=>t.id===e)?.active===!0}toggle(e){const t=M.value.map(s=>s.id===e.id?{...s,active:!s.active,lastActivatedAt:Date.now()}:s);M.value=t,l(this.isActive(e.id)?"ok":"info",`app ${e.id} deactivated`)}filtered(){let e=j;return A.value!=="all"&&(e=e.filter(t=>t.category===A.value)),x.value!=="all"&&(e=e.filter(t=>t.status===x.value)),B.value.trim()&&(e=e.map(t=>({a:t,s:xt(B.value,t)})).filter(t=>t.s>0).sort((t,s)=>s.s-t.s).map(t=>t.a)),e}categoryCounts(){const e={all:j.length};for(const t of Object.keys(F))e[t]=0;for(const t of j)e[t.category]=(e[t.category]??0)+1;return e}render(){const e=this.filtered(),t=this.categoryCounts(),s=M.value.filter(r=>r.active).length;return c` +
+
+ App Store + ${j.length} edge apps · ${s} active +
+ {B.value=r.target.value}} /> +
+ +
+ A.value="all"}> + All${t.all} + + ${Object.keys(F).map(r=>c` + A.value=r}> + + ${F[r].label} + ${t[r]??0} + + `)} + + x.value="all"}>any + x.value="available"}>available + x.value="beta"}>beta + x.value="research"}>research +
+ + ${e.length===0?c`
No apps match the current filters.
`:c`
${e.map(r=>this.card(r))}
`} + `}card(e){const t=this.isActive(e.id),s=F[e.category];return c` +
+
+ + ${e.name} +
+
${e.summary}
+
+ ${s.label} + ${e.status} + ${e.budget?c`budget ${e.budget}`:""} + ${e.adr?c`${e.adr}`:""} + ${e.events?.length?c`events ${e.events.join("·")}`:""} +
+
+ ${e.crate} + this.toggle(e)}> +
+
+ `}};ve.styles=m` + :host { + display: block; + height: 100%; + overflow-y: auto; + background: radial-gradient(ellipse at 50% 30%, var(--bg-2) 0%, var(--bg-0) 70%); + padding: 24px; + } + .head { + display: flex; align-items: center; gap: 16px; + margin-bottom: 18px; + flex-wrap: wrap; + } + .ttl { + font-size: 22px; font-weight: 700; letter-spacing: -0.02em; + color: var(--ink); + flex: 1; min-width: 200px; + } + .ttl small { + font-size: 12.5px; font-weight: 400; + color: var(--ink-3); margin-left: 8px; + } + .search { + width: 320px; max-width: 100%; + padding: 8px 12px; + background: var(--bg-2); + border: 1px solid var(--line); + border-radius: 8px; + font-family: var(--mono); + font-size: 12.5px; + color: var(--ink); outline: none; + } + .search:focus { border-color: var(--accent); } + .filters { + display: flex; flex-wrap: wrap; gap: 6px; + margin-bottom: 18px; + } + .chip { + padding: 4px 10px; + background: var(--bg-2); + border: 1px solid var(--line); + border-radius: 999px; + font-size: 11.5px; color: var(--ink-3); + cursor: pointer; + font-family: var(--mono); + display: inline-flex; align-items: center; gap: 4px; + } + .chip:hover { color: var(--ink); border-color: var(--line-2); } + .chip.on { background: var(--bg-3); border-color: var(--accent); color: var(--ink); } + .chip .swatch { + width: 7px; height: 7px; border-radius: 50%; + } + .chip .count { color: var(--ink-3); font-size: 10px; } + .grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 12px; + } + .card { + background: var(--bg-2); + border: 1px solid var(--line); + border-radius: var(--radius); + padding: 12px 14px; + display: flex; flex-direction: column; gap: 6px; + transition: border-color 0.15s, transform 0.15s; + position: relative; + } + .card:hover { border-color: var(--line-2); transform: translateY(-1px); } + .card.active { + border-color: oklch(0.78 0.14 145 / 0.7); + background: linear-gradient(180deg, var(--bg-2) 0%, oklch(0.78 0.14 145 / 0.04) 100%); + } + .card-h { + display: flex; align-items: flex-start; gap: 8px; + margin-bottom: 2px; + } + .card-h .name { + font-size: 13.5px; font-weight: 600; color: var(--ink); + flex: 1; line-height: 1.3; + } + .card-h .swatch { + width: 10px; height: 10px; border-radius: 50%; + flex-shrink: 0; margin-top: 4px; + } + .summary { + font-size: 12px; color: var(--ink-2); line-height: 1.45; + flex: 1; + } + .meta { + display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; + font-family: var(--mono); font-size: 10px; + } + .badge { + padding: 1px 6px; border-radius: 4px; + background: var(--bg-3); color: var(--ink-3); + border: 1px solid var(--line); + } + .badge.cat { color: var(--accent); border-color: oklch(0.78 0.14 70 / 0.3); } + .badge.status-available { color: var(--ok); border-color: oklch(0.78 0.14 145 / 0.4); } + .badge.status-beta { color: var(--warn); border-color: oklch(0.7 0.18 35 / 0.4); } + .badge.status-research { color: var(--accent-3); border-color: oklch(0.72 0.18 330 / 0.4); } + .badge.budget { color: var(--accent-2); border-color: oklch(0.78 0.12 195 / 0.3); } + .card-foot { + display: flex; align-items: center; gap: 8px; + padding-top: 8px; margin-top: 4px; + border-top: 1px solid var(--line); + font-size: 11px; color: var(--ink-3); + } + .toggle { + position: relative; + width: 32px; height: 18px; + background: var(--bg-3); border: 1px solid var(--line-2); + border-radius: 999px; cursor: pointer; + transition: background 0.15s; + flex-shrink: 0; + } + .toggle::after { + content: ''; position: absolute; + top: 1px; left: 1px; + width: 12px; height: 12px; + background: var(--ink-3); border-radius: 50%; + transition: transform 0.15s, background 0.15s; + } + .toggle.on { background: var(--accent); border-color: var(--accent); } + .toggle.on::after { background: #1a0f00; transform: translateX(14px); } + .events { + font-family: var(--mono); font-size: 10px; color: var(--ink-3); + flex: 1; + } + .empty { + padding: 40px; + text-align: center; color: var(--ink-3); + font-size: 13px; + } + `;We([u()],ve.prototype,"renderTick",2);ve=We([h("nv-app-store")],ve);var _t=Object.defineProperty,Ct=Object.getOwnPropertyDescriptor,he=(e,t,s,r)=>{for(var a=r>1?void 0:r?Ct(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=(r?n(t,s,a):n(a))||a);return r&&a&&_t(t,s,a),a};let L=class extends b{constructor(){super(...arguments),this.visible=!1,this.msg="",this.icon="✓",this.timer=null,this.onToast=e=>{const t=e.detail;this.msg=t.msg??"Done",this.icon=t.icon??"✓",this.visible=!0,this.setAttribute("visible",""),this.timer!==null&&window.clearTimeout(this.timer),this.timer=window.setTimeout(()=>{this.visible=!1,this.removeAttribute("visible")},1800)}}connectedCallback(){super.connectedCallback(),window.addEventListener("nv-toast",this.onToast)}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener("nv-toast",this.onToast)}render(){return c`${this.icon}${this.msg}`}};L.styles=m` + :host { + position: fixed; bottom: 24px; left: 50%; + transform: translateX(-50%) translateY(80px); + background: var(--bg-2); + border: 1px solid var(--line-2); + border-radius: var(--radius); + padding: 10px 14px; + font-size: 12.5px; + box-shadow: var(--shadow); + z-index: 100; + opacity: 0; pointer-events: none; + transition: opacity 0.2s, transform 0.2s; + display: flex; align-items: center; gap: 8px; + } + :host([visible]) { + opacity: 1; + transform: translateX(-50%) translateY(0); + pointer-events: auto; + } + .icon { color: var(--accent); } + `;he([u()],L.prototype,"visible",2);he([u()],L.prototype,"msg",2);he([u()],L.prototype,"icon",2);L=he([h("nv-toast")],L);function N(e,t="✓"){window.dispatchEvent(new CustomEvent("nv-toast",{detail:{msg:e,icon:t}}))}var Pt=Object.defineProperty,At=Object.getOwnPropertyDescriptor,Q=(e,t,s,r)=>{for(var a=r>1?void 0:r?At(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=(r?n(t,s,a):n(a))||a);return r&&a&&Pt(t,s,a),a};let z=class extends b{constructor(){super(...arguments),this.open=!1,this.mTitle="",this.mBody="",this.buttons=[],this.onModal=e=>{const t=e.detail;this.mTitle=t.title,this.mBody=t.body,this.buttons=t.buttons??[{label:"Close",variant:"primary"}],this.open=!0,this.setAttribute("open","")},this.onKey=e=>{e.key==="Escape"&&this.open&&this.close()}}connectedCallback(){super.connectedCallback(),window.addEventListener("nv-modal",this.onModal),window.addEventListener("keydown",this.onKey)}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener("nv-modal",this.onModal),window.removeEventListener("keydown",this.onKey)}close(){this.open=!1,this.removeAttribute("open")}clickBtn(e){e.onClick?.(),this.close()}render(){return c` + + `}};z.styles=m` + :host { + position: fixed; inset: 0; + background: rgba(0,0,0,0.55); + backdrop-filter: blur(4px); + z-index: 200; + display: grid; place-items: center; + opacity: 0; pointer-events: none; + transition: opacity 0.18s; + } + :host([open]) { opacity: 1; pointer-events: auto; } + .modal { + background: var(--bg-1); + border: 1px solid var(--line-2); + border-radius: var(--radius); + box-shadow: 0 30px 80px -20px rgba(0,0,0,0.7); + width: min(520px, 92vw); + max-height: 86vh; + display: flex; flex-direction: column; + transform: translateY(12px) scale(0.98); + transition: transform 0.22s cubic-bezier(0.2,0.7,0.3,1); + } + :host([open]) .modal { transform: translateY(0) scale(1); } + .h { + padding: 14px 16px; + border-bottom: 1px solid var(--line); + display: flex; align-items: center; justify-content: space-between; + } + .h .ttl { font-size: 14px; font-weight: 600; } + .body { padding: 16px; overflow-y: auto; font-size: 13px; color: var(--ink-2); line-height: 1.55; } + .f { + padding: 12px 16px; + border-top: 1px solid var(--line); + display: flex; gap: 8px; justify-content: flex-end; + } + button { + padding: 6px 12px; + border-radius: 8px; + font-size: 12.5px; + cursor: pointer; + font-family: inherit; + border: 1px solid var(--line); + background: var(--bg-2); color: var(--ink); + } + button.ghost { background: transparent; } + button.primary { background: var(--accent); border-color: var(--accent); color: #1a0f00; } + button.danger { background: var(--bad); border-color: var(--bad); color: #fff; } + .close { + width: 28px; height: 28px; + background: transparent; border: 1px solid var(--line); + border-radius: 6px; + color: var(--ink-2); + } + `;Q([u()],z.prototype,"open",2);Q([u()],z.prototype,"mTitle",2);Q([u()],z.prototype,"mBody",2);Q([u()],z.prototype,"buttons",2);z=Q([h("nv-modal")],z);function ke(e){window.dispatchEvent(new CustomEvent("nv-modal",{detail:e}))}var Mt=Object.defineProperty,zt=Object.getOwnPropertyDescriptor,J=(e,t,s,r)=>{for(var a=r>1?void 0:r?zt(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=(r?n(t,s,a):n(a))||a);return r&&a&&Mt(t,s,a),a};let T=class extends b{constructor(){super(...arguments),this.open=!1,this.filter="",this.idx=0,this.cmds=[{ico:"▶",label:"Run pipeline",kbd:"Space",run:async()=>{await P()?.run(),v.value=!0,N("Pipeline running","▶")}},{ico:"❚",label:"Pause pipeline",run:async()=>{await P()?.pause(),v.value=!1,N("Paused","❚❚")}},{ico:"⟳",label:"Reset pipeline",kbd:"⌘R",run:()=>ke({title:"Reset pipeline?",body:"

Clears the frame stream and rewinds t to 0.

",buttons:[{label:"Cancel",variant:"ghost"},{label:"Reset",variant:"danger",onClick:async()=>{await P()?.reset(),l("warn","pipeline reset · t=0"),N("Pipeline reset","⟳")}}]})},{ico:"✓",label:"Verify witness",run:async()=>{const e=P();if(!e)return;f.value="pending";const t=D.value,s=new Uint8Array(32);for(let a=0;a<32;a++)s[a]=parseInt(t.slice(a*2,a*2+2),16);(await e.verifyWitness(s)).ok?(f.value="ok",C.value=t,N("Witness verified","✓")):(f.value="fail",N("Witness mismatch!","✗"))}},{ico:"☼",label:"Toggle theme",kbd:"⌘/",run:()=>{g.value=g.value==="dark"?"light":"dark"}},{ico:"⚙",label:"Open settings",kbd:"⌘,",run:()=>window.dispatchEvent(new CustomEvent("open-settings"))},{ico:"?",label:"Keyboard shortcuts…",run:()=>ke({title:"Keyboard shortcuts",body:`
+
⌘K / Ctrl K
Command palette
+
Space
Play / pause
+
⌘R
Reset
+
⌘,
Settings
+
⌘/
Toggle theme
+
\`
Debug HUD
+
1 · 2 · 3
Inspector tabs
+
Esc
Close modal/palette
+
/
Focus REPL
+
`,buttons:[{label:"Close",variant:"primary"}]})},{ico:"i",label:"About nvsim…",run:()=>ke({title:"About nvsim",body:`

nvsim is a deterministic, byte-reproducible forward simulator for nitrogen-vacancy diamond magnetometry.

+

This dashboard runs nvsim as WASM in a Web Worker. Same (scene, config, seed) → byte-identical SHA-256 witness across runs and machines.

+

License: MIT OR Apache-2.0 · See ADR-089, ADR-092.

`,buttons:[{label:"Close",variant:"primary"}]})}],this.onKey=e=>{(e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==="k"?(e.preventDefault(),this.openPal()):e.key==="Escape"&&this.open?this.closePal():this.open&&(e.key==="ArrowDown"?(this.idx=Math.min(this.cmds.length-1,this.idx+1),e.preventDefault()):e.key==="ArrowUp"?(this.idx=Math.max(0,this.idx-1),e.preventDefault()):e.key==="Enter"&&(this.runIdx(),e.preventDefault()))},this.onOpen=()=>this.openPal()}connectedCallback(){super.connectedCallback(),window.addEventListener("keydown",this.onKey),window.addEventListener("nv-palette",this.onOpen)}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener("keydown",this.onKey),window.removeEventListener("nv-palette",this.onOpen)}openPal(){this.open=!0,this.setAttribute("open",""),this.filter="",this.idx=0,setTimeout(()=>this.inputEl?.focus(),0)}closePal(){this.open=!1,this.removeAttribute("open")}filtered(){if(!this.filter.trim())return this.cmds;const e=this.filter.toLowerCase();return this.cmds.filter(t=>t.label.toLowerCase().includes(e))}runIdx(){const t=this.filtered()[this.idx];t&&(t.run(),this.closePal())}render(){const e=this.filtered();return c` +
+
+ {this.filter=t.target.value,this.idx=0}} /> +
+
+ ${e.map((t,s)=>c` +
{this.idx=s,this.runIdx()}}> + ${t.ico} + ${t.label} + ${t.kbd?c`${t.kbd}`:""} +
+ `)} +
+
+ `}};T.styles=m` + :host { + position: fixed; inset: 0; z-index: 220; + background: rgba(0,0,0,0.5); + opacity: 0; pointer-events: none; + transition: opacity 0.15s; + display: flex; justify-content: center; padding-top: 12vh; + backdrop-filter: blur(4px); + } + :host([open]) { opacity: 1; pointer-events: auto; } + .palette { + width: min(560px, 92vw); + background: var(--bg-1); + border: 1px solid var(--line-2); + border-radius: var(--radius); + box-shadow: 0 30px 80px -20px rgba(0,0,0,0.7); + overflow: hidden; + display: flex; flex-direction: column; + max-height: 60vh; + } + .input { + padding: 14px 16px; + border-bottom: 1px solid var(--line); + } + input { + width: 100%; + background: transparent; border: none; outline: none; + color: var(--ink); font-size: 14px; + font-family: inherit; + } + .list { flex: 1; overflow-y: auto; padding: 4px; } + .item { + display: flex; align-items: center; gap: 10px; + padding: 8px 12px; + border-radius: 6px; + cursor: pointer; + font-size: 12.5px; + } + .item.active { background: var(--bg-3); } + .item .ico { width: 20px; text-align: center; color: var(--accent); } + .item .lbl { flex: 1; } + .item .kbd { + font-family: var(--mono); font-size: 10.5px; + color: var(--ink-3); + padding: 1px 5px; background: var(--bg-3); border-radius: 4px; + } + `;J([u()],T.prototype,"open",2);J([u()],T.prototype,"filter",2);J([u()],T.prototype,"idx",2);J([He("#palette-input")],T.prototype,"inputEl",2);T=J([h("nv-palette")],T);var Tt=Object.defineProperty,Rt=Object.getOwnPropertyDescriptor,ze=(e,t,s,r)=>{for(var a=r>1?void 0:r?Rt(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=(r?n(t,s,a):n(a))||a);return r&&a&&Tt(t,s,a),a};let Y=class extends b{constructor(){super(...arguments),this.open=!1,this.renderFps=0,this.lastTs=performance.now(),this.frameCount=0,this.rafId=0,this.onKey=e=>{e.key==="`"&&!e.target.matches("input, textarea")&&(this.open=!this.open,this.toggleAttribute("open",this.open))},this.tick=()=>{this.rafId=requestAnimationFrame(this.tick);const e=performance.now();this.frameCount++,e-this.lastTs>=500&&(this.renderFps=this.frameCount*1e3/(e-this.lastTs),this.frameCount=0,this.lastTs=e,this.requestUpdate())}}connectedCallback(){super.connectedCallback(),window.addEventListener("keydown",this.onKey),y(()=>{k.value,$e.value,O.value,E.value,st.value,this.requestUpdate()}),this.tick()}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener("keydown",this.onKey),cancelAnimationFrame(this.rafId)}render(){return c` +
nvsim · debug{this.open=!1,this.removeAttribute("open")}}>✕
+
render fps${this.renderFps.toFixed(1)}
+
sim fps${k.value>0?Math.round(k.value):"—"}
+
frames${$e.value.toString()}
+
|B|${(O.value*1e9).toFixed(3)} nT
+
SNR${E.value>0?E.value.toFixed(1):"—"}
+
DOM${document.querySelectorAll("*").length}
+ `}};Y.styles=m` + :host { + position: fixed; bottom: 8px; right: 8px; + width: 220px; + background: rgba(13,17,23,0.85); + backdrop-filter: blur(8px); + border: 1px solid var(--line-2); + border-radius: 8px; + padding: 8px 10px; + font-family: var(--mono); font-size: 11px; + color: var(--ink-2); + z-index: 99; + display: none; + box-shadow: var(--shadow); + } + :host([open]) { display: block; } + .h { + display: flex; justify-content: space-between; + font-weight: 600; color: var(--ink); + margin-bottom: 6px; padding-bottom: 4px; + border-bottom: 1px solid var(--line); + } + .x { cursor: pointer; color: var(--ink-3); } + .row { + display: flex; justify-content: space-between; + padding: 1px 0; + } + .k { color: var(--ink-3); } + .v { color: var(--ink); } + `;ze([u()],Y.prototype,"open",2);ze([u()],Y.prototype,"renderFps",2);Y=ze([h("nv-debug-hud")],Y);var Et=Object.defineProperty,Ot=Object.getOwnPropertyDescriptor,je=(e,t,s,r)=>{for(var a=r>1?void 0:r?Ot(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=(r?n(t,s,a):n(a))||a);return r&&a&&Et(t,s,a),a};let ge=class extends b{constructor(){super(...arguments),this.open=!1}connectedCallback(){super.connectedCallback(),y(()=>{g.value,w.value,$.value,se.value,S.value,xe.value,this.requestUpdate()}),window.addEventListener("open-settings",()=>{this.open=!0,this.setAttribute("open","")})}close(){this.open=!1,this.removeAttribute("open")}render(){return c` +
this.close()}>
+
+
Settings
+ +
+
+
+

Appearance

+
+
Theme
+
+ + +
+
+
+
+
Density
+
Affects panel padding and font scale.
+
+
+ + + +
+
+
+
+
Reduce motion
+
Disable rotating crystal & field-line animation.
+
+ $.value=!$.value}> +
+
+ +
+

Pipeline

+
+
Auto-rerun on edit
+
Restart pipeline when scene/config changes.
+ se.value=!se.value}> +
+
+ +
+

Transport

+
+
Mode
+
+ + +
+
+ ${S.value==="ws"?c` +
+
WS URL
+ xe.value=e.target.value} /> +
`:""} +
+
+ `}};ge.styles=m` + :host { + position: fixed; top: 0; right: 0; bottom: 0; + width: 420px; max-width: 100vw; + background: var(--bg-1); + border-left: 1px solid var(--line); + z-index: 51; + transform: translateX(100%); + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + display: flex; flex-direction: column; + box-shadow: -20px 0 60px -20px rgba(0,0,0,0.5); + } + :host([open]) { transform: translateX(0); } + .scrim { + position: fixed; inset: 0; + background: rgba(0,0,0,0.5); + z-index: 50; + opacity: 0; pointer-events: none; + transition: opacity 0.2s; + } + :host([open]) .scrim { opacity: 1; pointer-events: auto; } + .h { + padding: 14px 16px; + border-bottom: 1px solid var(--line); + display: flex; align-items: center; justify-content: space-between; + } + .h .ttl { font-size: 14px; font-weight: 600; } + .body { flex: 1; overflow-y: auto; padding: 16px; } + .group { margin-bottom: 22px; } + .group h4 { + margin: 0 0 10px; + font-size: 11px; font-weight: 600; + text-transform: uppercase; letter-spacing: 0.08em; + color: var(--ink-3); + } + .row { + display: flex; justify-content: space-between; align-items: center; + padding: 10px 0; + border-bottom: 1px solid var(--line); + } + .row:last-child { border-bottom: 0; } + .row .lbl { font-size: 13px; } + .row .desc { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; } + .row > div:first-child { flex: 1; padding-right: 12px; } + .seg { + display: inline-flex; + background: var(--bg-3); + border: 1px solid var(--line); + border-radius: var(--radius-sm); + padding: 2px; + } + .seg button { + padding: 4px 10px; + background: transparent; border: none; + border-radius: 6px; + font-size: 11.5px; color: var(--ink-3); + font-family: var(--mono); + cursor: pointer; + } + .seg button.on { background: var(--bg-1); color: var(--ink); } + .toggle { + position: relative; + width: 36px; height: 20px; + background: var(--bg-3); + border: 1px solid var(--line-2); + border-radius: 999px; + cursor: pointer; + flex-shrink: 0; + } + .toggle::after { + content: ''; position: absolute; + top: 2px; left: 2px; + width: 14px; height: 14px; + background: var(--ink-3); + border-radius: 50%; + transition: transform 0.15s, background 0.15s; + } + .toggle.on { background: var(--accent); border-color: var(--accent); } + .toggle.on::after { background: #1a0f00; transform: translateX(16px); } + .close { + width: 28px; height: 28px; + background: transparent; border: 1px solid var(--line); + border-radius: 6px; + color: var(--ink-2); + } + input[type="text"] { + background: var(--bg-3); + border: 1px solid var(--line); + border-radius: 6px; + padding: 6px 10px; + color: var(--ink); font-family: var(--mono); font-size: 12px; + outline: none; + } + `;je([u()],ge.prototype,"open",2);ge=je([h("nv-settings-drawer")],ge);var Dt=Object.defineProperty,It=Object.getOwnPropertyDescriptor,Te=(e,t,s,r)=>{for(var a=r>1?void 0:r?It(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=(r?n(t,s,a):n(a))||a);return r&&a&&Dt(t,s,a),a};const ie=[{title:"Welcome to nvsim",body:`

nvsim is an open-source, deterministic forward simulator for + nitrogen-vacancy diamond magnetometry — a real Rust crate compiled to + WASM and running in your browser, right now.

+

This 30-second tour highlights the four panels you'll use most.

`,cta:"Start tour"},{title:"1. Scene canvas",body:`

The middle panel shows your magnetic scene — sources you can + drag (rebar, heart proxy, mains hum, ferrous door) and a single NV-diamond + sensor in the centre. Field lines from each source connect to the sensor + and animate while the pipeline runs.

+

Click 2 on your keyboard any time to jump to the Frame inspector.

`},{title:"2. Run the pipeline",body:`

Click the ▶ Run button (top-right) to start streaming + MagFrame records at the digitiser's sample rate. The B-vector + trace and Frame stream sparkline update live, and the FPS pill in the + topbar shows the simulator's throughput in kHz.

+

Space toggles run/pause from anywhere.

`},{title:"3. Witness panel",body:`

The Witness tab is the heart of nvsim's determinism contract. + Click Verify and the pipeline re-derives the SHA-256 over a 256-frame + reference run and asserts it matches the constant pinned in the Rust crate.

+

Same input → same hash → byte-for-byte across browsers, OSes, transports. + If the hash drifts, your build is non-canonical.

`},{title:"4. App Store",body:`

The grid icon on the left rail opens the App Store — every + hot-loadable WASM edge module RuView ships, plus the simulators. 66 apps + across 13 categories: medical, security, building, retail, industrial, + signal, learning, autonomy, and more.

+

Toggle any card to mark it active in this session; the WS transport + will push the activation set to a connected ESP32 mesh.

`},{title:"You are ready",body:`

Press ⌘K (or Ctrl K) any time for the command + palette, ? for the full shortcuts list, or just start clicking.

+

Source on GitHub: + github.com/ruvnet/RuView · ADR-089, ADR-092 · MIT/Apache-2.0.

`,cta:"Get started"}];let X=class extends b{constructor(){super(...arguments),this.open=!1,this.step=0,this.show=()=>{this.step=0,this.open=!0,this.setAttribute("open","")}}async connectedCallback(){super.connectedCallback(),window.addEventListener("nv-show-tour",this.show),await q("onboarding-seen")||(this.open=!0,this.setAttribute("open",""))}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener("nv-show-tour",this.show)}async dismiss(){this.open=!1,this.removeAttribute("open"),await G("onboarding-seen",!0)}next(){this.step0&&this.step--}render(){const e=ie[this.step];return c` + + `}};X.styles=m` + :host { + position: fixed; inset: 0; + background: rgba(0, 0, 0, 0.55); + backdrop-filter: blur(4px); + z-index: 240; + display: grid; place-items: center; + opacity: 0; pointer-events: none; + transition: opacity 0.18s; + } + :host([open]) { opacity: 1; pointer-events: auto; } + .card { + background: var(--bg-1); + border: 1px solid var(--line-2); + border-radius: var(--radius); + box-shadow: 0 30px 80px -20px rgba(0,0,0,0.7); + width: min(560px, 92vw); + max-height: 86vh; + display: flex; flex-direction: column; + transform: translateY(12px) scale(0.98); + transition: transform 0.22s cubic-bezier(0.2,0.7,0.3,1); + } + :host([open]) .card { transform: translateY(0) scale(1); } + .h { + padding: 20px 22px 8px; + display: flex; justify-content: space-between; align-items: flex-start; + } + .h h2 { margin: 0; font-size: 18px; letter-spacing: -0.01em; } + .body { + padding: 8px 22px 16px; + font-size: 13px; color: var(--ink-2); line-height: 1.55; + overflow-y: auto; + } + .body p { margin: 0 0 12px; } + .body code, .body kbd { + font-family: var(--mono); font-size: 11.5px; + padding: 1px 5px; background: var(--bg-3); + border: 1px solid var(--line); border-radius: 4px; + color: var(--accent); + } + .footer { + display: flex; align-items: center; gap: 12px; + padding: 12px 22px; + border-top: 1px solid var(--line); + } + .dots { display: flex; gap: 6px; flex: 1; } + .dot { + width: 6px; height: 6px; border-radius: 50%; + background: var(--bg-3); border: 1px solid var(--line-2); + } + .dot.active { background: var(--accent); border-color: var(--accent); } + button { + padding: 8px 14px; + border-radius: 8px; + font-size: 12.5px; font-weight: 500; + border: 1px solid var(--line); + background: var(--bg-2); color: var(--ink); + cursor: pointer; + font-family: inherit; + } + button.primary { + background: var(--accent); border-color: var(--accent); + color: #1a0f00; + } + button.ghost { background: transparent; } + .skip { + width: 28px; height: 28px; + background: transparent; border: 1px solid var(--line); + border-radius: 6px; color: var(--ink-2); + } + `;Te([u()],X.prototype,"open",2);Te([u()],X.prototype,"step",2);X=Te([h("nv-onboarding")],X);var Ht=Object.getOwnPropertyDescriptor,Lt=(e,t,s,r)=>{for(var a=r>1?void 0:r?Ht(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=n(a)||a);return a};let Pe=class extends b{render(){return c` +

Ghost Murmur — open-source reality check

+
+ The physics-vs-press audit for the publicly-reported April 2026 + CIA NV-diamond heartbeat detector, and how RuView's existing + stack maps onto an honest, civilian version of the same idea. +
+ + + +

What the press reported

+
+
+

The story

+

3 Apr 2026: USAF F-15E pilot "Dude 44 Bravo" goes down in southern Iran during the regional exchange and evades for ~2 days.

+

President Trump publicly suggests detection from 40 miles away on a mountainside at night; CIA Director Ratcliffe says "invisible to the enemy, but not to the CIA."

+
+
+

The named tech

+

"Ghost Murmur" — Lockheed Skunk Works system using NV defects in synthetic diamond + AI to extract a heartbeat from environmental noise.

+

Outlets: Newsweek, Scientific American, Military.com, WION, Open The Magazine, Yahoo, Calcalist + HN thread #47679241.

+
+
+

What physicists said

+

Wikswo (Vanderbilt), Orzel (Union College), Roth (Oakland) — all pushing back hard.

+

"At 1 km, the heartbeat field drops to ~10⁻¹² of its 10 cm value." MCG-only at multi-mile range is not consistent with published physics.

+
+
+ +

Physics reality check

+
+ + + + + + + + + + + +
DistanceCardiac MCG (peak QRS)vs Earth field (~50 µT)
10 cm50 pT10⁹× weaker
1 m50 fT10¹²× weaker
10 m50 aT10¹⁵× weaker
1 km5 × 10⁻²³ T10²⁷× weaker
40 mi (65 km)~10⁻²⁸ T10³³× weaker
+

+ Best published NV-ensemble lab record: 0.9 pT/√Hz [Wolf 2015]. + Best SQUID in a shielded room: ~1 fT/√Hz. To detect a single heartbeat at 10 m + you'd need ~2 billion× more sensitivity than any published ensemble has ever shown, + in a magnetically silent environment. 40 miles is press-release physics. +

+
+ +

RuView's three-tier mesh — what is actually buildable

+
┌──────────────────────────┐ + │ Tier 3 — NV-diamond │ Range: 0.1–2 m (lab) + │ magnetometer ring │ Status: nvsim simulator only + │ (close-confirm) │ Hardware: $$$ (≥$8k DNV-B1) + └──────────┬───────────────┘ + │ + ┌──────────┴───────────────┐ + │ Tier 2 — 60 GHz FMCW │ Range: 1–10 m HR/BR + │ mmWave radar mesh │ Status: shipping (ADR-021) + │ (vital signs, posture) │ Hardware: $15 (MR60BHA2 + ESP32-C6) + └──────────┬───────────────┘ + │ + ┌──────────┴───────────────┐ + │ Tier 1 — WiFi CSI mesh │ Range: 10–30 m through-wall + │ (presence, breathing, │ Status: shipping (ADR-014, ADR-029) + │ pose, intention) │ Hardware: $9 (ESP32-S3 8MB) + └──────────┬───────────────┘ + │ + ▼ + ┌────────────────────────────────┐ + │ RuvSense multistatic fusion │ + │ + cross-viewpoint attention │ + │ + AETHER re-ID embeddings │ + │ + Cramer-Rao gating │ + └────────────────────────────────┘
+ +

Press claim → RuView equivalent

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Press claimRuView equivalent todayCrate / ADRHonest range
NV-diamond magnetometryDeterministic NV pipeline simulatornvsim · ADR-089Simulator only
"AI strips environmental noise"RuvSense multistatic fusion + AETHERsignal/ruvsense/ · ADR-029Mature
Heartbeat at distance60 GHz FMCW HR/BR + WiFi CSI breathingvitals · ADR-0211–5 m HR · 10–30 m presence
Long-range localisationMultistatic time-of-flight + CRLBruvector/viewpoint/Limited by node spacing
40-mile single-heartbeat detectionNot feasible at any tierPress-release physics
+
+ +

Build today on $165

+
+
+

Bill of materials

+

+ 3 × ESP32-S3 8 MB ($9 ea)
+ 3 × PoE injector + cat6 ($6 ea)
+ 1 × ESP32-C6 + Seeed MR60BHA2 ($15)
+ 1 × Raspberry Pi 5 8 GB ($80)
+ 1 × unmanaged GbE switch ($25) +

+

Total: $165

+
+
+

Honest performance

+ 95%TPR (LOS, 0–15 m)

+ ±2 bpmHR (LOS 0–3 m)

+ ±1 br/minBR (any mode)

+ ~10 cmpose error

+ 80–150 msend-to-end latency +
+
+

Determinism

+

Same (scene, config, seed) → byte-identical SHA-256 witness across browsers, OSes, transports.

+

Reference: cc8de9b01b0ff5bd…

+

Try the Witness tab on the right — it re-derives the hash live in this browser and compares against the published reference.

+
+
+ +

Privacy, ethics, legal

+
+

This is the open-source version. Same physics, opposite governance.

+
    +
  • Civilian opt-in only — search-and-rescue, elder-care, occupancy, ICU vitals. Not surveillance.
  • +
  • No directional pursuit — no beam-steering, target-following, or remote person-of-interest tracking.
  • +
  • Data minimisation — fused output is (presence, HR, BR, pose, p_alive); raw streams discarded at the edge.
  • +
  • PII gates (ADR-040) block identifying biometric streams from leaving the local mesh without consent.
  • +
  • Adversarial-signal detection flags physically-impossible signal patterns from compromised mesh nodes.
  • +
  • No export-controlled hardware — RuView targets < $50 COTS. ITAR/EAR sub-THz coherent radars and shielded NV ensembles are out of scope.
  • +
+

+ RuView is not affiliated with the United States government, the CIA, Lockheed Martin, + or any classified program. References to "Ghost Murmur" in this view refer + exclusively to the publicly-reported program of that name as covered in the open + press in April 2026. +

+
+ +

Cross-references

+
+

+ ADRs: 014 (signal) · 021 (vitals) · 024 (AETHER) · 027 (MERIDIAN) · + 028 (witness audit) · 029 (RuvSense) · 040 (PII gates) · 086 (ESP32 RaBitQ) · + 089 (nvsim, Accepted) · 090 (Lindblad, Proposed-conditional) · + 091 (sub-THz radar research) · 092 (this dashboard).

+ Primary physics: Cohen 1970 · Bison 2009 · Wolf 2015 · Barry RMP 2020 · Doherty 2013 · Jackson 3e §5.6/§5.8. +

+
+ `}};Pe.styles=m` + :host { + display: block; + height: 100%; + overflow-y: auto; + background: radial-gradient(ellipse at 50% 30%, var(--bg-2) 0%, var(--bg-0) 70%); + padding: 24px 28px 60px; + } + h1 { + margin: 0 0 4px; + font-size: 22px; + letter-spacing: -0.02em; + color: var(--ink); + } + .subtitle { + color: var(--ink-3); + font-size: 13px; + margin-bottom: 22px; + } + .links { + display: flex; flex-wrap: wrap; gap: 6px; + margin-bottom: 22px; + } + .links a { + padding: 5px 10px; + background: var(--bg-2); + border: 1px solid var(--line); + border-radius: 999px; + font-size: 11.5px; + font-family: var(--mono); + color: var(--accent-2); + text-decoration: none; + } + .links a:hover { border-color: var(--accent-2); } + h2 { + font-size: 14px; + font-weight: 600; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--ink-3); + margin: 28px 0 10px; + } + .grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 12px; + } + .card { + background: var(--bg-2); + border: 1px solid var(--line); + border-radius: var(--radius); + padding: 14px; + } + .card h3 { + margin: 0 0 8px; + font-size: 13.5px; font-weight: 600; + color: var(--ink); + } + .card p { + font-size: 12.5px; color: var(--ink-2); + margin: 0 0 8px; + line-height: 1.5; + } + .card p:last-child { margin-bottom: 0; } + .stat { + display: inline-flex; align-items: baseline; gap: 6px; + margin-right: 10px; + } + .stat .v { + font-family: var(--mono); font-size: 16px; font-weight: 600; + color: var(--accent); + } + .stat .l { + font-size: 10px; color: var(--ink-3); + text-transform: uppercase; letter-spacing: 0.04em; + } + table { + width: 100%; border-collapse: collapse; + font-size: 12.5px; + } + th, td { + padding: 8px 10px; + text-align: left; + border-bottom: 1px solid var(--line); + } + th { + color: var(--ink-3); + font-weight: 600; + font-size: 11px; + text-transform: uppercase; + letter-spacing: 0.06em; + } + td.amber { color: var(--accent); font-family: var(--mono); } + td.cyan { color: var(--accent-2); font-family: var(--mono); } + td.bad { color: var(--bad); font-family: var(--mono); } + .pill { + display: inline-block; + padding: 1px 6px; + border-radius: 4px; + font-family: var(--mono); + font-size: 10px; + border: 1px solid var(--line); + } + .pill.ok { color: var(--ok); border-color: oklch(0.78 0.14 145 / 0.4); } + .pill.skeptical { color: var(--bad); border-color: oklch(0.65 0.22 25 / 0.4); } + .pill.partial { color: var(--warn); border-color: oklch(0.7 0.18 35 / 0.4); } + .architecture { + font-family: var(--mono); + font-size: 11px; + color: var(--ink-2); + background: var(--bg-3); + padding: 16px; + border-radius: var(--radius-sm); + border: 1px solid var(--line); + white-space: pre; + overflow-x: auto; + line-height: 1.4; + } + .ethics { + background: linear-gradient(180deg, var(--bg-2) 0%, oklch(0.65 0.22 25 / 0.04) 100%); + border: 1px solid oklch(0.65 0.22 25 / 0.25); + border-radius: var(--radius); + padding: 16px; + } + .ethics h3 { color: var(--bad); margin-top: 0; } + .ethics ul { padding-left: 18px; margin: 8px 0; } + .ethics li { font-size: 12.5px; color: var(--ink-2); margin-bottom: 4px; } + `;Pe=Lt([h("nv-ghost-murmur")],Pe);var Ft=Object.defineProperty,Bt=Object.getOwnPropertyDescriptor,Ve=(e,t,s,r)=>{for(var a=r>1?void 0:r?Bt(t,s):t,i=e.length-1,n;i>=0;i--)(n=e[i])&&(a=(r?n(t,s,a):n(a))||a);return r&&a&&Ft(t,s,a),a};let me=class extends b{constructor(){super(...arguments),this.view="scene"}render(){return c` +
+ this.view=e.detail}> + + +
+ ${this.view==="apps"?c``:this.view==="ghost-murmur"?c``:c``} +
+ + + +
+ + + + + + + `}};me.styles=m` + :host { + display: block; + height: 100vh; + width: 100vw; + background: var(--bg-0); + } + .app { + display: grid; + grid-template-columns: 56px 280px 1fr 340px; + grid-template-rows: 48px 1fr 220px; + grid-template-areas: + 'rail topbar topbar topbar' + 'rail sidebar main inspector' + 'rail sidebar console inspector'; + height: 100vh; + width: 100vw; + } + nv-rail { grid-area: rail; } + nv-topbar { grid-area: topbar; } + nv-sidebar { grid-area: sidebar; } + .main { grid-area: main; min-width: 0; min-height: 0; position: relative; overflow: hidden; } + nv-inspector { grid-area: inspector; } + nv-console { grid-area: console; min-height: 0; } + @media (max-width: 1180px) { + .app { + grid-template-columns: 56px 1fr 320px; + grid-template-areas: + 'rail topbar topbar' + 'rail main inspector' + 'rail console console'; + } + nv-sidebar { display: none; } + } + @media (max-width: 860px) { + .app { + grid-template-columns: 1fr; + grid-template-rows: 52px 1fr 200px; + grid-template-areas: + 'topbar' + 'main' + 'console'; + } + nv-rail, nv-sidebar, nv-inspector { display: none; } + } + `;Ve([u()],me.prototype,"view",2);me=Ve([h("nv-app")],me);function Nt(e,t,s){const r=e.getUint32(t+0,!0),a=e.getUint16(t+4,!0),i=e.getUint16(t+6,!0),n=e.getUint16(t+8,!0),d=e.getBigUint64(t+12,!0),p=e.getFloat32(t+20,!0),R=e.getFloat32(t+24,!0),fe=e.getFloat32(t+28,!0),ye=e.getFloat32(t+32,!0),Ue=e.getFloat32(t+36,!0),qe=e.getFloat32(t+40,!0),Ge=e.getFloat32(t+44,!0),Ke=e.getFloat32(t+48,!0);return{magic:r,version:a,flags:i,sensorId:n,tUs:d,bPt:[p,R,fe],sigmaPt:[ye,Ue,qe],noiseFloorPtSqrtHz:Ge,temperatureK:Ke,raw:s.subarray(t,t+60)}}function Wt(e){const s=new DataView(e.buffer,e.byteOffset,e.byteLength),r=[];for(let a=0;a+60<=e.byteLength;a+=60)r.push(Nt(s,a,e));return r}class jt{constructor(){this.nextId=1,this.pending=new Map,this.frameSubs=new Set,this.eventSubs=new Set,this.bootInfo=null,this.worker=new Worker(new URL("/RuView/nvsim/assets/worker-BW0kLvYS.js",import.meta.url),{type:"module"}),this.worker.addEventListener("message",t=>this.onMessage(t)),this.worker.addEventListener("error",t=>this.eventSubs.forEach(s=>s({type:"log",level:"err",msg:String(t.message)})))}onMessage(t){const s=t.data;if(s.type==="frames"){const r=s.batch,a=new Uint8Array(r),n={frames:Wt(a),bytes:a};this.frameSubs.forEach(p=>p(n));const d=s.fps;d>0&&this.eventSubs.forEach(p=>p({type:"fps",value:d}));return}if(s.type==="state"){this.eventSubs.forEach(r=>r({type:"state",running:!!s.running,t:0,framesEmitted:Number(s.framesEmitted??0)}));return}if(s.type!=="ready"){if(s.type==="err"&&s.id==null){this.eventSubs.forEach(r=>r({type:"log",level:"err",msg:String(s.msg)}));return}if(typeof s.id=="number"&&this.pending.has(s.id)){const r=this.pending.get(s.id);this.pending.delete(s.id),s.type==="err"?r.reject(new Error(String(s.msg))):r.resolve(s)}}}rpc(t,s=[]){const r=this.nextId++;return new Promise((a,i)=>{this.pending.set(r,{resolve:a,reject:i}),this.worker.postMessage({...t,id:r},s)})}async boot(){if(this.bootInfo)return this.bootInfo;const s=await this.rpc({type:"boot",base:"/RuView/nvsim/"});return this.bootInfo={buildVersion:s.buildVersion,frameMagic:s.frameMagic,frameBytes:s.frameBytes,expectedWitnessHex:s.expectedWitnessHex},this.bootInfo}async loadScene(t){await this.rpc({type:"setScene",json:JSON.stringify(t)})}async setConfig(t){await this.rpc({type:"setConfig",json:JSON.stringify(t)})}async setSeed(t){await this.rpc({type:"setSeed",seed:Number(t&0xFFFFFFFFn)})}async reset(){await this.rpc({type:"reset"})}async run(t){await this.rpc({type:"run"})}async pause(){await this.rpc({type:"pause"})}async step(t,s){await this.rpc({type:"step"})}onFrames(t){this.frameSubs.add(t)}onEvent(t){this.eventSubs.add(t)}async generateWitness(t){const s=await this.rpc({type:"witnessGenerate",samples:t});return new Uint8Array(s.witness)}async verifyWitness(t){const s=t.slice().buffer,r=await this.rpc({type:"witnessVerify",samples:256,expected:s},[s]);return r.ok?{ok:!0}:{ok:!1,actual:new Uint8Array(r.actual)}}async exportProofBundle(){const t=await this.generateWitness(256),s=Array.from(t).map(i=>i.toString(16).padStart(2,"0")).join(""),r=this.bootInfo??await this.boot(),a=JSON.stringify({kind:"nvsim-proof-bundle",version:r.buildVersion,seed:"0x0000002A",nSamples:256,witness:s,expected:r.expectedWitnessHex,ok:s===r.expectedWitnessHex,ts:new Date().toISOString()},null,2);return new Blob([a],{type:"application/json"})}async buildId(){return(await this.rpc({type:"buildId"})).buildId}async close(){this.worker.terminate()}}function Oe(e){document.documentElement.setAttribute("data-theme",e)}function De(e){document.body.classList.remove("density-comfy","density-default","density-compact"),document.body.classList.add(`density-${e}`)}function Ie(e){document.body.classList.toggle("reduce-motion",e)}(async()=>{const e=await q("theme")??"dark",t=await q("density")??"default",s=await q("motionReduced")??!1;g.value=e,Oe(e),w.value=t,De(t),$.value=s,Ie(s),y(()=>{Oe(g.value),G("theme",g.value)}),y(()=>{De(w.value),G("density",w.value)}),y(()=>{Ie($.value),G("motionReduced",$.value)});const r=new jt;it(r),l("info","nvsim — booting WASM runtime"),r.onEvent(a=>{a.type==="log"&&l(a.level,a.msg),a.type==="fps"&&(k.value=a.value),a.type==="state"&&($e.value=BigInt(a.framesEmitted))}),r.onFrames(a=>{if(a.frames.length===0)return;const i=a.frames[a.frames.length-1];Se.value=i;const n=i.bPt[0]*1e-12,d=i.bPt[1]*1e-12,p=i.bPt[2]*1e-12;oe.value=[n,d,p],O.value=Math.sqrt(n*n+d*d+p*p),ot([n*1e9,d*1e9,p*1e9]);const R=Math.min(1,Math.abs(p*1e9)/5+.3);lt(R)});try{const a=await r.boot();D.value=a.expectedWitnessHex,l("ok",`WASM module ready · nvsim@${a.buildVersion} · magic=0x${a.frameMagic.toString(16).toUpperCase()}`),l("info",`expected witness · ${a.expectedWitnessHex.slice(0,16)}…`),rt.value="(reference scene)",S.value="wasm"}catch(a){l("err",`boot failed: ${a.message}`)}try{const a=D.value;if(a){const i=new Uint8Array(32);for(let d=0;d<32;d++)i[d]=parseInt(a.slice(d*2,d*2+2),16);const n=await r.verifyWitness(i);if(n.ok)C.value=a,l("ok","witness verified · determinism gate ✓");else{const d=Array.from(n.actual).map(p=>p.toString(16).padStart(2,"0")).join("");C.value=d,l("err",`WITNESS MISMATCH · expected ${a.slice(0,16)}… got ${d.slice(0,16)}…`)}}}catch(a){l("warn",`witness verify skipped: ${a.message}`)}})(); +//# sourceMappingURL=index-BWlL4FHH.js.map diff --git a/nvsim/assets/index-BWlL4FHH.js.map b/nvsim/assets/index-BWlL4FHH.js.map new file mode 100644 index 00000000..dbc2b49b --- /dev/null +++ b/nvsim/assets/index-BWlL4FHH.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index-BWlL4FHH.js","sources":["../../node_modules/@lit/reactive-element/decorators/custom-element.js","../../node_modules/@lit/reactive-element/decorators/property.js","../../node_modules/@lit/reactive-element/decorators/state.js","../../node_modules/@lit/reactive-element/decorators/base.js","../../node_modules/@lit/reactive-element/decorators/query.js","../../src/components/nv-rail.ts","../../src/store/appStore.ts","../../src/components/nv-topbar.ts","../../src/components/nv-sidebar.ts","../../src/components/nv-scene.ts","../../src/components/nv-inspector.ts","../../src/components/nv-console.ts","../../src/store/apps.ts","../../src/store/persistence.ts","../../src/components/nv-app-store.ts","../../src/components/nv-toast.ts","../../src/components/nv-modal.ts","../../src/components/nv-palette.ts","../../src/components/nv-debug-hud.ts","../../src/components/nv-settings-drawer.ts","../../src/components/nv-onboarding.ts","../../src/components/nv-ghost-murmur.ts","../../src/components/nv-app.ts","../../src/transport/NvsimClient.ts","../../src/transport/WasmClient.ts","../../src/main.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t=t=>(e,o)=>{void 0!==o?o.addInitializer(()=>{customElements.define(t,e)}):customElements.define(t,e)};export{t as customElement};\n//# sourceMappingURL=custom-element.js.map\n","import{notEqual as t,defaultConverter as e}from\"../reactive-element.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const o={attribute:!0,type:String,converter:e,reflect:!1,hasChanged:t},r=(t=o,e,r)=>{const{kind:n,metadata:i}=r;let s=globalThis.litPropertyMetadata.get(i);if(void 0===s&&globalThis.litPropertyMetadata.set(i,s=new Map),\"setter\"===n&&((t=Object.create(t)).wrapped=!0),s.set(r.name,t),\"accessor\"===n){const{name:o}=r;return{set(r){const n=e.get.call(this);e.set.call(this,r),this.requestUpdate(o,n,t,!0,r)},init(e){return void 0!==e&&this.C(o,void 0,t,e),e}}}if(\"setter\"===n){const{name:o}=r;return function(r){const n=this[o];e.call(this,r),this.requestUpdate(o,n,t,!0,r)}}throw Error(\"Unsupported decorator location: \"+n)};function n(t){return(e,o)=>\"object\"==typeof o?r(t,e,o):((t,e,o)=>{const r=e.hasOwnProperty(o);return e.constructor.createProperty(o,t),r?Object.getOwnPropertyDescriptor(e,o):void 0})(t,e,o)}export{n as property,r as standardProperty};\n//# sourceMappingURL=property.js.map\n","import{property as t}from\"./property.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */function r(r){return t({...r,state:!0,attribute:!1})}export{r as state};\n//# sourceMappingURL=state.js.map\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst e=(e,t,c)=>(c.configurable=!0,c.enumerable=!0,Reflect.decorate&&\"object\"!=typeof t&&Object.defineProperty(e,t,c),c);export{e as desc};\n//# sourceMappingURL=base.js.map\n","import{desc as t}from\"./base.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */function e(e,r){return(n,s,i)=>{const o=t=>t.renderRoot?.querySelector(e)??null;if(r){const{get:e,set:r}=\"object\"==typeof s?n:i??(()=>{const t=Symbol();return{get(){return this[t]},set(e){this[t]=e}}})();return t(n,s,{get(){let t=e.call(this);return void 0===t&&(t=o(this),(null!==t||this.hasUpdated)&&r.call(this,t)),t}})}return t(n,s,{get(){return o(this)}})}}export{e as query};\n//# sourceMappingURL=query.js.map\n","/* Left rail navigation. Emits `navigate` events for view switching. */\nimport { LitElement, html, css } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport type { View } from './nv-app';\n\n@customElement('nv-rail')\nexport class NvRail extends LitElement {\n @property() view: View = 'scene';\n\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n align-items: center;\n padding: 10px 0;\n gap: 4px;\n background: var(--bg-1);\n border-right: 1px solid var(--line);\n }\n .logo {\n width: 36px; height: 36px;\n border-radius: 10px;\n background: linear-gradient(135deg, oklch(0.78 0.14 70) 0%, oklch(0.55 0.16 30) 100%);\n display: grid; place-items: center;\n color: #1a0f00;\n font-weight: 700;\n font-family: var(--mono);\n font-size: 11px;\n margin-bottom: 14px;\n box-shadow: 0 4px 12px -2px oklch(0.55 0.16 30 / 0.35);\n }\n .btn {\n width: 36px; height: 36px;\n border-radius: 8px;\n background: transparent;\n border: 1px solid transparent;\n color: var(--ink-3);\n display: grid; place-items: center;\n transition: all 0.15s;\n position: relative;\n cursor: pointer;\n }\n .btn:hover { color: var(--ink); background: var(--bg-2); }\n .btn.active {\n color: var(--ink);\n background: var(--bg-3);\n border-color: var(--line-2);\n }\n .btn.active::before {\n content: ''; position: absolute; left: -10px; top: 8px; bottom: 8px;\n width: 2px; background: var(--accent); border-radius: 2px;\n }\n .btn.ghost.active::before { background: var(--accent-3); }\n .spacer { flex: 1; }\n svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; }\n `;\n\n private navigate(v: View): void {\n this.dispatchEvent(new CustomEvent('navigate', { detail: v }));\n }\n\n override render() {\n return html`\n
NV
\n \n \n \n \n \n
\n \n `;\n }\n}\n","/* Application-wide reactive state.\n *\n * One signal per logical observable; components subscribe to only the\n * signals they read. Keeps re-renders surgical even at 1 kHz frame rates.\n * Persistence lives in `persistence.ts`; this module is pure state.\n */\nimport { signal, computed } from '@preact/signals-core';\nimport type { NvsimClient, MagFrameRecord, NvsimEvent } from '../transport/NvsimClient';\n\nexport type Theme = 'dark' | 'light';\nexport type Density = 'comfy' | 'default' | 'compact';\nexport type TransportMode = 'wasm' | 'ws';\n\nexport const transport = signal('wasm');\nexport const wsUrl = signal('');\nexport const connected = signal(false);\nexport const transportError = signal(null);\n\nexport const running = signal(false);\nexport const paused = signal(true);\nexport const speed = signal(1.0);\nexport const t = signal(0); // sim time (s)\nexport const framesEmitted = signal(0n);\n\nexport const seed = signal(0xCAFEBABEn);\n\nexport const fs = signal(10000); // sample rate Hz\nexport const fmod = signal(1000); // lockin Hz\nexport const dtMs = signal(1.0);\nexport const noiseEnabled = signal(true);\n\nexport const theme = signal('dark');\nexport const density = signal('default');\nexport const motionReduced = signal(false);\nexport const autoUpdate = signal(true);\n\nexport const lastB = signal<[number, number, number]>([0, 0, 0]); // T\nexport const bMag = signal(0);\nexport const snr = signal(0);\nexport const fps = signal(0);\n\nexport const witnessHex = signal('');\nexport const witnessVerified = signal<'pending' | 'ok' | 'fail' | 'idle'>('idle');\nexport const expectedWitness = signal('');\n\nexport const lastFrame = signal(null);\nexport const traceX = signal([]);\nexport const traceY = signal([]);\nexport const traceZ = signal([]);\nexport const stripBars = signal([]);\n\nexport const sceneName = signal('rebar-walkby-01');\nexport const sceneJson = signal('');\n\nexport const consolePaused = signal(false);\nexport const consoleFilter = signal<'all' | 'info' | 'warn' | 'err' | 'dbg' | 'ok'>('all');\n\nexport const transportLabel = computed(() =>\n transport.value === 'wasm' ? 'wasm' : 'ws',\n);\n\nlet _client: NvsimClient | null = null;\nexport function setClient(c: NvsimClient): void { _client = c; }\nexport function getClient(): NvsimClient | null { return _client; }\n\nexport interface ConsoleLine {\n ts: number;\n level: 'info' | 'warn' | 'err' | 'dbg' | 'ok';\n msg: string;\n}\nexport const consoleLines = signal([]);\nconst MAX_LINES = 200;\n\nexport function pushLog(level: ConsoleLine['level'], msg: string): void {\n if (consolePaused.value) return;\n const next = consoleLines.value.slice();\n next.push({ ts: Date.now(), level, msg });\n while (next.length > MAX_LINES) next.shift();\n consoleLines.value = next;\n}\n\nexport function pushTrace(b: [number, number, number]): void {\n const cap = 200;\n const x = traceX.value.slice(); x.push(b[0]); if (x.length > cap) x.shift();\n const y = traceY.value.slice(); y.push(b[1]); if (y.length > cap) y.shift();\n const z = traceZ.value.slice(); z.push(b[2]); if (z.length > cap) z.shift();\n traceX.value = x;\n traceY.value = y;\n traceZ.value = z;\n}\n\nexport function pushStripBar(amp: number): void {\n const cap = 48;\n const next = stripBars.value.slice();\n next.push(Math.max(0, Math.min(1, amp)));\n while (next.length > cap) next.shift();\n stripBars.value = next;\n}\n\nexport function recordEvent(_ev: NvsimEvent): void {\n // future: route NvsimEvent into store updates per type. For V1 the\n // worker pushes B-vector / frame data directly via the data plane.\n}\n","/* Topbar — breadcrumbs, transport pill, FPS pill, seed pill, controls. */\nimport { LitElement, html, css } from 'lit';\nimport { customElement } from 'lit/decorators.js';\nimport { effect } from '@preact/signals-core';\nimport {\n fps, transportLabel, seed, theme, sceneName,\n running, getClient,\n} from '../store/appStore';\n\n@customElement('nv-topbar')\nexport class NvTopbar extends LitElement {\n static styles = css`\n :host {\n display: flex; align-items: center;\n padding: 0 16px; gap: 12px;\n background: var(--bg-1);\n border-bottom: 1px solid var(--line);\n z-index: 10;\n }\n .crumbs { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ink-3); }\n .crumbs .sep { color: var(--ink-4); }\n .crumbs .cur { color: var(--ink); font-weight: 500; }\n .spacer { flex: 1; }\n .pill {\n display: inline-flex; align-items: center; gap: 6px;\n padding: 5px 10px;\n background: var(--bg-2); border: 1px solid var(--line);\n border-radius: 999px;\n font-size: 12px; color: var(--ink-2);\n font-family: var(--mono); font-weight: 500;\n }\n .pill .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 6px var(--ok); animation: pulse 2s infinite; }\n .pill.wasm .dot { background: var(--accent-2); box-shadow: 0 0 6px var(--accent-2); }\n .pill.seed { color: var(--ink-3); }\n .pill.seed b { color: var(--accent); font-weight: 600; }\n button {\n display: inline-flex; align-items: center; gap: 6px;\n padding: 6px 12px;\n background: var(--bg-2); border: 1px solid var(--line);\n border-radius: 8px;\n font-size: 12.5px; font-weight: 500; color: var(--ink);\n cursor: pointer;\n transition: all 0.15s;\n }\n button:hover { border-color: var(--line-2); background: var(--bg-3); }\n button.primary { background: var(--accent); border-color: var(--accent); color: #1a0f00; }\n button.primary:hover { filter: brightness(1.08); }\n button.ghost { background: transparent; }\n `;\n\n override connectedCallback(): void {\n super.connectedCallback();\n effect(() => { fps.value; transportLabel.value; seed.value; theme.value; sceneName.value; running.value; this.requestUpdate(); });\n }\n\n private async toggleRun(): Promise {\n const c = getClient(); if (!c) return;\n if (running.value) { await c.pause(); running.value = false; }\n else { await c.run(); running.value = true; }\n }\n private async reset(): Promise {\n const c = getClient(); if (!c) return;\n await c.reset();\n }\n private toggleTheme(): void {\n theme.value = theme.value === 'dark' ? 'light' : 'dark';\n }\n\n override render() {\n const seedHex = seed.value.toString(16).toUpperCase().padStart(8, '0');\n return html`\n
\n RuView/\n nvsim/\n ${sceneName.value}\n
\n
\n \n \n ${fps.value > 0 ? (fps.value / 1000).toFixed(2) + ' kHz' : 'idle'}\n \n ${transportLabel.value}\n seed: 0x${seedHex}\n \n \n \n `;\n }\n}\n","/* Sidebar — Scene panel, NV sensor panel, Tunables, Pipeline diagram. */\nimport { LitElement, html, css } from 'lit';\nimport { customElement } from 'lit/decorators.js';\nimport { effect } from '@preact/signals-core';\nimport { fs, fmod, dtMs, noiseEnabled, running } from '../store/appStore';\n\n@customElement('nv-sidebar')\nexport class NvSidebar extends LitElement {\n static styles = css`\n :host {\n display: flex; flex-direction: column; gap: 14px;\n padding: 14px; overflow-y: auto;\n background: var(--bg-1); border-right: 1px solid var(--line);\n }\n .panel {\n background: var(--bg-2); border: 1px solid var(--line);\n border-radius: var(--radius); padding: 12px;\n }\n .panel-h {\n display: flex; align-items: center; justify-content: space-between;\n font-size: 11px; font-weight: 600; color: var(--ink-3);\n text-transform: uppercase; letter-spacing: 0.08em;\n margin-bottom: 10px;\n }\n .count {\n background: var(--bg-3); color: var(--ink-2);\n padding: 1px 6px; border-radius: 999px;\n font-family: var(--mono); font-size: 10px;\n text-transform: none; letter-spacing: 0;\n }\n .scene-item {\n display: flex; align-items: center; gap: 10px;\n padding: 8px 10px;\n border-radius: var(--radius-sm);\n cursor: pointer;\n transition: background 0.15s;\n border: 1px solid transparent;\n }\n .scene-item:hover { background: var(--bg-3); }\n .scene-item .swatch { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }\n .scene-item .name { font-size: 13px; flex: 1; }\n .scene-item .meta { font-family: var(--mono); font-size: 10.5px; color: var(--ink-3); }\n .field-row {\n display: flex; align-items: center; justify-content: space-between;\n padding: 6px 0; font-size: 12.5px;\n border-bottom: 1px solid var(--line);\n }\n .field-row:last-child { border-bottom: 0; }\n .field-row .lbl { color: var(--ink-3); }\n .field-row .val { font-family: var(--mono); color: var(--ink); font-size: 12px; }\n .slider-row { padding: 8px 0; border-bottom: 1px solid var(--line); }\n .slider-row:last-child { border-bottom: 0; padding-bottom: 0; }\n .slider-row .top { display: flex; justify-content: space-between; margin-bottom: 6px; font-size: 12px; }\n .slider-row .top .lbl { color: var(--ink-3); }\n .slider-row .top .val { font-family: var(--mono); color: var(--ink); }\n input[type=\"range\"] {\n -webkit-appearance: none; appearance: none;\n width: 100%; height: 4px;\n background: var(--bg-3); border-radius: 2px; outline: none;\n }\n input[type=\"range\"]::-webkit-slider-thumb {\n -webkit-appearance: none; appearance: none;\n width: 14px; height: 14px; border-radius: 50%;\n background: var(--accent); cursor: pointer;\n border: 2px solid var(--bg-2);\n box-shadow: 0 0 0 1px var(--line-2);\n }\n .pipeline { display: flex; gap: 4px; align-items: center; flex-wrap: wrap; margin-top: 6px; }\n .stage {\n flex: 1; min-width: 50px;\n padding: 4px 6px;\n background: var(--bg-3); border: 1px solid var(--line);\n border-radius: 6px; font-size: 9.5px; text-align: center;\n color: var(--ink-2); font-family: var(--mono);\n }\n .stage.live { border-color: var(--accent-2); color: var(--accent-2); }\n .stage-arrow { color: var(--ink-4); font-size: 10px; }\n `;\n\n override connectedCallback(): void {\n super.connectedCallback();\n effect(() => { fs.value; fmod.value; dtMs.value; noiseEnabled.value; running.value; this.requestUpdate(); });\n }\n\n override render() {\n return html`\n
\n
Scene 4 sources
\n
\n \n rebar.steel.coil\n χ=5000\n
\n
\n \n heart_proxy\n 1e-6 A·m²\n
\n
\n \n mains_60Hz\n 2 A · 60 Hz\n
\n
\n \n door.steel\n eddy\n
\n
\n\n
\n
NV sensor COTS
\n
V1 mm³
\n
N1e12 NV
\n
C0.030
\n
T₂*200 ns
\n
δB1.18 pT/√Hz
\n
\n\n
\n
Tunables
\n
\n
Sample rate${(fs.value / 1000).toFixed(1)} kHz
\n fs.value = +(e.target as HTMLInputElement).value} />\n
\n
\n
Lockin f_mod${(fmod.value / 1000).toFixed(3)} kHz
\n fmod.value = +(e.target as HTMLInputElement).value} />\n
\n
\n
Integration t${dtMs.value.toFixed(1)} ms
\n dtMs.value = +(e.target as HTMLInputElement).value} />\n
\n
\n
Shot noise${noiseEnabled.value ? 'ON' : 'OFF'}
\n noiseEnabled.value = (e.target as HTMLInputElement).value === '1'} />\n
\n
\n\n
\n
Pipeline
\n
\n scene\n \n B-S\n \n prop\n \n NV\n \n ADC\n \n frame\n
\n
\n `;\n }\n}\n","/* Scene canvas — SVG with draggable sources, NV crystal sensor, field lines, mini ODMR. */\nimport { LitElement, html, css, svg } from 'lit';\nimport { customElement, state } from 'lit/decorators.js';\nimport { effect } from '@preact/signals-core';\nimport { lastB, bMag, fps, snr, motionReduced } from '../store/appStore';\n\ninterface SceneItem { id: string; x: number; y: number; color: string; name: string; }\n\n@customElement('nv-scene')\nexport class NvScene extends LitElement {\n @state() private items: SceneItem[] = [\n { id: 'rebar', x: 740, y: 240, color: 'oklch(0.72 0.18 330)', name: 'rebar.steel' },\n { id: 'heart', x: 220, y: 180, color: 'oklch(0.78 0.14 195)', name: 'heart_proxy' },\n { id: 'mains', x: 180, y: 380, color: 'oklch(0.72 0.18 330)', name: 'mains_60Hz' },\n { id: 'door', x: 800, y: 470, color: 'oklch(0.78 0.14 145)', name: 'door.steel' },\n ];\n @state() private dragging: string | null = null;\n @state() private selected: string | null = null;\n private dragOffset = { dx: 0, dy: 0 };\n\n static styles = css`\n :host {\n display: block; height: 100%; width: 100%;\n background: radial-gradient(ellipse at 50% 30%, var(--bg-2) 0%, var(--bg-0) 70%);\n position: relative; overflow: hidden;\n border-bottom: 1px solid var(--line);\n }\n .grid {\n position: absolute; inset: 0;\n background-image:\n linear-gradient(var(--grid) 1px, transparent 1px),\n linear-gradient(90deg, var(--grid) 1px, transparent 1px);\n background-size: 32px 32px;\n pointer-events: none;\n mask-image: radial-gradient(ellipse at center, black 40%, transparent 100%);\n }\n svg { position: absolute; inset: 0; width: 100%; height: 100%; }\n .stat-card {\n background: rgba(13,17,23,0.7);\n backdrop-filter: blur(8px);\n border: 1px solid var(--line);\n border-radius: var(--radius-sm);\n padding: 8px 12px;\n font-size: 11px;\n min-width: 96px;\n }\n [data-theme=\"light\"] .stat-card { background: rgba(255,255,255,0.85); }\n .stat-card .lbl {\n color: var(--ink-3);\n text-transform: uppercase; font-weight: 600; letter-spacing: 0.06em; font-size: 9.5px;\n }\n .stat-card .val { font-family: var(--mono); font-size: 16px; font-weight: 600; margin-top: 2px; }\n .stat-card .val.amber { color: var(--accent); }\n .stat-card .val.cyan { color: var(--accent-2); }\n .stat-card .val.mint { color: var(--accent-4); }\n .scene-readout {\n position: absolute; top: 14px; right: 14px;\n display: flex; gap: 8px; z-index: 5;\n }\n .draggable { cursor: grab; transition: filter 0.15s; }\n .draggable:hover { filter: brightness(1.15) drop-shadow(0 0 6px currentColor); }\n .draggable.dragging { cursor: grabbing; filter: brightness(1.25) drop-shadow(0 0 10px currentColor); }\n .field-line { stroke-dasharray: 4 6; }\n @keyframes dash { to { stroke-dashoffset: -200; } }\n .field-line.anim { animation: dash 4s linear infinite; }\n @keyframes spin {\n 0% { transform: rotateY(0) rotateX(8deg); }\n 100% { transform: rotateY(360deg) rotateX(8deg); }\n }\n .crystal { transform-origin: center; transform-box: fill-box; }\n .crystal.anim { animation: spin 12s linear infinite; }\n .label {\n font-family: var(--mono); font-size: 11px; fill: var(--ink-2);\n pointer-events: none;\n }\n `;\n\n override connectedCallback(): void {\n super.connectedCallback();\n effect(() => { lastB.value; bMag.value; fps.value; snr.value; motionReduced.value; this.requestUpdate(); });\n window.addEventListener('pointermove', this.onPointerMove);\n window.addEventListener('pointerup', this.onPointerUp);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n window.removeEventListener('pointermove', this.onPointerMove);\n window.removeEventListener('pointerup', this.onPointerUp);\n }\n\n private onDown = (id: string, e: PointerEvent): void => {\n e.preventDefault();\n this.dragging = id;\n this.selected = id;\n const item = this.items.find((i) => i.id === id);\n if (!item) return;\n const svgEl = this.renderRoot.querySelector('svg') as SVGSVGElement | null;\n if (!svgEl) return;\n const pt = this.toSvg(e, svgEl);\n this.dragOffset = { dx: pt.x - item.x, dy: pt.y - item.y };\n };\n\n private onPointerMove = (e: PointerEvent): void => {\n if (!this.dragging) return;\n const svgEl = this.renderRoot.querySelector('svg') as SVGSVGElement | null;\n if (!svgEl) return;\n const pt = this.toSvg(e, svgEl);\n this.items = this.items.map((it) =>\n it.id === this.dragging\n ? { ...it, x: pt.x - this.dragOffset.dx, y: pt.y - this.dragOffset.dy }\n : it,\n );\n };\n\n private onPointerUp = (): void => { this.dragging = null; };\n\n private toSvg(e: PointerEvent, svgEl: SVGSVGElement): { x: number; y: number } {\n const r = svgEl.getBoundingClientRect();\n const vbX = ((e.clientX - r.left) / r.width) * 1000;\n const vbY = ((e.clientY - r.top) / r.height) * 600;\n return { x: vbX, y: vbY };\n }\n\n override render() {\n const b = lastB.value;\n const bnT = [b[0] * 1e9, b[1] * 1e9, b[2] * 1e9];\n const bMagNT = bMag.value * 1e9;\n const animClass = motionReduced.value ? '' : 'anim';\n\n return html`\n
\n \n \n \n \n \n \n \n \n\n \n ${this.items.map((it) => svg`\n \n `)}\n\n \n ${this.items.map((it) => svg`\n this.onDown(it.id, e)}>\n \n \n ${it.name}\n \n `)}\n\n \n \n \n \n \n \n \n \n sensor · 〈111〉 NV\n \n \n B_in: [${bnT[0].toFixed(2)}, ${bnT[1].toFixed(2)}, ${bnT[2].toFixed(2)}] nT\n \n \n \n\n
\n
\n
|B|
\n
${bMagNT.toFixed(3)} nT
\n
\n
\n
FPS
\n
${fps.value > 0 ? Math.round(fps.value) : '—'}
\n
\n
\n
SNR
\n
${snr.value > 0 ? snr.value.toFixed(1) : '—'}
\n
\n
\n `;\n }\n}\n","/* Inspector — tabbed: Signal / Frame / Witness. */\nimport { LitElement, html, css, svg, type PropertyValues } from 'lit';\nimport { customElement, state, property } from 'lit/decorators.js';\nimport { effect } from '@preact/signals-core';\nimport {\n traceX, traceY, traceZ, stripBars, lastFrame,\n witnessHex, expectedWitness, witnessVerified, getClient,\n pushLog, lastB, bMag,\n} from '../store/appStore';\n\ntype Tab = 'signal' | 'frame' | 'witness';\n\n@customElement('nv-inspector')\nexport class NvInspector extends LitElement {\n @state() private tab: Tab = 'signal';\n /** When set by the parent, force the tab and pulse-highlight it. */\n @property({ attribute: false }) pinTab: Tab | null = null;\n\n static styles = css`\n :host {\n display: flex; flex-direction: column;\n background: var(--bg-1);\n border-left: 1px solid var(--line);\n overflow: hidden;\n height: 100%;\n }\n .tabs {\n display: flex; border-bottom: 1px solid var(--line);\n }\n .tab {\n flex: 1;\n padding: 11px 8px;\n background: transparent; border: none;\n font-size: 11.5px; font-weight: 500;\n color: var(--ink-3);\n border-bottom: 2px solid transparent;\n cursor: pointer; transition: color 0.15s, border-color 0.15s;\n }\n .tab.active { color: var(--ink); border-bottom-color: var(--accent); }\n .tab:hover { color: var(--ink-2); }\n .body { padding: 14px; flex: 1; overflow-y: auto; }\n\n .card {\n background: var(--bg-2); border: 1px solid var(--line);\n border-radius: var(--radius); padding: 12px;\n margin-bottom: 12px;\n }\n .card-h {\n display: flex; justify-content: space-between; align-items: center;\n margin-bottom: 8px;\n }\n .card-h .ttl { font-size: 12px; font-weight: 600; }\n .badge {\n font-family: var(--mono); font-size: 10px;\n padding: 2px 6px;\n background: oklch(0.78 0.14 195 / 0.12);\n color: var(--accent-2);\n border-radius: 4px;\n border: 1px solid oklch(0.78 0.14 195 / 0.3);\n }\n svg { width: 100%; height: 130px; }\n .frame-strip {\n height: 28px;\n display: flex; align-items: flex-end; gap: 1px;\n padding: 4px 0;\n }\n .bar {\n flex: 1;\n background: linear-gradient(to top, var(--accent-2), var(--accent));\n border-radius: 1px;\n min-height: 2px;\n }\n table { width: 100%; border-collapse: collapse; font-family: var(--mono); font-size: 10.5px; }\n td { padding: 4px 0; border-bottom: 1px solid var(--line); }\n td:first-child { color: var(--ink-3); }\n td:last-child { text-align: right; color: var(--ink); }\n .hex {\n background: var(--bg-3);\n border: 1px solid var(--line);\n border-radius: var(--radius-sm);\n padding: 10px;\n font-family: var(--mono);\n font-size: 10.5px;\n color: var(--ink-2);\n line-height: 1.6;\n overflow-x: auto;\n white-space: nowrap;\n }\n .hex .magic { color: var(--accent); font-weight: 600; }\n .witness-box {\n font-family: var(--mono);\n font-size: 11px;\n color: var(--ink-2);\n background: var(--bg-3);\n border: 1px solid var(--line);\n border-radius: 6px;\n padding: 8px 10px;\n word-break: break-all;\n line-height: 1.5;\n }\n .verify-btn {\n margin-top: 10px;\n width: 100%;\n padding: 8px;\n border: 1px solid var(--line);\n background: var(--bg-3);\n color: var(--ink);\n border-radius: 8px;\n cursor: pointer;\n font-family: var(--mono);\n font-size: 12px;\n }\n .verify-btn:hover { border-color: var(--accent); }\n .verify-btn.ok { border-color: var(--ok); color: var(--ok); }\n .verify-btn.fail { border-color: var(--bad); color: var(--bad); }\n `;\n\n override connectedCallback(): void {\n super.connectedCallback();\n effect(() => {\n traceX.value; traceY.value; traceZ.value; stripBars.value;\n lastFrame.value; witnessHex.value; witnessVerified.value;\n lastB.value; bMag.value;\n this.requestUpdate();\n });\n }\n\n override updated(changed: PropertyValues): void {\n if (changed.has('pinTab') && this.pinTab) {\n this.tab = this.pinTab;\n }\n }\n\n private async verify(): Promise {\n const c = getClient(); if (!c) return;\n witnessVerified.value = 'pending';\n pushLog('info', 'verifying witness over 256 frames…');\n try {\n const exp = expectedWitness.value;\n const expBytes = new Uint8Array(32);\n for (let i = 0; i < 32; i++) expBytes[i] = parseInt(exp.slice(i * 2, i * 2 + 2), 16);\n const r = await c.verifyWitness(expBytes);\n if (r.ok) {\n witnessVerified.value = 'ok';\n witnessHex.value = exp;\n pushLog('ok', `witness ${exp.slice(0, 16)}… matches · determinism gate ✓`);\n } else {\n witnessVerified.value = 'fail';\n const actual = Array.from(r.actual).map((b) => b.toString(16).padStart(2, '0')).join('');\n witnessHex.value = actual;\n pushLog('err', `WITNESS MISMATCH actual=${actual.slice(0, 16)}…`);\n }\n } catch (e) {\n witnessVerified.value = 'fail';\n pushLog('err', `verify failed: ${(e as Error).message}`);\n }\n }\n\n private renderSignalTab() {\n const W = 320, H = 130, cy = 65, scale = 22;\n const cap = 200;\n const make = (arr: number[]) => {\n let p = '';\n arr.forEach((v, i) => {\n const x = (i / Math.max(1, cap - 1)) * W;\n const y = cy - v * scale;\n p += (i === 0 ? 'M' : 'L') + ` ${x.toFixed(1)} ${y.toFixed(1)} `;\n });\n return p;\n };\n\n return html`\n
\n
\n B-vector trace\n 3-axis · nT\n
\n \n \n ${svg``}\n ${svg``}\n ${svg``}\n \n
\n\n
\n
\n Frame stream\n live\n
\n
\n ${stripBars.value.map((v) => html`
`)}\n
\n
\n `;\n }\n\n private renderFrameTab() {\n const f = lastFrame.value;\n const bytes = f?.raw;\n let hex = '';\n if (bytes) {\n const arr = Array.from(bytes).map((b) => b.toString(16).padStart(2, '0'));\n hex = arr.slice(0, 60).join(' ');\n }\n return html`\n
\n
\n MagFrame v1 fields\n 60 B\n
\n \n \n \n \n \n \n \n \n \n \n \n
magic${f ? '0x' + f.magic.toString(16).toUpperCase() : '—'}
version${f?.version ?? '—'}
flags0x${(f?.flags ?? 0).toString(16).padStart(4, '0')}
sensor_id${f?.sensorId ?? '—'}
t_us${f ? f.tUs.toString() : '—'}
b_pT[0]${f ? f.bPt[0].toFixed(1) : '—'}
b_pT[1]${f ? f.bPt[1].toFixed(1) : '—'}
b_pT[2]${f ? f.bPt[2].toFixed(1) : '—'}
noise_floor${f ? f.noiseFloorPtSqrtHz.toFixed(2) : '—'}
temp_K${f ? f.temperatureK.toFixed(1) : '—'}
\n
\n
\n
\n Hex dump\n LE\n
\n
${hex || '—'}
\n
\n `;\n }\n\n private renderWitnessTab() {\n const status = witnessVerified.value;\n const cls = status === 'ok' ? 'ok' : status === 'fail' ? 'fail' : '';\n const label =\n status === 'pending' ? 'Verifying…' :\n status === 'ok' ? '✓ Witness verified · determinism gate' :\n status === 'fail' ? '✗ Witness mismatch · audit required' :\n 'Verify witness';\n return html`\n
\n
\n Expected (Proof::EXPECTED_WITNESS_HEX)\n SHA-256\n
\n
${expectedWitness.value || '(loading…)'}
\n
\n
\n
\n Actual (last verify)\n SHA-256\n
\n
${witnessHex.value || '(not verified yet)'}
\n \n
\n `;\n }\n\n override render() {\n return html`\n
\n \n \n \n
\n
\n ${this.tab === 'signal' ? this.renderSignalTab()\n : this.tab === 'frame' ? this.renderFrameTab()\n : this.renderWitnessTab()}\n
\n `;\n }\n}\n","/* Console — log stream + REPL. */\nimport { LitElement, html, css } from 'lit';\nimport { customElement, query } from 'lit/decorators.js';\nimport { effect } from '@preact/signals-core';\nimport {\n consoleLines, consoleFilter, consolePaused, pushLog,\n getClient, seed, theme, expectedWitness, witnessHex, witnessVerified,\n running,\n} from '../store/appStore';\n\n@customElement('nv-console')\nexport class NvConsole extends LitElement {\n @query('#console-input') private inputEl!: HTMLInputElement;\n private history: string[] = [];\n private hIdx = -1;\n\n static styles = css`\n :host {\n display: flex; flex-direction: column;\n background: var(--bg-1);\n overflow: hidden;\n }\n .tabs {\n display: flex; align-items: center;\n border-bottom: 1px solid var(--line);\n padding: 0 10px;\n gap: 2px;\n }\n .tab {\n padding: 8px 12px;\n background: transparent; border: none;\n font-size: 11.5px; color: var(--ink-3);\n font-family: var(--mono);\n border-bottom: 2px solid transparent;\n cursor: pointer;\n margin-bottom: -1px;\n }\n .tab.active { color: var(--ink); border-bottom-color: var(--accent); }\n .tab .cnt {\n background: var(--bg-3); padding: 1px 5px; border-radius: 999px;\n font-size: 9.5px; color: var(--ink-2); margin-left: 4px;\n }\n .spacer { flex: 1; }\n .tools { display: flex; gap: 4px; padding: 4px 0; }\n .tools button {\n width: 24px; height: 24px;\n background: transparent; border: 1px solid var(--line);\n border-radius: 6px;\n color: var(--ink-3);\n font-size: 11px; cursor: pointer;\n }\n .tools button:hover { color: var(--ink); border-color: var(--line-2); }\n\n .body {\n flex: 1; overflow-y: auto;\n font-family: var(--mono);\n font-size: 11.5px;\n padding: 6px 0;\n background: var(--bg-0);\n }\n .line {\n display: grid;\n grid-template-columns: 70px 60px 1fr;\n gap: 12px;\n padding: 2px 12px;\n color: var(--ink-2);\n border-left: 2px solid transparent;\n }\n .line:hover { background: var(--bg-1); }\n .ts { color: var(--ink-4); font-size: 10.5px; padding-top: 1px; }\n .lvl {\n font-size: 10px; font-weight: 600;\n text-transform: uppercase; letter-spacing: 0.04em; padding-top: 1px;\n }\n .line.info .lvl { color: var(--accent-2); }\n .line.warn .lvl { color: var(--warn); }\n .line.warn { border-left-color: var(--warn); background: oklch(0.7 0.18 35 / 0.04); }\n .line.err .lvl { color: var(--bad); }\n .line.err { border-left-color: var(--bad); background: oklch(0.65 0.22 25 / 0.05); }\n .line.dbg .lvl { color: var(--ink-3); }\n .line.ok .lvl { color: var(--ok); }\n .msg { color: var(--ink); white-space: pre-wrap; word-break: break-word; }\n\n .input {\n display: flex; align-items: center;\n border-top: 1px solid var(--line);\n background: var(--bg-0);\n padding: 0 10px;\n height: 32px; gap: 8px;\n }\n .prompt { color: var(--accent); font-family: var(--mono); font-size: 12px; }\n input[type=\"text\"] {\n flex: 1; background: transparent; border: none; outline: none;\n color: var(--ink); font-family: var(--mono); font-size: 12px;\n height: 100%;\n }\n input::placeholder { color: var(--ink-4); }\n `;\n\n override connectedCallback(): void {\n super.connectedCallback();\n effect(() => {\n consoleLines.value; consoleFilter.value; consolePaused.value;\n this.requestUpdate();\n });\n }\n\n override updated(): void {\n const body = this.renderRoot.querySelector('.body') as HTMLElement | null;\n if (body) body.scrollTop = body.scrollHeight;\n }\n\n private counts(): Record {\n const c: Record = { info: 0, warn: 0, err: 0, dbg: 0, ok: 0 };\n for (const l of consoleLines.value) c[l.level] = (c[l.level] ?? 0) + 1;\n c.all = consoleLines.value.length;\n return c;\n }\n\n private async exec(line: string): Promise {\n line = line.trim();\n if (!line) return;\n pushLog('info', `nvsim> ${line}`);\n this.history.push(line); this.hIdx = this.history.length;\n const [cmd, ...args] = line.split(/\\s+/);\n const arg = args.join(' ');\n const c = getClient();\n switch (cmd) {\n case 'help':\n pushLog('info', 'commands: help · scene.list · sensor.config · run · pause · seed · proof.verify · clear · theme · status');\n break;\n case 'scene.list':\n pushLog('info', 'scene rebar-walkby-01:');\n pushLog('info', ' rebar.steel.coil @ [+2.7, 0.0, +0.3] m χ=5000');\n pushLog('info', ' dipole.heart_proxy @ [-1.4, +0.2, +0.4] m m=1.0e-6 A·m²');\n pushLog('info', ' loop.mains_60Hz @ [-1.6, -0.4, 0.0] m I=2 A');\n pushLog('info', ' eddy.door_steel @ [+0.0, +1.8, +0.4] m σ=1e6 S/m');\n break;\n case 'sensor.config':\n pushLog('info', 'NvSensor::cots_defaults() {');\n pushLog('info', ' pos=[0,0,0], V=1mm³, N=1e12, C=0.03, T2*=200ns');\n pushLog('info', ' D=2.870 GHz, γe=28 GHz/T, Γ=1.0 MHz, axes=4×〈111〉');\n pushLog('info', ' δB ≈ 1.18 pT/√Hz (Barry 2020 §III.A) }');\n break;\n case 'run':\n if (c) { await c.run(); running.value = true; pushLog('ok', 'pipeline RUN'); }\n break;\n case 'pause':\n if (c) { await c.pause(); running.value = false; pushLog('warn', 'pipeline PAUSED'); }\n break;\n case 'reset':\n if (c) { await c.reset(); pushLog('info', 'pipeline reset · t=0'); }\n break;\n case 'seed': {\n if (!arg) { pushLog('info', `current seed = 0x${seed.value.toString(16).toUpperCase()}`); break; }\n const v = BigInt(arg.startsWith('0x') ? arg : '0x' + arg);\n seed.value = v;\n if (c) await c.setSeed(v);\n pushLog('ok', `seed → 0x${v.toString(16).toUpperCase()}`);\n break;\n }\n case 'proof.verify': {\n if (!c) break;\n pushLog('dbg', 'computing SHA-256 over 256 frames…');\n try {\n const exp = expectedWitness.value;\n const expBytes = new Uint8Array(32);\n for (let i = 0; i < 32; i++) expBytes[i] = parseInt(exp.slice(i * 2, i * 2 + 2), 16);\n const r = await c.verifyWitness(expBytes);\n if (r.ok) { witnessVerified.value = 'ok'; witnessHex.value = exp; pushLog('ok', `witness ${exp.slice(0, 16)}… matches · determinism gate ✓`); }\n else { witnessVerified.value = 'fail'; pushLog('err', 'WITNESS MISMATCH'); }\n } catch (e) { pushLog('err', `verify failed: ${(e as Error).message}`); }\n break;\n }\n case 'clear':\n consoleLines.value = [];\n break;\n case 'theme': {\n const t = (arg || '').toLowerCase();\n if (t === 'light' || t === 'dark') { theme.value = t; pushLog('ok', `theme → ${t}`); }\n else pushLog('info', 'theme [light|dark]');\n break;\n }\n case 'status':\n pushLog('info', `running=${running.value} seed=0x${seed.value.toString(16).toUpperCase()} verified=${witnessVerified.value}`);\n break;\n default:\n pushLog('err', `unknown command: ${cmd} · try help`);\n }\n }\n\n private onKey = (e: KeyboardEvent): void => {\n if (e.key === 'Enter') { void this.exec(this.inputEl.value); this.inputEl.value = ''; }\n else if (e.key === 'ArrowUp') {\n if (this.history.length) {\n this.hIdx = Math.max(0, this.hIdx - 1);\n this.inputEl.value = this.history[this.hIdx] ?? '';\n e.preventDefault();\n }\n } else if (e.key === 'ArrowDown') {\n if (this.history.length) {\n this.hIdx = Math.min(this.history.length, this.hIdx + 1);\n this.inputEl.value = this.history[this.hIdx] ?? '';\n e.preventDefault();\n }\n }\n };\n\n override render() {\n const c = this.counts();\n const filter = consoleFilter.value;\n const visible = consoleLines.value.filter((l) => filter === 'all' || l.level === filter);\n return html`\n
\n ${(['all', 'info', 'warn', 'err', 'dbg'] as const).map((k) => html`\n \n `)}\n \n
\n \n \n
\n
\n
\n ${visible.map((l) => {\n const ts = new Date(l.ts);\n const tsStr = `${String(ts.getSeconds()).padStart(2, '0')}.${String(ts.getMilliseconds()).padStart(3, '0')}`;\n // Use innerHTML pass-through via unsafe-html alt: inject raw html via property\n return html`
\n
${tsStr}
\n
${l.level}
\n
\n
`;\n })}\n
\n
\n nvsim>\n \n
\n `;\n }\n}\n","/* RuView Edge App Store registry.\n *\n * Catalog of every WASM edge module shipping in the workspace plus the\n * `nvsim` simulator itself. Each entry maps to a hot-loadable algorithm\n * the dashboard can run in-browser (WASM transport) or push to a real\n * ESP32-S3 mesh (WS transport, deployed via WASM3 — ADR-040 Tier 3).\n *\n * Categories (ADR-041 event-ID ranges):\n * med 100–199 Medical & health\n * sec 200–299 Security & safety\n * bld 300–399 Smart building\n * ret 400–499 Retail & hospitality\n * ind 500–599 Industrial\n * sig 600–619 Signal-processing primitives\n * lrn 620–639 Online learning\n * spt 640–659 Spatial / graph\n * tmp 640–660 Temporal logic / planning\n * ais 700–719 AI safety\n * qnt 720–739 Quantum-flavoured signal\n * aut 740–759 Autonomy / mesh\n * exo 650–699 Exotic / research\n * sim — Pipeline simulators (nvsim)\n *\n * The `crate` field names the Cargo crate that owns the implementation.\n * `wasmEdge` apps are compiled out of `wifi-densepose-wasm-edge`;\n * `nvsim` apps come from `nvsim`. Future apps may target other crates.\n */\n\nexport type AppCategory =\n | 'sim'\n | 'med'\n | 'sec'\n | 'bld'\n | 'ret'\n | 'ind'\n | 'sig'\n | 'lrn'\n | 'spt'\n | 'tmp'\n | 'ais'\n | 'qnt'\n | 'aut'\n | 'exo';\n\nexport interface AppManifest {\n /** Stable kebab-case id; matches the wasm-edge module name (e.g. `med_sleep_apnea`). */\n id: string;\n /** Human-readable name. */\n name: string;\n /** Category short-code. */\n category: AppCategory;\n /** Cargo crate the implementation lives in. */\n crate: 'nvsim' | 'wifi-densepose-wasm-edge' | string;\n /** One-liner description. */\n summary: string;\n /** Optional longer markdown body. */\n body?: string;\n /** Numeric event IDs this app emits (i32 codes from `event_types` mod). */\n events?: number[];\n /** Compute budget tier the module advertises. S=<5ms, M=<15ms, L=<50ms. */\n budget?: 'S' | 'M' | 'L';\n /** Default activation state when listed. */\n active?: boolean;\n /** Tags for fuzzy search and filtering. */\n tags?: string[];\n /** \"Available\", \"Beta\", or \"Research\" maturity. */\n status: 'available' | 'beta' | 'research';\n /** ADR back-reference. */\n adr?: string;\n}\n\nexport const APPS: AppManifest[] = [\n // ── Pipeline simulators ──────────────────────────────────────────────────\n {\n id: 'nvsim',\n name: 'nvsim — NV-diamond magnetometer',\n category: 'sim',\n crate: 'nvsim',\n summary:\n 'Deterministic forward simulator: scene → Biot–Savart → NV ensemble → ADC → MagFrame stream + SHA-256 witness.',\n budget: 'L',\n active: true,\n status: 'available',\n tags: ['quantum', 'magnetometer', 'simulator', 'witness', 'wasm'],\n adr: 'ADR-089',\n },\n\n // ── Core sensing primitives (ADR-014/040 flagship modules) ───────────────\n {\n id: 'gesture',\n name: 'Gesture (DTW)',\n category: 'sig',\n crate: 'wifi-densepose-wasm-edge',\n summary: 'Dynamic-Time-Warping gesture classifier from CSI motion templates.',\n events: [1],\n budget: 'M',\n status: 'available',\n tags: ['hci', 'csi', 'classifier', 'dtw'],\n adr: 'ADR-014',\n },\n {\n id: 'coherence',\n name: 'Coherence gate',\n category: 'sig',\n crate: 'wifi-densepose-wasm-edge',\n summary: 'Z-score coherence scoring + Accept/PredictOnly/Reject/Recalibrate gate.',\n events: [2],\n budget: 'S',\n status: 'available',\n tags: ['gate', 'csi', 'coherence', 'drift'],\n adr: 'ADR-029',\n },\n {\n id: 'adversarial',\n name: 'Adversarial-signal detector',\n category: 'ais',\n crate: 'wifi-densepose-wasm-edge',\n summary:\n 'Physically-impossible-signal detector — multi-link consistency, used to flag spoofed CSI.',\n events: [3],\n budget: 'M',\n status: 'available',\n tags: ['security', 'csi', 'spoofing', 'mesh'],\n adr: 'ADR-032',\n },\n {\n id: 'rvf',\n name: 'RVF — Rust Verified Feature stream',\n category: 'sig',\n crate: 'wifi-densepose-wasm-edge',\n summary: 'Verified-frame builder with SHA-256 hash + version metadata for the feature stream.',\n budget: 'S',\n status: 'available',\n tags: ['witness', 'csi', 'hash'],\n adr: 'ADR-040',\n },\n {\n id: 'occupancy',\n name: 'Occupancy estimator',\n category: 'bld',\n crate: 'wifi-densepose-wasm-edge',\n summary: 'Through-wall presence + person-count via CSI amplitude perturbation.',\n events: [300, 301, 302],\n budget: 'S',\n status: 'available',\n tags: ['csi', 'building', 'presence'],\n },\n {\n id: 'vital_trend',\n name: 'Vital-trend monitor',\n category: 'med',\n crate: 'wifi-densepose-wasm-edge',\n summary: 'HR + BR trend tracking with bradycardia/tachycardia/apnea events.',\n events: [100, 101, 102, 103, 104, 105],\n budget: 'S',\n status: 'available',\n tags: ['medical', 'vitals', 'csi'],\n adr: 'ADR-021',\n },\n {\n id: 'intrusion',\n name: 'Intrusion detector',\n category: 'sec',\n crate: 'wifi-densepose-wasm-edge',\n summary: 'Zone-based intrusion alert from CSI motion patterns.',\n events: [200, 201],\n budget: 'S',\n status: 'available',\n tags: ['security', 'zone', 'csi'],\n },\n\n // ── Medical & Health (100-series) ────────────────────────────────────────\n { id: 'med_sleep_apnea', name: 'Sleep-apnea detector', category: 'med', crate: 'wifi-densepose-wasm-edge', summary: 'Episodic respiratory pause detection during sleep cycles.', events: [105], budget: 'S', status: 'available', tags: ['medical', 'sleep', 'breathing'] },\n { id: 'med_cardiac_arrhythmia', name: 'Cardiac arrhythmia', category: 'med', crate: 'wifi-densepose-wasm-edge', summary: 'Beat-to-beat irregularity classifier from cardiac micro-Doppler.', events: [103, 104], budget: 'M', status: 'available', tags: ['medical', 'cardiac', 'arrhythmia'] },\n { id: 'med_respiratory_distress', name: 'Respiratory distress', category: 'med', crate: 'wifi-densepose-wasm-edge', summary: 'Distress signature: rapid shallow breathing + accessory-muscle motion.', events: [101, 102], budget: 'S', status: 'available', tags: ['medical', 'breathing', 'icu'] },\n { id: 'med_gait_analysis', name: 'Gait analysis', category: 'med', crate: 'wifi-densepose-wasm-edge', summary: 'Stride length, cadence, asymmetry from through-wall CSI pose tracking.', budget: 'M', status: 'available', tags: ['medical', 'gait', 'pose'] },\n { id: 'med_seizure_detect', name: 'Seizure detector', category: 'med', crate: 'wifi-densepose-wasm-edge', summary: 'Tonic-clonic seizure motion signature.', budget: 'M', status: 'beta', tags: ['medical', 'neuro'] },\n\n // ── Security (200-series) ────────────────────────────────────────────────\n { id: 'sec_perimeter_breach', name: 'Perimeter breach', category: 'sec', crate: 'wifi-densepose-wasm-edge', summary: 'Approach/departure detection at user-defined boundary segments.', events: [210, 211, 212, 213], budget: 'S', status: 'available', tags: ['security', 'perimeter'] },\n { id: 'sec_weapon_detect', name: 'Metal anomaly / weapon', category: 'sec', crate: 'wifi-densepose-wasm-edge', summary: 'Metal-perturbation flag in CSI; potential weapon presence (research).', events: [220, 221, 222], budget: 'M', status: 'research', tags: ['security', 'metal', 'csi'] },\n { id: 'sec_tailgating', name: 'Tailgating detector', category: 'sec', crate: 'wifi-densepose-wasm-edge', summary: 'Detect 2+ persons crossing a single-passage threshold.', events: [230, 231, 232], budget: 'S', status: 'available', tags: ['security', 'access-control'] },\n { id: 'sec_loitering', name: 'Loitering detector', category: 'sec', crate: 'wifi-densepose-wasm-edge', summary: 'Stationary occupancy past a configurable dwell threshold.', events: [240, 241, 242], budget: 'S', status: 'available', tags: ['security', 'dwell'] },\n { id: 'sec_panic_motion', name: 'Panic motion', category: 'sec', crate: 'wifi-densepose-wasm-edge', summary: 'High-energy distress motion: struggle / fleeing pattern.', events: [250, 251, 252], budget: 'S', status: 'beta', tags: ['security', 'distress'] },\n\n // ── Smart Building (300-series) ──────────────────────────────────────────\n { id: 'bld_hvac_presence', name: 'HVAC presence', category: 'bld', crate: 'wifi-densepose-wasm-edge', summary: 'Occupied/activity-level/departure-countdown for HVAC zones.', events: [310, 311, 312], budget: 'S', status: 'available', tags: ['hvac', 'building', 'energy'] },\n { id: 'bld_lighting_zones', name: 'Lighting zones', category: 'bld', crate: 'wifi-densepose-wasm-edge', summary: 'Per-zone light on/dim/off cues from occupancy.', events: [320, 321, 322], budget: 'S', status: 'available', tags: ['lighting', 'building'] },\n { id: 'bld_elevator_count', name: 'Elevator count', category: 'bld', crate: 'wifi-densepose-wasm-edge', summary: 'Person count inside elevator car from CSI.', events: [330], budget: 'S', status: 'available', tags: ['elevator', 'building'] },\n { id: 'bld_meeting_room', name: 'Meeting-room utilization', category: 'bld', crate: 'wifi-densepose-wasm-edge', summary: 'Meeting size + duration analytics for booking systems.', budget: 'S', status: 'available', tags: ['meeting', 'analytics'] },\n { id: 'bld_energy_audit', name: 'Energy audit', category: 'bld', crate: 'wifi-densepose-wasm-edge', summary: 'Continuous occupancy-vs-HVAC-state audit for energy savings.', budget: 'M', status: 'available', tags: ['energy', 'audit'] },\n\n // ── Retail (400-series) ──────────────────────────────────────────────────\n { id: 'ret_queue_length', name: 'Queue length', category: 'ret', crate: 'wifi-densepose-wasm-edge', summary: 'Live queue-length tracking for checkout / kiosks.', budget: 'S', status: 'available', tags: ['retail', 'queue'] },\n { id: 'ret_dwell_heatmap', name: 'Dwell heatmap', category: 'ret', crate: 'wifi-densepose-wasm-edge', summary: 'Per-zone dwell time accumulation; analytics-only export.', budget: 'M', status: 'available', tags: ['retail', 'heatmap'] },\n { id: 'ret_customer_flow', name: 'Customer flow', category: 'ret', crate: 'wifi-densepose-wasm-edge', summary: 'Origin-destination flow graph through a store layout.', budget: 'M', status: 'available', tags: ['retail', 'flow'] },\n { id: 'ret_table_turnover', name: 'Table turnover', category: 'ret', crate: 'wifi-densepose-wasm-edge', summary: 'Restaurant table seat / vacate transitions.', budget: 'S', status: 'available', tags: ['retail', 'restaurant'] },\n { id: 'ret_shelf_engagement', name: 'Shelf engagement', category: 'ret', crate: 'wifi-densepose-wasm-edge', summary: 'Reach-to-shelf gestures and dwell at product zones.', budget: 'M', status: 'available', tags: ['retail', 'shelf'] },\n\n // ── Industrial (500-series) ──────────────────────────────────────────────\n { id: 'ind_forklift_proximity', name: 'Forklift proximity', category: 'ind', crate: 'wifi-densepose-wasm-edge', summary: 'Worker-near-forklift safety alert.', budget: 'S', status: 'available', tags: ['industrial', 'safety'] },\n { id: 'ind_confined_space', name: 'Confined-space monitor', category: 'ind', crate: 'wifi-densepose-wasm-edge', summary: 'Last-person-out detection + presence audit for OSHA confined-space entries.', budget: 'S', status: 'available', tags: ['industrial', 'osha'] },\n { id: 'ind_clean_room', name: 'Clean-room PPE / motion', category: 'ind', crate: 'wifi-densepose-wasm-edge', summary: 'Motion patterns consistent with proper PPE-clad movement.', budget: 'M', status: 'beta', tags: ['industrial', 'cleanroom'] },\n { id: 'ind_livestock_monitor', name: 'Livestock monitor', category: 'ind', crate: 'wifi-densepose-wasm-edge', summary: 'Vital-sign + activity tracking for stall-bound livestock.', budget: 'M', status: 'beta', tags: ['agriculture', 'livestock'] },\n { id: 'ind_structural_vibration', name: 'Structural vibration', category: 'ind', crate: 'wifi-densepose-wasm-edge', summary: 'Building/equipment micro-vibration via CSI phase derivative.', budget: 'M', status: 'research', tags: ['industrial', 'vibration'] },\n\n // ── Signal primitives (600-series) ───────────────────────────────────────\n { id: 'sig_coherence_gate', name: 'Coherence gate (extended)', category: 'sig', crate: 'wifi-densepose-wasm-edge', summary: 'Hysteresis + multi-state coherence gate driving downstream apps.', budget: 'S', status: 'available', tags: ['gate', 'csi'] },\n { id: 'sig_flash_attention', name: 'Flash attention (CSI)', category: 'sig', crate: 'wifi-densepose-wasm-edge', summary: 'Edge-friendly attention block for CSI subcarrier weighting.', budget: 'M', status: 'beta', tags: ['attention', 'csi'] },\n { id: 'sig_temporal_compress', name: 'Temporal-tensor compress', category: 'sig', crate: 'wifi-densepose-wasm-edge', summary: 'RuVector temporal-tensor compression on the CSI buffer.', budget: 'M', status: 'available', tags: ['compress', 'tensor'] },\n { id: 'sig_sparse_recovery', name: 'Sparse recovery', category: 'sig', crate: 'wifi-densepose-wasm-edge', summary: '114→56 subcarrier sparse interpolation via L1 solver.', budget: 'M', status: 'available', tags: ['sparse', 'csi'] },\n { id: 'sig_mincut_person_match', name: 'Mincut person-match', category: 'sig', crate: 'wifi-densepose-wasm-edge', summary: 'Min-cut person assignment across multistatic frames.', budget: 'M', status: 'available', tags: ['mincut', 'matching'] },\n { id: 'sig_optimal_transport', name: 'Optimal transport', category: 'sig', crate: 'wifi-densepose-wasm-edge', summary: 'OT-based feature alignment between mesh nodes.', budget: 'M', status: 'beta', tags: ['ot', 'alignment'] },\n\n // ── Online learning ──────────────────────────────────────────────────────\n { id: 'lrn_dtw_gesture_learn', name: 'DTW gesture learn', category: 'lrn', crate: 'wifi-densepose-wasm-edge', summary: 'On-device template learning for personalized gesture libraries.', budget: 'M', status: 'beta', tags: ['lifelong', 'gesture'] },\n { id: 'lrn_anomaly_attractor', name: 'Anomaly attractor', category: 'lrn', crate: 'wifi-densepose-wasm-edge', summary: 'Novelty detector with dynamic-attractor recall.', budget: 'M', status: 'research', tags: ['novelty', 'lifelong'] },\n { id: 'lrn_meta_adapt', name: 'Meta-adapt', category: 'lrn', crate: 'wifi-densepose-wasm-edge', summary: 'Meta-learning adapter for fast site-to-site transfer.', budget: 'L', status: 'research', tags: ['meta-learning'] },\n { id: 'lrn_ewc_lifelong', name: 'EWC++ lifelong', category: 'lrn', crate: 'wifi-densepose-wasm-edge', summary: 'Elastic-weight-consolidation gate to avoid catastrophic forgetting.', budget: 'M', status: 'beta', tags: ['lifelong', 'ewc'] },\n\n // ── Spatial / graph ──────────────────────────────────────────────────────\n { id: 'spt_pagerank_influence', name: 'PageRank influence', category: 'spt', crate: 'wifi-densepose-wasm-edge', summary: 'Graph-influence ranking on the multistatic mesh.', budget: 'M', status: 'beta', tags: ['graph', 'pagerank'] },\n { id: 'spt_micro_hnsw', name: 'µHNSW vector index', category: 'spt', crate: 'wifi-densepose-wasm-edge', summary: 'Tiny HNSW index for AETHER re-ID embeddings on-device.', budget: 'M', status: 'available', tags: ['hnsw', 'reid'] },\n { id: 'spt_spiking_tracker', name: 'Spiking tracker', category: 'spt', crate: 'wifi-densepose-wasm-edge', summary: 'Spiking-network multi-target tracker.', budget: 'L', status: 'research', tags: ['snn', 'tracker'] },\n\n // ── Temporal / planning ──────────────────────────────────────────────────\n { id: 'tmp_pattern_sequence', name: 'Pattern sequence', category: 'tmp', crate: 'wifi-densepose-wasm-edge', summary: 'Sequence-of-events pattern matcher (e.g. ingress→linger→egress).', budget: 'M', status: 'available', tags: ['temporal', 'pattern'] },\n { id: 'tmp_temporal_logic_guard', name: 'Temporal logic guard', category: 'tmp', crate: 'wifi-densepose-wasm-edge', summary: 'LTL/MTL safety-property guard over event streams.', budget: 'M', status: 'beta', tags: ['ltl', 'safety'] },\n { id: 'tmp_goap_autonomy', name: 'GOAP autonomy', category: 'tmp', crate: 'wifi-densepose-wasm-edge', summary: 'Goal-oriented action planning for adaptive routines.', budget: 'L', status: 'research', tags: ['planning', 'autonomy'] },\n\n // ── AI safety ────────────────────────────────────────────────────────────\n { id: 'ais_prompt_shield', name: 'Prompt shield', category: 'ais', crate: 'wifi-densepose-wasm-edge', summary: 'Edge-side LLM prompt-injection guard for on-device assistants.', budget: 'M', status: 'beta', tags: ['security', 'llm'] },\n { id: 'ais_behavioral_profiler', name: 'Behavioral profiler', category: 'ais', crate: 'wifi-densepose-wasm-edge', summary: 'Anomalous-behaviour profiler (drift in motion habits).', budget: 'M', status: 'beta', tags: ['anomaly', 'behaviour'] },\n\n // ── Quantum-flavoured ────────────────────────────────────────────────────\n { id: 'qnt_quantum_coherence', name: 'Quantum coherence', category: 'qnt', crate: 'wifi-densepose-wasm-edge', summary: 'Coherence diagnostics adapted for quantum-sensor signals.', budget: 'M', status: 'research', tags: ['quantum', 'coherence'] },\n { id: 'qnt_interference_search', name: 'Interference search', category: 'qnt', crate: 'wifi-densepose-wasm-edge', summary: 'Interferometric anomaly search across mesh viewpoints.', budget: 'L', status: 'research', tags: ['quantum', 'interference'] },\n\n // ── Autonomy / mesh ──────────────────────────────────────────────────────\n { id: 'aut_psycho_symbolic', name: 'Psycho-symbolic agent', category: 'aut', crate: 'wifi-densepose-wasm-edge', summary: 'Symbolic-rule + neural-feature hybrid for low-power autonomy loops.', budget: 'L', status: 'research', tags: ['autonomy', 'symbolic'] },\n { id: 'aut_self_healing_mesh', name: 'Self-healing mesh', category: 'aut', crate: 'wifi-densepose-wasm-edge', summary: 'Mesh-topology repair with per-node health gossip.', budget: 'M', status: 'beta', tags: ['mesh', 'health'] },\n\n // ── Exotic / Research (650-series) ───────────────────────────────────────\n { id: 'exo_ghost_hunter', name: 'Ghost hunter (anomaly)', category: 'exo', crate: 'wifi-densepose-wasm-edge', summary: 'Empty-room CSI anomaly detector — impulsive/periodic/drift/random + hidden-presence sub-detector.', events: [650, 651, 652, 653], budget: 'S', status: 'available', tags: ['anomaly', 'paranormal', 'csi'], adr: 'ADR-041' },\n { id: 'exo_breathing_sync', name: 'Breathing sync', category: 'exo', crate: 'wifi-densepose-wasm-edge', summary: 'Multi-person breathing synchrony analytics.', budget: 'M', status: 'beta', tags: ['breathing', 'sync'] },\n { id: 'exo_dream_stage', name: 'Dream-stage classifier', category: 'exo', crate: 'wifi-densepose-wasm-edge', summary: 'NREM/REM stage classification from breathing + micro-motion.', budget: 'M', status: 'research', tags: ['sleep', 'rem'] },\n { id: 'exo_emotion_detect', name: 'Emotion detector', category: 'exo', crate: 'wifi-densepose-wasm-edge', summary: 'Coarse arousal/valence from breathing + heart-rate variability.', budget: 'M', status: 'research', tags: ['affect'] },\n { id: 'exo_gesture_language', name: 'Gesture language', category: 'exo', crate: 'wifi-densepose-wasm-edge', summary: 'Sign-language pattern recognition.', budget: 'L', status: 'research', tags: ['hci', 'sign'] },\n { id: 'exo_happiness_score', name: 'Happiness score', category: 'exo', crate: 'wifi-densepose-wasm-edge', summary: 'Aggregate well-being score from co-occupancy + activity dynamics.', budget: 'M', status: 'research', tags: ['affect', 'wellbeing'] },\n { id: 'exo_hyperbolic_space', name: 'Hyperbolic space embed', category: 'exo', crate: 'wifi-densepose-wasm-edge', summary: 'Hyperbolic embeddings for hierarchical scene structure.', budget: 'L', status: 'research', tags: ['embedding', 'hyperbolic'] },\n { id: 'exo_music_conductor', name: 'Music conductor', category: 'exo', crate: 'wifi-densepose-wasm-edge', summary: 'Map gesture energy to MIDI tempo/dynamics.', budget: 'M', status: 'research', tags: ['midi', 'art'] },\n { id: 'exo_plant_growth', name: 'Plant-growth tracker', category: 'exo', crate: 'wifi-densepose-wasm-edge', summary: 'Slow CSI drift tracking for greenhouse foliage growth.', budget: 'L', status: 'research', tags: ['agriculture'] },\n { id: 'exo_rain_detect', name: 'Rain detector', category: 'exo', crate: 'wifi-densepose-wasm-edge', summary: 'Outdoor CSI signature of rainfall.', budget: 'M', status: 'research', tags: ['weather'] },\n { id: 'exo_time_crystal', name: 'Time-crystal periodicity', category: 'exo', crate: 'wifi-densepose-wasm-edge', summary: 'Periodicity diagnostics with anti-aliasing harmonics.', budget: 'M', status: 'research', tags: ['periodicity'] },\n];\n\nexport const CATEGORIES: Record = {\n sim: { label: 'Simulators', color: 'oklch(0.78 0.14 70)', range: '—' },\n med: { label: 'Medical & Health', color: 'oklch(0.65 0.22 25)', range: '100–199' },\n sec: { label: 'Security & Safety', color: 'oklch(0.7 0.18 35)', range: '200–299' },\n bld: { label: 'Smart Building', color: 'oklch(0.78 0.12 195)', range: '300–399' },\n ret: { label: 'Retail & Hospitality', color: 'oklch(0.78 0.14 145)', range: '400–499' },\n ind: { label: 'Industrial', color: 'oklch(0.72 0.18 330)', range: '500–599' },\n sig: { label: 'Signal Processing', color: 'oklch(0.78 0.14 70)', range: '600–619' },\n lrn: { label: 'Online Learning', color: 'oklch(0.78 0.12 260)', range: '620–639' },\n spt: { label: 'Spatial / Graph', color: 'oklch(0.7 0.18 100)', range: '640–659' },\n tmp: { label: 'Temporal / Planning', color: 'oklch(0.7 0.16 50)', range: '660–679' },\n ais: { label: 'AI Safety', color: 'oklch(0.65 0.22 25)', range: '700–719' },\n qnt: { label: 'Quantum', color: 'oklch(0.72 0.18 290)', range: '720–739' },\n aut: { label: 'Autonomy', color: 'oklch(0.78 0.14 145)', range: '740–759' },\n exo: { label: 'Exotic / Research', color: 'oklch(0.72 0.18 330)', range: '650–699' },\n};\n\nexport interface AppActivation {\n id: string;\n /** Active in the current session. */\n active: boolean;\n /** Last activation timestamp. */\n lastActivatedAt?: number;\n /** Last event count seen (for the cards' counter). */\n eventCount?: number;\n}\n\nexport function defaultActivations(): AppActivation[] {\n return APPS.map((a) => ({ id: a.id, active: a.active === true, eventCount: 0 }));\n}\n\nexport function appsByCategory(): Record {\n const map = {} as Record;\n for (const c of Object.keys(CATEGORIES) as AppCategory[]) map[c] = [];\n for (const a of APPS) map[a.category].push(a);\n return map;\n}\n\nexport function findApp(id: string): AppManifest | undefined {\n return APPS.find((a) => a.id === id);\n}\n\nexport function fuzzyMatch(query: string, app: AppManifest): number {\n if (!query) return 1;\n const q = query.toLowerCase();\n let score = 0;\n if (app.id.toLowerCase().includes(q)) score += 3;\n if (app.name.toLowerCase().includes(q)) score += 3;\n if (app.summary.toLowerCase().includes(q)) score += 1;\n if (app.tags?.some((t) => t.toLowerCase().includes(q))) score += 2;\n if (app.category === q) score += 5;\n return score;\n}\n","/* IndexedDB-backed persistence for settings and saved scenes.\n * Mirrors the mockup's `nvsim/kv` store. */\n\nconst DB_NAME = 'nvsim';\nconst DB_VER = 1;\nconst STORE = 'kv';\n\nlet dbPromise: Promise | null = null;\n\nfunction openDb(): Promise {\n if (dbPromise) return dbPromise;\n dbPromise = new Promise((resolve, reject) => {\n const req = indexedDB.open(DB_NAME, DB_VER);\n req.onupgradeneeded = () => {\n const db = req.result;\n if (!db.objectStoreNames.contains(STORE)) db.createObjectStore(STORE);\n };\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error);\n });\n return dbPromise;\n}\n\nexport async function kvGet(key: string): Promise {\n const db = await openDb();\n return await new Promise((resolve, reject) => {\n const tx = db.transaction(STORE, 'readonly');\n const r = tx.objectStore(STORE).get(key);\n r.onsuccess = () => resolve(r.result as T | undefined);\n r.onerror = () => reject(r.error);\n });\n}\n\nexport async function kvSet(key: string, value: unknown): Promise {\n const db = await openDb();\n return await new Promise((resolve, reject) => {\n const tx = db.transaction(STORE, 'readwrite');\n tx.objectStore(STORE).put(value, key);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n\nexport async function kvDelete(key: string): Promise {\n const db = await openDb();\n return await new Promise((resolve, reject) => {\n const tx = db.transaction(STORE, 'readwrite');\n tx.objectStore(STORE).delete(key);\n tx.oncomplete = () => resolve();\n tx.onerror = () => reject(tx.error);\n });\n}\n","/* App Store — catalog of every WASM edge module + simulator app.\n *\n * Mirrors `wifi-densepose-wasm-edge`'s 60+ hot-loadable algorithms and\n * the `nvsim` simulator. Each card is filterable by category, fuzzy\n * name search, and maturity (available / beta / research). A toggle on\n * each card flips activation in the live session — that drives the\n * dashboard's event log when running. WS transport (future) pushes the\n * activation set to the connected ESP32 mesh.\n *\n * ADR-092 §18.\n */\n\nimport { LitElement, html, css } from 'lit';\nimport { customElement, state } from 'lit/decorators.js';\nimport { signal, effect } from '@preact/signals-core';\nimport {\n APPS, CATEGORIES, defaultActivations, fuzzyMatch,\n type AppCategory, type AppManifest, type AppActivation,\n} from '../store/apps';\nimport { kvGet, kvSet } from '../store/persistence';\nimport { pushLog } from '../store/appStore';\n\nconst activations = signal(defaultActivations());\nconst query = signal('');\nconst activeCat = signal('all');\nconst statusFilter = signal<'all' | 'available' | 'beta' | 'research'>('all');\n\n(async () => {\n const saved = await kvGet('app-activations');\n if (saved) activations.value = saved;\n})();\n\neffect(() => {\n // Persist activations on change (post-load).\n const v = activations.value;\n if (v.length > 0) void kvSet('app-activations', v);\n});\n\n@customElement('nv-app-store')\nexport class NvAppStore extends LitElement {\n @state() private renderTick = 0;\n\n static styles = css`\n :host {\n display: block;\n height: 100%;\n overflow-y: auto;\n background: radial-gradient(ellipse at 50% 30%, var(--bg-2) 0%, var(--bg-0) 70%);\n padding: 24px;\n }\n .head {\n display: flex; align-items: center; gap: 16px;\n margin-bottom: 18px;\n flex-wrap: wrap;\n }\n .ttl {\n font-size: 22px; font-weight: 700; letter-spacing: -0.02em;\n color: var(--ink);\n flex: 1; min-width: 200px;\n }\n .ttl small {\n font-size: 12.5px; font-weight: 400;\n color: var(--ink-3); margin-left: 8px;\n }\n .search {\n width: 320px; max-width: 100%;\n padding: 8px 12px;\n background: var(--bg-2);\n border: 1px solid var(--line);\n border-radius: 8px;\n font-family: var(--mono);\n font-size: 12.5px;\n color: var(--ink); outline: none;\n }\n .search:focus { border-color: var(--accent); }\n .filters {\n display: flex; flex-wrap: wrap; gap: 6px;\n margin-bottom: 18px;\n }\n .chip {\n padding: 4px 10px;\n background: var(--bg-2);\n border: 1px solid var(--line);\n border-radius: 999px;\n font-size: 11.5px; color: var(--ink-3);\n cursor: pointer;\n font-family: var(--mono);\n display: inline-flex; align-items: center; gap: 4px;\n }\n .chip:hover { color: var(--ink); border-color: var(--line-2); }\n .chip.on { background: var(--bg-3); border-color: var(--accent); color: var(--ink); }\n .chip .swatch {\n width: 7px; height: 7px; border-radius: 50%;\n }\n .chip .count { color: var(--ink-3); font-size: 10px; }\n .grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));\n gap: 12px;\n }\n .card {\n background: var(--bg-2);\n border: 1px solid var(--line);\n border-radius: var(--radius);\n padding: 12px 14px;\n display: flex; flex-direction: column; gap: 6px;\n transition: border-color 0.15s, transform 0.15s;\n position: relative;\n }\n .card:hover { border-color: var(--line-2); transform: translateY(-1px); }\n .card.active {\n border-color: oklch(0.78 0.14 145 / 0.7);\n background: linear-gradient(180deg, var(--bg-2) 0%, oklch(0.78 0.14 145 / 0.04) 100%);\n }\n .card-h {\n display: flex; align-items: flex-start; gap: 8px;\n margin-bottom: 2px;\n }\n .card-h .name {\n font-size: 13.5px; font-weight: 600; color: var(--ink);\n flex: 1; line-height: 1.3;\n }\n .card-h .swatch {\n width: 10px; height: 10px; border-radius: 50%;\n flex-shrink: 0; margin-top: 4px;\n }\n .summary {\n font-size: 12px; color: var(--ink-2); line-height: 1.45;\n flex: 1;\n }\n .meta {\n display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px;\n font-family: var(--mono); font-size: 10px;\n }\n .badge {\n padding: 1px 6px; border-radius: 4px;\n background: var(--bg-3); color: var(--ink-3);\n border: 1px solid var(--line);\n }\n .badge.cat { color: var(--accent); border-color: oklch(0.78 0.14 70 / 0.3); }\n .badge.status-available { color: var(--ok); border-color: oklch(0.78 0.14 145 / 0.4); }\n .badge.status-beta { color: var(--warn); border-color: oklch(0.7 0.18 35 / 0.4); }\n .badge.status-research { color: var(--accent-3); border-color: oklch(0.72 0.18 330 / 0.4); }\n .badge.budget { color: var(--accent-2); border-color: oklch(0.78 0.12 195 / 0.3); }\n .card-foot {\n display: flex; align-items: center; gap: 8px;\n padding-top: 8px; margin-top: 4px;\n border-top: 1px solid var(--line);\n font-size: 11px; color: var(--ink-3);\n }\n .toggle {\n position: relative;\n width: 32px; height: 18px;\n background: var(--bg-3); border: 1px solid var(--line-2);\n border-radius: 999px; cursor: pointer;\n transition: background 0.15s;\n flex-shrink: 0;\n }\n .toggle::after {\n content: ''; position: absolute;\n top: 1px; left: 1px;\n width: 12px; height: 12px;\n background: var(--ink-3); border-radius: 50%;\n transition: transform 0.15s, background 0.15s;\n }\n .toggle.on { background: var(--accent); border-color: var(--accent); }\n .toggle.on::after { background: #1a0f00; transform: translateX(14px); }\n .events {\n font-family: var(--mono); font-size: 10px; color: var(--ink-3);\n flex: 1;\n }\n .empty {\n padding: 40px;\n text-align: center; color: var(--ink-3);\n font-size: 13px;\n }\n `;\n\n override connectedCallback(): void {\n super.connectedCallback();\n effect(() => { activations.value; query.value; activeCat.value; statusFilter.value; this.renderTick++; });\n }\n\n private isActive(id: string): boolean {\n return activations.value.find((a) => a.id === id)?.active === true;\n }\n\n private toggle(app: AppManifest): void {\n const next = activations.value.map((a) => a.id === app.id ? { ...a, active: !a.active, lastActivatedAt: Date.now() } : a);\n activations.value = next;\n pushLog(this.isActive(app.id) ? 'ok' : 'info', `app ${app.id} deactivated`);\n }\n\n private filtered(): AppManifest[] {\n let list = APPS;\n if (activeCat.value !== 'all') list = list.filter((a) => a.category === activeCat.value);\n if (statusFilter.value !== 'all') list = list.filter((a) => a.status === statusFilter.value);\n if (query.value.trim()) {\n list = list\n .map((a) => ({ a, s: fuzzyMatch(query.value, a) }))\n .filter((x) => x.s > 0)\n .sort((a, b) => b.s - a.s)\n .map((x) => x.a);\n }\n return list;\n }\n\n private categoryCounts(): Record {\n const counts: Record = { all: APPS.length };\n for (const k of Object.keys(CATEGORIES)) counts[k] = 0;\n for (const a of APPS) counts[a.category] = (counts[a.category] ?? 0) + 1;\n return counts;\n }\n\n override render() {\n const list = this.filtered();\n const counts = this.categoryCounts();\n const activeCount = activations.value.filter((a) => a.active).length;\n return html`\n
\n
\n App Store\n ${APPS.length} edge apps · ${activeCount} active\n
\n { query.value = (e.target as HTMLInputElement).value; }} />\n
\n\n
\n activeCat.value = 'all'}>\n All${counts.all}\n \n ${(Object.keys(CATEGORIES) as AppCategory[]).map((k) => html`\n activeCat.value = k}>\n \n ${CATEGORIES[k].label}\n ${counts[k] ?? 0}\n \n `)}\n \n statusFilter.value = 'all'}>any\n statusFilter.value = 'available'}>available\n statusFilter.value = 'beta'}>beta\n statusFilter.value = 'research'}>research\n
\n\n ${list.length === 0\n ? html`
No apps match the current filters.
`\n : html`
${list.map((app) => this.card(app))}
`}\n `;\n }\n\n private card(app: AppManifest) {\n const active = this.isActive(app.id);\n const cat = CATEGORIES[app.category];\n return html`\n
\n
\n \n ${app.name}\n
\n
${app.summary}
\n
\n ${cat.label}\n ${app.status}\n ${app.budget ? html`budget ${app.budget}` : ''}\n ${app.adr ? html`${app.adr}` : ''}\n ${app.events?.length ? html`events ${app.events.join('·')}` : ''}\n
\n
\n ${app.crate}\n this.toggle(app)}>\n
\n
\n `;\n }\n}\n","/* Toast notification — shown briefly via window.dispatchEvent('nv-toast', detail). */\nimport { LitElement, html, css } from 'lit';\nimport { customElement, state } from 'lit/decorators.js';\n\n@customElement('nv-toast')\nexport class NvToast extends LitElement {\n @state() private visible = false;\n @state() private msg = '';\n @state() private icon = '✓';\n private timer: number | null = null;\n\n static styles = css`\n :host {\n position: fixed; bottom: 24px; left: 50%;\n transform: translateX(-50%) translateY(80px);\n background: var(--bg-2);\n border: 1px solid var(--line-2);\n border-radius: var(--radius);\n padding: 10px 14px;\n font-size: 12.5px;\n box-shadow: var(--shadow);\n z-index: 100;\n opacity: 0; pointer-events: none;\n transition: opacity 0.2s, transform 0.2s;\n display: flex; align-items: center; gap: 8px;\n }\n :host([visible]) {\n opacity: 1;\n transform: translateX(-50%) translateY(0);\n pointer-events: auto;\n }\n .icon { color: var(--accent); }\n `;\n\n override connectedCallback(): void {\n super.connectedCallback();\n window.addEventListener('nv-toast', this.onToast as EventListener);\n }\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n window.removeEventListener('nv-toast', this.onToast as EventListener);\n }\n\n private onToast = (e: Event): void => {\n const detail = (e as CustomEvent).detail as { msg?: string; icon?: string };\n this.msg = detail.msg ?? 'Done';\n this.icon = detail.icon ?? '✓';\n this.visible = true;\n this.setAttribute('visible', '');\n if (this.timer !== null) window.clearTimeout(this.timer);\n this.timer = window.setTimeout(() => {\n this.visible = false;\n this.removeAttribute('visible');\n }, 1800);\n };\n\n override render() {\n return html`${this.icon}${this.msg}`;\n }\n}\n\nexport function toast(msg: string, icon = '✓'): void {\n window.dispatchEvent(new CustomEvent('nv-toast', { detail: { msg, icon } }));\n}\n","/* Modal dialog — opened via window.dispatchEvent('nv-modal', { title, body, buttons }). */\nimport { LitElement, html, css } from 'lit';\nimport { customElement, state } from 'lit/decorators.js';\n\ninterface ModalButton {\n label: string;\n variant?: 'ghost' | 'primary' | 'danger';\n onClick?: () => void;\n}\ninterface ModalReq {\n title: string;\n body: string;\n buttons?: ModalButton[];\n}\n\n@customElement('nv-modal')\nexport class NvModal extends LitElement {\n @state() private open = false;\n @state() private mTitle = '';\n @state() private mBody = '';\n @state() private buttons: ModalButton[] = [];\n\n static styles = css`\n :host {\n position: fixed; inset: 0;\n background: rgba(0,0,0,0.55);\n backdrop-filter: blur(4px);\n z-index: 200;\n display: grid; place-items: center;\n opacity: 0; pointer-events: none;\n transition: opacity 0.18s;\n }\n :host([open]) { opacity: 1; pointer-events: auto; }\n .modal {\n background: var(--bg-1);\n border: 1px solid var(--line-2);\n border-radius: var(--radius);\n box-shadow: 0 30px 80px -20px rgba(0,0,0,0.7);\n width: min(520px, 92vw);\n max-height: 86vh;\n display: flex; flex-direction: column;\n transform: translateY(12px) scale(0.98);\n transition: transform 0.22s cubic-bezier(0.2,0.7,0.3,1);\n }\n :host([open]) .modal { transform: translateY(0) scale(1); }\n .h {\n padding: 14px 16px;\n border-bottom: 1px solid var(--line);\n display: flex; align-items: center; justify-content: space-between;\n }\n .h .ttl { font-size: 14px; font-weight: 600; }\n .body { padding: 16px; overflow-y: auto; font-size: 13px; color: var(--ink-2); line-height: 1.55; }\n .f {\n padding: 12px 16px;\n border-top: 1px solid var(--line);\n display: flex; gap: 8px; justify-content: flex-end;\n }\n button {\n padding: 6px 12px;\n border-radius: 8px;\n font-size: 12.5px;\n cursor: pointer;\n font-family: inherit;\n border: 1px solid var(--line);\n background: var(--bg-2); color: var(--ink);\n }\n button.ghost { background: transparent; }\n button.primary { background: var(--accent); border-color: var(--accent); color: #1a0f00; }\n button.danger { background: var(--bad); border-color: var(--bad); color: #fff; }\n .close {\n width: 28px; height: 28px;\n background: transparent; border: 1px solid var(--line);\n border-radius: 6px;\n color: var(--ink-2);\n }\n `;\n\n override connectedCallback(): void {\n super.connectedCallback();\n window.addEventListener('nv-modal', this.onModal as EventListener);\n window.addEventListener('keydown', this.onKey);\n }\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n window.removeEventListener('nv-modal', this.onModal as EventListener);\n window.removeEventListener('keydown', this.onKey);\n }\n\n private onModal = (e: Event): void => {\n const r = (e as CustomEvent).detail as ModalReq;\n this.mTitle = r.title; this.mBody = r.body;\n this.buttons = r.buttons ?? [{ label: 'Close', variant: 'primary' }];\n this.open = true; this.setAttribute('open', '');\n };\n\n private onKey = (e: KeyboardEvent): void => {\n if (e.key === 'Escape' && this.open) this.close();\n };\n\n private close(): void { this.open = false; this.removeAttribute('open'); }\n private clickBtn(b: ModalButton): void { b.onClick?.(); this.close(); }\n\n override render() {\n return html`\n
\n
\n
${this.mTitle}
\n \n
\n
\n
\n ${this.buttons.map((b) => html`\n \n `)}\n
\n
\n `;\n }\n}\n\nexport function openModal(req: ModalReq): void {\n window.dispatchEvent(new CustomEvent('nv-modal', { detail: req }));\n}\n","/* Command palette ⌘K. */\nimport { LitElement, html, css } from 'lit';\nimport { customElement, state, query } from 'lit/decorators.js';\nimport { toast } from './nv-toast';\nimport { openModal } from './nv-modal';\nimport {\n getClient, theme, expectedWitness, witnessHex, witnessVerified, pushLog, running,\n} from '../store/appStore';\n\ninterface Cmd { ico: string; label: string; kbd?: string; run: () => void; }\n\n@customElement('nv-palette')\nexport class NvPalette extends LitElement {\n @state() private open = false;\n @state() private filter = '';\n @state() private idx = 0;\n @query('#palette-input') private inputEl!: HTMLInputElement;\n\n static styles = css`\n :host {\n position: fixed; inset: 0; z-index: 220;\n background: rgba(0,0,0,0.5);\n opacity: 0; pointer-events: none;\n transition: opacity 0.15s;\n display: flex; justify-content: center; padding-top: 12vh;\n backdrop-filter: blur(4px);\n }\n :host([open]) { opacity: 1; pointer-events: auto; }\n .palette {\n width: min(560px, 92vw);\n background: var(--bg-1);\n border: 1px solid var(--line-2);\n border-radius: var(--radius);\n box-shadow: 0 30px 80px -20px rgba(0,0,0,0.7);\n overflow: hidden;\n display: flex; flex-direction: column;\n max-height: 60vh;\n }\n .input {\n padding: 14px 16px;\n border-bottom: 1px solid var(--line);\n }\n input {\n width: 100%;\n background: transparent; border: none; outline: none;\n color: var(--ink); font-size: 14px;\n font-family: inherit;\n }\n .list { flex: 1; overflow-y: auto; padding: 4px; }\n .item {\n display: flex; align-items: center; gap: 10px;\n padding: 8px 12px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12.5px;\n }\n .item.active { background: var(--bg-3); }\n .item .ico { width: 20px; text-align: center; color: var(--accent); }\n .item .lbl { flex: 1; }\n .item .kbd {\n font-family: var(--mono); font-size: 10.5px;\n color: var(--ink-3);\n padding: 1px 5px; background: var(--bg-3); border-radius: 4px;\n }\n `;\n\n private cmds: Cmd[] = [\n { ico: '▶', label: 'Run pipeline', kbd: 'Space', run: async () => { await getClient()?.run(); running.value = true; toast('Pipeline running', '▶'); } },\n { ico: '❚', label: 'Pause pipeline', run: async () => { await getClient()?.pause(); running.value = false; toast('Paused', '❚❚'); } },\n { ico: '⟳', label: 'Reset pipeline', kbd: '⌘R', run: () => openModal({\n title: 'Reset pipeline?',\n body: '

Clears the frame stream and rewinds t to 0.

',\n buttons: [\n { label: 'Cancel', variant: 'ghost' },\n { label: 'Reset', variant: 'danger', onClick: async () => { await getClient()?.reset(); pushLog('warn', 'pipeline reset · t=0'); toast('Pipeline reset', '⟳'); } },\n ],\n }) },\n { ico: '✓', label: 'Verify witness', run: async () => {\n const c = getClient(); if (!c) return;\n witnessVerified.value = 'pending';\n const exp = expectedWitness.value;\n const eb = new Uint8Array(32);\n for (let i = 0; i < 32; i++) eb[i] = parseInt(exp.slice(i * 2, i * 2 + 2), 16);\n const r = await c.verifyWitness(eb);\n if (r.ok) { witnessVerified.value = 'ok'; witnessHex.value = exp; toast('Witness verified', '✓'); }\n else { witnessVerified.value = 'fail'; toast('Witness mismatch!', '✗'); }\n } },\n { ico: '☼', label: 'Toggle theme', kbd: '⌘/', run: () => { theme.value = theme.value === 'dark' ? 'light' : 'dark'; } },\n { ico: '⚙', label: 'Open settings', kbd: '⌘,', run: () => window.dispatchEvent(new CustomEvent('open-settings')) },\n { ico: '?', label: 'Keyboard shortcuts…', run: () => openModal({\n title: 'Keyboard shortcuts',\n body: `
\n
⌘K / Ctrl K
Command palette
\n
Space
Play / pause
\n
⌘R
Reset
\n
⌘,
Settings
\n
⌘/
Toggle theme
\n
\\`
Debug HUD
\n
1 · 2 · 3
Inspector tabs
\n
Esc
Close modal/palette
\n
/
Focus REPL
\n
`,\n buttons: [{ label: 'Close', variant: 'primary' }],\n }) },\n { ico: 'i', label: 'About nvsim…', run: () => openModal({\n title: 'About nvsim',\n body: `

nvsim is a deterministic, byte-reproducible forward simulator for nitrogen-vacancy diamond magnetometry.

\n

This dashboard runs nvsim as WASM in a Web Worker. Same (scene, config, seed) → byte-identical SHA-256 witness across runs and machines.

\n

License: MIT OR Apache-2.0 · See ADR-089, ADR-092.

`,\n buttons: [{ label: 'Close', variant: 'primary' }],\n }) },\n ];\n\n override connectedCallback(): void {\n super.connectedCallback();\n window.addEventListener('keydown', this.onKey);\n window.addEventListener('nv-palette', this.onOpen as EventListener);\n }\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n window.removeEventListener('keydown', this.onKey);\n window.removeEventListener('nv-palette', this.onOpen as EventListener);\n }\n\n private onKey = (e: KeyboardEvent): void => {\n if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {\n e.preventDefault();\n this.openPal();\n } else if (e.key === 'Escape' && this.open) {\n this.closePal();\n } else if (this.open) {\n if (e.key === 'ArrowDown') { this.idx = Math.min(this.cmds.length - 1, this.idx + 1); e.preventDefault(); }\n else if (e.key === 'ArrowUp') { this.idx = Math.max(0, this.idx - 1); e.preventDefault(); }\n else if (e.key === 'Enter') { this.runIdx(); e.preventDefault(); }\n }\n };\n\n private onOpen = (): void => this.openPal();\n\n private openPal(): void {\n this.open = true; this.setAttribute('open', '');\n this.filter = ''; this.idx = 0;\n setTimeout(() => this.inputEl?.focus(), 0);\n }\n private closePal(): void { this.open = false; this.removeAttribute('open'); }\n\n private filtered(): Cmd[] {\n if (!this.filter.trim()) return this.cmds;\n const q = this.filter.toLowerCase();\n return this.cmds.filter((c) => c.label.toLowerCase().includes(q));\n }\n\n private runIdx(): void {\n const f = this.filtered();\n const c = f[this.idx];\n if (c) { c.run(); this.closePal(); }\n }\n\n override render() {\n const items = this.filtered();\n return html`\n
\n
\n { this.filter = (e.target as HTMLInputElement).value; this.idx = 0; }} />\n
\n
\n ${items.map((c, i) => html`\n
{ this.idx = i; this.runIdx(); }}>\n ${c.ico}\n ${c.label}\n ${c.kbd ? html`${c.kbd}` : ''}\n
\n `)}\n
\n
\n `;\n }\n}\n","/* Debug HUD toggled with `. Shows render fps, sim t, frames, |B|, SNR. */\nimport { LitElement, html, css } from 'lit';\nimport { customElement, state } from 'lit/decorators.js';\nimport { effect } from '@preact/signals-core';\nimport { fps, framesEmitted, bMag, snr, t as simT } from '../store/appStore';\n\n@customElement('nv-debug-hud')\nexport class NvDebugHud extends LitElement {\n @state() private open = false;\n @state() private renderFps = 0;\n private lastTs = performance.now();\n private frameCount = 0;\n private rafId = 0;\n\n static styles = css`\n :host {\n position: fixed; bottom: 8px; right: 8px;\n width: 220px;\n background: rgba(13,17,23,0.85);\n backdrop-filter: blur(8px);\n border: 1px solid var(--line-2);\n border-radius: 8px;\n padding: 8px 10px;\n font-family: var(--mono); font-size: 11px;\n color: var(--ink-2);\n z-index: 99;\n display: none;\n box-shadow: var(--shadow);\n }\n :host([open]) { display: block; }\n .h {\n display: flex; justify-content: space-between;\n font-weight: 600; color: var(--ink);\n margin-bottom: 6px; padding-bottom: 4px;\n border-bottom: 1px solid var(--line);\n }\n .x { cursor: pointer; color: var(--ink-3); }\n .row {\n display: flex; justify-content: space-between;\n padding: 1px 0;\n }\n .k { color: var(--ink-3); }\n .v { color: var(--ink); }\n `;\n\n override connectedCallback(): void {\n super.connectedCallback();\n window.addEventListener('keydown', this.onKey);\n effect(() => { fps.value; framesEmitted.value; bMag.value; snr.value; simT.value; this.requestUpdate(); });\n this.tick();\n }\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n window.removeEventListener('keydown', this.onKey);\n cancelAnimationFrame(this.rafId);\n }\n\n private onKey = (e: KeyboardEvent): void => {\n if (e.key === '`' && !(e.target as HTMLElement).matches('input, textarea')) {\n this.open = !this.open;\n this.toggleAttribute('open', this.open);\n }\n };\n\n private tick = (): void => {\n this.rafId = requestAnimationFrame(this.tick);\n const now = performance.now();\n this.frameCount++;\n if (now - this.lastTs >= 500) {\n this.renderFps = (this.frameCount * 1000) / (now - this.lastTs);\n this.frameCount = 0;\n this.lastTs = now;\n this.requestUpdate();\n }\n };\n\n override render() {\n return html`\n
nvsim · debug { this.open = false; this.removeAttribute('open'); }}>✕
\n
render fps${this.renderFps.toFixed(1)}
\n
sim fps${fps.value > 0 ? Math.round(fps.value) : '—'}
\n
frames${framesEmitted.value.toString()}
\n
|B|${(bMag.value * 1e9).toFixed(3)} nT
\n
SNR${snr.value > 0 ? snr.value.toFixed(1) : '—'}
\n
DOM${document.querySelectorAll('*').length}
\n `;\n }\n}\n","/* Settings drawer — theme / density / motion / auto-update. */\nimport { LitElement, html, css } from 'lit';\nimport { customElement, state } from 'lit/decorators.js';\nimport { effect } from '@preact/signals-core';\nimport { theme, density, motionReduced, autoUpdate, transport, wsUrl } from '../store/appStore';\n\n@customElement('nv-settings-drawer')\nexport class NvSettingsDrawer extends LitElement {\n @state() private open = false;\n\n static styles = css`\n :host {\n position: fixed; top: 0; right: 0; bottom: 0;\n width: 420px; max-width: 100vw;\n background: var(--bg-1);\n border-left: 1px solid var(--line);\n z-index: 51;\n transform: translateX(100%);\n transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n display: flex; flex-direction: column;\n box-shadow: -20px 0 60px -20px rgba(0,0,0,0.5);\n }\n :host([open]) { transform: translateX(0); }\n .scrim {\n position: fixed; inset: 0;\n background: rgba(0,0,0,0.5);\n z-index: 50;\n opacity: 0; pointer-events: none;\n transition: opacity 0.2s;\n }\n :host([open]) .scrim { opacity: 1; pointer-events: auto; }\n .h {\n padding: 14px 16px;\n border-bottom: 1px solid var(--line);\n display: flex; align-items: center; justify-content: space-between;\n }\n .h .ttl { font-size: 14px; font-weight: 600; }\n .body { flex: 1; overflow-y: auto; padding: 16px; }\n .group { margin-bottom: 22px; }\n .group h4 {\n margin: 0 0 10px;\n font-size: 11px; font-weight: 600;\n text-transform: uppercase; letter-spacing: 0.08em;\n color: var(--ink-3);\n }\n .row {\n display: flex; justify-content: space-between; align-items: center;\n padding: 10px 0;\n border-bottom: 1px solid var(--line);\n }\n .row:last-child { border-bottom: 0; }\n .row .lbl { font-size: 13px; }\n .row .desc { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }\n .row > div:first-child { flex: 1; padding-right: 12px; }\n .seg {\n display: inline-flex;\n background: var(--bg-3);\n border: 1px solid var(--line);\n border-radius: var(--radius-sm);\n padding: 2px;\n }\n .seg button {\n padding: 4px 10px;\n background: transparent; border: none;\n border-radius: 6px;\n font-size: 11.5px; color: var(--ink-3);\n font-family: var(--mono);\n cursor: pointer;\n }\n .seg button.on { background: var(--bg-1); color: var(--ink); }\n .toggle {\n position: relative;\n width: 36px; height: 20px;\n background: var(--bg-3);\n border: 1px solid var(--line-2);\n border-radius: 999px;\n cursor: pointer;\n flex-shrink: 0;\n }\n .toggle::after {\n content: ''; position: absolute;\n top: 2px; left: 2px;\n width: 14px; height: 14px;\n background: var(--ink-3);\n border-radius: 50%;\n transition: transform 0.15s, background 0.15s;\n }\n .toggle.on { background: var(--accent); border-color: var(--accent); }\n .toggle.on::after { background: #1a0f00; transform: translateX(16px); }\n .close {\n width: 28px; height: 28px;\n background: transparent; border: 1px solid var(--line);\n border-radius: 6px;\n color: var(--ink-2);\n }\n input[type=\"text\"] {\n background: var(--bg-3);\n border: 1px solid var(--line);\n border-radius: 6px;\n padding: 6px 10px;\n color: var(--ink); font-family: var(--mono); font-size: 12px;\n outline: none;\n }\n `;\n\n override connectedCallback(): void {\n super.connectedCallback();\n effect(() => { theme.value; density.value; motionReduced.value; autoUpdate.value; transport.value; wsUrl.value; this.requestUpdate(); });\n window.addEventListener('open-settings', () => { this.open = true; this.setAttribute('open', ''); });\n }\n\n private close(): void { this.open = false; this.removeAttribute('open'); }\n\n override render() {\n return html`\n
this.close()}>
\n
\n
Settings
\n \n
\n
\n
\n

Appearance

\n
\n
Theme
\n
\n \n \n
\n
\n
\n
\n
Density
\n
Affects panel padding and font scale.
\n
\n
\n \n \n \n
\n
\n
\n
\n
Reduce motion
\n
Disable rotating crystal & field-line animation.
\n
\n motionReduced.value = !motionReduced.value}>\n
\n
\n\n
\n

Pipeline

\n
\n
Auto-rerun on edit
\n
Restart pipeline when scene/config changes.
\n autoUpdate.value = !autoUpdate.value}>\n
\n
\n\n
\n

Transport

\n
\n
Mode
\n
\n \n \n
\n
\n ${transport.value === 'ws' ? html`\n
\n
WS URL
\n wsUrl.value = (e.target as HTMLInputElement).value} />\n
` : ''}\n
\n
\n `;\n }\n}\n","/* First-run welcome tour. 5 steps walking the user through the\n * dashboard's main concepts. Persists `seen` flag in IndexedDB so it\n * only shows the first time. ADR-092 §10 Pass 6.\n */\n\nimport { LitElement, html, css } from 'lit';\nimport { customElement, state } from 'lit/decorators.js';\nimport { kvGet, kvSet } from '../store/persistence';\n\ninterface TourStep {\n title: string;\n body: string;\n cta?: string;\n}\n\nconst STEPS: TourStep[] = [\n {\n title: 'Welcome to nvsim',\n body: `

nvsim is an open-source, deterministic forward simulator for\n nitrogen-vacancy diamond magnetometry — a real Rust crate compiled to\n WASM and running in your browser, right now.

\n

This 30-second tour highlights the four panels you'll use most.

`,\n cta: 'Start tour',\n },\n {\n title: '1. Scene canvas',\n body: `

The middle panel shows your magnetic scene — sources you can\n drag (rebar, heart proxy, mains hum, ferrous door) and a single NV-diamond\n sensor in the centre. Field lines from each source connect to the sensor\n and animate while the pipeline runs.

\n

Click 2 on your keyboard any time to jump to the Frame inspector.

`,\n },\n {\n title: '2. Run the pipeline',\n body: `

Click the ▶ Run button (top-right) to start streaming\n MagFrame records at the digitiser's sample rate. The B-vector\n trace and Frame stream sparkline update live, and the FPS pill in the\n topbar shows the simulator's throughput in kHz.

\n

Space toggles run/pause from anywhere.

`,\n },\n {\n title: '3. Witness panel',\n body: `

The Witness tab is the heart of nvsim's determinism contract.\n Click Verify and the pipeline re-derives the SHA-256 over a 256-frame\n reference run and asserts it matches the constant pinned in the Rust crate.

\n

Same input → same hash → byte-for-byte across browsers, OSes, transports.\n If the hash drifts, your build is non-canonical.

`,\n },\n {\n title: '4. App Store',\n body: `

The grid icon on the left rail opens the App Store — every\n hot-loadable WASM edge module RuView ships, plus the simulators. 66 apps\n across 13 categories: medical, security, building, retail, industrial,\n signal, learning, autonomy, and more.

\n

Toggle any card to mark it active in this session; the WS transport\n will push the activation set to a connected ESP32 mesh.

`,\n },\n {\n title: 'You are ready',\n body: `

Press ⌘K (or Ctrl K) any time for the command\n palette, ? for the full shortcuts list, or just start clicking.

\n

Source on GitHub:\n github.com/ruvnet/RuView · ADR-089, ADR-092 · MIT/Apache-2.0.

`,\n cta: 'Get started',\n },\n];\n\n@customElement('nv-onboarding')\nexport class NvOnboarding extends LitElement {\n @state() private open = false;\n @state() private step = 0;\n\n static styles = css`\n :host {\n position: fixed; inset: 0;\n background: rgba(0, 0, 0, 0.55);\n backdrop-filter: blur(4px);\n z-index: 240;\n display: grid; place-items: center;\n opacity: 0; pointer-events: none;\n transition: opacity 0.18s;\n }\n :host([open]) { opacity: 1; pointer-events: auto; }\n .card {\n background: var(--bg-1);\n border: 1px solid var(--line-2);\n border-radius: var(--radius);\n box-shadow: 0 30px 80px -20px rgba(0,0,0,0.7);\n width: min(560px, 92vw);\n max-height: 86vh;\n display: flex; flex-direction: column;\n transform: translateY(12px) scale(0.98);\n transition: transform 0.22s cubic-bezier(0.2,0.7,0.3,1);\n }\n :host([open]) .card { transform: translateY(0) scale(1); }\n .h {\n padding: 20px 22px 8px;\n display: flex; justify-content: space-between; align-items: flex-start;\n }\n .h h2 { margin: 0; font-size: 18px; letter-spacing: -0.01em; }\n .body {\n padding: 8px 22px 16px;\n font-size: 13px; color: var(--ink-2); line-height: 1.55;\n overflow-y: auto;\n }\n .body p { margin: 0 0 12px; }\n .body code, .body kbd {\n font-family: var(--mono); font-size: 11.5px;\n padding: 1px 5px; background: var(--bg-3);\n border: 1px solid var(--line); border-radius: 4px;\n color: var(--accent);\n }\n .footer {\n display: flex; align-items: center; gap: 12px;\n padding: 12px 22px;\n border-top: 1px solid var(--line);\n }\n .dots { display: flex; gap: 6px; flex: 1; }\n .dot {\n width: 6px; height: 6px; border-radius: 50%;\n background: var(--bg-3); border: 1px solid var(--line-2);\n }\n .dot.active { background: var(--accent); border-color: var(--accent); }\n button {\n padding: 8px 14px;\n border-radius: 8px;\n font-size: 12.5px; font-weight: 500;\n border: 1px solid var(--line);\n background: var(--bg-2); color: var(--ink);\n cursor: pointer;\n font-family: inherit;\n }\n button.primary {\n background: var(--accent); border-color: var(--accent);\n color: #1a0f00;\n }\n button.ghost { background: transparent; }\n .skip {\n width: 28px; height: 28px;\n background: transparent; border: 1px solid var(--line);\n border-radius: 6px; color: var(--ink-2);\n }\n `;\n\n override async connectedCallback(): Promise {\n super.connectedCallback();\n window.addEventListener('nv-show-tour', this.show as EventListener);\n const seen = await kvGet('onboarding-seen');\n if (!seen) {\n this.open = true;\n this.setAttribute('open', '');\n }\n }\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n window.removeEventListener('nv-show-tour', this.show as EventListener);\n }\n\n private show = (): void => {\n this.step = 0;\n this.open = true;\n this.setAttribute('open', '');\n };\n\n private async dismiss(): Promise {\n this.open = false;\n this.removeAttribute('open');\n await kvSet('onboarding-seen', true);\n }\n\n private next(): void {\n if (this.step < STEPS.length - 1) this.step++;\n else void this.dismiss();\n }\n\n private prev(): void {\n if (this.step > 0) this.step--;\n }\n\n override render() {\n const s = STEPS[this.step];\n return html`\n
\n
\n

${s.title}

\n \n
\n
\n
\n
\n ${STEPS.map((_, i) => html`
`)}\n
\n ${this.step > 0\n ? html``\n : ''}\n \n
\n
\n `;\n }\n}\n","/* Ghost Murmur — research view.\n *\n * Walks through the publicly-reported April 2026 CIA program and maps\n * the physically-defensible parts onto RuView's three-tier heartbeat\n * mesh. Source: docs/research/quantum-sensing/16-ghost-murmur-ruview-spec.md\n *\n * This view is reference material, not an operational mode. It exists\n * so practitioners (and journalists) can audit the physics-vs-press\n * gap in the open. ADR-092 §14b.\n */\n\nimport { LitElement, html, css } from 'lit';\nimport { customElement } from 'lit/decorators.js';\n\n@customElement('nv-ghost-murmur')\nexport class NvGhostMurmur extends LitElement {\n static styles = css`\n :host {\n display: block;\n height: 100%;\n overflow-y: auto;\n background: radial-gradient(ellipse at 50% 30%, var(--bg-2) 0%, var(--bg-0) 70%);\n padding: 24px 28px 60px;\n }\n h1 {\n margin: 0 0 4px;\n font-size: 22px;\n letter-spacing: -0.02em;\n color: var(--ink);\n }\n .subtitle {\n color: var(--ink-3);\n font-size: 13px;\n margin-bottom: 22px;\n }\n .links {\n display: flex; flex-wrap: wrap; gap: 6px;\n margin-bottom: 22px;\n }\n .links a {\n padding: 5px 10px;\n background: var(--bg-2);\n border: 1px solid var(--line);\n border-radius: 999px;\n font-size: 11.5px;\n font-family: var(--mono);\n color: var(--accent-2);\n text-decoration: none;\n }\n .links a:hover { border-color: var(--accent-2); }\n h2 {\n font-size: 14px;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: var(--ink-3);\n margin: 28px 0 10px;\n }\n .grid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: 12px;\n }\n .card {\n background: var(--bg-2);\n border: 1px solid var(--line);\n border-radius: var(--radius);\n padding: 14px;\n }\n .card h3 {\n margin: 0 0 8px;\n font-size: 13.5px; font-weight: 600;\n color: var(--ink);\n }\n .card p {\n font-size: 12.5px; color: var(--ink-2);\n margin: 0 0 8px;\n line-height: 1.5;\n }\n .card p:last-child { margin-bottom: 0; }\n .stat {\n display: inline-flex; align-items: baseline; gap: 6px;\n margin-right: 10px;\n }\n .stat .v {\n font-family: var(--mono); font-size: 16px; font-weight: 600;\n color: var(--accent);\n }\n .stat .l {\n font-size: 10px; color: var(--ink-3);\n text-transform: uppercase; letter-spacing: 0.04em;\n }\n table {\n width: 100%; border-collapse: collapse;\n font-size: 12.5px;\n }\n th, td {\n padding: 8px 10px;\n text-align: left;\n border-bottom: 1px solid var(--line);\n }\n th {\n color: var(--ink-3);\n font-weight: 600;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n }\n td.amber { color: var(--accent); font-family: var(--mono); }\n td.cyan { color: var(--accent-2); font-family: var(--mono); }\n td.bad { color: var(--bad); font-family: var(--mono); }\n .pill {\n display: inline-block;\n padding: 1px 6px;\n border-radius: 4px;\n font-family: var(--mono);\n font-size: 10px;\n border: 1px solid var(--line);\n }\n .pill.ok { color: var(--ok); border-color: oklch(0.78 0.14 145 / 0.4); }\n .pill.skeptical { color: var(--bad); border-color: oklch(0.65 0.22 25 / 0.4); }\n .pill.partial { color: var(--warn); border-color: oklch(0.7 0.18 35 / 0.4); }\n .architecture {\n font-family: var(--mono);\n font-size: 11px;\n color: var(--ink-2);\n background: var(--bg-3);\n padding: 16px;\n border-radius: var(--radius-sm);\n border: 1px solid var(--line);\n white-space: pre;\n overflow-x: auto;\n line-height: 1.4;\n }\n .ethics {\n background: linear-gradient(180deg, var(--bg-2) 0%, oklch(0.65 0.22 25 / 0.04) 100%);\n border: 1px solid oklch(0.65 0.22 25 / 0.25);\n border-radius: var(--radius);\n padding: 16px;\n }\n .ethics h3 { color: var(--bad); margin-top: 0; }\n .ethics ul { padding-left: 18px; margin: 8px 0; }\n .ethics li { font-size: 12.5px; color: var(--ink-2); margin-bottom: 4px; }\n `;\n\n override render() {\n return html`\n

Ghost Murmur — open-source reality check

\n
\n The physics-vs-press audit for the publicly-reported April 2026\n CIA NV-diamond heartbeat detector, and how RuView's existing\n stack maps onto an honest, civilian version of the same idea.\n
\n\n \n\n

What the press reported

\n
\n
\n

The story

\n

3 Apr 2026: USAF F-15E pilot \"Dude 44 Bravo\" goes down in southern Iran during the regional exchange and evades for ~2 days.

\n

President Trump publicly suggests detection from 40 miles away on a mountainside at night; CIA Director Ratcliffe says \"invisible to the enemy, but not to the CIA.\"

\n
\n
\n

The named tech

\n

\"Ghost Murmur\" — Lockheed Skunk Works system using NV defects in synthetic diamond + AI to extract a heartbeat from environmental noise.

\n

Outlets: Newsweek, Scientific American, Military.com, WION, Open The Magazine, Yahoo, Calcalist + HN thread #47679241.

\n
\n
\n

What physicists said

\n

Wikswo (Vanderbilt), Orzel (Union College), Roth (Oakland) — all pushing back hard.

\n

\"At 1 km, the heartbeat field drops to ~10⁻¹² of its 10 cm value.\" MCG-only at multi-mile range is not consistent with published physics.

\n
\n
\n\n

Physics reality check

\n
\n \n \n \n \n \n \n \n \n \n \n \n
DistanceCardiac MCG (peak QRS)vs Earth field (~50 µT)
10 cm50 pT10⁹× weaker
1 m50 fT10¹²× weaker
10 m50 aT10¹⁵× weaker
1 km5 × 10⁻²³ T10²⁷× weaker
40 mi (65 km)~10⁻²⁸ T10³³× weaker
\n

\n Best published NV-ensemble lab record: 0.9 pT/√Hz [Wolf 2015].\n Best SQUID in a shielded room: ~1 fT/√Hz. To detect a single heartbeat at 10 m\n you'd need ~2 billion× more sensitivity than any published ensemble has ever shown,\n in a magnetically silent environment. 40 miles is press-release physics.\n

\n
\n\n

RuView's three-tier mesh — what is actually buildable

\n
┌──────────────────────────┐\n │ Tier 3 — NV-diamond │ Range: 0.1–2 m (lab)\n │ magnetometer ring │ Status: nvsim simulator only\n │ (close-confirm) │ Hardware: $$$ (≥$8k DNV-B1)\n └──────────┬───────────────┘\n │\n ┌──────────┴───────────────┐\n │ Tier 2 — 60 GHz FMCW │ Range: 1–10 m HR/BR\n │ mmWave radar mesh │ Status: shipping (ADR-021)\n │ (vital signs, posture) │ Hardware: $15 (MR60BHA2 + ESP32-C6)\n └──────────┬───────────────┘\n │\n ┌──────────┴───────────────┐\n │ Tier 1 — WiFi CSI mesh │ Range: 10–30 m through-wall\n │ (presence, breathing, │ Status: shipping (ADR-014, ADR-029)\n │ pose, intention) │ Hardware: $9 (ESP32-S3 8MB)\n └──────────┬───────────────┘\n │\n ▼\n ┌────────────────────────────────┐\n │ RuvSense multistatic fusion │\n │ + cross-viewpoint attention │\n │ + AETHER re-ID embeddings │\n │ + Cramer-Rao gating │\n └────────────────────────────────┘
\n\n

Press claim → RuView equivalent

\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
Press claimRuView equivalent todayCrate / ADRHonest range
NV-diamond magnetometryDeterministic NV pipeline simulatornvsim · ADR-089Simulator only
\"AI strips environmental noise\"RuvSense multistatic fusion + AETHERsignal/ruvsense/ · ADR-029Mature
Heartbeat at distance60 GHz FMCW HR/BR + WiFi CSI breathingvitals · ADR-0211–5 m HR · 10–30 m presence
Long-range localisationMultistatic time-of-flight + CRLBruvector/viewpoint/Limited by node spacing
40-mile single-heartbeat detectionNot feasible at any tierPress-release physics
\n
\n\n

Build today on $165

\n
\n
\n

Bill of materials

\n

\n 3 × ESP32-S3 8 MB ($9 ea)
\n 3 × PoE injector + cat6 ($6 ea)
\n 1 × ESP32-C6 + Seeed MR60BHA2 ($15)
\n 1 × Raspberry Pi 5 8 GB ($80)
\n 1 × unmanaged GbE switch ($25)\n

\n

Total: $165

\n
\n
\n

Honest performance

\n 95%TPR (LOS, 0–15 m)

\n ±2 bpmHR (LOS 0–3 m)

\n ±1 br/minBR (any mode)

\n ~10 cmpose error

\n 80–150 msend-to-end latency\n
\n
\n

Determinism

\n

Same (scene, config, seed) → byte-identical SHA-256 witness across browsers, OSes, transports.

\n

Reference: cc8de9b01b0ff5bd…

\n

Try the Witness tab on the right — it re-derives the hash live in this browser and compares against the published reference.

\n
\n
\n\n

Privacy, ethics, legal

\n
\n

This is the open-source version. Same physics, opposite governance.

\n
    \n
  • Civilian opt-in only — search-and-rescue, elder-care, occupancy, ICU vitals. Not surveillance.
  • \n
  • No directional pursuit — no beam-steering, target-following, or remote person-of-interest tracking.
  • \n
  • Data minimisation — fused output is (presence, HR, BR, pose, p_alive); raw streams discarded at the edge.
  • \n
  • PII gates (ADR-040) block identifying biometric streams from leaving the local mesh without consent.
  • \n
  • Adversarial-signal detection flags physically-impossible signal patterns from compromised mesh nodes.
  • \n
  • No export-controlled hardware — RuView targets < $50 COTS. ITAR/EAR sub-THz coherent radars and shielded NV ensembles are out of scope.
  • \n
\n

\n RuView is not affiliated with the United States government, the CIA, Lockheed Martin,\n or any classified program. References to \"Ghost Murmur\" in this view refer\n exclusively to the publicly-reported program of that name as covered in the open\n press in April 2026.\n

\n
\n\n

Cross-references

\n
\n

\n ADRs: 014 (signal) · 021 (vitals) · 024 (AETHER) · 027 (MERIDIAN) ·\n 028 (witness audit) · 029 (RuvSense) · 040 (PII gates) · 086 (ESP32 RaBitQ) ·\n 089 (nvsim, Accepted) · 090 (Lindblad, Proposed-conditional) ·\n 091 (sub-THz radar research) · 092 (this dashboard).

\n Primary physics: Cohen 1970 · Bison 2009 · Wolf 2015 · Barry RMP 2020 · Doherty 2013 · Jackson 3e §5.6/§5.8.\n

\n
\n `;\n }\n}\n","/* Top-level shell: 4-zone grid with rail / topbar / sidebar / scene / inspector / console.\n * View routing is per-rail-button: the central area swaps between\n * ``, ``, etc. */\n\nimport { LitElement, html, css } from 'lit';\nimport { customElement, state } from 'lit/decorators.js';\nimport './nv-rail';\nimport './nv-topbar';\nimport './nv-sidebar';\nimport './nv-scene';\nimport './nv-inspector';\nimport './nv-console';\nimport './nv-app-store';\nimport './nv-toast';\nimport './nv-modal';\nimport './nv-palette';\nimport './nv-debug-hud';\nimport './nv-settings-drawer';\nimport './nv-onboarding';\nimport './nv-ghost-murmur';\n\nexport type View = 'scene' | 'apps' | 'inspector' | 'witness' | 'ghost-murmur';\n\n@customElement('nv-app')\nexport class NvApp extends LitElement {\n @state() private view: View = 'scene';\n\n static styles = css`\n :host {\n display: block;\n height: 100vh;\n width: 100vw;\n background: var(--bg-0);\n }\n .app {\n display: grid;\n grid-template-columns: 56px 280px 1fr 340px;\n grid-template-rows: 48px 1fr 220px;\n grid-template-areas:\n 'rail topbar topbar topbar'\n 'rail sidebar main inspector'\n 'rail sidebar console inspector';\n height: 100vh;\n width: 100vw;\n }\n nv-rail { grid-area: rail; }\n nv-topbar { grid-area: topbar; }\n nv-sidebar { grid-area: sidebar; }\n .main { grid-area: main; min-width: 0; min-height: 0; position: relative; overflow: hidden; }\n nv-inspector { grid-area: inspector; }\n nv-console { grid-area: console; min-height: 0; }\n @media (max-width: 1180px) {\n .app {\n grid-template-columns: 56px 1fr 320px;\n grid-template-areas:\n 'rail topbar topbar'\n 'rail main inspector'\n 'rail console console';\n }\n nv-sidebar { display: none; }\n }\n @media (max-width: 860px) {\n .app {\n grid-template-columns: 1fr;\n grid-template-rows: 52px 1fr 200px;\n grid-template-areas:\n 'topbar'\n 'main'\n 'console';\n }\n nv-rail, nv-sidebar, nv-inspector { display: none; }\n }\n `;\n\n override render() {\n return html`\n
\n ) => (this.view = e.detail)}>\n \n \n
\n ${this.view === 'apps'\n ? html``\n : this.view === 'ghost-murmur'\n ? html``\n : html``}\n
\n \n \n \n
\n \n \n \n \n \n \n `;\n }\n}\n","/* Common NvsimClient interface — both WasmClient and WsClient implement it.\n * Dashboard binds to this interface and never to a concrete client.\n * Aligns with ADR-092 §5.2.\n */\n\nexport interface PipelineConfigJson {\n digitiser?: {\n f_s_hz: number;\n f_mod_hz: number;\n lp_cutoff_hz: number;\n };\n sensor?: {\n n_centers: number;\n contrast: number;\n t2_star_s: number;\n shot_noise_disabled?: boolean;\n };\n dt_s?: number | null;\n}\n\nexport interface SceneJson {\n dipoles: { position: [number, number, number]; moment: [number, number, number] }[];\n loops: {\n centre: [number, number, number];\n normal: [number, number, number];\n radius: number;\n current: number;\n n_segments: number;\n }[];\n ferrous: {\n position: [number, number, number];\n volume: number;\n susceptibility: number;\n }[];\n eddy: unknown[];\n sensors: [number, number, number][];\n ambient_field: [number, number, number];\n}\n\nexport interface MagFrameRecord {\n magic: number;\n version: number;\n flags: number;\n sensorId: number;\n tUs: bigint;\n bPt: [number, number, number];\n sigmaPt: [number, number, number];\n noiseFloorPtSqrtHz: number;\n temperatureK: number;\n raw: Uint8Array;\n}\n\nexport interface MagFrameBatch {\n frames: MagFrameRecord[];\n bytes: Uint8Array;\n}\n\nexport type NvsimEvent =\n | { type: 'log'; level: 'info' | 'warn' | 'err' | 'dbg' | 'ok'; msg: string }\n | { type: 'witness'; hex: string }\n | { type: 'fps'; value: number }\n | { type: 'state'; running: boolean; t: number; framesEmitted: number };\n\nexport interface RunOpts { frames?: number }\n\nexport interface NvsimClient {\n loadScene(scene: SceneJson): Promise;\n setConfig(cfg: PipelineConfigJson): Promise;\n setSeed(seed: bigint): Promise;\n reset(): Promise;\n run(opts?: RunOpts): Promise;\n pause(): Promise;\n step(direction: 'fwd' | 'back', dtMs: number): Promise;\n\n onFrames(cb: (batch: MagFrameBatch) => void): void;\n onEvent(cb: (ev: NvsimEvent) => void): void;\n\n generateWitness(samples: number): Promise;\n verifyWitness(expected: Uint8Array): Promise<{ ok: true } | { ok: false; actual: Uint8Array }>;\n exportProofBundle(): Promise;\n\n buildId(): Promise;\n close(): Promise;\n}\n\n/** Parse one MagFrame from a 60-byte slice. Layout matches `nvsim::frame`. */\nexport function parseMagFrame(view: DataView, offset: number, raw: Uint8Array): MagFrameRecord {\n // v1 layout: magic(u32) | version(u16) | flags(u16) | sensor_id(u16) | _reserved(u16) |\n // t_us(u64) | b_pt[3](f32) | sigma_pt[3](f32) | noise_floor_pt_sqrt_hz(f32) |\n // temperature_k(f32) — 60 bytes total. All little-endian.\n const magic = view.getUint32(offset + 0, true);\n const version = view.getUint16(offset + 4, true);\n const flags = view.getUint16(offset + 6, true);\n const sensorId = view.getUint16(offset + 8, true);\n // skip 2 bytes reserved at offset+10\n const tUs = view.getBigUint64(offset + 12, true);\n const bx = view.getFloat32(offset + 20, true);\n const by = view.getFloat32(offset + 24, true);\n const bz = view.getFloat32(offset + 28, true);\n const sx = view.getFloat32(offset + 32, true);\n const sy = view.getFloat32(offset + 36, true);\n const sz = view.getFloat32(offset + 40, true);\n const noiseFloorPtSqrtHz = view.getFloat32(offset + 44, true);\n const temperatureK = view.getFloat32(offset + 48, true);\n return {\n magic,\n version,\n flags,\n sensorId,\n tUs,\n bPt: [bx, by, bz],\n sigmaPt: [sx, sy, sz],\n noiseFloorPtSqrtHz,\n temperatureK,\n raw: raw.subarray(offset, offset + 60),\n };\n}\n\nexport function parseFrameBatch(bytes: Uint8Array): MagFrameRecord[] {\n const frameSize = 60;\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const out: MagFrameRecord[] = [];\n for (let off = 0; off + frameSize <= bytes.byteLength; off += frameSize) {\n out.push(parseMagFrame(view, off, bytes));\n }\n return out;\n}\n","/* Default `NvsimClient` implementation. Talks to the Web Worker that\n * hosts the nvsim WASM module. ADR-092 §5.4 + §6.3. */\n\nimport {\n type NvsimClient,\n type SceneJson,\n type PipelineConfigJson,\n type RunOpts,\n type MagFrameBatch,\n type NvsimEvent,\n parseFrameBatch,\n} from './NvsimClient';\n\ninterface PendingRequest {\n resolve: (v: T) => void;\n reject: (err: Error) => void;\n}\n\nexport interface WasmBootInfo {\n buildVersion: string;\n frameMagic: number;\n frameBytes: number;\n expectedWitnessHex: string;\n}\n\nexport class WasmClient implements NvsimClient {\n private worker: Worker;\n private nextId = 1;\n private pending = new Map>();\n private frameSubs = new Set<(b: MagFrameBatch) => void>();\n private eventSubs = new Set<(e: NvsimEvent) => void>();\n private bootInfo: WasmBootInfo | null = null;\n\n constructor() {\n this.worker = new Worker(new URL('./worker.ts', import.meta.url), { type: 'module' });\n this.worker.addEventListener('message', (ev) => this.onMessage(ev));\n this.worker.addEventListener('error', (e) =>\n this.eventSubs.forEach((s) => s({ type: 'log', level: 'err', msg: String(e.message) })),\n );\n }\n\n private onMessage(ev: MessageEvent): void {\n const m = ev.data as { type: string; id?: number; [k: string]: unknown };\n if (m.type === 'frames') {\n const buf = m.batch as ArrayBuffer;\n const bytes = new Uint8Array(buf);\n const frames = parseFrameBatch(bytes);\n const batch: MagFrameBatch = { frames, bytes };\n this.frameSubs.forEach((s) => s(batch));\n const fps = m.fps as number;\n if (fps > 0) {\n this.eventSubs.forEach((s) => s({ type: 'fps', value: fps }));\n }\n return;\n }\n if (m.type === 'state') {\n this.eventSubs.forEach((s) =>\n s({\n type: 'state',\n running: Boolean(m.running),\n t: 0,\n framesEmitted: Number(m.framesEmitted ?? 0),\n }),\n );\n return;\n }\n if (m.type === 'ready') {\n return;\n }\n if (m.type === 'err' && m.id == null) {\n this.eventSubs.forEach((s) =>\n s({ type: 'log', level: 'err', msg: String(m.msg) }),\n );\n return;\n }\n if (typeof m.id === 'number' && this.pending.has(m.id)) {\n const p = this.pending.get(m.id)!;\n this.pending.delete(m.id);\n if (m.type === 'err') p.reject(new Error(String(m.msg)));\n else p.resolve(m);\n }\n }\n\n private rpc(msg: Record, transfer: Transferable[] = []): Promise {\n const id = this.nextId++;\n return new Promise((resolve, reject) => {\n this.pending.set(id, { resolve: resolve as (v: unknown) => void, reject });\n this.worker.postMessage({ ...msg, id }, transfer);\n });\n }\n\n async boot(): Promise {\n if (this.bootInfo) return this.bootInfo;\n // Pass Vite's resolved BASE_URL so the worker can locate /nvsim-pkg/\n // under the same prefix the dashboard is served from (e.g. /RuView/nvsim/\n // on GitHub Pages, \"/\" in dev).\n const base = import.meta.env.BASE_URL ?? '/';\n const r = await this.rpc<{ buildVersion: string; frameMagic: number; frameBytes: number; expectedWitnessHex: string }>(\n { type: 'boot', base },\n );\n this.bootInfo = {\n buildVersion: r.buildVersion,\n frameMagic: r.frameMagic,\n frameBytes: r.frameBytes,\n expectedWitnessHex: r.expectedWitnessHex,\n };\n return this.bootInfo;\n }\n\n async loadScene(scene: SceneJson): Promise {\n await this.rpc({ type: 'setScene', json: JSON.stringify(scene) });\n }\n\n async setConfig(cfg: PipelineConfigJson): Promise {\n await this.rpc({ type: 'setConfig', json: JSON.stringify(cfg) });\n }\n\n async setSeed(seed: bigint): Promise {\n await this.rpc({ type: 'setSeed', seed: Number(seed & 0xFFFFFFFFn) });\n }\n\n async reset(): Promise {\n await this.rpc({ type: 'reset' });\n }\n\n async run(_opts?: RunOpts): Promise {\n await this.rpc({ type: 'run' });\n }\n\n async pause(): Promise {\n await this.rpc({ type: 'pause' });\n }\n\n async step(_direction: 'fwd' | 'back', _dtMs: number): Promise {\n await this.rpc({ type: 'step' });\n }\n\n onFrames(cb: (batch: MagFrameBatch) => void): void { this.frameSubs.add(cb); }\n onEvent(cb: (ev: NvsimEvent) => void): void { this.eventSubs.add(cb); }\n\n async generateWitness(samples: number): Promise {\n const r = await this.rpc<{ witness: ArrayBuffer; hex: string }>({ type: 'witnessGenerate', samples });\n return new Uint8Array(r.witness);\n }\n\n async verifyWitness(expected: Uint8Array): Promise<{ ok: true } | { ok: false; actual: Uint8Array }> {\n const buf = expected.slice().buffer;\n const r = await this.rpc<{ ok: boolean; actual: ArrayBuffer; actualHex: string }>(\n { type: 'witnessVerify', samples: 256, expected: buf },\n [buf],\n );\n if (r.ok) return { ok: true };\n return { ok: false, actual: new Uint8Array(r.actual) };\n }\n\n async exportProofBundle(): Promise {\n // Bundle = REFERENCE_SCENE_JSON + computed witness hex + version. Wraps\n // the same artifacts `Proof::generate` produces natively. ADR-092 §6.1.\n const w = await this.generateWitness(256);\n const hex = Array.from(w).map((b) => b.toString(16).padStart(2, '0')).join('');\n const info = this.bootInfo ?? (await this.boot());\n const manifest = JSON.stringify(\n {\n kind: 'nvsim-proof-bundle',\n version: info.buildVersion,\n seed: '0x0000002A',\n nSamples: 256,\n witness: hex,\n expected: info.expectedWitnessHex,\n ok: hex === info.expectedWitnessHex,\n ts: new Date().toISOString(),\n },\n null,\n 2,\n );\n return new Blob([manifest], { type: 'application/json' });\n }\n\n async buildId(): Promise {\n const r = await this.rpc<{ buildId: string }>({ type: 'buildId' });\n return r.buildId;\n }\n\n async close(): Promise {\n this.worker.terminate();\n }\n}\n","/* nvsim dashboard entry — boots the WasmClient, mounts . */\nimport './app.css';\nimport './components/nv-app';\nimport { effect } from '@preact/signals-core';\n\nimport { WasmClient } from './transport/WasmClient';\nimport {\n setClient, transport, theme, density, motionReduced,\n pushLog, expectedWitness, framesEmitted, fps, lastB, bMag,\n pushTrace, pushStripBar, lastFrame, sceneJson, witnessHex,\n} from './store/appStore';\nimport { kvGet, kvSet } from './store/persistence';\n\nfunction applyTheme(t: string): void {\n document.documentElement.setAttribute('data-theme', t);\n}\nfunction applyDensity(d: string): void {\n document.body.classList.remove('density-comfy', 'density-default', 'density-compact');\n document.body.classList.add(`density-${d}`);\n}\nfunction applyMotion(reduced: boolean): void {\n document.body.classList.toggle('reduce-motion', reduced);\n}\n\n(async () => {\n // Restore persisted prefs\n const t = (await kvGet<'dark' | 'light'>('theme')) ?? 'dark';\n const d = (await kvGet<'comfy' | 'default' | 'compact'>('density')) ?? 'default';\n const m = (await kvGet('motionReduced')) ?? false;\n theme.value = t; applyTheme(t);\n density.value = d; applyDensity(d);\n motionReduced.value = m; applyMotion(m);\n\n // React to changes → persist\n effect(() => { applyTheme(theme.value); kvSet('theme', theme.value); });\n effect(() => { applyDensity(density.value); kvSet('density', density.value); });\n effect(() => { applyMotion(motionReduced.value); kvSet('motionReduced', motionReduced.value); });\n\n // Boot WASM client\n const client = new WasmClient();\n setClient(client);\n\n pushLog('info', 'nvsim — booting WASM runtime');\n client.onEvent((ev) => {\n if (ev.type === 'log') pushLog(ev.level, ev.msg);\n if (ev.type === 'fps') fps.value = ev.value;\n if (ev.type === 'state') {\n framesEmitted.value = BigInt(ev.framesEmitted);\n }\n });\n\n client.onFrames((batch) => {\n if (batch.frames.length === 0) return;\n const last = batch.frames[batch.frames.length - 1];\n lastFrame.value = last;\n const bx = last.bPt[0] * 1e-12; // pT → T\n const by = last.bPt[1] * 1e-12;\n const bz = last.bPt[2] * 1e-12;\n lastB.value = [bx, by, bz];\n bMag.value = Math.sqrt(bx * bx + by * by + bz * bz);\n // For trace display we use nT scale.\n pushTrace([bx * 1e9, by * 1e9, bz * 1e9]);\n const amp = Math.min(1, Math.abs(bz * 1e9) / 5 + 0.3);\n pushStripBar(amp);\n });\n\n try {\n const info = await client.boot();\n expectedWitness.value = info.expectedWitnessHex;\n pushLog('ok', `WASM module ready · nvsim@${info.buildVersion} · magic=0x${info.frameMagic.toString(16).toUpperCase()}`);\n pushLog('info', `expected witness · ${info.expectedWitnessHex.slice(0, 16)}…`);\n\n // Load reference scene by default.\n sceneJson.value = '(reference scene)';\n transport.value = 'wasm';\n } catch (e) {\n pushLog('err', `boot failed: ${(e as Error).message}`);\n }\n\n // Auto-verify witness once at boot — proves WASM determinism contract.\n try {\n const exp = expectedWitness.value;\n if (exp) {\n const expBytes = new Uint8Array(32);\n for (let i = 0; i < 32; i++) expBytes[i] = parseInt(exp.slice(i * 2, i * 2 + 2), 16);\n const r = await client.verifyWitness(expBytes);\n if (r.ok) {\n witnessHex.value = exp;\n pushLog('ok', `witness verified · determinism gate ✓`);\n } else {\n const actual = Array.from(r.actual)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('');\n witnessHex.value = actual;\n pushLog('err', `WITNESS MISMATCH · expected ${exp.slice(0, 16)}… got ${actual.slice(0, 16)}…`);\n }\n }\n } catch (e) {\n pushLog('warn', `witness verify skipped: ${(e as Error).message}`);\n }\n})();\n"],"names":["t","e","o","r","n","i","s","c","NvRail","LitElement","v","html","css","__decorateClass","property","customElement","transport","signal","wsUrl","running","framesEmitted","seed","fs","fmod","dtMs","noiseEnabled","theme","density","motionReduced","autoUpdate","lastB","bMag","snr","fps","witnessHex","witnessVerified","expectedWitness","lastFrame","traceX","traceY","traceZ","stripBars","sceneName","sceneJson","consolePaused","consoleFilter","transportLabel","computed","_client","setClient","getClient","consoleLines","MAX_LINES","pushLog","level","msg","next","pushTrace","b","x","y","z","pushStripBar","amp","NvTopbar","effect","seedHex","NvSidebar","NvScene","id","item","svgEl","pt","it","vbX","vbY","bnT","bMagNT","animClass","svg","state","NvInspector","changed","exp","expBytes","actual","make","arr","p","f","bytes","hex","status","cls","label","NvConsole","body","l","line","cmd","args","arg","filter","visible","k","ts","tsStr","query","APPS","CATEGORIES","defaultActivations","a","fuzzyMatch","app","q","score","DB_NAME","DB_VER","STORE","dbPromise","openDb","resolve","reject","req","db","kvGet","key","kvSet","value","tx","activations","activeCat","statusFilter","saved","NvAppStore","list","counts","activeCount","active","cat","NvToast","detail","toast","icon","NvModal","openModal","NvPalette","eb","items","NvDebugHud","now","simT","NvSettingsDrawer","STEPS","NvOnboarding","_","NvGhostMurmur","NvApp","parseMagFrame","view","offset","raw","magic","version","flags","sensorId","tUs","bx","by","bz","sx","sy","sz","noiseFloorPtSqrtHz","temperatureK","parseFrameBatch","out","off","WasmClient","ev","m","buf","batch","transfer","scene","cfg","_opts","_direction","_dtMs","cb","samples","expected","w","info","manifest","applyTheme","applyDensity","d","applyMotion","reduced","client","last"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4]} \ No newline at end of file diff --git a/nvsim/index.html b/nvsim/index.html index f33dfd4e..57646cc9 100644 --- a/nvsim/index.html +++ b/nvsim/index.html @@ -10,7 +10,7 @@ - + diff --git a/nvsim/sw.js b/nvsim/sw.js index 30816a43..6d7fe31f 100644 --- a/nvsim/sw.js +++ b/nvsim/sw.js @@ -1,2 +1,2 @@ -if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const c=e||("document"in self?document.currentScript.src:"")||location.href;if(s[c])return;let d={};const o=e=>i(e,c),l={module:{uri:c},exports:d,require:o};s[c]=Promise.all(n.map(e=>l[e]||o(e))).then(e=>(r(...e),d))}}define(["./workbox-8c29f6e4"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"registerSW.js",revision:"4bcaa063d693b37532f242f566232490"},{url:"index.html",revision:"cb26da184b8d91f8e9bc1910e87fd519"},{url:"icon-512.svg",revision:"98fc1c8102c279bf1c0dd52559821ddc"},{url:"icon-192.svg",revision:"e73b6aa9016dca426a59e0f8ff4f1b04"},{url:"nvsim-pkg/nvsim_bg.wasm",revision:"b510b70684796cc95dd7fb5bb0d23df7"},{url:"nvsim-pkg/nvsim.js",revision:"ec3b99fbf8131dc1b3d86dc2ae0cf7b8"},{url:"assets/worker-BW0kLvYS.js",revision:null},{url:"assets/signals-SG45zFCj.js",revision:null},{url:"assets/lit-BS7WqYd5.js",revision:null},{url:"assets/index-CyUCBwRA.css",revision:null},{url:"assets/index-C2Z9YIJa.js",revision:null},{url:"icon-192.svg",revision:"e73b6aa9016dca426a59e0f8ff4f1b04"},{url:"icon-512.svg",revision:"98fc1c8102c279bf1c0dd52559821ddc"},{url:"nvsim-pkg/nvsim.js",revision:"ec3b99fbf8131dc1b3d86dc2ae0cf7b8"},{url:"nvsim-pkg/nvsim_bg.wasm",revision:"b510b70684796cc95dd7fb5bb0d23df7"},{url:"manifest.webmanifest",revision:"e8c97968cae19a0ed3b64c1303a27a90"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))}); +if(!self.define){let s,e={};const i=(i,n)=>(i=new URL(i+".js",n).href,e[i]||new Promise(e=>{if("document"in self){const s=document.createElement("script");s.src=i,s.onload=e,document.head.appendChild(s)}else s=i,importScripts(i),e()}).then(()=>{let s=e[i];if(!s)throw new Error(`Module ${i} didn’t register its module`);return s}));self.define=(n,r)=>{const c=s||("document"in self?document.currentScript.src:"")||location.href;if(e[c])return;let d={};const l=s=>i(s,c),o={module:{uri:c},exports:d,require:l};e[c]=Promise.all(n.map(s=>o[s]||l(s))).then(s=>(r(...s),d))}}define(["./workbox-8c29f6e4"],function(s){"use strict";self.skipWaiting(),s.clientsClaim(),s.precacheAndRoute([{url:"registerSW.js",revision:"4bcaa063d693b37532f242f566232490"},{url:"index.html",revision:"934dcb4a251b1c4907091ce92f5ac9d0"},{url:"icon-512.svg",revision:"98fc1c8102c279bf1c0dd52559821ddc"},{url:"icon-192.svg",revision:"e73b6aa9016dca426a59e0f8ff4f1b04"},{url:"nvsim-pkg/nvsim_bg.wasm",revision:"b510b70684796cc95dd7fb5bb0d23df7"},{url:"nvsim-pkg/nvsim.js",revision:"ec3b99fbf8131dc1b3d86dc2ae0cf7b8"},{url:"assets/worker-BW0kLvYS.js",revision:null},{url:"assets/signals-SG45zFCj.js",revision:null},{url:"assets/lit-BS7WqYd5.js",revision:null},{url:"assets/index-CyUCBwRA.css",revision:null},{url:"assets/index-BWlL4FHH.js",revision:null},{url:"icon-192.svg",revision:"e73b6aa9016dca426a59e0f8ff4f1b04"},{url:"icon-512.svg",revision:"98fc1c8102c279bf1c0dd52559821ddc"},{url:"nvsim-pkg/nvsim.js",revision:"ec3b99fbf8131dc1b3d86dc2ae0cf7b8"},{url:"nvsim-pkg/nvsim_bg.wasm",revision:"b510b70684796cc95dd7fb5bb0d23df7"},{url:"manifest.webmanifest",revision:"e8c97968cae19a0ed3b64c1303a27a90"}],{}),s.cleanupOutdatedCaches(),s.registerRoute(new s.NavigationRoute(s.createHandlerBoundToURL("index.html")))}); //# sourceMappingURL=sw.js.map diff --git a/nvsim/sw.js.map b/nvsim/sw.js.map index b9f5c434..455d5360 100644 --- a/nvsim/sw.js.map +++ b/nvsim/sw.js.map @@ -1 +1 @@ -{"version":3,"file":"sw.js","sources":["../../../AppData/Local/Temp/4f9d042f382c206d714057826365f38b/sw.js"],"sourcesContent":["import {clientsClaim as workbox_core_clientsClaim} from 'C:/Users/ruv/Projects/wifi-densepose/dashboard/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from 'C:/Users/ruv/Projects/wifi-densepose/dashboard/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from 'C:/Users/ruv/Projects/wifi-densepose/dashboard/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';\nimport {registerRoute as workbox_routing_registerRoute} from 'C:/Users/ruv/Projects/wifi-densepose/dashboard/node_modules/workbox-routing/registerRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from 'C:/Users/ruv/Projects/wifi-densepose/dashboard/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from 'C:/Users/ruv/Projects/wifi-densepose/dashboard/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"registerSW.js\",\n \"revision\": \"4bcaa063d693b37532f242f566232490\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"cb26da184b8d91f8e9bc1910e87fd519\"\n },\n {\n \"url\": \"icon-512.svg\",\n \"revision\": \"98fc1c8102c279bf1c0dd52559821ddc\"\n },\n {\n \"url\": \"icon-192.svg\",\n \"revision\": \"e73b6aa9016dca426a59e0f8ff4f1b04\"\n },\n {\n \"url\": \"nvsim-pkg/nvsim_bg.wasm\",\n \"revision\": \"b510b70684796cc95dd7fb5bb0d23df7\"\n },\n {\n \"url\": \"nvsim-pkg/nvsim.js\",\n \"revision\": \"ec3b99fbf8131dc1b3d86dc2ae0cf7b8\"\n },\n {\n \"url\": \"assets/worker-BW0kLvYS.js\",\n \"revision\": null\n },\n {\n \"url\": \"assets/signals-SG45zFCj.js\",\n \"revision\": null\n },\n {\n \"url\": \"assets/lit-BS7WqYd5.js\",\n \"revision\": null\n },\n {\n \"url\": \"assets/index-CyUCBwRA.css\",\n \"revision\": null\n },\n {\n \"url\": \"assets/index-C2Z9YIJa.js\",\n \"revision\": null\n },\n {\n \"url\": \"icon-192.svg\",\n \"revision\": \"e73b6aa9016dca426a59e0f8ff4f1b04\"\n },\n {\n \"url\": \"icon-512.svg\",\n \"revision\": \"98fc1c8102c279bf1c0dd52559821ddc\"\n },\n {\n \"url\": \"nvsim-pkg/nvsim.js\",\n \"revision\": \"ec3b99fbf8131dc1b3d86dc2ae0cf7b8\"\n },\n {\n \"url\": \"nvsim-pkg/nvsim_bg.wasm\",\n \"revision\": \"b510b70684796cc95dd7fb5bb0d23df7\"\n },\n {\n \"url\": \"manifest.webmanifest\",\n \"revision\": \"e8c97968cae19a0ed3b64c1303a27a90\"\n }\n], {});\nworkbox_precaching_cleanupOutdatedCaches();\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"index.html\")));\n\n\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","url","revision","workbox_precaching_cleanupOutdatedCaches","workbox","registerRoute","workbox_routing_NavigationRoute","NavigationRoute","workbox_precaching_createHandlerBoundToURL"],"mappings":"inBAwBAA,KAAKC,cAELC,EAAAA,eAQAC,EAAAA,iBAAoC,CAClC,CACEC,IAAO,gBACPC,SAAY,oCAEd,CACED,IAAO,aACPC,SAAY,oCAEd,CACED,IAAO,eACPC,SAAY,oCAEd,CACED,IAAO,eACPC,SAAY,oCAEd,CACED,IAAO,0BACPC,SAAY,oCAEd,CACED,IAAO,qBACPC,SAAY,oCAEd,CACED,IAAO,4BACPC,SAAY,MAEd,CACED,IAAO,6BACPC,SAAY,MAEd,CACED,IAAO,yBACPC,SAAY,MAEd,CACED,IAAO,4BACPC,SAAY,MAEd,CACED,IAAO,2BACPC,SAAY,MAEd,CACED,IAAO,eACPC,SAAY,oCAEd,CACED,IAAO,eACPC,SAAY,oCAEd,CACED,IAAO,qBACPC,SAAY,oCAEd,CACED,IAAO,0BACPC,SAAY,oCAEd,CACED,IAAO,uBACPC,SAAY,qCAEb,CAAE,GACLC,EAAAA,wBAC6BC,EAAAC,cAAC,IAAIC,EAA+BC,gBAACC,0BAA2C"} \ No newline at end of file +{"version":3,"file":"sw.js","sources":["../../../AppData/Local/Temp/19f266b374f78468c3fcf58fd5709833/sw.js"],"sourcesContent":["import {clientsClaim as workbox_core_clientsClaim} from 'C:/Users/ruv/Projects/wifi-densepose/dashboard/node_modules/workbox-core/clientsClaim.mjs';\nimport {precacheAndRoute as workbox_precaching_precacheAndRoute} from 'C:/Users/ruv/Projects/wifi-densepose/dashboard/node_modules/workbox-precaching/precacheAndRoute.mjs';\nimport {cleanupOutdatedCaches as workbox_precaching_cleanupOutdatedCaches} from 'C:/Users/ruv/Projects/wifi-densepose/dashboard/node_modules/workbox-precaching/cleanupOutdatedCaches.mjs';\nimport {registerRoute as workbox_routing_registerRoute} from 'C:/Users/ruv/Projects/wifi-densepose/dashboard/node_modules/workbox-routing/registerRoute.mjs';\nimport {NavigationRoute as workbox_routing_NavigationRoute} from 'C:/Users/ruv/Projects/wifi-densepose/dashboard/node_modules/workbox-routing/NavigationRoute.mjs';\nimport {createHandlerBoundToURL as workbox_precaching_createHandlerBoundToURL} from 'C:/Users/ruv/Projects/wifi-densepose/dashboard/node_modules/workbox-precaching/createHandlerBoundToURL.mjs';/**\n * Welcome to your Workbox-powered service worker!\n *\n * You'll need to register this file in your web app.\n * See https://goo.gl/nhQhGp\n *\n * The rest of the code is auto-generated. Please don't update this file\n * directly; instead, make changes to your Workbox build configuration\n * and re-run your build process.\n * See https://goo.gl/2aRDsh\n */\n\n\n\n\n\n\n\n\nself.skipWaiting();\n\nworkbox_core_clientsClaim();\n\n\n/**\n * The precacheAndRoute() method efficiently caches and responds to\n * requests for URLs in the manifest.\n * See https://goo.gl/S9QRab\n */\nworkbox_precaching_precacheAndRoute([\n {\n \"url\": \"registerSW.js\",\n \"revision\": \"4bcaa063d693b37532f242f566232490\"\n },\n {\n \"url\": \"index.html\",\n \"revision\": \"934dcb4a251b1c4907091ce92f5ac9d0\"\n },\n {\n \"url\": \"icon-512.svg\",\n \"revision\": \"98fc1c8102c279bf1c0dd52559821ddc\"\n },\n {\n \"url\": \"icon-192.svg\",\n \"revision\": \"e73b6aa9016dca426a59e0f8ff4f1b04\"\n },\n {\n \"url\": \"nvsim-pkg/nvsim_bg.wasm\",\n \"revision\": \"b510b70684796cc95dd7fb5bb0d23df7\"\n },\n {\n \"url\": \"nvsim-pkg/nvsim.js\",\n \"revision\": \"ec3b99fbf8131dc1b3d86dc2ae0cf7b8\"\n },\n {\n \"url\": \"assets/worker-BW0kLvYS.js\",\n \"revision\": null\n },\n {\n \"url\": \"assets/signals-SG45zFCj.js\",\n \"revision\": null\n },\n {\n \"url\": \"assets/lit-BS7WqYd5.js\",\n \"revision\": null\n },\n {\n \"url\": \"assets/index-CyUCBwRA.css\",\n \"revision\": null\n },\n {\n \"url\": \"assets/index-BWlL4FHH.js\",\n \"revision\": null\n },\n {\n \"url\": \"icon-192.svg\",\n \"revision\": \"e73b6aa9016dca426a59e0f8ff4f1b04\"\n },\n {\n \"url\": \"icon-512.svg\",\n \"revision\": \"98fc1c8102c279bf1c0dd52559821ddc\"\n },\n {\n \"url\": \"nvsim-pkg/nvsim.js\",\n \"revision\": \"ec3b99fbf8131dc1b3d86dc2ae0cf7b8\"\n },\n {\n \"url\": \"nvsim-pkg/nvsim_bg.wasm\",\n \"revision\": \"b510b70684796cc95dd7fb5bb0d23df7\"\n },\n {\n \"url\": \"manifest.webmanifest\",\n \"revision\": \"e8c97968cae19a0ed3b64c1303a27a90\"\n }\n], {});\nworkbox_precaching_cleanupOutdatedCaches();\nworkbox_routing_registerRoute(new workbox_routing_NavigationRoute(workbox_precaching_createHandlerBoundToURL(\"index.html\")));\n\n\n\n\n\n\n"],"names":["self","skipWaiting","workbox_core_clientsClaim","workbox_precaching_precacheAndRoute","url","revision","workbox_precaching_cleanupOutdatedCaches","workbox","registerRoute","workbox_routing_NavigationRoute","NavigationRoute","workbox_precaching_createHandlerBoundToURL"],"mappings":"inBAwBAA,KAAKC,cAELC,EAAAA,eAQAC,EAAAA,iBAAoC,CAClC,CACEC,IAAO,gBACPC,SAAY,oCAEd,CACED,IAAO,aACPC,SAAY,oCAEd,CACED,IAAO,eACPC,SAAY,oCAEd,CACED,IAAO,eACPC,SAAY,oCAEd,CACED,IAAO,0BACPC,SAAY,oCAEd,CACED,IAAO,qBACPC,SAAY,oCAEd,CACED,IAAO,4BACPC,SAAY,MAEd,CACED,IAAO,6BACPC,SAAY,MAEd,CACED,IAAO,yBACPC,SAAY,MAEd,CACED,IAAO,4BACPC,SAAY,MAEd,CACED,IAAO,2BACPC,SAAY,MAEd,CACED,IAAO,eACPC,SAAY,oCAEd,CACED,IAAO,eACPC,SAAY,oCAEd,CACED,IAAO,qBACPC,SAAY,oCAEd,CACED,IAAO,0BACPC,SAAY,oCAEd,CACED,IAAO,uBACPC,SAAY,qCAEb,CAAE,GACLC,EAAAA,wBAC6BC,EAAAC,cAAC,IAAIC,EAA+BC,gBAACC,0BAA2C"} \ No newline at end of file