(function () { function escapeHtml(str) { return String(str) .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } function chunk(arr, size) { var out = []; for (var i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size)); return out; } function renderLinksTable(links, columns) { columns = columns || 3; links = Array.isArray(links) ? links : []; var rows = chunk(links, columns); if (rows.length) { var last = rows[rows.length - 1]; while (last.length < columns) last.push(null); } var html = ""; for (var r = 0; r < rows.length; r++) { html += ""; for (var c = 0; c < columns; c++) { var item = rows[r][c]; if (!item) { html += ""; continue; } var href = escapeHtml(item.href || "#"); var label = escapeHtml(item.label || ""); var img = escapeHtml(item.image || ""); var alt = escapeHtml(item.alt || item.label || ""); html += '"; } html += ""; } html += "
' + '' + '' + alt + '' + "

" + label + "

" + "
" + "
"; return html; } function renderAllSections(containerId, sectionsObj) { var container = document.getElementById(containerId); if (!container) return; sectionsObj = sectionsObj || {}; var keys = Object.keys(sectionsObj); // If you want a custom order, add an "order" number in links.js and sort here. // Default: object insertion order. var html = ""; for (var i = 0; i < keys.length; i++) { var key = keys[i]; var section = sectionsObj[key]; // support BOTH formats: // 1) new format: { title, links: [...] } // 2) old format: key: [ ...links... ] var title, links; if (Array.isArray(section)) { title = key; // fallback title links = section; } else { title = section && section.title ? section.title : key; links = section && Array.isArray(section.links) ? section.links : []; } // Skip empty sections (optional) if (!links.length) continue; html += "

" + escapeHtml(title) + "

"; html += renderLinksTable(links, 3); // divider between sections if (i !== keys.length - 1) html += "
"; } container.innerHTML = html || "

No sections defined.

"; } window.addEventListener("DOMContentLoaded", function () { // focus search input var q = document.getElementById("q"); if (q) q.focus(); renderAllSections("sections", window.LAUNCHPAD_LINKS); }); })();