/** Shared utility functions. */ export function scroll(el) { el.scrollTop = el.scrollHeight; } export function esc(s) { const d = document.createElement('span'); d.textContent = s; return d.innerHTML; } export function truncate(s, n) { return s.length > n ? s.slice(0, n) + '\u2026' : s; } export function renderMarkdown(text) { let html = esc(text); // Code blocks html = html.replace(/```(\w*)\n([\s\S]*?)```/g, (_, lang, code) => '
' + code.trim() + '');
// Inline code
html = html.replace(/`([^`]+)`/g, '$1');
// Bold
html = html.replace(/\*\*(.+?)\*\*/g, '$1');
// Italic
html = html.replace(/\*(.+?)\*/g, '$1');
// Bullet lists
html = html.replace(/^[\*\-]\s+(.+)$/gm, '