Skip to content

Commit 8f778e7

Browse files
committed
System Touch
1 parent 6ff34cb commit 8f778e7

2 files changed

Lines changed: 128 additions & 134 deletions

File tree

docs/index.html

Lines changed: 64 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@
99
:root{
1010
--color-title: #0B2545;
1111
--color-section: #1B3A63;
12-
--color-subsection: #2B4F80;
1312
--color-body: #222222;
14-
--color-link: #0A66C2;
1513
--carolina-blue: #4B9CD3;
1614
--max-width: 980px;
1715
--sidebar-width: 310px;
@@ -52,9 +50,9 @@
5250
.sidebar::-webkit-scrollbar { display:none; width:0; height:0; }
5351

5452
.repo-link { display:block; font-weight:700; color:var(--color-title); text-decoration:none; margin-bottom:12px; font-size:0.98rem; }
55-
.repo-link small { display:block; font-weight:600; color:var(--color-link); margin-top:4px; font-size:0.85rem; }
53+
.repo-link small { display:block; font-weight:600; color:#0A66C2; margin-top:4px; font-size:0.85rem; }
5654

57-
.toc-title { color: var(--color-subsection); font-weight:700; margin-bottom:8px; font-size:0.95rem; }
55+
.toc-title { color: #2B4F80; font-weight:700; margin-bottom:8px; font-size:0.95rem; }
5856
.sidebar nav ul { list-style:none; padding:0; margin:0; }
5957
.sidebar nav li { margin:0.45rem 0; }
6058
.sidebar nav a { color:var(--color-section); text-decoration:none; font-weight:600; font-size:0.95rem; padding:6px 8px; border-radius:6px; display:inline-block; }
@@ -167,12 +165,12 @@
167165
<p class="subtitle">Modular Java web server and Telnet front end for Java 21. Virtual threads, NIO file handling, and a command‑driven Telnet shell with a centralized <code>Main.java</code> entry point.</p>
168166
</header>
169167

170-
<!-- Progress / commits line chart card -->
168+
<!-- Progress / commits additive line chart card -->
171169
<section id="progress" class="progress-card" aria-labelledby="progressTitle">
172170
<div class="progress-header">
173171
<div>
174172
<div id="progressTitle" class="progress-title">Progress</div>
175-
<div class="progress-sub">Commits (last 52 weeks)</div>
173+
<div class="progress-sub">Cumulative commits (last 52 weeks, daily)</div>
176174
</div>
177175
<div id="commitSummary" style="color:#333;font-weight:600;font-size:0.95rem;">Loading…</div>
178176
</div>
@@ -188,7 +186,7 @@
188186
</div>
189187
</section>
190188

191-
<!-- Content sections -->
189+
<!-- Content sections (unchanged) -->
192190
<section id="purpose-and-governance-structure">
193191
<h2>1. Purpose and governance structure</h2>
194192
<p><strong>The National Finance Engine (NFE)</strong> and the <strong>National IQ Conservatorship &amp; Legal Protectorate (NICLP)</strong> form a dual‑layer digital infrastructure designed to support secure, remote, and ethically governed financial coordination within the United States. Developed by <strong>Max Rupplin</strong>, the framework integrates a national‑grade encrypted trading engine with a state‑aligned analytical and Positionortorship layer represented by <strong>NCIQ (North Carolina IQ)</strong>.</p>
@@ -264,10 +262,10 @@ <h2>11. Summary</h2>
264262

265263
<script>
266264
(function () {
267-
// Feature detection
265+
// Basic feature detection
268266
if (!window.fetch || !document.createElement('canvas').getContext) {
269267
var note = document.getElementById('chartNote');
270-
if (note) note.textContent = 'Your browser does not support required features (fetch or canvas). Please update or use a modern browser.';
268+
if (note) note.textContent = 'Your browser lacks required features (fetch or canvas). Please update or use a modern browser.';
271269
return;
272270
}
273271

@@ -300,6 +298,7 @@ <h2>11. Summary</h2>
300298
noteEl.textContent = 'Token cleared.';
301299
});
302300

301+
// week/day helpers
303302
function weekStartUTC(date) {
304303
var d = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));
305304
var day = d.getUTCDay();
@@ -308,7 +307,7 @@ <h2>11. Summary</h2>
308307
return d.getTime();
309308
}
310309

311-
// Parse Link header for pagination (returns object of rel->url)
310+
// parse Link header for pagination
312311
function parseLinkHeader(header) {
313312
if (!header) return {};
314313
var parts = header.split(',');
@@ -323,7 +322,7 @@ <h2>11. Summary</h2>
323322
return map;
324323
}
325324

326-
// Fetch commits using REST API with robust pagination (Link header)
325+
// robust paginated fetch using Link header
327326
async function fetchCommitsSince(sinceIso) {
328327
var perPage = 100;
329328
var url = 'https://api.github.com/repos/' + owner + '/' + repo + '/commits?since=' + encodeURIComponent(sinceIso) + '&per_page=' + perPage;
@@ -332,11 +331,10 @@ <h2>11. Summary</h2>
332331
var headers = token ? { 'Authorization': 'token ' + token } : {};
333332
var attempts = 0;
334333

335-
while (url && attempts < 100) {
334+
while (url && attempts < 200) {
336335
attempts++;
337336
var res = await fetch(url, { headers: headers });
338337
if (res.status === 403) {
339-
// rate limited or forbidden
340338
var reset = res.headers.get('x-ratelimit-reset');
341339
throw new Error('Rate limited or access denied. ' + (reset ? 'Reset at ' + new Date(parseInt(reset,10)*1000).toLocaleString() : ''));
342340
}
@@ -355,47 +353,50 @@ <h2>11. Summary</h2>
355353
} else {
356354
url = null;
357355
}
358-
// small delay to be polite (avoid bursts)
356+
// small polite delay
359357
await new Promise(function (r) { setTimeout(r, 120); });
360358
}
361359
return allCommits;
362360
}
363361

364-
function aggregateWeekly(commits, sinceTs) {
365-
var weeksMap = {};
366-
var now = Date.now();
367-
var oneWeekMs = 7 * 24 * 60 * 60 * 1000;
368-
for (var t = sinceTs; t <= now; t += oneWeekMs) {
369-
weeksMap[t] = 0;
370-
}
362+
// Aggregate commits into daily buckets across the full range (52 weeks)
363+
function aggregateDailyCumulative(commits, sinceTs, daysCount) {
364+
var oneDayMs = 24 * 60 * 60 * 1000;
365+
var days = new Array(daysCount);
366+
for (var i = 0; i < daysCount; i++) days[i] = 0;
367+
371368
for (var i = 0; i < commits.length; i++) {
372369
var c = commits[i];
373370
var dateStr = c && c.commit && c.commit.author && c.commit.author.date;
374371
if (!dateStr) continue;
375372
var d = new Date(dateStr);
376-
var wk = weekStartUTC(d);
377-
if (wk < sinceTs) continue;
378-
if (!weeksMap.hasOwnProperty(wk)) weeksMap[wk] = 0;
379-
weeksMap[wk] = weeksMap[wk] + 1;
373+
var idx = Math.floor((d.getTime() - sinceTs) / oneDayMs);
374+
if (idx < 0) continue;
375+
if (idx >= daysCount) idx = daysCount - 1; // clamp to last day
376+
days[idx] = days[idx] + 1;
380377
}
381-
var arr = [];
382-
var keys = Object.keys(weeksMap).map(function(k){ return parseInt(k,10); }).sort(function(a,b){ return a-b; });
383-
for (var j = 0; j < keys.length; j++) {
384-
arr.push({ weekStart: keys[j], total: weeksMap[keys[j]] });
378+
379+
// cumulative
380+
var cumulative = new Array(daysCount);
381+
var running = 0;
382+
for (var j = 0; j < daysCount; j++) {
383+
running += days[j];
384+
cumulative[j] = running;
385385
}
386-
return arr;
386+
return { days: days, cumulative: cumulative };
387387
}
388388

389-
function drawLineChart(weeklyData) {
390-
var totals = weeklyData.map(function(w){ return w.total; });
389+
// Draw smooth additive (cumulative) line chart across daily points
390+
function drawCumulativeLineChart(cumulativeArray) {
391+
var totals = cumulativeArray.slice(); // cumulative values
391392
var max = Math.max.apply(null, totals.concat([1]));
392-
var padding = 28;
393+
var paddingX = 28;
394+
var paddingY = 28;
393395
var deviceRatio = window.devicePixelRatio || 1;
394396
var clientW = commitsCanvas.clientWidth;
395397
var clientH = commitsCanvas.clientHeight;
396398
commitsCanvas.width = Math.round(clientW * deviceRatio);
397399
commitsCanvas.height = Math.round(clientH * deviceRatio);
398-
// reset transform then scale
399400
ctx.setTransform(1,0,0,1,0,0);
400401
ctx.clearRect(0,0,commitsCanvas.width,commitsCanvas.height);
401402
ctx.setTransform(deviceRatio, 0, 0, deviceRatio, 0, 0);
@@ -404,31 +405,32 @@ <h2>11. Summary</h2>
404405
ctx.fillStyle = '#fff';
405406
ctx.fillRect(0,0,clientW,clientH);
406407

407-
var availW = clientW - padding * 2;
408-
var availH = clientH - padding * 2;
408+
var availW = clientW - paddingX * 2;
409+
var availH = clientH - paddingY * 2;
409410
var pointCount = totals.length;
410411
var stepX = pointCount > 1 ? availW / (pointCount - 1) : availW;
411412

413+
// compute points
412414
var points = totals.map(function(v,i){
413-
var x = padding + i * stepX;
414-
var y = padding + (1 - (v / max)) * availH;
415+
var x = paddingX + i * stepX;
416+
var y = paddingY + (1 - (v / max)) * availH;
415417
return { x: x, y: y, v: v };
416418
});
417419

418-
// translucent fill
420+
// translucent fill under curve (smooth by using straight lines; still visually pleasing)
419421
if (points.length) {
420422
ctx.beginPath();
421-
ctx.moveTo(points[0].x, clientH - padding);
423+
ctx.moveTo(points[0].x, clientH - paddingY);
422424
for (var k = 0; k < points.length; k++) {
423425
ctx.lineTo(points[k].x, points[k].y);
424426
}
425-
ctx.lineTo(points[points.length - 1].x, clientH - padding);
427+
ctx.lineTo(points[points.length - 1].x, clientH - paddingY);
426428
ctx.closePath();
427429
ctx.fillStyle = getComputedStyle(document.documentElement).getPropertyValue('--line-fill') || 'rgba(153,102,255,0.18)';
428430
ctx.fill();
429431
}
430432

431-
// line
433+
// draw line
432434
ctx.beginPath();
433435
for (var m = 0; m < points.length; m++) {
434436
if (m === 0) ctx.moveTo(points[m].x, points[m].y);
@@ -440,9 +442,10 @@ <h2>11. Summary</h2>
440442
ctx.lineCap = 'round';
441443
ctx.stroke();
442444

443-
// points
445+
// small circles at sampled points (to avoid drawing 364 circles on very small canvases, sample every Nth point)
446+
var sampleEvery = Math.max(1, Math.floor(points.length / 80)); // limit to ~80 markers
444447
ctx.fillStyle = getComputedStyle(document.documentElement).getPropertyValue('--line-color') || 'rgba(153,102,255,0.95)';
445-
for (var p = 0; p < points.length; p++) {
448+
for (var p = 0; p < points.length; p += sampleEvery) {
446449
ctx.beginPath();
447450
ctx.arc(points[p].x, points[p].y, 2.5, 0, Math.PI * 2);
448451
ctx.fill();
@@ -452,44 +455,38 @@ <h2>11. Summary</h2>
452455
ctx.fillStyle = '#666';
453456
ctx.font = '12px system-ui, Inter, Arial';
454457
ctx.textAlign = 'right';
455-
ctx.fillText('Weekly commits', clientW - 8, 14);
458+
ctx.fillText('Cumulative commits', clientW - 8, 14);
456459
}
457460

461+
// Main update flow: fetch commits, aggregate per day, compute cumulative, draw
458462
async function updateCommits() {
459463
try {
460464
noteEl.textContent = 'Fetching commits via GitHub REST API…';
461465
var now = new Date();
462466
var oneWeekMs = 7 * 24 * 60 * 60 * 1000;
463467
var sinceDate = new Date(now.getTime() - 52 * oneWeekMs);
464468
var sinceWeekStart = new Date(weekStartUTC(sinceDate));
469+
// days across 52 weeks
470+
var daysCount = 52 * 7;
471+
var sinceTs = sinceWeekStart.getTime();
465472
var sinceIso = sinceWeekStart.toISOString();
466473

467474
var commits = await fetchCommitsSince(sinceIso);
468-
var weekly = aggregateWeekly(commits, sinceWeekStart.getTime());
469-
470-
// ensure 52 weeks
471-
if (weekly.length < 52) {
472-
var full = [];
473-
for (var i = 0; i < 52; i++) {
474-
var wk = sinceWeekStart.getTime() + i * oneWeekMs;
475-
var found = null;
476-
for (var z = 0; z < weekly.length; z++) {
477-
if (weekly[z].weekStart === wk) { found = weekly[z]; break; }
478-
}
479-
full.push(found ? found : { weekStart: wk, total: 0 });
480-
}
481-
weekly = full;
482-
}
483475

484-
drawLineChart(weekly);
485-
var totalYear = 0;
486-
for (var q = 0; q < weekly.length; q++) totalYear += weekly[q].total;
476+
// aggregate into daily cumulative
477+
var agg = aggregateDailyCumulative(commits, sinceTs, daysCount);
478+
var cumulative = agg.cumulative;
479+
480+
// draw cumulative line chart across all days
481+
drawCumulativeLineChart(cumulative);
482+
483+
var totalCommits = cumulative.length ? cumulative[cumulative.length - 1] : 0;
487484
var updatedAt = new Date();
488-
summaryEl.textContent = totalYear + ' commits (last 52 weeks) · updated ' + updatedAt.toLocaleString();
489-
noteEl.textContent = 'Data fetched from GitHub REST commits endpoint.';
485+
summaryEl.textContent = totalCommits + ' commits (cumulative, last 52 weeks) · updated ' + updatedAt.toLocaleString();
486+
noteEl.textContent = 'Additive cumulative chart (daily) from GitHub REST commits endpoint.';
490487
} catch (err) {
491488
console.warn(err);
492-
// fallback to repo summary
489+
// fallback: repo summary
493490
try {
494491
var token = getToken();
495492
var headers = token ? { 'Authorization': 'token ' + token } : {};
@@ -519,7 +516,7 @@ <h2>11. Summary</h2>
519516
ctx.fillStyle = '#999';
520517
ctx.font = '14px system-ui, Inter';
521518
ctx.textAlign = 'center';
522-
ctx.fillText('Weekly commit data unavailable', clientW/2, clientH/2);
519+
ctx.fillText('Cumulative commit data unavailable', clientW/2, clientH/2);
523520
}
524521
}
525522

0 commit comments

Comments
 (0)