尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證A Scorigami-inspired heatmap of which national football teams have (and haven't) ever played each other — every current FIFA member in one massive grid.
翻譯準備中
取自儲存庫 README
正在載入完整 README。 以下為已儲存的摘錄。
Morocco have never played Mexico. Spain have never played Senegal. Japan have never played
Portugal. Dozens of pairs of top-40 national teams have never met at all.
Fewer than a third of the 22,155 possible men's international fixtures have been played,
and fewer than one in six of the women's. Every pairing is one cell of this grid.
Every current FIFA member is a row and a column. Each cell is a pairing. Red means those two
national teams have never played each other, in 150 years of trying. The grid is creased down
its diagonal: the men's record above it, the women's below.檢視完整 README ↗Morocco have never played Mexico. Spain have never played Senegal. Japan have never played Portugal. Dozens of pairs of top-40 national teams have never met at all.
Fewer than a third of the 22,155 possible men's international fixtures have been played, and fewer than one in six of the women's. Every pairing is one cell of this grid.
▶ Live: https://dgoodenough.github.io/fifagami/
Every current FIFA member is a row and a column. Each cell is a pairing. Red means those two national teams have never played each other, in 150 years of trying. The grid is creased down its diagonal: the men's record above it, the women's below.
Rows and columns are national teams, grouped by confederation and ordered by FIFA ranking within each one. Teams mostly play their neighbours, so the grid fills in along the diagonal and empties out between the blocks.
Red is a pairing that has never happened. Grey is one that has, darker for more meetings. Turn off Never-played and the grid colours by meetings instead, a green ramp from a single match up to Argentina against Uruguay, the most-played fixture in the game, first contested in 1902.
The diagonal is blacked out. A team cannot play itself. It is also the crease: the same two teams appear once above it in the men's game and once below it in the women's.
Every view obeys the same controls. The confederation filter, the ticked teams and the timeline scrubber narrow all five. Filter to CONMEBOL, scrub to 1950, open One-offs, and you have the South American pairs that had met exactly once by 1950. The fold belongs to the grid, which is the only view with a sheet to fold; the four lists read both archives either way.
| View | What it shows |
|---|---|
| Grid | The 211×211 matrix. |
| Fixtures | Pairings that have never met and have a date on the calendar, with a countdown. Also published as a feed. |
| One-offs | Pairings played exactly once across both archives, oldest first. Egypt beat Lithuania 10–0 in 1924 and the two have not met since. |
| Near misses | Pairs that have never met, ranked by opponents they already share. Canada and Sweden have more than seventy in common and have never played. |
| Connect | Tonga has played a dozen countries at most, and still reaches every other national team on earth within three matches. |
prefers-reduced-motion skips it.| Dataset | Source |
|---|---|
| Men's internationals, 1872–present, ~49k matches | martj42/international_results |
| Women's internationals, 1969–present, ~12k matches | martj42/womens-international-results |
| Historical team renames | former_names.csv (martj42) |
| Current FIFA ranking, men's and women's | FotMob, mirroring the official ranking |
| Scheduled internationals | ESPN public scoreboard API |
| Confederation membership | cnc8/fifa-world-ranking |
| FIFA code to ISO 3166-1 | data/iso2.csv |
Current FIFA members only, 211 teams, unless you switch on defunct sides.
Names are reconciled across three sources. They disagree: Côte d'Ivoire against
Ivory Coast, Korea Republic against South Korea, FotMob's USA and Turkiye and
Czechia. build.py resolves them, and former_names.csv folds historical names into the
modern team, so Zaïre counts as DR Congo and Upper Volta as Burkina Faso. USSR resolves to
Russia and Serbia & Montenegro to Serbia, following the source's lineage. Teams that are
neither a current member nor a curated defunct side, mostly non-FIFA territories like
Martinique and Jersey, are excluded, and the build prints all of them.
Rankings are current and per-gender, pulled at build time. The publication date is recorded
in members.json and shown in the app footer. About 14 members have never been given a women's
ranking; under Rank by they sort last on the women's table and on the average, which is an
average only where there are two numbers to take it of. The default — the better of a team's
two ranks — always has one.
The archives have a cut-off. martj42 updates within a day or two of most internationals.
The current cut-off for each is in members.json as data_through, and in the app footer.
What counts as "upcoming" is decided by the browser's date, not the build's, so a fixture that has since been played stops being advertised as a first meeting between data refreshes.
build.py uses only the standard library.
python build.py # download, reconcile, aggregate, write docs/data/*.json
python build.py --refresh # force re-download of every source
python build.py --derive # regenerate derived artifacts only, no network
It writes the artifacts the site loads:
members.json — ordered members with confederation, ranks, flag, data vintagematrix_men.json, matrix_women.json — sparse [i, j, meetings, firstYear, lastYear]matches_men.json, matches_women.json — per-pair detail, fetched only when a cell is clickedyears_men.json, years_women.json — meeting years per pair, delta-encoded, for the scrubberdefunct.json — the defunct-teams layerupcoming.json — scheduled first-ever meetingsfacts.json — the lines the app shows under the headline, derived so they cannot go stalefeed.json, feed.xml — upcoming first meetings, as a subscribable feedpython render_hero.py draws the README image, the share card and the touch icon. It reads the
palette out of docs/style.css and re-sorts the members the way the app does, so the pictures
cannot drift from the site. The share card quotes live figures, so the daily refresh
regenerates it.
Then serve it:
python -m http.server -d docs 8000
python -m unittest discover -s tests -v
A daily GitHub Action commits the build straight to the repo, so nobody reads that diff. The
suite runs in CI on every push and again inside the refresh workflow before it is allowed to
commit. build.py raises on a structurally broken artifact. The tests catch the subtler drift:
a confederation losing members, the most-played fixture changing identity, the feeds falling
out of sync, a fact on the landing page that stopped being true when two teams finally met.
Upcoming first meetings are published as RSS and JSON Feed. Item ids are stable per pair and date, so a reader shows an entry once: when a fixture between two nations that have never met first appears on the calendar. Every item links back to that pairing in the app.
A static site. Vanilla JavaScript and a canvas, no build step, no runtime dependencies, hosted
on GitHub Pages from docs/. The 44,000-cell grid is drawn with view-culling for smooth
zoom and pan, and Pointer Events give mouse and touch a single interaction path.
The fold is three sheets: the destination triangle on the live canvas, plus two offscreen
renders of the same grid — the half that stays put and the half that moves. Each is clipped to
a triangle, and the moving one is hinged on the square's diagonal by a CSS
rotate3d(1, 1, 0) about its top-left corner. Because the matrix is symmetric, a half-turn
lands every cell on the pairing it mirrors, which is what makes the fold mean something: the
flap's back face carries the women's record onto the men's, cell for cell, and the two then
resolve into the four-way key. The hypotenuse of each triangle is offset by one cell so the
diagonal squares stay whole and the two halves register exactly.
Two things keep it quick at 22,155 pairings. The never-played count is a prefix sum over each pair's first-meeting year, so a timeline drag reads it in constant time per frame instead of walking every pair. The played graph is held as bitsets, so common-opponent counts for every never-played pair come out in a few milliseconds.
The one third-party script is GoatCounter, which counts pageviews without cookies or cross-site identifiers.
Styled with Ledger. Greyscale carries structure, colour carries meaning: red is never, green is played, yellow is scheduled.
Match data © the martj42 datasets. Rankings via FotMob. Upcoming fixtures via ESPN. Confederation mapping from cnc8/fifa-world-ranking. Concept inspired by Scorigami (Jon Bois). Code under the MIT License.