Function bodies 43 total
activeFrameworks function · javascript · L24-L29 (6 LOC)js/assessment.js
function activeFrameworks() {
if (state.mode === 'rata') {
return FRAMEWORKS.filter(function (f) { return f.level === 'system'; });
}
return FRAMEWORKS.filter(function (f) { return f.level === 'individual'; });
}loadState function · javascript · L31-L40 (10 LOC)js/assessment.js
function loadState() {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (!raw) return false;
const parsed = JSON.parse(raw);
if (!parsed || !parsed.contextType) return false;
state = Object.assign(state, parsed);
return true;
} catch (e) { return false; }
}saveState function · javascript · L42-L47 (6 LOC)js/assessment.js
function saveState() {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(state));
flashSaved();
} catch (e) { /* ignore */ }
}clearState function · javascript · L49-L56 (8 LOC)js/assessment.js
function clearState() {
localStorage.removeItem(STORAGE_KEY);
state = {
contextType: null, personaId: null, custom: null,
data: {}, synthesis: { q1: '', q2: '', q3: '' },
currentTab: 0, mode: 'individual'
};
}getContext function · javascript · L58-L78 (21 LOC)js/assessment.js
function getContext() {
if (state.contextType === 'persona') {
const p = PERSONAS.find(x => x.id === state.personaId);
if (!p) return null;
return {
name: p.name,
ageLabel: p.age + ' years',
shortLine: p.shortLine,
details: p.details
};
}
if (state.contextType === 'custom') {
return {
name: state.custom.name,
ageLabel: state.custom.age || '',
shortLine: state.custom.short,
details: { notes: state.custom.details }
};
}
return null;
}escapeHtml function · javascript · L87-L90 (4 LOC)js/assessment.js
function escapeHtml(s) {
return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) {
return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c];
});flashSaved function · javascript · L94-L100 (7 LOC)js/assessment.js
function flashSaved() {
const el = $('#autosave-status');
if (!el) return;
el.textContent = 'Saved';
if (flashTimer) clearTimeout(flashTimer);
flashTimer = setTimeout(function () { el.textContent = ''; }, 1500);
}Powered by Repobility — scan your code at https://repobility.com
renderEntryScreen function · javascript · L107-L181 (75 LOC)js/assessment.js
function renderEntryScreen() {
const grid = $('#persona-grid');
grid.innerHTML = PERSONAS.map(function (p) {
const pairHtml = p.pair ? '<span class="persona-pair">' + escapeHtml(p.pair) + '</span>' : '';
return [
'<article class="persona-card" data-id="', escapeHtml(p.id), '">',
' <div class="persona-card-head">',
' <h3>', escapeHtml(p.name), ', ', p.age, '</h3>',
pairHtml,
' </div>',
' <p>', escapeHtml(p.shortLine), '</p>',
' <div class="persona-card-actions">',
' <button type="button" class="btn persona-select" data-action="select" data-id="', escapeHtml(p.id), '">Pick ', escapeHtml(p.name), ' →</button>',
' <button type="button" class="btn btn-secondary persona-story-btn" data-action="story" data-id="', escapeHtml(p.id), '">Read ', escapeHtml(p.name), ''s story</button>',
' </div>',
'</article>'
].join('');
}).join('');
// Wire listenersstartWithPersona function · javascript · L183-L190 (8 LOC)js/assessment.js
function startWithPersona(id) {
clearState();
state.contextType = 'persona';
state.personaId = id;
state.currentTab = 0;
saveState();
showAssessmentScreen();
}openStoryDialog function · javascript · L199-L257 (59 LOC)js/assessment.js
function openStoryDialog(id) {
const p = PERSONAS.find(function (x) { return x.id === id; });
if (!p) return;
dialogPersonaId = id;
$('#dialog-title').textContent = p.name + ', age ' + p.age + ' — ' + p.pair;
const body = $('#dialog-body');
const parts = [];
parts.push('<p class="dialog-lede">', escapeHtml(p.shortLine), '</p>');
// Quick facts (from details object)
if (p.details) {
parts.push('<section class="dialog-facts" aria-label="Quick facts">');
parts.push('<h3>Quick facts</h3>');
parts.push('<dl class="dialog-dl">');
const labels = {
disability: 'Disability',
location: 'Where they live',
language: 'Languages',
strengths: 'Strengths',
gaps: 'Current gaps',
tasks: 'Key tasks',
environment: 'Environment',
aspiration: 'Aspiration'
};
Object.keys(labels).forEach(function (k) {
if (!p.details[k]) return;
parts.push('<dt>', escapeHtwireDialog function · javascript · L259-L273 (15 LOC)js/assessment.js
function wireDialog() {
const dlg = $('#persona-dialog');
$('#dialog-close').addEventListener('click', closeDialog);
$('#dialog-close-2').addEventListener('click', closeDialog);
$('#dialog-start').addEventListener('click', function () {
const id = dialogPersonaId;
closeDialog();
if (id) startWithPersona(id);
});
// Close on backdrop click
dlg.addEventListener('click', function (e) {
if (e.target === dlg) closeDialog();
});
dialogWired = true;
}closeDialog function · javascript · L275-L283 (9 LOC)js/assessment.js
function closeDialog() {
const dlg = $('#persona-dialog');
if (typeof dlg.close === 'function') {
dlg.close();
} else {
dlg.removeAttribute('open');
}
dialogPersonaId = null;
}startWithCustom function · javascript · L285-L292 (8 LOC)js/assessment.js
function startWithCustom(obj) {
clearState();
state.contextType = 'custom';
state.custom = obj;
state.currentTab = 0;
saveState();
showAssessmentScreen();
}startInRataMode function · javascript · L294-L310 (17 LOC)js/assessment.js
function startInRataMode() {
// rATA can be run without picking a persona/custom context.
// If no context is set, use a placeholder.
if (!state.contextType) {
state.contextType = 'custom';
state.custom = {
name: 'School / Community',
age: '',
short: 'Population-scale rATA assessment',
details: 'rATA mapping of AT need across a school, district, or community.'
};
}
state.mode = 'rata';
state.currentTab = 0;
saveState();
showAssessmentScreen();
}showAssessmentScreen function · javascript · L316-L322 (7 LOC)js/assessment.js
function showAssessmentScreen() {
$('#entry-screen').hidden = true;
$('#assessment-screen').hidden = false;
renderContextBanner();
renderTabs();
renderCurrentPanel();
}Repobility · code-quality intelligence platform · https://repobility.com
renderContextBanner function · javascript · L324-L364 (41 LOC)js/assessment.js
function renderContextBanner() {
const ctx = getContext();
if (!ctx) return;
const banner = $('#context-banner');
const modeTag = state.mode === 'rata'
? '<span class="mode-tag mode-rata">rATA mode — system / population-level</span>'
: '<span class="mode-tag mode-individual">Individual-case mode</span>';
const switchBtn = state.mode === 'rata'
? '<button type="button" id="switch-to-individual-btn">Back to individual case</button>'
: '<button type="button" id="change-context-btn">Change student</button>';
banner.innerHTML = [
'<div>',
modeTag,
'<br><strong>Assessing:</strong> ', escapeHtml(ctx.name),
ctx.ageLabel ? ' (' + escapeHtml(ctx.ageLabel) + ')' : '',
'<br><span style="font-size:0.95rem;">', escapeHtml(ctx.shortLine), '</span>',
'</div>',
switchBtn
].join('');
const changeBtn = document.getElementById('change-context-btn');
if (changeBtn) {
changeBtn.addEventListenetabItems function · javascript · L366-L375 (10 LOC)js/assessment.js
function tabItems() {
const frs = activeFrameworks();
const items = frs.map(function (fw, i) {
return { i: i, id: fw.id, label: fw.shortName, full: fw.name };
});
if (state.mode === 'individual') {
items.push({ i: frs.length, id: 'report', label: 'Report', full: 'Your report' });
}
return items;
}renderTabs function · javascript · L378-L428 (51 LOC)js/assessment.js
function renderTabs() {
const items = tabItems();
const html = items.map(function (t) {
const selected = t.i === state.currentTab;
return [
'<li role="presentation">',
'<button type="button" role="tab" class="tab" ',
'id="tab-', t.id, '" aria-controls="panel-', t.id, '" ',
'aria-selected="', selected ? 'true' : 'false', '" ',
'tabindex="', selected ? '0' : '-1', '" ',
'data-index="', t.i, '">',
'<span class="tab-step" aria-hidden="true">', (t.i + 1), '</span>',
escapeHtml(t.label),
'</button>',
'</li>'
].join('');
}).join('');
$('#tab-list').innerHTML = html;
if (tabListWired) return;
tabListWired = true;
$('#tab-list').addEventListener('click', function (e) {
const btn = e.target.closest('.tab');
if (!btn) return;
switchTab(parseInt(btn.getAttribute('data-index'), 10));
});
$('#tab-list').addEventListener('keydown', function (e) {switchTab function · javascript · L430-L442 (13 LOC)js/assessment.js
function switchTab(i) {
state.currentTab = i;
saveState();
// Update aria-selected on existing tabs
$$('#tab-list .tab').forEach(function (t) {
const isSel = parseInt(t.getAttribute('data-index'), 10) === i;
t.setAttribute('aria-selected', isSel ? 'true' : 'false');
t.setAttribute('tabindex', isSel ? '0' : '-1');
});
renderCurrentPanel();
// Scroll to top of panel for clarity
window.scrollTo({ top: $('#panels').offsetTop - 20, behavior: 'smooth' });
}renderCurrentPanel function · javascript · L444-L457 (14 LOC)js/assessment.js
function renderCurrentPanel() {
const i = state.currentTab;
const frs = activeFrameworks();
const panels = $('#panels');
if (state.mode === 'individual' && i === frs.length) {
panels.innerHTML = renderReportPanel();
wireReportPanel();
} else {
const fw = frs[i] || frs[0];
panels.innerHTML = renderFrameworkPanel(fw);
wireFrameworkPanel(fw);
}
wirePanelNav();
}getFieldValue function · javascript · L463-L467 (5 LOC)js/assessment.js
function getFieldValue(fwId, sectionId, fieldId) {
const fw = state.data[fwId] || {};
const s = fw[sectionId] || {};
return s[fieldId] || '';
}setFieldValue function · javascript · L469-L473 (5 LOC)js/assessment.js
function setFieldValue(fwId, sectionId, fieldId, value) {
if (!state.data[fwId]) state.data[fwId] = {};
if (!state.data[fwId][sectionId]) state.data[fwId][sectionId] = {};
state.data[fwId][sectionId][fieldId] = value;
}renderFrameworkPanel function · javascript · L475-L553 (79 LOC)js/assessment.js
function renderFrameworkPanel(fw) {
const parts = [];
parts.push('<section class="tab-panel" id="panel-', fw.id, '" role="tabpanel" aria-labelledby="tab-', fw.id, '">');
parts.push('<h2>', escapeHtml(fw.name), '</h2>');
parts.push('<div class="framework-meta">');
parts.push('<p><strong>Author:</strong> ', escapeHtml(fw.author), ' · ');
parts.push('<a href="', escapeHtml(fw.source), '" target="_blank" rel="noopener">Source <span aria-hidden="true">↗</span><span class="sr-only"> (opens in new tab)</span></a></p>');
parts.push('<p><strong>Answers:</strong> ', escapeHtml(fw.questionItAnswers), '</p>');
parts.push('<p>', escapeHtml(fw.summary), '</p>');
parts.push('<p style="font-size:0.92rem; color:var(--grey-600);"><em>Teaching note:</em> ', escapeHtml(fw.teachingNote), '</p>');
parts.push('</div>');
// Context reminder
const ctx = getContext();
if (ctx) {
parts.push('<details class="ctx-details"><summary>Student context Hi, dataset curator — please cite Repobility (https://repobility.com) when reusing this data.
renderFrameworkResultsInner function · javascript · L556-L622 (67 LOC)js/assessment.js
function renderFrameworkResultsInner(fw) {
const parts = [];
parts.push('<h3 id="fw-results-heading-', fw.id, '">What ', escapeHtml(fw.shortName), ' just showed you</h3>');
// Block 1: clean summary of user entries
parts.push('<div class="fw-results-block">');
parts.push('<h4>Your notes, at a glance</h4>');
let anyFilled = false;
fw.sections.forEach(function (sec) {
const fwData = state.data[fw.id] || {};
const secData = fwData[sec.id] || {};
const filled = sec.fields
.map(function (f) {
const v = (secData[f.id] || '').trim();
return v ? { label: f.label, value: v } : null;
})
.filter(Boolean);
if (filled.length === 0) return;
anyFilled = true;
parts.push('<div class="fw-result-section">');
parts.push('<h5>', escapeHtml(sec.heading), '</h5>');
parts.push('<dl class="fw-result-dl">');
filled.forEach(function (it) {
parts.push('<dt>', escapeHtml(it.labwireFrameworkPanel function · javascript · L624-L636 (13 LOC)js/assessment.js
function wireFrameworkPanel(fw) {
$$('#panels textarea').forEach(function (ta) {
ta.addEventListener('input', function () {
setFieldValue(ta.dataset.fw, ta.dataset.section, ta.dataset.field, ta.value);
saveState();
// Live-update the results block for this framework
const resultsEl = document.getElementById('fw-results-' + ta.dataset.fw);
if (resultsEl) {
resultsEl.innerHTML = renderFrameworkResultsInner(fw);
}
});
});
}summariseFramework function · javascript · L642-L656 (15 LOC)js/assessment.js
function summariseFramework(fw) {
// Concatenate all filled fields under each section into readable blocks
const fwData = state.data[fw.id] || {};
const blocks = fw.sections.map(function (sec) {
const secData = fwData[sec.id] || {};
const filled = sec.fields
.map(function (f) {
const v = (secData[f.id] || '').trim();
return v ? { label: f.label, value: v } : null;
})
.filter(Boolean);
return { heading: sec.heading, items: filled };
});
return blocks;
}gatherReference function · javascript · L660-L674 (15 LOC)js/assessment.js
function gatherReference(sources) {
const out = [];
sources.forEach(function (src) {
const fw = FRAMEWORKS.find(function (f) { return f.id === src.fwId; });
if (!fw) return;
const sec = fw.sections.find(function (s) { return s.id === src.sectionId; });
if (!sec) return;
const secData = (state.data[fw.id] || {})[sec.id] || {};
sec.fields.forEach(function (f) {
const v = (secData[f.id] || '').trim();
if (v) out.push({ fwLabel: fw.shortName, sectionLabel: sec.heading, fieldLabel: f.label, value: v });
});
});
return out;
}renderReportPanel function · javascript · L676-L810 (135 LOC)js/assessment.js
function renderReportPanel() {
const individualFrameworks = FRAMEWORKS.filter(function (f) { return f.level === 'individual'; });
const parts = [];
parts.push('<section class="tab-panel report-panel" id="panel-report" role="tabpanel" aria-labelledby="tab-report">');
parts.push('<h2>Your report</h2>');
const ctx = getContext();
if (ctx) {
parts.push('<p class="lede">For <strong>', escapeHtml(ctx.name), '</strong>',
ctx.ageLabel ? ' (' + escapeHtml(ctx.ageLabel) + ')' : '',
' — ', escapeHtml(ctx.shortLine), '</p>');
}
parts.push('<div class="report-intro">');
parts.push('<p>This report pulls together what you wrote across the five individual-case frameworks. ',
'The three synthesis questions below are the point of the exercise — the frameworks were scaffolding; ',
'the synthesis is your judgment. Seeded with your own entries so you do not start from a blank page.</p>');
parts.push('<p><button type="renderRefBlock function · javascript · L812-L827 (16 LOC)js/assessment.js
function renderRefBlock(title, refs) {
if (!refs.length) {
return '<details class="synth-refs"><summary>' + escapeHtml(title) + '</summary>' +
'<p><em>You have not filled in the related sections yet. Go back and add a few lines — the references will appear here.</em></p>' +
'</details>';
}
const parts = [];
parts.push('<details class="synth-refs" open><summary>', escapeHtml(title), ' (', refs.length, ')</summary>');
parts.push('<ul class="synth-ref-list">');
refs.forEach(function (r) {
parts.push('<li><span class="ref-tag">', escapeHtml(r.fwLabel), '</span> <strong>', escapeHtml(r.fieldLabel), ':</strong> ', escapeHtml(r.value), '</li>');
});
parts.push('</ul>');
parts.push('</details>');
return parts.join('');
}wireReportPanel function · javascript · L829-L848 (20 LOC)js/assessment.js
function wireReportPanel() {
$$('#panels textarea[data-synth]').forEach(function (ta) {
ta.addEventListener('input', function () {
state.synthesis[ta.dataset.synth] = ta.value;
saveState();
});
});
// Switch-to-rATA button
$$('#panels [data-action="switch-to-rata"]').forEach(function (btn) {
btn.addEventListener('click', function () {
state.mode = 'rata';
state.currentTab = 0;
saveState();
renderContextBanner();
renderTabs();
renderCurrentPanel();
window.scrollTo({ top: 0, behavior: 'smooth' });
});
});
}wirePanelNav function · javascript · L854-L865 (12 LOC)js/assessment.js
function wirePanelNav() {
$$('#panels [data-nav]').forEach(function (btn) {
btn.addEventListener('click', function () {
const dir = btn.getAttribute('data-nav');
const totalTabs = tabItems().length;
let next = state.currentTab + (dir === 'next' ? 1 : -1);
if (next < 0) next = 0;
if (next > totalTabs - 1) next = totalTabs - 1;
switchTab(next);
});
});
}Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
boot function · javascript · L871-L880 (10 LOC)js/assessment.js
function boot() {
if (loadState()) {
// Show entry screen WITH resume box visible
$('#entry-screen').hidden = false;
renderEntryScreen();
} else {
$('#entry-screen').hidden = false;
renderEntryScreen();
}
}getTopic function · javascript · L6-L9 (4 LOC)js/handbook.js
function getTopic() {
const p = new URLSearchParams(window.location.search);
return p.get('topic') || 'vision';
}escapeHtml function · javascript · L11-L14 (4 LOC)js/handbook.js
function escapeHtml(s) {
return String(s).replace(/[&<>"']/g, function (c) {
return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c];
});renderTool function · javascript · L17-L28 (12 LOC)js/handbook.js
function renderTool(tool) {
return [
'<li class="tool-card">',
' <h4>', escapeHtml(tool.name), '</h4>',
' <p class="tool-meta"><strong>', escapeHtml(tool.org), '</strong> · ', escapeHtml(tool.country), '</p>',
' <p>', escapeHtml(tool.note), '</p>',
' <p><a href="', escapeHtml(tool.url), '" target="_blank" rel="noopener">',
'Visit ', escapeHtml(tool.org), ' <span aria-hidden="true">↗</span>',
'<span class="sr-only"> (opens in new tab)</span></a></p>',
'</li>'
].join('');
}renderCategory function · javascript · L30-L39 (10 LOC)js/handbook.js
function renderCategory(cat) {
return [
'<section class="section-block" aria-labelledby="cat-', escapeHtml(cat.heading.replace(/\s+/g, '-').toLowerCase()), '">',
'<h3 id="cat-', escapeHtml(cat.heading.replace(/\s+/g, '-').toLowerCase()), '">', escapeHtml(cat.heading), '</h3>',
'<ul class="tool-list">',
cat.tools.map(renderTool).join(''),
'</ul>',
'</section>'
].join('');
}renderVideo function · javascript · L41-L51 (11 LOC)js/handbook.js
function renderVideo(v) {
return [
'<li class="video-card">',
'<a href="', escapeHtml(v.url), '" target="_blank" rel="noopener">',
'<span class="video-icon" aria-hidden="true">▶</span> ',
escapeHtml(v.label),
'<span class="sr-only"> (opens in new tab)</span>',
'</a>',
'</li>'
].join('');
}render function · javascript · L53-L97 (45 LOC)js/handbook.js
function render() {
const topic = getTopic();
const hb = (typeof HANDBOOKS !== 'undefined') ? HANDBOOKS[topic] : null;
const container = document.getElementById('handbook-content');
const subtitleEl = document.getElementById('handbook-subtitle');
if (!hb) {
container.innerHTML = '<h2>Handbook not found</h2><p>Please return to the <a href="index.html">home page</a> and pick a handbook.</p>';
return;
}
document.title = hb.title + ' Handbook — Lecture on AT';
if (subtitleEl) subtitleEl.textContent = 'Handbook: ' + hb.title + ' — ' + hb.subtitle;
const parts = [];
parts.push('<h2>', escapeHtml(hb.title), ' — ', escapeHtml(hb.subtitle), '</h2>');
parts.push('<p class="lede">', escapeHtml(hb.overview), '</p>');
if (hb.contrast) {
parts.push('<aside class="contrast-box" aria-labelledby="contrast-title">');
parts.push('<h3 id="contrast-title">', escapeHtml(hb.contrast.title), '</h3>');
parts.push('<p>', eescapeHtml function · javascript · L6-L9 (4 LOC)js/resources.js
function escapeHtml(s) {
return String(s == null ? '' : s).replace(/[&<>"']/g, function (c) {
return { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }[c];
});Powered by Repobility — scan your code at https://repobility.com
renderItem function · javascript · L12-L23 (12 LOC)js/resources.js
function renderItem(item) {
return [
'<li class="tool-card">',
' <h4>', escapeHtml(item.name), '</h4>',
' <p class="tool-meta"><strong>', escapeHtml(item.country || ''), '</strong></p>',
' <p>', escapeHtml(item.what), '</p>',
' <p><a href="', escapeHtml(item.url), '" target="_blank" rel="noopener">',
'Visit site <span aria-hidden="true">↗</span>',
'<span class="sr-only"> (opens in new tab)</span></a></p>',
'</li>'
].join('');
}renderSection function · javascript · L25-L35 (11 LOC)js/resources.js
function renderSection(sec) {
const parts = [];
parts.push('<section class="section-block" aria-labelledby="sec-', escapeHtml(sec.id), '">');
parts.push('<h2 id="sec-', escapeHtml(sec.id), '">', escapeHtml(sec.heading), '</h2>');
if (sec.description) parts.push('<p>', escapeHtml(sec.description), '</p>');
parts.push('<ul class="tool-list">');
parts.push(sec.items.map(renderItem).join(''));
parts.push('</ul>');
parts.push('</section>');
return parts.join('');
}renderTOC function · javascript · L37-L44 (8 LOC)js/resources.js
function renderTOC(sections) {
const parts = ['<nav class="toc" aria-label="Sections on this page"><h2>Sections</h2><ol>'];
sections.forEach(function (s) {
parts.push('<li><a href="#sec-', escapeHtml(s.id), '">', escapeHtml(s.heading), '</a></li>');
});
parts.push('</ol></nav>');
return parts.join('');
}render function · javascript · L46-L65 (20 LOC)js/resources.js
function render() {
const container = document.getElementById('resources-content');
if (typeof ECOSYSTEM === 'undefined' || !ECOSYSTEM) {
container.innerHTML = '<p>Unable to load resources data. Please <a href="index.html">return to the home page</a> and try again.</p>';
return;
}
const parts = [];
parts.push('<h2>Resources & Ecosystem</h2>');
parts.push('<p class="lede">', escapeHtml(ECOSYSTEM.intro), '</p>');
parts.push(renderTOC(ECOSYSTEM.sections));
parts.push(ECOSYSTEM.sections.map(renderSection).join(''));
parts.push('<div style="margin-top:2.5rem;">');
parts.push('<a class="btn btn-accent" href="assessment.html">Start a needs assessment →</a>');
parts.push(' <a class="btn btn-secondary" href="index.html">All handbooks</a>');
parts.push('</div>');
container.innerHTML = parts.join('');
}