miner-ui-5: live-dag.js 2.0.2 (master 86113b40, byte-identical), fps 60 and narrow on the phone-width card, four captures reshot
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 6ba028f725)
|
|
@ -1564,7 +1564,7 @@ if (typeof document !== 'undefined') (function () {
|
|||
function mountDag() {
|
||||
if (dag || typeof IgneumDag === 'undefined' || !$('dag-live')) return;
|
||||
try {
|
||||
dag = IgneumDag.mount($('dag-live'), { compact: true, window: 60, poll: false, mine: mineFn, tooltip: $('dag-tip'), chip: $('dag-chip'), pauseButton: $('dag-pause'),
|
||||
dag = IgneumDag.mount($('dag-live'), { compact: true, window: 60, fps: 60, narrow: window.innerWidth < 720, poll: false, mine: mineFn, tooltip: $('dag-tip'), chip: $('dag-chip'), pauseButton: $('dag-pause'),
|
||||
onSelect: function (b, why) { if (b && why !== 'update') openFull(b.hash); },
|
||||
onState: function (st, why) { if (dagMode === 'failed') return; if (st === 'live' || st === 'stale') { setText('dag-state', st === 'live' ? 'live' : 'behind'); setText('dag-note', st === 'stale' ? (why || '') : (lastLive ? View.liveNote(lastLive) : '')); } } });
|
||||
pollLive();
|
||||
|
|
@ -1594,7 +1594,7 @@ if (typeof document !== 'undefined') (function () {
|
|||
function mountFull() {
|
||||
if (dagFull || typeof IgneumDag === 'undefined') return;
|
||||
if (typeof IgneumProof !== 'undefined' && !proof) proof = IgneumProof.mount($('proof'));
|
||||
dagFull = IgneumDag.mount($('dag-full'), { poll: false, window: 60, mine: mineFn, tooltip: $('dag-tip-full'), chip: $('dag-chip-full'), pauseButton: $('dag-pause-full'),
|
||||
dagFull = IgneumDag.mount($('dag-full'), { poll: false, window: 60, fps: 60, mine: mineFn, tooltip: $('dag-tip-full'), chip: $('dag-chip-full'), pauseButton: $('dag-pause-full'),
|
||||
onWindow: function (w) { setText('z-pct', w + ' s'); },
|
||||
onSelect: function (b) { if (b) inspect(b); else uninspect(); },
|
||||
onPause: function (p) { $('dag-follow').classList.toggle('on', !p); if (proof) proof.setPaused(p || dagFull.getState().state !== 'live'); },
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
/* Igneum DAG / Ember 2.0 (the EMBER 02 renderer pack, 7 Oct 2026) with the real-data presentation options of 2.0.1:
|
||||
/* Igneum DAG / Ember 2.0 (the EMBER 02 renderer pack, 7 Oct 2026) with the narrow options of 2.0.2 (narrow, narrowBreak 720,
|
||||
* narrowWindow 30, narrowLanes 4, narrowMinNode 11; on a phone the window shortens until the viewer sets one, four lanes, bigger
|
||||
* nodes, no hairlines but the selected chain, checkpoint labels as the percent) and the real-data presentation options of 2.0.1:
|
||||
* maxLanes (own key + top keys + others, default 7), minNode (node half-size floor, default 9.5), hairlineAlpha (non-chain
|
||||
* edges, default .12, drawn only within laneReach lanes, default 2, and only a merged block's first parent unless selected),
|
||||
* othersScale (the others lane's size and alpha, default .75), provenGlow (a glow and ring on proven blocks, default on).
|
||||
|
|
@ -50,6 +52,10 @@
|
|||
var maxBlocks=clamp(finite(opts.maxBlocks)?opts.maxBlocks:6000,100,20000);
|
||||
var lag=finite(opts.lagMs)?clamp(opts.lagMs,0,10000):2500;
|
||||
var fps=clamp(finite(opts.fps)?opts.fps:30,10,60), minFrame=1000/fps;
|
||||
// narrow (phones, under narrowBreak px, or opts.narrow true/false): window narrowWindow s until the viewer sets one, at most
|
||||
// narrowLanes lanes, nodes no smaller than narrowMinNode, hairlines off except the selected chain and the selected block,
|
||||
// checkpoint labels as the percent alone. The owner's call of 7 Oct 2026: faster drift, more gap, on a phone.
|
||||
var narrow=false,narrowBreak=finite(opts.narrowBreak)?opts.narrowBreak:720,narrowWindow=clamp(finite(opts.narrowWindow)?opts.narrowWindow:30,30,300),narrowLanes=clamp(finite(opts.narrowLanes)?opts.narrowLanes:4,2,12),narrowMinNode=finite(opts.narrowMinNode)?opts.narrowMinNode:11,baseWindow=0,windowTouched=false;
|
||||
var maxLanes=clamp(finite(opts.maxLanes)?opts.maxLanes:7,2,12), minNode=finite(opts.minNode)?opts.minNode:9.5, hairAlpha=finite(opts.hairlineAlpha)?opts.hairlineAlpha:.12, laneReach=finite(opts.laneReach)?opts.laneReach:2, othersScale=finite(opts.othersScale)?opts.othersScale:.75, provenGlow=opts.provenGlow!==false;
|
||||
var mq=root.matchMedia?root.matchMedia('(prefers-reduced-motion: reduce)'):null;
|
||||
var reduced=mq?mq.matches:false, manualMotion=true;
|
||||
|
|
@ -94,10 +100,13 @@
|
|||
emit('onState',s,reason);redraw();
|
||||
}
|
||||
function layout(){
|
||||
if(!baseWindow)baseWindow=windowS;
|
||||
var wasNarrow=narrow;narrow=opts.narrow===true||(opts.narrow!==false&&!compact&&W>0&&W<narrowBreak);
|
||||
if(narrow!==wasNarrow&&!windowTouched){var nw=narrow?narrowWindow:baseWindow;if(nw!==windowS){windowS=nw;emit('onWindow',windowS);}}
|
||||
padL=compact||W<510?14:W<750?84:106;padR=compact?12:24;padT=compact?29:58;padB=compact?22:38;
|
||||
var start=rightTime()-windowS*1000, end=rightTime()+lag+1000,counts=new Map(),mineKeys=new Set();
|
||||
blocks.forEach(function(b){if(b.ts>=start && b.ts<=end){counts.set(b.miner,(counts.get(b.miner)||0)+1);if(own(b))mineKeys.add(b.miner);}});
|
||||
var capacity=Math.min(maxLanes,Math.max(2,Math.floor((H-padT-padB)/(compact?26:46)))),ids=Array.from(counts.keys());
|
||||
var capacity=Math.min(narrow?narrowLanes:maxLanes,Math.max(2,Math.floor((H-padT-padB)/(compact?26:narrow?40:46)))),ids=Array.from(counts.keys());
|
||||
ids.sort(function(a,b){return (mineKeys.has(b)?1:0)-(mineKeys.has(a)?1:0)||(counts.get(b)-counts.get(a))||a.localeCompare(b);});
|
||||
var chosen=ids.slice(0,ids.length>capacity?capacity-1:capacity);
|
||||
// Preserve existing key order instead of re-ranking every poll. Always keep the user's lane visible.
|
||||
|
|
@ -164,7 +173,7 @@
|
|||
selectedChain:v.filter(function(b){return b.chain;}).length,proven:v.filter(function(b){return b.proven;}).length,
|
||||
own:v.filter(own).length,minerKeys:new Set(v.map(function(b){return b.miner;})).size,
|
||||
lockedCheckpoints:cps.filter(function(c){return c.state==='locked';}).length,paused:paused,following:following,queued:paused?queuedCount:0,
|
||||
invalidRecords:invalid,omittedRecords:omitted,rendered:blocks.length,frames:frameCount,window:windowS,reducedMotion:reduced||!manualMotion,state:state};
|
||||
invalidRecords:invalid,omittedRecords:omitted,rendered:blocks.length,frames:frameCount,window:windowS,narrow:narrow,lanes:lanes.length,reducedMotion:reduced||!manualMotion,state:state};
|
||||
}
|
||||
function poll(){
|
||||
if(destroyed||opts.poll===false||doc.hidden)return;
|
||||
|
|
@ -209,10 +218,10 @@
|
|||
var band=ctx.createLinearGradient(x-20,0,x+36,0);band.addColorStop(0,rgba(col.ember,0));band.addColorStop(.38,rgba(col.ember,locked?.09:.035));band.addColorStop(1,rgba(col.ember,0));ctx.fillStyle=band;ctx.fillRect(x-20,padT-12,56,plotH+12);
|
||||
ctx.strokeStyle=rgba(col.ember,locked?.6:.32);ctx.lineWidth=locked?1.5:1;ctx.setLineDash(locked?[]:[3,6]);ctx.beginPath();ctx.moveTo(x,padT-14);ctx.lineTo(x,H-padB);ctx.stroke();ctx.setLineDash([]);
|
||||
if(burst>0){ctx.strokeStyle=rgba(col.molten,burst*.5);ctx.lineWidth=1;ctx.strokeRect(x-(1-burst)*42,padT-12,(1-burst)*84,plotH+12);}
|
||||
if(!compact && W>510)cpLabels.push({x:x,cp:c,locked:locked});
|
||||
if(!compact && (narrow || W>510))cpLabels.push({x:x,cp:c,locked:locked});
|
||||
});
|
||||
cpLabels.sort(function(a,b){return b.x-a.x;});var cpLast=Infinity;
|
||||
cpLabels.forEach(function(p){var label=(p.locked?'LOCKED':'PENDING')+(p.cp.fraction_total===null?'':' '+Math.round(p.cp.fraction_total*100)+'%'),w=label.length*5.5+22,x=clamp(p.x-w/2,padL,W-padR-w);if(x+w+8>cpLast)return;cpLast=x;
|
||||
cpLabels.forEach(function(p){var pct=p.cp.fraction_total===null||p.cp.fraction_total===undefined?'':Math.round(p.cp.fraction_total*100)+'%',label=narrow?(pct||(p.locked?'LOCKED':'PENDING')):(p.locked?'LOCKED':'PENDING')+(pct?' '+pct:''),w=label.length*5.5+(narrow?14:22),x=clamp(p.x-w/2,padL,W-padR-w);if(x+w+8>cpLast)return;cpLast=x;
|
||||
ctx.fillStyle=col.bg;ctx.strokeStyle=rgba(col.ember,p.locked?.45:.23);rounded(ctx,x,17,w,22,4);ctx.fill();ctx.stroke();ctx.font='9px ui-monospace, monospace';ctx.fillStyle=p.locked?col.ember:col.ash;ctx.textAlign='center';ctx.textBaseline='middle';ctx.fillText(label,x+w/2,28);
|
||||
});
|
||||
// Animate lane transitions without changing their underlying key identity.
|
||||
|
|
@ -220,12 +229,12 @@
|
|||
ctx.save();ctx.beginPath();ctx.rect(padL-1,padT-15,plotW+2,plotH+25);ctx.clip();
|
||||
blocks.forEach(function(b){if(!b.on)return;var bSel=selected&&b.hash===selected;b.parents.forEach(function(hash,pi){var p=view.get(hash);if(!p||!passes(p)||p.x>W-padR||p.x<padL-plotW*.2)return;
|
||||
var path=b.chain&&p.chain,selectedEdge=selected&&(b.hash===selected||p.hash===selected);
|
||||
if(!path&&!selectedEdge){if(pi>0)return;var li=laneOf.has(b.miner)?laneOf.get(b.miner):lanes.length-1,lp=laneOf.has(p.miner)?laneOf.get(p.miner):lanes.length-1;if(Math.abs(li-lp)>laneReach)return;}
|
||||
if(!path&&!selectedEdge){if(narrow||pi>0)return;var li=laneOf.has(b.miner)?laneOf.get(b.miner):lanes.length-1,lp=laneOf.has(p.miner)?laneOf.get(p.miner):lanes.length-1;if(Math.abs(li-lp)>laneReach)return;}
|
||||
if(path||selectedEdge){ctx.strokeStyle=rgba(path?col.ember:col.bone,path?.1:.10);ctx.lineWidth=path?8:4;curve(b,p);ctx.stroke();}
|
||||
ctx.strokeStyle=rgba(path?col.ember:selectedEdge?col.bone:b.color==='red'?col.red:col.ash,path?.68:selectedEdge?.7:hairAlpha);ctx.lineWidth=path?1.65:selectedEdge?1.4:1;curve(b,p);ctx.stroke();
|
||||
var age=t-b.born;if(animate&&age>=0&&age<1400){var f=clamp(age/1150,0,1),pt=pointOn(b,p,f);ctx.shadowBlur=10;ctx.shadowColor=path?col.ember:col.blue;ctx.fillStyle=path?col.molten:col.blue;ctx.beginPath();ctx.arc(pt.x,pt.y,path?2.2:1.65,0,TAU);ctx.fill();ctx.shadowBlur=0;}
|
||||
});});
|
||||
var S=compact?6.5:clamp(lh*.22,minNode,13);
|
||||
var S=compact?6.5:narrow?clamp(lh*.24,narrowMinNode,15):clamp(lh*.22,minNode,13);
|
||||
blocks.forEach(function(b){if(!b.on)return;
|
||||
var age=t-b.born,newness=animate?Math.max(clamp(1-age/1700,0,1),clamp(1-(t-b.changed)/900,0,1)*.65):0;
|
||||
var ink=b.color==='red'?col.red:b.chain?col.ember:b.color==='blue'?col.blue:col.ash;
|
||||
|
|
@ -290,7 +299,7 @@
|
|||
function hit(ev){var p=eventXY(ev),best=null,dist=22*22;blocks.forEach(function(b){if(!b.on)return;var d=(b.x-p.x)**2+(b.y-p.y)**2;if(d<dist){dist=d;best=b;}});return best;}
|
||||
function select(hash,why){if(hash!==null&&!view.has(hash))return false;selected=hash;showTip(hash?view.get(hash):null);emit('onSelect',hash?cloneBlock(view.get(hash)):null,why||'select');redraw();return true;}
|
||||
function engage(onValue){var value=!!onValue;if(engaged===value)return;engaged=value;canvas.classList.toggle('engaged',value);if(chip)chip.hidden=!value;emit('onEngage',value);}
|
||||
function setWindow(seconds){var n=Math.round(clamp(seconds,30,300));if(!finite(n)||n===windowS)return;windowS=n;layout();emit('onWindow',n);emit('onStats',stats());poll();redraw();}
|
||||
function setWindow(seconds){var n=Math.round(clamp(seconds,30,300));if(!finite(n)||n===windowS)return;windowTouched=true;windowS=n;layout();emit('onWindow',n);emit('onStats',stats());poll();redraw();}
|
||||
function zoom(f){if(!finite(f)||f<=0)return;setWindow(windowS*f);}
|
||||
function follow(){following=true;fixedRight=0;if(paused)pausedRight=Date.now()-lag;layout();emit('onFollow',true);redraw();}
|
||||
function setPaused(p){p=!!p;if(paused===p)return;
|
||||
|
|
@ -345,5 +354,5 @@
|
|||
getSnapshot:function(){return {ok:true,state:{stale:state!=='live'},blocks:blocks.map(cloneBlock),finality:{checkpoints:cps.map(function(c){return Object.assign({},c);})}};}};
|
||||
instances.set(canvas,api);if(chip)chip.hidden=true;theme();size();emit('onState',state,reason);if(opts.poll!==false)poll();redraw();return api;
|
||||
}
|
||||
root.IgneumDag={mount:mount,version:'2.0.1'};
|
||||
root.IgneumDag={mount:mount,version:'2.0.2'};
|
||||
})(window);
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 290 KiB After Width: | Height: | Size: 299 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 320 KiB After Width: | Height: | Size: 340 KiB |
|
|
@ -25,7 +25,7 @@ listed in section 6.
|
|||
|
||||
## 2. The chain scene (EMBER 02, taken from the site lane)
|
||||
|
||||
the project lead's renderer pack (11:3x UK): `ui/live-dag.js` (sha256 e78f2d38…, IgneumDag 2.0.1: the site lane's real-data options, maxLanes 7 with the own key first and an OTHERS lane, minNode 9.5, merge hairlines within two lanes, provenGlow; 2.0.0 was 582f2e73…) and `ui/proof-core.js` (c2a094a6…,
|
||||
the project lead's renderer pack (11:3x UK): `ui/live-dag.js` (sha256 82d56565…, IgneumDag 2.0.2, master 9162c847: the phone-width options narrow/narrowWindow 30/narrowLanes 4/narrowMinNode 11, hairlines off when narrow, percent-only checkpoint labels; the app passes fps 60 on both mounts and narrow when the window is under 720 px on the compact card, since compact never auto-narrows; 2.0.1 e78f2d38… added the site lane's real-data options, maxLanes 7 with the own key first and an OTHERS lane, minNode 9.5, merge hairlines within two lanes, provenGlow; 2.0.0 was 582f2e73…) and `ui/proof-core.js` (c2a094a6…,
|
||||
IgneumProof 2.0.0) are byte-identical copies of the site-ui-4 files; the engine serves `proof-core.js` beside
|
||||
`live-dag.js`. The Overview card mounts the compact mode (`compact: true, window: 60, poll: false`); Inspect, or a
|
||||
click on a block, opens the full scene under it with the block inspector in the site's words (Proof in progress /
|
||||
|
|
|
|||