import { catalog } from './catalog.js'; import { files } from './files.js'; const state = { selected: catalog[0], query: '', preview: 'original', source: '', file: null }; const $ = (selector) => document.querySelector(selector); const escape = (value) => value.replace(/[&<>"']/g, (character) => ({ '&':'&', '<':'<', '>':'>', '"':'"', "'":''' })[character]); const redact = (value) => value.replace(/(NDO_PASS[^\n=]*[=:]\s*["']?)[^\n"']+/gi, '$1[REDACTED]').replace(/(password["']?\s*[:=]\s*["']?)[^\n"']+/gi, '$1[REDACTED]').replace(/\bsysadm@netcracker\.com\b/gi, '[REDACTED SERVICE ACCOUNT]'); const download = (name, content) => { const url = URL.createObjectURL(new Blob([content], { type: 'text/markdown' })); const a = document.createElement('a'); a.href = url; a.download = name; a.click(); URL.revokeObjectURL(url); }; const copy = async (content) => { if (navigator.clipboard?.writeText) return navigator.clipboard.writeText(content); const textarea = document.createElement('textarea'); textarea.value = content; textarea.setAttribute('readonly', ''); textarea.style.position = 'fixed'; textarea.style.opacity = '0'; document.body.append(textarea); textarea.select(); document.execCommand('copy'); textarea.remove(); }; function visible() { return catalog.filter((item) => `${item.author} ${item.title} ${item.focus}`.toLowerCase().includes(state.query)); } function syncUrl() { const url = new URL(window.location.href); url.searchParams.set('author', state.selected.author); url.searchParams.set('skill', state.selected.id); url.searchParams.set('view', state.preview); if (state.file && state.file.name !== 'SKILL.md') url.searchParams.set('file', state.file.name); else url.searchParams.delete('file'); history.replaceState({}, '', url); } function selectFromUrl() { const params = new URLSearchParams(window.location.search); const author = params.get('author'); const id = params.get('skill'); const view = params.get('view'); const byAuthor = author && catalog.filter((item) => item.author.toLowerCase() === author.toLowerCase()); const byId = id && catalog.find((item) => item.id === id); state.selected = byId || byAuthor?.[0] || catalog[0]; state.query = byAuthor ? state.selected.author.toLowerCase() : ''; state.preview = view === 'improved' ? 'improved' : 'original'; const available = files[state.selected.id] || [{ name:'SKILL.md', path:state.selected.path, kind:'skill' }]; state.file = available.find((item) => item.name === params.get('file')) || available[0]; $('#skill-filter').value = byAuthor ? state.selected.author : ''; } function renderList() { const items = visible(); $('#count').textContent = `${items.length} of ${catalog.length} reviewed`; $('#skill-list').innerHTML = items.map((item) => ``).join(''); $('#skill-list').querySelectorAll('button').forEach((button) => button.addEventListener('click', () => { state.selected = catalog.find((item) => item.id === button.dataset.id); state.file = (files[state.selected.id] || [{ name:'SKILL.md', path:state.selected.path, kind:'skill' }])[0]; state.preview = 'original'; state.source = ''; syncUrl(); renderList(); renderDetail(); })); } async function original(entry) { if (state.source) return state.source; try { state.source = redact(await (await fetch(state.file.path)).text()); } catch { state.source = '# Original preview unavailable\n\nServe this site from the repository root to load the submitted source.'; } renderDetail(); return state.source; } function renderDetail() { const entry = state.selected; const available = files[entry.id] || [{ name:'SKILL.md', path:entry.path, kind:'skill' }]; const markdown = state.preview === 'original' ? (state.source || 'Loading original Markdown…') : entry.improved; $('#detail').innerHTML = `
${escape(entry.status)}

${escape(entry.title)}

Submitted by ${escape(entry.author)} ·

THE JOB

${escape(entry.focus)}

WHAT'S ALREADY WORKING
HIGHEST-VALUE IMPROVEMENTS
${state.preview === 'original' ? 'ORIGINAL / SAFETY-REDACTED WHERE NEEDED' : 'IMPROVED DRAFT / READY TO ADAPT'}
${escape(markdown)}
`; $('#detail').querySelectorAll('[data-file]').forEach((button) => button.addEventListener('click', () => { state.file = available.find((item) => item.name === button.dataset.file) || available[0]; state.source = ''; state.preview = 'original'; syncUrl(); renderDetail(); })); $('#detail').querySelectorAll('[data-preview]').forEach((button) => button.addEventListener('click', () => { state.preview = button.dataset.preview; state.source = state.preview === 'original' ? state.source : ''; syncUrl(); renderDetail(); if (state.preview === 'original') original(entry); })); $('[data-copy]').addEventListener('click', async () => { const content = state.preview === 'original' ? await original(entry) : entry.improved; await copy(content); $('[data-copy]').textContent = 'Copied'; }); $('[data-download]').addEventListener('click', async () => download(`${entry.id}-${state.file.name.replaceAll('/', '-')}-${state.preview}.md`, state.preview === 'original' ? await original(entry) : entry.improved)); if (state.preview === 'original' && !state.source) original(entry); } $('#skill-filter').addEventListener('input', (event) => { state.query = event.target.value.toLowerCase().trim(); renderList(); }); window.addEventListener('popstate', () => { state.source = ''; selectFromUrl(); renderList(); renderDetail(); }); selectFromUrl(); renderList(); renderDetail();