CookbookHobbies and playNo. 53
A fantasy league almanacinjuries, waivers and the league’s history, updated every Tuesday
See it in know.sh
The Gridiron IrregularsNo. 2
Season 2026the Tuesday reports
5 sections, 2,140 words, about 9 minutes, revised the Tuesday after week 5, shared.
Twelve teams, seventeen weeks. Each Tuesday’s report is a section below: the weekend’s injuries, the waiver targets worth a bid, and the week’s result. The platform’s scores are the official ones; the chart is copied from its scoreboard every Tuesday.
Points by week, the four top-scoring teams, weeks 1 to 5
| Week | Fourth and Long | Hail Mary Club | Two-Minute Drill | The Taxi Squad |
|---|---|---|---|---|
| Week 1 | 118.4 points | 102.6 points | 125.9 points | 91.3 points |
| Week 2 | 96.2 points | 124.8 points | 83.7 points | 108.5 points |
| Week 3 | 131.7 points | 88.3 points | 99.2 points | 112 points |
| Week 4 | 104.9 points | 115.1 points | 121.6 points | 79.4 points |
| Week 5 | 122.3 points | 109.6 points | 94.5 points | 127.8 points |
Weekly scores from the league’s platform, half-point per reception.
Points by week, the four top-scoring teams, weeks 1 to 5
| Week | Fourth and Long | Hail Mary Club | Two-Minute Drill | The Taxi Squad |
|---|---|---|---|---|
| Week 1 | 118.4 points | 102.6 points | 125.9 points | 91.3 points |
| Week 2 | 96.2 points | 124.8 points | 83.7 points | 108.5 points |
| Week 3 | 131.7 points | 88.3 points | 99.2 points | 112 points |
| Week 4 | 104.9 points | 115.1 points | 121.6 points | 79.4 points |
| Week 5 | 122.3 points | 109.6 points | 94.5 points | 127.8 points |
Values: Points scored
Marked at Week 5: The Monday comeback.
Source: Weekly scores from the league’s platform, half-point per reception.
```element chart
{
"type": "line",
"caption": "Points by week, the four top-scoring teams, weeks 1 to 5",
"dimension": "Week",
"labels": [
{
"label": "Week 1"
},
{
"label": "Week 2"
},
{
"label": "Week 3"
},
{
"label": "Week 4"
},
{
"label": "Week 5"
}
],
"series": [
{
"name": "Fourth and Long",
"values": "118.4, 96.2, 131.7, 104.9, 122.3"
},
{
"name": "Hail Mary Club",
"values": "102.6, 124.8, 88.3, 115.1, 109.6"
},
{
"name": "Two-Minute Drill",
"values": "125.9, 83.7, 99.2, 121.6, 94.5"
},
{
"name": "The Taxi Squad",
"values": "91.3, 108.5, 112.0, 79.4, 127.8"
}
],
"units": "points",
"measure": "Points scored",
"axisTitles": true,
"markers": true,
"highlight": "The Taxi Squad",
"annotations": [
{
"axis": "x",
"at": "Week 5",
"label": "The Monday comeback"
}
],
"source": "Weekly scores from the league’s platform, half-point per reception."
}
```After five weeks Fourth and Long lead on points, 573.5 to Hail Mary Club’s 540.4. The standings go by wins, and those are on the platform.
Sections
- 1Week 1: the opener, and two starters hurtObservation
- 2Week 2: the first waiver runObservationEleven bids, and the season’s first argument about the budget.
- 3Week 3: Fourth and Long score 131.7ObservationThe highest score of the season so far.
- 4Week 4: The Taxi Squad’s worst weekObservation
- 5Week 5: injuries, waivers and the Monday comebackObservation, keyThe Taxi Squad were 19 points behind Fourth and Long going into Monday night, and won by 5.5.
The Gridiron IrregularsRulebook
1of 6
Scoring
Observation, key section, 1 element, 1 note, 290 words
Players. One point for every 25 passing yards and every 10 rushing or receiving yards, counted to the decimal as the platform does. Four points for a passing touchdown, six for a rushing or receiving touchdown, two for a two-point conversion however it is scored, and half a point for each reception. Minus two for an interception thrown and for a fumble lost. Kickers and team defences score by the platform’s defaults, as its settings page lists them.
Why half a point. The league voted in August 2019, 7 to 5, to move from standard scoring to half-PPR, so that a catch is worth as much as five yards: backs and receivers who catch the ball count for more, while a one-yard catch still scores less than a ten-yard run, which under full PPR it would not.
Fantasy points, three ways
Enter one player’s stat line and see its points under standard, half-PPR and PPR scoring side by side, each line of the arithmetic shown. The rules are the Gridiron Irregulars’ own, which are also the common defaults: 1 point per 25 passing yards, 4 per passing touchdown, −2 per interception, 1 per 10 rushing or receiving yards, 6 per rushing or receiving touchdown, −2 per fumble lost, 2 per two-point conversion, and 0, 0.5 or 1 per reception; the league plays half-PPR. Yards count to the decimal unless you tick whole blocks. Kickers, defences, return touchdowns and bonuses are left out.
<div class="fp">
<div class="presets" role="group" aria-label="Fill in an example stat line">
<span>Try</span>
<button type="button" data-preset="qb" aria-label="A quarterback"><span class="long">A quarterback</span><span class="short">QB</span></button>
<button type="button" data-preset="rb" aria-label="A running back" aria-pressed="true"><span class="long">A running back</span><span class="short">RB</span></button>
<button type="button" data-preset="wr" aria-label="A receiver"><span class="long">A receiver</span><span class="short">WR</span></button>
<button type="button" data-preset="clear">Clear</button>
</div>
<div class="grid">
<label><span class="long">Passing yards</span><span class="short">Pass yards</span><input type="number" inputmode="numeric" aria-label="Passing yards" data-k="passYd" min="-99" max="999" step="1"></label>
<label><span class="long">Passing TDs</span><span class="short">Pass TDs</span><input type="number" inputmode="numeric" aria-label="Passing TDs" data-k="passTd" min="0" max="15" step="1"></label>
<label><span>Interceptions</span><input type="number" inputmode="numeric" data-k="int" min="0" max="15" step="1"></label>
<label><span class="long">Rushing yards</span><span class="short">Rush yards</span><input type="number" inputmode="numeric" aria-label="Rushing yards" data-k="rushYd" min="-99" max="999" step="1"></label>
<label><span class="long">Rushing TDs</span><span class="short">Rush TDs</span><input type="number" inputmode="numeric" aria-label="Rushing TDs" data-k="rushTd" min="0" max="15" step="1"></label>
<label><span>Receptions</span><input type="number" inputmode="numeric" data-k="rec" min="0" max="40" step="1"></label>
<label><span class="long">Receiving yards</span><span class="short">Rec. yards</span><input type="number" inputmode="numeric" aria-label="Receiving yards" data-k="recYd" min="-99" max="999" step="1"></label>
<label><span class="long">Receiving TDs</span><span class="short">Rec. TDs</span><input type="number" inputmode="numeric" aria-label="Receiving TDs" data-k="recTd" min="0" max="15" step="1"></label>
<label><span>Fumbles lost</span><input type="number" inputmode="numeric" data-k="fum" min="0" max="15" step="1"></label>
<label><span class="long">Two-point conversions</span><span class="short">2-pt conversions</span><input type="number" inputmode="numeric" aria-label="Two-point conversions" data-k="twoPt" min="0" max="15" step="1"></label>
<label class="whole"><input type="checkbox" id="whole"> <span>Whole blocks only: a point per full 25 passing yards or 10 rushing or receiving yards</span></label>
</div>
<table>
<thead><tr><th scope="col">Line</th><th scope="col" class="n"><span class="long">Standard</span><span class="short">Std</span></th><th scope="col" class="n ours"><span class="long">Half-PPR</span><span class="short">Half</span></th><th scope="col" class="n">PPR</th></tr></thead>
<tbody id="lines"></tbody>
<tfoot><tr><th scope="row">Total</th><td class="n" id="tStd"></td><td class="n ours" id="tHalf"></td><td class="n" id="tPpr"></td></tr></tfoot>
</table>
<p class="say" id="say" aria-live="polite"></p>
</div>.fp { font: 400 14px/1.4 var(--sans); color: var(--ink); }
.presets { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 12px; }
.presets > span { font: 400 13px var(--sans); color: var(--ink-3); margin-right: 2px; }
button { font: 500 13px/1 var(--sans); color: var(--ink); background: var(--paper); border: 1px solid var(--ink); border-radius: 0; padding: 8px 10px; min-height: 36px; cursor: pointer; touch-action: manipulation; }
button[aria-pressed='true'] { background: var(--ink); color: var(--paper); }
button:focus-visible, input:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px 10px; }
.grid label { display: flex; flex-direction: column; justify-content: flex-end; gap: 3px; font: 400 12.5px/1.25 var(--sans); color: var(--ink-2); }
.grid input { width: 100%; font: 400 16px var(--sans); padding: 5px 6px; font-variant-numeric: tabular-nums; }
.grid .whole { grid-column: 1 / -1; flex-direction: row; justify-content: flex-start; align-items: flex-start; gap: 8px; margin-top: 4px; font: 400 13px/1.35 var(--sans); color: var(--ink-2); }
.grid .whole input { width: auto; margin-top: 2px; flex: none; }
table { width: 100%; border-collapse: collapse; margin-top: 10px; font-variant-numeric: tabular-nums; }
th, td { padding: 5px 8px 5px 0; vertical-align: top; }
th.n, td.n { text-align: right; padding-right: 0; padding-left: 8px; width: 17%; white-space: nowrap; }
.ours { background: var(--wash); padding-right: 6px !important; }
thead th { font: 500 13px var(--sans); color: var(--ink); border-bottom: 1px solid var(--ink); }
tbody td, tbody th { border-bottom: 1px solid var(--rule); }
tbody th { font: 400 14px/1.3 var(--sans); color: var(--ink); text-align: left; }
tbody th small { display: block; font: 400 12.5px/1.3 var(--mono); color: var(--ink-3); margin-top: 1px; white-space: nowrap; }
tbody td { font: 400 15px/1.3 var(--sans); font-variant-numeric: lining-nums tabular-nums; }
tfoot th, tfoot td { border-top: 1px solid var(--ink); border-bottom: 0; font: 600 16px/1.3 var(--sans); font-variant-numeric: lining-nums tabular-nums; padding-top: 7px; text-align: left; }
tfoot td { text-align: right; }
.short { display: none; }
.empty td { color: var(--ink-3); font: italic 400 15px var(--serif); }
.say { margin: 10px 0 0; min-height: 1.4em; font: italic 400 16px/1.45 var(--serif); font-variant-numeric: lining-nums; color: var(--ink-2); }
@media (max-width: 560px) { .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px 8px; } .long { display: none; } .short { display: inline; } th.n, td.n { width: 18%; } tbody th small { display: inline-block; margin: 0 0 0 5px; } .grid .whole { grid-column: span 2; } th, td { padding-top: 4px; padding-bottom: 4px; } }(function () {
var root = document.querySelector('.fp');
var inputs = {};
root.querySelectorAll('[data-k]').forEach(function (el) { inputs[el.getAttribute('data-k')] = el; });
var PRESETS = {
qb: { passYd: 287, passTd: 2, int: 1, rushYd: 18, rushTd: 0, rec: 0, recYd: 0, recTd: 0, fum: 0, twoPt: 0 },
rb: { passYd: 0, passTd: 0, int: 0, rushYd: 94, rushTd: 1, rec: 5, recYd: 38, recTd: 0, fum: 1, twoPt: 1 },
wr: { passYd: 0, passTd: 0, int: 0, rushYd: 6, rushTd: 0, rec: 8, recYd: 112, recTd: 1, fum: 0, twoPt: 0 },
clear: { passYd: 0, passTd: 0, int: 0, rushYd: 0, rushTd: 0, rec: 0, recYd: 0, recTd: 0, fum: 0, twoPt: 0 }
};
function num(k) {
var v = Math.trunc(Number(inputs[k].value));
if (!isFinite(v)) return 0;
var lo = Number(inputs[k].min), hi = Number(inputs[k].max);
return Math.max(lo, Math.min(hi, v));
}
// Points are kept in hundredths, so 0.04 a yard never rounds wrongly.
function fmt(h) {
var s = (Math.abs(h) / 100).toFixed(2).replace(/\.?0+$/, '');
return (h < 0 ? '−' : '') + s;
}
function minus(n) { return n < 0 ? '−' + Math.abs(n) : String(n); }
function lines(s, whole) {
var out = [];
function yards(label, n, per) {
if (!n) return;
var h = whole ? Math.trunc(n / per) * 100 : n * 100 / per;
out.push({ label: label, math: minus(n) + ' ÷ ' + per + (whole ? ', whole blocks' : ''), pts: [h, h, h] });
}
function each(label, n, pts) {
if (!n) return;
var h = n * pts;
out.push({ label: label, math: n + ' × ' + fmt(pts), pts: [h, h, h] });
}
yards('Passing yards', s.passYd, 25);
each('Passing TDs', s.passTd, 400);
each('Interceptions', s.int, -200);
yards('Rushing yards', s.rushYd, 10);
each('Rushing TDs', s.rushTd, 600);
if (s.rec) out.push({ label: 'Receptions', math: s.rec + ' × 0 / 0.5 / 1', pts: [0, s.rec * 50, s.rec * 100] });
yards('Receiving yards', s.recYd, 10);
each('Receiving TDs', s.recTd, 600);
each('Fumbles lost', s.fum, -200);
each('Two-point conversions', s.twoPt, 200);
return out;
}
function td(h, ours) { return '<td class="n' + (ours ? ' ours' : '') + '">' + fmt(h) + '</td>'; }
function render() {
var s = {};
Object.keys(inputs).forEach(function (k) { s[k] = num(k); });
var whole = root.querySelector('#whole').checked;
var ls = lines(s, whole);
var tot = [0, 0, 0];
ls.forEach(function (l) { for (var i = 0; i < 3; i++) tot[i] += l.pts[i]; });
var body = root.querySelector('#lines');
if (!ls.length) body.innerHTML = '<tr class="empty"><td colspan="4">Enter a stat line above.</td></tr>';
else body.innerHTML = ls.map(function (l) {
return '<tr><th scope="row">' + l.label + '<small>' + l.math + '</small></th>' + td(l.pts[0]) + td(l.pts[1], true) + td(l.pts[2]) + '</tr>';
}).join('');
root.querySelector('#tStd').textContent = fmt(tot[0]);
root.querySelector('#tHalf').textContent = fmt(tot[1]);
root.querySelector('#tPpr').textContent = fmt(tot[2]);
var gap = s.rec ? ' The ' + fmt(tot[2] - tot[0]) + '-point gap is all receptions.' : ' No receptions, so all three agree.';
root.querySelector('#say').textContent = 'Standard ' + fmt(tot[0]) + ', half-PPR ' + fmt(tot[1]) + ' (ours), PPR ' + fmt(tot[2]) + '.' + gap;
}
function fill(name) {
var p = PRESETS[name];
Object.keys(p).forEach(function (k) { inputs[k].value = p[k] ? String(p[k]) : ''; });
root.querySelectorAll('[data-preset]').forEach(function (b) {
if (b.getAttribute('data-preset') !== 'clear') b.setAttribute('aria-pressed', String(b.getAttribute('data-preset') === name));
});
render();
}
root.querySelectorAll('[data-preset]').forEach(function (b) {
b.addEventListener('click', function () { fill(b.getAttribute('data-preset')); });
});
Object.keys(inputs).forEach(function (k) {
inputs[k].placeholder = '0';
inputs[k].addEventListener('input', function () {
root.querySelectorAll('[data-preset]').forEach(function (b) { if (b.hasAttribute('aria-pressed')) b.setAttribute('aria-pressed', 'false'); });
render();
});
});
root.querySelector('#whole').addEventListener('change', render);
fill('rb');
})();```element widget
{
"title": "Fantasy points, three ways",
"caption": "Enter one player’s stat line and see its points under standard, half-PPR and PPR scoring side by side, each line of the arithmetic shown. The rules are the Gridiron Irregulars’ own, which are also the common defaults: 1 point per 25 passing yards, 4 per passing touchdown, −2 per interception, 1 per 10 rushing or receiving yards, 6 per rushing or receiving touchdown, −2 per fumble lost, 2 per two-point conversion, and 0, 0.5 or 1 per reception; the league plays half-PPR. Yards count to the decimal unless you tick whole blocks. Kickers, defences, return touchdowns and bonuses are left out.",
"height": 620,
"html": "<div class=\"fp\">\n <div class=\"presets\" role=\"group\" aria-label=\"Fill in an example stat line\">\n <span>Try</span>\n <button type=\"button\" data-preset=\"qb\" aria-label=\"A quarterback\"><span class=\"long\">A quarterback</span><span class=\"short\">QB</span></button>\n <button type=\"button\" data-preset=\"rb\" aria-label=\"A running back\" aria-pressed=\"true\"><span class=\"long\">A running back</span><span class=\"short\">RB</span></button>\n <button type=\"button\" data-preset=\"wr\" aria-label=\"A receiver\"><span class=\"long\">A receiver</span><span class=\"short\">WR</span></button>\n <button type=\"button\" data-preset=\"clear\">Clear</button>\n </div>\n <div class=\"grid\">\n <label><span class=\"long\">Passing yards</span><span class=\"short\">Pass yards</span><input type=\"number\" inputmode=\"numeric\" aria-label=\"Passing yards\" data-k=\"passYd\" min=\"-99\" max=\"999\" step=\"1\"></label>\n <label><span class=\"long\">Passing TDs</span><span class=\"short\">Pass TDs</span><input type=\"number\" inputmode=\"numeric\" aria-label=\"Passing TDs\" data-k=\"passTd\" min=\"0\" max=\"15\" step=\"1\"></label>\n <label><span>Interceptions</span><input type=\"number\" inputmode=\"numeric\" data-k=\"int\" min=\"0\" max=\"15\" step=\"1\"></label>\n <label><span class=\"long\">Rushing yards</span><span class=\"short\">Rush yards</span><input type=\"number\" inputmode=\"numeric\" aria-label=\"Rushing yards\" data-k=\"rushYd\" min=\"-99\" max=\"999\" step=\"1\"></label>\n <label><span class=\"long\">Rushing TDs</span><span class=\"short\">Rush TDs</span><input type=\"number\" inputmode=\"numeric\" aria-label=\"Rushing TDs\" data-k=\"rushTd\" min=\"0\" max=\"15\" step=\"1\"></label>\n <label><span>Receptions</span><input type=\"number\" inputmode=\"numeric\" data-k=\"rec\" min=\"0\" max=\"40\" step=\"1\"></label>\n <label><span class=\"long\">Receiving yards</span><span class=\"short\">Rec. yards</span><input type=\"number\" inputmode=\"numeric\" aria-label=\"Receiving yards\" data-k=\"recYd\" min=\"-99\" max=\"999\" step=\"1\"></label>\n <label><span class=\"long\">Receiving TDs</span><span class=\"short\">Rec. TDs</span><input type=\"number\" inputmode=\"numeric\" aria-label=\"Receiving TDs\" data-k=\"recTd\" min=\"0\" max=\"15\" step=\"1\"></label>\n <label><span>Fumbles lost</span><input type=\"number\" inputmode=\"numeric\" data-k=\"fum\" min=\"0\" max=\"15\" step=\"1\"></label>\n <label><span class=\"long\">Two-point conversions</span><span class=\"short\">2-pt conversions</span><input type=\"number\" inputmode=\"numeric\" aria-label=\"Two-point conversions\" data-k=\"twoPt\" min=\"0\" max=\"15\" step=\"1\"></label>\n <label class=\"whole\"><input type=\"checkbox\" id=\"whole\"> <span>Whole blocks only: a point per full 25 passing yards or 10 rushing or receiving yards</span></label>\n </div>\n <table>\n <thead><tr><th scope=\"col\">Line</th><th scope=\"col\" class=\"n\"><span class=\"long\">Standard</span><span class=\"short\">Std</span></th><th scope=\"col\" class=\"n ours\"><span class=\"long\">Half-PPR</span><span class=\"short\">Half</span></th><th scope=\"col\" class=\"n\">PPR</th></tr></thead>\n <tbody id=\"lines\"></tbody>\n <tfoot><tr><th scope=\"row\">Total</th><td class=\"n\" id=\"tStd\"></td><td class=\"n ours\" id=\"tHalf\"></td><td class=\"n\" id=\"tPpr\"></td></tr></tfoot>\n </table>\n <p class=\"say\" id=\"say\" aria-live=\"polite\"></p>\n</div>",
"css": ".fp { font: 400 14px/1.4 var(--sans); color: var(--ink); }\n.presets { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 12px; }\n.presets > span { font: 400 13px var(--sans); color: var(--ink-3); margin-right: 2px; }\nbutton { font: 500 13px/1 var(--sans); color: var(--ink); background: var(--paper); border: 1px solid var(--ink); border-radius: 0; padding: 8px 10px; min-height: 36px; cursor: pointer; touch-action: manipulation; }\nbutton[aria-pressed='true'] { background: var(--ink); color: var(--paper); }\nbutton:focus-visible, input:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }\n.grid { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px 10px; }\n.grid label { display: flex; flex-direction: column; justify-content: flex-end; gap: 3px; font: 400 12.5px/1.25 var(--sans); color: var(--ink-2); }\n.grid input { width: 100%; font: 400 16px var(--sans); padding: 5px 6px; font-variant-numeric: tabular-nums; }\n.grid .whole { grid-column: 1 / -1; flex-direction: row; justify-content: flex-start; align-items: flex-start; gap: 8px; margin-top: 4px; font: 400 13px/1.35 var(--sans); color: var(--ink-2); }\n.grid .whole input { width: auto; margin-top: 2px; flex: none; }\ntable { width: 100%; border-collapse: collapse; margin-top: 10px; font-variant-numeric: tabular-nums; }\nth, td { padding: 5px 8px 5px 0; vertical-align: top; }\nth.n, td.n { text-align: right; padding-right: 0; padding-left: 8px; width: 17%; white-space: nowrap; }\n.ours { background: var(--wash); padding-right: 6px !important; }\nthead th { font: 500 13px var(--sans); color: var(--ink); border-bottom: 1px solid var(--ink); }\ntbody td, tbody th { border-bottom: 1px solid var(--rule); }\ntbody th { font: 400 14px/1.3 var(--sans); color: var(--ink); text-align: left; }\ntbody th small { display: block; font: 400 12.5px/1.3 var(--mono); color: var(--ink-3); margin-top: 1px; white-space: nowrap; }\ntbody td { font: 400 15px/1.3 var(--sans); font-variant-numeric: lining-nums tabular-nums; }\ntfoot th, tfoot td { border-top: 1px solid var(--ink); border-bottom: 0; font: 600 16px/1.3 var(--sans); font-variant-numeric: lining-nums tabular-nums; padding-top: 7px; text-align: left; }\ntfoot td { text-align: right; }\n.short { display: none; }\n.empty td { color: var(--ink-3); font: italic 400 15px var(--serif); }\n.say { margin: 10px 0 0; min-height: 1.4em; font: italic 400 16px/1.45 var(--serif); font-variant-numeric: lining-nums; color: var(--ink-2); }\n@media (max-width: 560px) { .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px 8px; } .long { display: none; } .short { display: inline; } th.n, td.n { width: 18%; } tbody th small { display: inline-block; margin: 0 0 0 5px; } .grid .whole { grid-column: span 2; } th, td { padding-top: 4px; padding-bottom: 4px; } }",
"js": "(function () {\n var root = document.querySelector('.fp');\n var inputs = {};\n root.querySelectorAll('[data-k]').forEach(function (el) { inputs[el.getAttribute('data-k')] = el; });\n var PRESETS = {\n qb: { passYd: 287, passTd: 2, int: 1, rushYd: 18, rushTd: 0, rec: 0, recYd: 0, recTd: 0, fum: 0, twoPt: 0 },\n rb: { passYd: 0, passTd: 0, int: 0, rushYd: 94, rushTd: 1, rec: 5, recYd: 38, recTd: 0, fum: 1, twoPt: 1 },\n wr: { passYd: 0, passTd: 0, int: 0, rushYd: 6, rushTd: 0, rec: 8, recYd: 112, recTd: 1, fum: 0, twoPt: 0 },\n clear: { passYd: 0, passTd: 0, int: 0, rushYd: 0, rushTd: 0, rec: 0, recYd: 0, recTd: 0, fum: 0, twoPt: 0 }\n };\n\n function num(k) {\n var v = Math.trunc(Number(inputs[k].value));\n if (!isFinite(v)) return 0;\n var lo = Number(inputs[k].min), hi = Number(inputs[k].max);\n return Math.max(lo, Math.min(hi, v));\n }\n // Points are kept in hundredths, so 0.04 a yard never rounds wrongly.\n function fmt(h) {\n var s = (Math.abs(h) / 100).toFixed(2).replace(/\\.?0+$/, '');\n return (h < 0 ? '−' : '') + s;\n }\n function minus(n) { return n < 0 ? '−' + Math.abs(n) : String(n); }\n\n function lines(s, whole) {\n var out = [];\n function yards(label, n, per) {\n if (!n) return;\n var h = whole ? Math.trunc(n / per) * 100 : n * 100 / per;\n out.push({ label: label, math: minus(n) + ' ÷ ' + per + (whole ? ', whole blocks' : ''), pts: [h, h, h] });\n }\n function each(label, n, pts) {\n if (!n) return;\n var h = n * pts;\n out.push({ label: label, math: n + ' × ' + fmt(pts), pts: [h, h, h] });\n }\n yards('Passing yards', s.passYd, 25);\n each('Passing TDs', s.passTd, 400);\n each('Interceptions', s.int, -200);\n yards('Rushing yards', s.rushYd, 10);\n each('Rushing TDs', s.rushTd, 600);\n if (s.rec) out.push({ label: 'Receptions', math: s.rec + ' × 0 / 0.5 / 1', pts: [0, s.rec * 50, s.rec * 100] });\n yards('Receiving yards', s.recYd, 10);\n each('Receiving TDs', s.recTd, 600);\n each('Fumbles lost', s.fum, -200);\n each('Two-point conversions', s.twoPt, 200);\n return out;\n }\n\n function td(h, ours) { return '<td class=\"n' + (ours ? ' ours' : '') + '\">' + fmt(h) + '</td>'; }\n\n function render() {\n var s = {};\n Object.keys(inputs).forEach(function (k) { s[k] = num(k); });\n var whole = root.querySelector('#whole').checked;\n var ls = lines(s, whole);\n var tot = [0, 0, 0];\n ls.forEach(function (l) { for (var i = 0; i < 3; i++) tot[i] += l.pts[i]; });\n var body = root.querySelector('#lines');\n if (!ls.length) body.innerHTML = '<tr class=\"empty\"><td colspan=\"4\">Enter a stat line above.</td></tr>';\n else body.innerHTML = ls.map(function (l) {\n return '<tr><th scope=\"row\">' + l.label + '<small>' + l.math + '</small></th>' + td(l.pts[0]) + td(l.pts[1], true) + td(l.pts[2]) + '</tr>';\n }).join('');\n root.querySelector('#tStd').textContent = fmt(tot[0]);\n root.querySelector('#tHalf').textContent = fmt(tot[1]);\n root.querySelector('#tPpr').textContent = fmt(tot[2]);\n var gap = s.rec ? ' The ' + fmt(tot[2] - tot[0]) + '-point gap is all receptions.' : ' No receptions, so all three agree.';\n root.querySelector('#say').textContent = 'Standard ' + fmt(tot[0]) + ', half-PPR ' + fmt(tot[1]) + ' (ours), PPR ' + fmt(tot[2]) + '.' + gap;\n }\n\n function fill(name) {\n var p = PRESETS[name];\n Object.keys(p).forEach(function (k) { inputs[k].value = p[k] ? String(p[k]) : ''; });\n root.querySelectorAll('[data-preset]').forEach(function (b) {\n if (b.getAttribute('data-preset') !== 'clear') b.setAttribute('aria-pressed', String(b.getAttribute('data-preset') === name));\n });\n render();\n }\n\n root.querySelectorAll('[data-preset]').forEach(function (b) {\n b.addEventListener('click', function () { fill(b.getAttribute('data-preset')); });\n });\n Object.keys(inputs).forEach(function (k) {\n inputs[k].placeholder = '0';\n inputs[k].addEventListener('input', function () {\n root.querySelectorAll('[data-preset]').forEach(function (b) { if (b.hasAttribute('aria-pressed')) b.setAttribute('aria-pressed', 'false'); });\n render();\n });\n });\n root.querySelector('#whole').addEventListener('change', render);\n fill('rb');\n})();"
}
```Checking a score. The platform’s number is the official one. When a manager disputes it, type the player’s box-score line into the calculator above and see where every point came from. If the calculator and the platform disagree, the platform’s settings decide, and the commissioner files what was found as a Decision.
How it works
Every Tuesday a scheduled task gathers the weekend’s injury news and the waiver targets that fit your scoring, and your assistant files the week’s report with its sources. The rulebook sits one link away, with a scoring calculator that shows where every half point came from, and the season’s points by week drawn as a line chart.
Try this prompt
Made with
ShelfDocumentScheduled runsYour AI assistantElementsPublic link