From 84b575880dfe191b4c79732e949992989128093a Mon Sep 17 00:00:00 2001 From: KoiosSG Date: Wed, 27 May 2026 21:59:50 +0200 Subject: [PATCH 01/12] Add enterprise dashboard accessibility guard --- .../.gitignore | 3 + .../README.md | 33 +++ .../acceptance-notes.md | 24 ++ .../demo.js | 81 +++++++ .../index.js | 210 ++++++++++++++++++ .../make-demo-video.py | 136 ++++++++++++ .../package.json | 12 + .../reports/accessibility-report.md | 9 + .../reports/blocked-packet.json | 75 +++++++ .../reports/clean-packet.json | 22 ++ .../reports/demo.mp4 | Bin 0 -> 104275 bytes .../reports/summary.svg | 24 ++ .../reports/warning-packet.json | 29 +++ .../requirements-map.md | 16 ++ .../sample-data.js | 149 +++++++++++++ .../test.js | 62 ++++++ 16 files changed, 885 insertions(+) create mode 100644 enterprise-dashboard-accessibility-guard/.gitignore create mode 100644 enterprise-dashboard-accessibility-guard/README.md create mode 100644 enterprise-dashboard-accessibility-guard/acceptance-notes.md create mode 100644 enterprise-dashboard-accessibility-guard/demo.js create mode 100644 enterprise-dashboard-accessibility-guard/index.js create mode 100644 enterprise-dashboard-accessibility-guard/make-demo-video.py create mode 100644 enterprise-dashboard-accessibility-guard/package.json create mode 100644 enterprise-dashboard-accessibility-guard/reports/accessibility-report.md create mode 100644 enterprise-dashboard-accessibility-guard/reports/blocked-packet.json create mode 100644 enterprise-dashboard-accessibility-guard/reports/clean-packet.json create mode 100644 enterprise-dashboard-accessibility-guard/reports/demo.mp4 create mode 100644 enterprise-dashboard-accessibility-guard/reports/summary.svg create mode 100644 enterprise-dashboard-accessibility-guard/reports/warning-packet.json create mode 100644 enterprise-dashboard-accessibility-guard/requirements-map.md create mode 100644 enterprise-dashboard-accessibility-guard/sample-data.js create mode 100644 enterprise-dashboard-accessibility-guard/test.js diff --git a/enterprise-dashboard-accessibility-guard/.gitignore b/enterprise-dashboard-accessibility-guard/.gitignore new file mode 100644 index 00000000..75b3a515 --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/.gitignore @@ -0,0 +1,3 @@ +frames/ +__pycache__/ +*.tmp diff --git a/enterprise-dashboard-accessibility-guard/README.md b/enterprise-dashboard-accessibility-guard/README.md new file mode 100644 index 00000000..8c82fa3a --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/README.md @@ -0,0 +1,33 @@ +# Enterprise Dashboard Accessibility Guard + +Self-contained Enterprise Tooling slice for issue #19. + +This module evaluates institutional admin dashboard releases before they are shown to admins, included in scheduled exports, or summarized through webhook notices. It uses synthetic dashboard records only and does not call external accessibility scanners, SSO providers, webhook endpoints, or private institutional systems. + +## What It Checks + +- Critical metric color contrast +- Missing screen-reader labels +- Keyboard reachability and focus traps +- Private user or project data embedded in accessibility text +- Missing table and export summaries +- Heading-order skips +- Missing reduced-motion fallbacks for animated dashboard content + +## Commands + +```bash +npm run check +npm test +npm run demo +npm run demo:video +``` + +`npm run demo` writes JSON, Markdown, and SVG reviewer artifacts under `reports/`. `npm run demo:video` renders a short local MP4 walkthrough. + +## Safety + +- Synthetic sample data only +- No private dashboard data, SSO records, webhook calls, or network access +- No credentials, tokens, payment details, or institutional secrets +- Release decisions are guard outputs, not production enforcement actions diff --git a/enterprise-dashboard-accessibility-guard/acceptance-notes.md b/enterprise-dashboard-accessibility-guard/acceptance-notes.md new file mode 100644 index 00000000..6d94ec18 --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/acceptance-notes.md @@ -0,0 +1,24 @@ +# Acceptance Notes + +- Adds `enterprise-dashboard-accessibility-guard/` as an independent module. +- Keeps all records synthetic and local. +- Uses dependency-free Node.js logic for deterministic dashboard release decisions. +- Covers blocked, clean, and warning-only dashboard states with tests. +- Generates reviewer artifacts: + - `reports/blocked-packet.json` + - `reports/clean-packet.json` + - `reports/warning-packet.json` + - `reports/accessibility-report.md` + - `reports/summary.svg` + - `reports/demo.mp4` + +## Local Validation + +Run: + +```bash +npm run check +npm test +npm run demo +npm run demo:video +``` diff --git a/enterprise-dashboard-accessibility-guard/demo.js b/enterprise-dashboard-accessibility-guard/demo.js new file mode 100644 index 00000000..36656709 --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/demo.js @@ -0,0 +1,81 @@ +const fs = require('fs'); +const path = require('path'); + +const { assessDashboardRelease } = require('./index'); +const { blockedDashboard, cleanDashboard, warningDashboard } = require('./sample-data'); + +const reportsDir = path.join(__dirname, 'reports'); +fs.mkdirSync(reportsDir, { recursive: true }); + +const packets = [ + ['blocked-packet.json', assessDashboardRelease(blockedDashboard)], + ['clean-packet.json', assessDashboardRelease(cleanDashboard)], + ['warning-packet.json', assessDashboardRelease(warningDashboard)] +]; + +for (const [fileName, packet] of packets) { + fs.writeFileSync(path.join(reportsDir, fileName), `${JSON.stringify(packet, null, 2)}\n`); +} + +fs.writeFileSync(path.join(reportsDir, 'accessibility-report.md'), renderMarkdown(packets)); +fs.writeFileSync(path.join(reportsDir, 'summary.svg'), renderSvg(packets)); + +for (const [fileName, packet] of packets) { + console.log(`${fileName}: ${packet.status}; findings=${packet.findings.length}; digest=${packet.auditDigest.slice(0, 12)}`); +} + +function renderMarkdown(packetRows) { + const lines = [ + '# Enterprise Dashboard Accessibility Report', + '', + '| Packet | Status | Dashboard | Export | Webhook | Findings |', + '| --- | --- | --- | --- | --- | --- |' + ]; + + for (const [fileName, packet] of packetRows) { + lines.push([ + fileName, + packet.status, + packet.releaseLanes.adminDashboard, + packet.releaseLanes.scheduledExport, + packet.releaseLanes.webhookNotice, + packet.findings.map((finding) => finding.code).join(', ') || 'none' + ].join(' | ').replace(/^/, '| ').replace(/$/, ' |')); + } + + lines.push(''); + lines.push('All packets use synthetic dashboard records and deterministic SHA-256 audit digests.'); + return `${lines.join('\n')}\n`; +} + +function renderSvg(packetRows) { + const rows = packetRows.map(([, packet], index) => { + const y = 105 + index * 72; + const color = packet.status === 'hold_accessibility_release' ? '#dc2626' : packet.status === 'remediate_before_public_release' ? '#d97706' : '#16a34a'; + return ` + + + + ${escapeXml(packet.dashboardId)} + ${escapeXml(packet.status)} | findings ${packet.findings.length} | digest ${packet.auditDigest.slice(0, 16)} + `; + }).join(''); + + return [ + '', + ' ', + ' Enterprise Dashboard Accessibility Guard', + ' Institutional dashboards, exports, and webhook notices are gated before release.', + rows, + '', + '' + ].join('\n'); +} + +function escapeXml(value) { + return String(value) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +} diff --git a/enterprise-dashboard-accessibility-guard/index.js b/enterprise-dashboard-accessibility-guard/index.js new file mode 100644 index 00000000..ede63f3a --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/index.js @@ -0,0 +1,210 @@ +const crypto = require('crypto'); + +function assessDashboardRelease(dashboard) { + const findings = [ + ...assessVisualAndOperableComponents(dashboard), + ...assessMotion(dashboard) + ]; + const blockerCount = findings.filter((finding) => finding.severity === 'blocker').length; + const warningCount = findings.filter((finding) => finding.severity === 'warning').length; + + const packet = { + dashboardId: dashboard.dashboardId, + institutionId: dashboard.institutionId, + status: chooseStatus(blockerCount, warningCount), + releaseLanes: chooseReleaseLanes(blockerCount, warningCount), + findings, + actions: buildActions(dashboard, findings), + wcagSignals: buildWcagSignals(findings), + assessedAt: dashboard.assessedAt + }; + + packet.auditDigest = digestPacket(packet); + return packet; +} + +function assessVisualAndOperableComponents(dashboard) { + const components = [ + ...(dashboard.widgets || []), + ...(dashboard.alerts || []), + ...(dashboard.exports || []) + ]; + const findings = []; + + for (const component of components) { + if (component.foreground && component.background) { + const contrast = contrastRatio(component.foreground, component.background); + if (component.critical && contrast < 4.5) { + findings.push(finding( + component, + 'LOW_CONTRAST_CRITICAL_METRIC', + 'blocker', + `Critical component contrast is ${contrast.toFixed(2)}:1, below the 4.5:1 release threshold.` + )); + } + } + + if (!component.screenReaderLabel || !component.screenReaderLabel.trim()) { + findings.push(finding(component, 'MISSING_SCREEN_READER_LABEL', 'blocker', 'Component lacks a meaningful screen-reader label.')); + } + + if (component.keyboardReachable === false || component.focusTrap) { + findings.push(finding(component, 'KEYBOARD_TRAP', 'blocker', 'Keyboard users cannot reach or leave this component predictably.')); + } + + if (component.ariaTextContainsPrivateData || containsPrivateData(component.screenReaderLabel)) { + findings.push(finding(component, 'PRIVATE_DATA_IN_ACCESSIBILITY_TEXT', 'blocker', 'Accessibility text exposes private user, lab, or project data.')); + } + + if ((component.type === 'table' || component.format) && !component.tableSummary) { + findings.push(finding(component, 'MISSING_TABLE_SUMMARY', 'blocker', 'Table or export output needs a concise nonvisual summary.')); + } + } + + findings.push(...assessHeadingOrder(components)); + return findings; +} + +function assessHeadingOrder(components) { + const findings = []; + let previousLevel = null; + + for (const component of components.filter((item) => item.headingLevel)) { + if (previousLevel !== null && component.headingLevel > previousLevel + 1) { + findings.push(finding(component, 'HEADING_ORDER_SKIP', 'warning', 'Heading order skips a level and may confuse screen-reader navigation.')); + } + previousLevel = component.headingLevel; + } + + return findings; +} + +function assessMotion(dashboard) { + if (dashboard.motion?.animatedCharts?.length && !dashboard.motion.reducedMotionFallback) { + return dashboard.motion.animatedCharts.map((componentId) => ({ + componentId, + code: 'MISSING_REDUCED_MOTION_FALLBACK', + severity: 'warning', + message: 'Animated dashboard content needs a reduced-motion fallback before public release.' + })); + } + return []; +} + +function finding(component, code, severity, message) { + return { + componentId: component.id, + code, + severity, + message + }; +} + +function chooseStatus(blockerCount, warningCount) { + if (blockerCount > 0) return 'hold_accessibility_release'; + if (warningCount > 0) return 'remediate_before_public_release'; + return 'release_with_accessibility_monitoring'; +} + +function chooseReleaseLanes(blockerCount, warningCount) { + if (blockerCount > 0) { + return { + adminDashboard: 'blocked', + scheduledExport: 'blocked', + webhookNotice: 'blocked' + }; + } + if (warningCount > 0) { + return { + adminDashboard: 'internal_only', + scheduledExport: 'blocked', + webhookNotice: 'internal_only' + }; + } + return { + adminDashboard: 'allowed', + scheduledExport: 'allowed', + webhookNotice: 'allowed' + }; +} + +function buildActions(dashboard, findings) { + if (!findings.length) return ['release_with_accessibility_monitoring']; + + const actions = new Set(); + const hasBlocker = findings.some((item) => item.severity === 'blocker'); + if (hasBlocker) actions.add(`block_release:${dashboard.dashboardId}`); + + for (const item of findings) { + if (item.code === 'MISSING_REDUCED_MOTION_FALLBACK') { + actions.add(`add_reduced_motion_fallback:${item.componentId}`); + } + if (item.code === 'MISSING_TABLE_SUMMARY') { + actions.add(`add_table_summary:${item.componentId}`); + } + if (item.code === 'MISSING_SCREEN_READER_LABEL') { + actions.add(`add_screen_reader_label:${item.componentId}`); + } + } + + return [...actions].sort(); +} + +function buildWcagSignals(findings) { + const codes = new Set(findings.map((finding) => finding.code)); + return { + perceivable: !codes.has('LOW_CONTRAST_CRITICAL_METRIC') && !codes.has('MISSING_TABLE_SUMMARY'), + operable: !codes.has('KEYBOARD_TRAP') && !codes.has('MISSING_REDUCED_MOTION_FALLBACK'), + understandable: !codes.has('PRIVATE_DATA_IN_ACCESSIBILITY_TEXT') && !codes.has('HEADING_ORDER_SKIP'), + robust: !codes.has('MISSING_SCREEN_READER_LABEL') + }; +} + +function contrastRatio(foreground, background) { + const fg = relativeLuminance(hexToRgb(foreground)); + const bg = relativeLuminance(hexToRgb(background)); + const lighter = Math.max(fg, bg); + const darker = Math.min(fg, bg); + return (lighter + 0.05) / (darker + 0.05); +} + +function hexToRgb(hex) { + const normalized = hex.replace('#', ''); + const bigint = parseInt(normalized, 16); + return { + r: (bigint >> 16) & 255, + g: (bigint >> 8) & 255, + b: bigint & 255 + }; +} + +function relativeLuminance({ r, g, b }) { + const channels = [r, g, b].map((channel) => { + const srgb = channel / 255; + return srgb <= 0.03928 ? srgb / 12.92 : ((srgb + 0.055) / 1.055) ** 2.4; + }); + return 0.2126 * channels[0] + 0.7152 * channels[1] + 0.0722 * channels[2]; +} + +function containsPrivateData(value = '') { + return /[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}|private lab|restricted project/i.test(value); +} + +function digestPacket(packet) { + return crypto.createHash('sha256').update(stableStringify(packet)).digest('hex'); +} + +function stableStringify(value) { + if (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`; + if (value && typeof value === 'object') { + return `{${Object.keys(value) + .sort() + .map((key) => `${JSON.stringify(key)}:${stableStringify(value[key])}`) + .join(',')}}`; + } + return JSON.stringify(value); +} + +module.exports = { + assessDashboardRelease +}; diff --git a/enterprise-dashboard-accessibility-guard/make-demo-video.py b/enterprise-dashboard-accessibility-guard/make-demo-video.py new file mode 100644 index 00000000..8f779777 --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/make-demo-video.py @@ -0,0 +1,136 @@ +from pathlib import Path +import subprocess +import sys + +from PIL import Image, ImageDraw, ImageFont + + +ROOT = Path(__file__).resolve().parent +REPORTS = ROOT / "reports" +FRAMES = ROOT / "frames" + + +def load_font(size): + candidates = [ + Path("C:/Windows/Fonts/arial.ttf"), + Path("C:/Windows/Fonts/segoeui.ttf"), + Path("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"), + ] + for candidate in candidates: + if candidate.exists(): + return ImageFont.truetype(str(candidate), size=size) + return ImageFont.load_default() + + +def draw_frame(path, title, subtitle, accent, bullets): + image = Image.new("RGB", (1280, 720), "#111827") + draw = ImageDraw.Draw(image) + title_font = load_font(48) + subtitle_font = load_font(28) + bullet_font = load_font(25) + + draw.rectangle((0, 0, 1280, 18), fill=accent) + draw.text((70, 82), title, fill="#f9fafb", font=title_font) + draw.text((74, 154), subtitle, fill="#d1d5db", font=subtitle_font) + + y = 242 + for bullet in bullets: + draw.rounded_rectangle((84, y + 4, 106, y + 26), radius=5, fill=accent) + draw.text((130, y), bullet, fill="#e5e7eb", font=bullet_font) + y += 64 + + draw.text((74, 656), "Synthetic dashboard data only - no SSO, webhook, export, or private institution calls", fill="#9ca3af", font=load_font(20)) + image.save(path) + + +def main(): + REPORTS.mkdir(exist_ok=True) + FRAMES.mkdir(exist_ok=True) + + slides = [ + ( + "Enterprise Dashboard Accessibility Guard", + "Issue #19 admin dashboard release slice", + "#60a5fa", + [ + "Gates institutional dashboards before admin release", + "Checks contrast, labels, keyboard reachability, table summaries, and motion fallbacks", + "Keeps export and webhook lanes aligned with accessibility readiness", + ], + ), + ( + "Blocked Release", + "Critical accessibility and privacy issues", + "#ef4444", + [ + "Critical metrics fail contrast threshold", + "Screen-reader labels are missing or expose private data", + "Keyboard traps and missing table summaries block dashboard and export release", + ], + ), + ( + "Warning Release", + "Internal-only until remediated", + "#f59e0b", + [ + "Reduced-motion fallback is missing for animated charts", + "Dashboard and webhook notices stay internal-only", + "Scheduled exports remain blocked until the fallback is attached", + ], + ), + ( + "Clean Release", + "Allowed with monitoring", + "#22c55e", + [ + "WCAG-oriented signals are all true", + "Admin dashboard, export, and webhook lanes are allowed", + "Reviewer packet includes stable SHA-256 audit evidence", + ], + ), + ] + + frame_paths = [] + for index, slide in enumerate(slides): + frame_path = FRAMES / f"frame-{index:03d}.png" + draw_frame(frame_path, *slide) + frame_paths.append(frame_path) + + concat_file = FRAMES / "frames.txt" + concat_lines = [] + for frame_path in frame_paths: + concat_lines.append(f"file '{frame_path.as_posix()}'") + concat_lines.append("duration 1.5") + concat_lines.append(f"file '{frame_paths[-1].as_posix()}'") + concat_file.write_text("\n".join(concat_lines) + "\n", encoding="utf-8") + + output = REPORTS / "demo.mp4" + subprocess.run( + [ + "ffmpeg", + "-y", + "-f", + "concat", + "-safe", + "0", + "-i", + str(concat_file), + "-vf", + "fps=24,format=yuv420p", + "-movflags", + "+faststart", + str(output), + ], + check=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + print(f"wrote {output}") + + +if __name__ == "__main__": + try: + main() + except Exception as exc: + print(f"demo video generation failed: {exc}", file=sys.stderr) + raise diff --git a/enterprise-dashboard-accessibility-guard/package.json b/enterprise-dashboard-accessibility-guard/package.json new file mode 100644 index 00000000..fa2ed07d --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/package.json @@ -0,0 +1,12 @@ +{ + "name": "enterprise-dashboard-accessibility-guard", + "version": "1.0.0", + "private": true, + "type": "commonjs", + "scripts": { + "check": "node --check index.js && node --check sample-data.js && node --check test.js && node --check demo.js && python -m py_compile make-demo-video.py", + "test": "node test.js", + "demo": "node demo.js", + "demo:video": "python make-demo-video.py" + } +} diff --git a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md new file mode 100644 index 00000000..0af26adf --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md @@ -0,0 +1,9 @@ +# Enterprise Dashboard Accessibility Report + +| Packet | Status | Dashboard | Export | Webhook | Findings | +| --- | --- | --- | --- | --- | --- | +| blocked-packet.json | hold_accessibility_release | blocked | blocked | blocked | PRIVATE_DATA_IN_ACCESSIBILITY_TEXT, MISSING_SCREEN_READER_LABEL, KEYBOARD_TRAP, MISSING_TABLE_SUMMARY, LOW_CONTRAST_CRITICAL_METRIC, MISSING_TABLE_SUMMARY, HEADING_ORDER_SKIP, MISSING_REDUCED_MOTION_FALLBACK | +| clean-packet.json | release_with_accessibility_monitoring | allowed | allowed | allowed | none | +| warning-packet.json | remediate_before_public_release | internal_only | blocked | internal_only | MISSING_REDUCED_MOTION_FALLBACK | + +All packets use synthetic dashboard records and deterministic SHA-256 audit digests. diff --git a/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json b/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json new file mode 100644 index 00000000..e06ebec5 --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json @@ -0,0 +1,75 @@ +{ + "dashboardId": "enterprise-admin-overview", + "institutionId": "institution-redacted", + "status": "hold_accessibility_release", + "releaseLanes": { + "adminDashboard": "blocked", + "scheduledExport": "blocked", + "webhookNotice": "blocked" + }, + "findings": [ + { + "componentId": "compute-usage-critical", + "code": "PRIVATE_DATA_IN_ACCESSIBILITY_TEXT", + "severity": "blocker", + "message": "Accessibility text exposes private user, lab, or project data." + }, + { + "componentId": "private-project-table", + "code": "MISSING_SCREEN_READER_LABEL", + "severity": "blocker", + "message": "Component lacks a meaningful screen-reader label." + }, + { + "componentId": "private-project-table", + "code": "KEYBOARD_TRAP", + "severity": "blocker", + "message": "Keyboard users cannot reach or leave this component predictably." + }, + { + "componentId": "private-project-table", + "code": "MISSING_TABLE_SUMMARY", + "severity": "blocker", + "message": "Table or export output needs a concise nonvisual summary." + }, + { + "componentId": "webhook-failure-alert", + "code": "LOW_CONTRAST_CRITICAL_METRIC", + "severity": "blocker", + "message": "Critical component contrast is 3.08:1, below the 4.5:1 release threshold." + }, + { + "componentId": "weekly-admin-export", + "code": "MISSING_TABLE_SUMMARY", + "severity": "blocker", + "message": "Table or export output needs a concise nonvisual summary." + }, + { + "componentId": "private-project-table", + "code": "HEADING_ORDER_SKIP", + "severity": "warning", + "message": "Heading order skips a level and may confuse screen-reader navigation." + }, + { + "componentId": "compute-usage-critical", + "code": "MISSING_REDUCED_MOTION_FALLBACK", + "severity": "warning", + "message": "Animated dashboard content needs a reduced-motion fallback before public release." + } + ], + "actions": [ + "add_reduced_motion_fallback:compute-usage-critical", + "add_screen_reader_label:private-project-table", + "add_table_summary:private-project-table", + "add_table_summary:weekly-admin-export", + "block_release:enterprise-admin-overview" + ], + "wcagSignals": { + "perceivable": false, + "operable": false, + "understandable": false, + "robust": false + }, + "assessedAt": "2026-05-27T13:00:00Z", + "auditDigest": "c23d9d45d2282027a0571519fa0e8f8e75c43e21882757f6259b23f3ef547728" +} diff --git a/enterprise-dashboard-accessibility-guard/reports/clean-packet.json b/enterprise-dashboard-accessibility-guard/reports/clean-packet.json new file mode 100644 index 00000000..32bcfb6e --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/reports/clean-packet.json @@ -0,0 +1,22 @@ +{ + "dashboardId": "enterprise-admin-clean", + "institutionId": "institution-redacted", + "status": "release_with_accessibility_monitoring", + "releaseLanes": { + "adminDashboard": "allowed", + "scheduledExport": "allowed", + "webhookNotice": "allowed" + }, + "findings": [], + "actions": [ + "release_with_accessibility_monitoring" + ], + "wcagSignals": { + "perceivable": true, + "operable": true, + "understandable": true, + "robust": true + }, + "assessedAt": "2026-05-27T13:00:00Z", + "auditDigest": "e3abe7a1521f56544cd037dc7fc520af8f8841edf3fbbde2841b57729e2f1e43" +} diff --git a/enterprise-dashboard-accessibility-guard/reports/demo.mp4 b/enterprise-dashboard-accessibility-guard/reports/demo.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..9f8ca46389667e6b00e68206df0016fa5543da9c GIT binary patch literal 104275 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≤spK(r@%R{Qiymc&XSVqAQIs%ite2yK)LvqKt^+5fUKCidc4Wci6NLF%Ao85arl{<2 zH%Hknf2serFBF|-5sPs|E1LyyYt#x3?JrMr(eGA5hy()N!G}AJgP{67xx#=|=y6;L zB)Ahy;W6r$ILaGO!Hz2G9ZY0W{Z$APWEc6LVxrBC3e(w#inPWpgXn-QT=cDJm0o0COD4prQxz^G}BlvU){Rr1D>~p87A{< zwZfuxMmia=um~WF#Y>mrWR@MfkD|MxePxtZ0bYEUCHt_3QD&8_i z6o7ot&nlLM6E4QG?3s(oj@HGXNz$M z0zTKszp@Q5!)5@0x*@59n1l4nB&cW67n9622nO_nnGIis8}X1um)DQ9Kl`7ljzi)F zVPF=UR;W2Ytr#5RnKIjVd9OcbzHxGa$qV64Hg3}HJ&I?o>yFx7T*ZlT#5B-JpTzgi zMJvtQMBtVS1p&_0tD6)3-1ndc?767Pc^GMkOcbgB>k~~5<~}A^fY=8ZP1=lZbLCjZ zuad2e3#sEm?gehGRnvh|A!zbj_Zxg%07D_fzAhG#E1~r?8z!I42w2+H5nN#PqU~=3 zg1v+s#70D`tI=QH0DskGE(VMCr#rUol_?EWJ&zfN8=M8oN zWN+D>+HObFy_XfXQ5adv#3!E5aQF9`_@Wyt9#QQXQ=7hC@2oZ@JH$N*RXC~cuUMzeu?)b&Qx7_9tMPtuRwN3#+LDs&dGtaPH+0mxp{ZNReos1r6eH-r1fC-RuH(Np+rd|0gT%EY{|CSCKFUU| znOku9BF3*S2H&L@hjWr+VPNRpzAuKH6N2`pi;s7Kk4Mm(qETcuomK0SQvkA(wFMAC zLwjzKT6;9si;Eo$Sa%#4qB%20fuG*&p83s(f!Fz z$m#x>S%=&2xNy)i9v=ZuFCV^3db|+45MhAT8avDzhrQ?1aB~}tyc#4n>L=+nF+TSq zmxPJsW>9u#mM037g9FTJ8m_%U<<-YMT>%+0F|B7N*}rBFB0gKx{-!}gN5 z0&DrfWH|v{xD2y$KJJ$oDH>bTq3r1Quo=G9Pbt3dR2+twTQ1;DZ#u8LituT#U{rKr zRCMQoNhRt~zkw)X@Pl$kgvE@TJb7mNgv~ab?}2d+TjRePT*;)=#0qNnYdl@CK`_TF z0=7<#B>z%S!%(QsR<`g%VaFIt%ww>_fSh!2mvLQOqrh_aj#SH~Iu#&;1=Tp{2ixIn{>=q>1JX((5q=sRQq;w~d8_w?Hq*`@ zud|RXgjyAX34;5u)vB$rnjUmxAOdrKo*|Xa(M%HLSg@166!Y4COH%JqHMJ>?3*lNHq9b?+r7e8-OTeFe5g(=g_9*j`MUfcd{xD3BxR3YMWiOU{bOrx)JJndRyl2G zBslCduK1w-2<8qxXeA+%%i*3&E#GvnD#q5FeLp$l1?Qrp z&jovCQyrB=n`I?+`2 zf72_i_M0*$Sm!_W=Hvn34ldt4u&g!riv z-!}AAM6*kuu-~b2dc-ql#qR~y`OIO@{HwrptZ&DkPAh76DqhDRhEX0qH^1KcAh$xX z%neMz1uc(wCzkW}z)O4KetabZuUXOwjH}*j`+;YNugqbw>jPfDQU=D@IC7r?q$-|w z?|HsWM*41{p<>06AK3x{???AewraTi?yDHy5vAJ78Fn;JzMCGHYEagvQHOq&4;Z6b zij%qZ_`XWf*I|e#h_WWZViGQaVAmaXejvoq(uxqoU-NCe<-P2kkQYYy1c>iWZoSW~ z5t5^9@c`;gEazLuejaU%w+L`eQobM+G7=N~6Gn#(@rKp|1nEuG;XXS&D$fUkJv&pi zQO%)O2pdm&!TAryW%-Ll5_K8E)sDI5z&s}uIL0tXfiNcjgFq!UVHOOy(1;%_ik2 z>T1=EW`q_e^{jq*USd2)DVUNtkdNgvu@$}XV~QM*MI(Bm)N`%EsG;b-C-S%c#3)R% z9OWO5^iblnSG}%N7Jx})PM?uX9RPzRngh04_ULTIv6At=-HF7lgKOwC_MR?3lNY^S z@mveDma6NLmq@%-ZYA*~`;l(2*|n~iP>0zIccc`4BWl`rsEo=cSt>8lEfT_)!(Fb& zypcVes(Np=?+<<<0MDHB$0JjVoA9^ZuqJl_RO}wz`efAGt(sEveoZfi3PHUfUg>JaP{Uo?GB+z|LfZ@2@|1 zAyBAex8?1uE@`Gt;tFWZ{LkC`DGwaacMv?WH%)fdB&C+MQqcg?^_NC^>5=Ilw`D$CzFnw!qP z2(5PmOVe~|$&u3|q0AjVH;QqBNfBl9x7I}P(<*=3@JXLsS-Ejm>0|;xxNUUDaC!=j zQZ;*#92{i8&Ug7CC$pA8e6rrrW@f>p0p6$P#g2jUWel)OB5;dOG+8+7?GgT_XLuqk zX|@2{(ve-j4axBmP6Wc8it(KIa!R@*bSW%nv3`4CoBFLR9oY<$B5Nd;ydOZ7+yi$V z+xSc8f-q|L&XO*h%fLaUS>(ra7EZI8y)FNbxkW}&_@<@t8#F8Cz(I`QS1Cbp9`)lY zVon3rf0ll=W$Jh1aZoGol?hOyN%a;;XW4~$MgXUbx_=<<)dh~CT@;e=_)5TlWzmZ+ zl~9#rIX}MSH98TvDK~K?+DG4Nq_@S*9xHS}Oyk&PJemAR{?c4E;tItRJ1OfbBGqe$Ac9w6e^CM`RLyf$cq?#8CM zEzV}ci5aiL=OpA@;$_C6ppe&=BQN+2*Sr_|JFZK=;hKTU0lr}Fq4G;miG;DTiVz0K z&I3POWYeJvnd)zz{319KSzRVeW$S7hH+BWAuZO#HVR79y&pt%k9Oj*3t9sQA2JzdT zpWVhTh~NajcA^Fh{h0%_>@nD`42si&+>s69)cCTjl1DS%Lk+$s$)01drR zQAn*BeF6~UnK1(|bN6DT22iSVvDNOJ9xO=dh-gn1F01y5l%iC(KVZ0H7i+X|Lr;-- z4MO>d9$-bs4+(%P!dDi9J36^?tG^9K2(zh9S6Ygw?S-yV_F_1*-9fgra&W6)T zlxG7N#uUbGck;a*0Dz+$@e%vat3M}JINsE)}eYVm{2D}ncI7obebM;(?$9QqO1tALO=tp zDGnb#@xkDTWbQ^g+3FbsZDzOg6{GF$Bd=NNL(GP7A3YZA5mU_}KMJ^h32RMmjReDG zn9H7tr)bVtkz9OfxDz1R^On0ulZ7n&iU0rrseR^~Y0tA$&BiYAkDZ&(xElQ&#Y>0n zqLT~IdbPjBvmaoo`+ukU|IaqW|C?F*|GHaDb^Y0)Ymo(D zajGJt^G6$k@A0}gO6=9vWSSIW@=}uPFbtCm3Dj@g(NMg9!YSjzqX4YDSY~fo=v3og zSS&fA!I4Zxs+6XP`3Q5!Vop#6r&PRiB0uc!?A+-0+Iizu{O}J~iRa{QZ55bUcM26X z|2{zV(hS!_ql>LlP%m_?`$IU09m*+RjYOh%MW8Ni+8F4DRE{jSPkc5MxA_4)WE1M>mFUa;4+hM=vJ7%SqC%DklHJg`5Q38UGG;)+d4AM|Tabesx zN>ee!Joz^DcR(u>;K6|}{D_7|ITpy6mE{r?C6XDUt1*f?-s%(K4CGQ4?^84v@n)HUPb zk-91X3;(*Q6g+Bm5tb@t%npf(T9tWhF~nv5!n9q)$e5KbKH^Yjk02n3`-(+gOe8jqwq~mrg|3{)W)9yFIL=AwOr&u{JnUIY4pxoOPLLG2arS$w#66LW z<`Vh><{g=PbqKY48*)uz=V~`D_oTCptN!xq0pm7Dc?zI2s-r#c&Wued*|;)R?B$*Q zTyHbbqT+T$fLJ*{GFE6KG-J0xA5Boi&62@fWa&iGCk;=YzD9p^;7ZO3BcU>!#6i2ISpQ_SJ^!S5PWG*3n)*{&iuD& z7G2L4arQqK$ml^zE`#I!jTt$Z=J6@}Q~j-2>!UVDG$UHS{k$oqD**2NHPNtITvpDmJa%O5-jdOUYOK%^M@n$i}ePi z0{O<@8nd07*|m6IfC$4k*J@#{PMcEhBZ%`oMh;UBEJBpsG-KS{*;m_|{5S3hMTxhG z2=?)yD0U@AIcQPZ8JUi-8+@R}SzY6N+gtvOmqqkfGVu^9=xQQqdcG~G)+G`mD&{L(YVB0qRj zNumF6PAiMI#kh&EGTe0PQb3AfAQgii4r+;VfX;@j_fHfMU-L1J{H8D=p9$(Wkq`tCy7pQb|ls0>S?d#`c(pGX|bPE zCX38I$7LBTodkUm00up}GqHBK`IH)Ke)>nMw8$uEr#2QLZ0)4$+A1@D!ts`mqyX$# zOwtaQhu-~)iQeFlc52dLnWmBqB&5L>WQ|^b3a2~{XZZLvppRh^a;U=@4>l9Hr!=f29Vht(Z` zv%^t)B1jJ`cLB!HIVIhZP#qjNzjdT6#eXG_ro$ov0w6;NpIK9jdWB1t$84pRS;KS{ z1QMI}8Cx*fMZ$pZ#%pDIOf()1>#n}#t6+$Uqa*!Q)&|5O-!0i2E;OH66 zFT~tfG^&lpslRr7GB8ELJJ>M5XG);INhVV?50pXi;}+}eKe|2!gZxM)114Q^pHONH z9n877D{A%%2zr>FFc+a(WcSC1)tWFS194wN29qa*L+QI$XpK{;1%$-Uss zHjq7yJku1AE7*!-P`It@H7NK{-)kdQdA9O|Umkujg~R?g-5@qy1z{a!%@zk8|0i_t z!6l2>HflS9-p_M}j9LGeHFl$x+$r4w&(+I&b`XhxPzPP+695sfmknDoSXNpX8Y9CB z*wH%|4t$3;Q+%aiWW=$<=&C5(4I;KGC&V{3vvD_TKK_Ug2M3TH56P>qaHt@s>h)ac zFt;ytge0ZND%RWAk+t!uRAi{6lX~X3PR00%c_s!%?eiu(o#4hPsJ=tfkDkT|NdS56jN`eLFx@vr_s5ii7FOjNc)*fZ<9ed zuXU+}lSP{@dVZKQ+Q`j)k2K4?grEoZfan!2RP4L8c@vQ8PD%Q`i9ugD%CON?abMdC zz3N-|=D-b_?&rC36Bm?5_Dk=cQXdY!#q_yd4F%vOBkusu61PMl!u_+!@F|<^Y!nRU zoNN^I)!=%3EpVU=%A-lLx_jL>Uj^8TWDIW^9TyHD~{!t=9572EZxxMQk%dmv~lp zN4+_4(MN4g4V zKp$}j@d%oc3R}h$0LM8aniuP2gjOKQ$&FInnfvo9F6I@8U~I% z8(~K&w0itwVxI2J>V??sV}DTU%9c)1D&Q~vYwGaZUa*xpG>qL5gbwp2jIj-H@FNV_ zsQlBq!hE}pYy90Rg52equ{_h$8HRdo&jeqVz54Pn3{-5${fE>K+hw%44#h-6k}xiu z4=^+}=I81eTM*7(@Mw{+m$BRe&pYN52YPs6bL(8g~Y%hhOzARI*lf&%tz2P z-)Pc<2}nl`V9KUSEuT;i3;g@3ObaifKVNMSd5+qlhrLZlMkx&LR~Q z%cJuN-be~2!OXA;D?mfeC4_6g!gAW<{fA=uiUgp5KTU2fEUP`4M1gCJnB>X%nQc?G z`#d@MGB)2#LDKhVK89Y%e+d%Y8cdX*(Ae-{hY3^t#!*=9diMeaY)+D&vF^@amQA8- zqd`A07a^Iv%+?tam-4a2An+jOPKSZcgSxiqDcQ zF-o-aaEgBHBF0pM+R`*VlhaP;m&}vTle5ImL@+7F^haJzZMgXY&fRSpkEL>ZF)eD2 zBjha3eDKJzv&E}HYv@{%?6NQh^&#D2-;=1BB}OLx=87}ua! zj?$!nU@?EZqz7FzfdyQ}D!1rV5B|}>om>2-ZS|HrPmgntexTk96aDH)-ky~ynHHX7 zEqRxT@K`2s3cM7qhh)c^m_+hf(x^o_F_5KD3G;bBvR74rC44O>u{gkgkgdG+6vY4M zRX-dzq9P*Y0#Cn1AGsr-CfCMJ_64Ehh%=UZ5$ak(Ow`3Q@bJAG9WP>`h+cJ3VtzRdLnWXPHzXRo^TY&j7Cv9X4>Z15aU&B&PIsYCher5J0 z(cyH~W2m40SmIOIysxA&u^S3jchqsEhWyKn{Wwivc%WF<(pH;MMzx^wo!xNefrX6A z8+N?86m!lo@dUapWNIE=kXnyI&8vakY{^Jk@d;Yh<8|ve;mz+ zQmHQDyL{j5I9S|Ho#al~vwP}5yWwtSFXqZ;D{jk zL&ZId?X!m`diYoe`|1${WG1)9%Erq<)~DN(^cPxa)BKWX9&HAj7A&i-^G{@@E)y@= z?XQ*5)Ec{^aW(YzJFF!-oBJ?4_{))^xjp_!P3!#v%v*t+!}(U$z4z#H_`d+q|gi~ha61M+66q5{qX5Y=EmbZy>O|9l`oi%ccQEA7w` zdgi9sOgr0PZ#vYZhjkE2#rJaxqw@y^1kDTPkcQ@_2WoLM^zc+Wcc%_i{E|K}Yq$ef zR~VMLw)eaF2AruY<{=U9I`~d)93&Bhh8{xjMiqyZq00&Xv0{AkLJ&w7n zT|&N0s_rswi93YO{7|q)qMNTAkK(00_C7Ov-I@!?*m4W`0`#mV8qu1mH{IzrcwmxT z9|&?lS%TYl^CE7vBm~Bpl22q86W!QZ|LB+Sb4E{DPi8*04uxMxwh9iNUpxZO^@`Ww z1xj%8DGzef(OZ>JZpUlP#N(;qeu3_T+G;?u5JOqGhG&K`Q({m4#+KUQYb-;KQ1Z$r z7@Keu4UGwoYJYde)oz71BFpu6Z00k~p;UhZ45CTJ5n*Y3fK5nXLE#mtjA?)!n z6i0nL=sjrk!3Foh^HqCp=IWj|dCCNymy&|UO3dK~Nm2gtFjXmO>Cwmwx6l=_YKLN( zVDHHqM=BZ_#fUQs`pG5@_^=AS{TX^AjEbo7j`g~b)2Kng?|yFOsz5l-y!gV62Yq1D z&=MIhDS=oFa9JJ=d=D_py_&45Z<3Ylg`5LZ?>D^_!08 z$up*ZX-CIHa57~(uY-^jLfxpCC<`!nV7tW)1Tp?U( z&xhRPclWs2@vu%B`4R8%?{z{Rw8%@I9bq(`RZ^tT6FLhxPwrUWHKisNB-{X2YJn9O z&2Bz7O@mV(SCSDJ}ey{W+JaraN8Ip zSS(sin4r2`8P<_9h;3go-5H>;D*W~kQg%wvgn0fYC`*N-TJ@(karFZ{`k5mBXo*_T zAH3;X0o+i){D&cz#r1&J0002sESM|g5&Hd)2kiq3lS;o3h*I8M2H{=t32J!b6e-}zggH(TQpay{{W5;m-yaoT>RvReS&_$^4?^TfJe&Gib5(TGq zeB{=-a&PdF%n9V0L@P+w-+_w`AQL;MHLo_gwkE1@|5 z3ONOH!$g13(EpHDbpZgaaGgM(cEDEb|5*PD_=mM%X7yh%oBss+Z-4(;z+m`m%_5jPDT?|ZGHt)W^WQN6 zMg1crpxlf96Tr>?4uJ8W0D18LZvc6;{|A6P`u__+7R&z*;9o6}r}X~_;P`(5aQ@!| zPzz>x{Qm(OL(cDZ|GQcLs{jV}uO>+S9|CZ@vk70E`F)vn=wRb~K&}XY)ITlgvy#WA4@Bi`4OZe9_jbK*y zzX9yOzsf@XaTy{nWUDg!e+>WK6<{^~+A|C0t^YRxHe{3wD^CiXs^!x@>?**H3;>To zss*tQAYAz$HJ{;M83j<@>%Ra1B(*^z@(dQ@h=3yIu%KL7AkoYJG5$ML`~&v=e;q%S zVAk%x<2V2Q%Khg+^q*b#zsp^L|BOBt@BbLR!9SzV<^A7BpUeNhjb1A5?}X;x(d&N? z4E6k~gEa1c+C{>;B26z@ab1D4Fc(IEZXWKktc~ij&j|WCpFgFxo)8|*&&yKb|E+t0 zrdh~wFU3G2fHf5~D*cue`{PTv!1j62|3PRh^h?B6``C4}&Q$AbyxY$6JDi9a`l%Vh zK^VoYD{f2PqUkEukSy3P1bi3ewyX8;r0Qph0)TyMERnJ~E%r9*9YRbcJoiKOI*scd zS$nbLqKpTWdH6)aay|JOnnI>e2G8)PJgQYPS%^#yE_8H z2a%@$iI zL{7G5Vddh1E%SjY>^SnA^1N61lc0He(PTCJRA+HabMT9Yco#LVS25?AE}+&nKeP($ z+5#NH$@*KH-Rr|JV46;der};}eV=4Doo4RRhIJ5JX$fM1dH;OjAnjbI&Fx6C&%UJg zk0T&iuujo!;&u8wZqb|a?)K{s4%0K-Lpa!AzC;Z$by=w8;QgDdGCl$O#C5|*H6%r; zK=!%N3lr&JkkgfZaq;azb&s15wtE8r!1i-7O?qkNILL=Na=DAu*{M6-Lq0#Sl^iU# z*oiTqG|Zrj?TEEwY1p+Ta>&5<0w*y!w>AxsRXqM&k66ddC2&m`AfM{S;S;=C-O8xA z6F4z-_7@H;24h)Cqz}vCZE!b(Y;H~rpLVaaom#Jj`^~MdJHH{V%VHhKxe(;S>7AXShtFCA z1TdP-pZ@1p2>OK-P;pQtK@MiFYHfr|fK@xYyUQ>#ZM;1ESv7H1wY- z+G1((0=)|}1G}lQD{B#Uae?l>_A>$l84lMvOwd2+K$jG&xQi!BL2x{SOBH*X|@8#ZX@Hz+U=3t;!Uv#ctAP@(P{Sn{ffmlFpw7L$Js9;Om zm8plPi?iNssAmipdPR=1UY)MC$&nvUX0=JjQ~Ka1qU_FyG}h-#oAQMPdu56MFNyuN z0im$RVnjye#DoR8#mx^^-AD$|x4c+{o%kvcs%LK%3F3#uqNz-;yK~%@EH@#Qr6=^n zR`^U7kt30BzXUlrjXP(;^?RpO@BWPYoxn5op1)h~3d#4$r{e2PCkyzp<9Ri^BrlhO z5>rYn1kr=?MVV0%3T1&=_*oQmLZ%+Y>#%C+Wu!ye^sV&6ongq!Q*>e?tPxG66ZH{U zQlnl`+`Z^pTt~%_ir<&TZB1m7Q|bO5dGh4GKJ`A!GZh4mD(3zSs8hw9%#p&X$rSg- zDD~y1dG1L+r?7T1`%}3UVWbP$ns_f7K_@>&|3)UP`H|b*ILm;8c0Dh{nC{;;hUSH@ zm3RvJwiH9a`Oelp0AZSIzRE$jc{z!xH4v)QyBuQi)dhIkpALR0C*hRnD)8qHO=c=I z^XAjWf0z@**zgZ<_vGMJf@rPcW1y8ld){z~MTIF%F=v1YoAV@tnj=pkM_v*xZ<$uv z%cSw7{I;ny@r1xuTy&FAqY!1CC5f0T3L&Xue8e8DgJL91I;AY`#bg$yE{m+$g11_| zF8UQLEr*gLX#!u)B`x`aI2dshP#F_N28pyY^K}*mcV@1@#*k&@b8x%baA;}w*Yw6iOdYKq5Xkn(2{ShhIXTSUgkzS3K*{2Xf)3W zrO7oyT9dqRhjsg*A*JY!*F$c&e>bZ9EPC|Q4%oZmc7n3}-9qV9zv9uoZ-#ivnT1)) zaTwwuCorOW*m+`H^;Ycw_94cU*?r#+2*wW(_z@wLKmn~zi7IiAA+|q<%Z)6RliaB! zt2o71rW?`k4~cwB}DDG@3jEOGs4yl&r0C-}wDcp3uNZS@S)O@jle zt%L7A~Et@VjuD83Zly#$Xs1aX5zsjVVat$@yx zN<%7}be7?flA!XzOH4VX<($_pqNV+)5NkOhvUMeJu^EFf`(D;SgMe6pmN-v;f9pw4 z2A~I?mwJvB1WOH_crSXCf~Y(?M$oHYWM3G~US3|yw7$p>`>!D^lAtRZR?3IF#WN4aQz1ZnCw%Y1@*wZu zBl}9oGpJZ3-$@+yF8TjK)2k4O9oXOIN%E91rS?H*B~5*YEZV@P_g&6guMe#j3~RlUi*oNLflVL`p~He0YaB=FSydjS9f(0TKTw~` z);$b1dkK{D#?=!;hdxS4WB9`?UbN%LF6Xz(sNi?UDERZ|0bv>W-?n|kyCcbi`hpns zv~nE0F(hgJ_1#I*N`2{5he43FZk7ta^e4xXLzK?!=b;#EHGWg(alv8&?<0eMW`Edul_EmeLsBuCC2M;w4*#%DVO9oswfb#i$6vuJiK zo2f4=sb_b7A62d-=aM@3D0uyL!f2;4DCREm5U&$OFA{x?88UhZ~|tB zc5q%FIWLJfPrWDd*`@gkFi@r>aIfGJOuwb82AJ$rASRD3E4cF?d$u?7jkFhWbBxCuRSt_rkScJ^5Pn08_d90QvNoHsq=xaCbp&OsV%~)k7J78C()UG6cr_w#HHus+skVI=YXj(j@8eTWwUkd zz7lATL1F9Ab0|xBud4^Wd$6k61oaIS z<>mR@lU=72tDQk%paLAN_(gMA^7L>f8MWi25C_zDu)FIyw%L^I`^6+_SamAW`C%sI zA&T|%LC1Zp;I~?*tgJ)y@-8Ta8_(y7 zC3nW{td&%hv+24pO<+;xQ(NZs@iruq7|sgIB#VzASYXQ35djf!+lB{dA+^fB%eF4Wd|13v2?Ex#6U=kaa>I4K*HPBsl^>*mo1Lug;!c zT|$GOTB|YQvRW!&f73tCvDD}IcF)w2(~oc)(XdXHtYXoVvNGrr+xcuMdr_Qt_Cmk> z7KJnT_J0Q#1bV8=j>;cXQwAdA81b~`@5#bUU%a|yjc?P@l!#^^)9YPVl8_HY89eVZ z45?L^M<=0XiaHA-YRcPi6M5*Ar17K6A0MKo^SoJk91VIcJNHDLReYlBr<=qOV?%!V zqBc{Bud!1U$8C#Dj@nr5c7ejngSGDXP{3f`)D^LqAogEm4kuNZnTo(?_=Go0(|EOHEoEOHSk ziaby%Y#DI|Ja&u-D)uPx&nX1c45_i5?$R|p9KTxGw0LA)#s?toXCnZBP;vxIr)U46 zb~Oy#`8zc$CtS}wp{49KLiZ|!r=vW@RSf$9A)o^D>vryQKwZW~=8t=cO<~9?FtQX4 zD6#OhL^vzV3gVGC!IM5mAZssKO==0%tv`Hu6iVK>-o~;JXhoUJ>29#lcqrHW%!aZl zp~jwrR|4#DdF>^dW0|&}Ag}~#oVVbWEF1Q4np*zJY@&~&rTny#ltZ;ik+sXyJ2~R# zh=BaptnA||^1L1Pg2$;vg}1*^A|+HauT~Ph?4XkdNhZ7|Y{{i39oO=Ky3g+|p^0d* z4C8jIw%qx@U4Tr6N{P7Y94JFV-q}CO5~XR;v7Vyc_dy-cztL#y)264o_RzKse=**s zCj80$qlIJ`-;!m2T5ADTba`Uldk|#Za|{Yr<)|L^)?F(tTBb5!nxkk%B(J{8S8C$O z$^4<}aR^&fnuI+SA@?Y=^N!vTt8;j!5c#xI*a3ByMcrWcth;5NG!q&9yA7vTD1vgn z@5cz{Nw{SKD5V91W#>ua5UmU<>d{9RUU8iSH|Gc$kkj~Y(uj2pb#6+*Kv3uyi5||l z;N1%daKGW72r4-xt=)z&zd3; zZexjMHm!(c4GZ^x_BSO<>L8MSB^YX+WxR#|t{bSj9MwmGA(J=4U$^pnjvPdXZeU~j zLq@V`R_RtbuR2W-%kTE3vGr!LfcW@AL)!rTrNq76d7i-~@vxu(;u0Swa-79Boujh* z)A{&IL3VAj{RyAw5x>z#cS>b2Yv}wBVoH7*CT-C^d(BgyJGV6j{2>)ZaVWHRU@qkbA+ZHr ze7q;KLnpH<9z_{8RS?wj;TbbdGPz#iC}1dyC(D<}7X`#?FHTCZSuys`8LSTWw(zqe+(QdqUDF@!cKI^H$MmHn*eCnv0f~->$tuOmd+E-xq7@rt zYA%RE{3=jg)X)8G1<#>!f(OV`XCBlnaxsOf-8gE z;Gqv7nApiG_aaAodT`@UyeC$(kZKWww@Cv7ETfeo%?w3yu*6Z<{8aJUtT>7bn9&i8 zMi~Wk3Z!_v^~RTdHVQw2VQ*Hml2RRI1ohwS=!O&7ioM|kJA^X0r7b_qekGhbR5xoV z=V<%<$qjM{j;Ql+Gs?pMLL5z5B+!g;fs4qzP1*`R1M$~aI75+bkgZfgml{eGf4ReB z^_W9!Y;}CTBpW`GPsEq|xim5jgR^qTt8|6B*(QYmTG9(j*zEV)(W^TSB`jp4tDNS< zVEjNLyski@RN^ND46%+1;~6i|6fME&yDn}$;a&6PK;H=fy7W(={i+TIW1%BIHpvYx zUzQI7!8y#5C%&4mjE`IbAI#=d^Y& zSiq~98?^c(Agxi9ao2z_^6;<(ORwgab*q<2D>?znSe~q3Ay+gbb#=!j5L!b0Q*QTu zM9gEUI5D`$-~1UK!3K{B$33mQh!MBs6I7u#Re~)nm&{Ts9m%k9&3L#i)6)-Fj~93Z z_=fT!Xip!^JZp{Y5Py|-uRKKN{*cKM4;_U0n6P6?oV)m={l;v1bEP1My!0HT(PwUo{I9Z(!D!nYe>Ry!O8n*$EXSG@*YO}NcNaz{*yypp%pa4pxv923^Ec;$jq>3B%qgj4vBtiCT?qjf zaGCL?xR<7vdJxD>wk!UKLc-y=A=Rnd+)p|whA94<{!-kuq9QgT6K-Ktw;fIFwpsr3 zeiT?U6hXm>A!YN5*l*-6m*?P}08ZM#?6RuBo)XSlLYnq(8tf-v2`I&)3VP0AV{Pa> z&w^YaEl#FzJAdXK< zuu~)9pvbAvsG5EpPcTm2CLs;xTsy;2f4Ed%ll9I@9SF{zjAw6BrGfX@4X2 z@JLl6`6Pc%0AuP7{#?0Ql>770qaW<%*Hk81tZ8Tx*I7EgL$D?Bcn<)`AU>HLM#1sE z_^qwUEVwO$V6Q$Ukp-Ebh38w4So$6NT|}4u7W5|xp?=&?#BAT~XUzu=?bXpkZNgYZ)PjkFUGJB9yGhufD&W0Tp7YpXBj)<;;VFG0-$ zod|ryFu+y)zOSDu4q_wv1agBFKgx|vU-j{83&Hat+HnuO!eo_dt2Aa4iy0nZbb$V2Atv7gA&Ljq8s zMd$tKvXtYj`$eQO*&(;eLvJ0n3M7T?OHUwNW%v9P;-7d+*b(ps~%l`^8XH%dq#L0R(`jPgtEAfvueweX`sFWD?R*ygk)hoOO9 z&uHL?`hi~-v@!_3h2zV^(I>*7i3MjKVk`5SHxEX<%UnowFUa4|e4=aw5`4|IUz&Fp z4_DX3z73MJ(LCcYQ@2rAb+|mH^avD09cEZp{xo{f5xo~a zbIZQd{(qj$i|=GO3(M+Y?1wWGVmc%-k}J!p2hr(#A5Go&opEJnYb+09AJ>=1M&Qql zwLKq=w0B;9*ftU38!kvoIgj`ERoE^v|DeqAK4BDryxFo65{eQwknDhu*^J@%R8q87+h zdRIGRl|vWu1~^sc^N`e5{Uvl;#w4i;9hK*rSn)nb+NSuUH@Ki}S4O{*&WD@r#2G{{ z$&T?7#x{tB7)V~1hS@e23{W}82=cGx#jRhC^JhnAaev;Jp*fGbHGtxa95CalZQ2$< z4rPwh9^oeWHP6pMkG!o*ODA^BGM{xM;P&)I^g~2iyX`P!Bz&u1aEoPu1im*C|O3`j|R>}$q?i3p&K`sqI%NQ4!Fpo~nUWX~9S4w#{F_7=Rp>5Wi7mHg3ATe1;;$2599 zOz2@{We@^J7VY-Jgb{)8+rilJSZk_RnEP8c=z6@yF$Ssu?K9TU9bB2q-eyT%MSPH^ zE2y15(znis=6P3b3LrNKRv35`CSqEoZpIs?y(}fb<#ktyV#RBlH-E(-ss@-uGWEX# zcEjJuX~Mj2EPYAR!!Z%{gl`_{M8cyGD^&TcM*}-0fOih9pL#*gn(my_u^6}f7)GqDQ=)|sFDZ>B9GRY7d=M0^?vPr-QZC=y2E3p@@NcgKPBFXvy%2Y| zf`y!*O`&XF3(n;x2f~q47ytZ<3omE|O|?c2mL4)RZELT4DTLth!u8?qw!1`Rv}p`h z+1lNZ%} z0ovH4wk4(~IQtk36wRWEE^7KO-t!{s#Tf!Nksz%QipyO##BO{>lylC`T`bDtAasd8 zKMv@AOq6R^jD0eu!k6FM+~jdC?fOl*n`rS@7-?ERYEN)%^m1wNzZt+8ps2N5Oi9z? zGc`=yp(iBbdEfYiND%d)u$^l?<%LORi_15+=vp&NPV9VGq%i<^mY+M-skh_Vo~)za zCX)(niEfE&!B=@2xUY=`rS{qhi}!?<^Ap?4Tj0Bvg0Y^7Wq4ZEd2bnSk))fkp6apc z=L&6O-)wVd#ON!;WUn8iNL*wb)@~tc%2u%+yq@ckXi3+MOT?^LxbzZ8k>!gvr1dM- zR~Z|I>q0It}9s2dKhFSeFS*yMmS)~ zqn8B1F8zp?1bV7LNgB+bQP#X<6Y5f+Fd;G^rERoa5P9a0_vg7Vs1R)l|F;KQYYtw2~x;e@41JyIpS>-(0O zHZ$jmG_=Fuv`#y!UqWr&Dd|(k&`s+)SJ;3 ze-kceW<;#X#E=?yxp86Q!({jOaE!+*QHg<&dZCuzwpx{2YKZOij+!Hv(yz#+% zxk_@v&J`bZV43lxVtGG%l5V3M5GghdS?(%D!jeslXWUB4h`1V(cVBMTNO{cr@KHWX?Zn5tIH#a=>zNY0X29FZ4DY)Ck2!20V2qK zh$@zowa9)uHY#uxFM}MH>+;R8v<=64dgBx4`Jkp^Xx&b;zQ9Hh9Ba3RMNLM{VPX0D z-=-+|H*K5fr%l(RMF+8{fcrP5sG5Uw_Mz5`2$5BZm%Cn|9tgBUPYV3jx1wi+{#wKx ztAn*#qq~8Z!hy*zk}SvNirPL8_m3NgN&F#LLXzS*o&~CsL^}kS!BRcj%H<@7!hU@i zkK3RE_@4-{|Gw<$^`)3b)_XvOJSt)t8;jr3h?$K_z+&$bbpT{?9vcsIs@9!*Y(U(r z-OS%V8Xoh5J@48hV7v&gDHADN@sXL;dB|xPRt?R5sOSD-HB!)a{(BT|Y*sk|Avo5i zG4^9wGqiz)^0_og0*5+xNzq-(x_P3d?^B6uUP|KMf8+c>_OymEy+CWKbn4M(K9Qh3UlvbP8Wr->UyKOR>3^Q)9)j;6;=* z07fXPUFx$B+&1v~TCw0!_uUknR@&(n<{+A4pP%!LXn3)Fc4hG;QJ@^N2uHyu%CbCT zkjp-tTsK=S75;?kfkiu4S5iGHb!b<^ki212(bJXA!emq+pAAnPw5$7?B=X596lv`N z$2G}y`Hg_dD|r6z(u@N|BqLV%z#6p>}2WU#2pDJnY6EMFNn_Kh(f$ zk-DC(qDaXf$)@nxy;6KT5(~!O4?-@^3Hqg+W0}-VnhXx364uv&m+Oq$x_ig3&9?PU z{Ggnujn?*!cn~H^llQ-xRV|KpyJHYW^&`J?!}^PUmaSqlT!YkffK+!}SA>CtBTMM9YE6Tj|o#URb zB-KOzHMq6mEu43VQrP70P8CPAqdV;Df3Zq`?PZo8O6nkUfikF)ai-Y<@e030E*9Pc zi}l188Nq&B&VBY^Bye9Q5@aBBRqW56w{=V>R>g@<-0bU-3&>G2{>tGKlHX|ZLO zSdB!e^C;Ljr4v)_hNwA|y93YV(On*YIl`am3Q+G<8X?GWR7zz zSnRh25%x+cPm_0|sek%u_6xqfUW*j~Xg;l*I?-^=+3Q?Nl+1yWf^63hl)g^Wxb?Hb zPXrb!+z4Th+qfTHApe`+yoA7hq&x2e)tGL1F%YzRO4wu+aV-!f`=mtf_O48Y>Zx-= zo6TtT=RqXG@tA7k_|uC?yn1GF>Mgu0wMug<@HZs=lE?m0H<*O5=l;CzImz?sSvzMu zF0aNoEgLZeff2)f?8*ffo#P2O6NS&w;Rcppzhp=U=u_MK?}A%Et&}GvE_gysdT)q8 z^L2C{%Z&(qSi`rL@xe0@{V45qD%dt3B8**jS>istlBf0lKqNd61g;6A<`ofysw6Fk ze}hZhbaZ_ukC(Ai$ds%nvR0ZB)`5`m!&i{|Es^P#nLAaaw|j+lNHpZ;-QYNuCZ0Q>fKRTh9Cx;Ga;Ge8Ip| zP|j*qX%hMAFn>0rXB9gfH}lrH9m46l&kmu|c={!hNW>q4!?<+xnvuUzo`pUU?eFm@ zm%bup&>PuO?)eQR!ZYQSCO`M%0*=+rrz-2o>u88CM!8Ifj4HD7AfT>nzm2tbIvikz zI@WiMHjcGO7yO|sJU2;*Xc9*Jq5R>Jj!n853SF1D|D67Yus3&7w0JaNe!wF-nj(IirT;W`2Tv?G+kkvH)3EJqKMxtc*#C|==wk;kpX151Dw(Z#w zTqFI>PL;?eO?alkjf+=?6!Ms|_Qlt^`bdKyCA(k85reYT4iP&~n@Ov|BOCAuJA{BP z^(Agdf~XYZXhvb(P9F}b%0)gkp~@XKeAD0EIcX9v*OvRi{`cI*$6IK`MuOGRQuhSDZ}-F_Gv zUD=!FxuC0KsCEr-wt8B@2KV2lF_dPxyi2h-Oh~DAJgt|g#UMP&sUXE}Bwiswc_H%l z?^t((iz+I$vUcySw5j-A9&qM8fsa7vgp!gEz~~<_5_Q#Ny9CWDTmq1V3eA+xDI5#4 zLfa8%@wL4TPJQF(D%9oIAfi1Qic{H}TQen(AS3?HkF$-*Q}>l9dxx-S&Z%k;T605K zP&|suK4?g`H9w5W*E|KI?DokeYvd}-KGc})5hyux0-v)IPH}YA4;5mFsho{+pO-=l zlHbJCTqu_YE8_AglJQRnOZCf?QwDy$KA!tOpXnyE#u?=3bjAfaN?s}dR!1l2k8X!$ z%zhHw}$=0hq)$NX?;RULHZQ18TbF71s7M`yh%)iAp8CFfe z$GyhbI(sD$mmFNK*@*~;q^y|CM+4di$m1wn$MfV@dXpNK^jQ%#B?_AE@J5cr@O>=V z7_~>jT@=>?o&7|28(rJcb+JTX8A4d~x8>XkM>}eL?<{v6lsR?UftnWPfYp6Jr)wYY z#;3oqt=x*5Io96I?yg-L%Q;ZFeRy1H$E#% zz@pRkDwXvwP`+!p3zAIT#qDryX;$M#!U%mosrHn7*3JyGV$vn-(YfvZuQ{hpk@G|23o>J$o3`bZV=wxmZccTCs6ct!7rmkf2)v^d`^mR zC)~|m?tDCx})*nisE=n{k#}M|4 z)PA_{Ma?Y!qQ_7Dd8A)`)_~b919+$dGWTf1OpI=ug1#{Cp`gp7yK}uwI|EPlb5HJN z+W_Yac^%q51fCV{7kU{Br>>X+YP&qpG0MPZH?T=>$PcZ<&af=^a;<}rPR|o=e;Bc> z&Y8{2iW~s61k82epCg;p3A|FouXW}p7^*WO4_pi>IsR?dFn1J2*6;dtZWkIsa;r|N z8>I^#Mu9)Fe*46+%hw!!$HG0Zcja8Hk*?%26X^NavBeRf)&4vR154F*D8nT2)TMNV z0tt2)l;s{#-Jf;XCNq2#!ix-wQKQ+Ah88xp-A_M)iLQo@(kZ+~n-Q^_q`_y66Hl8g zqGfoZyWg%db7v{Wl0k=PGYqRW3( zX}grCMlOxDsdgn2<;D z*jMa(CZ|yB#dTyZfG$Z6BZ15TuYcF(cSL%$dwH15TdM86Dgx#%c3QKyBYt%3K^6tc z;%JriN?aT6qRDQ!2Q5oZ|LOtX0Eb%A6>gv_(05B!7D}s{?gOA}?pwpiT1-~9 ztwVO5UYvy^s-H7m;xR3ZT@l(<+PAq=xpmeD=1eC^d*0YR{urRVEPGt*++$B+z30yi zF!*3-1APP1>GZ@bZ9olBhRSD^W64U6$$#c2@FU|enTn;=e9@S;e*JXvmhQMu`ZxSvmw%sg;g@T^W_Ss8Xe&E+z63Kn1eG*`qCmLnK;I20)vfT zc2+#GXoC9Szc5!jZICzrCX2#aotS*7UG^rNnj2E+tC4!hba(g7Rbf+_$NX-*iPxBC#1%R1Q0c#v0tsL)bB9CSCHaaP_iurQn zXC5X%Nt!>UF_kWefvoU{OM+{ z*Z{gVH_#a+L0c&NDc;<;8M?CfOpI_lZ^0DOs2y3{;zxu@JHWU51n$e&(Vo-Cb9}AV zt?X;q)U2zL-}oH4RCLO%`ih3tf@=Ec^JXVFCjbaBU@xrg`JirKK%D zO!EM{ZOT@U*zcy*1bx=&rzLj4=~52m$H}Kp-mxcsL3NQ*j{B@!mx&4fS^>;^qi#L; zGaDBRxxppEos?_5JQsD9`GEWO!sF{CWTb^jS9fv={G%p>$$VuIYIDyHt}3tbWrwc>=qV zYM>Z(FnSsX2yhO*=yFn_F6tW@7L<9nUJap#LC>Kc#^ihyEgD0oI=j#!0*T)LIpRLa zV@wjGB8o8U2|a${y&c9LLTXxz%*1;Bu0NfoEQy+PGN}(s1T->hL*~e~&`*MRIy8BQ z8HiW9O}#x%$7nF@ZR--(dE>)s)cI2;mjW93$0c^JT5|6>D%jk;2={SP7ws7N_w8VI zfvP6mAQM?aZ&Vq?`}^M%MbE<672Zc~qnoHyb(x~};H{WTiqkld`0gu8bUt({?57fq z-Y3CkwG&B;3pc4BBU8lyP;Zq)w485HA08C<7pl*A(6caio!io|HNH6f+{#| ze*_v5VmG|C?>+JSyYd!39<2_DT>xUnzxVg5tGT0QuGo(xU zo{1I7`pY{UGp3egt-5FI8Gonjq7I$8*Cg2^eo*_Zoy-||Nv18Um=UO5{n`7Jwb-fy zx@;{VZtky?1_Nd)U6!NnVearBWYnk_4TW(US6GEdv4r`x+KYy!r)*K#f~BZf$E5WF z1esplKLeg=E_0Vry=FRZ^eMl2CzLU6EQsxpE=gW}R88?3j#pXSi0)W+r4;e=YeDn9 zHNy zhOQGV2QyRI6}jbR%eZnOt-jqrXVs=;K<4IkGNRVIzkS_Z9zlC zNbodP9P0IT^0C~Z`=tgg=`?Vk(r5d4_mx73(I0 z^+$w99wgX!UlgSedR-49ACj0b5GZ`J+>1H6by(acp)=24s+y0&inOLtq)ICcVB(?)pyr= zs=A+FhpH?1nO)H&!YMIhqx}HS@|#019!2fv*#Q&ZJr))oG@QkOH?16HiKNf3a`d%9 zsrcsZK&K^KL9;7xM#pD>KHlahqkB3gLe<7j`=z5c2J{>Ew}>)jVg&Y*q55A4&Avkz za^kno=spG~bv89MgT}$^XiB2)4uUqKxKr9BQID^QHayr%2zWj|mnf&hZsQGZ*oXw;f<|P@b=oE@q-G5Lb1GDoBnmDq6zt9I zVGBL!S&rwm*e1sJ_`1CV^T!|0!hYX!Tt6?E(3k@Bt@W;@fD)87`cJd+QQ&$_+K_G_ z35&htv4e7;<2ZD-fbycAM57TEmy+#9)#O5Ks`8|(o7cW)GHyh2Q>Cet_KD-8J4z;` za6OqKVs7n{i#FZki}kPbxOZ-)BEt9SoxgoIDN!8Q&M8QYImC90Z|bEFj2DOMmC3{5 z<;$ZtKm1AiW_yR4h@t%II&quvnMK;>s}_y!Vk%L-Y9EGo=UN$93dx!PNF)Ydi~P+~ zk@}DjN2}nM2x=|w*4jIxF@4$9^+OvuX{|TDS&iQc;`L4fNY9r63E0Xu6fI(OBb__MpFZ z2Dte;QHglPBr^aV$cciD2-NSzjrO!+#_6a|n}>56y7J*KKd=?L2K*3P2?;v@wtLX3 z$(7$h$b(h8hnRsHo_TZd%>{E~1qz`M9w6Ds(?YS~rHV%WP&5AH+ZJ9c@7%P^H-bt+ zVhjl7lURQ+w<7+I-coT#78(cF5hOTaQxkf~C+OR{X>0W3J;){xytcY8-KvD<+cFk2 ziW`UimGqQ!IzAhh1s}a0cvp^7YHJGEc&%jCHNI5cO-5~bB|`-L(Cijif&0|{&Igw2 zsw1uw^J73)?ZBiPV8gnO0j8X0oWhMOHmQMEMQdhTp^)XqbiPmB~ zGc%;=0ct7(nGiD?7fdCcRNj8%-pwyVp8^ruz0TO$gvHICiu5}mKd*Qsr%|T`Y-(4p z<`C_z0e!LITHXDw{QFifuQH+9XWzutLG%>c{kZL>F?5h6dDKX=3`U{_>Zd$Y({oeX zbfma^j<8NRm7Z{nbZacN=x_FzQT)z zHc{eV9Y*1syEg;RK|Ks?J|R{wq*==|6nYj4)@iN%opIc;A=BMvVsa|Z{WKJqpua)@ zGuLL9hvbylvL|5DJtAeyeGidg4@6L0$+K|N8+Myg*QJvd^$~WF`o#Fuye-ZslBjgF zPL3MIGKN!Mg;x8VQvKODUE@RQONy^7&$m0d@^fm>8c zO<1Y6&$5uYx{@bFYG*moxxo>T<>)3OE_M8%UV<=2SY%25w)3MW4)eN|3No=DLZvyP z%4PUeI7O1MH91nZ5pg3RdT5{5qh3uF(nk#+)d^NY}%su@^s zXQA)jp1p?Z7N4LzLMLOX3ySO2rrV8k#GlRGi@oRqI$#OQpt8m5K^(UST98dW(!er@rwViBA^p4NKR+!be@^}yKQzJ!eQ8%d6rGj-mLz2gk|G z=)hi+G7KLbJb8}(H8bpqt-fJy)>CX~aUf|kONPo`@*xn69OM)*{S~4G4MQ-Ts_s0i zQar=b|lQz^zBJxpt{IFeZh)I0Y>?tWT7JuaE|-M!DzLKOcw(XqQDjYaTd2*!M!o^M36N17QGsO*vCJ`?wXz{>Z4h zxF^ekT4mt1eYOm6w&&cJD495Qq>$P{Auv&}CT{tX-*iy9zA_4}C!04TFyvXCPdd|- zjr;X|FG24*8GOMmbq3<+)U0fNVs%}qKnAen3zGB%n`m(deF%9djM1_fB6jMj$%r0o zILpAqgP`6h&E%p~%A-yVh!`t36vYzx9kZnYmRowSp_OI0k$zRU?51!e@mX67G_vXN+99AsmecU&dv~i0LMCV7p0Qr!qZW?h7 zDZ4hvg01q4hbg~#f%x6dY}9S?4;ZFrXbCD6Wa@=}kxV6Eg)5u}#`1>q?&|t=XRRgY z@87%}Et;rGj~PY6A~(%szjtmNc=i8I^`q;tGO?fqrQep8f!XRg~4gqLcFN}>va zala`B$_@vQiI0hk)3|f5Z?C$S>*DCwZ!AZAHnOOQ-^(IFLB`BiS=04za9IK_aG-{S zKvO$d1O!bTF`mjNRQzYou3fHRFROQ=Y2@o|x&+1RZ%TIcWPcY?}G3mxdwWV#`4*)_kqIEiVXt+q}u`?i{p*=0T7e zwQcsAqQU341_SL{WqQ@hyJ!+g43W(07DKIr#6>7sojarx7Uk5>xPa5jTMdFlA5mbO zK%A(29=`VZ8QdB_sf3E`fGl%gGa1SvMo8Y8QsO{&#ZV?GrKW1Z)>Ya&Vi7}))(M2x zy{$k?x{C21LIYGJcmB}y44gV2^1-SBsDurV+!)Ikg_J#CBtp$bF1ny1-qeNDXfz^O zi&{!&(|7oVD2Ff?l;FW)AfS~f{POIs6!8_7@aF3nNdn7Z!*k)yGdrh3{n&-f2Xw!y zGEqfmgmH42bT$X5 z-6TPF;|TV=XDqK2sBdy%Pmyjz6(7mDCl0reE>N)O2f}BLo?ldwh|Zod4wQ-Q;ZdoI zigDoZtkgJg7keW1tgJya7@wUU)ekjF%LkyL`ht z^~ok|RAS(E*v8eHB~R857i1mcyt|3%2_|ocogx}JJJPjTFi0Zgh##?!)9Pq>`Nrs` z7OvNe7e#r0fQX)~CB?QmDnBtc|?cSV%uaIAEe<-dlhX;J+lunYm`B(|Y)F+*M8XsLr$z?5FZ*p+Gb+`p_TLtXbF!`ASSw3B9Dfr*!){T^$9 zmgJI#BSqDRzw8D5bqOuhD2=b&9)4rS>B9&yG=q_?2gg)^VBRziZGf3(&n`Rspk}GQ zN9H6sj^Xz0si1Pjf7-p81zBiLx}Xo|604hXG`72-Ez~W;yk?1gHjUR`C_ogpQNQ#D z&qw>$eIbE2L$t0z-I;4H3Z&C48Z*sSg&Z{sP))`yjQZJ4i98(8I1IQCkIwM()yElgYKL>qR3nu+y@W^QhVXiWie^;5!7rb1E%rc7fPrDSWmuFiXcHL``jnRc@9JVm*Y=vxcxXz0Z6NS>M!I4p>#$U8k|`#d&0?JDwZ!b<6LzLAs2`7UrYYYOT+@TF zR@iTHYhXFfSW*B$uY~ozmQ8W*Z!CF@4b9;jS=!SWPSwY4FLoV2^gsi0pR|2*+|*hf zZ+DIB?_!S&7F+W+!WbP~>p)VNOq2^uf++OPOl8Brya)RoRabu{=oTC#Gq-A@lx*-W zjd*ld0nYNzQ;9i03MDmF=tOV5w*Wl!R$jNCU{izj`w76<<;}-2~gfLU%QSU>vQ1Hi^VTvoLWh`OToOr z_;&UJVJCl7tVU6{t6@d0*M)ES?s-NyU|FA$$^@!<0Z#dzKGdEJ7ZA}!ata3e0$ui6 z!HZpES97ec0Ev3!G8s7-=D5bZjewcPVWqJ5iD=6Oqb6E{L4kkGkmO!G$_S}R)S4Y3 zFwXM6#LN!|x&%&H9DT`3Wl*_$fuFnIgT5-G5AJa5OVj4DGl8rgIEXjm8amST_d+Q% z)Mwg_!|v zpTL$iChzxq96ALX@$eTF1^NeX*`IfCt7u?R8c#notw8bC2cc|hkamF`!h3EmN?&6t z8BS;m_v3bgwW?r+EC!TGm;$Zy#)EK&L-Ck8-#gANXQ?z-LX}w*mE<$VTeD=_uWAD* z$DBwI&0~BcwTbezdD?^CC6*~9dgRtPP4((dD)}<8%@F59S8*9DLO!}L)eMmEeog8p zrpo^^tb7bPyT(>?r<2(=2YzVKI-A*h}DhGU-VMNTiTsd z=^TDVW3l6UX*CM%83xr!&o&-NTsAmc>!+0f`+3;D7wqSC0lPU-I1Rk>ZK2{rPKpK? zH5sR(>n^`H{_kKPH49XcuXSI87r+bPJW;4N-Ca)CE|CVe9VaE+&Q+P|YATkw8|2?7 z0yJ{YTVu=#a$l+M$(Y0UxbsCK<5sS}oXaQ^9>O*Up>xnp*8!SYx~89HSc^a`h)F2yA+Fe zIdB=MqJ>I~oV|G~#f$amZXT_J`A0D4IBbpFt@ochtkpp~y@RhG*+bjZ(FRuyqm?=# z`GhX2kldeuPv2oIs8>(+&REs)!j+gb!cK_{mao zlXH*{sxC(I7(t)!35;;a4eetWWq8&^2?FV)-#+t|GxoaS5~)SNc3hu@dDHTWmlO03 zQbct;(|kh>`|7v!U0t6sg!OeOn`8s@6f8HbPfW6K0dIE9ZG!cYH~yB*^Q24&QwpJb zbok3;z2+oBbdfvi_Yd%K>m+5-1|2UAA|bWbd;|RFpBF9l8B0uL>Ym*quV+@ebf}R+ z%gU)in$DWN(^%AMsJTGIsZx6*g zDqQZ@_x`e*K$5u6oZtcs$7d1!J$jG^lE(5{ zL2Ti#wY5iER5#?e%Yzb(0D57=AoyW&<7DH;;JidGh)%&U2KG>hwVDFx?ki2Qg?5(p zHv-1R}Wgh&_id3d-jYjV3S9tkQgMZfM1M4{=^W5S_?+Dolg`L%(!Hw&-vm| zvyZKzp|^F9%7ohHB4u7>v7?BxT*WKLOc=9rpwkcMa=ir4Z{HnHqss(~Qs0yj$Sp)wh0OH3*!w|9WzOImT;yh9EUbP9*3PP^Yi!2g zq@3=P7v2^2dNsO)hE1-4qGgGnFRy>Hz6MfxgK+6XUfwreW5Ok@;Kcp0v<6J9jJ+&m za-uNINl=P)fCrDk;@z~od)p)_W6nhQ$-46U;n=^#RkJhCp=a*`xgy>qX!^gbpcR!`t?@;?)PVNl7B-E?}})5P5u`A z#RUGF2lj_a2ITN>uHhg2pZ>>tWDQ6g>AfI&1jyFC;;)f(bk`@Ej(lBT?dUDDRfU#` zKK^&uAaj!+5MC&49(roK)a}>0@IXz!|9;CSh@a6y!0pgY5$nDCExWVpU(O}3_{4O1K#~{mn zrp0@Xr(A75ZVK-qsG9FpWI2hvc2tVL`%E_S8as!Fg9?CWHJ}>cs&NvIgVR~b1aCb* z`-xIQ{thphD+zF6s{CDSFG$gYf2K|_wKi6E=9n!-l$k<^+Ibz@!QCB&L*6+F6Siv>ACj z|8=LQtZL84g09SIU=1MBEe^dF(6ih_zsXFtd>x;QZ6C{uah1^J*XywVK)w->u5S1> z#--XpuqFmF(Y9A&dY<{Z{eQ3@kN?EM{Rb~8@d31-_gpKqSFi9l$Uk`kEcNdh{ogtB zACesW@n>t%Kb%R4PgotU1_75LU(Vjffgy8BNCv=PkVlb-V5ohiP!h~4CQ(OH7rf3J<@X0rfr>&b^aZ1$cHOp~0kVZYGX(+hZwLRe;uCiH zzpM}*|3RDDL68y<23S0hS3w0fWTO;^g{pOG5=!)UALJcA)F86-`@Uu@i|P)tIv+*g#Lxd{Kt;w8)Y>t3M{LHKH31b zSj<1o$a07R(n+8Yu1Fra(wFsaMfXY+SM+=q;D|1>zM%IH+yo5$12;jv8Qh(4V{wM#z zy*^d`2W;~{c2Mh^DgOE=;Qu}}{Yi~aFaE$b|9Y_jb-L?eQh9$hF0PFk_OH51_r&1I z*x2LwkoE{l%s>m2KujRNNX{1h5X?;{&b-0@D`?&GDfl^x#=l-P|DwiXSuqqtCgLs- z1VaVfYSSGpTFNwgR*DAY_@4{(l|W*t69UXCZoGm2kpUL?w@UM0FF4I)MW!{;)!XvY zoq_E9$P!4V8oQu*6LN&0Q{_Os?1CW?5KD9bX$-V$(*ITYMBoA#{>$zBj~5(?W{NwF z7g4Z0|DD3WZN3S9Hj()^y7OOttng~yh#<{u3q4Il*@3_N{iz6IW(da+_7VtgW{vbX7vr?K)?{~AO+`<`v`u(sNLD`&} z{brdD(Je`XWgGps`1(p9enm$DR6i0$t^bAu0+jtJBKU{(`9}l?ilY+(J!jvt-;yLB zfY$=lQ$&IQ=O}8?qUj(T7$2+IspF%GL z2>r47Z-49kvrMFVKO4vh{fh$n#|XrotdL$-@Z`))_4%jPlz-JH%QH}^LK>#zZ!ZRv zM?oUTxm49spD_S{;PWG_bDd`^hpQ(GY0HeVzK6t)7Wunj-BA1Isj^3 zo#d;t*j`_iAhhP^bUOW+&QuFP-d%9e$Uh>$H~-cU`0GPQf5+!0?%fx4PIp0|{tQ@o zkckX(NPJ8|h!K=HGaNs`dIJMsN$TwOe&I`>ZVe z@7KJ)9@H|Oof<91vFPjmYsvAE8t9V$dd2j;wfAd;#YC;mf&-Am%esGZWWj)BjBbJc zD|q^6sR{gfVf$-=U0KEvc#iib<|sfU8aN_l%p8iyEeR3m2<%raBq63a#}yz6JNmur z9}S>C5}z&_{~sL?uKk~Hbln_JzP=y3w;&j4G|wOPYzWvw57kxKmC>>q4`Nq({(dhz zir*?bBw6@yPd9Nrv_0jdjb8`iYa6F!6Ygr*3Kj$rsd@mDrN`_uKmaJQHnCYC)}2G^ zIk$xURR5VYzdHD&zM(VgAdPhc%3n3OT1X=g%ed&OUl`7)PzBb?R@OvIeR6RY~|Zb57$q8hxe+m}3~&6SVv z4Y(E1-T_i)Nd=?7B^3E#d-o?W_~}~YQ7O1z^&7IK&m%A zL`E;bx(}y=V=R|;3pg92^LJ8qzO!PO>Ri|YRr+lZ zrP6GB#fe2WpYRB<<4G2M^sc`k3$bo@o!=vjn#br?F_iTe(c2^9Z^!s%^u2xYdmk9g zhfI!+(0Y$dX293WQ9lcjE`iW0UI8Jv2kQ)5)$eFZN3@il7K)x8Eb><`$31nrg#FW& zRlG9OMtQorBCCFNoV@vv?nIt3$&c@Y03X&eX5V^h2iwqjff}~bd z^wq9G)ELY?Z55O@i&fUcHCSQgo-?&}v9sGWQmh2qoidvkc;Py-`by(>mnv=}nHn57 z7noJ`kjGT>(+oC8BANYW6=?mey4}GXn3PO>IEy#(4zxH3Q@H6%IJEyaST1bzG39rN zNG2rlY*xKQyC0@>M5198-bA&|#SWOKn>+dM4Rk%f!_+ltXkdIN%X~REXv+Hmhs$Gx zZ$QD!`5^X$^u@kp%Nsljz;DJ4(g!jWmA{fT;RT%f71oenAe1d>+M};2Na;;OzkajU zAVen(s?b_x(gpRVxM^;$48XWwVg%7z6QwSevsI^6Oi5j0uT;8-e*-!Sj-QS)gh!Bc<|X<*{Y|avS$4YGJV{x;CL!dgDb((hS!3Df2kRhAKT$LP6aI1xlg$UX?*Y`>){ zM`SHdHsS2|AMaJF%+Zk1&=-At*VSjdJUU3DNyphefBJChUA9%L@%>tyyxYEb4*~eX zguAz$+!xC=-)1$YdOh>w60JW3wG6`~jk2E@V$G%xwbS|4!#gQr9eN)0u93 zvNo!^bHB5zdv4nAJeF*>S?<|;8|Ndo%qmL;F{;P)8WLTSU!*D7Oe7U+XgZQ$-*$Ll ze;(ZS={qwUzbC_;bxCqf4~Xr0Y!8sKtR8rLQ7-)L25 zsXmWxD98kmBAs9LF@J#;IZk80i&)@AEHJ!}ujXnqU zA;R-i-Ok!TNu1x95^B@Gd|r#JbZ~0hnoq-GciO*2OE?^!j;Iw)4@*OsS_GD1$vT)5 zgD>s|>=CA4uP#7htv)q^l%e}7XbNS&0B%bfFbUiYVyN^6es13>VINyy%|8j+jr-BG zUF5Q1C({`aB;mE{bu{jm-{@hu;POE`9Cm%ZFY?kW`&;cHk9|NM(;p&iF1WFz?5HBp zckvkG-Dk~gaM?m#-aPZzJZ>5YT51mYN3Tts!C3sHTCglbfGl?DYQl5)!g0Ogw=y^w zN55^o9a7S%M!y)=o@u%j49p?sa#L_srJRDJCWbMiBu>bppFXwX$YF+XFNYJEDZcdV zG8&;?frU~HW9o<0Ck~&09r!z6(j)@6eaT&ZCCx8T(lSD=xU$hoCdvAY&N>DBweXKl z{Arg5Z7|o+vUGuANDf)DFybo(%m-gpHwH%LB#2(Kokq%wBHRs)6}p{X5Q1+V(H>)( z!|%S0#(WJ4LP{2phO8j1W3Ad$;-MhL2td(BKb)A(-HVz_N|G3VAUye)a#Dl~VB9GI z4dO!{Ct%6=63~%ELuex@3)Rw6c>XlZSEln80=PVjVUO5gB1Nkr9Y`x(p+hL3Fl2mh zEH|fV*E3=-lSm~vmX;k^-0eD8g>KVUQ~Hud1dU@_Zg%$@`nL^8ZmsCl1&d!Wi!c#d z2T$r;16IYI3lp&MVngO~M{EeTED}>MzHw0lmfpJq_gRMk3$u^7g z-xUkr?beA$(FkEh6|UYh!Ps%oc#5veGuyUa(-rLhm^lL@_l$m{uS} zp+LNZt=7f4&#`Zksf2OzOpu<9FyiaVIp(7?K<(`8$eG}MXXc=JrefeOc(Tf+K^{-ktNBafVkP`0x8Z5= ze?Ul1r{=>CpOY1NsK|%3PB4Hbn_~A>w7PCYKA#(x7gBMeku%%V)a5uL5 z7WKH>w-arbUy?l%_j4e};YFf$D4Yn!JA4hY5GE@ojF;{hE6!0l48v^Z+_j)9qz4N_`U+iwuOzl zMmjNQ0>1w5YVz?oIEv|dd5oAp%;MttHy~3l(l(lI>mIe=S)0 z&tCV2JN2&Q7rxXKPZ1AyOwNu}Hx_zc{|YD1#eniT@X!KI$eg$H3qg?FH@f!Rz#-&0EfHe-nfo&Y|09O)#1AW#(s!aMnk8@w zU(rB`MCmS7$K!_84DFYopyUy#afY^D{&yDp2a|71d20L0${D=XavB;ihg{YKRv8eE z8nhR>(g&+OfgrS_6dPeC8)v~g@&o=!Y43g7+)iU@`IBP5<|8TxqAl>oVQ+(5fzRQ=*|bx`Trz?K75!B>-HhiMfh552B7gCjlR zUoZ>@S<3ndK0A!G8dR>r2*7upsj9w(r=QRAI<)*ilG zv#_7nuC2UvNxNVl3kmW0iH+$I2~(oNgG#bNTuMm-AXaWabZoij{0O^-b~lbgeii>9 z>)`ZiRN4uid9S7$ZB_nA45IZo5TL9rCbU7o3DvWUOy_U%5_7-|t<@q_q3rX$I-vOA z4ZJfj$*J7h-yALXc04LfNj!QoE;iEjw=h%UVS^K$6iT)d&<6GADMjn^h{B~+FEdGul~kXi}lFPBFlJ2A9cO-E-E^lEFQ*DS}Wnw z5NC~wl}AVlOZ&0*$VN(c!7VC9!UY!QRl0k2d~X%?_Vnu=Ngm$v zX*N~^oEKU&nrT~9QTlzpkxtLrJY8I7;M5C;@A7CmvZ7806Mi}~>Z&+i*U2x0Tq5Fo ziJws%zt8(zUlI1*TCH-BjWJhZosLam)|*OB%wU!4$Y@~3=XVG@l1C4AhRPzy}1 z`3Ny9pGPyg#4&-`;niI(UrBZG%vmM3wT#b^G1|CirgH__K_ErC=_Zo=j$9L>BvEiP ze`+o{ZdW;I*a>&FmB*ZISDiE28;`-cxx9;hJ5jZnagYP~V8*|7N8K;S8tm->xkeDO zSMUde#P?E7ym{sqJFMil#a7tDA~tdA;ti&ECx{hc#NT?dM=S82Rq`&mbyK0mJp$@My!Hs;qzX*_VWHV zhwS8T%9_k%2xPEj?s3zY85ML+KFNvP7kw9YY7hH#&$24I{C&Ghrhkf3s^v%A)@tkRHnan(M$z5&F6Rgx!hS=sy{J16bpfeT#g4PrJa z)!^VUT^BHkm7;pWqB=CYC-+XH$^5c<-;l6D+B|=StTfX0WrhOr2CDs{4`Hvt%?Q|P zOe~Ctj~Ih9)y-CH^>PyK$7@h$5W7lOe(kDKSZ-?n(z2FTQ)`V-MGg75SA4JGxiT?{htk2x^{T5V z6bWe&a0mAU)N}0Xsf}uQqZSgUQzxk;;eW0shQRj9-Q#54m!7ZGl~(dmtS0qPA9DFx z8#Y4d@=$cf%Y7csTAp)(nevS!&Fc}P&eR={9;-4;CyGOwL*8VPbEc1sf%&|-!_PvU z#$c9m?f9ef>rd*ipG8Y<1bF1~-(-51;ay=_HjDFKgl+_u1BoS-c21jur;RbNJP)H0 z7C?HBDA&Z@2R(WYM)2oc;C_Vmz3eBoJ{mPB8#qt|3FZs&LxLHj1}hjQm^9U%poO2M>Qmp-yARB1ylpGHD{Qk3;k!_+uQPO4jxX4ljrC(t ziDDcT3#zwkTINlt(3bkU78+593^X7Tc)Xo>D4y{w;I8iT;Cy<+>OK69$7u$D<3ZHB zWF^mDgYmFY8M+}oD^IzVZISPE4$q>C!xQzu^UFf}(Ge?1V3LA#L0M@)+-A%>kIPCTSe0ZnKQeVw0mj31KK$fajh8pJQSvb>E7MS?id ztzk~lkVr*dKAUTu?kCkf9)D!4$V~L4-5D)`-JY``XN?VR0ds!8pu7r%_2$ntTv z*FwEGljK4_yMDHY$O~bh91;xzSz3(C_O9ouG zTpfU{d4?ZFFOA4w+nJVSwt-`#AJTyGFc=2WBj21!*f|GPU;QvVIl$h ztzVRJ`qq$q+>;ie(uIg+qNXfH9k&Z%iY_01t@#)~KgAo}B|g@I%%9C>-`m;%{~@7E zJ0yo$$7dImpK2Z0sb1~CqB?H2CyQ=bJ$Hq<-@-IbjitI8D2Ld-hmo9Dd3Q`jl|c~p z4Vko{``Aa1wjdLbFUcB?sncc@dEM26u5_bdX*nu+{S}|o(j5l8gb6>`{FFwnb8Y4~ z{Tzof{Pd|cT+y2k7|oe@X^6v=%2xOa(|{sOL8pu`liR;YbS)OxY}bOAuKM@)Fy$qJN;lh?aje^}>IweLhb;|Js9lK7JG=*dxb2Xj zj-uh;M0~Pw!W|O}hLAAP2c3FrQ8bI_Mz8T2lCu?~qsfvD);8Ft*_-FRvuZ3<=&fNN z`X|x9UxosH77WD-@654jEa!| zDb_`Nz$Fp#r5tuQD+Zzeh)m>I%{<{`KR3JtI_dWZBF0AEZnl5WpeQ31&pHU;g?KI) zYRpQL3fquR(~sFTH;D}H|MKvlx1EXxTr2++Vzgz=d-E6r9Vfc?6Mu-&FsJ=7#v`ux zrleISsN2^xkGIBx@7vIVaMO5ymkg?9{qUYSX^IDagO+z@c(LlB2_ z+=@2i4L7#h@e6L)pkk9Bm<8+|HTuCzzt>I6=Q)&4K#4=WuBoK9djQzIF213E?~;F9 z&59?6I0nB@LKS(${ZS84$+W z-+!f0eN{hpHx6 z*tHWwEHBrw;luly(T@+J9fWWW3+3TO=J8fFvCUXe0I@Dk%#r>kO2~Yn2elhHkRha3 zT2EcIJa@W59^?>~11XUWQFi=TlXnx?`4w!}=$(D52onJtoPOi%gN|QoNixCd+tk-S z;`Jipqpe3FS`%J}JSAiOx0a+JX9S(M%~zP0lf7UNYL^e*FX)JQW`I1@yh6-d3aZeH zS)ByaQQYUjv2c`FX4misY*) z3S%4Iek2~(a_uTYNhMjBsjF+%E27i8D!l?fm%nOb2rJsUXACG#@R`F3onXaF2K(Zb zBz1G#uIdB15}}I3ZE-Sk8a7%o#PB5YJy32 zYx4{63OF{m<#M;ylly8-9%t8SJCt|_-!0}N3_(P+p0IfawkrR5AxP{;`bx0-eK=AR z*Z7ezMc}}ULLYVwkLvi%0}mC~X0PLt$!pfDVn)>JGLXGRs*xkARL(DXrgny-Hi9SR<>y9j0!uh0|EQ?MjR5QM z>L&|ijFvWw;j6m_cduk`za-%El)i%Rnz}jS3e-CZ_>MMcTE5a~6+wAH7nR zW6~a-)4ZT_ah3SG(dzkZhgod4lPvuH!4Ot@>dvkNOFc21Acmuqcp z4wdTlx$KTd_mS(atjiZcroNuV?R%Gen8jq@J{`Bswq*(*`d2vrA#(mcJ1VWRXhgq!f=e&Zqd-l2HFx*M+65*$qz9&yNyfLyH zYi>Fpwzn!jQ6kC+5;ZeL);Zq0KL%qh8;l3SOYJ!jAd9u?n2pOMJh_(0zfSSb@$0 z#y{3mmPcbZSz_9W^+^w%bdM^B>D{`RPkK)?mYxuhO!_swhdKkb6|P`#A$Wj#@>V~e z4({0BD-lk=8)v#_9!+RV#Bo7ge+izba8GeeO5bKhYqYAz#xGCh$_GFg#o5x?Eb0N} zzPfjdF5=D#LS>_T$GmGx<+$<~fLQO}=I~DbEvv1sJ&n4b#~@|CD)WxG?_+C(A-xGT;;>dUx|saSEF z;m@;66d{T<`Je&%W?htv2&&aLWhhYF#DiFML1!37 z>V>k+>zHWKpQhhE7^0Sj$Rz!$W7b5O9O5kbUal{fWu4#8BvqA~Ty2RB+RT1BJ-USC z4Z);b85h`M%00ARC%vCBwNA1J6R&uAuBcRAfM-_gN`p7E^VubZJT2^Z>oxJrP)cvv;qz}!pH;2G>O{P8<#ooYSg zaMG=gw0#ol9E$-1#RYBa=%{6a+DlvYK8s2{#S1p(l+$-AHqhv&A`d&O@eu#uJ~+q}9yKNd`t3ms zPfJLdg*@t~3J?q6HH`iYw&R*|LlZ@~cq=q&XL=(=jKJ$*f4ydbFMTMtc}jXT;-vQR zhiND80(~(ZzlVOs49?Vgngn%*{2aQTrVRO-*SXUe%Vf*oPnBPyP66n`I!=_{|Gh;>X5%Ny* z{ao5ak@EH<*=pzs9CuY3sZNr$K!{0^XU-qB+4?3{Q=cIdiWt^)Ro?ML7^& z@tVSW%@gNu0IhBGnvz|M5P!SgRxKLG!av>oHo;%pn*^|3qSsxWdD*|)O&73x$?J2$O=@XB^YguS+tCM=@K+>fT_i+Jer>ft|X z13t-{b>&_hLAFuhW)pW~&$?XQxz$J&I_$EVUMUd;e@(lKR(rh;Y%4iw|1}R&u@+A^ zudlbZq;6OD!r@J@y$!kPJ^7htC0xHXXv-|i6O-)+Tc^^N(W*~Xv&J?p2rsX{#uFh% z-%VE})=U2AbdZWjBF88E9&m)HH*9Z^|WqPvJi<)Aex?q1XpE_qROeBhL=h+=UKjTkoahDuckdc%b)u zGQ6k!FU(sDyF6|E!1hUc2!5Qihy+EUHY>utfZHl0-{~ z<6=wn+LJ)ecE!+1O6a*q;9w6GI+tdjyUo#<*0A}T!CBUtgJ^5^fz651Hj;JGa0CJM z>|x3zebv!^RWJzxQdjJ3PN?SmMMm!q+EgLYH-wwly}V#}nDEOwpe3>fKAQCtRybpm zy?3UbG9xl#MOD|eMN(ePo`A-^!opl)T|2(->4Y_w3eAYxBpLWA^#< z(eH7OKGdJ9*Y_+WmLPm&ih-N>FFok#5o{bxUaRVcSi47=RLLjoeG8Y6`VMQu+p7-U zB~`!)rx!KY&i7c2zN(bpoimgY#ry5VT&v%K7T5M3RJB#(hs$B>ggoSQ3~$G9T&~EN zF?{#@Io>MB{LJSq>jr#N7sHehqzQMnWWE0ff;7Mj`KEvdiy~h0lGW!e^HY+Oo#WdQ z`2y6XpqRe?tv?9VZ?C}xso@iZ3^~E-PQZc1YSG3Brd88wIx7{7 z&e!~`230@Qu4%C=Pg`oP`d{csrM>Ky5d8+SttBc$gzE3Lg#7eV&Pzq*rw)^#)`z?xYvoz`Q_0#cM%AGS(LrM3PYd?h$9WS!SDr zE&%%0T6S=wH>@S7DUB1@U@o)DpCf#y4pjjj_#6Rm5*7{=7miw;_-h<@gp&itGTET; z`c$=v3_pL&5%2Pom3*sPi37LI=frdE*WGJ*(JJOa*1*vr>F;i>#bA=X0=F{QP*zuX zsi%jl5o7}oN|0okTXd-DlPi6l>)pMFyqrvFFC{l-ftgI9cbwpak!Vh*j+BR}*bDLY8+d z&ia-tS|3OV#B!b5pv`A!m)oKd0^V8Y5_pu}@#TMRI?CYp*>=Jy@_*z#xSUHhALqdC z)}=)c`3?0gB?TFEHONL{L&F-YhA71LVah0-nE7yhLa1o?FbCErgs5h$=ln^?2zBpv zJY(zH)@&6hf)5-!ZpnX=h?n99eu2BG=N@}~zAQ3)OI|{)0mK=-YWu0~8Qt!K<@kFZRp33{)?F{Wgd3n{ zV|Sjo-adHiOfim3gNBoH=kXWfTM?7%yvwYs-GL9-8U-f5nB2huqz&FwUqSZyx%%Wj zmMRL2afRBkn=f2JMCqQyb*hZ9{Ls1m*#$Y+ZU_@xwC24Go30ZTC|$YB1xM)Y3nnK2 z20Lf`N%oW@_w3r+DOa%arL)#KhPR59jUI^z!LL}VQ+Av=( zZCu8w5%n}NTxu@t-n=W*?3Iqk+bW^v-p}M-J5N;T^zfOyyAJ5vhBo%NS#+w~HDKS1 zE~m-RrkAZDRo9Qub)_R+@k-!}>%awcR%UmWdy*S4@U$K|(_O|uM!WMB@hP7?MK@P; z24l-uRd=&w^VB38?s4m9=HEl#iUTCdK5MJUouuxgy$Q_1SG-k1Dhi(~U0p!Zr8_{P z?g-g-(WQH7Uon%uq0B37E~%jm#19TE`f~KTbV@iE_nfni?c#%>trC83sAuyiBnNiy zM{(Gl7b#QDnt{SBdwsH(cXiUPmK?|aEJSh5@bYxnyL!DxiMQ%f2Ego;rA4u@4^CUY zvAQo2O0f>kl%>eG`(j>PSZ9dANYeV$N%;LzSPWl2tCrB3lZ}p-fN}@V%wD(zSL9X9 zvaw!**IqDYssG+DP{f0wo+$7$0z8Mh`kHL4bi$$Y+^*oMzm=(}Zq~?RhuG!=i5M58 zayc=cDQu?T;oCLCj68`I>jBu=XV4^`*9aWyUOV-qfLLVFMzwFFRo%(722KMK_$ zp`UplFzzib`lTSJAB>ar2Gq87vZWi7dgRsGsaDvmi1I_6=Bru94n+*~8SZAiYm+Vy zgV~~gnQo#f?w;+mqhbmPky$=3$ysL!uf^da`F&9$y-Y7$#=0r!xTz27+t2A|$NGAl z#iwDbxoQoQrv-)i7wG%qyzqMism=703W+RgHIF0&A%u!qwTD~6k=+tZ!#LoG*`l;k zW8mSECVzRWUDz4R_A;u6(txNOaCW%|u-w&>Q+XWbSWrMz zTy#HouG<=suQ5-I{SK_;`6)?7y+B1G^S2&V1JCZyB3jxTd1WF@=jKZBV@d4DYXnB3 zmwiGqqiTBIsFM*bNDsG?xSl6vB7?ZYcYi9N=5ahEjx~x}Pk#r_wK5`NZ$$3^MOtv$ z`EuG7_@IyN2}-8gV`Ou4dI01B8L|b1KuAE34}*2ol45sR z@|J(}wssTi%yXQ*qZ)&n1$_Zzu)$M5`uaifwH#^1OT3zsy0p#Nj(DiYve!&}CZl~n zbIeAakrf8Y~ zJ#1ky#l6KimG_JiPJZKqNfUGiHZom9K9(gL?fkT2_Hed#8CM|0TFVQjvzlgkH!r|# zFN2!x*#@7rZZ23dM7exYN=a&k2Os0ZO!y2Dq{(ujTB946?kC8W{NpMKo#cC{biLb4 zC!=GCPwq9}&*hP%$ZpW@S%;sDot4)@{+Y#f-Wf37#rU76MW9j9f82su2m@iodk#!g1^l@b|v&FxN< zWNbgA^yyfvn$rRx1}xl_K5n>sJ)!!ITAYwAg@25DS|Cl^2~i4+3{qQETm?7#g@#cB z6Z^!Tn2pp&%j5>aN;@=$UGsa8^PBifa4UFwYXsarkdnmqD4lKrfOzCyx_Z6X4IJSJ zp9(bZWQ;X~XIL%d^p~j6do!)@`r%4WW^x|P&xLKA^WzbXcT10=0{hgMbHPW+@wkup zk4w0#W$OcX9)7fq7pB-CZ?nrt%Ab`VKx_IsKMH^%>cM|s$ifK54-pZj5k;V2ymgsH zi{$pONOa0|;h=Z~`IU3*ksrx7cXyLIS6uFdE6sm^m)Jp{F=vwpUhw_Sq8SSP?v82<_P7~_vBn5H^;yebf`?a6H8>)`(ty>-^T-vp zQ=g`0g;tGmw0u~NH_&^u+<;GeHVb#cHj#d zo6G{1WPW)bd*V&Ksu$)s#>2oT;Xqf28)VH@y)kCIR{PnMy$e=BI&S0K>Ese;-Pp{+ z8~WpIrN!-+jIIv@(QX`<-VlQ-K$SlNZph$33T!-BR#{rO7 zVWgK`i@+m>R|lurqwn=+C9YbqEBbH+%ynP0u~W4615GQ3VsFldt4^@XFEn<;A9O~z zA=zx^3)yz~`e6krJ^ZU44m(tBA8>rbh|>iVNF$l->{WKrdVxf^!Z z>w&PtAM*48&cfaX;n~pG68^${+0in`e}X_zs5l28s#cyGcYd|d9&Mbjo(5FV;P1q= zKls9oL@z^bpCNnb-N|n^!C(9K{Lb@u<1_99%3qS41rHgvP?c`lw4rB9KngdW z4VG}jP{iiIPX84yfkv`4=A-$p6t-Y{X<44|NRi$=0Q~Ov0e{}sZ|tH!O5;iXYNYl? zv+J3mqkVHMe!N=MXUtVQ|87$&ra?`@Xc5gl%jW!o;ip%f`j*}l%;e0(_R|~*&U94V zfP56@BFr!PQZ-^$QVE&Xgco5GJ@Ki*YW@m`J{8IUA6R;wnOKJ;dWSuOG^5$atSIjD z6HJR+1fu`C;b~X=w>7K^0ff_6iql{|t-eykruFD`K26W%F{n{_e6@GM@9s*^W&*tNL3j%oS>=Aj4Vy|J0Thc_4+nc^kplYBSmTnJbH$tN(`0?0^66x>GZv+6 zDZt0fOnlDolYoyv_mGi9dQQ_u;`u}kr`ay<=KKa;jW7-7miouQsvr1nn| zP~6{gUvOL`D}YFo(az*OtHV(b{Z#u@BNV7B!hZRo&>2~~>#FUZ2WNmd0vh~$OH{d8 z856d2`DDy$bi1usZknb!A?7NJItR|!*)WmdVg%C6Q`L(6*ond1y%H!ep%Uh<>|3tG zIVOHi5>UJCl+tBJHWF3H^LZ>RXK<&4Y`sx5V$7MGq1g$DYtc9>pr|Fnz*9~_|TR_tMX2uN^EXG)*?XV&4DRR`Z z9?KjQwuri@w}5R8w6Hq%k_$v*izydxczLg_e0+wVJ8i@v2*IuOe&5KuBnFd1TZ>Px zd~gN(kq76OXM>VcKM(&q={PwT6pr~OWw=Bc^>TF+EjY{r>V!#LK>7utnDX0_%UXEI zl3oKEhztnt*p+mIg*BT0QtUux6ZL#Te1U_yMSIZ0_=A!1Aygj?Mh1lP+KJ5UVu7hG z=8G}FD+8$;0%3`sz7%5_z7PsC=upY@8su$Gm}4VE1?-**lj!5r2jFUD-1%WGLo!)f z{%T1xEw*Kpn?WwqWnUqq6!9>jAW~Q7T>*`Y)I(&ebJqR|$MqoAM|AC_dAsAAG6Mn6 zVK^=Nb$=*)PX(9KHD=nT>>(_9)3&kytdf@9h9wHmi&7~-liAJ|lorm`e7T~5wVuvQ zB6Hy!2@P+qbUL}!?EqAb1KkOG;^$WE#DD*iqX(bx^U;f#3(os%N+!W|yiV!R~(f!?VzFG)R8xK@L$csZ5ntUT9!~EDvrV^)~F=?D4OQWl@RT6iLl$p9pmM}zV zU14?E@vXGJZ&cR7-CgYv9?eHpKj1<+Gs4ptlESdq^hmuWYdMst^F&rmv)^r+TI{!7 zIQFvPi=*i>!=I2}nECoVDSsD`e7#w$TsUgQbD;yR)?HTBdn3eQU1cIAFhSfzm)N-z zQAy|-?^VYIRh4&k;7~&ivcic_ioIv6!HZZxu+Rw>*+IJXuVzF)59RoHEfdLi+Yn*@ zToZ;fII4NiP3hQ4DRU8@2z|%i;wbal%(iwnWPmr+!cnr6hl*wi=KamDh$7O4m4VJc zqQ>Kn=f$|pOUKbtJ~tw@n}R_4 zbS~4zEEPjtZzQmHIEr)mF~W$}jd=*0kg#n_9c^Sf5c%HcK!n#7R8~KD@yy^l>`A_Z>~}7Mo}D zW`et;1KK;`y%eIvSGOq^`u z#WQ?Zw9v9NQ|9cF82>!4*KQkV#Wu{%#W0n%_fzzC;u^W#bAc+AnD3+AGzA@9fGw`0 zmd#&(&}zPn%Vm>yJ=0^D1!+rNkoSu4plIcn>jIU;H~Z;ytpGE~VZ@#B2YftGB9ZW9 zkkWw5ftc6I$($p&%0 zj|k49_^?{6!I)1)L0i|V)7c4`Cu5aGg_wa0{bGe|?z^b8Hk@7dF-@5o$Ml}t5qJ{- z)cU#UXZn?0$XrH|Q`46`_ulI~X1qxz?iCzNR|yOPKG2lXvCpUHw?Le# z%wOVTg?xDN?51$hnUxzLBSdzGq3l}kq$~V78>%wY0K?Ilp*@|vIg;~|lQN0&1h2Q7OjdOnr&dw8y|Wxba}ig!SfW4w8iW5gkO@# zx_G-yX=8^#{>*F=98~zno&7AMKLBskN@1Wz8n#jhSvpo7@N>~%9g?j^F8jtW9XN%o ziBUL>Vm6r>ctq-D0Orb)DVKGI7zdaC@x=O*6+vz7U~5$VzH}oD#ja>h@xc6qg+?Na znN}84u5h*H;6A*)RI=%kjGtBFMaKmcdt*Yitmpor!Q5emJjSfLgHdrZ)|=INHQH7} zR(jU|kGXGXVCUqB0dk=YsT8l--lxb)ReWeh$OwKCY{21|ZsvOCwKdgo;X08&f$N+N#hbE3P)t@37Chtt>Re>1Bu=qgX-ciH(i`u1Hl!^N z?}qpFEFU>&_4;u$)eSlYUE}aLI-_BaZA5^8VmhyKJrHx=M#_H$FdlB+#NHoCZR8aNIrIrUjTq1OjZq4st3 zB)Ci&Y?s39pZblEjt{f=;@PISVpbryNR6E>+~IbHe$a_#JGh9wo7|gsyCK~QToV*PEjyyx*os6Zzv!8$|>>eE66ZWM(&YnCGzngcsA z$NEx>yFDB!y39}muAl0S78g*cM{86Oyc|}11+@K4C@G9y0!k5J`73q(8v->x}yOckgQm#4hayi_az>Hn#|UFrr3h`?iqeg3B%Qj({}TW%!Y@P=5WgBiNl?>A}+?Q`>#+NH?>$ za9OMeAFgYqozDvyqCHV|Xq7|Mo29mg7$V=R%XjpccWk=Ob*J|EZeZzcpVyn2M%#B_ zXQVY?^Q6?ks{1GFyK^3}u!G`*KUSZzM48c%@hLlCNf{W5ooi{O1p#Vhkz0GPoLv}$Av)5dMe;XE}a#;$; zDx%Luu{!ruD}|F4@#mf6BcI0EO()QFz%Ld56A~K?7Hw30At^@2HNIqB;7a_u;rd?1_+O6`Iq7cUAPz zO4>8yXCJ`dO`4K6?wk*_Z$Yh#9OU?5;n|7r^!XjmW z^;B8EqQlc>OC#|p+gjQ8Ch!!nVWF&*2e{m;VyvH#yU`T}bj|dN{>XzwU-3;S*%YU8 zvtfrsht^JRMq?Nkcc?gL!ALwJe^kgRd}~h-z7CC2QCQn+;wS>6bFAngP$4ly{4K9o zm3p*G()zu(eKx4#1eTYxeiBd)L2d0?(di<7A>nX5d+>3~P%w?ow>j~PcjzdFza-g< z(3l?Nx7pzWq;S08MOpx_my^JP(~{z=QM)C&9yQNzX|BTGeE@-ObTnn{U7pPaYqCbm zFfO=DhBQ*p=L!z;zt_afaF`B485ag38|dDA9d-Hm&={1cf@!8Gu;AnFq{j!rL+9|l^zh<76DA6q5i65vx|#TG{|ve(;3NhrWI~E3+{m3Meit>bwsarDffR1}Rn>MEr+=ZRAqa;)9B}lXtA3L@+~3 z(L+wbuiQmIl7Y!(AGXiW`$i zif59qJ2!Y*GPrd>aRESEldme1F&D@^N}gYns>s6q74z>82*%&|jlXzUe?v_E-vkdb zf_cV)KO6rJ0=)hegXnK6))TsHp~1g@`R@xLLSNW5mjBMY`ogXO0O0vcpuj4i+MxQ4 zFH1Y&Z1Ehu70jv^(!ZRjmoh3sy)E1IA| z@+Q?kbmMs(x|!(!m+zHa%^adkNYQ#s@_Sp;9xmu`q0r(qU21mqoeGl~hfO25u>Mk)7-NALI`-2~x^{oxu3v6BupZmT5cj&7VPQM}rL-&q`rh%1?9WC!vKG=3rOK z;Qg!(vqOIvxNl{!x8!Yme$T$LB9Z>4z;pjW_1vnR`owOl5y@E!z%)@%8k%S{6Gv)Sc6Nc4HY*A10bQMbYVVETk~uNrHo2B2#4roh@~^U124G!6yN8z z1?|f_=W7N{nE1DJz`-`5Ht#}J|-yRL6E96yNR zRGPlQ;?j|H1VG9O2Uf@5i(%8Re3WbQ0QeNxPeIhZE$2qsKtxj6`h=w>IX1bn(31_Z ztPyKA+x}f2;KyIaH2sSTCiZ0s5CH0@4CPD^(QPT|1VBX@JH$5XDU7k{j5H-=it(#m zpRKHvCSaSR(1IvC}-RujM`*%YT=Lk$1r zJ!gThiq!rBhy7g<8m!S+%27YrF3(ksTeE&4&^WcXiH)Oa|cq0z%rc53+m!5%5?sLpqgJrGY0%rptJ^+X^fRp$l4?vafe0&jX zCneKO0QH}Z1N!q7?2EOU}z_%1)P9AJUx4Dxgo7)yd0Ez+-BX@p%j zkz-=e;h*~Q{_>*4Ul_7~ONE=h$>bVl76Yj+N1X)&-gZ%VLMs_u#X^O$@mJeCA<=dK z-rh*|0uTxf^xwX;`Ip`JcD`cC`~@TXw@!oXcv~@fd2^vr*V43f;P|x?zBB0JaU7tcvOO!9{*RV{$2EI;r{^Z^!}!j z{iBrAo1)+`-NM3&;%^=-$GMgF8&l)&iu*j*GQ2qlg`!}iUUj_bM@@oP3t4RRezj0;%fl%ZPhyct! zATxm&^f=>N0|3mH_w5w{kTg|Q$1BHbWc)u>H2jyRp8q#=+WFepFHgPxPjvd9c*^i^ zrFQ|qWv#*RDYR@<{vzo_~-lA;r*{}OtOO% zllY&nU+Xa(|Mt~itk(ZPtpCJUb6+(`{6%5?Ur_6-Eni*L7nAjWpw|D}S6{u4u+~3U zsqUXMeK1qiRv3McCL=(YP=_{oUG0~4o%Y&_8fwj#T|G1X(~$#o%5oj-c@`M;KHt*}_pDUTFAEfQ=8`?JGW(=dC;`OC1S*fBK;z@?n&7KzMw;kDaDSh>eU z;RM?u7>T^9tcA)S>kfI^3I2`CS!Z^;VY4m8>Wm$5l}M$`B#*7{$)ywFSr)&KO@k@Kxh}7vr)8jp6PPp_ zSn(1S0on1_h;@yfXZ@ySaQb2qeJFR$gW~H?5R12LLbkaFC@I1$*foQP%*orgwXZo= z_TsYPM4p()nj-EC8^Dg{ooIu~wRyO`K0Dhj7Y`MtYz?}XG$V9y__$3oz^Z8(kDh7n z_Q`JggE{(xu^p2p8uQ#vd3Z?O=Kwk>Uz8p@i!SAD&20@EacZhnl!8J z(X;HTlFHMFQl;_GZ^xibO{zjudwJW<^P-l^Xu*Tvxr+i8YWVYJRvDs+^V1$j8T|d+ z^@vbtZ6=t7wQy-qgjP`a~=} z<>Wh?QMr8`amYX3i$JVWJ503NWwos}$t+L{xHPq*(G;1ZIqw5W7G1Zpa@G(y(HU$- z$Zf%M8Uvd{6ixk}ZT);2M|8GX>E<93p%9X4exirl_WAN#1sWCLjK11B;!<~=2| zPGC?V>3{)GP63f}c{+;-ijLUO*5ZE0X>G5L-4|fW4HuIQNpXoiJzFGP!68dM+Cai( z`0n$C7qzDnnTG`r=Yo#nxO!H6-1qR`L+O&}COU-Hut|0{;BuwMMZ~jkvTWH4E(QZq zm%Sf1Xtv*vCu_eG67zu;lBr)TV$zzk%PfjETcbnn%h$$ zL83vZQR*Tk7l5+!4Sin)&hip^DI>O3*jDen$h}XfOrUGG2K%I_12(hq?5+{BaoH?MV zEEr2f)205X5K;OqwSE>44lM^GtHP3>n$MWG$otTc%m%FT2l+eXOP^76P8bsdQHzf` z-auTdh~+mgT`XRZ6-`Ev9-Qf+m;9oU<(JV-5S@R_T+9AaCp;oVxyQtY`m&_Tr1$M8N%LPtYd$o!0mejs-u6G=8|iLo zcp%G}btj1L*yy2Yk>UQ(#9SB&Lh>au#A};b#J-w@Dl*4sP>XhiLCvmM&UIMS1fIk9 zK^cLpP&J_2v1Y-6e6~+rlFReoophA!kONhjOW`E5G(D=1xt%Q=N-~ z!%*wJ`vuVYtd7F+lx=}Ev=zp`T5Pch6wTgePuUO2vm6klEZ<4EAmrK0i4o;oRe2J5 zJarTt8_uN%GHC4MCdixg7PAy@oV|Ij8pJ;r1~*8uf_60$`7SCnD}VQs7)?MV8Y}LS zY?VvS!_$IwTAk1H5}Hl2B2!Qz#<6Lek+ZiY7^Cm@sC6A-nmEP|H>DB}uC6$F`+hvX zU8>@~D4FTT+Q5tJ8bdQDAzl1)S1mS3kTMn3hIav8e&!4&j_xFeFUMH5?mayph3cgI zotRJ4-I=LvSE}OG7vC;lf3Vr_=~kzeQsVTrf!DlHWep!%!YW_k2%m>~ktFye*|S~G zO^_3a;zt3FU^F&g8kT}mpd5k!{#5|m-4gNeZwT5mux^A%G=tQ4T`LmFc})y1*iiOr z;oOj@KRyx^5lAvfcsuzo5}UE*YX&f}XE84LPv3h~|WL2<*OKT{T2nXI|FpO67;OLg5gOLvGqJA*t1f;DE0uIHEq|T3AOOc)qm< zP%O`laNPHomTm?0KN86X;e5R|IeXSh?Z8bU)^S~t%qXXcQKR@4X1NAa`xSHg^F}Rx zY)AVt^r04uZjHFIQ(+}2NV`})G0)skZ*g%b+IlUIaG7Z3>nW#NJCVH|l}}OXjZ{e^ zmNEKO3FM2EqC3Zo^+t!YqT_#jmiT=qdR61UXZtyGd##PU3uDzE22R$?(Xl>j`Wr^w z|FyCD6!!DErb>rx+DjZ);R3a#dH$`Q;h3?C38P{%PK9Mc2&$Hw~e%1gY@}v zLXgNcuT!!e)ih!*&als|hg*dYqrHyQK2EN0c4PTkYQ3~%4M7Rn;W|&q=O}mBOCk-l zxpP#X1WT?{LWgga><9tP)YH^$@>f(xl9+29P@{F}gJqV1oNa|%=Z-<3m(1#L8wdN@ zM4|(eqMH3Lxs4so9$4c0E&pIO@?W6n^&);}bZk?WJl_k-eth3d&g!2o$Y?x9ya}W% z0j>AlH6vQkUb{a;Tg#682=VWDvWJV0qSIQX$NV8;`LZLLk=&l~>QFmwV5 zAK_(PgISJ+0j%qCIP&Jus_}PTd9|>VyTY!{SAYDzLAB!7NkvdjZWtzPF~45WtKdTu zl@mmt4=p9X35-XR(TJ%>7%yH5COFPL2{#-)#I?gwP#~Y!U=oUx_VpMz$NAAg zm7H**z^pWHgmN5>!;?ws72GPp5u6E49hEwVkA9K#2UhvLiUu>I*>Mv=56mEsr~Z+M za_f|j3TSf3W`516+M{Rzs`obxcFF5{eOG9FZ;oE9c8^`QOe;H|VWlj=Az!c+s1YVy zW)PSDbzzKs;)$_h&|NJ>%E9w1SUK~3id4Hz3%+B2g-QZ?9#$#m?Hv(0C^};S5=yNC z?6(Z!SwvYyH5?X9PwGd4skov8gxsvyI67mxJ(XQZK1789xw3+)D51u9lhAyE_)9MS5 z7D66mv!8E!2^ES^1Koj6WL>TPPaDC$XY-+vvIY@xmwliY!uRWuzoli7l7?0N=!HJb z5b}|B0*Z{=h5k$i+TA8!VOCABiDJg0azWhXd6TWm#?zR}JP7X4m8clpV7z0ZvGZNG z<4^xC(@uCDz|&%C}J7X z?pXY?PmbYrQsr%zzFc>XPG)d*-k{NBXjHNddf-I#NF2W2k>Q%2#TvUpak3E}(~JNU z8Ggz`13RCpu?02O)xmJBMK`f`*W@p2k-FMOMoe3INZVCuEb}`5GqAA8S?m3^QQ7&Z zTqhl`lIFIKHGIi>gKS{M#DqCi*cJ5SllICC`x7?*NTZTn7!f2w4xb|3)XU1a4`$cn zye>y0@>^`~wkpXD&yecU*&uJ5n$1+jv+*HGJG`UlQxICL;}Q5w#dqkNsd_dJ`mEPb z|C+DMJ0iD+=l04yfqjjcZQRG*9ZW;<+XeXdyvov+ww&|miSG|KL#C}clcLY`&3ty*M2Qq{tO0FTwM!YA=ddGA>Mut>NE9mDSrXv?#KM*0`D;-v0Y;h=|Z@!4^8?U zGSLnh%c`*hROndUtEfr%OqQ4ul{10{bW6c3jA{#&?#X{Lgz4L^B5U6KlxMlq0%ywZ zd;K!Y%KZPi%NRDiCcM!dK2GospK7uCZIEyqy#Q#3Y1zvwqW= zj9u3dp@W-u9v0;UNCi;mxZtxjLw)Yn*7Wdw&i_Ep;N{ z?Ko(GxSo07y~Gk0u|i4=Ng~NI!rHH2_ueo*>?>HK$IL+r{90vIGE5X3q}tLl7UT?j zNufJ-`*o;pRbNT;gTmE1lUu{gHEBAdl9~G9ZVk={H(iy&^X~3Qd_q?{{7_cSi;C@mvlj77UxVGLoIEBvUMaq34SE{P+BdIgh<#+lXx{$u z2+{fLjB@)yrq!5oRDgpw8y~-5em^=Wv)`6cA@HjSWPN8a*GWKGkUg(oKp{3|V2hYe|VH*N}NM zB}%j7apQu5e{w0^+zP_FDflPSiM^jO?=T;1k%-%wW>YLv;u}Y-;dI!h5pMg1b+}K1 zIt99vl51*|gh%EFRl;}u!Sp_B z+OnT!j-uhM$JzKb9j@qe9oADS_}7VO!V?*j=Q8$}Q!-P#s}R3BQ0Ey_T|BL~NbgIh zZuTWKhNh>p9*r^hMciNH)I57q-X;;IABMhHpod4$o=uh|4?&r8#S$_+O%wN+Q$2` zV&(ANE8U?o+`n>;7uPfNjaf^{gk3F>3@QJcR`1CcKyA9Ja$3DCIFHwGJF_1fq zqaoGdqI}um6*v1^!=c{VUw^<0gY(lcX=P1Q?b6*VVkmU-j7;Y2qk&yDfRjE=W4~@k zw(_|Gw@NTbQK04YQrU7 zCkmC@TduPk@_%Z|uoo&{9bOU3kz6#W15Fm}mqFud-1L2Xc;%%nz`(K-FTx=+%D&ka z}o{&0o<*k7MR)6R8m2mL>^{BKO#CW%cZ6QaEmLoSUR)^m|M5)N$oBuv4 zhN#{L#58aCn|0tZVF+kXug;y^b82q>U==U7Eu}5^dpqi>>?0=xhY~13wpV@%8?=1@ zvh)%3gcdLwsPmrC*Lb>E(QcVN)k9zdc}-{|xqUKQ>)zqpDH%d@ABLUpAfJAgvYwhW zaz{v};XRE*kkW$!6n4dg6KlWC?UnR14BO3`!cEHT`>G198t}{bD1cz$0set3E}T0v zgP=~!(-1Q~guIf>wO@%&97U!OMW-2Jr1NPdlP3C2y;Q$1D|)%tsrq7m>FMM#aowa4 zPxby5Me!q&9k50QBf!U+0x<_BJ~ag?h=t&-CuPRDEKYYGCcyEF#%O%lqSD!y1{n?U z`E6)AZMRvYNl(HsZdXb6?ypcMTCo2ZU>(Z|#jHmD02c6nUJppiZz*a`aMyq{*)N^F z2^ueXflrhtdVN+fh)*w0QfJK3ol zbzc2pEX0_VT6FHbG|)6C-;X#|*=Spf+9k>!RnzGjkrmfY{-xOl*A&QuW z4Dxm?3(k#+vDN;$ys0sD-uJ6_ag-<}2EHO4^e~FS463MbjdnI(TC(AX5{K<$C^w2i zE$l5SAfI1mfpoCbl#6rN$|z(_;bfAM5^v|7P9@mPxq>%e`gyzT(m1=dfA~s{OEM_& zZZ&gz?9Zg{RVL$*&@c8sIwkd&iZE0fV&HQfW=5l_hD15y;v!5&#-!2uZXY`W)o2#7 z?#8Sms6(1eDdB)yhp~(@JD7SCN5JL>RQ=;(>eR%p-$p$kKr`T0#cVd5UyGank*n95 zl0P{|11Yeo7Jc`lU394;JGWqdf8ma|F|6ES?O*=RS24!p}Iv%nSTcm`o z7E~*Qp3+uB=!I4eOCGU!=gHs_jv3a2Pb#ryKMX8_7)!lO1};{ zJVqqtY4`0srF$q9$k=LMl2M`PgcsK7Ew;cRHvZ_Cs_Hi|mWbvF!X*#Jfo90&Z6?g6 zNr7$Pk8fyhbtU`i91rKtInzDXx7ay4@7!9sNrF8+}34{v2T_Wfr-uw0(%_U$u-X|fKt z&w_%%o#vE`bsg`04u{Rp2YQr`-EC>9#9xCPg9x*{(|)&#r7}Tc*ER*mf`&MLM!~mC z-sC?|logN`Dt_4YiN(PjmQocrNAy2Z0*xHrR126b>$55I*OnZwOQ zaf~yJoO#vKP-G>tx%NN7Ojh+AL#0In22?ur22Tp9bAfWAUjv@-w`he5s z5Y7ELC0^_Q|Fw6P!Er2Gf^IRhEVfuJSfJAaivE?8*X0QyT%rQEXk0`7#d^uc$qaZS6S^fFq#VW+k)$??pWx4S%PH@z>p&o? zcsu#VB6luG!OWmgNCL4N1WBiFvCT|#9fWP>D6mQbFPv(Wkp(5B>Twq`jtL9s^4F>Z zW#R<5ef5$G>JCL+#%Wni45+Sf5teJ7o_fm_H!51)hx=Ic1lZm4p}j8Hv2WP?UYe=s zA#TwU+SrAShn0DjI5mruRQYSw+ONn=_oAoruQPZ*dS}3X@^r|H4Rt-cb@ocL*`;`!pQvL}nhym%GSY18Z3-czw{?+#=0vtd}P*yBFe%3AZ4!5`cIW%hB<-QNyr z-nxMX46v1tHV`{9vq?SOr>uE6ljkHe**pTqDysr8^gKKaxVy=Q39N(k_xUc3JAwj= zg>#mVNQxv^CGlVspeHfxeUeJ6RxL|iqHcl%Q{2)IK4YKjqczt!I=JWjye}jIgUtzj zi~9m(DZD2nk@X3dbKTp$!!jIPtx>2&SA<@Kwn-1Xg?WiJS^aQ+EkvCHNCU(v7%ZXA0z~SnbXO)&dm9 z<*694{^;mHGvWm6LeZR^_+vIcv|nX2rW3DtWPZoP3y6k+r~qsnn7R53kXQXy zKjJA3)r@9wOe!UO&mNx-=fZ+lr^zGzw{nwc= zdZ)!s&X#o*a~07nL~YdN)ta@(8!PODeiIeWsG%p zWOu?LWHFpY$y;>^`EC?lgWDvO>aWQ)!W7d8M6iYMzo!?p4neKo;31!BM80|_v}{({ z`?hd-L$gM0%pTID)q6Xoy0>L-BHDJ>Rn|kc1i>(=@>{uD-=;ys`i1(#1V2#ai>n2k zvFQ2b0r~8?%qq+$!Z7<8_;mDbW6GcwxS%EQS(|0c;6uWOhrRWM!sFdh{5uOR{@Y!_2h(6f_o`Uu2sU4Bh8&BD4vh3@H%guiu zT@q|Ed5~_JqM}|%jQ5mjHJFNA>GuhLR*k9G=@1B$nA>0{82==2vJhV{$Z_3GN$EOt-1_0o@WA!i+!|_s-p?4t z#bJpFv=;E4*W5A5hx;7Ia&Y7xBXo8xx%lEvI>@u<^K;l?%WyOw~`Eh;eFl&EDUAqCMVODgC5AVuD|yWpNg z`lh#&97zMSU$;c1Fe#S>!z!dPQy^WBuDL$b9!=#d;m~?C45`E71X)0zvP{NF1f6E0 zt{kT$FY9x)?<(hE2bggVluD6dHG5`#@X-|KQRqFt3WuszO_F5na?KeR+Rl{mik9-eS~NxvEy zKOZlDW;Su-BFDKyM0efs@GJ@8qibGwc+qgo>WWOW2pwfs4XDrx)=IxhYB|x#>HcK& ztpG{HbQ1mpNRI&SV&F4jbCo3@Q>~Oz%cxe6SQ)E$J$mD*Y9<6JeOp}dcF%oDplIA6 z$dKL~rFRkZtMTARCOwWCB3@IjOtoq%~pa$HG6JC}y#S=q<4I#WVH-dXgyE&Eur89}LurXcT0q}-I*Z(zdF$uv>KCFViP|wVlKIe|GLCu6LnvbAaEjW-joLMGI1Yz$krKC=SvmFhRPmAv?3emXe@dfK*?(^1 zu9a?$yY^%0eyfxFJryhaxvV6oCEYf$*!W2*mt6L3d3gI@7tI-nD-0Jlwq;V2+7lyO zfZ9zzM)+ytPztw)1)*<}9dGU;$W=Vspg&8KgpaStDpv%dX0%i9bDC{(d}56CSiRE| zn<2)NtpG@V)n=}dlO5i^sOiui24@!r-X#ymFgv({%_Usl8}9d$pYv?^Mr-jbDMq<2 ze7eEbb|fx2zaGFN{W^yRs%7UZq0?2n=b-sgY>(-jLe{y$lYHIalVX=x==Cr$5hCdG^d}$c^3;xyaZ;qlyyD(5F3L$g1dg=0i0R zH5>}BcGxw8F_N)zqgC~B9Yz!~&9VQEt$!L1xl|zh^O<1pMyGbSDmAw6(v9brIxdEl z6R5eVIdH2eih5KKc2SNJ4|xL~K`_EGyb#4%A^J`Mvi^P3LiD5%0WO=+-0sBL_xueq zR@v1AbAx+&%Ctq;6zl1Z{5hwR4G~y64L0A{Q(g(30tz6f*l9fhIY^tOe+n(W;l$?1wnGFG#fk2h!%lAJRcDIJi92tEpZ=Ix4XQJ%=|zB0rk zaY2yOpxfyi!Hh7Ckh6Y@i|(c6*}>*oLOgTtdrfoo-|qP7E=0acL@v&y?N|XbsqGNPjyA!rj}@)YEKdu&J(YP3Z3SmrD}CG&Bl3|2Ovh9OX!w(eqwce zVSM>udCxavOaSV?>bT=FGpaJ&QUwkBg?z~9Vjc&D5R|Xc3@9>r;p0Q|_%)v?Y-uG< zq$0SBEg2%#J(D)8en!d0-l&g4lNw20=q2%0+hI?;6M8QQ_2=M4Znnqhm!Wq~6e9s< zI*VxWh9q#^kU7opJ`pst+Hdvhf_91Uc_~46YLuQet}*hs=Fo zHkjKsp~O8Y*hE1V`6OJ$qkptU;~`%9H};1m$JiaaYcs1Nl;;yXixhCS6Zn2vU*BA3 zk@ABxFe3cfPk%EN#feyXJ5s%sgq?zXOcKjwpjhjeS$z3Gm~&pqECmk3ve%AFDBe3N zNXBSshj-nSfFBdX?}X?G-b^ygWS8qks0j!w%=u`Y)PSd!omnCaIo%YX3DR4Bw{kA^ z(PynBA^ZAu6UiCl(QnL^UJH)++P9SxdjsjIG>$UJ*KRY5jcaYIB!gClHhc&!k63QY z^vCRK(hriK>u}L;BNS5VY%$9C`>V1@xoVnj*wSsZxu}Q$pUv3iY{^{i20Na+oe@!7 z1EiJAcTEXJox*4iwQRcn(l>RUR^>4CWOW6;b&A?n_@;Ri>yFC=BRyh91* zZ7DGW*p7G$g=8=CJ)Kzu*LPQ}$7~-*V_BVL!#bib13sj_vb<*4VT$BVWiT=6>5nIKI1sSM?f#b%{b!!9Xd?L#Y`I zdnS<{{dh4f+9;qYpCgkak;ZqU zYaq}<_-f*&o2h83;K}#BrO(z4s8@Lt%SLhN>S10D86eE6a-3-3gC$l0jRng29rmi8 zzz;Nmi9_yWPPaQpN3VjAe1c5kh|O`Q8n8NacflnO6IbTN1 zQ~3EtM|fRy^(k5?Est+y$-x6-q03CJT?kY|x7=)m-j6p&QYb8#aRSECRLk9L-hOyG z^Uz~R3SmZWLAa;a1Fmn6p2 zNR$O>0u^%jRbW7QX(FKwhEh0Mt{fz-eM=3wkL>~*9<%TGBAiQ(t%8!L!S1{}#D9vu z3ySSv6V?uBpL8lV^MnOtXsP}GS~1WO(LAG=22SQ z$y<_fLh6#3*ln+t7SEsTl|gD%*Q=$4!nhsvGr3}CkdRZ}fP*U&ALl%91lp1B=%8VX zUWF}>dz@uzlAN8lk*%31<4@LUZ+k^IK7|Q9hzMACVI$!1`oHRu7awl%y$HU1`GTNR zcTT|$AG2@g>f;}bWyq!2DXz>zrSlVDBBzBM$-l~QGif&sj9QidrVr#lYGLm*7Z8*b z-2q`igVbGNbK-}Lng#7feowDGV3DUg*@xjnn$UkbnT#76zDYLDL9Ve|0)RkVQ>TM| zmr17}=tBx#Z`EmBgju3?N(vutfb#)ryQ_{RbG?1Nf;G{b!LC?AJr;6;m(GWZa!;Ix zB|tHuj-<;!C*Xw3?``E@iw}f_9=g`my_$n@j8i`WVx|L%GhifDs(Cx8C*qU@*LQ zA(v<%`28zRGcZalbv6E^o;2FbmH z&J8tR@Ae8TWPbt~$`0NKbfR&VHa-DZc2)dJ6|ySGljy-b;;T4GIQ%Gc zD3)el_{fY8K|pTPKqOECm2L;-i^ zJIc2=O>*lTvDCJlm)(z4CFyayo3 zLQ^Mp8-pgvUaz?U2AzDhfe$`7Cw^LAco}G`a(5-ufIUIlr7qiV3l^!6LS8HfrZVJR z9+iA!jLFGOO)=-Ehicv#IuyBqxF5mhLpDI1@7J-=U3ooj3%^MW1N! zB8B=WMu_68mv&~QvtNvMU?xRe1P_yv5ji;=7yWVb_*`YI>at!dkvW7dP@Q`RNRMsh zSio9>;5+wJu<9=3VgrZa6$9$~1l!nnJHek~JDxD5@7+U(Q(~Fo@RjkH5Fr)m`4Y#r z*}_)ac0`7m3_bp=>k|c>eeQ&l(>k-nY@J>C!>#g+N(?uKM z#8aWJ<7W*0I$o5+rn+R}VOa@i3H3NJIo_7AxmM4y7KVi@G5r!|t zKHDcgLxQm(@o97IWm|amcDLKL57ec{^vJ!!Li_6?%+YG1An5}(*<%_}FRBHbS9s#H zLajOZJ{ZZ!m#>gYm?HChH69Bbpa;1{6{T-h#3bd7p9d||f1;UTwT^^XSwa?9 zjWy$7c~c`X#Ka$8&?Msz1{&Dq>za1xKai03#`PaI0#6&m+Hl`DR3g2bpbgVm{a`ao z8mwB>_rz9i({xqL*Rt8Lg^Ss}FibGn#ejkUzN)p`Im*GtNT%W;3;eR)1kVoLksut1 z`Ps!oK6iik6l`=~Q%!nz)dakQ<3=epH<>LTk1M;7x8)|%!U8553w^5Nm~ay;OXa_mm+ z&_VbZwTzP7P+Fkp7{Bt?TiT2|UsMJmLgB&AzBl-}YK1FmI)I2QX#09VWF;9ra@=4) zr-l-@1Kfbg`jj}2<(C*xyPg#?vYi`s^5K){BT|{_DB_!;PlmsRG7$)@Ajf+fY}u_z z*LRUz3}w}6d0`G(7fU8T9&5I6Q=|;S0%QcJsS(f+zVdB`efFN zLD?pWI3H1<+}v{rx8~!LXV{3}!#5-hW{LJI{b*}lL-=OLhNkF`!|?g?*@vqV{F#Hv z&QC3&92kLSfrC!diB!m`w`d2|@~Kba%I5*M;3tDSIcVR*H`9R!3?1IYjICWYp0xUm z{?4gpIY2%5U7(@UMbK?To4b$Cuzn%_w-;g|A#YgfF(GsLt_rvu z6gh_yXq@I(WN!-x|3Q$TPlnH*m&Sdkf&xHRRhGUfpgZ-WK~9}^l4vKJbR(~-A1z|? z3v-}}4WHOe$0=q8HWWRaUK%b|%Syvq$KFizsl4GI=Lcn?O|lRT+lQ(uI};)n&} z69}Noptg6F+;6s;=!D{OP`5VY(Kf_FIf&8hz+las|;J>w+}Wtl~m z{`9E6TIUD!e8U@o_S2X;8(g>vki?M2a|yAQ6fbThrkZZwFOj=h96ol0GCJw2iRQ(y zkt+x-Y=p$!x=pGl{sx`vR|8X;eL`S?S5u;UDST?ja7q~};-nkM{Svq%G;ZHb861@d zLFlnBQXadyCQ}VHwsjr8+V=8*5W37$4P_@=n9m-Bu{5pN~2+FRvS$! zsC^bpnLk)gf*YB;rGP97bx8L^2SLs!axd@NM@`$Is40Rzr$aK|+Lgn8r2t}OW#xzL zx{`h69kM(@=VzfO$5DKhzEJG}b+JX4%?oBhzGs!4(r9^gd3^au4!y^R5 zPL>>rIltm4CifWaWZP*kyuCgk7>Z}@+fuCR0~3&4$HaNFv~b9oGYnvPr&a?iFjL0+ zfCe23BXfgAjyO#?ulg8>Z9_A?{4*Tii#?;9(Ank`P}i=&m}K zc3a0u15eYrm4m`T8a?_oL?#2!u7{rFs$$@9km;IIw{1sZv++-(J>JW4x_d3Ia9_HE zbk>>R_7KwWw>cP#b-!PmVudRvz+PNlPLWao@n^dc$ho<(54fqg$m6oWuGtz3#2RSE zMysJ_?R8&M!fY;G=XYt~;L`Asz!Dr0N>r*)80>)9m3M46&2ho1 z`-`?3*H&q_*A8i|TT$f2>5(5;*>&uCR67Q)4f)m#_>L4oJCG?D9ldU$K89H`GCZcKE%y%aB#(XRX^Mr2aZEWG)AB1rNf)4=)!0o zqdJijvWNt8JWV^^vCuU2e2oc#$e+P?1+XLhP~y9W{hXHIV|3oeZiw zYqhIEXu^1-%=QHbj1fpkDLAY&aw8sUD7xzA{o;&N>F}7(qh6T{#?XbD|_VVm| z!ClBP|KY%z_xh#ERCHKNk57?6_P(fScXoDS8dLxc3gjb_Ay4q&bbY$x(?z2YN!ORL5hD{M@f43Appv zp%1G}{&RYT5Qg=AnIbN7=ygVi?Wce$#s=)=T^3rzf>oM=Svc91Go4dZF_kF)?gMG2v)TvZ=p;6j)hAydmCRZ=?2pruR zwNiLTVbcqimkbPKH%ib|LOOuZ6i6d1hrX8KMb+9AEIA~-h=GR)Jx?UudX)yB&9p22 zhzb3>VWhfTXq1_FPZ($?JzoE#jV!mtPLP@$IvRgLrB^4ky0cfgg>qEOy(_IoxRZj8 zQahsUG2}wOB$+xvaeNt*Z#gY4z>6YDIWc}xQ^8{rJM*6yU(%a9Kl?VOoG^n z>m>Zmd>gqPocLzZ7bzdID2it*z{Xj+2{_$qd~LeBf_|g6mDzABZIsj;P(L0`|4Tic< zna?zkeseCKoq{VOlet22b=yK4CCUddl0VYF@URhJu)jSfovGC#sgC2FI)Q8Hw4OBx z(yiH!r#6{_5ARHeWwk5I;=uYcxMuUi-d8dqk{0z0Wy%OWaf=uRToI)5xVpAkZGnjk zDjSNm^hu;pFZ%nb*X@>#hwiRZ#1BEXIa{d)+LVsZ>k11>N8UKgrR9@ET45SG$^!wOgU0H%1D>h>SF`Z0`HH z*j>Sx-dTKSXUycDlPR8*r4^-Qoe8Af+vx$vkui;Lcb@o$92}A;t566trm9-y@-O&! zEi0_5NcVTdB=}j~iU=Pa;#asHu<&fTjv`p7;Rw4;si$u#>ulR5U1{3x4g~jNCL@7+ z149`Nwn%4^(tUYpJ=!-uA3(rwRwlH7)vG0Gz(R!d8t;%;ts`ouDO1mpq7HmD!}|jp z>CHIyW!L6G8VW#ES`Trv#1`_ zkn_QYa2NGZy2r>RwI0SCd|M8{?70Ws=*+4Gs)?#0fpD%UmXUq9RzC;2`a!F8gf6PM zVQ0U$thIYUGJ*P?@p=S+8@jqoX{Om27Ny_Jyy;1Q<}g8uA8y2Cc#`o2f?;V|43@A5_f^k}K97G=$!H&XGgjJF zk@4)Sl7Q8qaUUb4pi41?NdxvC?6;H1AmI19WFj-xgy46EZM5&4bMYzbB$2C`_i`22 zV1%hrKPUXio4)I-+&gH(knn_E;4KjUfvZRjL9B_BZ5xLWLMCy^`@#pqzY7q0p4s1m z&Mfx2IpS{MpuJ1T9buuylKU|)?OMZ%h)ptW_s=@>POLNQ9=OJ z=r_N(E)&9ZG-?wq}S)|ocR8|?o5)w0xX?Y=0;ZI-bbA|Pi_sLISQN}5a*31V9xw* zLRo6ZCqWn;e@E_bLBJT_V!Rpf{xF%{nWB~a?Ti0y16=FPfammgE1A>lOJM>401=y7 z>MhPLdD@d!X=U|rwwHVR)wy6FRQ~m=;ZPA}W&tmnpI4g(Nb0M{`D33dX5q~vHRf?2 zBytnxTojq=;ogF(pknq{7%|>dh|UHm0=(7=Wh`r}pUM)58hdJx_gMW(+r%X-2-?~9 zOxhCO)mlKgw}+?Mcjr&|D&hTzf=aC`mPr%#_qP~|pZq@}Ptv?1=#&;^* zeXwlOvA%(>Jx?&=kJhq-~J%;UurkH*Ej26 z5>r*fW~_^3Dr`P?`ayaJxn2$|2v(WFyB}?Q#Id$OmFn^bMW(L+&<~4z2$bfdQCdi3 z`V3H#SB3T{kxW|fm&1L@+|PM&LALDPp<)$$Z8K(hZhsyP48W@Qc0A=j6mJ6U008u1 z7H0=@+4r6(AOU<>)`z;t0YS8RqDrmsm|F?}WB@ea+>4VY$+V)@!nF#o;!+oMb&YQi zdO|}P{9P#|J4(L5;eF9cA0O^JN zpyUsL5d*<~f6*ZU_9J^NIWq+S)e1Vj((z{`)=zJd*#B;N`<;zo0B{h+!k*bYV*nT> z3sHzSOhv;E6PCj_qv$S4!rwciBfssd@Jsvl2hO*hX6@w@a2ic^48>_acmY5S(5)+= zm}~Nv-{uLKt>NzhU`hZ%zD4(7Lq3oL(XYaZl9B)~CKcidEEDfP&q$#2EvnETvbW#Y zmiWAMr4Y*rZ=2uL<-`YRmmUU-nMKRH?hAl`24sV58G{lVJ3w_mcoS3nfcseRXB;U1 zUvcbyGlICE7z#IF@lHm?+|a%P0qcl(SA6A3_YN`#01ghY^8uL$;b3dBN(4&+AxU)Y z{xb|1i11sSeDx^`}AU*GDXdw_nTs61@FpQa=W5D{IzG!0CpTQ%lM)xETV7 zmHd*XaRn*!OcFu}F!hEZ#3`4Dr{|*(nbp73-6n)(+~%2|_}dwP@%*}y+TTPVZf`YU z<3!?-l4d&}J4iKMU|<}qN?UAW03bgA^n9*Ue6BI15$yNqfaJN;!@q_3C7*jETmKgk zY5A=u`zJ)+n%^Hp7T-Kle;EcX z=FPYEFB18qRucNdwf5KKNXdVW$glfI#?XHQk^O&_$nREj_!kj5`_B>i-Pa)g^+bM` zEMS2D@_po2j{L1c`B!`2KTWj%|I{P@NaS~4^FQ^-pQD@K3CF^~jsVoauLkruzEA&i5Y?`8SFA8xZ-o za)j#NCP*M{yD~GvZ`k*r8X<5yK(Hde-$BOoIYN}j86r2>SOXv@05Kp##E8H&u!2aO dU7ZX^5Dsmj2ZFyJ!I=LI^4lQZ_Fpa|{udtygJl2! literal 0 HcmV?d00001 diff --git a/enterprise-dashboard-accessibility-guard/reports/summary.svg b/enterprise-dashboard-accessibility-guard/reports/summary.svg new file mode 100644 index 00000000..6b4ce1ee --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/reports/summary.svg @@ -0,0 +1,24 @@ + + + Enterprise Dashboard Accessibility Guard + Institutional dashboards, exports, and webhook notices are gated before release. + + + + + enterprise-admin-overview + hold_accessibility_release | findings 8 | digest c23d9d45d2282027 + + + + + enterprise-admin-clean + release_with_accessibility_monitoring | findings 0 | digest e3abe7a1521f5654 + + + + + enterprise-admin-motion-warning + remediate_before_public_release | findings 1 | digest bfa5b6aae578307a + + diff --git a/enterprise-dashboard-accessibility-guard/reports/warning-packet.json b/enterprise-dashboard-accessibility-guard/reports/warning-packet.json new file mode 100644 index 00000000..496fb404 --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/reports/warning-packet.json @@ -0,0 +1,29 @@ +{ + "dashboardId": "enterprise-admin-motion-warning", + "institutionId": "institution-redacted", + "status": "remediate_before_public_release", + "releaseLanes": { + "adminDashboard": "internal_only", + "scheduledExport": "blocked", + "webhookNotice": "internal_only" + }, + "findings": [ + { + "componentId": "research-output-trend", + "code": "MISSING_REDUCED_MOTION_FALLBACK", + "severity": "warning", + "message": "Animated dashboard content needs a reduced-motion fallback before public release." + } + ], + "actions": [ + "add_reduced_motion_fallback:research-output-trend" + ], + "wcagSignals": { + "perceivable": true, + "operable": false, + "understandable": true, + "robust": true + }, + "assessedAt": "2026-05-27T13:00:00Z", + "auditDigest": "bfa5b6aae578307ad58b740178a32b2a53dac335acea64ac2ee20afa87ca4864" +} diff --git a/enterprise-dashboard-accessibility-guard/requirements-map.md b/enterprise-dashboard-accessibility-guard/requirements-map.md new file mode 100644 index 00000000..811a918c --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/requirements-map.md @@ -0,0 +1,16 @@ +# Requirements Map + +Issue #19 asks for enterprise tooling around admin dashboards, API and webhook integrations, export pipelines, compliance tracking, usage visibility, and institution-scale governance. + +| Issue Area | This Slice | +| --- | --- | +| Admin dashboards | Gates institutional dashboard widgets before release to admins. | +| Contributor and usage analytics | Checks that critical metrics are perceivable, labeled, keyboard reachable, and safe for nonvisual users. | +| Compliance tracking | Produces WCAG-oriented readiness signals and deterministic audit evidence for institutional governance. | +| Export pipelines | Blocks scheduled exports when tables lack summaries or dashboard views are not accessible enough for release. | +| Webhook support | Keeps webhook notices internal-only when the dashboard state has nonblocking accessibility warnings. | +| Enterprise governance | Detects private-data leakage in screen-reader text before dashboard or export surfaces are published. | + +## Non-Overlap + +This is distinct from the existing dashboard/export/webhook replay/compliance/identity/retention/data-residency/SLA/secret-rotation/quota/API-change/connector-certification/incident/funder/AI-model/dashboard-attribution/initiative-tag/policy-exception/IRB/data-export/SCIM/deposit-reconciliation/admin-notification/cost-allocation/LMS/payload-redaction/vendor-DPA/cohort-privacy/API-rate-limit slices. It focuses specifically on accessibility readiness for institutional admin dashboards and their downstream export/webhook release lanes. diff --git a/enterprise-dashboard-accessibility-guard/sample-data.js b/enterprise-dashboard-accessibility-guard/sample-data.js new file mode 100644 index 00000000..3c9e103e --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/sample-data.js @@ -0,0 +1,149 @@ +const blockedDashboard = { + dashboardId: 'enterprise-admin-overview', + institutionId: 'institution-redacted', + assessedAt: '2026-05-27T13:00:00Z', + widgets: [ + { + id: 'compute-usage-critical', + type: 'metric', + title: 'Compute usage', + foreground: '#64748b', + background: '#f8fafc', + critical: true, + keyboardReachable: true, + screenReaderLabel: 'Compute usage for private lab alice@example.edu', + ariaTextContainsPrivateData: true, + headingLevel: 2 + }, + { + id: 'private-project-table', + type: 'table', + title: 'Private projects', + foreground: '#111827', + background: '#ffffff', + critical: true, + keyboardReachable: false, + focusTrap: true, + screenReaderLabel: '', + tableSummary: '', + headingLevel: 4 + } + ], + alerts: [ + { + id: 'webhook-failure-alert', + title: 'Webhook delivery failed', + foreground: '#ef4444', + background: '#fee2e2', + critical: true, + keyboardReachable: true, + screenReaderLabel: 'Webhook delivery failed', + headingLevel: 3 + } + ], + exports: [ + { + id: 'weekly-admin-export', + format: 'csv', + tableSummary: '', + screenReaderLabel: 'Weekly admin export' + } + ], + motion: { + animatedCharts: ['compute-usage-critical'], + reducedMotionFallback: false + } +}; + +const cleanDashboard = { + dashboardId: 'enterprise-admin-clean', + institutionId: 'institution-redacted', + assessedAt: '2026-05-27T13:00:00Z', + widgets: [ + { + id: 'open-access-compliance', + type: 'metric', + title: 'Open access compliance', + foreground: '#0f172a', + background: '#ffffff', + critical: true, + keyboardReachable: true, + screenReaderLabel: 'Open access compliance percentage across hosted projects', + headingLevel: 2 + }, + { + id: 'lab-output-table', + type: 'table', + title: 'Lab output', + foreground: '#0f172a', + background: '#f8fafc', + critical: false, + keyboardReachable: true, + screenReaderLabel: 'Research output by lab', + tableSummary: 'Rows list labs; columns show projects, reviews, storage, and reproducibility score.', + headingLevel: 3 + } + ], + alerts: [ + { + id: 'repo-sync-alert', + title: 'Repository sync complete', + foreground: '#14532d', + background: '#dcfce7', + critical: false, + keyboardReachable: true, + screenReaderLabel: 'Repository sync complete', + headingLevel: 3 + } + ], + exports: [ + { + id: 'quarterly-accessibility-export', + format: 'json', + tableSummary: 'Export includes aggregate accessibility status only.', + screenReaderLabel: 'Quarterly accessibility readiness export' + } + ], + motion: { + animatedCharts: ['open-access-compliance'], + reducedMotionFallback: true + } +}; + +const warningDashboard = { + dashboardId: 'enterprise-admin-motion-warning', + institutionId: 'institution-redacted', + assessedAt: '2026-05-27T13:00:00Z', + widgets: [ + { + id: 'research-output-trend', + type: 'metric', + title: 'Research output trend', + foreground: '#172554', + background: '#dbeafe', + critical: false, + keyboardReachable: true, + screenReaderLabel: 'Research output trend for all departments', + headingLevel: 2 + } + ], + alerts: [], + exports: [ + { + id: 'trend-export', + format: 'json', + tableSummary: 'Trend export contains aggregate department counts only.', + screenReaderLabel: 'Research output trend export' + } + ], + motion: { + animatedCharts: ['research-output-trend'], + reducedMotionFallback: false + } +}; + +module.exports = { + blockedDashboard, + cleanDashboard, + warningDashboard +}; diff --git a/enterprise-dashboard-accessibility-guard/test.js b/enterprise-dashboard-accessibility-guard/test.js new file mode 100644 index 00000000..0ff2701f --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/test.js @@ -0,0 +1,62 @@ +const assert = require('assert'); + +const { assessDashboardRelease } = require('./index'); +const { blockedDashboard, cleanDashboard, warningDashboard } = require('./sample-data'); + +function codes(packet) { + return packet.findings.map((finding) => finding.code).sort(); +} + +function testCriticalAccessibilityIssuesBlockDashboardRelease() { + const packet = assessDashboardRelease(blockedDashboard); + const findingCodes = codes(packet); + + assert.equal(packet.status, 'hold_accessibility_release'); + assert.equal(packet.releaseLanes.adminDashboard, 'blocked'); + assert.equal(packet.releaseLanes.scheduledExport, 'blocked'); + assert.equal(packet.releaseLanes.webhookNotice, 'blocked'); + assert.ok(findingCodes.includes('LOW_CONTRAST_CRITICAL_METRIC')); + assert.ok(findingCodes.includes('MISSING_SCREEN_READER_LABEL')); + assert.ok(findingCodes.includes('KEYBOARD_TRAP')); + assert.ok(findingCodes.includes('PRIVATE_DATA_IN_ACCESSIBILITY_TEXT')); + assert.ok(findingCodes.includes('MISSING_TABLE_SUMMARY')); + assert.ok(packet.actions.includes('block_release:enterprise-admin-overview')); + assert.match(packet.auditDigest, /^[a-f0-9]{64}$/); +} + +function testCleanDashboardReleasesWithWcagSignals() { + const packet = assessDashboardRelease(cleanDashboard); + + assert.equal(packet.status, 'release_with_accessibility_monitoring'); + assert.equal(packet.releaseLanes.adminDashboard, 'allowed'); + assert.equal(packet.releaseLanes.scheduledExport, 'allowed'); + assert.equal(packet.releaseLanes.webhookNotice, 'allowed'); + assert.deepEqual(packet.findings, []); + assert.equal(packet.wcagSignals.perceivable, true); + assert.equal(packet.wcagSignals.operable, true); + assert.equal(packet.wcagSignals.understandable, true); + assert.equal(packet.wcagSignals.robust, true); +} + +function testWarningsAllowInternalOnlyPreview() { + const packet = assessDashboardRelease(warningDashboard); + + assert.equal(packet.status, 'remediate_before_public_release'); + assert.equal(packet.releaseLanes.adminDashboard, 'internal_only'); + assert.equal(packet.releaseLanes.scheduledExport, 'blocked'); + assert.equal(packet.releaseLanes.webhookNotice, 'internal_only'); + assert.deepEqual(codes(packet), ['MISSING_REDUCED_MOTION_FALLBACK']); + assert.ok(packet.actions.includes('add_reduced_motion_fallback:research-output-trend')); +} + +const tests = [ + testCriticalAccessibilityIssuesBlockDashboardRelease, + testCleanDashboardReleasesWithWcagSignals, + testWarningsAllowInternalOnlyPreview +]; + +for (const test of tests) { + test(); +} + +console.log(`enterprise-dashboard-accessibility-guard tests passed (${tests.length})`); From 5047577d679657c74969ceb6b8e4db33040b23de Mon Sep 17 00:00:00 2001 From: KoiosSG Date: Thu, 28 May 2026 17:30:33 +0200 Subject: [PATCH 02/12] Harden enterprise dashboard contrast checks --- .../README.md | 2 +- .../acceptance-notes.md | 1 + .../index.js | 18 ++++++++- .../reports/blocked-packet.json | 5 ++- .../reports/summary.svg | 2 +- .../requirements-map.md | 2 +- .../test.js | 37 ++++++++++++++++++- 7 files changed, 60 insertions(+), 7 deletions(-) diff --git a/enterprise-dashboard-accessibility-guard/README.md b/enterprise-dashboard-accessibility-guard/README.md index 8c82fa3a..e28c5002 100644 --- a/enterprise-dashboard-accessibility-guard/README.md +++ b/enterprise-dashboard-accessibility-guard/README.md @@ -6,7 +6,7 @@ This module evaluates institutional admin dashboard releases before they are sho ## What It Checks -- Critical metric color contrast +- Critical metric color contrast and warning-level contrast checks for noncritical content - Missing screen-reader labels - Keyboard reachability and focus traps - Private user or project data embedded in accessibility text diff --git a/enterprise-dashboard-accessibility-guard/acceptance-notes.md b/enterprise-dashboard-accessibility-guard/acceptance-notes.md index 6d94ec18..0f2e6fdd 100644 --- a/enterprise-dashboard-accessibility-guard/acceptance-notes.md +++ b/enterprise-dashboard-accessibility-guard/acceptance-notes.md @@ -4,6 +4,7 @@ - Keeps all records synthetic and local. - Uses dependency-free Node.js logic for deterministic dashboard release decisions. - Covers blocked, clean, and warning-only dashboard states with tests. +- Treats noncritical low-contrast content as a remediation warning before public release. - Generates reviewer artifacts: - `reports/blocked-packet.json` - `reports/clean-packet.json` diff --git a/enterprise-dashboard-accessibility-guard/index.js b/enterprise-dashboard-accessibility-guard/index.js index ede63f3a..5583f81c 100644 --- a/enterprise-dashboard-accessibility-guard/index.js +++ b/enterprise-dashboard-accessibility-guard/index.js @@ -41,6 +41,13 @@ function assessVisualAndOperableComponents(dashboard) { 'blocker', `Critical component contrast is ${contrast.toFixed(2)}:1, below the 4.5:1 release threshold.` )); + } else if (contrast < 4.5) { + findings.push(finding( + component, + 'LOW_CONTRAST_NONCRITICAL_METRIC', + 'warning', + `Noncritical component contrast is ${contrast.toFixed(2)}:1, below the 4.5:1 readiness threshold.` + )); } } @@ -145,6 +152,12 @@ function buildActions(dashboard, findings) { if (item.code === 'MISSING_SCREEN_READER_LABEL') { actions.add(`add_screen_reader_label:${item.componentId}`); } + if ( + item.code === 'LOW_CONTRAST_CRITICAL_METRIC' || + item.code === 'LOW_CONTRAST_NONCRITICAL_METRIC' + ) { + actions.add(`improve_contrast:${item.componentId}`); + } } return [...actions].sort(); @@ -153,7 +166,10 @@ function buildActions(dashboard, findings) { function buildWcagSignals(findings) { const codes = new Set(findings.map((finding) => finding.code)); return { - perceivable: !codes.has('LOW_CONTRAST_CRITICAL_METRIC') && !codes.has('MISSING_TABLE_SUMMARY'), + perceivable: + !codes.has('LOW_CONTRAST_CRITICAL_METRIC') && + !codes.has('LOW_CONTRAST_NONCRITICAL_METRIC') && + !codes.has('MISSING_TABLE_SUMMARY'), operable: !codes.has('KEYBOARD_TRAP') && !codes.has('MISSING_REDUCED_MOTION_FALLBACK'), understandable: !codes.has('PRIVATE_DATA_IN_ACCESSIBILITY_TEXT') && !codes.has('HEADING_ORDER_SKIP'), robust: !codes.has('MISSING_SCREEN_READER_LABEL') diff --git a/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json b/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json index e06ebec5..ecfb7205 100644 --- a/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json +++ b/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json @@ -62,7 +62,8 @@ "add_screen_reader_label:private-project-table", "add_table_summary:private-project-table", "add_table_summary:weekly-admin-export", - "block_release:enterprise-admin-overview" + "block_release:enterprise-admin-overview", + "improve_contrast:webhook-failure-alert" ], "wcagSignals": { "perceivable": false, @@ -71,5 +72,5 @@ "robust": false }, "assessedAt": "2026-05-27T13:00:00Z", - "auditDigest": "c23d9d45d2282027a0571519fa0e8f8e75c43e21882757f6259b23f3ef547728" + "auditDigest": "08fe3d5920f0e34baf7e2c3d0919ac2a322e0b3bd2bc92602de6e6b201e8dfc5" } diff --git a/enterprise-dashboard-accessibility-guard/reports/summary.svg b/enterprise-dashboard-accessibility-guard/reports/summary.svg index 6b4ce1ee..4d4e7ab7 100644 --- a/enterprise-dashboard-accessibility-guard/reports/summary.svg +++ b/enterprise-dashboard-accessibility-guard/reports/summary.svg @@ -7,7 +7,7 @@ enterprise-admin-overview - hold_accessibility_release | findings 8 | digest c23d9d45d2282027 + hold_accessibility_release | findings 8 | digest 08fe3d5920f0e34b diff --git a/enterprise-dashboard-accessibility-guard/requirements-map.md b/enterprise-dashboard-accessibility-guard/requirements-map.md index 811a918c..c1e6cc2f 100644 --- a/enterprise-dashboard-accessibility-guard/requirements-map.md +++ b/enterprise-dashboard-accessibility-guard/requirements-map.md @@ -5,7 +5,7 @@ Issue #19 asks for enterprise tooling around admin dashboards, API and webhook i | Issue Area | This Slice | | --- | --- | | Admin dashboards | Gates institutional dashboard widgets before release to admins. | -| Contributor and usage analytics | Checks that critical metrics are perceivable, labeled, keyboard reachable, and safe for nonvisual users. | +| Contributor and usage analytics | Checks that critical and noncritical metrics are perceivable, labeled, keyboard reachable, and safe for nonvisual users. | | Compliance tracking | Produces WCAG-oriented readiness signals and deterministic audit evidence for institutional governance. | | Export pipelines | Blocks scheduled exports when tables lack summaries or dashboard views are not accessible enough for release. | | Webhook support | Keeps webhook notices internal-only when the dashboard state has nonblocking accessibility warnings. | diff --git a/enterprise-dashboard-accessibility-guard/test.js b/enterprise-dashboard-accessibility-guard/test.js index 0ff2701f..541bb40f 100644 --- a/enterprise-dashboard-accessibility-guard/test.js +++ b/enterprise-dashboard-accessibility-guard/test.js @@ -49,10 +49,45 @@ function testWarningsAllowInternalOnlyPreview() { assert.ok(packet.actions.includes('add_reduced_motion_fallback:research-output-trend')); } +function testNonCriticalLowContrastRequiresRemediationBeforeRelease() { + const packet = assessDashboardRelease({ + dashboardId: 'enterprise-admin-low-contrast-secondary', + institutionId: 'institution-redacted', + assessedAt: '2026-05-27T13:05:00Z', + widgets: [ + { + id: 'secondary-storage-trend', + type: 'metric', + title: 'Storage trend', + foreground: '#94a3b8', + background: '#f8fafc', + critical: false, + keyboardReachable: true, + screenReaderLabel: 'Storage trend across departments', + headingLevel: 2 + } + ], + alerts: [], + exports: [], + motion: { + animatedCharts: [], + reducedMotionFallback: true + } + }); + + assert.equal(packet.status, 'remediate_before_public_release'); + assert.equal(packet.releaseLanes.adminDashboard, 'internal_only'); + assert.equal(packet.releaseLanes.scheduledExport, 'blocked'); + assert.deepEqual(codes(packet), ['LOW_CONTRAST_NONCRITICAL_METRIC']); + assert.equal(packet.wcagSignals.perceivable, false); + assert.ok(packet.actions.includes('improve_contrast:secondary-storage-trend')); +} + const tests = [ testCriticalAccessibilityIssuesBlockDashboardRelease, testCleanDashboardReleasesWithWcagSignals, - testWarningsAllowInternalOnlyPreview + testWarningsAllowInternalOnlyPreview, + testNonCriticalLowContrastRequiresRemediationBeforeRelease ]; for (const test of tests) { From 836537b85fb043387848b61f5130b67a6c0fd2f2 Mon Sep 17 00:00:00 2001 From: KoiosSG Date: Fri, 29 May 2026 17:44:20 +0200 Subject: [PATCH 03/12] Harden dashboard accessibility summaries --- .../README.md | 2 +- .../acceptance-notes.md | 1 + .../index.js | 9 ++++- .../reports/blocked-packet.json | 5 ++- .../reports/summary.svg | 2 +- .../requirements-map.md | 2 +- .../test.js | 37 ++++++++++++++++++- 7 files changed, 51 insertions(+), 7 deletions(-) diff --git a/enterprise-dashboard-accessibility-guard/README.md b/enterprise-dashboard-accessibility-guard/README.md index e28c5002..d53dc2da 100644 --- a/enterprise-dashboard-accessibility-guard/README.md +++ b/enterprise-dashboard-accessibility-guard/README.md @@ -9,7 +9,7 @@ This module evaluates institutional admin dashboard releases before they are sho - Critical metric color contrast and warning-level contrast checks for noncritical content - Missing screen-reader labels - Keyboard reachability and focus traps -- Private user or project data embedded in accessibility text +- Private user or project data embedded in screen-reader labels, table summaries, or export summaries - Missing table and export summaries - Heading-order skips - Missing reduced-motion fallbacks for animated dashboard content diff --git a/enterprise-dashboard-accessibility-guard/acceptance-notes.md b/enterprise-dashboard-accessibility-guard/acceptance-notes.md index 0f2e6fdd..0ef30f50 100644 --- a/enterprise-dashboard-accessibility-guard/acceptance-notes.md +++ b/enterprise-dashboard-accessibility-guard/acceptance-notes.md @@ -5,6 +5,7 @@ - Uses dependency-free Node.js logic for deterministic dashboard release decisions. - Covers blocked, clean, and warning-only dashboard states with tests. - Treats noncritical low-contrast content as a remediation warning before public release. +- Blocks release when private data appears in table or export accessibility summaries. - Generates reviewer artifacts: - `reports/blocked-packet.json` - `reports/clean-packet.json` diff --git a/enterprise-dashboard-accessibility-guard/index.js b/enterprise-dashboard-accessibility-guard/index.js index 5583f81c..3c97a67a 100644 --- a/enterprise-dashboard-accessibility-guard/index.js +++ b/enterprise-dashboard-accessibility-guard/index.js @@ -59,7 +59,7 @@ function assessVisualAndOperableComponents(dashboard) { findings.push(finding(component, 'KEYBOARD_TRAP', 'blocker', 'Keyboard users cannot reach or leave this component predictably.')); } - if (component.ariaTextContainsPrivateData || containsPrivateData(component.screenReaderLabel)) { + if (component.ariaTextContainsPrivateData || containsPrivateData(accessibilityText(component))) { findings.push(finding(component, 'PRIVATE_DATA_IN_ACCESSIBILITY_TEXT', 'blocker', 'Accessibility text exposes private user, lab, or project data.')); } @@ -158,6 +158,9 @@ function buildActions(dashboard, findings) { ) { actions.add(`improve_contrast:${item.componentId}`); } + if (item.code === 'PRIVATE_DATA_IN_ACCESSIBILITY_TEXT') { + actions.add(`redact_accessibility_text:${item.componentId}`); + } } return [...actions].sort(); @@ -206,6 +209,10 @@ function containsPrivateData(value = '') { return /[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}|private lab|restricted project/i.test(value); } +function accessibilityText(component) { + return [component.screenReaderLabel, component.tableSummary].filter(Boolean).join(' '); +} + function digestPacket(packet) { return crypto.createHash('sha256').update(stableStringify(packet)).digest('hex'); } diff --git a/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json b/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json index ecfb7205..146c201b 100644 --- a/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json +++ b/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json @@ -63,7 +63,8 @@ "add_table_summary:private-project-table", "add_table_summary:weekly-admin-export", "block_release:enterprise-admin-overview", - "improve_contrast:webhook-failure-alert" + "improve_contrast:webhook-failure-alert", + "redact_accessibility_text:compute-usage-critical" ], "wcagSignals": { "perceivable": false, @@ -72,5 +73,5 @@ "robust": false }, "assessedAt": "2026-05-27T13:00:00Z", - "auditDigest": "08fe3d5920f0e34baf7e2c3d0919ac2a322e0b3bd2bc92602de6e6b201e8dfc5" + "auditDigest": "99f76262882d98d054a07949f72bd391fce08701fc36c67821b2d0be13f39300" } diff --git a/enterprise-dashboard-accessibility-guard/reports/summary.svg b/enterprise-dashboard-accessibility-guard/reports/summary.svg index 4d4e7ab7..ed4ed167 100644 --- a/enterprise-dashboard-accessibility-guard/reports/summary.svg +++ b/enterprise-dashboard-accessibility-guard/reports/summary.svg @@ -7,7 +7,7 @@ enterprise-admin-overview - hold_accessibility_release | findings 8 | digest 08fe3d5920f0e34b + hold_accessibility_release | findings 8 | digest 99f76262882d98d0 diff --git a/enterprise-dashboard-accessibility-guard/requirements-map.md b/enterprise-dashboard-accessibility-guard/requirements-map.md index c1e6cc2f..a3c4fe75 100644 --- a/enterprise-dashboard-accessibility-guard/requirements-map.md +++ b/enterprise-dashboard-accessibility-guard/requirements-map.md @@ -9,7 +9,7 @@ Issue #19 asks for enterprise tooling around admin dashboards, API and webhook i | Compliance tracking | Produces WCAG-oriented readiness signals and deterministic audit evidence for institutional governance. | | Export pipelines | Blocks scheduled exports when tables lack summaries or dashboard views are not accessible enough for release. | | Webhook support | Keeps webhook notices internal-only when the dashboard state has nonblocking accessibility warnings. | -| Enterprise governance | Detects private-data leakage in screen-reader text before dashboard or export surfaces are published. | +| Enterprise governance | Detects private-data leakage in screen-reader labels, table summaries, and export summaries before dashboard or export surfaces are published. | ## Non-Overlap diff --git a/enterprise-dashboard-accessibility-guard/test.js b/enterprise-dashboard-accessibility-guard/test.js index 541bb40f..734d7137 100644 --- a/enterprise-dashboard-accessibility-guard/test.js +++ b/enterprise-dashboard-accessibility-guard/test.js @@ -83,11 +83,46 @@ function testNonCriticalLowContrastRequiresRemediationBeforeRelease() { assert.ok(packet.actions.includes('improve_contrast:secondary-storage-trend')); } +function testPrivateDataInTableSummaryBlocksRelease() { + const packet = assessDashboardRelease({ + dashboardId: 'enterprise-admin-private-summary', + institutionId: 'institution-redacted', + assessedAt: '2026-05-27T13:10:00Z', + widgets: [ + { + id: 'private-summary-table', + type: 'table', + title: 'Project review', + foreground: '#111827', + background: '#ffffff', + critical: true, + keyboardReachable: true, + screenReaderLabel: 'Project review table', + tableSummary: 'Rows include restricted project alpha and private lab owner alice@example.edu.', + headingLevel: 2 + } + ], + alerts: [], + exports: [], + motion: { + animatedCharts: [], + reducedMotionFallback: true + } + }); + + assert.equal(packet.status, 'hold_accessibility_release'); + assert.equal(packet.releaseLanes.adminDashboard, 'blocked'); + assert.ok(codes(packet).includes('PRIVATE_DATA_IN_ACCESSIBILITY_TEXT')); + assert.equal(packet.wcagSignals.understandable, false); + assert.ok(packet.actions.includes('redact_accessibility_text:private-summary-table')); +} + const tests = [ testCriticalAccessibilityIssuesBlockDashboardRelease, testCleanDashboardReleasesWithWcagSignals, testWarningsAllowInternalOnlyPreview, - testNonCriticalLowContrastRequiresRemediationBeforeRelease + testNonCriticalLowContrastRequiresRemediationBeforeRelease, + testPrivateDataInTableSummaryBlocksRelease ]; for (const test of tests) { From e0195d72f796813325ecc492595d4b957c627e16 Mon Sep 17 00:00:00 2001 From: KoiosSG Date: Fri, 29 May 2026 19:44:51 +0200 Subject: [PATCH 04/12] Validate dashboard contrast evidence --- .../README.md | 1 + .../acceptance-notes.md | 1 + .../index.js | 25 ++++++- .../reports/accessibility-report.md | 2 +- .../reports/blocked-packet.json | 9 ++- .../reports/summary.svg | 2 +- .../requirements-map.md | 2 +- .../sample-data.js | 11 +++ .../test.js | 68 ++++++++++++++++++- 9 files changed, 113 insertions(+), 8 deletions(-) diff --git a/enterprise-dashboard-accessibility-guard/README.md b/enterprise-dashboard-accessibility-guard/README.md index d53dc2da..be51126b 100644 --- a/enterprise-dashboard-accessibility-guard/README.md +++ b/enterprise-dashboard-accessibility-guard/README.md @@ -7,6 +7,7 @@ This module evaluates institutional admin dashboard releases before they are sho ## What It Checks - Critical metric color contrast and warning-level contrast checks for noncritical content +- Invalid or unparseable contrast evidence, including unresolved CSS color tokens - Missing screen-reader labels - Keyboard reachability and focus traps - Private user or project data embedded in screen-reader labels, table summaries, or export summaries diff --git a/enterprise-dashboard-accessibility-guard/acceptance-notes.md b/enterprise-dashboard-accessibility-guard/acceptance-notes.md index 0ef30f50..b427242e 100644 --- a/enterprise-dashboard-accessibility-guard/acceptance-notes.md +++ b/enterprise-dashboard-accessibility-guard/acceptance-notes.md @@ -5,6 +5,7 @@ - Uses dependency-free Node.js logic for deterministic dashboard release decisions. - Covers blocked, clean, and warning-only dashboard states with tests. - Treats noncritical low-contrast content as a remediation warning before public release. +- Blocks release when dashboard contrast evidence is invalid or still expressed as unresolved CSS color tokens. - Blocks release when private data appears in table or export accessibility summaries. - Generates reviewer artifacts: - `reports/blocked-packet.json` diff --git a/enterprise-dashboard-accessibility-guard/index.js b/enterprise-dashboard-accessibility-guard/index.js index 3c97a67a..89aa90b4 100644 --- a/enterprise-dashboard-accessibility-guard/index.js +++ b/enterprise-dashboard-accessibility-guard/index.js @@ -34,7 +34,14 @@ function assessVisualAndOperableComponents(dashboard) { for (const component of components) { if (component.foreground && component.background) { const contrast = contrastRatio(component.foreground, component.background); - if (component.critical && contrast < 4.5) { + if (contrast === null) { + findings.push(finding( + component, + 'INVALID_CONTRAST_EVIDENCE', + 'blocker', + 'Component color evidence must be parseable hex values before dashboard release.' + )); + } else if (component.critical && contrast < 4.5) { findings.push(finding( component, 'LOW_CONTRAST_CRITICAL_METRIC', @@ -158,6 +165,9 @@ function buildActions(dashboard, findings) { ) { actions.add(`improve_contrast:${item.componentId}`); } + if (item.code === 'INVALID_CONTRAST_EVIDENCE') { + actions.add(`provide_valid_contrast_evidence:${item.componentId}`); + } if (item.code === 'PRIVATE_DATA_IN_ACCESSIBILITY_TEXT') { actions.add(`redact_accessibility_text:${item.componentId}`); } @@ -170,6 +180,7 @@ function buildWcagSignals(findings) { const codes = new Set(findings.map((finding) => finding.code)); return { perceivable: + !codes.has('INVALID_CONTRAST_EVIDENCE') && !codes.has('LOW_CONTRAST_CRITICAL_METRIC') && !codes.has('LOW_CONTRAST_NONCRITICAL_METRIC') && !codes.has('MISSING_TABLE_SUMMARY'), @@ -182,13 +193,19 @@ function buildWcagSignals(findings) { function contrastRatio(foreground, background) { const fg = relativeLuminance(hexToRgb(foreground)); const bg = relativeLuminance(hexToRgb(background)); + if (fg === null || bg === null) return null; const lighter = Math.max(fg, bg); const darker = Math.min(fg, bg); return (lighter + 0.05) / (darker + 0.05); } function hexToRgb(hex) { - const normalized = hex.replace('#', ''); + if (typeof hex !== 'string') return null; + const token = hex.trim().replace('#', ''); + const normalized = /^[0-9a-f]{3}$/i.test(token) + ? token.split('').map((char) => char + char).join('') + : token; + if (!/^[0-9a-f]{6}$/i.test(normalized)) return null; const bigint = parseInt(normalized, 16); return { r: (bigint >> 16) & 255, @@ -197,7 +214,9 @@ function hexToRgb(hex) { }; } -function relativeLuminance({ r, g, b }) { +function relativeLuminance(rgb) { + if (!rgb) return null; + const { r, g, b } = rgb; const channels = [r, g, b].map((channel) => { const srgb = channel / 255; return srgb <= 0.03928 ? srgb / 12.92 : ((srgb + 0.055) / 1.055) ** 2.4; diff --git a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md index 0af26adf..944c8c26 100644 --- a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md +++ b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md @@ -2,7 +2,7 @@ | Packet | Status | Dashboard | Export | Webhook | Findings | | --- | --- | --- | --- | --- | --- | -| blocked-packet.json | hold_accessibility_release | blocked | blocked | blocked | PRIVATE_DATA_IN_ACCESSIBILITY_TEXT, MISSING_SCREEN_READER_LABEL, KEYBOARD_TRAP, MISSING_TABLE_SUMMARY, LOW_CONTRAST_CRITICAL_METRIC, MISSING_TABLE_SUMMARY, HEADING_ORDER_SKIP, MISSING_REDUCED_MOTION_FALLBACK | +| blocked-packet.json | hold_accessibility_release | blocked | blocked | blocked | PRIVATE_DATA_IN_ACCESSIBILITY_TEXT, INVALID_CONTRAST_EVIDENCE, MISSING_SCREEN_READER_LABEL, KEYBOARD_TRAP, MISSING_TABLE_SUMMARY, LOW_CONTRAST_CRITICAL_METRIC, MISSING_TABLE_SUMMARY, HEADING_ORDER_SKIP, MISSING_REDUCED_MOTION_FALLBACK | | clean-packet.json | release_with_accessibility_monitoring | allowed | allowed | allowed | none | | warning-packet.json | remediate_before_public_release | internal_only | blocked | internal_only | MISSING_REDUCED_MOTION_FALLBACK | diff --git a/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json b/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json index 146c201b..01d4c08a 100644 --- a/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json +++ b/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json @@ -14,6 +14,12 @@ "severity": "blocker", "message": "Accessibility text exposes private user, lab, or project data." }, + { + "componentId": "contract-risk-score", + "code": "INVALID_CONTRAST_EVIDENCE", + "severity": "blocker", + "message": "Component color evidence must be parseable hex values before dashboard release." + }, { "componentId": "private-project-table", "code": "MISSING_SCREEN_READER_LABEL", @@ -64,6 +70,7 @@ "add_table_summary:weekly-admin-export", "block_release:enterprise-admin-overview", "improve_contrast:webhook-failure-alert", + "provide_valid_contrast_evidence:contract-risk-score", "redact_accessibility_text:compute-usage-critical" ], "wcagSignals": { @@ -73,5 +80,5 @@ "robust": false }, "assessedAt": "2026-05-27T13:00:00Z", - "auditDigest": "99f76262882d98d054a07949f72bd391fce08701fc36c67821b2d0be13f39300" + "auditDigest": "3a92697e16f9be41158da60c1f880d443a67a58d6e367fa94882fe8874f69864" } diff --git a/enterprise-dashboard-accessibility-guard/reports/summary.svg b/enterprise-dashboard-accessibility-guard/reports/summary.svg index ed4ed167..1c0a3e4a 100644 --- a/enterprise-dashboard-accessibility-guard/reports/summary.svg +++ b/enterprise-dashboard-accessibility-guard/reports/summary.svg @@ -7,7 +7,7 @@ enterprise-admin-overview - hold_accessibility_release | findings 8 | digest 99f76262882d98d0 + hold_accessibility_release | findings 9 | digest 3a92697e16f9be41 diff --git a/enterprise-dashboard-accessibility-guard/requirements-map.md b/enterprise-dashboard-accessibility-guard/requirements-map.md index a3c4fe75..a1f044d7 100644 --- a/enterprise-dashboard-accessibility-guard/requirements-map.md +++ b/enterprise-dashboard-accessibility-guard/requirements-map.md @@ -5,7 +5,7 @@ Issue #19 asks for enterprise tooling around admin dashboards, API and webhook i | Issue Area | This Slice | | --- | --- | | Admin dashboards | Gates institutional dashboard widgets before release to admins. | -| Contributor and usage analytics | Checks that critical and noncritical metrics are perceivable, labeled, keyboard reachable, and safe for nonvisual users. | +| Contributor and usage analytics | Checks that critical and noncritical metrics are perceivable, use valid contrast evidence, are labeled, keyboard reachable, and safe for nonvisual users. | | Compliance tracking | Produces WCAG-oriented readiness signals and deterministic audit evidence for institutional governance. | | Export pipelines | Blocks scheduled exports when tables lack summaries or dashboard views are not accessible enough for release. | | Webhook support | Keeps webhook notices internal-only when the dashboard state has nonblocking accessibility warnings. | diff --git a/enterprise-dashboard-accessibility-guard/sample-data.js b/enterprise-dashboard-accessibility-guard/sample-data.js index 3c9e103e..c877af89 100644 --- a/enterprise-dashboard-accessibility-guard/sample-data.js +++ b/enterprise-dashboard-accessibility-guard/sample-data.js @@ -15,6 +15,17 @@ const blockedDashboard = { ariaTextContainsPrivateData: true, headingLevel: 2 }, + { + id: 'contract-risk-score', + type: 'metric', + title: 'Contract risk score', + foreground: 'var(--metric-danger)', + background: '#ffffff', + critical: true, + keyboardReachable: true, + screenReaderLabel: 'Contract risk score across departments', + headingLevel: 2 + }, { id: 'private-project-table', type: 'table', diff --git a/enterprise-dashboard-accessibility-guard/test.js b/enterprise-dashboard-accessibility-guard/test.js index 734d7137..2e09b03b 100644 --- a/enterprise-dashboard-accessibility-guard/test.js +++ b/enterprise-dashboard-accessibility-guard/test.js @@ -117,12 +117,78 @@ function testPrivateDataInTableSummaryBlocksRelease() { assert.ok(packet.actions.includes('redact_accessibility_text:private-summary-table')); } +function testInvalidContrastEvidenceBlocksRelease() { + const packet = assessDashboardRelease({ + dashboardId: 'enterprise-admin-invalid-contrast-evidence', + institutionId: 'institution-redacted', + assessedAt: '2026-05-27T13:15:00Z', + widgets: [ + { + id: 'contract-risk-score', + type: 'metric', + title: 'Contract risk score', + foreground: 'var(--metric-danger)', + background: '#ffffff', + critical: true, + keyboardReachable: true, + screenReaderLabel: 'Contract risk score across departments', + headingLevel: 2 + } + ], + alerts: [], + exports: [], + motion: { + animatedCharts: [], + reducedMotionFallback: true + } + }); + + assert.equal(packet.status, 'hold_accessibility_release'); + assert.equal(packet.releaseLanes.adminDashboard, 'blocked'); + assert.deepEqual(codes(packet), ['INVALID_CONTRAST_EVIDENCE']); + assert.equal(packet.wcagSignals.perceivable, false); + assert.ok(packet.actions.includes('provide_valid_contrast_evidence:contract-risk-score')); +} + +function testShorthandHexContrastEvidenceRemainsValid() { + const packet = assessDashboardRelease({ + dashboardId: 'enterprise-admin-shorthand-contrast', + institutionId: 'institution-redacted', + assessedAt: '2026-05-27T13:20:00Z', + widgets: [ + { + id: 'repository-sync-status', + type: 'metric', + title: 'Repository sync status', + foreground: '#000', + background: '#fff', + critical: true, + keyboardReachable: true, + screenReaderLabel: 'Repository sync status across departments', + headingLevel: 2 + } + ], + alerts: [], + exports: [], + motion: { + animatedCharts: [], + reducedMotionFallback: true + } + }); + + assert.equal(packet.status, 'release_with_accessibility_monitoring'); + assert.deepEqual(packet.findings, []); + assert.equal(packet.wcagSignals.perceivable, true); +} + const tests = [ testCriticalAccessibilityIssuesBlockDashboardRelease, testCleanDashboardReleasesWithWcagSignals, testWarningsAllowInternalOnlyPreview, testNonCriticalLowContrastRequiresRemediationBeforeRelease, - testPrivateDataInTableSummaryBlocksRelease + testPrivateDataInTableSummaryBlocksRelease, + testInvalidContrastEvidenceBlocksRelease, + testShorthandHexContrastEvidenceRemainsValid ]; for (const test of tests) { From 69c962db436c428e04e13aefd694a091c8682f68 Mon Sep 17 00:00:00 2001 From: KoiosSG Date: Sat, 30 May 2026 02:11:32 +0200 Subject: [PATCH 05/12] Require visible dashboard focus indicators --- .../README.md | 1 + .../acceptance-notes.md | 1 + .../index.js | 12 +++++- .../reports/accessibility-report.md | 2 +- .../reports/blocked-packet.json | 9 ++++- .../reports/summary.svg | 2 +- .../requirements-map.md | 2 +- .../sample-data.js | 1 + .../test.js | 37 ++++++++++++++++++- 9 files changed, 61 insertions(+), 6 deletions(-) diff --git a/enterprise-dashboard-accessibility-guard/README.md b/enterprise-dashboard-accessibility-guard/README.md index be51126b..b6dd914e 100644 --- a/enterprise-dashboard-accessibility-guard/README.md +++ b/enterprise-dashboard-accessibility-guard/README.md @@ -10,6 +10,7 @@ This module evaluates institutional admin dashboard releases before they are sho - Invalid or unparseable contrast evidence, including unresolved CSS color tokens - Missing screen-reader labels - Keyboard reachability and focus traps +- Missing visible focus indicators for keyboard-reachable dashboard controls - Private user or project data embedded in screen-reader labels, table summaries, or export summaries - Missing table and export summaries - Heading-order skips diff --git a/enterprise-dashboard-accessibility-guard/acceptance-notes.md b/enterprise-dashboard-accessibility-guard/acceptance-notes.md index b427242e..1195746b 100644 --- a/enterprise-dashboard-accessibility-guard/acceptance-notes.md +++ b/enterprise-dashboard-accessibility-guard/acceptance-notes.md @@ -6,6 +6,7 @@ - Covers blocked, clean, and warning-only dashboard states with tests. - Treats noncritical low-contrast content as a remediation warning before public release. - Blocks release when dashboard contrast evidence is invalid or still expressed as unresolved CSS color tokens. +- Blocks release when keyboard-reachable dashboard controls suppress visible focus indicators. - Blocks release when private data appears in table or export accessibility summaries. - Generates reviewer artifacts: - `reports/blocked-packet.json` diff --git a/enterprise-dashboard-accessibility-guard/index.js b/enterprise-dashboard-accessibility-guard/index.js index 89aa90b4..79f090af 100644 --- a/enterprise-dashboard-accessibility-guard/index.js +++ b/enterprise-dashboard-accessibility-guard/index.js @@ -66,6 +66,10 @@ function assessVisualAndOperableComponents(dashboard) { findings.push(finding(component, 'KEYBOARD_TRAP', 'blocker', 'Keyboard users cannot reach or leave this component predictably.')); } + if (component.keyboardReachable !== false && component.focusVisible === false) { + findings.push(finding(component, 'MISSING_VISIBLE_FOCUS_INDICATOR', 'blocker', 'Keyboard users need a visible focus indicator on reachable dashboard controls.')); + } + if (component.ariaTextContainsPrivateData || containsPrivateData(accessibilityText(component))) { findings.push(finding(component, 'PRIVATE_DATA_IN_ACCESSIBILITY_TEXT', 'blocker', 'Accessibility text exposes private user, lab, or project data.')); } @@ -159,6 +163,9 @@ function buildActions(dashboard, findings) { if (item.code === 'MISSING_SCREEN_READER_LABEL') { actions.add(`add_screen_reader_label:${item.componentId}`); } + if (item.code === 'MISSING_VISIBLE_FOCUS_INDICATOR') { + actions.add(`add_visible_focus_indicator:${item.componentId}`); + } if ( item.code === 'LOW_CONTRAST_CRITICAL_METRIC' || item.code === 'LOW_CONTRAST_NONCRITICAL_METRIC' @@ -184,7 +191,10 @@ function buildWcagSignals(findings) { !codes.has('LOW_CONTRAST_CRITICAL_METRIC') && !codes.has('LOW_CONTRAST_NONCRITICAL_METRIC') && !codes.has('MISSING_TABLE_SUMMARY'), - operable: !codes.has('KEYBOARD_TRAP') && !codes.has('MISSING_REDUCED_MOTION_FALLBACK'), + operable: + !codes.has('KEYBOARD_TRAP') && + !codes.has('MISSING_REDUCED_MOTION_FALLBACK') && + !codes.has('MISSING_VISIBLE_FOCUS_INDICATOR'), understandable: !codes.has('PRIVATE_DATA_IN_ACCESSIBILITY_TEXT') && !codes.has('HEADING_ORDER_SKIP'), robust: !codes.has('MISSING_SCREEN_READER_LABEL') }; diff --git a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md index 944c8c26..208c7d61 100644 --- a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md +++ b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md @@ -2,7 +2,7 @@ | Packet | Status | Dashboard | Export | Webhook | Findings | | --- | --- | --- | --- | --- | --- | -| blocked-packet.json | hold_accessibility_release | blocked | blocked | blocked | PRIVATE_DATA_IN_ACCESSIBILITY_TEXT, INVALID_CONTRAST_EVIDENCE, MISSING_SCREEN_READER_LABEL, KEYBOARD_TRAP, MISSING_TABLE_SUMMARY, LOW_CONTRAST_CRITICAL_METRIC, MISSING_TABLE_SUMMARY, HEADING_ORDER_SKIP, MISSING_REDUCED_MOTION_FALLBACK | +| blocked-packet.json | hold_accessibility_release | blocked | blocked | blocked | MISSING_VISIBLE_FOCUS_INDICATOR, PRIVATE_DATA_IN_ACCESSIBILITY_TEXT, INVALID_CONTRAST_EVIDENCE, MISSING_SCREEN_READER_LABEL, KEYBOARD_TRAP, MISSING_TABLE_SUMMARY, LOW_CONTRAST_CRITICAL_METRIC, MISSING_TABLE_SUMMARY, HEADING_ORDER_SKIP, MISSING_REDUCED_MOTION_FALLBACK | | clean-packet.json | release_with_accessibility_monitoring | allowed | allowed | allowed | none | | warning-packet.json | remediate_before_public_release | internal_only | blocked | internal_only | MISSING_REDUCED_MOTION_FALLBACK | diff --git a/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json b/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json index 01d4c08a..f9688c3f 100644 --- a/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json +++ b/enterprise-dashboard-accessibility-guard/reports/blocked-packet.json @@ -8,6 +8,12 @@ "webhookNotice": "blocked" }, "findings": [ + { + "componentId": "compute-usage-critical", + "code": "MISSING_VISIBLE_FOCUS_INDICATOR", + "severity": "blocker", + "message": "Keyboard users need a visible focus indicator on reachable dashboard controls." + }, { "componentId": "compute-usage-critical", "code": "PRIVATE_DATA_IN_ACCESSIBILITY_TEXT", @@ -68,6 +74,7 @@ "add_screen_reader_label:private-project-table", "add_table_summary:private-project-table", "add_table_summary:weekly-admin-export", + "add_visible_focus_indicator:compute-usage-critical", "block_release:enterprise-admin-overview", "improve_contrast:webhook-failure-alert", "provide_valid_contrast_evidence:contract-risk-score", @@ -80,5 +87,5 @@ "robust": false }, "assessedAt": "2026-05-27T13:00:00Z", - "auditDigest": "3a92697e16f9be41158da60c1f880d443a67a58d6e367fa94882fe8874f69864" + "auditDigest": "54a2b80eea438f90254991c20ca827636fa16789c652fbef6309e56662e55253" } diff --git a/enterprise-dashboard-accessibility-guard/reports/summary.svg b/enterprise-dashboard-accessibility-guard/reports/summary.svg index 1c0a3e4a..4c46c25a 100644 --- a/enterprise-dashboard-accessibility-guard/reports/summary.svg +++ b/enterprise-dashboard-accessibility-guard/reports/summary.svg @@ -7,7 +7,7 @@ enterprise-admin-overview - hold_accessibility_release | findings 9 | digest 3a92697e16f9be41 + hold_accessibility_release | findings 10 | digest 54a2b80eea438f90 diff --git a/enterprise-dashboard-accessibility-guard/requirements-map.md b/enterprise-dashboard-accessibility-guard/requirements-map.md index a1f044d7..54ed8ab7 100644 --- a/enterprise-dashboard-accessibility-guard/requirements-map.md +++ b/enterprise-dashboard-accessibility-guard/requirements-map.md @@ -5,7 +5,7 @@ Issue #19 asks for enterprise tooling around admin dashboards, API and webhook i | Issue Area | This Slice | | --- | --- | | Admin dashboards | Gates institutional dashboard widgets before release to admins. | -| Contributor and usage analytics | Checks that critical and noncritical metrics are perceivable, use valid contrast evidence, are labeled, keyboard reachable, and safe for nonvisual users. | +| Contributor and usage analytics | Checks that critical and noncritical metrics are perceivable, use valid contrast evidence, are labeled, keyboard reachable with visible focus indicators, and safe for nonvisual users. | | Compliance tracking | Produces WCAG-oriented readiness signals and deterministic audit evidence for institutional governance. | | Export pipelines | Blocks scheduled exports when tables lack summaries or dashboard views are not accessible enough for release. | | Webhook support | Keeps webhook notices internal-only when the dashboard state has nonblocking accessibility warnings. | diff --git a/enterprise-dashboard-accessibility-guard/sample-data.js b/enterprise-dashboard-accessibility-guard/sample-data.js index c877af89..b2846012 100644 --- a/enterprise-dashboard-accessibility-guard/sample-data.js +++ b/enterprise-dashboard-accessibility-guard/sample-data.js @@ -11,6 +11,7 @@ const blockedDashboard = { background: '#f8fafc', critical: true, keyboardReachable: true, + focusVisible: false, screenReaderLabel: 'Compute usage for private lab alice@example.edu', ariaTextContainsPrivateData: true, headingLevel: 2 diff --git a/enterprise-dashboard-accessibility-guard/test.js b/enterprise-dashboard-accessibility-guard/test.js index 2e09b03b..800c929d 100644 --- a/enterprise-dashboard-accessibility-guard/test.js +++ b/enterprise-dashboard-accessibility-guard/test.js @@ -181,6 +181,40 @@ function testShorthandHexContrastEvidenceRemainsValid() { assert.equal(packet.wcagSignals.perceivable, true); } +function testMissingVisibleFocusIndicatorBlocksKeyboardRelease() { + const packet = assessDashboardRelease({ + dashboardId: 'enterprise-admin-hidden-focus', + institutionId: 'institution-redacted', + assessedAt: '2026-05-27T13:25:00Z', + widgets: [ + { + id: 'project-risk-filter', + type: 'filter', + title: 'Project risk filter', + foreground: '#111827', + background: '#ffffff', + critical: true, + keyboardReachable: true, + focusVisible: false, + screenReaderLabel: 'Filter projects by risk status', + headingLevel: 2 + } + ], + alerts: [], + exports: [], + motion: { + animatedCharts: [], + reducedMotionFallback: true + } + }); + + assert.equal(packet.status, 'hold_accessibility_release'); + assert.equal(packet.releaseLanes.adminDashboard, 'blocked'); + assert.deepEqual(codes(packet), ['MISSING_VISIBLE_FOCUS_INDICATOR']); + assert.equal(packet.wcagSignals.operable, false); + assert.ok(packet.actions.includes('add_visible_focus_indicator:project-risk-filter')); +} + const tests = [ testCriticalAccessibilityIssuesBlockDashboardRelease, testCleanDashboardReleasesWithWcagSignals, @@ -188,7 +222,8 @@ const tests = [ testNonCriticalLowContrastRequiresRemediationBeforeRelease, testPrivateDataInTableSummaryBlocksRelease, testInvalidContrastEvidenceBlocksRelease, - testShorthandHexContrastEvidenceRemainsValid + testShorthandHexContrastEvidenceRemainsValid, + testMissingVisibleFocusIndicatorBlocksKeyboardRelease ]; for (const test of tests) { From 13606f964ce81080385f2c49eba00ac962a91b90 Mon Sep 17 00:00:00 2001 From: KoiosSG Date: Sat, 30 May 2026 10:40:46 +0200 Subject: [PATCH 06/12] Block missing critical contrast evidence --- .../README.md | 2 +- .../acceptance-notes.md | 3 +- .../demo.js | 12 +++++-- .../index.js | 9 +++++- .../reports/accessibility-report.md | 1 + .../reports/missing-contrast-packet.json | 30 +++++++++++++++++ .../reports/summary.svg | 12 +++++-- .../requirements-map.md | 2 +- .../sample-data.js | 26 ++++++++++++++- .../test.js | 32 +++++++++++++++++++ 10 files changed, 118 insertions(+), 11 deletions(-) create mode 100644 enterprise-dashboard-accessibility-guard/reports/missing-contrast-packet.json diff --git a/enterprise-dashboard-accessibility-guard/README.md b/enterprise-dashboard-accessibility-guard/README.md index b6dd914e..868665ad 100644 --- a/enterprise-dashboard-accessibility-guard/README.md +++ b/enterprise-dashboard-accessibility-guard/README.md @@ -7,7 +7,7 @@ This module evaluates institutional admin dashboard releases before they are sho ## What It Checks - Critical metric color contrast and warning-level contrast checks for noncritical content -- Invalid or unparseable contrast evidence, including unresolved CSS color tokens +- Missing, invalid, or unparseable contrast evidence, including unresolved CSS color tokens - Missing screen-reader labels - Keyboard reachability and focus traps - Missing visible focus indicators for keyboard-reachable dashboard controls diff --git a/enterprise-dashboard-accessibility-guard/acceptance-notes.md b/enterprise-dashboard-accessibility-guard/acceptance-notes.md index 1195746b..0b8b6355 100644 --- a/enterprise-dashboard-accessibility-guard/acceptance-notes.md +++ b/enterprise-dashboard-accessibility-guard/acceptance-notes.md @@ -5,11 +5,12 @@ - Uses dependency-free Node.js logic for deterministic dashboard release decisions. - Covers blocked, clean, and warning-only dashboard states with tests. - Treats noncritical low-contrast content as a remediation warning before public release. -- Blocks release when dashboard contrast evidence is invalid or still expressed as unresolved CSS color tokens. +- Blocks release when critical dashboard contrast evidence is missing, invalid, or still expressed as unresolved CSS color tokens. - Blocks release when keyboard-reachable dashboard controls suppress visible focus indicators. - Blocks release when private data appears in table or export accessibility summaries. - Generates reviewer artifacts: - `reports/blocked-packet.json` + - `reports/missing-contrast-packet.json` - `reports/clean-packet.json` - `reports/warning-packet.json` - `reports/accessibility-report.md` diff --git a/enterprise-dashboard-accessibility-guard/demo.js b/enterprise-dashboard-accessibility-guard/demo.js index 36656709..133674ca 100644 --- a/enterprise-dashboard-accessibility-guard/demo.js +++ b/enterprise-dashboard-accessibility-guard/demo.js @@ -2,13 +2,19 @@ const fs = require('fs'); const path = require('path'); const { assessDashboardRelease } = require('./index'); -const { blockedDashboard, cleanDashboard, warningDashboard } = require('./sample-data'); +const { + blockedDashboard, + cleanDashboard, + warningDashboard, + missingContrastDashboard +} = require('./sample-data'); const reportsDir = path.join(__dirname, 'reports'); fs.mkdirSync(reportsDir, { recursive: true }); const packets = [ ['blocked-packet.json', assessDashboardRelease(blockedDashboard)], + ['missing-contrast-packet.json', assessDashboardRelease(missingContrastDashboard)], ['clean-packet.json', assessDashboardRelease(cleanDashboard)], ['warning-packet.json', assessDashboardRelease(warningDashboard)] ]; @@ -62,8 +68,8 @@ function renderSvg(packetRows) { }).join(''); return [ - '', - ' ', + '', + ' ', ' Enterprise Dashboard Accessibility Guard', ' Institutional dashboards, exports, and webhook notices are gated before release.', rows, diff --git a/enterprise-dashboard-accessibility-guard/index.js b/enterprise-dashboard-accessibility-guard/index.js index 79f090af..acfa7977 100644 --- a/enterprise-dashboard-accessibility-guard/index.js +++ b/enterprise-dashboard-accessibility-guard/index.js @@ -32,7 +32,14 @@ function assessVisualAndOperableComponents(dashboard) { const findings = []; for (const component of components) { - if (component.foreground && component.background) { + if (component.critical && (!component.foreground || !component.background)) { + findings.push(finding( + component, + 'INVALID_CONTRAST_EVIDENCE', + 'blocker', + 'Critical component color contrast evidence must include foreground and background hex values before dashboard release.' + )); + } else if (component.foreground && component.background) { const contrast = contrastRatio(component.foreground, component.background); if (contrast === null) { findings.push(finding( diff --git a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md index 208c7d61..2f645d80 100644 --- a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md +++ b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md @@ -3,6 +3,7 @@ | Packet | Status | Dashboard | Export | Webhook | Findings | | --- | --- | --- | --- | --- | --- | | blocked-packet.json | hold_accessibility_release | blocked | blocked | blocked | MISSING_VISIBLE_FOCUS_INDICATOR, PRIVATE_DATA_IN_ACCESSIBILITY_TEXT, INVALID_CONTRAST_EVIDENCE, MISSING_SCREEN_READER_LABEL, KEYBOARD_TRAP, MISSING_TABLE_SUMMARY, LOW_CONTRAST_CRITICAL_METRIC, MISSING_TABLE_SUMMARY, HEADING_ORDER_SKIP, MISSING_REDUCED_MOTION_FALLBACK | +| missing-contrast-packet.json | hold_accessibility_release | blocked | blocked | blocked | INVALID_CONTRAST_EVIDENCE | | clean-packet.json | release_with_accessibility_monitoring | allowed | allowed | allowed | none | | warning-packet.json | remediate_before_public_release | internal_only | blocked | internal_only | MISSING_REDUCED_MOTION_FALLBACK | diff --git a/enterprise-dashboard-accessibility-guard/reports/missing-contrast-packet.json b/enterprise-dashboard-accessibility-guard/reports/missing-contrast-packet.json new file mode 100644 index 00000000..13e86dd3 --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/reports/missing-contrast-packet.json @@ -0,0 +1,30 @@ +{ + "dashboardId": "enterprise-admin-missing-contrast-evidence", + "institutionId": "institution-redacted", + "status": "hold_accessibility_release", + "releaseLanes": { + "adminDashboard": "blocked", + "scheduledExport": "blocked", + "webhookNotice": "blocked" + }, + "findings": [ + { + "componentId": "contract-risk-without-colors", + "code": "INVALID_CONTRAST_EVIDENCE", + "severity": "blocker", + "message": "Critical component color contrast evidence must include foreground and background hex values before dashboard release." + } + ], + "actions": [ + "block_release:enterprise-admin-missing-contrast-evidence", + "provide_valid_contrast_evidence:contract-risk-without-colors" + ], + "wcagSignals": { + "perceivable": false, + "operable": true, + "understandable": true, + "robust": true + }, + "assessedAt": "2026-05-27T13:17:00Z", + "auditDigest": "1d62d0b424cfe9c0ebbe8c9effdc876399ca66b04e13d2df5f6d6f7f91eff442" +} diff --git a/enterprise-dashboard-accessibility-guard/reports/summary.svg b/enterprise-dashboard-accessibility-guard/reports/summary.svg index 4c46c25a..e4c9ae46 100644 --- a/enterprise-dashboard-accessibility-guard/reports/summary.svg +++ b/enterprise-dashboard-accessibility-guard/reports/summary.svg @@ -1,5 +1,5 @@ - - + + Enterprise Dashboard Accessibility Guard Institutional dashboards, exports, and webhook notices are gated before release. @@ -10,12 +10,18 @@ hold_accessibility_release | findings 10 | digest 54a2b80eea438f90 + + + enterprise-admin-missing-contrast-evidence + hold_accessibility_release | findings 1 | digest 1d62d0b424cfe9c0 + + enterprise-admin-clean release_with_accessibility_monitoring | findings 0 | digest e3abe7a1521f5654 - + enterprise-admin-motion-warning diff --git a/enterprise-dashboard-accessibility-guard/requirements-map.md b/enterprise-dashboard-accessibility-guard/requirements-map.md index 54ed8ab7..b0961fcb 100644 --- a/enterprise-dashboard-accessibility-guard/requirements-map.md +++ b/enterprise-dashboard-accessibility-guard/requirements-map.md @@ -5,7 +5,7 @@ Issue #19 asks for enterprise tooling around admin dashboards, API and webhook i | Issue Area | This Slice | | --- | --- | | Admin dashboards | Gates institutional dashboard widgets before release to admins. | -| Contributor and usage analytics | Checks that critical and noncritical metrics are perceivable, use valid contrast evidence, are labeled, keyboard reachable with visible focus indicators, and safe for nonvisual users. | +| Contributor and usage analytics | Checks that critical and noncritical metrics are perceivable, include required contrast evidence, use valid contrast evidence, are labeled, keyboard reachable with visible focus indicators, and safe for nonvisual users. | | Compliance tracking | Produces WCAG-oriented readiness signals and deterministic audit evidence for institutional governance. | | Export pipelines | Blocks scheduled exports when tables lack summaries or dashboard views are not accessible enough for release. | | Webhook support | Keeps webhook notices internal-only when the dashboard state has nonblocking accessibility warnings. | diff --git a/enterprise-dashboard-accessibility-guard/sample-data.js b/enterprise-dashboard-accessibility-guard/sample-data.js index b2846012..4877e019 100644 --- a/enterprise-dashboard-accessibility-guard/sample-data.js +++ b/enterprise-dashboard-accessibility-guard/sample-data.js @@ -154,8 +154,32 @@ const warningDashboard = { } }; +const missingContrastDashboard = { + dashboardId: 'enterprise-admin-missing-contrast-evidence', + institutionId: 'institution-redacted', + assessedAt: '2026-05-27T13:17:00Z', + widgets: [ + { + id: 'contract-risk-without-colors', + type: 'metric', + title: 'Contract risk score', + critical: true, + keyboardReachable: true, + screenReaderLabel: 'Contract risk score across departments', + headingLevel: 2 + } + ], + alerts: [], + exports: [], + motion: { + animatedCharts: [], + reducedMotionFallback: true + } +}; + module.exports = { blockedDashboard, cleanDashboard, - warningDashboard + warningDashboard, + missingContrastDashboard }; diff --git a/enterprise-dashboard-accessibility-guard/test.js b/enterprise-dashboard-accessibility-guard/test.js index 800c929d..92b81922 100644 --- a/enterprise-dashboard-accessibility-guard/test.js +++ b/enterprise-dashboard-accessibility-guard/test.js @@ -150,6 +150,37 @@ function testInvalidContrastEvidenceBlocksRelease() { assert.ok(packet.actions.includes('provide_valid_contrast_evidence:contract-risk-score')); } +function testMissingCriticalContrastEvidenceBlocksRelease() { + const packet = assessDashboardRelease({ + dashboardId: 'enterprise-admin-missing-contrast-evidence', + institutionId: 'institution-redacted', + assessedAt: '2026-05-27T13:17:00Z', + widgets: [ + { + id: 'contract-risk-without-colors', + type: 'metric', + title: 'Contract risk score', + critical: true, + keyboardReachable: true, + screenReaderLabel: 'Contract risk score across departments', + headingLevel: 2 + } + ], + alerts: [], + exports: [], + motion: { + animatedCharts: [], + reducedMotionFallback: true + } + }); + + assert.equal(packet.status, 'hold_accessibility_release'); + assert.equal(packet.releaseLanes.adminDashboard, 'blocked'); + assert.deepEqual(codes(packet), ['INVALID_CONTRAST_EVIDENCE']); + assert.equal(packet.wcagSignals.perceivable, false); + assert.ok(packet.actions.includes('provide_valid_contrast_evidence:contract-risk-without-colors')); +} + function testShorthandHexContrastEvidenceRemainsValid() { const packet = assessDashboardRelease({ dashboardId: 'enterprise-admin-shorthand-contrast', @@ -222,6 +253,7 @@ const tests = [ testNonCriticalLowContrastRequiresRemediationBeforeRelease, testPrivateDataInTableSummaryBlocksRelease, testInvalidContrastEvidenceBlocksRelease, + testMissingCriticalContrastEvidenceBlocksRelease, testShorthandHexContrastEvidenceRemainsValid, testMissingVisibleFocusIndicatorBlocksKeyboardRelease ]; From 0a193d204528ff5f4e1d98791a25b12c6023df60 Mon Sep 17 00:00:00 2001 From: KoiosSG Date: Sat, 30 May 2026 15:08:26 +0200 Subject: [PATCH 07/12] Warn on missing noncritical contrast evidence --- .../README.md | 2 +- .../acceptance-notes.md | 2 ++ .../demo.js | 9 +++-- .../index.js | 11 ++++++ .../reports/accessibility-report.md | 1 + .../missing-noncritical-contrast-packet.json | 29 ++++++++++++++++ .../reports/summary.svg | 12 +++++-- .../requirements-map.md | 2 +- .../sample-data.js | 26 +++++++++++++- .../test.js | 34 +++++++++++++++++++ 10 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 enterprise-dashboard-accessibility-guard/reports/missing-noncritical-contrast-packet.json diff --git a/enterprise-dashboard-accessibility-guard/README.md b/enterprise-dashboard-accessibility-guard/README.md index 868665ad..7a5b419e 100644 --- a/enterprise-dashboard-accessibility-guard/README.md +++ b/enterprise-dashboard-accessibility-guard/README.md @@ -7,7 +7,7 @@ This module evaluates institutional admin dashboard releases before they are sho ## What It Checks - Critical metric color contrast and warning-level contrast checks for noncritical content -- Missing, invalid, or unparseable contrast evidence, including unresolved CSS color tokens +- Missing, invalid, or unparseable contrast evidence, including unresolved CSS color tokens and noncritical missing contrast evidence - Missing screen-reader labels - Keyboard reachability and focus traps - Missing visible focus indicators for keyboard-reachable dashboard controls diff --git a/enterprise-dashboard-accessibility-guard/acceptance-notes.md b/enterprise-dashboard-accessibility-guard/acceptance-notes.md index 0b8b6355..c9e37f4e 100644 --- a/enterprise-dashboard-accessibility-guard/acceptance-notes.md +++ b/enterprise-dashboard-accessibility-guard/acceptance-notes.md @@ -6,11 +6,13 @@ - Covers blocked, clean, and warning-only dashboard states with tests. - Treats noncritical low-contrast content as a remediation warning before public release. - Blocks release when critical dashboard contrast evidence is missing, invalid, or still expressed as unresolved CSS color tokens. +- Treats missing noncritical dashboard contrast evidence as a remediation warning before public release. - Blocks release when keyboard-reachable dashboard controls suppress visible focus indicators. - Blocks release when private data appears in table or export accessibility summaries. - Generates reviewer artifacts: - `reports/blocked-packet.json` - `reports/missing-contrast-packet.json` + - `reports/missing-noncritical-contrast-packet.json` - `reports/clean-packet.json` - `reports/warning-packet.json` - `reports/accessibility-report.md` diff --git a/enterprise-dashboard-accessibility-guard/demo.js b/enterprise-dashboard-accessibility-guard/demo.js index 133674ca..6831e647 100644 --- a/enterprise-dashboard-accessibility-guard/demo.js +++ b/enterprise-dashboard-accessibility-guard/demo.js @@ -6,7 +6,8 @@ const { blockedDashboard, cleanDashboard, warningDashboard, - missingContrastDashboard + missingContrastDashboard, + missingNoncriticalContrastDashboard } = require('./sample-data'); const reportsDir = path.join(__dirname, 'reports'); @@ -15,6 +16,7 @@ fs.mkdirSync(reportsDir, { recursive: true }); const packets = [ ['blocked-packet.json', assessDashboardRelease(blockedDashboard)], ['missing-contrast-packet.json', assessDashboardRelease(missingContrastDashboard)], + ['missing-noncritical-contrast-packet.json', assessDashboardRelease(missingNoncriticalContrastDashboard)], ['clean-packet.json', assessDashboardRelease(cleanDashboard)], ['warning-packet.json', assessDashboardRelease(warningDashboard)] ]; @@ -55,6 +57,7 @@ function renderMarkdown(packetRows) { } function renderSvg(packetRows) { + const height = 108 + packetRows.length * 72 + 36; const rows = packetRows.map(([, packet], index) => { const y = 105 + index * 72; const color = packet.status === 'hold_accessibility_release' ? '#dc2626' : packet.status === 'remediate_before_public_release' ? '#d97706' : '#16a34a'; @@ -68,8 +71,8 @@ function renderSvg(packetRows) { }).join(''); return [ - '', - ' ', + ``, + ` `, ' Enterprise Dashboard Accessibility Guard', ' Institutional dashboards, exports, and webhook notices are gated before release.', rows, diff --git a/enterprise-dashboard-accessibility-guard/index.js b/enterprise-dashboard-accessibility-guard/index.js index acfa7977..d3cbaf7b 100644 --- a/enterprise-dashboard-accessibility-guard/index.js +++ b/enterprise-dashboard-accessibility-guard/index.js @@ -39,6 +39,13 @@ function assessVisualAndOperableComponents(dashboard) { 'blocker', 'Critical component color contrast evidence must include foreground and background hex values before dashboard release.' )); + } else if (requiresContrastEvidence(component) && (!component.foreground || !component.background)) { + findings.push(finding( + component, + 'INVALID_CONTRAST_EVIDENCE', + 'warning', + 'Noncritical dashboard component contrast evidence should include foreground and background hex values before public release.' + )); } else if (component.foreground && component.background) { const contrast = contrastRatio(component.foreground, component.background); if (contrast === null) { @@ -90,6 +97,10 @@ function assessVisualAndOperableComponents(dashboard) { return findings; } +function requiresContrastEvidence(component) { + return Boolean(component.type || component.title || component.foreground || component.background); +} + function assessHeadingOrder(components) { const findings = []; let previousLevel = null; diff --git a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md index 2f645d80..1bb0f39e 100644 --- a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md +++ b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md @@ -4,6 +4,7 @@ | --- | --- | --- | --- | --- | --- | | blocked-packet.json | hold_accessibility_release | blocked | blocked | blocked | MISSING_VISIBLE_FOCUS_INDICATOR, PRIVATE_DATA_IN_ACCESSIBILITY_TEXT, INVALID_CONTRAST_EVIDENCE, MISSING_SCREEN_READER_LABEL, KEYBOARD_TRAP, MISSING_TABLE_SUMMARY, LOW_CONTRAST_CRITICAL_METRIC, MISSING_TABLE_SUMMARY, HEADING_ORDER_SKIP, MISSING_REDUCED_MOTION_FALLBACK | | missing-contrast-packet.json | hold_accessibility_release | blocked | blocked | blocked | INVALID_CONTRAST_EVIDENCE | +| missing-noncritical-contrast-packet.json | remediate_before_public_release | internal_only | blocked | internal_only | INVALID_CONTRAST_EVIDENCE | | clean-packet.json | release_with_accessibility_monitoring | allowed | allowed | allowed | none | | warning-packet.json | remediate_before_public_release | internal_only | blocked | internal_only | MISSING_REDUCED_MOTION_FALLBACK | diff --git a/enterprise-dashboard-accessibility-guard/reports/missing-noncritical-contrast-packet.json b/enterprise-dashboard-accessibility-guard/reports/missing-noncritical-contrast-packet.json new file mode 100644 index 00000000..3027eb55 --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/reports/missing-noncritical-contrast-packet.json @@ -0,0 +1,29 @@ +{ + "dashboardId": "enterprise-admin-missing-secondary-contrast", + "institutionId": "institution-redacted", + "status": "remediate_before_public_release", + "releaseLanes": { + "adminDashboard": "internal_only", + "scheduledExport": "blocked", + "webhookNotice": "internal_only" + }, + "findings": [ + { + "componentId": "secondary-usage-trend-without-colors", + "code": "INVALID_CONTRAST_EVIDENCE", + "severity": "warning", + "message": "Noncritical dashboard component contrast evidence should include foreground and background hex values before public release." + } + ], + "actions": [ + "provide_valid_contrast_evidence:secondary-usage-trend-without-colors" + ], + "wcagSignals": { + "perceivable": false, + "operable": true, + "understandable": true, + "robust": true + }, + "assessedAt": "2026-05-30T15:25:00Z", + "auditDigest": "68bfb1e3df68d7733c886d880fc4c014e8f4040b5e47d09f37d2e9cf9589a14d" +} diff --git a/enterprise-dashboard-accessibility-guard/reports/summary.svg b/enterprise-dashboard-accessibility-guard/reports/summary.svg index e4c9ae46..7e41332d 100644 --- a/enterprise-dashboard-accessibility-guard/reports/summary.svg +++ b/enterprise-dashboard-accessibility-guard/reports/summary.svg @@ -1,5 +1,5 @@ - - + + Enterprise Dashboard Accessibility Guard Institutional dashboards, exports, and webhook notices are gated before release. @@ -16,12 +16,18 @@ hold_accessibility_release | findings 1 | digest 1d62d0b424cfe9c0 + + + enterprise-admin-missing-secondary-contrast + remediate_before_public_release | findings 1 | digest 68bfb1e3df68d773 + + enterprise-admin-clean release_with_accessibility_monitoring | findings 0 | digest e3abe7a1521f5654 - + enterprise-admin-motion-warning diff --git a/enterprise-dashboard-accessibility-guard/requirements-map.md b/enterprise-dashboard-accessibility-guard/requirements-map.md index b0961fcb..3e658879 100644 --- a/enterprise-dashboard-accessibility-guard/requirements-map.md +++ b/enterprise-dashboard-accessibility-guard/requirements-map.md @@ -5,7 +5,7 @@ Issue #19 asks for enterprise tooling around admin dashboards, API and webhook i | Issue Area | This Slice | | --- | --- | | Admin dashboards | Gates institutional dashboard widgets before release to admins. | -| Contributor and usage analytics | Checks that critical and noncritical metrics are perceivable, include required contrast evidence, use valid contrast evidence, are labeled, keyboard reachable with visible focus indicators, and safe for nonvisual users. | +| Contributor and usage analytics | Checks that critical and noncritical metrics are perceivable, include required contrast evidence, use valid contrast evidence, are labeled, keyboard reachable with visible focus indicators, and safe for nonvisual users. Missing noncritical contrast evidence now keeps public release in remediation instead of passing clean. | | Compliance tracking | Produces WCAG-oriented readiness signals and deterministic audit evidence for institutional governance. | | Export pipelines | Blocks scheduled exports when tables lack summaries or dashboard views are not accessible enough for release. | | Webhook support | Keeps webhook notices internal-only when the dashboard state has nonblocking accessibility warnings. | diff --git a/enterprise-dashboard-accessibility-guard/sample-data.js b/enterprise-dashboard-accessibility-guard/sample-data.js index 4877e019..55d36397 100644 --- a/enterprise-dashboard-accessibility-guard/sample-data.js +++ b/enterprise-dashboard-accessibility-guard/sample-data.js @@ -177,9 +177,33 @@ const missingContrastDashboard = { } }; +const missingNoncriticalContrastDashboard = { + dashboardId: 'enterprise-admin-missing-secondary-contrast', + institutionId: 'institution-redacted', + assessedAt: '2026-05-30T15:25:00Z', + widgets: [ + { + id: 'secondary-usage-trend-without-colors', + type: 'metric', + title: 'Storage usage trend', + critical: false, + keyboardReachable: true, + screenReaderLabel: 'Storage usage trend across departments', + headingLevel: 2 + } + ], + alerts: [], + exports: [], + motion: { + animatedCharts: [], + reducedMotionFallback: true + } +}; + module.exports = { blockedDashboard, cleanDashboard, warningDashboard, - missingContrastDashboard + missingContrastDashboard, + missingNoncriticalContrastDashboard }; diff --git a/enterprise-dashboard-accessibility-guard/test.js b/enterprise-dashboard-accessibility-guard/test.js index 92b81922..b4f32b6c 100644 --- a/enterprise-dashboard-accessibility-guard/test.js +++ b/enterprise-dashboard-accessibility-guard/test.js @@ -181,6 +181,39 @@ function testMissingCriticalContrastEvidenceBlocksRelease() { assert.ok(packet.actions.includes('provide_valid_contrast_evidence:contract-risk-without-colors')); } +function testMissingNoncriticalContrastEvidenceRequiresRemediation() { + const packet = assessDashboardRelease({ + dashboardId: 'enterprise-admin-missing-secondary-contrast', + institutionId: 'institution-redacted', + assessedAt: '2026-05-30T15:25:00Z', + widgets: [ + { + id: 'secondary-usage-trend-without-colors', + type: 'metric', + title: 'Storage usage trend', + critical: false, + keyboardReachable: true, + screenReaderLabel: 'Storage usage trend across departments', + headingLevel: 2 + } + ], + alerts: [], + exports: [], + motion: { + animatedCharts: [], + reducedMotionFallback: true + } + }); + + assert.equal(packet.status, 'remediate_before_public_release'); + assert.equal(packet.releaseLanes.adminDashboard, 'internal_only'); + assert.equal(packet.releaseLanes.scheduledExport, 'blocked'); + assert.equal(packet.releaseLanes.webhookNotice, 'internal_only'); + assert.deepEqual(codes(packet), ['INVALID_CONTRAST_EVIDENCE']); + assert.equal(packet.wcagSignals.perceivable, false); + assert.ok(packet.actions.includes('provide_valid_contrast_evidence:secondary-usage-trend-without-colors')); +} + function testShorthandHexContrastEvidenceRemainsValid() { const packet = assessDashboardRelease({ dashboardId: 'enterprise-admin-shorthand-contrast', @@ -254,6 +287,7 @@ const tests = [ testPrivateDataInTableSummaryBlocksRelease, testInvalidContrastEvidenceBlocksRelease, testMissingCriticalContrastEvidenceBlocksRelease, + testMissingNoncriticalContrastEvidenceRequiresRemediation, testShorthandHexContrastEvidenceRemainsValid, testMissingVisibleFocusIndicatorBlocksKeyboardRelease ]; From c2eae8446b2a63f17e00ff42fbe150bbce37dc99 Mon Sep 17 00:00:00 2001 From: KoiosSG Date: Sun, 31 May 2026 16:40:30 +0200 Subject: [PATCH 08/12] Harden malformed dashboard component evidence --- .../README.md | 1 + .../acceptance-notes.md | 2 + .../demo.js | 4 +- .../index.js | 48 +++++++++++++++--- .../make-demo-video.py | 10 ++++ .../reports/accessibility-report.md | 1 + .../reports/demo.mp4 | Bin 104275 -> 132119 bytes .../reports/malformed-component-packet.json | 30 +++++++++++ .../reports/summary.svg | 12 +++-- .../requirements-map.md | 2 +- .../sample-data.js | 16 +++++- .../test.js | 22 ++++++++ 12 files changed, 136 insertions(+), 12 deletions(-) create mode 100644 enterprise-dashboard-accessibility-guard/reports/malformed-component-packet.json diff --git a/enterprise-dashboard-accessibility-guard/README.md b/enterprise-dashboard-accessibility-guard/README.md index 7a5b419e..ad1c10b4 100644 --- a/enterprise-dashboard-accessibility-guard/README.md +++ b/enterprise-dashboard-accessibility-guard/README.md @@ -11,6 +11,7 @@ This module evaluates institutional admin dashboard releases before they are sho - Missing screen-reader labels - Keyboard reachability and focus traps - Missing visible focus indicators for keyboard-reachable dashboard controls +- Malformed dashboard component evidence that would otherwise crash release assessment - Private user or project data embedded in screen-reader labels, table summaries, or export summaries - Missing table and export summaries - Heading-order skips diff --git a/enterprise-dashboard-accessibility-guard/acceptance-notes.md b/enterprise-dashboard-accessibility-guard/acceptance-notes.md index c9e37f4e..bb83d75a 100644 --- a/enterprise-dashboard-accessibility-guard/acceptance-notes.md +++ b/enterprise-dashboard-accessibility-guard/acceptance-notes.md @@ -8,11 +8,13 @@ - Blocks release when critical dashboard contrast evidence is missing, invalid, or still expressed as unresolved CSS color tokens. - Treats missing noncritical dashboard contrast evidence as a remediation warning before public release. - Blocks release when keyboard-reachable dashboard controls suppress visible focus indicators. +- Blocks malformed dashboard component evidence before it can crash release assessment. - Blocks release when private data appears in table or export accessibility summaries. - Generates reviewer artifacts: - `reports/blocked-packet.json` - `reports/missing-contrast-packet.json` - `reports/missing-noncritical-contrast-packet.json` + - `reports/malformed-component-packet.json` - `reports/clean-packet.json` - `reports/warning-packet.json` - `reports/accessibility-report.md` diff --git a/enterprise-dashboard-accessibility-guard/demo.js b/enterprise-dashboard-accessibility-guard/demo.js index 6831e647..3fd1bc2c 100644 --- a/enterprise-dashboard-accessibility-guard/demo.js +++ b/enterprise-dashboard-accessibility-guard/demo.js @@ -7,7 +7,8 @@ const { cleanDashboard, warningDashboard, missingContrastDashboard, - missingNoncriticalContrastDashboard + missingNoncriticalContrastDashboard, + malformedComponentDashboard } = require('./sample-data'); const reportsDir = path.join(__dirname, 'reports'); @@ -17,6 +18,7 @@ const packets = [ ['blocked-packet.json', assessDashboardRelease(blockedDashboard)], ['missing-contrast-packet.json', assessDashboardRelease(missingContrastDashboard)], ['missing-noncritical-contrast-packet.json', assessDashboardRelease(missingNoncriticalContrastDashboard)], + ['malformed-component-packet.json', assessDashboardRelease(malformedComponentDashboard)], ['clean-packet.json', assessDashboardRelease(cleanDashboard)], ['warning-packet.json', assessDashboardRelease(warningDashboard)] ]; diff --git a/enterprise-dashboard-accessibility-guard/index.js b/enterprise-dashboard-accessibility-guard/index.js index d3cbaf7b..70b10d9c 100644 --- a/enterprise-dashboard-accessibility-guard/index.js +++ b/enterprise-dashboard-accessibility-guard/index.js @@ -24,12 +24,8 @@ function assessDashboardRelease(dashboard) { } function assessVisualAndOperableComponents(dashboard) { - const components = [ - ...(dashboard.widgets || []), - ...(dashboard.alerts || []), - ...(dashboard.exports || []) - ]; const findings = []; + const components = collectDashboardComponents(dashboard, findings); for (const component of components) { if (component.critical && (!component.foreground || !component.background)) { @@ -97,6 +93,43 @@ function assessVisualAndOperableComponents(dashboard) { return findings; } +function collectDashboardComponents(dashboard, findings) { + const groups = [ + ['widgets', dashboard.widgets], + ['alerts', dashboard.alerts], + ['exports', dashboard.exports] + ]; + const components = []; + + for (const [groupName, group] of groups) { + if (group == null) continue; + if (!Array.isArray(group)) { + findings.push({ + componentId: groupName, + code: 'MALFORMED_DASHBOARD_COMPONENT_ENTRY', + severity: 'blocker', + message: `Dashboard ${groupName} evidence must be an array of component objects before release.` + }); + continue; + } + + group.forEach((component, index) => { + if (!component || typeof component !== 'object' || Array.isArray(component)) { + findings.push({ + componentId: `${groupName}[${index}]`, + code: 'MALFORMED_DASHBOARD_COMPONENT_ENTRY', + severity: 'blocker', + message: 'Dashboard component evidence must be an object before accessibility release.' + }); + return; + } + components.push(component); + }); + } + + return components; +} + function requiresContrastEvidence(component) { return Boolean(component.type || component.title || component.foreground || component.background); } @@ -196,6 +229,9 @@ function buildActions(dashboard, findings) { if (item.code === 'PRIVATE_DATA_IN_ACCESSIBILITY_TEXT') { actions.add(`redact_accessibility_text:${item.componentId}`); } + if (item.code === 'MALFORMED_DASHBOARD_COMPONENT_ENTRY') { + actions.add(`repair_dashboard_component_evidence:${item.componentId}`); + } } return [...actions].sort(); @@ -214,7 +250,7 @@ function buildWcagSignals(findings) { !codes.has('MISSING_REDUCED_MOTION_FALLBACK') && !codes.has('MISSING_VISIBLE_FOCUS_INDICATOR'), understandable: !codes.has('PRIVATE_DATA_IN_ACCESSIBILITY_TEXT') && !codes.has('HEADING_ORDER_SKIP'), - robust: !codes.has('MISSING_SCREEN_READER_LABEL') + robust: !codes.has('MISSING_SCREEN_READER_LABEL') && !codes.has('MALFORMED_DASHBOARD_COMPONENT_ENTRY') }; } diff --git a/enterprise-dashboard-accessibility-guard/make-demo-video.py b/enterprise-dashboard-accessibility-guard/make-demo-video.py index 8f779777..32143ec0 100644 --- a/enterprise-dashboard-accessibility-guard/make-demo-video.py +++ b/enterprise-dashboard-accessibility-guard/make-demo-video.py @@ -68,6 +68,16 @@ def main(): "Keyboard traps and missing table summaries block dashboard and export release", ], ), + ( + "Malformed Evidence Hold", + "Reviewer packet instead of a crash", + "#f97316", + [ + "Malformed dashboard component entries become explicit blocker findings", + "Release lanes stay blocked until component evidence is repaired", + "Audit packet keeps deterministic remediation actions for maintainers", + ], + ), ( "Warning Release", "Internal-only until remediated", diff --git a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md index 1bb0f39e..35dc09e6 100644 --- a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md +++ b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md @@ -5,6 +5,7 @@ | blocked-packet.json | hold_accessibility_release | blocked | blocked | blocked | MISSING_VISIBLE_FOCUS_INDICATOR, PRIVATE_DATA_IN_ACCESSIBILITY_TEXT, INVALID_CONTRAST_EVIDENCE, MISSING_SCREEN_READER_LABEL, KEYBOARD_TRAP, MISSING_TABLE_SUMMARY, LOW_CONTRAST_CRITICAL_METRIC, MISSING_TABLE_SUMMARY, HEADING_ORDER_SKIP, MISSING_REDUCED_MOTION_FALLBACK | | missing-contrast-packet.json | hold_accessibility_release | blocked | blocked | blocked | INVALID_CONTRAST_EVIDENCE | | missing-noncritical-contrast-packet.json | remediate_before_public_release | internal_only | blocked | internal_only | INVALID_CONTRAST_EVIDENCE | +| malformed-component-packet.json | hold_accessibility_release | blocked | blocked | blocked | MALFORMED_DASHBOARD_COMPONENT_ENTRY | | clean-packet.json | release_with_accessibility_monitoring | allowed | allowed | allowed | none | | warning-packet.json | remediate_before_public_release | internal_only | blocked | internal_only | MISSING_REDUCED_MOTION_FALLBACK | diff --git a/enterprise-dashboard-accessibility-guard/reports/demo.mp4 b/enterprise-dashboard-accessibility-guard/reports/demo.mp4 index 9f8ca46389667e6b00e68206df0016fa5543da9c..df87b72526b803bbf9c6310fe95202e14e08c203 100644 GIT binary patch delta 90445 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 z

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 delta 62875 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 - + + Enterprise Dashboard Accessibility Guard Institutional dashboards, exports, and webhook notices are gated before release. @@ -22,12 +22,18 @@ remediate_before_public_release | findings 1 | digest 68bfb1e3df68d773 + + + enterprise-admin-malformed-component + hold_accessibility_release | findings 1 | digest 5c9dbb472c16ae68 + + enterprise-admin-clean release_with_accessibility_monitoring | findings 0 | digest e3abe7a1521f5654 - + enterprise-admin-motion-warning diff --git a/enterprise-dashboard-accessibility-guard/requirements-map.md b/enterprise-dashboard-accessibility-guard/requirements-map.md index 3e658879..84fbbfe9 100644 --- a/enterprise-dashboard-accessibility-guard/requirements-map.md +++ b/enterprise-dashboard-accessibility-guard/requirements-map.md @@ -9,7 +9,7 @@ Issue #19 asks for enterprise tooling around admin dashboards, API and webhook i | Compliance tracking | Produces WCAG-oriented readiness signals and deterministic audit evidence for institutional governance. | | Export pipelines | Blocks scheduled exports when tables lack summaries or dashboard views are not accessible enough for release. | | Webhook support | Keeps webhook notices internal-only when the dashboard state has nonblocking accessibility warnings. | -| Enterprise governance | Detects private-data leakage in screen-reader labels, table summaries, and export summaries before dashboard or export surfaces are published. | +| Enterprise governance | Detects private-data leakage in screen-reader labels, table summaries, and export summaries before dashboard or export surfaces are published, and blocks malformed dashboard component evidence instead of crashing before audit packet generation. | ## Non-Overlap diff --git a/enterprise-dashboard-accessibility-guard/sample-data.js b/enterprise-dashboard-accessibility-guard/sample-data.js index 55d36397..d5ca369f 100644 --- a/enterprise-dashboard-accessibility-guard/sample-data.js +++ b/enterprise-dashboard-accessibility-guard/sample-data.js @@ -200,10 +200,24 @@ const missingNoncriticalContrastDashboard = { } }; +const malformedComponentDashboard = { + dashboardId: 'enterprise-admin-malformed-component', + institutionId: 'institution-redacted', + assessedAt: '2026-05-31T14:30:00Z', + widgets: [null], + alerts: [], + exports: [], + motion: { + animatedCharts: [], + reducedMotionFallback: true + } +}; + module.exports = { blockedDashboard, cleanDashboard, warningDashboard, missingContrastDashboard, - missingNoncriticalContrastDashboard + missingNoncriticalContrastDashboard, + malformedComponentDashboard }; diff --git a/enterprise-dashboard-accessibility-guard/test.js b/enterprise-dashboard-accessibility-guard/test.js index b4f32b6c..57bbee77 100644 --- a/enterprise-dashboard-accessibility-guard/test.js +++ b/enterprise-dashboard-accessibility-guard/test.js @@ -214,6 +214,27 @@ function testMissingNoncriticalContrastEvidenceRequiresRemediation() { assert.ok(packet.actions.includes('provide_valid_contrast_evidence:secondary-usage-trend-without-colors')); } +function testMalformedDashboardComponentEntriesBlockRelease() { + const packet = assessDashboardRelease({ + dashboardId: 'enterprise-admin-malformed-component', + institutionId: 'institution-redacted', + assessedAt: '2026-05-31T14:30:00Z', + widgets: [null], + alerts: [], + exports: [], + motion: { + animatedCharts: [], + reducedMotionFallback: true + } + }); + + assert.equal(packet.status, 'hold_accessibility_release'); + assert.equal(packet.releaseLanes.adminDashboard, 'blocked'); + assert.deepEqual(codes(packet), ['MALFORMED_DASHBOARD_COMPONENT_ENTRY']); + assert.equal(packet.wcagSignals.robust, false); + assert.ok(packet.actions.includes('repair_dashboard_component_evidence:widgets[0]')); +} + function testShorthandHexContrastEvidenceRemainsValid() { const packet = assessDashboardRelease({ dashboardId: 'enterprise-admin-shorthand-contrast', @@ -288,6 +309,7 @@ const tests = [ testInvalidContrastEvidenceBlocksRelease, testMissingCriticalContrastEvidenceBlocksRelease, testMissingNoncriticalContrastEvidenceRequiresRemediation, + testMalformedDashboardComponentEntriesBlockRelease, testShorthandHexContrastEvidenceRemainsValid, testMissingVisibleFocusIndicatorBlocksKeyboardRelease ]; From 6f06509e1f5948a22e1e51adb1ae36c5b88f2534 Mon Sep 17 00:00:00 2001 From: KoiosSG Date: Tue, 2 Jun 2026 01:01:03 +0200 Subject: [PATCH 09/12] Harden malformed dashboard packet handling --- .../README.md | 1 + .../acceptance-notes.md | 2 + .../demo.js | 4 +- .../index.js | 48 ++++++++++++++++--- .../reports/accessibility-report.md | 1 + .../reports/malformed-dashboard-packet.json | 30 ++++++++++++ .../reports/summary.svg | 12 +++-- .../requirements-map.md | 2 +- .../sample-data.js | 5 +- .../test.js | 12 +++++ 10 files changed, 104 insertions(+), 13 deletions(-) create mode 100644 enterprise-dashboard-accessibility-guard/reports/malformed-dashboard-packet.json diff --git a/enterprise-dashboard-accessibility-guard/README.md b/enterprise-dashboard-accessibility-guard/README.md index ad1c10b4..68a1873a 100644 --- a/enterprise-dashboard-accessibility-guard/README.md +++ b/enterprise-dashboard-accessibility-guard/README.md @@ -12,6 +12,7 @@ This module evaluates institutional admin dashboard releases before they are sho - Keyboard reachability and focus traps - Missing visible focus indicators for keyboard-reachable dashboard controls - Malformed dashboard component evidence that would otherwise crash release assessment +- Malformed top-level dashboard packets that would otherwise crash before reviewer evidence is generated - Private user or project data embedded in screen-reader labels, table summaries, or export summaries - Missing table and export summaries - Heading-order skips diff --git a/enterprise-dashboard-accessibility-guard/acceptance-notes.md b/enterprise-dashboard-accessibility-guard/acceptance-notes.md index bb83d75a..02c6d151 100644 --- a/enterprise-dashboard-accessibility-guard/acceptance-notes.md +++ b/enterprise-dashboard-accessibility-guard/acceptance-notes.md @@ -9,12 +9,14 @@ - Treats missing noncritical dashboard contrast evidence as a remediation warning before public release. - Blocks release when keyboard-reachable dashboard controls suppress visible focus indicators. - Blocks malformed dashboard component evidence before it can crash release assessment. +- Blocks malformed top-level dashboard packets before they can crash release assessment. - Blocks release when private data appears in table or export accessibility summaries. - Generates reviewer artifacts: - `reports/blocked-packet.json` - `reports/missing-contrast-packet.json` - `reports/missing-noncritical-contrast-packet.json` - `reports/malformed-component-packet.json` + - `reports/malformed-dashboard-packet.json` - `reports/clean-packet.json` - `reports/warning-packet.json` - `reports/accessibility-report.md` diff --git a/enterprise-dashboard-accessibility-guard/demo.js b/enterprise-dashboard-accessibility-guard/demo.js index 3fd1bc2c..f9bd347d 100644 --- a/enterprise-dashboard-accessibility-guard/demo.js +++ b/enterprise-dashboard-accessibility-guard/demo.js @@ -8,7 +8,8 @@ const { warningDashboard, missingContrastDashboard, missingNoncriticalContrastDashboard, - malformedComponentDashboard + malformedComponentDashboard, + malformedDashboardPacket } = require('./sample-data'); const reportsDir = path.join(__dirname, 'reports'); @@ -19,6 +20,7 @@ const packets = [ ['missing-contrast-packet.json', assessDashboardRelease(missingContrastDashboard)], ['missing-noncritical-contrast-packet.json', assessDashboardRelease(missingNoncriticalContrastDashboard)], ['malformed-component-packet.json', assessDashboardRelease(malformedComponentDashboard)], + ['malformed-dashboard-packet.json', assessDashboardRelease(malformedDashboardPacket)], ['clean-packet.json', assessDashboardRelease(cleanDashboard)], ['warning-packet.json', assessDashboardRelease(warningDashboard)] ]; diff --git a/enterprise-dashboard-accessibility-guard/index.js b/enterprise-dashboard-accessibility-guard/index.js index 70b10d9c..cae8257a 100644 --- a/enterprise-dashboard-accessibility-guard/index.js +++ b/enterprise-dashboard-accessibility-guard/index.js @@ -1,28 +1,56 @@ const crypto = require('crypto'); function assessDashboardRelease(dashboard) { + const normalized = normalizeDashboardPacket(dashboard); const findings = [ - ...assessVisualAndOperableComponents(dashboard), - ...assessMotion(dashboard) + ...normalized.findings, + ...assessVisualAndOperableComponents(normalized.dashboard), + ...assessMotion(normalized.dashboard) ]; const blockerCount = findings.filter((finding) => finding.severity === 'blocker').length; const warningCount = findings.filter((finding) => finding.severity === 'warning').length; const packet = { - dashboardId: dashboard.dashboardId, - institutionId: dashboard.institutionId, + dashboardId: normalized.dashboard.dashboardId, + institutionId: normalized.dashboard.institutionId, status: chooseStatus(blockerCount, warningCount), releaseLanes: chooseReleaseLanes(blockerCount, warningCount), findings, - actions: buildActions(dashboard, findings), + actions: buildActions(normalized.dashboard, findings), wcagSignals: buildWcagSignals(findings), - assessedAt: dashboard.assessedAt + assessedAt: normalized.dashboard.assessedAt }; packet.auditDigest = digestPacket(packet); return packet; } +function normalizeDashboardPacket(dashboard) { + if (dashboard && typeof dashboard === 'object' && !Array.isArray(dashboard)) { + return { dashboard, findings: [] }; + } + + const normalizedDashboard = { + dashboardId: 'unidentified-dashboard', + institutionId: 'unidentified-institution', + assessedAt: null, + widgets: [], + alerts: [], + exports: [], + motion: {} + }; + + return { + dashboard: normalizedDashboard, + findings: [{ + componentId: normalizedDashboard.dashboardId, + code: 'MALFORMED_DASHBOARD_PACKET', + severity: 'blocker', + message: 'Dashboard release evidence must be an object before accessibility assessment.' + }] + }; +} + function assessVisualAndOperableComponents(dashboard) { const findings = []; const components = collectDashboardComponents(dashboard, findings); @@ -232,6 +260,9 @@ function buildActions(dashboard, findings) { if (item.code === 'MALFORMED_DASHBOARD_COMPONENT_ENTRY') { actions.add(`repair_dashboard_component_evidence:${item.componentId}`); } + if (item.code === 'MALFORMED_DASHBOARD_PACKET') { + actions.add(`repair_dashboard_packet:${item.componentId}`); + } } return [...actions].sort(); @@ -250,7 +281,10 @@ function buildWcagSignals(findings) { !codes.has('MISSING_REDUCED_MOTION_FALLBACK') && !codes.has('MISSING_VISIBLE_FOCUS_INDICATOR'), understandable: !codes.has('PRIVATE_DATA_IN_ACCESSIBILITY_TEXT') && !codes.has('HEADING_ORDER_SKIP'), - robust: !codes.has('MISSING_SCREEN_READER_LABEL') && !codes.has('MALFORMED_DASHBOARD_COMPONENT_ENTRY') + robust: + !codes.has('MISSING_SCREEN_READER_LABEL') && + !codes.has('MALFORMED_DASHBOARD_COMPONENT_ENTRY') && + !codes.has('MALFORMED_DASHBOARD_PACKET') }; } diff --git a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md index 35dc09e6..3ee6f72f 100644 --- a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md +++ b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md @@ -6,6 +6,7 @@ | missing-contrast-packet.json | hold_accessibility_release | blocked | blocked | blocked | INVALID_CONTRAST_EVIDENCE | | missing-noncritical-contrast-packet.json | remediate_before_public_release | internal_only | blocked | internal_only | INVALID_CONTRAST_EVIDENCE | | malformed-component-packet.json | hold_accessibility_release | blocked | blocked | blocked | MALFORMED_DASHBOARD_COMPONENT_ENTRY | +| malformed-dashboard-packet.json | hold_accessibility_release | blocked | blocked | blocked | MALFORMED_DASHBOARD_PACKET | | clean-packet.json | release_with_accessibility_monitoring | allowed | allowed | allowed | none | | warning-packet.json | remediate_before_public_release | internal_only | blocked | internal_only | MISSING_REDUCED_MOTION_FALLBACK | diff --git a/enterprise-dashboard-accessibility-guard/reports/malformed-dashboard-packet.json b/enterprise-dashboard-accessibility-guard/reports/malformed-dashboard-packet.json new file mode 100644 index 00000000..0d7c7024 --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/reports/malformed-dashboard-packet.json @@ -0,0 +1,30 @@ +{ + "dashboardId": "unidentified-dashboard", + "institutionId": "unidentified-institution", + "status": "hold_accessibility_release", + "releaseLanes": { + "adminDashboard": "blocked", + "scheduledExport": "blocked", + "webhookNotice": "blocked" + }, + "findings": [ + { + "componentId": "unidentified-dashboard", + "code": "MALFORMED_DASHBOARD_PACKET", + "severity": "blocker", + "message": "Dashboard release evidence must be an object before accessibility assessment." + } + ], + "actions": [ + "block_release:unidentified-dashboard", + "repair_dashboard_packet:unidentified-dashboard" + ], + "wcagSignals": { + "perceivable": true, + "operable": true, + "understandable": true, + "robust": false + }, + "assessedAt": null, + "auditDigest": "516d9cbe81ea9fa4fdefc56855e88adb197ca89d9365bd483e484e8e387f8fc4" +} diff --git a/enterprise-dashboard-accessibility-guard/reports/summary.svg b/enterprise-dashboard-accessibility-guard/reports/summary.svg index 2e8ba7f1..34f1fcc8 100644 --- a/enterprise-dashboard-accessibility-guard/reports/summary.svg +++ b/enterprise-dashboard-accessibility-guard/reports/summary.svg @@ -1,5 +1,5 @@ - - + + Enterprise Dashboard Accessibility Guard Institutional dashboards, exports, and webhook notices are gated before release. @@ -28,12 +28,18 @@ hold_accessibility_release | findings 1 | digest 5c9dbb472c16ae68 + + + unidentified-dashboard + hold_accessibility_release | findings 1 | digest 516d9cbe81ea9fa4 + + enterprise-admin-clean release_with_accessibility_monitoring | findings 0 | digest e3abe7a1521f5654 - + enterprise-admin-motion-warning diff --git a/enterprise-dashboard-accessibility-guard/requirements-map.md b/enterprise-dashboard-accessibility-guard/requirements-map.md index 84fbbfe9..c9f610e3 100644 --- a/enterprise-dashboard-accessibility-guard/requirements-map.md +++ b/enterprise-dashboard-accessibility-guard/requirements-map.md @@ -9,7 +9,7 @@ Issue #19 asks for enterprise tooling around admin dashboards, API and webhook i | Compliance tracking | Produces WCAG-oriented readiness signals and deterministic audit evidence for institutional governance. | | Export pipelines | Blocks scheduled exports when tables lack summaries or dashboard views are not accessible enough for release. | | Webhook support | Keeps webhook notices internal-only when the dashboard state has nonblocking accessibility warnings. | -| Enterprise governance | Detects private-data leakage in screen-reader labels, table summaries, and export summaries before dashboard or export surfaces are published, and blocks malformed dashboard component evidence instead of crashing before audit packet generation. | +| Enterprise governance | Detects private-data leakage in screen-reader labels, table summaries, and export summaries before dashboard or export surfaces are published, and blocks malformed dashboard packets or component evidence instead of crashing before audit packet generation. | ## Non-Overlap diff --git a/enterprise-dashboard-accessibility-guard/sample-data.js b/enterprise-dashboard-accessibility-guard/sample-data.js index d5ca369f..2846b5f0 100644 --- a/enterprise-dashboard-accessibility-guard/sample-data.js +++ b/enterprise-dashboard-accessibility-guard/sample-data.js @@ -213,11 +213,14 @@ const malformedComponentDashboard = { } }; +const malformedDashboardPacket = null; + module.exports = { blockedDashboard, cleanDashboard, warningDashboard, missingContrastDashboard, missingNoncriticalContrastDashboard, - malformedComponentDashboard + malformedComponentDashboard, + malformedDashboardPacket }; diff --git a/enterprise-dashboard-accessibility-guard/test.js b/enterprise-dashboard-accessibility-guard/test.js index 57bbee77..4b45b45a 100644 --- a/enterprise-dashboard-accessibility-guard/test.js +++ b/enterprise-dashboard-accessibility-guard/test.js @@ -235,6 +235,17 @@ function testMalformedDashboardComponentEntriesBlockRelease() { assert.ok(packet.actions.includes('repair_dashboard_component_evidence:widgets[0]')); } +function testMalformedDashboardPacketBlocksRelease() { + const packet = assessDashboardRelease(null); + + assert.equal(packet.dashboardId, 'unidentified-dashboard'); + assert.equal(packet.status, 'hold_accessibility_release'); + assert.equal(packet.releaseLanes.adminDashboard, 'blocked'); + assert.deepEqual(codes(packet), ['MALFORMED_DASHBOARD_PACKET']); + assert.equal(packet.wcagSignals.robust, false); + assert.ok(packet.actions.includes('repair_dashboard_packet:unidentified-dashboard')); +} + function testShorthandHexContrastEvidenceRemainsValid() { const packet = assessDashboardRelease({ dashboardId: 'enterprise-admin-shorthand-contrast', @@ -310,6 +321,7 @@ const tests = [ testMissingCriticalContrastEvidenceBlocksRelease, testMissingNoncriticalContrastEvidenceRequiresRemediation, testMalformedDashboardComponentEntriesBlockRelease, + testMalformedDashboardPacketBlocksRelease, testShorthandHexContrastEvidenceRemainsValid, testMissingVisibleFocusIndicatorBlocksKeyboardRelease ]; From a0f3773860590ca05cbc62226a4a2735021dc08f Mon Sep 17 00:00:00 2001 From: KoiosSG Date: Wed, 10 Jun 2026 13:11:13 +0200 Subject: [PATCH 10/12] Harden malformed dashboard motion evidence --- .../README.md | 1 + .../acceptance-notes.md | 2 ++ .../demo.js | 4 ++- .../index.js | 21 ++++++++++-- .../reports/accessibility-report.md | 1 + .../reports/malformed-motion-packet.json | 30 ++++++++++++++++ .../reports/summary.svg | 12 +++++-- .../requirements-map.md | 2 +- .../sample-data.js | 28 ++++++++++++++- .../test.js | 34 +++++++++++++++++++ 10 files changed, 126 insertions(+), 9 deletions(-) create mode 100644 enterprise-dashboard-accessibility-guard/reports/malformed-motion-packet.json diff --git a/enterprise-dashboard-accessibility-guard/README.md b/enterprise-dashboard-accessibility-guard/README.md index 68a1873a..c8c9f229 100644 --- a/enterprise-dashboard-accessibility-guard/README.md +++ b/enterprise-dashboard-accessibility-guard/README.md @@ -13,6 +13,7 @@ This module evaluates institutional admin dashboard releases before they are sho - Missing visible focus indicators for keyboard-reachable dashboard controls - Malformed dashboard component evidence that would otherwise crash release assessment - Malformed top-level dashboard packets that would otherwise crash before reviewer evidence is generated +- Malformed reduced-motion evidence that would otherwise crash animated chart assessment - Private user or project data embedded in screen-reader labels, table summaries, or export summaries - Missing table and export summaries - Heading-order skips diff --git a/enterprise-dashboard-accessibility-guard/acceptance-notes.md b/enterprise-dashboard-accessibility-guard/acceptance-notes.md index 02c6d151..f01f5f27 100644 --- a/enterprise-dashboard-accessibility-guard/acceptance-notes.md +++ b/enterprise-dashboard-accessibility-guard/acceptance-notes.md @@ -10,6 +10,7 @@ - Blocks release when keyboard-reachable dashboard controls suppress visible focus indicators. - Blocks malformed dashboard component evidence before it can crash release assessment. - Blocks malformed top-level dashboard packets before they can crash release assessment. +- Blocks malformed reduced-motion evidence before it can crash animated chart assessment. - Blocks release when private data appears in table or export accessibility summaries. - Generates reviewer artifacts: - `reports/blocked-packet.json` @@ -17,6 +18,7 @@ - `reports/missing-noncritical-contrast-packet.json` - `reports/malformed-component-packet.json` - `reports/malformed-dashboard-packet.json` + - `reports/malformed-motion-packet.json` - `reports/clean-packet.json` - `reports/warning-packet.json` - `reports/accessibility-report.md` diff --git a/enterprise-dashboard-accessibility-guard/demo.js b/enterprise-dashboard-accessibility-guard/demo.js index f9bd347d..ff9e9372 100644 --- a/enterprise-dashboard-accessibility-guard/demo.js +++ b/enterprise-dashboard-accessibility-guard/demo.js @@ -9,7 +9,8 @@ const { missingContrastDashboard, missingNoncriticalContrastDashboard, malformedComponentDashboard, - malformedDashboardPacket + malformedDashboardPacket, + malformedMotionDashboard } = require('./sample-data'); const reportsDir = path.join(__dirname, 'reports'); @@ -21,6 +22,7 @@ const packets = [ ['missing-noncritical-contrast-packet.json', assessDashboardRelease(missingNoncriticalContrastDashboard)], ['malformed-component-packet.json', assessDashboardRelease(malformedComponentDashboard)], ['malformed-dashboard-packet.json', assessDashboardRelease(malformedDashboardPacket)], + ['malformed-motion-packet.json', assessDashboardRelease(malformedMotionDashboard)], ['clean-packet.json', assessDashboardRelease(cleanDashboard)], ['warning-packet.json', assessDashboardRelease(warningDashboard)] ]; diff --git a/enterprise-dashboard-accessibility-guard/index.js b/enterprise-dashboard-accessibility-guard/index.js index cae8257a..bd194ad6 100644 --- a/enterprise-dashboard-accessibility-guard/index.js +++ b/enterprise-dashboard-accessibility-guard/index.js @@ -177,8 +177,19 @@ function assessHeadingOrder(components) { } function assessMotion(dashboard) { - if (dashboard.motion?.animatedCharts?.length && !dashboard.motion.reducedMotionFallback) { - return dashboard.motion.animatedCharts.map((componentId) => ({ + const animatedCharts = dashboard.motion?.animatedCharts; + if (animatedCharts == null) return []; + if (!Array.isArray(animatedCharts) || animatedCharts.some((componentId) => typeof componentId !== 'string' || !componentId.trim())) { + return [{ + componentId: 'motion.animatedCharts', + code: 'MALFORMED_MOTION_EVIDENCE', + severity: 'blocker', + message: 'Dashboard motion evidence must list animated component IDs before reduced-motion release assessment.' + }]; + } + + if (animatedCharts.length && !dashboard.motion.reducedMotionFallback) { + return animatedCharts.map((componentId) => ({ componentId, code: 'MISSING_REDUCED_MOTION_FALLBACK', severity: 'warning', @@ -263,6 +274,9 @@ function buildActions(dashboard, findings) { if (item.code === 'MALFORMED_DASHBOARD_PACKET') { actions.add(`repair_dashboard_packet:${item.componentId}`); } + if (item.code === 'MALFORMED_MOTION_EVIDENCE') { + actions.add(`repair_motion_evidence:${item.componentId}`); + } } return [...actions].sort(); @@ -279,7 +293,8 @@ function buildWcagSignals(findings) { operable: !codes.has('KEYBOARD_TRAP') && !codes.has('MISSING_REDUCED_MOTION_FALLBACK') && - !codes.has('MISSING_VISIBLE_FOCUS_INDICATOR'), + !codes.has('MISSING_VISIBLE_FOCUS_INDICATOR') && + !codes.has('MALFORMED_MOTION_EVIDENCE'), understandable: !codes.has('PRIVATE_DATA_IN_ACCESSIBILITY_TEXT') && !codes.has('HEADING_ORDER_SKIP'), robust: !codes.has('MISSING_SCREEN_READER_LABEL') && diff --git a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md index 3ee6f72f..65a02f97 100644 --- a/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md +++ b/enterprise-dashboard-accessibility-guard/reports/accessibility-report.md @@ -7,6 +7,7 @@ | missing-noncritical-contrast-packet.json | remediate_before_public_release | internal_only | blocked | internal_only | INVALID_CONTRAST_EVIDENCE | | malformed-component-packet.json | hold_accessibility_release | blocked | blocked | blocked | MALFORMED_DASHBOARD_COMPONENT_ENTRY | | malformed-dashboard-packet.json | hold_accessibility_release | blocked | blocked | blocked | MALFORMED_DASHBOARD_PACKET | +| malformed-motion-packet.json | hold_accessibility_release | blocked | blocked | blocked | MALFORMED_MOTION_EVIDENCE | | clean-packet.json | release_with_accessibility_monitoring | allowed | allowed | allowed | none | | warning-packet.json | remediate_before_public_release | internal_only | blocked | internal_only | MISSING_REDUCED_MOTION_FALLBACK | diff --git a/enterprise-dashboard-accessibility-guard/reports/malformed-motion-packet.json b/enterprise-dashboard-accessibility-guard/reports/malformed-motion-packet.json new file mode 100644 index 00000000..7811237c --- /dev/null +++ b/enterprise-dashboard-accessibility-guard/reports/malformed-motion-packet.json @@ -0,0 +1,30 @@ +{ + "dashboardId": "enterprise-admin-malformed-motion", + "institutionId": "institution-redacted", + "status": "hold_accessibility_release", + "releaseLanes": { + "adminDashboard": "blocked", + "scheduledExport": "blocked", + "webhookNotice": "blocked" + }, + "findings": [ + { + "componentId": "motion.animatedCharts", + "code": "MALFORMED_MOTION_EVIDENCE", + "severity": "blocker", + "message": "Dashboard motion evidence must list animated component IDs before reduced-motion release assessment." + } + ], + "actions": [ + "block_release:enterprise-admin-malformed-motion", + "repair_motion_evidence:motion.animatedCharts" + ], + "wcagSignals": { + "perceivable": true, + "operable": false, + "understandable": true, + "robust": true + }, + "assessedAt": "2026-06-10T13:10:00Z", + "auditDigest": "1b15a9f22c15eec4f0e4bc19d6a25231fac688e02875894ca3fb7ce2847b2fe7" +} diff --git a/enterprise-dashboard-accessibility-guard/reports/summary.svg b/enterprise-dashboard-accessibility-guard/reports/summary.svg index 34f1fcc8..94ebf997 100644 --- a/enterprise-dashboard-accessibility-guard/reports/summary.svg +++ b/enterprise-dashboard-accessibility-guard/reports/summary.svg @@ -1,5 +1,5 @@ - - + + Enterprise Dashboard Accessibility Guard Institutional dashboards, exports, and webhook notices are gated before release. @@ -34,12 +34,18 @@ hold_accessibility_release | findings 1 | digest 516d9cbe81ea9fa4 + + + enterprise-admin-malformed-motion + hold_accessibility_release | findings 1 | digest 1b15a9f22c15eec4 + + enterprise-admin-clean release_with_accessibility_monitoring | findings 0 | digest e3abe7a1521f5654 - + enterprise-admin-motion-warning diff --git a/enterprise-dashboard-accessibility-guard/requirements-map.md b/enterprise-dashboard-accessibility-guard/requirements-map.md index c9f610e3..1405c6ce 100644 --- a/enterprise-dashboard-accessibility-guard/requirements-map.md +++ b/enterprise-dashboard-accessibility-guard/requirements-map.md @@ -9,7 +9,7 @@ Issue #19 asks for enterprise tooling around admin dashboards, API and webhook i | Compliance tracking | Produces WCAG-oriented readiness signals and deterministic audit evidence for institutional governance. | | Export pipelines | Blocks scheduled exports when tables lack summaries or dashboard views are not accessible enough for release. | | Webhook support | Keeps webhook notices internal-only when the dashboard state has nonblocking accessibility warnings. | -| Enterprise governance | Detects private-data leakage in screen-reader labels, table summaries, and export summaries before dashboard or export surfaces are published, and blocks malformed dashboard packets or component evidence instead of crashing before audit packet generation. | +| Enterprise governance | Detects private-data leakage in screen-reader labels, table summaries, and export summaries before dashboard or export surfaces are published, and blocks malformed dashboard packets, component evidence, or reduced-motion evidence instead of crashing before audit packet generation. | ## Non-Overlap diff --git a/enterprise-dashboard-accessibility-guard/sample-data.js b/enterprise-dashboard-accessibility-guard/sample-data.js index 2846b5f0..36687d6b 100644 --- a/enterprise-dashboard-accessibility-guard/sample-data.js +++ b/enterprise-dashboard-accessibility-guard/sample-data.js @@ -215,6 +215,31 @@ const malformedComponentDashboard = { const malformedDashboardPacket = null; +const malformedMotionDashboard = { + dashboardId: 'enterprise-admin-malformed-motion', + institutionId: 'institution-redacted', + assessedAt: '2026-06-10T13:10:00Z', + widgets: [ + { + id: 'animated-usage-trend', + type: 'metric', + title: 'Usage trend', + foreground: '#111827', + background: '#ffffff', + critical: false, + keyboardReachable: true, + screenReaderLabel: 'Usage trend across departments', + headingLevel: 2 + } + ], + alerts: [], + exports: [], + motion: { + animatedCharts: 'animated-usage-trend', + reducedMotionFallback: false + } +}; + module.exports = { blockedDashboard, cleanDashboard, @@ -222,5 +247,6 @@ module.exports = { missingContrastDashboard, missingNoncriticalContrastDashboard, malformedComponentDashboard, - malformedDashboardPacket + malformedDashboardPacket, + malformedMotionDashboard }; diff --git a/enterprise-dashboard-accessibility-guard/test.js b/enterprise-dashboard-accessibility-guard/test.js index 4b45b45a..5ac5aee7 100644 --- a/enterprise-dashboard-accessibility-guard/test.js +++ b/enterprise-dashboard-accessibility-guard/test.js @@ -246,6 +246,39 @@ function testMalformedDashboardPacketBlocksRelease() { assert.ok(packet.actions.includes('repair_dashboard_packet:unidentified-dashboard')); } +function testMalformedMotionEvidenceBlocksRelease() { + const packet = assessDashboardRelease({ + dashboardId: 'enterprise-admin-malformed-motion', + institutionId: 'institution-redacted', + assessedAt: '2026-06-10T13:10:00Z', + widgets: [ + { + id: 'animated-usage-trend', + type: 'metric', + title: 'Usage trend', + foreground: '#111827', + background: '#ffffff', + critical: false, + keyboardReachable: true, + screenReaderLabel: 'Usage trend across departments', + headingLevel: 2 + } + ], + alerts: [], + exports: [], + motion: { + animatedCharts: 'animated-usage-trend', + reducedMotionFallback: false + } + }); + + assert.equal(packet.status, 'hold_accessibility_release'); + assert.equal(packet.releaseLanes.adminDashboard, 'blocked'); + assert.deepEqual(codes(packet), ['MALFORMED_MOTION_EVIDENCE']); + assert.equal(packet.wcagSignals.operable, false); + assert.ok(packet.actions.includes('repair_motion_evidence:motion.animatedCharts')); +} + function testShorthandHexContrastEvidenceRemainsValid() { const packet = assessDashboardRelease({ dashboardId: 'enterprise-admin-shorthand-contrast', @@ -322,6 +355,7 @@ const tests = [ testMissingNoncriticalContrastEvidenceRequiresRemediation, testMalformedDashboardComponentEntriesBlockRelease, testMalformedDashboardPacketBlocksRelease, + testMalformedMotionEvidenceBlocksRelease, testShorthandHexContrastEvidenceRemainsValid, testMissingVisibleFocusIndicatorBlocksKeyboardRelease ]; From a2e2f1058713459b1e4daabfb69204774540ce77 Mon Sep 17 00:00:00 2001 From: KoiosSG Date: Sat, 13 Jun 2026 20:36:39 +0200 Subject: [PATCH 11/12] Harden dashboard identifier leakage checks --- .../README.md | 2 +- .../acceptance-notes.md | 2 +- .../index.js | 2 +- .../requirements-map.md | 2 +- .../test.js | 33 +++++++++++++++++++ 5 files changed, 37 insertions(+), 4 deletions(-) diff --git a/enterprise-dashboard-accessibility-guard/README.md b/enterprise-dashboard-accessibility-guard/README.md index c8c9f229..f9072ed0 100644 --- a/enterprise-dashboard-accessibility-guard/README.md +++ b/enterprise-dashboard-accessibility-guard/README.md @@ -14,7 +14,7 @@ This module evaluates institutional admin dashboard releases before they are sho - Malformed dashboard component evidence that would otherwise crash release assessment - Malformed top-level dashboard packets that would otherwise crash before reviewer evidence is generated - Malformed reduced-motion evidence that would otherwise crash animated chart assessment -- Private user or project data embedded in screen-reader labels, table summaries, or export summaries +- Private user, project, or direct identifier data embedded in screen-reader labels, table summaries, or export summaries - Missing table and export summaries - Heading-order skips - Missing reduced-motion fallbacks for animated dashboard content diff --git a/enterprise-dashboard-accessibility-guard/acceptance-notes.md b/enterprise-dashboard-accessibility-guard/acceptance-notes.md index f01f5f27..dc044e1e 100644 --- a/enterprise-dashboard-accessibility-guard/acceptance-notes.md +++ b/enterprise-dashboard-accessibility-guard/acceptance-notes.md @@ -11,7 +11,7 @@ - Blocks malformed dashboard component evidence before it can crash release assessment. - Blocks malformed top-level dashboard packets before they can crash release assessment. - Blocks malformed reduced-motion evidence before it can crash animated chart assessment. -- Blocks release when private data appears in table or export accessibility summaries. +- Blocks release when private data or direct identifiers appear in screen-reader labels, table summaries, or export accessibility summaries. - Generates reviewer artifacts: - `reports/blocked-packet.json` - `reports/missing-contrast-packet.json` diff --git a/enterprise-dashboard-accessibility-guard/index.js b/enterprise-dashboard-accessibility-guard/index.js index bd194ad6..e93e0a34 100644 --- a/enterprise-dashboard-accessibility-guard/index.js +++ b/enterprise-dashboard-accessibility-guard/index.js @@ -338,7 +338,7 @@ function relativeLuminance(rgb) { } function containsPrivateData(value = '') { - return /[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}|private lab|restricted project/i.test(value); + return /[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}|orcid:\d{4}-\d{4}-\d{4}-\d{3}[\dx]|(?:sso|student|user|account)\s+id|private lab|restricted project/i.test(value); } function accessibilityText(component) { diff --git a/enterprise-dashboard-accessibility-guard/requirements-map.md b/enterprise-dashboard-accessibility-guard/requirements-map.md index 1405c6ce..c4b2e5b0 100644 --- a/enterprise-dashboard-accessibility-guard/requirements-map.md +++ b/enterprise-dashboard-accessibility-guard/requirements-map.md @@ -9,7 +9,7 @@ Issue #19 asks for enterprise tooling around admin dashboards, API and webhook i | Compliance tracking | Produces WCAG-oriented readiness signals and deterministic audit evidence for institutional governance. | | Export pipelines | Blocks scheduled exports when tables lack summaries or dashboard views are not accessible enough for release. | | Webhook support | Keeps webhook notices internal-only when the dashboard state has nonblocking accessibility warnings. | -| Enterprise governance | Detects private-data leakage in screen-reader labels, table summaries, and export summaries before dashboard or export surfaces are published, and blocks malformed dashboard packets, component evidence, or reduced-motion evidence instead of crashing before audit packet generation. | +| Enterprise governance | Detects private-data and direct identifier leakage in screen-reader labels, table summaries, and export summaries before dashboard or export surfaces are published, and blocks malformed dashboard packets, component evidence, or reduced-motion evidence instead of crashing before audit packet generation. | ## Non-Overlap diff --git a/enterprise-dashboard-accessibility-guard/test.js b/enterprise-dashboard-accessibility-guard/test.js index 5ac5aee7..69952f47 100644 --- a/enterprise-dashboard-accessibility-guard/test.js +++ b/enterprise-dashboard-accessibility-guard/test.js @@ -117,6 +117,38 @@ function testPrivateDataInTableSummaryBlocksRelease() { assert.ok(packet.actions.includes('redact_accessibility_text:private-summary-table')); } +function testDirectIdentifierInScreenReaderLabelBlocksRelease() { + const packet = assessDashboardRelease({ + dashboardId: 'enterprise-admin-private-label', + institutionId: 'institution-redacted', + assessedAt: '2026-05-27T13:12:00Z', + widgets: [ + { + id: 'private-label-metric', + type: 'metric', + title: 'Sensitive usage metric', + foreground: '#111827', + background: '#ffffff', + critical: true, + keyboardReachable: true, + screenReaderLabel: 'Usage for ORCID:0000-0002-1825-0097', + headingLevel: 2 + } + ], + alerts: [], + exports: [], + motion: { + animatedCharts: [], + reducedMotionFallback: true + } + }); + + assert.equal(packet.status, 'hold_accessibility_release'); + assert.deepEqual(codes(packet), ['PRIVATE_DATA_IN_ACCESSIBILITY_TEXT']); + assert.equal(packet.wcagSignals.understandable, false); + assert.ok(packet.actions.includes('redact_accessibility_text:private-label-metric')); +} + function testInvalidContrastEvidenceBlocksRelease() { const packet = assessDashboardRelease({ dashboardId: 'enterprise-admin-invalid-contrast-evidence', @@ -350,6 +382,7 @@ const tests = [ testWarningsAllowInternalOnlyPreview, testNonCriticalLowContrastRequiresRemediationBeforeRelease, testPrivateDataInTableSummaryBlocksRelease, + testDirectIdentifierInScreenReaderLabelBlocksRelease, testInvalidContrastEvidenceBlocksRelease, testMissingCriticalContrastEvidenceBlocksRelease, testMissingNoncriticalContrastEvidenceRequiresRemediation, From 86978f280895b2fe86475e5ed326d57bf67909c5 Mon Sep 17 00:00:00 2001 From: KoiosSG Date: Sat, 13 Jun 2026 21:29:17 +0200 Subject: [PATCH 12/12] Harden dashboard accessibility identifier redaction --- .../index.js | 40 ++++++++++++++++--- .../test.js | 40 ++++++++++++++++++- 2 files changed, 74 insertions(+), 6 deletions(-) diff --git a/enterprise-dashboard-accessibility-guard/index.js b/enterprise-dashboard-accessibility-guard/index.js index e93e0a34..24cd35a5 100644 --- a/enterprise-dashboard-accessibility-guard/index.js +++ b/enterprise-dashboard-accessibility-guard/index.js @@ -7,17 +7,26 @@ function assessDashboardRelease(dashboard) { ...assessVisualAndOperableComponents(normalized.dashboard), ...assessMotion(normalized.dashboard) ]; + const safeComponentId = createComponentIdentifierSanitizer(); + const safeFindings = findings.map((finding) => ({ + ...finding, + componentId: safeComponentId(finding.componentId) + })); + const safeDashboard = { + ...normalized.dashboard, + dashboardId: safeDashboardId(normalized.dashboard.dashboardId) + }; const blockerCount = findings.filter((finding) => finding.severity === 'blocker').length; const warningCount = findings.filter((finding) => finding.severity === 'warning').length; const packet = { - dashboardId: normalized.dashboard.dashboardId, + dashboardId: safeDashboard.dashboardId, institutionId: normalized.dashboard.institutionId, status: chooseStatus(blockerCount, warningCount), releaseLanes: chooseReleaseLanes(blockerCount, warningCount), - findings, - actions: buildActions(normalized.dashboard, findings), - wcagSignals: buildWcagSignals(findings), + findings: safeFindings, + actions: buildActions(safeDashboard, safeFindings), + wcagSignals: buildWcagSignals(safeFindings), assessedAt: normalized.dashboard.assessedAt }; @@ -312,6 +321,27 @@ function contrastRatio(foreground, background) { return (lighter + 0.05) / (darker + 0.05); } +function createComponentIdentifierSanitizer() { + const redactions = new Map(); + let redactionCount = 0; + + return (componentId) => { + if (!containsPrivateIdentifier(componentId)) return componentId; + if (!redactions.has(componentId)) { + redactions.set(componentId, `component-redacted-${++redactionCount}`); + } + return redactions.get(componentId); + }; +} + +function safeDashboardId(dashboardId) { + return containsPrivateIdentifier(dashboardId) ? 'dashboard-redacted' : dashboardId; +} + +function containsPrivateIdentifier(value = '') { + return /[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}|orcid:\d{4}-\d{4}-\d{4}-\d{3}[\dx]|(?:file:\/\/|[A-Z]:[\\/]Users[\\/][^ \s"')]+|\/Users\/[^ \s"')]+|\/home\/[^ \s"')]+|\bprivate[- ]lab\b|\bpatient-export\b)/i.test(value); +} + function hexToRgb(hex) { if (typeof hex !== 'string') return null; const token = hex.trim().replace('#', ''); @@ -338,7 +368,7 @@ function relativeLuminance(rgb) { } function containsPrivateData(value = '') { - return /[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}|orcid:\d{4}-\d{4}-\d{4}-\d{3}[\dx]|(?:sso|student|user|account)\s+id|private lab|restricted project/i.test(value); + return /[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}|orcid:\d{4}-\d{4}-\d{4}-\d{3}[\dx]|(?:sso|student|user|account)\s+id|(?:file:\/\/|[A-Z]:[\\/]Users[\\/][^ \s"')]+|\/Users\/[^ \s"')]+|\/home\/[^ \s"')]+)|\bprivate[- ]lab\b|\bpatient-export\b|restricted project/i.test(value); } function accessibilityText(component) { diff --git a/enterprise-dashboard-accessibility-guard/test.js b/enterprise-dashboard-accessibility-guard/test.js index 69952f47..52552fd5 100644 --- a/enterprise-dashboard-accessibility-guard/test.js +++ b/enterprise-dashboard-accessibility-guard/test.js @@ -376,6 +376,43 @@ function testMissingVisibleFocusIndicatorBlocksKeyboardRelease() { assert.ok(packet.actions.includes('add_visible_focus_indicator:project-risk-filter')); } +function testPrivateComponentIdsAreRedactedFromFindingsAndActions() { + const packet = assessDashboardRelease({ + dashboardId: 'C:\\Users\\Alice\\dashboards\\private-lab', + institutionId: 'institution-redacted', + assessedAt: '2026-05-27T13:25:00Z', + widgets: [ + { + id: 'alice.private@example.edu', + type: 'metric', + title: 'Private cohort summary', + foreground: '#111827', + background: '#ffffff', + critical: true, + keyboardReachable: true, + screenReaderLabel: 'Owner alice.private@example.edu cohort summary', + headingLevel: 2 + } + ], + alerts: [], + exports: [], + motion: { + animatedCharts: [], + reducedMotionFallback: true + } + }); + + const packetJson = JSON.stringify(packet); + + assert.equal(packet.status, 'hold_accessibility_release'); + assert.equal(packet.findings[0].componentId, 'component-redacted-1'); + assert.ok(packet.actions.includes('block_release:dashboard-redacted')); + assert.ok(packet.actions.includes('redact_accessibility_text:component-redacted-1')); + assert.equal(packetJson.includes('alice.private@example.edu'), false); + assert.equal(packetJson.includes('C:\\Users\\Alice'), false); + assert.equal(packetJson.includes('private-lab'), false); +} + const tests = [ testCriticalAccessibilityIssuesBlockDashboardRelease, testCleanDashboardReleasesWithWcagSignals, @@ -390,7 +427,8 @@ const tests = [ testMalformedDashboardPacketBlocksRelease, testMalformedMotionEvidenceBlocksRelease, testShorthandHexContrastEvidenceRemainsValid, - testMissingVisibleFocusIndicatorBlocksKeyboardRelease + testMissingVisibleFocusIndicatorBlocksKeyboardRelease, + testPrivateComponentIdsAreRedactedFromFindingsAndActions ]; for (const test of tests) {