Files
connectai/brain-viz.html
T

205 lines
7.8 KiB
HTML

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Connect AI - Neural Construct</title>
<style>
body { margin: 0; padding: 0; background: #0a0a0a; overflow: hidden; font-family: 'SF Pro Display', -apple-system, sans-serif; }
#ui-layer { position: absolute; top: 20px; left: 24px; z-index: 10; pointer-events: none; }
#ui-layer h1 { font-size: 22px; margin: 0 0 4px 0; font-weight: 800; letter-spacing: -0.5px; color: #e0e0e0; }
#ui-layer h1 span { color: #00cc44; }
#ui-layer p { margin: 0; font-size: 12px; color: #555; letter-spacing: 0.3px; }
#mem-status { color: #888; font-family: 'SF Mono', monospace; font-size: 11px; }
canvas { cursor: grab; }
canvas:active { cursor: grabbing; }
</style>
<script src="https://unpkg.com/force-graph"></script>
</head>
<body>
<div id="ui-layer">
<h1><span>Neural Construct</span></h1>
<p id="mem-status">loading...</p>
</div>
<div id="graph"></div>
<script>
// ── Realistic knowledge node names ──
const clusters = {
'AI/ML': [
'Transformer Architecture', 'Attention Mechanism', 'Backpropagation', 'Gradient Descent',
'Neural Network Layers', 'Loss Function', 'Embedding Space', 'Tokenization',
'Fine-tuning', 'Transfer Learning', 'LoRA Adapter', 'RLHF', 'DPO Training',
'Prompt Engineering', 'Chain of Thought', 'RAG Pipeline', 'Vector Database',
],
'Programming': [
'TypeScript', 'React Components', 'Node.js Runtime', 'REST API Design',
'GraphQL Schema', 'WebSocket Protocol', 'Docker Container', 'Kubernetes',
'CI/CD Pipeline', 'Git Version Control', 'Database Schema', 'SQL Optimization',
'Redis Caching', 'Message Queue', 'Microservices', 'Load Balancing',
],
'YouTube/Business': [
'YouTube Algorithm', 'CTR Optimization', 'Thumbnail Design', 'Title A/B Testing',
'Audience Retention', 'Content Calendar', 'Funnel Strategy', 'Email Marketing',
'SEO Fundamentals', 'Analytics Dashboard', 'Conversion Rate', 'Growth Hacking',
'Brand Positioning', 'Community Building', 'Monetization', 'Ad Revenue Model',
],
'Tools/Platform': [
'VS Code Extension API', 'Ollama Runtime', 'Gemma Model', 'LLaMA Architecture',
'Google Veo', 'Nanobanana Pro', 'NotebookLM', 'Google Stitch',
'MCP Protocol', 'Antigravity CLI', 'Agent University', 'Brain Pack Format',
'OPAL Framework', 'Gemini API', 'DeepSeek Model', 'Whisper STT',
],
'Knowledge Mgmt': [
'Second Brain Method', 'Zettelkasten System', 'Spaced Repetition', 'Active Recall',
'Mind Mapping', 'Knowledge Graph', 'Semantic Search', 'Document Chunking',
'Metadata Extraction', 'Tag Taxonomy', 'Bidirectional Links', 'Atomic Notes',
],
'Content/Korean': [
'#AI수익화', '#바이브코딩', '#1인기업', '#AI창업',
'#코딩기초', '#시니어전성시대', '#자기개발', '#AI쇼핑몰',
'#GPT사용법', '#사이트만들기', '#수익화모델', '#노코드',
'#AI자동수익', '#VEO3.1', '#왕초보가이드', '#디지털건물주',
],
'Math/Science': [
'Linear Algebra', 'Probability Theory', 'Calculus', 'Statistics',
'Information Theory', 'Game Theory', 'Optimization', 'Graph Theory',
],
'MrBeast Pack': [
'MrBeast Viral Formula', 'Hook Strategy', 'Retention Graph Analysis',
'Challenge Video Format', 'Giveaway ROI Model', 'Production Scaling',
'Clickbait Psychology', 'First 30s Rule', 'Re-watch Value',
'Comment Engagement', 'Shorts Repurposing', 'Thumbnail Contrast',
'Emotional Arc Design', 'Pacing Rhythm', 'Sound Design Impact',
],
};
let nodeId = 0;
const gData = { nodes: [], links: [] };
const groupIds = {};
// Core hub
gData.nodes.push({ id: nodeId++, group: -1, name: 'Core Agent', val: 22, connections: 0 });
// Build nodes per cluster
let groupIdx = 0;
Object.entries(clusters).forEach(([clusterName, names]) => {
groupIds[clusterName] = groupIdx;
names.forEach(name => {
gData.nodes.push({ id: nodeId++, group: groupIdx, name, val: 2, connections: 0 });
});
groupIdx++;
});
// ── Build connections ──
const nodesByGroup = {};
gData.nodes.forEach(n => {
if (n.group < 0) return;
if (!nodesByGroup[n.group]) nodesByGroup[n.group] = [];
nodesByGroup[n.group].push(n);
});
// Dense intra-cluster
Object.values(nodesByGroup).forEach(group => {
for (let i = 0; i < group.length; i++) {
for (let j = i + 1; j < group.length; j++) {
if (Math.random() < 0.22) {
gData.links.push({ source: group[i].id, target: group[j].id });
group[i].connections++;
group[j].connections++;
}
}
}
});
// Hub connections
gData.nodes.forEach(n => {
if (n.group >= 0 && Math.random() < 0.05) {
gData.links.push({ source: n.id, target: 0 });
n.connections++;
gData.nodes[0].connections++;
}
});
// Cross-cluster bridges
for (let i = 0; i < 35; i++) {
const a = 1 + Math.floor(Math.random() * (gData.nodes.length - 1));
const b = 1 + Math.floor(Math.random() * (gData.nodes.length - 1));
if (a !== b && gData.nodes[a].group !== gData.nodes[b].group) {
gData.links.push({ source: a, target: b });
gData.nodes[a].connections++;
gData.nodes[b].connections++;
}
}
// Size by connections
gData.nodes.forEach(n => { n.val = Math.max(2, n.connections * 1.5); });
document.getElementById('mem-status').textContent =
gData.nodes.length + ' nodes · ' + gData.links.length + ' synapses';
// ── Colors per cluster ──
const groupColors = ['#00cc44','#00b7ff','#ff6b6b','#ffaa33','#aa66ff','#00cc44','#66cccc','#00ff88'];
// ── Render ──
const Graph = ForceGraph()(document.getElementById('graph'))
.backgroundColor('#0a0a0a')
.nodeCanvasObject((node, ctx, globalScale) => {
const r = Math.sqrt(node.val) * 1.8;
ctx.beginPath();
ctx.arc(node.x, node.y, r, 0, 2 * Math.PI);
if (node.group === -1) {
ctx.fillStyle = '#333';
ctx.fill();
ctx.strokeStyle = '#00cc44';
ctx.lineWidth = 1.5;
ctx.stroke();
} else if (node.connections > 4) {
ctx.fillStyle = groupColors[node.group] || '#00cc44';
ctx.fill();
} else {
ctx.fillStyle = '#2a2a2a';
ctx.fill();
}
// Labels — show based on zoom
const showLabel = globalScale > 1.2 || node.connections > 3 || node.group === -1;
if (showLabel) {
const fontSize = Math.max(2.5, Math.min(5, 11 / globalScale));
ctx.font = `${fontSize}px -apple-system, sans-serif`;
ctx.textAlign = 'center';
ctx.textBaseline = 'top';
ctx.fillStyle = node.connections > 4 ? '#ccc' : '#555';
ctx.fillText(node.name, node.x, node.y + r + 1.5);
}
})
.nodePointerAreaPaint((node, color, ctx) => {
const r = Math.sqrt(node.val) * 1.8 + 4;
ctx.beginPath();
ctx.arc(node.x, node.y, r, 0, 2 * Math.PI);
ctx.fillStyle = color;
ctx.fill();
})
.linkColor(() => 'rgba(255,255,255,0.04)')
.linkWidth(0.3)
.d3VelocityDecay(0.3)
.warmupTicks(150)
.cooldownTicks(300)
.graphData(gData);
Graph.d3Force('charge').strength(-100);
Graph.d3Force('link').distance(35);
// Click to zoom
Graph.onNodeClick(node => {
Graph.centerAt(node.x, node.y, 800);
Graph.zoom(4, 1200);
});
// Start with a nice fit
setTimeout(() => Graph.zoomToFit(1500, 40), 500);
</script>
</body>
</html>