eyeling 1.16.3 → 1.16.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +0 -1
  2. package/package.json +2 -3
  3. package/arctifacts/README.md +0 -59
  4. package/arctifacts/ackermann.html +0 -678
  5. package/arctifacts/auroracare.html +0 -1297
  6. package/arctifacts/bike-trip.html +0 -752
  7. package/arctifacts/binomial-theorem.html +0 -631
  8. package/arctifacts/bmi.html +0 -511
  9. package/arctifacts/building-performance.html +0 -750
  10. package/arctifacts/clinical-care.html +0 -726
  11. package/arctifacts/collatz.html +0 -403
  12. package/arctifacts/complex.html +0 -321
  13. package/arctifacts/control-system.html +0 -482
  14. package/arctifacts/delfour.html +0 -849
  15. package/arctifacts/earthquake-epicenter.html +0 -982
  16. package/arctifacts/eco-route.html +0 -662
  17. package/arctifacts/euclid-infinitude.html +0 -564
  18. package/arctifacts/euler-identity.html +0 -667
  19. package/arctifacts/exoplanet-transit.html +0 -1000
  20. package/arctifacts/faltings-theorem.html +0 -1046
  21. package/arctifacts/fibonacci.html +0 -299
  22. package/arctifacts/fundamental-theorem-arithmetic.html +0 -398
  23. package/arctifacts/godel-numbering.html +0 -743
  24. package/arctifacts/gps-bike.html +0 -759
  25. package/arctifacts/gps-clinical-bench.html +0 -792
  26. package/arctifacts/graph-french.html +0 -449
  27. package/arctifacts/grass-molecular.html +0 -592
  28. package/arctifacts/group-theory.html +0 -740
  29. package/arctifacts/health-info.html +0 -833
  30. package/arctifacts/kaprekar-constant.html +0 -576
  31. package/arctifacts/lee.html +0 -805
  32. package/arctifacts/linked-lists.html +0 -502
  33. package/arctifacts/lldm.html +0 -612
  34. package/arctifacts/matrix-multiplication.html +0 -502
  35. package/arctifacts/matrix.html +0 -651
  36. package/arctifacts/newton-raphson.html +0 -944
  37. package/arctifacts/peano-factorial.html +0 -456
  38. package/arctifacts/pi.html +0 -363
  39. package/arctifacts/polynomial.html +0 -646
  40. package/arctifacts/prime.html +0 -366
  41. package/arctifacts/pythagorean-theorem.html +0 -468
  42. package/arctifacts/rest-path.html +0 -469
  43. package/arctifacts/roots-of-unity.html +0 -363
  44. package/arctifacts/turing.html +0 -409
  45. package/arctifacts/wind-turbines.html +0 -726
