// Memory list and detail rendering, extracted from render.js.
import { state, FOLDER_SVG } from './state.js';
import { loadMemoryMarkdown, isTextTruncated, loadFullText } from './data.js';
import registry from './registry.js';
// --- Utilities (local copies to avoid importing render.js) ---
function escapeHTML(s) { return String(s || '').replace(/&/g, '&').replace(//g, '>'); }
function pad2(n) { return String(n).padStart(2, '0'); }
function isSameDay(a, b) {
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
}
function fmtListTime(ts) {
const d = new Date(ts);
const now = new Date();
const hhmm = `${pad2(d.getHours())}:${pad2(d.getMinutes())}`;
if (isSameDay(d, now)) return hhmm;
const mmdd = `${pad2(d.getMonth() + 1)}/${pad2(d.getDate())}`;
if (d.getFullYear() === now.getFullYear()) return `${mmdd} ${hhmm}`;
return `${d.getFullYear()}/${mmdd} ${hhmm}`;
}
function fmtRelative(ts) {
const diff = Date.now() - ts;
const min = 60000, hr = 3600000, day = 86400000;
if (diff < 0) return 'in the future';
if (diff < min) return 'just now';
if (diff < hr) return Math.floor(diff / min) + 'm ago';
if (diff < day) return Math.floor(diff / hr) + 'h ago';
if (diff < day * 30) return Math.floor(diff / day) + 'd ago';
if (diff < day * 365) return Math.floor(diff / (day * 30)) + 'mo ago';
return Math.floor(diff / (day * 365)) + 'y ago';
}
function highlightPlain(text, query) {
if (!query) return escapeHTML(text);
const safe = escapeHTML(text);
const q = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
return safe.replace(new RegExp(q, 'gi'), m => `${m}`);
}
function sanitizeMarkdown(html) {
return html
.replace(/