'); inOl = true; }
parts.push(`- ${inlineToHtml(m[2].trim())}
`);
continue;
}
para += (para ? ' ' : '') + t.trim();
}
flushPara();
closeLists();
if(inCode) parts.push('');
return parts.join('');
}
function buildTocFromContent(root){
const toc = [];
const hs = root.querySelectorAll('h1, h2, h3');
hs.forEach(h => {
const level = Number(h.tagName.slice(1));
const title = h.textContent || '';
const id = h.getAttribute('id') || '';
if(!id) return;
toc.push({level, title, id});
});
return toc;
}
function render(){
const nav = document.getElementById('nav');
const content = document.getElementById('content');
const tocEl = document.getElementById('toc');
const dict = t();
const search = (state.search || '').toLowerCase().trim();
const searchInput = document.getElementById('search');
if(searchInput) searchInput.placeholder = dict.searchPlaceholder;
nav.innerHTML = '';
const visible = state.chapters.filter(ch => {
if(!search) return true;
return (ch.title||'').toLowerCase().includes(search) || getNavTitle(ch).toLowerCase().includes(search) || (ch.relPath||'').toLowerCase().includes(search);
});
const groups = buildGroups(visible);
const forceExpand = !!search;
groups.forEach(g => {
const header = document.createElement('button');
header.type = 'button';
header.className = 'nav-group-header';
const toggle = document.createElement('span');
toggle.className = 'nav-group-toggle';
header.appendChild(toggle);
const title = document.createElement('span');
title.className = 'nav-group-title';
title.textContent = g.title;
header.appendChild(title);
const expanded = forceExpand || state.expandedGroups.has(g.key);
header.setAttribute('data-expanded', expanded ? 'true' : 'false');
header.addEventListener('click', () => {
const nowExpanded = !(header.getAttribute('data-expanded') === 'true');
header.setAttribute('data-expanded', nowExpanded ? 'true' : 'false');
if(nowExpanded) state.expandedGroups.add(g.key);
else state.expandedGroups.delete(g.key);
saveExpandedGroups();
render();
});
const groupWrap = document.createElement('div');
groupWrap.className = 'nav-group';
groupWrap.appendChild(header);
const children = document.createElement('div');
children.className = 'nav-children';
children.style.display = expanded ? 'block' : 'none';
g.children.forEach(ch => {
const a = document.createElement('a');
a.className = 'nav-item' + (ch.id === state.activeId ? ' active' : '');
a.href = `#/${encodeURIComponent(ch.id)}`;
a.textContent = getNavTitle(ch);
children.appendChild(a);
});
groupWrap.appendChild(children);
nav.appendChild(groupWrap);
});
const active = state.chapters.find(c => c.id === state.activeId) || visible[0] || state.chapters[0];
if(!active){
content.innerHTML = '' + escapeHtml(dict.noChapters) + '
';
tocEl.innerHTML = '';
return;
}
if(active.id !== state.activeId){
state.activeId = active.id;
location.hash = `#/${encodeURIComponent(active.id)}`;
return;
}
const html = markdownToHtml(active.content);
content.innerHTML = html;
const toc = buildTocFromContent(content);
tocEl.innerHTML = '';
if(toc.length > 0){
const title = document.createElement('div');
title.className = 'toc-title';
title.textContent = dict.onThisPage;
tocEl.appendChild(title);
toc.forEach(it => {
const a = document.createElement('a');
a.href = `#/${encodeURIComponent(active.id)}#${encodeURIComponent(it.id)}`;
a.textContent = it.title;
a.style.paddingLeft = (it.level - 1) * 10 + 'px';
tocEl.appendChild(a);
});
}else{
tocEl.innerHTML = '' + escapeHtml(dict.onThisPage) + '
' + escapeHtml(dict.noHeadings) + '
';
}
const anchor = decodeURIComponent((location.hash.split('#')[2] || '').trim());
if(anchor){
const el = document.getElementById(anchor);
if(el) el.scrollIntoView({block:'start'});
}else{
window.scrollTo(0,0);
}
}
function syncFromHash(){
const h = location.hash || '';
const m = h.match(/^#\/([^#]+)/);
if(m && m[1]){
state.activeId = decodeURIComponent(m[1]);
}
}
function init(){
loadLang();
try{
const req = window.EASYCHART_MANUAL_OPEN || {};
const hasHash = !!(location.hash && location.hash.length > 1);
if(!hasHash && req && req.chapterId){
location.hash = `#/${encodeURIComponent(req.chapterId)}` + (req.anchor ? `#${encodeURIComponent(req.anchor)}` : '');
}
}catch(_){
}
setChaptersFromManualData(getManualDataForLang(state.lang));
loadExpandedGroups();
ensureDefaultExpanded();
const langSelect = document.getElementById('lang');
if(langSelect){
langSelect.value = (state.lang === 'en') ? 'en' : 'zh';
langSelect.addEventListener('change', () => {
state.lang = (langSelect.value === 'en') ? 'en' : 'zh';
saveLang(state.lang);
ensureManualDataForLang(state.lang, () => {
setChaptersFromManualData(getManualDataForLang(state.lang));
syncFromHash();
render();
});
});
}
const searchInput = document.getElementById('search');
if(searchInput){
searchInput.addEventListener('input', () => {
state.search = searchInput.value || '';
render();
});
}
window.addEventListener('hashchange', () => {
syncFromHash();
render();
});
syncFromHash();
if(!state.activeId && state.chapters.length > 0) state.activeId = state.chapters[0].id;
render();
}
if(document.readyState === 'loading'){
document.addEventListener('DOMContentLoaded', init);
}else{
init();
}
})();