@@ -1,678 +0,0 @@
1
- <!doctype html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>A₂ (Ackermann via hyper-operations)</title>
7
- <style>
8
- :root {
9
- --fg: #101014;
10
- --bg: #ffffff;
11
- --muted: #666;
12
- --accent: #2563eb;
13
- --chip: #eef2ff;
14
- --ok: #16a34a;
15
- --bad: #dc2626;
16
- --warn: #ca8a04;
17
- }
18
- @media (prefers-color-scheme: dark) {
19
- :root {
20
- --fg: #eaeaf0;
21
- --bg: #0b0b10;
22
- --muted: #a0a0b0;
23
- --accent: #60a5fa;
24
- --chip: #0e1a32;
25
- }
26
- }
27
- html,
28
- body {
29
- margin: 0;
30
- padding: 0;
31
- background: var(--bg);
32
- color: var(--fg);
33
- font:
34
- 15px/1.6 ui-sans-serif,
35
- system-ui,
36
- -apple-system,
37
- Segoe UI,
38
- Roboto,
39
- Helvetica,
40
- Arial;
41
- }
42
- main {
43
- max-width: 1100px;
44
- margin: 0 auto;
45
- padding: 28px 16px 80px;
46
- }
47
- h1 {
48
- font-size: clamp(1.6rem, 2.6vw + 1rem, 2.2rem);
49
- margin: 0 0 6px;
50
- }
51
- header p {
52
- margin: 0;
53
- color: var(--muted);
54
- }
55
- section {
56
- margin: 18px 0 22px;
57
- padding: 14px 14px 16px;
58
- border: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
59
- border-radius: 14px;
60
- background: color-mix(in srgb, var(--accent) 4%, transparent);
61
- }
62
- section h2 {
63
- margin: 0 0 8px;
64
- font-size: 1.15rem;
65
- }
66
- .row {
67
- display: flex;
68
- gap: 12px;
69
- align-items: center;
70
- flex-wrap: wrap;
71
- }
72
- .btn {
73
- appearance: none;
74
- border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
75
- background: color-mix(in srgb, var(--accent) 8%, transparent);
76
- color: var(--fg);
77
- border-radius: 10px;
78
- padding: 8px 12px;
79
- font-weight: 700;
80
- cursor: pointer;
81
- }
82
- .mono {
83
- font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace;
84
- }
85
- .muted {
86
- color: var(--muted);
87
- }
88
- .small {
89
- font-size: 0.92em;
90
- }
91
- .chip {
92
- display: inline-block;
93
- padding: 2px 8px;
94
- border-radius: 999px;
95
- background: var(--chip);
96
- font-weight: 600;
97
- }
98
- input[type='number'] {
99
- width: 100px;
100
- border-radius: 10px;
101
- border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
102
- padding: 8px 10px;
103
- }
104
- label {
105
- user-select: none;
106
- }
107
- code {
108
- background: color-mix(in srgb, var(--accent) 10%, transparent);
109
- padding: 0.1rem 0.35rem;
110
- border-radius: 0.35rem;
111
- }
112
- details > summary {
113
- cursor: pointer;
114
- }
115
- .ok {
116
- color: var(--ok);
117
- }
118
- .bad {
119
- color: var(--bad);
120
- }
121
- .spinner {
122
- display: inline-block;
123
- width: 1em;
124
- height: 1em;
125
- border: 2px solid color-mix(in srgb, var(--accent) 30%, transparent);
126
- border-top-color: var(--accent);
127
- border-radius: 50%;
128
- animation: spin 1s linear infinite;
129
- vertical-align: middle;
130
- }
131
- @keyframes spin {
132
- to {
133
- transform: rotate(360deg);
134
- }
135
- }
136
-
137
- /* Ensure the Answer card can scroll horizontally for long lines */
138
- #answer {
139
- overflow-x: auto;
140
- }
141
- #answer pre {
142
- white-space: pre !important;
143
- overflow-x: auto;
144
- overflow-y: auto;
145
- max-width: 100%;
146
- }
147
- </style>
148
- </head>
149
- <body>
150
- <main>
151
- <header class="row">
152
- <div>
153
- <h1>A₂ (Ackermann via hyper-operations)</h1>
154
- </div>
155
- <div class="row" style="margin-left: auto">
156
- <label class="muted small">x: <input id="x" type="number" min="0" max="6" value="3" /></label>
157
- <label class="muted small">y: <input id="y" type="number" min="0" max="100000" value="4" /></label>
158
- <button id="compute" class="btn">Compute</button>
159
- <button id="demo" class="btn">Run demo set</button>
160
- </div>
161
- </header>
162
-
163
- <section>
164
- <h2>What this is?</h2>
165
- <p>This page mirrors the case file definition:</p>
166
- <p class="mono">A₂(x, y) = H(x, y+3, 2) − 3</p>
167
- <p class="small">
168
- with hyper‑operations <code>H</code> defined by <code>H(0,y,z)=y+1</code>, <code>H(1,y,z)=y+z</code>,
169
- <code>H(2,y,z)=y·z</code>, <code>H(x≥3,0,z)=1</code>, <code>H(x≥3,y>0,z)</code>: repeat <code>y</code> times
170
- <code>result = H(x−1, result, z)</code> starting from <code>1</code>. For <code>z=2</code>, this yields
171
- exponentiation for <code>x=3</code> and tetration for <code>x=4</code>.
172
- </p>
173
- </section>
174
-
175
- <section id="answer">
176
- <h2>Answer</h2>
177
- <div id="chips" class="row small" style="gap: 8px"></div>
178
- <div id="one"></div>
179
- <details id="demos">
180
- <summary>Demo queries (12)</summary>
181
- <div id="demosBody" class="mono small"></div>
182
- </details>
183
- </section>
184
-
185
- <section id="reason">
186
- <h2>Reason why</h2>
187
- <div class="small">
188
- <p>
189
- Closed forms: <code>A₂(0,y)=y+1</code>, <code>A₂(1,y)=y+2</code>, <code>A₂(2,y)=2y+3</code>,
190
- <code>A₂(3,y)=2^(y+3)−3</code>.
191
- </p>
192
- <p>
193
- For <code>x=4</code> we hit <code>2^^(y+3)</code>. When that’s still realistically printable (like
194
- <code>2^65536−3</code>), we expand it exactly using a background worker.
195
- </p>
196
- </div>
197
- </section>
198
-
199
- <section id="check">
200
- <h2>Check (harness)</h2>
201
- <div id="check-body"></div>
202
- </section>
203
- </main>
204
-
205
- <script>
206
- (function () {
207
- 'use strict';
208
- const $ = (id) => document.getElementById(id);
209
- const setHTML = (id, html) => {
210
- const el = $(id);
211
- if (el) el.innerHTML = html;
212
- };
213
- const now = () => performance.now();
214
-
215
- // ---------- Limits ----------
216
- const DECIMAL_LIMIT = 70000; // auto-expand if decimal digits <= this
217
-
218
- // ---------- Worker for heavy expansion ----------
219
- function createPow2Minus3Worker() {
220
- const code = `
221
- self.onmessage = function(e){
222
- const expStr = e.data && e.data.exp;
223
- try{
224
- const exp = BigInt(expStr);
225
- function pow2ExactExp(e){
226
- try { return (1n << e); }
227
- catch (_){
228
- // fallback to exponentiation by squaring
229
- let base = 2n, res = 1n, x = e;
230
- while (x > 0n){
231
- if (x & 1n) res *= base;
232
- x >>= 1n;
233
- if (x > 0n) base *= base;
234
- }
235
- return res;
236
- }
237
- }
238
- const t0 = Date.now();
239
- const val = pow2ExactExp(exp) - 3n;
240
- const s = val.toString();
241
- const t1 = Date.now();
242
- self.postMessage({ ok:true, digits: s.length, ms: t1 - t0, text: s });
243
- } catch(err){
244
- self.postMessage({ ok:false, error: (err && err.message) || String(err) });
245
- }
246
- };
247
- `;
248
- const blob = new Blob([code], { type: 'application/javascript' });
249
- return new Worker(URL.createObjectURL(blob));
250
- }
251
-
252
- // ---------- Representations ----------
253
- // {kind:'bigint', value: BigInt}
254
- // {kind:'pow2', exp: BigInt} // represents 2^exp
255
- // After A2: {kind:'pow2minus3', exp: BigInt}
256
-
257
- // Hyper-operations (z fixed to 2)
258
- function hyper2(x, y) {
259
- x = Number(x);
260
- y = Number(y);
261
- if (x === 0) return { kind: 'bigint', value: BigInt(y) + 1n };
262
- if (x === 1) return { kind: 'bigint', value: BigInt(y) + 2n };
263
- if (x === 2) return { kind: 'bigint', value: BigInt(y) * 2n };
264
- if (y === 0) return { kind: 'bigint', value: 1n };
265
- let result = { kind: 'bigint', value: 1n };
266
- for (let i = 0; i < y; i++) {
267
- if (x === 3) {
268
- result = { kind: 'bigint', value: result.kind === 'bigint' ? result.value * 2n : 1n << result.exp }; // safe for small
269
- } else if (x === 4) {
270
- if (result.kind === 'bigint') {
271
- const k = result.value;
272
- // If k is modest, compute 2^k exactly; otherwise keep symbolic
273
- if (k <= 4096n) {
274
- result = { kind: 'bigint', value: 1n << k };
275
- } else {
276
- result = { kind: 'pow2', exp: k };
277
- }
278
- } else {
279
- // result is already 2^k; next step would be astronomical; keep symbolic
280
- result = { kind: 'pow2', exp: result.exp > 4096n ? result.exp : 1n << result.exp };
281
- }
282
- } else {
283
- if (result.kind !== 'bigint') return result;
284
- result = hyper2(x - 1, Number(result.value));
285
- }
286
- }
287
- return result;
288
- }
289
-
290
- function A2_repr(x, y) {
291
- if (x < 0 || y < 0) throw new Error('x and y must be non-negative integers.');
292
- const h = hyper2(x, y + 3);
293
- if (h.kind === 'bigint') {
294
- return { kind: 'bigint', value: h.value - 3n };
295
- } else if (h.kind === 'pow2') {
296
- return { kind: 'pow2minus3', exp: h.exp };
297
- } else {
298
- return h;
299
- }
300
- }
301
-
302
- // ---------- Meta ----------
303
- function bitLengthBig(x) {
304
- return x.toString(2).length;
305
- }
306
- function digitsOfPow2(exp) {
307
- return Math.floor(Number(exp) * Math.LOG10E * Math.log(2)) + 1;
308
- }
309
- function chips(pairs) {
310
- return pairs
311
- .map(([k, v, cls]) => '<span class="chip ' + (cls || '') + '">' + k + ': ' + v + '</span>')
312
- .join(' ');
313
- }
314
-
315
- // ---------- Render one (uses worker if needed) ----------
316
- function renderOne(x, y) {
317
- const t0 = now();
318
- let rep,
319
- err = null;
320
- try {
321
- rep = A2_repr(x, y);
322
- } catch (e) {
323
- err = e.message || String(e);
324
- }
325
- const t1 = now();
326
- if (err) {
327
- setHTML('one', '<p class="bad">Error: ' + err + '</p>');
328
- return;
329
- }
330
-
331
- if (rep.kind === 'bigint') {
332
- const v = rep.value;
333
- const s = v.toString();
334
- const digits = s.length;
335
- const bits = bitLengthBig(v + 3n);
336
- setHTML(
337
- 'chips',
338
- chips([
339
- ['x', x],
340
- ['y', y],
341
- ['time', (t1 - t0).toFixed(2) + ' ms'],
342
- ['digits', digits],
343
- ['bit_length(A₂+3)', bits],
344
- ]),
345
- );
346
- setHTML(
347
- 'one',
348
- '<p><strong>A₂(' +
349
- x +
350
- ',' +
351
- y +
352
- ')</strong></p><pre class="mono" style="white-space:pre-wrap;overflow:auto">' +
353
- s +
354
- '</pre>',
355
- );
356
- } else if (rep.kind === 'pow2minus3') {
357
- const digits = digitsOfPow2(rep.exp);
358
- const bits = Number(rep.exp) + 1;
359
- if (digits <= DECIMAL_LIMIT) {
360
- // Expand in a worker so the UI stays responsive
361
- setHTML(
362
- 'chips',
363
- chips([
364
- ['x', x],
365
- ['y', y],
366
- ['time', (t1 - t0).toFixed(2) + ' ms'],
367
- ['digits', digits],
368
- ['bit_length(A₂+3)', bits],
369
- ]),
370
- );
371
- setHTML(
372
- 'one',
373
- '<p><strong>A₂(' +
374
- x +
375
- ',' +
376
- y +
377
- ')</strong> <span class="small muted"><span class="spinner"></span> expanding…</span></p>',
378
- );
379
- const w = createPow2Minus3Worker();
380
- w.onmessage = (ev) => {
381
- const d = ev.data || {};
382
- if (d.ok) {
383
- setHTML(
384
- 'chips',
385
- chips([
386
- ['x', x],
387
- ['y', y],
388
- ['time', (t1 - t0).toFixed(2) + ' ms'],
389
- ['expand', d.ms.toFixed ? d.ms.toFixed(1) + ' ms' : d.ms + ' ms'],
390
- ['digits', d.digits],
391
- ['bit_length(A₂+3)', bits],
392
- ]),
393
- );
394
- setHTML(
395
- 'one',
396
- '<p><strong>A₂(' +
397
- x +
398
- ',' +
399
- y +
400
- ')</strong></p><pre class="mono" style="white-space:pre-wrap;overflow:auto">' +
401
- d.text +
402
- '</pre>',
403
- );
404
- } else {
405
- setHTML(
406
- 'one',
407
- '<p class="bad">Expansion failed: ' +
408
- (d.error || 'unknown') +
409
- '</p><div class="small mono muted">A₂(' +
410
- x +
411
- ',' +
412
- y +
413
- ') = 2^(' +
414
- String(rep.exp) +
415
- ') − 3</div>',
416
- );
417
- }
418
- w.terminate();
419
- };
420
- w.postMessage({ exp: String(rep.exp) });
421
- } else {
422
- setHTML(
423
- 'chips',
424
- chips([
425
- ['x', x],
426
- ['y', y],
427
- ['time', (t1 - t0).toFixed(2) + ' ms'],
428
- ['digits', digits],
429
- ['bit_length(A₂+3)', bits],
430
- ]),
431
- );
432
- setHTML(
433
- 'one',
434
- '<p><strong>A₂(' +
435
- x +
436
- ',' +
437
- y +
438
- ')</strong> <em>(not expanded)</em></p><div class="small mono muted">A₂(' +
439
- x +
440
- ',' +
441
- y +
442
- ') = 2^(' +
443
- String(rep.exp) +
444
- ') − 3</div>',
445
- );
446
- }
447
- } else {
448
- setHTML('one', '<p class="bad">Unexpected representation.</p>');
449
- }
450
- }
451
-
452
- // ---------- Demo set (expand safe heavy case via worker) ----------
453
- const DEMO = [
454
- [0, 0],
455
- [0, 6],
456
- [1, 2],
457
- [1, 7],
458
- [2, 2],
459
- [2, 9],
460
- [3, 4],
461
- [3, 14],
462
- [4, 0],
463
- [4, 1],
464
- [4, 2],
465
- [5, 0],
466
- ];
467
-
468
- function runDemos() {
469
- const lines = new Array(DEMO.length);
470
- for (let i = 0; i < DEMO.length; i++) {
471
- const x = DEMO[i][0],
472
- y = DEMO[i][1];
473
- try {
474
- const rep = A2_repr(x, y);
475
- if (rep.kind === 'bigint') {
476
- const s = rep.value.toString();
477
- lines[i] =
478
- 'A' +
479
- String(i).padStart(2, '0') +
480
- ' = A₂(' +
481
- x +
482
- ',' +
483
- y +
484
- ') = ' +
485
- s +
486
- ' (digits=' +
487
- s.length +
488
- ')';
489
- } else if (rep.kind === 'pow2minus3') {
490
- const digits = digitsOfPow2(rep.exp);
491
- if (digits <= DECIMAL_LIMIT) {
492
- // placeholder; expand via worker
493
- lines[i] =
494
- 'A' +
495
- String(i).padStart(2, '0') +
496
- ' = A₂(' +
497
- x +
498
- ',' +
499
- y +
500
- ') = (expanding …) (digits≈' +
501
- digits +
502
- ')';
503
- // kick off worker for this line
504
- const w = createPow2Minus3Worker();
505
- ((idx, X, Y) => {
506
- w.onmessage = (ev) => {
507
- const d = ev.data || {};
508
- if (d.ok) {
509
- const s = d.text;
510
- lines[idx] =
511
- 'A' +
512
- String(idx).padStart(2, '0') +
513
- ' = A₂(' +
514
- X +
515
- ',' +
516
- Y +
517
- ') = ' +
518
- s +
519
- ' (digits=' +
520
- s.length +
521
- ')';
522
- } else {
523
- lines[idx] =
524
- 'A' +
525
- String(idx).padStart(2, '0') +
526
- ' = A₂(' +
527
- X +
528
- ',' +
529
- Y +
530
- ') = (expand failed) (digits≈' +
531
- digits +
532
- ')';
533
- }
534
- setHTML(
535
- 'demosBody',
536
- '<pre class="mono" style="white-space:pre-wrap">' + lines.join('\n') + '</pre>',
537
- );
538
- w.terminate();
539
- };
540
- })(i, x, y);
541
- w.postMessage({ exp: String(rep.exp) });
542
- } else {
543
- lines[i] =
544
- 'A' +
545
- String(i).padStart(2, '0') +
546
- ' = A₂(' +
547
- x +
548
- ',' +
549
- y +
550
- ') = (2^' +
551
- String(rep.exp) +
552
- ' − 3) (digits≈' +
553
- digits +
554
- ')';
555
- }
556
- } else {
557
- lines[i] = 'A' + String(i).padStart(2, '0') + ' = A₂(' + x + ',' + y + ') = [unexpected rep]';
558
- }
559
- } catch (e) {
560
- lines[i] =
561
- 'A' + String(i).padStart(2, '0') + ' = A₂(' + x + ',' + y + ') = [error: ' + (e.message || e) + ']';
562
- }
563
- }
564
- setHTML('demosBody', '<pre class="mono" style="white-space:pre-wrap">' + lines.join('\n') + '</pre>');
565
- $('demos').open = true;
566
- }
567
-
568
- // ---------- Check (unchanged from previous version) ----------
569
- function runChecks() {
570
- const lines = [];
571
- const ok = (b) => (b ? '✓' : '✗');
572
- const t0 = now();
573
- let okAll = true;
574
-
575
- // Closed forms
576
- let o = true;
577
- for (let y = 0; y <= 50; y++) {
578
- const r = A2_repr(0, y);
579
- if (r.kind !== 'bigint' || r.value !== BigInt(y) + 1n) {
580
- o = false;
581
- break;
582
- }
583
- }
584
- lines.push('A₂(0,y) = y+1 on y∈[0,50]? ' + ok(o));
585
- okAll = okAll && o;
586
-
587
- o = true;
588
- for (let y = 0; y <= 50; y++) {
589
- const r = A2_repr(1, y);
590
- if (r.kind !== 'bigint' || r.value !== BigInt(y) + 2n) {
591
- o = false;
592
- break;
593
- }
594
- }
595
- lines.push('A₂(1,y) = y+2 on y∈[0,50]? ' + ok(o));
596
- okAll = okAll && o;
597
-
598
- o = true;
599
- for (let y = 0; y <= 200; y++) {
600
- const r = A2_repr(2, y);
601
- if (r.kind !== 'bigint' || r.value !== 2n * BigInt(y) + 3n) {
602
- o = false;
603
- break;
604
- }
605
- }
606
- lines.push('A₂(2,y) = 2y+3 on y∈[0,200]? ' + ok(o));
607
- okAll = okAll && o;
608
-
609
- o = true;
610
- for (let y = 0; y <= 20; y++) {
611
- const r = A2_repr(3, y);
612
- const want = (1n << BigInt(y + 3)) - 3n;
613
- if (r.kind !== 'bigint' || r.value !== want) {
614
- o = false;
615
- break;
616
- }
617
- }
618
- lines.push('A₂(3,y) = 2^(y+3)−3 on y∈[0,20]? ' + ok(o));
619
- okAll = okAll && o;
620
-
621
- // Spot checks (11/12 exact)
622
- const expected = new Map([
623
- ['0,0', 1n],
624
- ['0,6', 7n],
625
- ['1,2', 4n],
626
- ['1,7', 9n],
627
- ['2,2', 7n],
628
- ['2,9', 21n],
629
- ['3,4', 125n],
630
- ['3,14', (1n << 17n) - 3n],
631
- ['4,0', 13n],
632
- ['4,1', 65533n],
633
- ['5,0', 65533n],
634
- ]);
635
- o = true;
636
- for (const [key, want] of expected) {
637
- const parts = key.split(',');
638
- const x = Number(parts[0]),
639
- y = Number(parts[1]);
640
- const r = A2_repr(x, y);
641
- if (r.kind !== 'bigint' || r.value !== want) {
642
- o = false;
643
- }
644
- }
645
- lines.push('Exact checks for 11/12 queries OK? ' + ok(o));
646
- okAll = okAll && o;
647
-
648
- // Big one handled symbolically in the rep (we expand later via worker if needed)
649
- const r = A2_repr(4, 2);
650
- const pass = r.kind === 'pow2minus3' && String(r.exp) === '65536';
651
- lines.push('A₂(4,2) handled as 2^65536−3 symbolically? ' + ok(pass));
652
- okAll = okAll && pass;
653
-
654
- const t1 = now();
655
- lines.push('');
656
- lines.push('All checks passed? ' + ok(okAll) + ' (' + (t1 - t0).toFixed(1) + ' ms)');
657
- const pre = document.createElement('pre');
658
- pre.className = 'mono';
659
- pre.style.whiteSpace = 'pre-wrap';
660
- pre.textContent = lines.join('\n');
661
- $('check-body').replaceChildren(pre);
662
- }
663
-
664
- // ---------- Wire up ----------
665
- $('compute').addEventListener('click', function () {
666
- const x = Math.max(0, Math.floor(Number($('x').value)));
667
- const y = Math.max(0, Math.floor(Number($('y').value)));
668
- renderOne(x, y);
669
- });
670
- $('demo').addEventListener('click', runDemos);
671
-
672
- // Initial
673
- renderOne(3, 4);
674
- runChecks();
675
- })();
676
- </script>
677
- </body>
678
- </html>