Replace Constellation with Radar sector sweep layout.
VLAN wedges on range rings with a rotating sweep beam, distinct from subnet islands. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,7 +11,8 @@
|
|||||||
laneGuides: [],
|
laneGuides: [],
|
||||||
labelAnchors: [],
|
labelAnchors: [],
|
||||||
bloomPetals: [],
|
bloomPetals: [],
|
||||||
constellationCharts: [],
|
radarSectors: [],
|
||||||
|
radarMaxR: 0,
|
||||||
subnet: "all",
|
subnet: "all",
|
||||||
model: null,
|
model: null,
|
||||||
groupHint: null,
|
groupHint: null,
|
||||||
@@ -253,7 +254,8 @@
|
|||||||
state.laneGuides = [];
|
state.laneGuides = [];
|
||||||
state.labelAnchors = [];
|
state.labelAnchors = [];
|
||||||
state.bloomPetals = [];
|
state.bloomPetals = [];
|
||||||
state.constellationCharts = [];
|
state.radarSectors = [];
|
||||||
|
state.radarMaxR = 0;
|
||||||
setTargets(nodes);
|
setTargets(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,7 +287,8 @@
|
|||||||
state.laneGuides = [];
|
state.laneGuides = [];
|
||||||
state.labelAnchors = [];
|
state.labelAnchors = [];
|
||||||
state.bloomPetals = [];
|
state.bloomPetals = [];
|
||||||
state.constellationCharts = [];
|
state.radarSectors = [];
|
||||||
|
state.radarMaxR = 0;
|
||||||
setTargets(nodes);
|
setTargets(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,100 +342,83 @@
|
|||||||
state.laneGuides = [];
|
state.laneGuides = [];
|
||||||
state.labelAnchors = anchors;
|
state.labelAnchors = anchors;
|
||||||
state.bloomPetals = [];
|
state.bloomPetals = [];
|
||||||
state.constellationCharts = [];
|
state.radarSectors = [];
|
||||||
|
state.radarMaxR = 0;
|
||||||
setTargets(nodes);
|
setTargets(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
function layoutConstellation(devices, cx, cy, w, h) {
|
function layoutRadar(devices, cx, cy, w, h) {
|
||||||
const groups = groupBySubnet(devices);
|
const groups = groupBySubnet(devices);
|
||||||
const nodes = [];
|
const nodes = [];
|
||||||
const anchors = [];
|
const anchors = [];
|
||||||
const charts = [];
|
const sectors = [];
|
||||||
const orbitR = Math.min(w, h) * 0.3;
|
const maxR = Math.min(w, h) * 0.42;
|
||||||
const omeHub = { x: cx, y: cy };
|
|
||||||
const nGroups = Math.max(groups.length, 1);
|
const nGroups = Math.max(groups.length, 1);
|
||||||
const golden = Math.PI * (3 - Math.sqrt(5));
|
const gap = 0.045;
|
||||||
|
const usable = Math.PI * 2 - gap * nGroups;
|
||||||
|
const slice = usable / nGroups;
|
||||||
|
let cursor = -Math.PI / 2;
|
||||||
|
|
||||||
groups.forEach((g, si) => {
|
groups.forEach((g, si) => {
|
||||||
const a = (si / nGroups) * Math.PI * 2 - Math.PI / 2;
|
const a0 = cursor + gap / 2;
|
||||||
const hx = cx + Math.cos(a) * orbitR;
|
const a1 = a0 + slice;
|
||||||
const hy = cy + Math.sin(a) * orbitR;
|
const mid = (a0 + a1) / 2;
|
||||||
|
cursor = a1 + gap / 2;
|
||||||
const info = subnetLabelInfo(g.cidr);
|
const info = subnetLabelInfo(g.cidr);
|
||||||
const localR = 22 + Math.min(72, Math.sqrt(Math.max(g.members.length, 1)) * 15);
|
|
||||||
const pts = [];
|
|
||||||
|
|
||||||
g.members.forEach((n, i) => {
|
sectors.push({
|
||||||
const r = localR * Math.sqrt((i + 0.55) / Math.max(g.members.length, 1));
|
a0,
|
||||||
const ang = i * golden + si * 0.35;
|
a1,
|
||||||
const jx = Math.sin((n.id || i) * 0.17) * 2.8;
|
mid,
|
||||||
const jy = Math.cos((n.id || i) * 0.13) * 2.8;
|
|
||||||
const x = hx + Math.cos(ang) * r + jx;
|
|
||||||
const y = hy + Math.sin(ang) * r + jy;
|
|
||||||
pts.push({ x, y, id: n.id });
|
|
||||||
nodes.push({
|
|
||||||
...n,
|
|
||||||
tx: x,
|
|
||||||
ty: y,
|
|
||||||
r: nodeRadius(n),
|
|
||||||
depth: 1,
|
|
||||||
constellation: si,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Constellation lines: each star to its 2 nearest neighbors
|
|
||||||
const edgeSet = new Set();
|
|
||||||
const edges = [];
|
|
||||||
for (let i = 0; i < pts.length; i++) {
|
|
||||||
const ranked = pts
|
|
||||||
.map((p, j) => ({
|
|
||||||
j,
|
|
||||||
d: i === j ? Infinity : (p.x - pts[i].x) ** 2 + (p.y - pts[i].y) ** 2,
|
|
||||||
}))
|
|
||||||
.sort((aa, bb) => aa.d - bb.d);
|
|
||||||
for (const nb of ranked.slice(0, Math.min(2, ranked.length))) {
|
|
||||||
if (!Number.isFinite(nb.d)) continue;
|
|
||||||
const lo = Math.min(i, nb.j);
|
|
||||||
const hi = Math.max(i, nb.j);
|
|
||||||
const key = lo + ":" + hi;
|
|
||||||
if (edgeSet.has(key)) continue;
|
|
||||||
edgeSet.add(key);
|
|
||||||
edges.push({
|
|
||||||
x1: pts[lo].x,
|
|
||||||
y1: pts[lo].y,
|
|
||||||
x2: pts[hi].x,
|
|
||||||
y2: pts[hi].y,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
charts.push({
|
|
||||||
x: hx,
|
|
||||||
y: hy,
|
|
||||||
localR,
|
|
||||||
color: info.color,
|
color: info.color,
|
||||||
cidr: g.cidr,
|
cidr: g.cidr,
|
||||||
label: info.label,
|
label: info.label,
|
||||||
edges,
|
|
||||||
count: g.members.length,
|
count: g.members.length,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const labelR = maxR + 6;
|
||||||
anchors.push(
|
anchors.push(
|
||||||
makeLabelAnchor({
|
makeLabelAnchor({
|
||||||
x: hx,
|
x: cx + Math.cos(mid) * labelR,
|
||||||
y: hy,
|
y: cy + Math.sin(mid) * labelR,
|
||||||
cidr: g.cidr,
|
cidr: g.cidr,
|
||||||
localR,
|
localR: 4,
|
||||||
dirX: hx - omeHub.x,
|
dirX: Math.cos(mid),
|
||||||
dirY: hy - omeHub.y,
|
dirY: Math.sin(mid),
|
||||||
pipeExtra: 34,
|
pipeExtra: 26,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const sorted = [...g.members].sort(
|
||||||
|
(a, b) => Number(b.connected) - Number(a.connected) || (b.watts || 0) - (a.watts || 0)
|
||||||
|
);
|
||||||
|
const ringCount = Math.max(3, Math.min(7, Math.ceil(Math.sqrt(Math.max(sorted.length, 1)))));
|
||||||
|
sorted.forEach((n, i) => {
|
||||||
|
const ring = 1 + (i % ringCount);
|
||||||
|
const slot = Math.floor(i / ringCount);
|
||||||
|
const slotsOnRing = Math.max(1, Math.ceil(sorted.length / ringCount));
|
||||||
|
const t = slotsOnRing <= 1 ? 0.5 : (slot + 0.5) / slotsOnRing;
|
||||||
|
// keep a small inset from sector edges
|
||||||
|
const ang = a0 + 0.08 * (a1 - a0) + t * 0.84 * (a1 - a0);
|
||||||
|
const r = maxR * (0.22 + (ring / (ringCount + 0.35)) * 0.72);
|
||||||
|
nodes.push({
|
||||||
|
...n,
|
||||||
|
tx: cx + Math.cos(ang) * r,
|
||||||
|
ty: cy + Math.sin(ang) * r,
|
||||||
|
r: nodeRadius(n),
|
||||||
|
depth: 0.45 + ring * 0.12,
|
||||||
|
radar: si,
|
||||||
|
radarRing: ring,
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
state.clusterHubs = [];
|
state.clusterHubs = [];
|
||||||
state.laneGuides = [];
|
state.laneGuides = [];
|
||||||
state.labelAnchors = anchors;
|
state.labelAnchors = anchors;
|
||||||
state.bloomPetals = [];
|
state.bloomPetals = [];
|
||||||
state.constellationCharts = charts;
|
state.radarSectors = sectors;
|
||||||
|
state.radarMaxR = maxR;
|
||||||
setTargets(nodes);
|
setTargets(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -478,7 +464,8 @@
|
|||||||
state.laneGuides = guides;
|
state.laneGuides = guides;
|
||||||
state.labelAnchors = anchors;
|
state.labelAnchors = anchors;
|
||||||
state.bloomPetals = [];
|
state.bloomPetals = [];
|
||||||
state.constellationCharts = [];
|
state.radarSectors = [];
|
||||||
|
state.radarMaxR = 0;
|
||||||
// hub left side
|
// hub left side
|
||||||
state.hub = { x: 48, y: cy, r: 26 };
|
state.hub = { x: 48, y: cy, r: 26 };
|
||||||
setTargets(nodes);
|
setTargets(nodes);
|
||||||
@@ -523,7 +510,8 @@
|
|||||||
state.laneGuides = [];
|
state.laneGuides = [];
|
||||||
state.labelAnchors = anchors;
|
state.labelAnchors = anchors;
|
||||||
state.bloomPetals = [];
|
state.bloomPetals = [];
|
||||||
state.constellationCharts = [];
|
state.radarSectors = [];
|
||||||
|
state.radarMaxR = 0;
|
||||||
setTargets(nodes);
|
setTargets(nodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,8 +531,8 @@
|
|||||||
case "clusters":
|
case "clusters":
|
||||||
layoutClusters(devices, cx, cy, w, h);
|
layoutClusters(devices, cx, cy, w, h);
|
||||||
break;
|
break;
|
||||||
case "constellation":
|
case "radar":
|
||||||
layoutConstellation(devices, cx, cy, w, h);
|
layoutRadar(devices, cx, cy, w, h);
|
||||||
break;
|
break;
|
||||||
case "lanes":
|
case "lanes":
|
||||||
layoutLanes(devices, cx, cy, w, h);
|
layoutLanes(devices, cx, cy, w, h);
|
||||||
@@ -734,52 +722,62 @@
|
|||||||
ctx.globalAlpha = 1;
|
ctx.globalAlpha = 1;
|
||||||
drawPulseLink(hub.x, hub.y, ch.x, ch.y, true, t, (ch.label || "").length * 17, 0.55);
|
drawPulseLink(hub.x, hub.y, ch.x, ch.y, true, t, (ch.label || "").length * 17, 0.55);
|
||||||
}
|
}
|
||||||
} else if (mode === "constellation") {
|
} else if (mode === "radar") {
|
||||||
// Celestial guide rings
|
const maxR = state.radarMaxR || Math.min(w, h) * 0.42;
|
||||||
|
// Range rings
|
||||||
for (let i = 1; i <= 4; i++) {
|
for (let i = 1; i <= 4; i++) {
|
||||||
|
const rr = maxR * (i / 4);
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(hub.x, hub.y, 55 * i * 0.55, 0, Math.PI * 2);
|
ctx.arc(hub.x, hub.y, rr, 0, Math.PI * 2);
|
||||||
ctx.strokeStyle = canvasTheme().decor(i);
|
ctx.strokeStyle = canvasTheme().decor(i);
|
||||||
ctx.lineWidth = 1;
|
ctx.lineWidth = 1;
|
||||||
ctx.setLineDash(i % 2 ? [2, 6] : []);
|
ctx.setLineDash(i === 4 ? [] : [3, 5]);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.setLineDash([]);
|
ctx.setLineDash([]);
|
||||||
}
|
}
|
||||||
// Radial tick marks
|
// Sector wedges + outer arcs
|
||||||
for (let i = 0; i < 12; i++) {
|
for (const s of state.radarSectors || []) {
|
||||||
const ang = (i / 12) * Math.PI * 2;
|
const rgb = hexToRgb(s.color || "#00a8e8");
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(hub.x + Math.cos(ang) * 36, hub.y + Math.sin(ang) * 36);
|
ctx.moveTo(hub.x, hub.y);
|
||||||
ctx.lineTo(hub.x + Math.cos(ang) * 48, hub.y + Math.sin(ang) * 48);
|
ctx.arc(hub.x, hub.y, maxR, s.a0, s.a1);
|
||||||
ctx.strokeStyle = canvasTheme().decor(2);
|
ctx.closePath();
|
||||||
ctx.lineWidth = 1;
|
ctx.fillStyle = `rgba(${rgb.r},${rgb.g},${rgb.b},0.045)`;
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
for (const ch of state.constellationCharts || []) {
|
|
||||||
const rgb = hexToRgb(ch.color || "#00a8e8");
|
|
||||||
// Soft halo around constellation
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(ch.x, ch.y, (ch.localR || 40) + 14, 0, Math.PI * 2);
|
|
||||||
ctx.strokeStyle = `rgba(${rgb.r},${rgb.g},${rgb.b},0.2)`;
|
|
||||||
ctx.lineWidth = 1;
|
|
||||||
ctx.stroke();
|
|
||||||
// Star-chart edges
|
|
||||||
for (const e of ch.edges || []) {
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.moveTo(e.x1, e.y1);
|
|
||||||
ctx.lineTo(e.x2, e.y2);
|
|
||||||
ctx.strokeStyle = `rgba(${rgb.r},${rgb.g},${rgb.b},0.38)`;
|
|
||||||
ctx.lineWidth = 1;
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
// Dim center marker
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(ch.x, ch.y, 3, 0, Math.PI * 2);
|
|
||||||
ctx.fillStyle = `rgba(${rgb.r},${rgb.g},${rgb.b},0.55)`;
|
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
drawPulseLink(hub.x, hub.y, ch.x, ch.y, true, t, (ch.label || "").length * 19, 0.4);
|
// divider rays
|
||||||
|
for (const ang of [s.a0, s.a1]) {
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(hub.x, hub.y);
|
||||||
|
ctx.lineTo(hub.x + Math.cos(ang) * maxR, hub.y + Math.sin(ang) * maxR);
|
||||||
|
ctx.strokeStyle = `rgba(${rgb.r},${rgb.g},${rgb.b},0.22)`;
|
||||||
|
ctx.lineWidth = 1;
|
||||||
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
} else if (mode === "lanes") {
|
// outer rim arc
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(hub.x, hub.y, maxR, s.a0, s.a1);
|
||||||
|
ctx.strokeStyle = `rgba(${rgb.r},${rgb.g},${rgb.b},0.55)`;
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
// Rotating sweep beam
|
||||||
|
const sweep = (t * 0.018) % (Math.PI * 2);
|
||||||
|
const grad = ctx.createRadialGradient(hub.x, hub.y, 8, hub.x, hub.y, maxR);
|
||||||
|
grad.addColorStop(0, "rgba(61,255,224,0.18)");
|
||||||
|
grad.addColorStop(1, "rgba(61,255,224,0)");
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(hub.x, hub.y);
|
||||||
|
ctx.arc(hub.x, hub.y, maxR, sweep - 0.22, sweep);
|
||||||
|
ctx.closePath();
|
||||||
|
ctx.fillStyle = grad;
|
||||||
|
ctx.fill();
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo(hub.x, hub.y);
|
||||||
|
ctx.lineTo(hub.x + Math.cos(sweep) * maxR, hub.y + Math.sin(sweep) * maxR);
|
||||||
|
ctx.strokeStyle = "rgba(61,255,224,0.55)";
|
||||||
|
ctx.lineWidth = 1.5;
|
||||||
|
ctx.stroke();
|
||||||
|
} else if (mode === "lanes") { } else if (mode === "lanes") {
|
||||||
for (const g of state.laneGuides || []) {
|
for (const g of state.laneGuides || []) {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(70, g.y);
|
ctx.moveTo(70, g.y);
|
||||||
@@ -922,15 +920,10 @@
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mode === "constellation") {
|
if (mode === "radar") {
|
||||||
// Soft hub link to each star; constellation edges already in decor
|
// Radial blips to OME — classic radar spokes
|
||||||
for (const n of state.nodes) {
|
for (const n of state.nodes) {
|
||||||
const ch = (state.constellationCharts || [])[n.constellation];
|
drawPulseLink(hub.x, hub.y, n.x, n.y, n.connected, t, n.id, n.connected ? 0.85 : 0.35);
|
||||||
if (ch) {
|
|
||||||
drawPulseLink(ch.x, ch.y, n.x, n.y, n.connected, t, n.id, 0.55);
|
|
||||||
} else {
|
|
||||||
drawPulseLink(hub.x, hub.y, n.x, n.y, n.connected, t, n.id, 0.7);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1696,8 +1689,10 @@
|
|||||||
}
|
}
|
||||||
if (state.hub) expand(state.hub.x, state.hub.y, (state.hub.r || 28) + 16);
|
if (state.hub) expand(state.hub.x, state.hub.y, (state.hub.r || 28) + 16);
|
||||||
for (const ch of state.clusterHubs || []) expand(ch.x, ch.y, 56);
|
for (const ch of state.clusterHubs || []) expand(ch.x, ch.y, 56);
|
||||||
for (const c of state.constellationCharts || []) expand(c.x, c.y, (c.localR || 40) + 24);
|
|
||||||
for (const a of state.labelAnchors || []) expand(a.x, a.y, 48);
|
for (const a of state.labelAnchors || []) expand(a.x, a.y, 48);
|
||||||
|
if (state.layoutMode === "radar" && state.radarMaxR) {
|
||||||
|
expand(state.hub?.x || 0, state.hub?.y || 0, state.radarMaxR + 56);
|
||||||
|
}
|
||||||
|
|
||||||
const bw = Math.max(80, maxX - minX);
|
const bw = Math.max(80, maxX - minX);
|
||||||
const bh = Math.max(80, maxY - minY);
|
const bh = Math.max(80, maxY - minY);
|
||||||
|
|||||||
+3
-3
@@ -7,7 +7,7 @@
|
|||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
||||||
<link rel="stylesheet" href="/styles.css?v=constellation1" />
|
<link rel="stylesheet" href="/styles.css?v=radar1" />
|
||||||
<link rel="icon" href="/dell.png" type="image/png" />
|
<link rel="icon" href="/dell.png" type="image/png" />
|
||||||
<link rel="stylesheet" href="/vendor/xterm/xterm.css?v=home1" />
|
<link rel="stylesheet" href="/vendor/xterm/xterm.css?v=home1" />
|
||||||
<script>
|
<script>
|
||||||
@@ -58,7 +58,7 @@
|
|||||||
<button type="button" class="viz-card active" data-layout="orbit"><span class="viz-ico">◎</span><span class="viz-t">Orbit</span><span class="viz-s">Hub & rings</span></button>
|
<button type="button" class="viz-card active" data-layout="orbit"><span class="viz-ico">◎</span><span class="viz-t">Orbit</span><span class="viz-s">Hub & rings</span></button>
|
||||||
<button type="button" class="viz-card" data-layout="galaxy"><span class="viz-ico">✶</span><span class="viz-t">Galaxy</span><span class="viz-s">Spiral arms</span></button>
|
<button type="button" class="viz-card" data-layout="galaxy"><span class="viz-ico">✶</span><span class="viz-t">Galaxy</span><span class="viz-s">Spiral arms</span></button>
|
||||||
<button type="button" class="viz-card" data-layout="clusters"><span class="viz-ico">◉</span><span class="viz-t">Clusters</span><span class="viz-s">Subnet islands</span></button>
|
<button type="button" class="viz-card" data-layout="clusters"><span class="viz-ico">◉</span><span class="viz-t">Clusters</span><span class="viz-s">Subnet islands</span></button>
|
||||||
<button type="button" class="viz-card" data-layout="constellation"><span class="viz-ico">✦</span><span class="viz-t">Constellation</span><span class="viz-s">Star chart</span></button>
|
<button type="button" class="viz-card" data-layout="radar"><span class="viz-ico">◔</span><span class="viz-t">Radar</span><span class="viz-s">Sector sweep</span></button>
|
||||||
<button type="button" class="viz-card" data-layout="lanes"><span class="viz-ico">≡</span><span class="viz-t">Lanes</span><span class="viz-s">Fiber highways</span></button>
|
<button type="button" class="viz-card" data-layout="lanes"><span class="viz-ico">≡</span><span class="viz-t">Lanes</span><span class="viz-s">Fiber highways</span></button>
|
||||||
<button type="button" class="viz-card" data-layout="helix"><span class="viz-ico">∿</span><span class="viz-t">Helix</span><span class="viz-s">3D depth coil</span></button>
|
<button type="button" class="viz-card" data-layout="helix"><span class="viz-ico">∿</span><span class="viz-t">Helix</span><span class="viz-s">3D depth coil</span></button>
|
||||||
</div>
|
</div>
|
||||||
@@ -634,7 +634,7 @@
|
|||||||
|
|
||||||
<script src="/vendor/xterm/xterm.min.js?v=home1"></script>
|
<script src="/vendor/xterm/xterm.min.js?v=home1"></script>
|
||||||
<script src="/vendor/xterm/xterm-addon-fit.min.js?v=home1"></script>
|
<script src="/vendor/xterm/xterm-addon-fit.min.js?v=home1"></script>
|
||||||
<script src="/app.js?v=constellation1"></script>
|
<script src="/app.js?v=radar1"></script>
|
||||||
<script src="/ops.js?v=opsfde2"></script>
|
<script src="/ops.js?v=opsfde2"></script>
|
||||||
<script src="/ssh.js?v=fabric4"></script>
|
<script src="/ssh.js?v=fabric4"></script>
|
||||||
<script src="/rdp.js?v=fabric4"></script>
|
<script src="/rdp.js?v=fabric4"></script>
|
||||||
|
|||||||
Reference in New Issue
Block a user