diff --git a/changelog.json b/changelog.json index aac818b..245f3f8 100644 --- a/changelog.json +++ b/changelog.json @@ -8,7 +8,8 @@ "Lookup cache: a TTL of 0 switches it off, so a callbook record you are correcting is re-read every time.", "TCI: when the radio forbids transmitting, PTT now says so instead of doing nothing silently.", "TCI sharing: the server now announces transmit permission, without which a client such as MSHV never keys at all.", - "TCI sharing: split is armed on the frequency the client asked for, whichever order it sent the two commands in." + "TCI sharing: split is armed on the frequency the client asked for, whichever order it sent the two commands in.", + "WAJA carried Japan’s civil prefecture numbers instead of the JARL’s: 35 of the 47 references are renumbered." ], "fr": [ "Une entité qui est un seul groupe d’îles remplit désormais la référence IOTA toute seule, sans abonnement callbook.", @@ -16,7 +17,8 @@ "Cache des recherches : un TTL à 0 le désactive, pour relire à chaque fois une fiche callbook en cours de correction.", "TCI : quand la radio interdit l’émission, le PTT le dit désormais au lieu de ne rien faire en silence.", "Partage TCI : le serveur annonce désormais l’autorisation d’émettre, sans laquelle un client comme MSHV ne passe jamais en émission.", - "Partage TCI : le split s’arme sur la fréquence demandée par le logiciel, quel que soit l’ordre de ses deux commandes." + "Partage TCI : le split s’arme sur la fréquence demandée par le logiciel, quel que soit l’ordre de ses deux commandes.", + "WAJA portait les numéros civils des préfectures japonaises et non ceux de la JARL : 35 des 47 références sont renumérotées." ] }, { diff --git a/internal/award/catalog/waja.json b/internal/award/catalog/waja.json index cbb36be..5b7aadb 100644 --- a/internal/award/catalog/waja.json +++ b/internal/award/catalog/waja.json @@ -46,11 +46,12 @@ "qsl" ], "total": 0, - "builtin": true + "builtin": true, + "version": 2 }, "references": [ { - "code": "1", + "code": "01", "name": "Hokkaido", "dxcc": 0, "group": "", @@ -58,16 +59,81 @@ "valid": true }, { - "code": "10", - "name": "Gunma", + "code": "02", + "name": "Aomori", "dxcc": 0, "group": "", "subgrp": "", "valid": true }, + { + "code": "03", + "name": "Iwate", + "dxcc": 0, + "group": "", + "subgrp": "", + "valid": true + }, + { + "code": "04", + "name": "Akita", + "dxcc": 0, + "group": "", + "subgrp": "", + "valid": true + }, + { + "code": "05", + "name": "Yamagata", + "dxcc": 0, + "group": "", + "subgrp": "", + "valid": true + }, + { + "code": "06", + "name": "Miyagi", + "dxcc": 0, + "group": "", + "subgrp": "", + "valid": true + }, + { + "code": "07", + "name": "Fukushima", + "dxcc": 0, + "group": "", + "subgrp": "", + "valid": true + }, + { + "code": "08", + "name": "Niigata", + "dxcc": 0, + "group": "", + "subgrp": "", + "valid": true + }, + { + "code": "09", + "name": "Nagano", + "dxcc": 0, + "group": "", + "subgrp": "", + "valid": true + }, + { + "code": "10", + "name": "Tokyo", + "dxcc": 0, + "group": "", + "subgrp": "", + "pattern": "\\bTok[iy]o\\b", + "valid": true + }, { "code": "11", - "name": "Saitama", + "name": "Kanagawa", "dxcc": 0, "group": "", "subgrp": "", @@ -83,16 +149,15 @@ }, { "code": "13", - "name": "Tokyo", + "name": "Saitama", "dxcc": 0, "group": "", "subgrp": "", - "pattern": "\\bTok[iy]o\\b", "valid": true }, { "code": "14", - "name": "Kanagawa", + "name": "Ibaraki", "dxcc": 0, "group": "", "subgrp": "", @@ -100,7 +165,7 @@ }, { "code": "15", - "name": "Niigata", + "name": "Tochigi", "dxcc": 0, "group": "", "subgrp": "", @@ -108,7 +173,7 @@ }, { "code": "16", - "name": "Toyama", + "name": "Gunma", "dxcc": 0, "group": "", "subgrp": "", @@ -116,22 +181,6 @@ }, { "code": "17", - "name": "Ishikawa", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true - }, - { - "code": "18", - "name": "Fukui", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true - }, - { - "code": "19", "name": "Yamanashi", "dxcc": 0, "group": "", @@ -139,31 +188,7 @@ "valid": true }, { - "code": "2", - "name": "Aomori", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true - }, - { - "code": "20", - "name": "Nagano", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true - }, - { - "code": "21", - "name": "Gifu", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true - }, - { - "code": "22", + "code": "18", "name": "Shizuoka", "dxcc": 0, "group": "", @@ -171,7 +196,15 @@ "valid": true }, { - "code": "23", + "code": "19", + "name": "Gifu", + "dxcc": 0, + "group": "", + "subgrp": "", + "valid": true + }, + { + "code": "20", "name": "Aichi", "dxcc": 0, "group": "", @@ -179,7 +212,7 @@ "valid": true }, { - "code": "24", + "code": "21", "name": "Mie", "dxcc": 0, "group": "", @@ -187,15 +220,7 @@ "valid": true }, { - "code": "25", - "name": "Shiga", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true - }, - { - "code": "26", + "code": "22", "name": "Kyoto", "dxcc": 0, "group": "", @@ -203,23 +228,15 @@ "valid": true }, { - "code": "27", - "name": "Osaka", + "code": "23", + "name": "Shiga", "dxcc": 0, "group": "", "subgrp": "", "valid": true }, { - "code": "28", - "name": "Hyogo", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true - }, - { - "code": "29", + "code": "24", "name": "Nara", "dxcc": 0, "group": "", @@ -227,24 +244,56 @@ "valid": true }, { - "code": "3", - "name": "Iwate", + "code": "25", + "name": "Osaka", "dxcc": 0, "group": "", "subgrp": "", "valid": true }, { - "code": "30", + "code": "26", "name": "Wakayama", "dxcc": 0, "group": "", "subgrp": "", "valid": true }, + { + "code": "27", + "name": "Hyogo", + "dxcc": 0, + "group": "", + "subgrp": "", + "valid": true + }, + { + "code": "28", + "name": "Toyama", + "dxcc": 0, + "group": "", + "subgrp": "", + "valid": true + }, + { + "code": "29", + "name": "Fukui", + "dxcc": 0, + "group": "", + "subgrp": "", + "valid": true + }, + { + "code": "30", + "name": "Ishikawa", + "dxcc": 0, + "group": "", + "subgrp": "", + "valid": true + }, { "code": "31", - "name": "Tottori", + "name": "Okayama", "dxcc": 0, "group": "", "subgrp": "", @@ -260,31 +309,31 @@ }, { "code": "33", - "name": "Okayama", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true - }, - { - "code": "34", - "name": "Hiroshima", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true - }, - { - "code": "35", "name": "Yamaguchi", "dxcc": 0, "group": "", "subgrp": "", "valid": true }, + { + "code": "34", + "name": "Tottori", + "dxcc": 0, + "group": "", + "subgrp": "", + "valid": true + }, + { + "code": "35", + "name": "Hiroshima", + "dxcc": 0, + "group": "", + "subgrp": "", + "valid": true + }, { "code": "36", - "name": "Tokushima", + "name": "Kagawa", "dxcc": 0, "group": "", "subgrp": "", @@ -292,7 +341,7 @@ }, { "code": "37", - "name": "Kagawa", + "name": "Tokushima", "dxcc": 0, "group": "", "subgrp": "", @@ -314,14 +363,6 @@ "subgrp": "", "valid": true }, - { - "code": "4", - "name": "Miyagi", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true - }, { "code": "40", "name": "Fukuoka", @@ -385,48 +426,8 @@ "group": "", "subgrp": "", "valid": true - }, - { - "code": "5", - "name": "Akita", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true - }, - { - "code": "6", - "name": "Yamagata", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true - }, - { - "code": "7", - "name": "Fukushima", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true - }, - { - "code": "8", - "name": "Ibaraki", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true - }, - { - "code": "9", - "name": "Tochigi", - "dxcc": 0, - "group": "", - "subgrp": "", - "valid": true } ] } ] -} \ No newline at end of file +} diff --git a/internal/award/waja_test.go b/internal/award/waja_test.go new file mode 100644 index 0000000..cb84e99 --- /dev/null +++ b/internal/award/waja_test.go @@ -0,0 +1,101 @@ +package award + +import ( + "encoding/json" + "testing" +) + +// WAJA is numbered by the JARL, and the numbering is NOT Japan's ordinary +// prefecture code. +// +// The catalog shipped with the government's JIS numbering instead — 01 +// Hokkaido, 02 Aomori, 03 Iwate, 04 Miyagi… — which agrees with the JARL's for +// the first three prefectures and then diverges for thirty-five of the +// remaining forty-four. The names were right throughout, so the award still +// counted the right contacts; every reference simply carried the wrong number, +// which is what an operator sends to the JARL when they claim it. +// +// The two schemes agree often enough to look correct at a glance, so this pins +// the places they differ rather than a count. Each pair below is one the old +// list got wrong, and the comment is what the old list said. +func TestCatalogWAJAUsesTheJARLNumbering(t *testing.T) { + raw, ok := CatalogRefs("WAJA") + if !ok { + t.Fatal("WAJA has no reference list in the embedded catalog") + } + var refs []struct { + Code string `json:"code"` + Name string `json:"name"` + Pattern string `json:"pattern"` + } + if err := json.Unmarshal(raw, &refs); err != nil { + t.Fatalf("WAJA references: %v", err) + } + if len(refs) != 47 { + t.Fatalf("WAJA has %d prefectures, want exactly 47", len(refs)) + } + + byName := map[string]string{} + byCode := map[string]string{} + for _, r := range refs { + byName[r.Name] = r.Code + if prev, dup := byCode[r.Code]; dup { + t.Errorf("number %s is on both %s and %s", r.Code, prev, r.Name) + } + byCode[r.Code] = r.Name + } + + for _, c := range []struct{ name, code string }{ + {"Hokkaido", "01"}, // the one both schemes agree on, and the anchor + {"Miyagi", "06"}, // was 04 + {"Akita", "04"}, // was 05 + {"Niigata", "08"}, // was 15 — the JIS number + {"Nagano", "09"}, // was 20 + {"Tokyo", "10"}, // was 13, the JIS number everyone recognises + {"Kanagawa", "11"}, // was 14 + {"Saitama", "13"}, // was 11 + {"Ibaraki", "14"}, // was 8 + {"Gunma", "16"}, // was 10 + {"Yamanashi", "17"}, // was 19 + {"Kyoto", "22"}, // was 26 + {"Osaka", "25"}, // was 27 + {"Toyama", "28"}, // was 16 + {"Ishikawa", "30"}, // was 17 + {"Okayama", "31"}, // was 33 + {"Tottori", "34"}, // was 31 + {"Kagawa", "36"}, // was 37 + {"Tokushima", "37"}, // was 36 + {"Okinawa", "47"}, // unchanged: the far end of the list was already right + } { + if got := byName[c.name]; got != c.code { + t.Errorf("%s is numbered %q, want %q on the JARL list", c.name, got, c.code) + } + } + + // Two digits throughout, as the JARL prints them. Not cosmetic: the codes + // are strings, so "1" sorts between "09" and "10" and the panel showed the + // prefectures in an order no list anywhere uses. + for _, r := range refs { + if len(r.Code) != 2 { + t.Errorf("%s is numbered %q — the JARL list is two digits throughout", r.Name, r.Code) + } + } + + // The Tokyo spelling rule has to sit on Tokyo, and Tokyo moved. Left behind + // on the old number it would be matching QTHs for Saitama. + for _, r := range refs { + if r.Pattern == "" { + continue + } + if r.Name != "Tokyo" { + t.Errorf("%s (%s) carries the pattern %q, which belongs to Tokyo", r.Name, r.Code, r.Pattern) + } + } + if byName["Tokyo"] != "" { + for _, r := range refs { + if r.Name == "Tokyo" && r.Pattern == "" { + t.Error("Tokyo lost its spelling pattern in the renumbering — Tokio would stop counting") + } + } + } +}