import { useState, useEffect, useRef } from 'react'; import * as THREE from 'three'; function NeuralNetworkDiagram({ width = 420, height = 280 }) { const [hovered, setHovered] = useState(null); const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 80); return () => clearInterval(id); }, []); const layers = [ { x: 60, nodes: [80, 130, 180, 230], label: 'لایه ورودی' }, { x: 160, nodes: [100, 155, 210], label: 'لایه پنهان ۱' }, { x: 260, nodes: [110, 165, 220], label: 'لایه توجه' }, { x: 360, nodes: [140, 195], label: 'خروجی مدل' }, ]; const pulses = []; for (let li = 0; li < layers.length - 1; li++) { const from = layers[li], to = layers[li + 1]; from.nodes.forEach((fy, fi) => { to.nodes.forEach((ty, ti) => { const phase = (tick + li * 7 + fi * 3 + ti * 5) % 40; if (phase < 20) pulses.push({ x: from.x + (to.x - from.x) * phase / 20, y: fy + (ty - fy) * phase / 20 }); }); }); } const nodeColors = ['#0F6B73', '#D49A2A', '#C76D4A', '#2F8F6B']; return ( {layers.map((layer, li) => layers[li + 1] && layer.nodes.map((fy, fi) => layers[li + 1].nodes.map((ty, ti) => ( )) ) )} {pulses.map((p, i) => ( ))} {layers.map((layer, li) => layer.nodes.map((y, ni) => ( setHovered(`${li}-${ni}`)} onMouseLeave={() => setHovered(null)} style={{ cursor: 'pointer' }}> {hovered === `${li}-${ni}` && ( {layer.label} )} )) )} {layers.map((layer, li) => ( {layer.label} ))} ); } function DataPipelineDiagram({ compact = false }) { const [tick, setTick] = useState(0); const [hovered, setHovered] = useState(null); useEffect(() => { const id = setInterval(() => setTick(t => (t + 1) % 100), 60); return () => clearInterval(id); }, []); const steps = [ { id: 'raw', label: 'داده خام', icon: '⬡', color: '#5F6B6D', desc: 'جمع‌آوری از منابع مختلف' }, { id: 'clean', label: 'پاک‌سازی', icon: '◈', color: '#D49A2A', desc: 'حذف تکراری و نویز' }, { id: 'label', label: 'برچسب‌گذاری', icon: '◉', color: '#C76D4A', desc: 'دسته‌بندی و تعریف' }, { id: 'feature', label: 'ویژگی‌سازی', icon: '⬟', color: '#0F6B73', desc: 'استخراج ویژگی' }, { id: 'train', label: 'آموزش مدل', icon: '◈', color: '#2F8F6B', desc: 'یادگیری از داده' }, { id: 'eval', label: 'ارزیابی', icon: '◉', color: '#D49A2A', desc: 'سنجش عملکرد' }, { id: 'output', label: 'خروجی', icon: '★', color: '#0F6B73', desc: 'مدل آماده' }, ]; const W = compact ? 480 : 700, H = compact ? 140 : 180; const stepW = W / steps.length; return ( {[0, 25, 50, 75].map(offset => { const pos = ((tick + offset) % 100) / 100; const x = stepW * 0.5 + pos * (W - stepW); return ; })} {steps.map((step, i) => { const cx = stepW * (i + 0.5); const isHov = hovered === step.id; return ( setHovered(step.id)} onMouseLeave={() => setHovered(null)} style={{ cursor: 'pointer' }}> {i + 1} {step.label} {isHov && ( {step.desc} )} ); })} ); } function CyberSecurityDiagram() { const [hovered, setHovered] = useState(null); const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 100); return () => clearInterval(id); }, []); const cx = 200, cy = 150, r = 90; const threats = [ { angle: 0, label: 'فیشینگ', color: '#C94C4C' }, { angle: 60, label: 'حمله زنجیره تأمین', color: '#D08A22' }, { angle: 120, label: 'آسیب‌پذیری کتابخانه', color: '#C76D4A' }, { angle: 180, label: 'دسترسی غیرمجاز', color: '#C94C4C' }, { angle: 240, label: 'باج‌افزار', color: '#D08A22' }, { angle: 300, label: 'حمله DDoS', color: '#C76D4A' }, ]; return ( سرور مرکزی {threats.map((t, i) => { const rad = (t.angle * Math.PI) / 180; const tx = cx + Math.cos(rad) * r; const ty = cy + Math.sin(rad) * r; const lx = cx + Math.cos(rad) * (r + 38); const ly = cy + Math.sin(rad) * (r + 38); const isH = hovered === i; const pulse = (tick + i * 6) % 30 < 15; return ( setHovered(i)} onMouseLeave={() => setHovered(null)} style={{ cursor: 'pointer' }}> {isH && ( {t.label} )} ); })} ); } function StartupGrowthDiagram() { const [progress, setProgress] = useState(0); useEffect(() => { let v = 0; const id = setInterval(() => { v = Math.min(v + 2, 100); setProgress(v); if (v >= 100) clearInterval(id); }, 20); return () => clearInterval(id); }, []); const milestones = ['ایده', 'محصول اولیه', 'جذب کاربر', 'درآمد', 'مقیاس‌پذیری']; const W = 400, H = 200, padX = 40, padY = 20; const points = milestones.map((_, i) => { const t = i / (milestones.length - 1); return { x: padX + t * (W - padX * 2), y: H - padY - Math.pow(t, 1.8) * (H - padY * 3) }; }); const drawProgress = Math.min(progress / 100, 1); const pathPoints = points.filter((_, i) => i / (milestones.length - 1) <= drawProgress + 0.01); const pathD = pathPoints.length > 1 ? pathPoints.map((p, i) => `${i === 0 ? 'M' : 'L'} ${p.x} ${p.y}`).join(' ') : ''; return ( {pathD && } {pathPoints.length > 1 && ( )} {points.map((p, i) => { const t = i / (milestones.length - 1); const visible = t <= drawProgress + 0.01; return visible ? ( {milestones[i]} ) : null; })} منحنی رشد استارتاپ ); } function HardwareChipDiagram() { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 70); return () => clearInterval(id); }, []); const blocks = [ { x: 30, y: 60, w: 80, h: 40, label: 'حافظه', color: '#D49A2A' }, { x: 160, y: 40, w: 80, h: 80, label: 'پردازنده', color: '#0F6B73' }, { x: 290, y: 60, w: 80, h: 40, label: 'شتاب‌دهنده AI', color: '#C76D4A' }, { x: 30, y: 150, w: 80, h: 40, label: 'گذرگاه داده', color: '#2F8F6B' }, { x: 290, y: 150, w: 80, h: 40, label: 'کنترلر حافظه', color: '#5F6B6D' }, ]; const routes = [ { x1: 110, y1: 80, x2: 160, y2: 80 }, { x1: 240, y1: 80, x2: 290, y2: 80 }, { x1: 110, y1: 170, x2: 160, y2: 120 }, { x1: 240, y1: 100, x2: 290, y2: 170 }, { x1: 200, y1: 120, x2: 200, y2: 170 }, ]; return ( {routes.map((r, i) => { const len = Math.hypot(r.x2 - r.x1, r.y2 - r.y1); const phase = ((tick + i * 12) % 40) / 40; const px = r.x1 + (r.x2 - r.x1) * phase; const py = r.y1 + (r.y2 - r.y1) * phase; return ( ); })} {blocks.map((b, i) => ( {b.label} ))} ); } function FutureTimelineDiagram() { const [activeIdx, setActiveIdx] = useState(null); const milestones = [ { year: '۲۰۲۵', label: 'AGI اولیه', color: '#0F6B73' }, { year: '۲۰۲۷', label: 'رایانش کوانتومی', color: '#D49A2A' }, { year: '۲۰۲۹', label: 'رباتیک خودکار', color: '#C76D4A' }, { year: '۲۰۳۱', label: 'رابط مغز-ماشین', color: '#2F8F6B' }, { year: '۲۰۳۵', label: 'جوش هسته‌ای تجاری', color: '#0F6B73' }, ]; const W = 480, H = 120; return ( {milestones.map((m, i) => { const x = 40 + (i / (milestones.length - 1)) * (W - 80); const isH = activeIdx === i; return ( setActiveIdx(i)} onMouseLeave={() => setActiveIdx(null)} style={{ cursor: 'pointer' }}> {m.year} {isH && ( {m.label} )} {!isH && {m.label}} ); })} ); } function SoftwareArchDiagram() { const modules = [ { x: 180, y: 30, label: 'API Gateway', color: '#0F6B73' }, { x: 60, y: 110, label: 'Auth Service', color: '#2F8F6B' }, { x: 180, y: 110, label: 'Core Service', color: '#D49A2A' }, { x: 300, y: 110, label: 'AI Service', color: '#C76D4A' }, { x: 60, y: 190, label: 'Database', color: '#5F6B6D' }, { x: 300, y: 190, label: 'Cache', color: '#5F6B6D' }, ]; const edges = [[0,1],[0,2],[0,3],[1,4],[2,4],[3,5]]; return ( {edges.map(([a, b], i) => ( ))} {modules.map((m, i) => ( {m.label} ))} ); } function WaveStreamDiagram() { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 40); return () => clearInterval(id); }, []); const W = 480, H = 160; const streams = [ { color: '#D49A2A', amp: 28, freq: 0.022, phase: 0, y: 50 }, { color: '#C46A4D', amp: 20, freq: 0.03, phase: 1.5, y: 85 }, { color: '#2F8F6B', amp: 24, freq: 0.018, phase: 3, y: 120 }, ]; const buildPath = (s) => { const pts = Array.from({ length: 60 }, (_, i) => { const x = (i / 59) * W; const y = s.y + s.amp * Math.sin(x * s.freq + tick * 0.08 + s.phase); return `${i === 0 ? 'M' : 'L'}${x.toFixed(1)},${y.toFixed(1)}`; }); return pts.join(' '); }; return ( {streams.map((s, i) => ( ))} {streams.map((s, i) => ( {(() => { const pct = ((tick * 1.8 + i * 80) % 480) / 480; const x = pct * W; const y = s.y + s.amp * Math.sin(x * s.freq + tick * 0.08 + s.phase); return ; })()} ))} جریان داده در شبکه ); } function OrbitDiagram() { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 50); return () => clearInterval(id); }, []); const cx = 140, cy = 110; const orbits = [ { r: 40, speed: 0.04, color: '#D49A2A', label: 'داده', dotR: 7 }, { r: 65, speed: -0.025, color: '#C46A4D', label: 'مدل', dotR: 9 }, { r: 90, speed: 0.016, color: '#2F8F6B', label: 'استنتاج', dotR: 8 }, ]; return ( AI {orbits.map((o, i) => ( {(() => { const angle = tick * o.speed; const x = cx + o.r * Math.cos(angle); const y = cy + o.r * Math.sin(angle); return ( {o.label} ); })()} ))} ); } function GeneratedDiagram({ variant = 1, compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick((t) => t + 1), 50); return () => clearInterval(id); }, []); const W = compact ? 320 : 520; const H = compact ? 150 : 210; const seed = Number.isFinite(variant) ? variant : 1; const nodeCount = 6 + (seed % 7); const radius = compact ? 36 + (seed % 5) * 6 : 48 + (seed % 6) * 7; const centerX = W * 0.5; const centerY = H * 0.48; const palette = ['#0F6B73', '#D49A2A', '#C76D4A', '#2F8F6B', '#5F6B6D']; const points = Array.from({ length: nodeCount }, (_, i) => { const angle = ((Math.PI * 2) / nodeCount) * i + (seed % 9) * 0.11; return { x: centerX + Math.cos(angle) * radius, y: centerY + Math.sin(angle) * radius, color: palette[(i + seed) % palette.length] }; }); const pulse = (tick + seed * 3) % 100; return ( {points.map((a, i) => points.slice(i + 1).map((b, j) => ( )))} {points.map((p, i) => ( ))} Generated Diagram {String(seed).padStart(2, '0')} ); } function BrainDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 60); return () => clearInterval(id); }, []); const W = compact ? 300 : 400, H = compact ? 180 : 260; const cx = W / 2, cy = H * 0.45; const nodes = [ { x: cx, y: cy - 60 }, { x: cx - 50, y: cy - 30 }, { x: cx + 50, y: cy - 30 }, { x: cx - 70, y: cy + 20 }, { x: cx + 70, y: cy + 20 }, { x: cx, y: cy + 60 }, { x: cx - 30, y: cy + 40 }, { x: cx + 30, y: cy + 40 } ]; return ( {nodes.map((n1, i) => nodes.slice(i + 1).map((n2, j) => { const dist = Math.hypot(n1.x - n2.x, n1.y - n2.y); if (dist > 100) return null; return ; }))} {nodes.map((n, i) => { const pulse = Math.sin(tick * 0.1 + i) * 3 + 6; return ; })} رابط عصبی هوشمند ); } function DatabaseDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 50); return () => clearInterval(id); }, []); const W = 320, H = 200; const stacks = [ { x: 60, y: 140, h: 40, color: '#5F6B6D' }, { x: 160, y: 140, h: 60, color: '#D49A2A' }, { x: 260, y: 140, h: 50, color: '#0F6B73' }, ]; return ( {stacks.map((s, i) => ( ))} ساختار داده‌های برداری ); } function CloudDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 80); return () => clearInterval(id); }, []); return ( {[0, 1, 2].map(i => { const x = 150 + i * 50, y = 110; const pulse = (tick + i * 10) % 20 < 10; return ; })} رایانش ابری و لبه شبکه ); } function QuantumDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 40); return () => clearInterval(id); }, []); const cx1 = 120, cy = 100, cx2 = 280; const orbit = tick * 0.05; return ( درهم‌تنیدگی کوانتومی ); } function VlaDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 50); return () => clearInterval(id); }, []); return ( VLA MODEL Vision Language ACTION ); } function DnaDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 60); return () => clearInterval(id); }, []); const W = 320, H = 200; const nodes = Array.from({ length: 10 }, (_, i) => i); return ( {nodes.map(i => { const y = 30 + i * 15; const x1 = 160 + Math.sin(tick * 0.1 + i * 0.8) * 40; const x2 = 160 - Math.sin(tick * 0.1 + i * 0.8) * 40; return ( ); })} مهندسی ژنتیک و بیوتکنولوژی ); } function FusionDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 40); return () => clearInterval(id); }, []); const cx = 160, cy = 100; return ( گداخت هسته‌ای و انرژی پاک ); } function SatelliteDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 50); return () => clearInterval(id); }, []); const cx = 160, cy = 100; const satX = cx + Math.cos(tick * 0.03) * 80; const satY = cy + Math.sin(tick * 0.03) * 40; return ( ارتباطات ماهواره‌ای و فضا ); } function BlockchainDiagram({ compact = false }) { const blocks = [0, 1, 2, 3]; return ( {blocks.map(i => ( BLOCK {i} {i < 3 && } ))} فناوری زنجیره بلوکی و فین‌تک ); } function TekRagThreeDiagram({ variant = 'corpus', compact = false }) { const hostRef = useRef(null); const [hoverLabel, setHoverLabel] = useState('TekRAG-Persian'); useEffect(() => { const host = hostRef.current; if (!host) return undefined; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(45, 1, 0.1, 100); camera.position.set(0, 3.2, 8.5); const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, 2)); renderer.outputColorSpace = THREE.SRGBColorSpace; host.appendChild(renderer.domElement); const group = new THREE.Group(); scene.add(group); scene.add(new THREE.AmbientLight(0xffffff, 0.7)); const key = new THREE.DirectionalLight(0xffffff, 1.4); key.position.set(4, 6, 5); scene.add(key); const rim = new THREE.DirectionalLight(0xd49a2a, 0.8); rim.position.set(-5, 3, -4); scene.add(rim); const pickables = []; const palette = { teal: 0x0f6b73, gold: 0xd49a2a, clay: 0xc76d4a, green: 0x2f8f6b, ink: 0x20343a, line: 0xe4ddd2, red: 0xc94c4c, cream: 0xf4efe6, }; const addLabel = (object, label) => { object.userData.label = label; pickables.push(object); return object; }; const box = (label, position, scale, color, opacity = 0.92) => { const mesh = new THREE.Mesh( new THREE.BoxGeometry(scale[0], scale[1], scale[2]), new THREE.MeshStandardMaterial({ color, roughness: 0.48, metalness: 0.12, transparent: opacity < 1, opacity }) ); mesh.position.set(...position); group.add(addLabel(mesh, label)); const edges = new THREE.LineSegments( new THREE.EdgesGeometry(mesh.geometry), new THREE.LineBasicMaterial({ color: 0xffffff, transparent: true, opacity: 0.18 }) ); mesh.add(edges); return mesh; }; const sphere = (label, position, radius, color, opacity = 0.95) => { const mesh = new THREE.Mesh( new THREE.SphereGeometry(radius, 28, 18), new THREE.MeshStandardMaterial({ color, roughness: 0.35, metalness: 0.2, transparent: opacity < 1, opacity }) ); mesh.position.set(...position); group.add(addLabel(mesh, label)); return mesh; }; const line = (from, to, color = palette.line, opacity = 0.45) => { const geometry = new THREE.BufferGeometry().setFromPoints([ new THREE.Vector3(...from), new THREE.Vector3(...to), ]); const mesh = new THREE.Line(geometry, new THREE.LineBasicMaterial({ color, transparent: true, opacity })); group.add(mesh); return mesh; }; if (variant === 'corpus') { const layers = [ ['Raw HTML export', -1.8, palette.ink], ['Persian normalization', -0.6, palette.teal], ['Heading-aware chunks', 0.6, palette.gold], ['Metadata and provenance', 1.8, palette.green], ]; layers.forEach(([label, y, color], idx) => { const slab = box(label, [0, y, 0], [5.8, 0.22, 3.2], color, 0.42); slab.rotation.y = idx % 2 ? 0.08 : -0.08; for (let i = 0; i < 9; i += 1) { const x = -2.2 + (i % 3) * 2.2 + (idx % 2 ? 0.15 : -0.1); const z = -1.05 + Math.floor(i / 3) * 1.05; const doc = sphere(`${label}: document ${i + 1}`, [x, y + 0.28, z], 0.09, idx % 2 ? palette.cream : palette.gold, 0.82); doc.scale.y = 0.55; } }); for (let i = 0; i < 8; i += 1) { const x = -2.3 + (i % 4) * 1.55; const z = -1.35 + (i % 2) * 2.7; line([x, -1.65, z], [x * 0.72, 1.95, z * 0.55], palette.gold, 0.36); } sphere('Benchmark release: QA plus evidence IDs', [0, 2.45, 0], 0.38, palette.clay); camera.position.set(0, 4.1, 8.2); } else if (variant === 'retrieval') { line([-3.3, 0, 0], [3.3, 0, 0], palette.teal, 0.5); line([0, -2.2, 0], [0, 2.2, 0], palette.gold, 0.5); line([0, 0, -2.8], [0, 0, 2.8], palette.green, 0.5); const clusters = [ ['BM25 exact acronym region', [-1.75, 0.45, -0.6], palette.gold], ['Dense semantic Persian region', [1.55, 0.1, 0.75], palette.teal], ['Hybrid fused evidence region', [0.2, 1.2, -0.1], palette.green], ]; clusters.forEach(([label, center, color], ci) => { sphere(label, center, 0.3, color, 0.82); for (let i = 0; i < 18; i += 1) { const a = (i / 18) * Math.PI * 2; const r = 0.35 + (i % 5) * 0.09; const p = [ center[0] + Math.cos(a) * r, center[1] + Math.sin(a * 1.7) * 0.38, center[2] + Math.sin(a) * r, ]; sphere(`${label}: chunk ${i + 1}`, p, 0.055, color, 0.76); } }); const query = sphere('Persian technical user query', [-3.0, -1.45, 1.7], 0.22, palette.red); clusters.forEach(([, center], i) => line(query.position.toArray(), center, i === 1 ? palette.teal : palette.gold, 0.48)); box('Reranker: top-k evidence gate', [0, -1.55, 0], [1.9, 0.16, 1.0], palette.ink, 0.68); camera.position.set(0.2, 2.9, 7.4); } else { const metrics = [ ['Recall@k', -2.4, 1.55, palette.teal], ['Citation precision', -1.2, 2.1, palette.green], ['Atomic support precision', 0, 2.45, palette.gold], ['Abstention F1', 1.2, 1.65, palette.clay], ['Unsupported-claim rate', 2.4, 0.9, palette.red], ]; metrics.forEach(([label, x, h, color]) => { const pillar = box(label, [x, h / 2 - 1.2, 0], [0.52, h, 0.52], color, 0.9); const cap = sphere(`${label}: confidence interval marker`, [x, h - 1.0, 0], 0.18, color, 0.95); line([x, h - 1.0, -0.65], [x, h - 1.0, 0.65], color, 0.48); pillar.rotation.y = 0.2; cap.scale.y = 0.7; }); const ringGeo = new THREE.TorusGeometry(1.55, 0.025, 12, 96); const ring = new THREE.Mesh(ringGeo, new THREE.MeshStandardMaterial({ color: palette.teal, transparent: true, opacity: 0.5 })); ring.rotation.x = Math.PI / 2; ring.position.y = -1.05; group.add(addLabel(ring, 'Paired statistical testing and confidence intervals')); for (let i = 0; i < 14; i += 1) { const a = (i / 14) * Math.PI * 2; sphere('Hallucination error atom', [Math.cos(a) * 1.55, -1.05, Math.sin(a) * 1.55], 0.065, i % 3 === 0 ? palette.red : palette.gold, 0.82); } camera.position.set(0, 3.0, 7.2); } const raycaster = new THREE.Raycaster(); const pointer = new THREE.Vector2(); let raf = 0; let dragging = false; let lastX = 0; let lastY = 0; let targetX = -0.16; let targetY = 0.34; renderer.domElement.style.display = 'block'; const resize = () => { const rect = host.getBoundingClientRect(); const width = Math.max(rect.width || host.offsetWidth || 600, 280); const height = compact ? 240 : 340; renderer.setSize(width, height); camera.aspect = width / height; camera.updateProjectionMatrix(); }; resize(); requestAnimationFrame(resize); const resizeObserver = new ResizeObserver(resize); resizeObserver.observe(host); const updatePointer = (event) => { const rect = renderer.domElement.getBoundingClientRect(); pointer.x = ((event.clientX - rect.left) / rect.width) * 2 - 1; pointer.y = -((event.clientY - rect.top) / rect.height) * 2 + 1; raycaster.setFromCamera(pointer, camera); const hit = raycaster.intersectObjects(pickables, true)[0]; const label = hit?.object?.userData?.label || hit?.object?.parent?.userData?.label; if (label) setHoverLabel(label); if (dragging) { targetY += (event.clientX - lastX) * 0.008; targetX += (event.clientY - lastY) * 0.006; lastX = event.clientX; lastY = event.clientY; } }; const pointerDown = (event) => { dragging = true; lastX = event.clientX; lastY = event.clientY; renderer.domElement.setPointerCapture?.(event.pointerId); }; const pointerUp = (event) => { dragging = false; renderer.domElement.releasePointerCapture?.(event.pointerId); }; renderer.domElement.addEventListener('pointermove', updatePointer); renderer.domElement.addEventListener('pointerdown', pointerDown); renderer.domElement.addEventListener('pointerup', pointerUp); renderer.domElement.addEventListener('pointerleave', pointerUp); const animate = () => { targetY += dragging ? 0 : 0.003; group.rotation.x += (targetX - group.rotation.x) * 0.08; group.rotation.y += (targetY - group.rotation.y) * 0.08; renderer.render(scene, camera); raf = requestAnimationFrame(animate); }; animate(); return () => { cancelAnimationFrame(raf); resizeObserver.disconnect(); renderer.domElement.removeEventListener('pointermove', updatePointer); renderer.domElement.removeEventListener('pointerdown', pointerDown); renderer.domElement.removeEventListener('pointerup', pointerUp); renderer.domElement.removeEventListener('pointerleave', pointerUp); renderer.dispose(); scene.traverse((object) => { object.geometry?.dispose?.(); if (Array.isArray(object.material)) object.material.forEach((m) => m.dispose?.()); else object.material?.dispose?.(); }); host.replaceChildren(); }; }, [variant, compact]); const labels = { corpus: ['Raw', 'Cleaned', 'Metadata', 'Provenance'], retrieval: ['BM25', 'Dense', 'Hybrid', 'Rerank'], evaluation: ['Recall', 'Citation', 'Support', 'Abstention'], }[variant] || ['TekRAG', 'RAG', 'QA']; return (
{hoverLabel}
{labels.map((label) => {label})}
); } function BillingDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => (t + 1) % 120), 80); return () => clearInterval(id); }, []); const h = compact ? 200 : 280; const bars = [ { label: 'Input', base: 40, peak: 110, color: '#0F6B73' }, { label: 'Output', base: 55, peak: 140, color: '#D49A2A' }, { label: 'Cache', base: 20, peak: 70, color: '#2F8F6B' }, { label: 'Image', base: 65, peak: 160, color: '#C76D4A' }, { label: 'Audio', base: 30, peak: 90, color: '#5F6B6D' }, ]; const progress = (Math.sin(tick * 0.08) + 1) / 2; return ( {bars.map((b, i) => { const bh = b.base + (b.peak - b.base) * progress; const x = 40 + i * 72; return ( {b.label} {Math.round(b.base + (b.peak - b.base) * progress)}k ); })} Token Usage {[0, 40, 80, 120, 160].map((v, i) => ( {v}k ))} ); } function LegalDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 100); return () => clearInterval(id); }, []); const h = compact ? 200 : 280; const tilt = Math.sin(tick * 0.05) * 12; return ( AI Product Liability AI Legal Scales {['CEO', 'Product', 'Corp'].map((t, i) => ( {t} ))} ); } function MathDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 60); return () => clearInterval(id); }, []); const h = compact ? 200 : 280; const nodes = [ { x: 210, y: 60, label: 'v₁', color: '#D49A2A' }, { x: 120, y: 120, label: 'v₂', color: '#0F6B73' }, { x: 300, y: 120, label: 'v₃', color: '#0F6B73' }, { x: 80, y: 200, label: 'v₄', color: '#2F8F6B' }, { x: 170, y: 200, label: 'v₅', color: '#2F8F6B' }, { x: 250, y: 200, label: 'v₆', color: '#2F8F6B' }, { x: 340, y: 200, label: 'v₇', color: '#C76D4A' }, ]; const edges = [[0,1],[0,2],[1,3],[1,4],[2,5],[2,6],[3,4],[4,5],[5,6]]; const pulse = (tick % 60) / 60; return ( {edges.map(([a,b], i) => { const p = (tick * 0.02 + i * 0.3) % 1; const mx = nodes[a].x + (nodes[b].x - nodes[a].x) * p; const my = nodes[a].y + (nodes[b].y - nodes[a].y) * p; return ( ); })} {nodes.map((n, i) => ( {n.label} ))} Unit Distance Graph — Erdős Conjecture ); } function AgentLoopDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 50); return () => clearInterval(id); }, []); const h = compact ? 200 : 280; const cx = 210, cy = h / 2, r = compact ? 70 : 90; const steps = ['Plan', 'Act', 'Observe', 'Reflect']; const colors = ['#0F6B73', '#D49A2A', '#2F8F6B', '#C76D4A']; const active = Math.floor(tick / 30) % 4; return ( {steps.map((s, i) => { const angle = (i / 4) * Math.PI * 2 - Math.PI / 2; const nx = cx + Math.cos(angle) * r, ny = cy + Math.sin(angle) * r; const next = (i + 1) % 4; const na = (next / 4) * Math.PI * 2 - Math.PI / 2; const nx2 = cx + Math.cos(na) * r, ny2 = cy + Math.sin(na) * r; const p = (tick % 30) / 30; const px = nx + (nx2 - nx) * p, py = ny + (ny2 - ny) * p; return ( {active === i && } {s} ); })} Agent ); } function GeopoliticsDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 70); return () => clearInterval(id); }, []); const h = compact ? 200 : 280; const regions = [ { x: 100, y: 80, label: 'US', color: '#0F6B73' }, { x: 200, y: 60, label: 'EU', color: '#D49A2A' }, { x: 310, y: 80, label: 'China', color: '#C76D4A' }, { x: 80, y: 180, label: 'India', color: '#2F8F6B' }, { x: 200, y: 190, label: 'MENA', color: '#5F6B6D' }, { x: 330, y: 180, label: 'APAC', color: '#0F6B73' }, ]; const links = [[0,1],[0,3],[1,2],[1,4],[2,5],[3,4],[4,5]]; return ( {links.map(([a, b], i) => { const p = (tick * 0.015 + i * 0.2) % 1; const mx = regions[a].x + (regions[b].x - regions[a].x) * p; const my = regions[a].y + (regions[b].y - regions[a].y) * p; return ( ); })} {regions.map((n, i) => ( {n.label} ))} Geopolitical AI Ecosystem ); } function BrowserDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 90); return () => clearInterval(id); }, []); const h = compact ? 200 : 280; const reqs = [0, 1, 2, 3, 4].map(i => ({ label: ['HTML','CSS','JS','API','WS'][i], color: ['#0F6B73','#D49A2A','#C76D4A','#2F8F6B','#5F6B6D'][i], w: [160,80,120,100,60][i] })); const progress = (tick % 60) / 60; return ( teknav.ir/article/... {reqs.map((r, i) => { const y = 58 + i * 34; const filled = Math.min(r.w, r.w * (((tick + i * 12) % 60) / 60) * 1.8); return ( {r.label} {Math.round(Math.min(filled, r.w) / r.w * 100)}% ); })} Browser DevTools — Network ); } function MemorySafetyDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 80); return () => clearInterval(id); }, []); const h = compact ? 200 : 280; const blocks = [ { x: 30, label: 'Stack', owned: true }, { x: 110, label: 'Heap A', owned: true }, { x: 190, label: 'Heap B', owned: false }, { x: 270, label: 'Heap C', owned: true }, { x: 350, label: 'Static', owned: true }, ]; const flash = Math.sin(tick * 0.15) > 0.7; return ( Memory Safety — Rust Ownership {blocks.map((b, i) => { const isUnsafe = !b.owned; const color = isUnsafe ? '#C76D4A' : '#2F8F6B'; const bh = 60 + Math.sin(tick * 0.05 + i) * 10; return ( {b.owned ? '✓' : '✗'} {b.label} ); })} use-after-free ); } function MediaDiagram({ compact = false }) { const [tick, setTick] = useState(0); useEffect(() => { const id = setInterval(() => setTick(t => t + 1), 60); return () => clearInterval(id); }, []); const h = compact ? 200 : 280; const nodes = [ { x: 60, y: h / 2, label: 'نویسنده', color: '#D49A2A', r: 22 }, { x: 210, y: h / 2 - 30, label: 'پلتفرم', color: '#0F6B73', r: 28 }, { x: 210, y: h / 2 + 30, label: 'RSS/Feed', color: '#2F8F6B', r: 20 }, { x: 360, y: h / 2 - 60, label: 'خواننده ۱', color: '#5F6B6D', r: 16 }, { x: 360, y: h / 2, label: 'خواننده ۲', color: '#5F6B6D', r: 16 }, { x: 360, y: h / 2 + 60, label: 'خواننده ۳', color: '#5F6B6D', r: 16 }, ]; const edges = [[0,1],[0,2],[1,3],[1,4],[1,5],[2,3],[2,4],[2,5]]; return ( {edges.map(([a, b], i) => { const p = (tick * 0.02 + i * 0.15) % 1; const mx = nodes[a].x + (nodes[b].x - nodes[a].x) * p; const my = nodes[a].y + (nodes[b].y - nodes[a].y) * p; return ( ); })} {nodes.map((n, i) => ( {n.label} ))} Content Distribution Network ); } function DiagramRenderer({ type, compact = false }) { const map = { neural: NeuralNetworkDiagram, pipeline: DataPipelineDiagram, cyber: CyberSecurityDiagram, growth: StartupGrowthDiagram, chip: HardwareChipDiagram, timeline: FutureTimelineDiagram, arch: SoftwareArchDiagram, wave: WaveStreamDiagram, orbit: OrbitDiagram, brain: BrainDiagram, database: DatabaseDiagram, cloud: CloudDiagram, quantum: QuantumDiagram, vla: VlaDiagram, dna: DnaDiagram, fusion: FusionDiagram, satellite: SatelliteDiagram, blockchain: BlockchainDiagram, billing: BillingDiagram, legal: LegalDiagram, math: MathDiagram, 'agent-loop': AgentLoopDiagram, geopolitics: GeopoliticsDiagram, browser: BrowserDiagram, 'memory-safety': MemorySafetyDiagram, media: MediaDiagram, 'tekrag-corpus-3d': (props) => , 'tekrag-retrieval-3d': (props) => , 'tekrag-evaluation-3d': (props) => }; if (typeof type === 'string' && /^diagram-\d{3}$/.test(type)) { const variant = Number(type.split('-')[1]); return ; } const Comp = map[type] || NeuralNetworkDiagram; return ; } export { NeuralNetworkDiagram, DataPipelineDiagram, CyberSecurityDiagram, StartupGrowthDiagram, HardwareChipDiagram, FutureTimelineDiagram, SoftwareArchDiagram, WaveStreamDiagram, OrbitDiagram, GeneratedDiagram, TekRagThreeDiagram, BillingDiagram, LegalDiagram, MathDiagram, AgentLoopDiagram, GeopoliticsDiagram, BrowserDiagram, MemorySafetyDiagram, MediaDiagram, DiagramRenderer };