個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證製作者的介紹僅有上面的一句話。 更多詳情請閱讀儲存庫 README。 儲存庫 README ↗
正在載入完整 README。
檢視完整 README ↗A private, no-account ratings tracker built for a 10-year-old on an iPad, a phone or a PC — Madden 27
and, since 2026-09-19, NBA 2K27 on the same page. It is a static site: no build step, framework,
analytics, ads, or webfonts. Every rating comes from a feed a script snapshots into data/; nobody
types a rating in here.
Live site: https://clawboriclaw.github.io/janafari/ (basketball straight away: ?sport=nba)
The 🏈 Madden | 🏀 NBA 2K switch in the header flips the whole page: the league, the team picker (30
NBA clubs, ESPN logos), the filters (Guards / Forwards / Centers instead of Offense / Defense / Special
teams), the ⭐ Stars filter (Hall of Fame / Gold badges instead of X-Factor / Superstar abilities), the
player card (size with wingspan, build, hometown, badges by level, top 2K attributes) and the Playbook's
copy. Each sport has its own watchlist and saved weeks (janafari-v2 for Madden, janafari-nba-v1
for NBA 2K) — switching never touches the other list, and a backup file says which sport it belongs to.
The last sport used is remembered (janafari-sport). Each sport has its own easter-egg game: End Zone Run on
the football side, Janafari Jam on the basketball side (below). In the code, everything sport-specific is one SPORTS object at the top of
app.js; the rest reads SPORT and never says "football" itself. Elements that belong to one sport carry
data-sport="nfl|nba" and html[data-sport] hides the other's.
data/abilities.json: our lines for
all 115 names, plus the ea block the fetcher fills from the feed — new names get EA's text automatically).
A player with no badge has no abilities in EA's feed this year (e.g. Aaron Donald at launch).janafari-seen-week-nfl / -nba), so a reload does not
flash again. Opening a player card rolls his overall up from 20 below (600 ms, ease-out); screen readers get
the real number straight away. Both are one-shot, and reduced motion turns both off; the ▲/▼ pills still say it.janafari-ezr-v2 (best) and janafari-ezr-scores-v1 (board). game.js loads only on Play; the loop runs
only while the sheet is open and running; backgrounding pauses; Exit stops loop and sound; sound off until
switched on; reduced motion → no fireworks. Everything scales with the canvas width.hoops.js, NBA side; the hoop button in the footer, More → Play, the Playbook, or catch the
ball that bounces across the top bar) — two-on-two, one button, everything random. Your two Pacers run on their
own; you tap to jump and tap with the ball to shoot. Every basket rerolls the rules: the ball (basketball, beach
ball, bowling ball, mini ball, a football), gravity (moon, heavy), the bodies (giants, shorties, big heads, one of
each), the sky (snow, rain, lights out). First to 5. Beat a team and the next one comes to town in its own colours,
with its two best-rated players from data/nba/ratings.json wearing their real names and numbers — their 2K
three-point rating steers how straight they shoot, dunk rating how they finish at the rim, height is height.
Lose once and your win streak goes on the retro board (janafari-jam-v1, janafari-jam-scores-v1). An 8-second
shot clock, a jump ball after 25 s without a basket, the scored-on team brings it in. 2 players puts a friend on
the ↑ key or the right half of the court. Same house rules as End Zone Run (loop only while open, hidden → pause,
sound off until switched on, reduced motion → no confetti). JanafariHoops.peek() is a read-only snapshot for tests.brand/make_brand.py draws the wordmark and the jersey-patch J as SVG paths (no fonts, so it renders the
same on every device). Chosen 2026-09-12: B · Scoreboard. Outputs: brand/wordmark-B.svg,
brand/mark-B.svg (both inlined in index.html), brand/apple-touch-icon.png (rendered from the vector);
the favicon is the same mark as a data URI. brand/compare.html shows the treatments at header size.
data/nba/)2K publishes no ratings feed — nba.2k.com shows only a top 100 — so the whole league comes from
2K Ratings, the NBA 2K Play Now database (every current team, every player,
35 attributes, badges with 2K's descriptions, and each player's overall on every roster update of the
season). The site sits behind Cloudflare and refuses plain HTTP clients, so tools/fetch_nba_ratings.py
drives a real headless Chromium through Playwright (pip install playwright && python3 -m playwright install chromium; on the WSL box CHROME_PATH=/usr/bin/google-chrome). It writes the same shape as the
Madden files: data/nba/ratings.json (core fields), data/nba/stats/<TEAM>.json (attributes, diffs,
badges with descriptions, loaded when a card opens), data/nba/history.json (one map per roster update —
the site's own labels, "NBA 2K27 Launch Rating", "Nov. 5, 2026", …), plus movement.json (the raw
per-player series), badges.json (2K's text and art for every badge seen + our plain-English lines) and
photos.json (headshots from ESPN's public roster API; 2K Ratings' own images refuse hotlinks), and
data/nba/free-agents.json (2K's own free agency page — see Free agents below).
tools/test_fetch_nba.py pins what a thin sheet, a full sheet, a team page and a broken page parse to (real
pages saved gzipped in tools/fixtures/) — it runs offline before every fetch, so a parser change fails in CI
before a request goes out. .github/workflows/refresh-nba-ratings.yml runs it every day (team pages + only the players whose
overall moved; Sundays every player page) and commits only when something changed. Same exit codes
(0 changed · 3 unchanged · 2 failed → red run + Telegram).
data/)tools/fetch_ratings.py reads EA's feed (it needs EA's own x-feature header or it serves last
season; the script refuses a wrong-season file) and writes data/ratings.json (core fields),
data/stats/<TEAM>.json (attributes, loaded when a card opens), data/history.json (every
iteration's overall ratings, so a week the page was not opened is never lost) and
data/free-agents.json (see Free agents below)..github/workflows/refresh-ratings.yml runs the script every day and commits only when EA's
numbers changed; GitHub Pages redeploys from the commit. Exit codes: 0 changed · 3 unchanged ·
2 failed (the workflow goes red on 2).Neither source rates a player who is not on a roster. EA's Week 1 Ratings simply stopped carrying 1,215 of the 1,240 free agents that Launch Ratings had — Bobby Wagner, Tyreek Hill, Joey Bosa, Joe Mixon — dropping the feed from 3,111 players to 1,891. The page used to react by deleting them: off the board, and silently off someone's list of favourite players, with nothing said and no way back.
They live in free-agents.json now, one file per sport, and the page reads it on demand — only when
a watched player is missing from the feed, otherwise in the background once the board is painted.
lastSeen naming the week they came from. He leaves the file the
day EA carries him again. tools/test_free_agent_pool.py pins that rule and runs offline in CI.lastSeen. A player who leaves every roster and that page is carried
forward the Madden way.FA
chip where a week-over-week arrow would be, a line on the card sheet saying when he was last rated,
and, the first time someone on your list becomes one, a sheet that asks whether to keep him. Every
way out of that sheet keeps him; removing is a deliberate tap next to his name.tools/test_free_agents.py drives all of that in a real browser against the committed data files
(30 checks, both sports, phone and desktop) and runs in the NBA workflow.python3 -m http.server 8027 --bind 0.0.0.0
On a device on the same Wi-Fi, visit http://COMPUTER-IP:8027. In Safari, Share → Add to Home Screen
gives an app-like shortcut. The watchlist lives in that browser's local storage — use ⋯ More → Save a
backup file now and then, because Safari can clear website data. Separate devices do not share.
ES5 only in app.js; no flex gap (margins instead; grids carry a grid-gap twin); a plain colour
before every var(); no webfonts; XHR not fetch. CSS Grid needs iOS 10.3+.
Official sources: https://www.ea.com/games/madden-nfl/ratings · NBA 2K27 via https://www.2kratings.com/