Project homepage Mailing List  Warmcat.com  API Docs  Github Mirror 
    npro  
 Modern all-safe Rust Network Protocol library supporting h1, h2, h3, ws, wt sans-IO and with socket IO + tls
git clone https://npro.rs/repo/npro
Author[]Andy Green <andy@warmcat.com> 2026-06-18 14:51 UTC
Committer[]Andy Green <andy@warmcat.com> 2026-06-19 04:48 UTC
Tree388baf139196696dc724de4dde1c42491f1d2df3   Raw Patch
 
debug
debug
diff --git a/assets/sai.css b/assets/sai.css index 98b6d57..8ce9d40 100644 --- a/assets/sai.css +++ b/assets/sai.css @@ -738,7 +738,10 @@ div.bdr { } .bdr.offline { - opacity: 0.35; + background: #e0e0e0; + color: #666666; + border: 1px solid #b0b0b0; + filter: grayscale(100%); } /* Style for the powering-up state */ diff --git a/assets/sai.js b/assets/sai.js index db86359..78f0137 100644 --- a/assets/sai.js +++ b/assets/sai.js @@ -1920,6 +1920,46 @@ function renderPconHierarchy(container) { roots.sort(sortByName); pcons.forEach(p => p.children.sort(sortByName)); + const appendBuilderRows = (buildersList, tbody) => { + let prevBaseName = null; + let prevTr = null; + let stackedCount = 0; + + buildersList.forEach(b => { + let baseName = b.name.split('.')[0].replace(/-\d+$/, ''); + if (!b.online && baseName === prevBaseName && prevTr) { + stackedCount++; + const tdInfo = prevTr.querySelector(".builder-info"); + const builderDiv = createBuilderDiv(b); + + /* Stacking visual effect */ + builderDiv.style.position = "absolute"; + builderDiv.style.top = (stackedCount * 6) + "px"; + builderDiv.style.left = (stackedCount * 6) + "px"; + builderDiv.style.zIndex = 10 - stackedCount; + builderDiv.style.boxShadow = "-2px -2px 4px rgba(0,0,0,0.15)"; + + tdInfo.style.position = "relative"; + tdInfo.style.paddingBottom = (stackedCount * 6) + "px"; + tdInfo.style.paddingRight = (stackedCount * 6) + "px"; + + tdInfo.appendChild(builderDiv); + } else { + const tr = createBuilderRow(b); + tbody.appendChild(tr); + prevTr = tr; + prevBaseName = baseName; + stackedCount = 0; + + const builderDiv = tr.querySelector(".builder-info .ibuil"); + if (builderDiv) { + builderDiv.style.position = "relative"; + builderDiv.style.zIndex = 10; + } + } + }); + }; + /* Helper to recursively render PCONs and their builders */ function renderPcon(pcon, parentDiv) { const div = createPconDiv(pcon); @@ -1936,9 +1976,7 @@ function renderPconHierarchy(container) { table.className = "builders"; const tbody = document.createElement("tbody"); table.appendChild(tbody); - myBuilders.forEach(b => { - tbody.appendChild(createBuilderRow(b)); - }); + appendBuilderRows(myBuilders, tbody); childrenContainer.appendChild(table); } @@ -1966,9 +2004,7 @@ function renderPconHierarchy(container) { table.className = "builders"; const tbody = document.createElement("tbody"); table.appendChild(tbody); - orphanBuilders.forEach(b => { - tbody.appendChild(createBuilderRow(b)); - }); + appendBuilderRows(orphanBuilders, tbody); childrenContainer.appendChild(table); container.appendChild(orphanDiv);
Page fetched -1s ago, creation time: 4ms (vhost etag hits: 0%, cache hits: 0%)