vehicles 0.6.1 → 0.8.0

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 (186) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +164 -0
  3. data/CHANGELOG.md +274 -0
  4. data/README.md +55 -10
  5. data/data/PROVENANCE-vehicles.md +12 -0
  6. data/data/plates/PROVENANCE.md +5 -4
  7. data/data/plates/_decode/at-districts.yml +287 -0
  8. data/data/plates/_decode/ch-cantons.yml +110 -0
  9. data/data/plates/_decode/cn-issuing-offices.yml +463 -0
  10. data/data/plates/_decode/cn-provinces.yml +614 -0
  11. data/data/plates/_decode/cz-kraj.yml +159 -0
  12. data/data/plates/_decode/dk-serial-blocks.yml +327 -0
  13. data/data/plates/_decode/fr-departements.yml +191 -0
  14. data/data/plates/_decode/gb-age-identifiers.yml +170 -0
  15. data/data/plates/_decode/gb-memory-tags.yml +202 -0
  16. data/data/plates/_decode/gr-prefectures.yml +1408 -0
  17. data/data/plates/_decode/hr-cities.yml +315 -0
  18. data/data/plates/_decode/ie-counties.yml +227 -0
  19. data/data/plates/_decode/in-state-codes.yml +169 -0
  20. data/data/plates/_decode/is-districts-1938.yml +116 -0
  21. data/data/plates/_decode/it-provinces.yml +348 -0
  22. data/data/plates/_decode/jp-office-marks.yml +960 -0
  23. data/data/plates/_decode/jp-use-marks.yml +205 -0
  24. data/data/plates/_decode/kr-authority-marks.yml +146 -0
  25. data/data/plates/_decode/kr-use-syllables.yml +194 -0
  26. data/data/plates/_decode/lu-series-order.yml +638 -0
  27. data/data/plates/_decode/mx-entity-series.yml +380 -0
  28. data/data/plates/_decode/my-index-marks.yml +271 -0
  29. data/data/plates/_decode/no-counties-1913.yml +148 -0
  30. data/data/plates/_decode/no-districts.yml +901 -0
  31. data/data/plates/_decode/pl-powiats.yml +567 -0
  32. data/data/plates/_decode/pt-trailer-services.yml +96 -0
  33. data/data/plates/_decode/ro-counties.yml +213 -0
  34. data/data/plates/_decode/se-diplomatic.yml +220 -0
  35. data/data/plates/_decode/si-regions.yml +123 -0
  36. data/data/plates/_decode/sk-districts.yml +314 -0
  37. data/data/plates/_decode/th-registration-elements.yml +208 -0
  38. data/data/plates/_decode/ua-regions.yml +393 -0
  39. data/data/plates/_decode/za-licence-marks.yml +215 -0
  40. data/data/plates/_meta/classes.yml +1 -0
  41. data/data/plates/_meta/separators.yml +102 -0
  42. data/data/plates/ad.yml +961 -0
  43. data/data/plates/ar.yml +762 -0
  44. data/data/plates/at.yml +1424 -0
  45. data/data/plates/au-act.yml +472 -0
  46. data/data/plates/au-nsw.yml +282 -0
  47. data/data/plates/au-nt.yml +431 -0
  48. data/data/plates/au-qld.yml +272 -0
  49. data/data/plates/au-sa.yml +248 -0
  50. data/data/plates/au-tas.yml +302 -0
  51. data/data/plates/au-vic.yml +215 -0
  52. data/data/plates/au-wa.yml +309 -0
  53. data/data/plates/be.yml +1840 -0
  54. data/data/plates/br.yml +1152 -0
  55. data/data/plates/ca-ab.yml +430 -0
  56. data/data/plates/ca-bc.yml +697 -0
  57. data/data/plates/ca-mb.yml +499 -0
  58. data/data/plates/ca-nb.yml +537 -0
  59. data/data/plates/ca-nl.yml +743 -0
  60. data/data/plates/ca-ns.yml +808 -0
  61. data/data/plates/ca-nt.yml +610 -0
  62. data/data/plates/ca-nu.yml +280 -0
  63. data/data/plates/ca-on.yml +881 -0
  64. data/data/plates/ca-pe.yml +592 -0
  65. data/data/plates/ca-qc.yml +1036 -0
  66. data/data/plates/ca-sk.yml +256 -0
  67. data/data/plates/ca-yt.yml +656 -0
  68. data/data/plates/ch.yml +1273 -0
  69. data/data/plates/cn.yml +1431 -0
  70. data/data/plates/cy.yml +688 -0
  71. data/data/plates/cz.yml +1179 -0
  72. data/data/plates/de.yml +553 -118
  73. data/data/plates/dk.yml +1647 -0
  74. data/data/plates/ee.yml +1275 -0
  75. data/data/plates/es.yml +228 -32
  76. data/data/plates/fi.yml +1271 -0
  77. data/data/plates/fr.yml +1265 -0
  78. data/data/plates/gb.yml +1188 -0
  79. data/data/plates/gr.yml +721 -0
  80. data/data/plates/hr.yml +860 -0
  81. data/data/plates/hu.yml +959 -0
  82. data/data/plates/ie.yml +775 -0
  83. data/data/plates/in.yml +1172 -0
  84. data/data/plates/is.yml +667 -0
  85. data/data/plates/it.yml +1317 -0
  86. data/data/plates/jp.yml +3650 -0
  87. data/data/plates/kr.yml +1375 -0
  88. data/data/plates/li.yml +1010 -0
  89. data/data/plates/lt.yml +879 -0
  90. data/data/plates/lu.yml +842 -0
  91. data/data/plates/lv.yml +924 -0
  92. data/data/plates/mc.yml +1024 -0
  93. data/data/plates/mt.yml +854 -0
  94. data/data/plates/mx.yml +1372 -0
  95. data/data/plates/my.yml +685 -0
  96. data/data/plates/nl.yml +44 -0
  97. data/data/plates/no.yml +1018 -0
  98. data/data/plates/nz.yml +1699 -0
  99. data/data/plates/pl.yml +1296 -0
  100. data/data/plates/pt.yml +847 -0
  101. data/data/plates/ro.yml +785 -0
  102. data/data/plates/se.yml +1091 -0
  103. data/data/plates/si.yml +1105 -0
  104. data/data/plates/sk.yml +1439 -0
  105. data/data/plates/sm.yml +1119 -0
  106. data/data/plates/th.yml +1150 -0
  107. data/data/plates/ua.yml +1672 -0
  108. data/data/plates/us-ak.yml +763 -0
  109. data/data/plates/us-al.yml +457 -0
  110. data/data/plates/us-ar.yml +427 -0
  111. data/data/plates/us-as.yml +454 -0
  112. data/data/plates/us-az.yml +430 -0
  113. data/data/plates/us-ca.yml +892 -0
  114. data/data/plates/us-co.yml +452 -0
  115. data/data/plates/us-ct.yml +427 -0
  116. data/data/plates/us-dc.yml +614 -0
  117. data/data/plates/us-de.yml +551 -0
  118. data/data/plates/us-fl.yml +319 -96
  119. data/data/plates/us-ga.yml +644 -0
  120. data/data/plates/us-gu.yml +658 -0
  121. data/data/plates/us-hi.yml +585 -0
  122. data/data/plates/us-ia.yml +438 -0
  123. data/data/plates/us-id.yml +531 -0
  124. data/data/plates/us-il.yml +516 -0
  125. data/data/plates/us-in.yml +324 -0
  126. data/data/plates/us-ks.yml +351 -0
  127. data/data/plates/us-ky.yml +770 -0
  128. data/data/plates/us-la.yml +568 -0
  129. data/data/plates/us-ma.yml +379 -0
  130. data/data/plates/us-md.yml +536 -0
  131. data/data/plates/us-me.yml +445 -0
  132. data/data/plates/us-mi.yml +408 -0
  133. data/data/plates/us-mn.yml +411 -0
  134. data/data/plates/us-mo.yml +356 -0
  135. data/data/plates/us-mp.yml +402 -0
  136. data/data/plates/us-ms.yml +432 -0
  137. data/data/plates/us-mt.yml +619 -0
  138. data/data/plates/us-nc.yml +602 -0
  139. data/data/plates/us-nd.yml +419 -0
  140. data/data/plates/us-ne.yml +483 -0
  141. data/data/plates/us-nh.yml +394 -0
  142. data/data/plates/us-nj.yml +547 -0
  143. data/data/plates/us-nm.yml +574 -0
  144. data/data/plates/us-nv.yml +655 -0
  145. data/data/plates/us-ny.yml +592 -0
  146. data/data/plates/us-oh.yml +404 -0
  147. data/data/plates/us-ok.yml +513 -0
  148. data/data/plates/us-or.yml +392 -0
  149. data/data/plates/us-pa.yml +506 -0
  150. data/data/plates/us-pr.yml +507 -0
  151. data/data/plates/us-ri.yml +445 -0
  152. data/data/plates/us-sc.yml +605 -0
  153. data/data/plates/us-sd.yml +428 -0
  154. data/data/plates/us-tn.yml +471 -0
  155. data/data/plates/us-tx.yml +535 -0
  156. data/data/plates/us-ut.yml +384 -0
  157. data/data/plates/us-va.yml +567 -0
  158. data/data/plates/us-vi.yml +489 -0
  159. data/data/plates/us-vt.yml +458 -0
  160. data/data/plates/us-wa.yml +484 -0
  161. data/data/plates/us-wi.yml +509 -0
  162. data/data/plates/us-wv.yml +446 -0
  163. data/data/plates/us-wy.yml +523 -0
  164. data/data/plates/va.yml +604 -0
  165. data/data/plates/za.yml +1141 -0
  166. data/data/vehicles.json +160653 -105090
  167. data/lib/vehicles/configuration.rb +17 -3
  168. data/lib/vehicles/dataset.rb +73 -18
  169. data/lib/vehicles/fuzzy.rb +115 -0
  170. data/lib/vehicles/http.rb +48 -0
  171. data/lib/vehicles/make.rb +36 -6
  172. data/lib/vehicles/mcp_server.rb +5 -5
  173. data/lib/vehicles/model.rb +21 -2
  174. data/lib/vehicles/plates/series.rb +172 -18
  175. data/lib/vehicles/plates/template_fill.rb +188 -0
  176. data/lib/vehicles/plates/templates.rb +162 -0
  177. data/lib/vehicles/plates.rb +12 -0
  178. data/lib/vehicles/providers/hosted_provider.rb +28 -55
  179. data/lib/vehicles/validators/vehicle_make_validator.rb +3 -1
  180. data/lib/vehicles/validators/vehicle_model_validator.rb +1 -1
  181. data/lib/vehicles/version.rb +1 -1
  182. data/lib/vehicles.rb +32 -16
  183. data/rakelib/data_refresh.rake +109 -0
  184. data/rakelib/plates_refresh.rake +29 -0
  185. data/sig/vehicles.rbs +18 -0
  186. metadata +164 -2
@@ -0,0 +1,159 @@
1
+ # plates/_decode/cz-kraj.yml — the Czech region (kraj) codes carried by a
2
+ # registrační značka.
3
+ #
4
+ # THE SOURCE FINDING, and it is the Austrian case rather than the German one:
5
+ # THE LIST IS INSIDE THE REGULATION. Two lists, in fact, and a consumer needs
6
+ # both, because Czech law encodes the kraj in TWO DIFFERENT ALPHABETS depending
7
+ # on which series it is looking at:
8
+ #
9
+ # 1. A LETTER, for standard, dealer and one-trip marks. § 24 ods. 2 vyhlášky
10
+ # č. 343/2014 Sb.: "První písmeno ve standardní registrační značce
11
+ # vyjadřuje kód kraje" in the 2001 wording; the letter-to-kraj assignment
12
+ # itself is § 28 of vyhláška č. 343/2014 Sb. (and was § 19 ods. 2 of
13
+ # vyhláška č. 243/2001 Sb., with the identical fourteen pairs).
14
+ # 2. A TWO-DIGIT NUMERAL, for historic-vehicle and sports-vehicle marks.
15
+ # § 26 ods. 6 vyhlášky č. 343/2014 Sb.: "Na tabulkách s registrační
16
+ # značkou pro historická vozidla a registrační značkou pro sportovní
17
+ # vozidla se používají číselné kódy pro ...".
18
+ #
19
+ # The two alphabets DO NOT AGREE and are not derivable from one another —
20
+ # Jihomoravský is B in letters and 02 in numerals, Jihočeský is C and 03. A
21
+ # parse API that learned one and inferred the other would be wrong on twelve of
22
+ # the fourteen rows. Both are authored here, in the instrument's own order.
23
+ #
24
+ # PERIOD DISCIPLINE (PRD-PLATES §2.4). The fourteen kraje were created by
25
+ # ústavní zákon č. 347/1997 Sb. and have not been re-cut since, so unlike the
26
+ # German and Austrian tables this one has no withdrawn rows and no merger
27
+ # history. What DID change is the meaning of the code on a plate, and it
28
+ # changed on a dated day — see `portability_2015` below. The letter pairs
29
+ # themselves are unchanged between the 2001 and the 2014 regulation; the pass
30
+ # read both and diffed them.
31
+ #
32
+ # Referenced by plates/cz.yml via region_encoding.
33
+ jurisdiction: cz
34
+ topic: kraj
35
+ authority:
36
+ name: "Vyhláška č. 343/2014 Sb., o registraci vozidel — § 28 (letters) and § 26 ods. 6 (numerals)"
37
+ url: "https://aplikace.mv.gov.cz/sbirka-zakonu/ViewFile.aspx?type=z&id=27609"
38
+ sources:
39
+ - "https://aplikace.mv.gov.cz/sbirka-zakonu/ViewFile.aspx?type=z&id=27609 # vyhláška č. 343/2014 Sb., o registraci vozidel, částka 136 rozeslaná 31. prosince 2014, as published in the official Sbírka zákonů PDF. § 28 'Způsob zajišťování tabulek s registrační značkou' carries the fourteen kraj LETTERS a) to n); § 26 ods. 6 carries the fourteen kraj NUMERALS 01 to 14; § 24 ods. 2 the 5-8 character rule; § 27 ods. 3 the letter charset. Accessed 2026-08-02"
40
+ - "https://aplikace.mv.gov.cz/sbirka-zakonu/ViewFile.aspx?type=c&id=3670 # vyhláška č. 243/2001 Sb., o registraci vozidel, částka 92 rozeslaná 17. července 2001. § 19 ods. 2 'Tabulky s registrační značkou se přidělují pouze podle kódu kraje' — the SAME fourteen letter pairs, first enacted. § 19 ods. 3: 'Registrační místa okresních úřadů vydávají tabulky pouze s registrační značkou podle místní příslušnosti svého kraje.' Accessed 2026-08-02"
41
+ - "https://www.psp.cz/sqw/sbirka.sqw?cz=343&r=2014 # official Sbírka index entry: Částka 136 (31. 12. 2014), Účinnost od 1. 1. 2015, still in force. Accessed 2026-08-02"
42
+ period: { start: 2001 }
43
+ period_evidence: enacted-commencement
44
+ period_note: >-
45
+ 2001 is the letter system's own commencement, not an instrument date: vyhláška
46
+ č. 243/2001 Sb. § 32 provides "Tato vyhláška nabývá účinnosti dnem vyhlášení"
47
+ and the Sbírka masthead of částka 92 reads "Rozeslána dne 17. července 2001",
48
+ so the kraj letters entered force on 17 JULY 2001 — not on 29 June 2001, which
49
+ is the date the minister SIGNED the vyhláška and which secondary sources
50
+ routinely quote as a range ("introduced between 29 June and 17 July 2001").
51
+ The table has run unbroken since; vyhláška č. 343/2014 Sb. re-enacted the same
52
+ fourteen pairs with effect from 1 January 2015.
53
+
54
+ decode_direction: "code -> kraj of the registration place that ISSUED the mark"
55
+ split_note: >-
56
+ FIXED WIDTH, and self-delimiting for the wrong reason. The kraj letter is a
57
+ SINGLE character and it is the FIRST LETTER of the mark, not the first
58
+ character: § 24 ods. 2 vyhlášky 243/2001 Sb., verbatim, "První písmeno ve
59
+ standardní registrační značce vyjadřuje kód kraje, do jehož obvodu náleží
60
+ registrační místo, které registrační značku přiděluje". On the canonical
61
+ modern mark (digit, letter, digit, gap, four digits — "1A2 3456") that letter
62
+ sits at position 2, which is why a naive first-character decode fails on every
63
+ Czech plate. Three series are expressly EXCLUDED from the rule by the same
64
+ sentence: diplomatic, cizinecká and historic marks.
65
+
66
+ portability_2015:
67
+ effective: "2015-01-01"
68
+ effect: >-
69
+ THE CODE STOPPED TRACKING THE VEHICLE. Under vyhláška č. 243/2001 Sb. § 20
70
+ ods. 1, verbatim: "Při převodu vozidla do obvodu registračního místa, pro
71
+ něž je určen jiný kód kraje, přidělí nové registrační místo vždy novou
72
+ registrační značku a vydá novou tabulku registrační značky." — a move to
73
+ another kraj FORCED a new mark. Vyhláška č. 343/2014 Sb. carries no such
74
+ provision, and from its commencement on 1 January 2015 the mark is retained
75
+ on a change of keeper or of kraj.
76
+ consequence: >-
77
+ Exactly as in Slovakia after 2023, though eight years earlier and by a
78
+ quieter route (an omission rather than an express repeal): a decode of the
79
+ kraj letter is a claim about WHERE THE MARK WAS ISSUED, never about where
80
+ the vehicle is registered now. For marks issued before 2015 the two
81
+ coincided at issue; for marks issued since, and for any pre-2015 mark whose
82
+ vehicle has since moved, they need not.
83
+ evidence: instrument-in-force
84
+ evidence_note: >-
85
+ The 2001 rule is quoted verbatim from the primary. Its ABSENCE from the 2014
86
+ vyhláška is this pass's own reading of the successor text, which is weaker
87
+ than a repeal clause would be; the widely repeated "as of 1 January 2015
88
+ registration numbers are not changed if the owner moves to another region"
89
+ is corroborating secondary and is tagged as such below. No transitional
90
+ provision was located expressly stating the retention rule — recorded gap.
91
+ corroboration: secondary-wikipedia
92
+ corroboration_source: "https://en.wikipedia.org/wiki/Vehicle_registration_plates_of_the_Czech_Republic # 'As of 1 January 2015, registration numbers are not changed if the owner of a vehicle moves to another region or if the vehicle is re-registered to a new owner residing in a different region.' Accessed 2026-08-02"
93
+
94
+ # ---------------------------------------------------------------------------
95
+ # 1. THE LETTER CODES — § 28 vyhlášky č. 343/2014 Sb., in the instrument's own
96
+ # order a) to n). Used by cz-standard-*, cz-dealer, cz-transfer.
97
+ # ---------------------------------------------------------------------------
98
+ letters:
99
+ - { code: A, kraj: "Hlavní město Praha" }
100
+ - { code: S, kraj: "Středočeský" }
101
+ - { code: U, kraj: "Ústecký" }
102
+ - { code: L, kraj: "Liberecký" }
103
+ - { code: K, kraj: "Karlovarský" }
104
+ - { code: H, kraj: "Královéhradecký" }
105
+ - { code: E, kraj: "Pardubický" }
106
+ - { code: P, kraj: "Plzeňský" }
107
+ - { code: C, kraj: "Jihočeský" }
108
+ - { code: J, kraj: "Vysočina" }
109
+ - { code: B, kraj: "Jihomoravský" }
110
+ - { code: M, kraj: "Olomoucký" }
111
+ - { code: T, kraj: "Moravskoslezský" }
112
+ - { code: Z, kraj: "Zlínský" }
113
+ letters_note: >-
114
+ Fourteen codes for fourteen kraje — a CLOSED, COMPLETE table, which is the
115
+ useful thing about it: an unmatched leading letter on a standard Czech mark is
116
+ not an unknown region, it is a malformed or non-standard mark. Recorded
117
+ drafting defect in the FIRST enactment, because it is visible in the official
118
+ PDF and a future verifier will otherwise think this file miscopied it:
119
+ § 19 ods. 2 of vyhláška č. 243/2001 Sb. labels FIFTEEN sub-paragraphs a) to
120
+ m) but prints the letter "e)" TWICE — once for Karlovarský and again for
121
+ Královéhradecký — so its list runs a) b) c) d) e) e) f) ... m). The pairs
122
+ themselves are correct and are unchanged in § 28 of vyhláška č. 343/2014 Sb.,
123
+ which numbers them cleanly a) to n).
124
+
125
+ # ---------------------------------------------------------------------------
126
+ # 2. THE NUMERIC CODES — § 26 ods. 6 vyhlášky č. 343/2014 Sb. Used ONLY by
127
+ # cz-historic-2015 and cz-sport, where the two digits open the mark.
128
+ # ---------------------------------------------------------------------------
129
+ numerals:
130
+ - { code: "01", kraj: "Hlavní město Praha" }
131
+ - { code: "02", kraj: "Jihomoravský" }
132
+ - { code: "03", kraj: "Jihočeský" }
133
+ - { code: "04", kraj: "Pardubický" }
134
+ - { code: "05", kraj: "Královéhradecký" }
135
+ - { code: "06", kraj: "Vysočina" }
136
+ - { code: "07", kraj: "Karlovarský" }
137
+ - { code: "08", kraj: "Liberecký" }
138
+ - { code: "09", kraj: "Olomoucký" }
139
+ - { code: "10", kraj: "Plzeňský" }
140
+ - { code: "11", kraj: "Středočeský" }
141
+ - { code: "12", kraj: "Moravskoslezský" }
142
+ - { code: "13", kraj: "Ústecký" }
143
+ - { code: "14", kraj: "Zlínský" }
144
+ numerals_note: >-
145
+ The numeral identifies "registračního místa, které zajišťuje registraci
146
+ historických vozidel na správním území kraje" (§ 26 ods. 1) — the ONE
147
+ registration office per kraj that handles historic vehicles, so the code is a
148
+ kraj code with an administrative extra meaning. These codes are ALPHABETICAL
149
+ BY CZECH KRAJ NAME (Hlavní město Praha, Jihomoravský, Jihočeský, Pardubický,
150
+ ...) rather than following the letter table's order, which is why the two
151
+ tables look unrelated: they are two different orderings of the same fourteen
152
+ regions. Note 01 is Praha in both alphabets and nothing else lines up.
153
+
154
+ not_region_codes:
155
+ - "F — the leading letter of a TEST mark (registrační značka pro zkušební provoz), § 26 ods. 4 vyhlášky 343/2014 Sb.: 'začíná vždy písmenem „F“'. F is not a kraj letter in either regulation, and vyhláška 243/2001 Sb. § 18 ods. 1 expressly kept F out of the general letter charset, which is what made it available as a series marker."
156
+ - "V — the historic-vehicle marker, § 26 ods. 1: the mark is 'dvoumístným číselným znakem ... a velkým písmenem „V“'. Under the 2001 regulation the mark was V + four digits with NO kraj code at all (§ 16 ods. 5), so a bare-V historic mark is pre-2015 and carries no geography."
157
+ - "R — the sports-vehicle marker, § 26 ods. 5, in the same numeral+letter position as V."
158
+ - "CD, XX, XS, HC — diplomatic and cizinecká prefixes, § 24 ods. 3 vyhlášky 343/2014 Sb. Expressly excluded from the kraj rule and carrying no geography."
159
+ - "G, O, Q, W — issued in NO position. § 27 ods. 3 vyhlášky 343/2014 Sb. enumerates the letters usable after the kraj code as A, B, C, D, E, F, H, I, J, K, L, M, N, P, R, S, T, U, V, X, Y, Z — twenty-two of twenty-six. The 2001 predecessor (§ 18 ods. 1 vyhlášky 243/2001 Sb.) was tighter still, omitting F and H as well and leaving twenty."
@@ -0,0 +1,327 @@
1
+ # plates/_decode/dk-serial-blocks.yml — what a Danish registration number's
2
+ # DIGIT BLOCK says about the vehicle.
3
+ #
4
+ # WHY THIS FILE EXISTS AND WHAT IT IS NOT. Denmark encodes NO GEOGRAPHY. The
5
+ # single letter on a pre-1958 plate was a county marker and it is long gone;
6
+ # since then the two letters are a pure serial, re-used after deregistration
7
+ # and restarted from AA when the digital register came in, so they date and
8
+ # locate nothing. What a Danish number DOES still encode is the vehicle's kind
9
+ # or use, and it encodes it in the DIGITS. This file is that decode, and it is
10
+ # the only decode table Denmark supports.
11
+ #
12
+ # THE LEGAL BASIS IS PRIMARY; THE TABLE IS NOT IN ANY INSTRUMENT.
13
+ # BEK nr 663 af 10/06/2025 § 68, stk. 3, verbatim: "Skatteforvaltningen kan
14
+ # inddele registreringsnumre i serier efter køretøjers art eller anvendelse."
15
+ # The POWER to divide numbers into series by vehicle kind or use is enacted;
16
+ # the DIVISION is published only by the authority, in its plate catalogue, and
17
+ # has never been an annex to anything. That is why this file exists as a decode
18
+ # table rather than as a quotation, and why its rows are tiered by source.
19
+ #
20
+ # THE HINGE DATE IS 6 JUNE 2012, and it is dated by an instrument, not by an
21
+ # enthusiast page. BEK nr 504 af 30/05/2012 § 118: "Bekendtgørelsen træder i
22
+ # kraft den 6. juni 2012." SKAT dated its complete plate catalogue "pr.
23
+ # 06.06.2012" to the same day. On that day the fine-grained per-kind blocks
24
+ # were consolidated: cars, vans, lorries, motorcycles and approved tractors now
25
+ # share one range, and only two carve-outs survived — 76.000-77.999 for
26
+ # diplomatic plates and 98.000-99.999 for taxis and patient transport.
27
+ # English Wikipedia says "after 2012"; Danish Wikipedia says the digital
28
+ # register came in "i 2011". Both are approximations of a date the
29
+ # bekendtgørelse gives exactly.
30
+ #
31
+ # SOURCE TIERS, PER ROW, AND WHY THEY DIFFER BETWEEN THE TWO ERAS
32
+ # * `primary-authority` — SKAT's own documents: the 2012 plate catalogue
33
+ # (complete, every stocked plate type with its number range) and the
34
+ # archived skat.dk per-plate pages from the 2009 EU-plate rollout (one
35
+ # page per type, each carrying Serie / Betegnelse / Størrelse / Farve /
36
+ # Nummerrække / Format). Only ONE of those per-plate pages survived in the
37
+ # Internet Archive in a readable state — "Personbil - EU", Serie 61 — so
38
+ # the pre-2012 era has exactly one primary row.
39
+ # * `secondary-wikipedia` — the rest of the pre-2012 rows. Both the English
40
+ # and the Danish Wikipedia article carry a pre-2012 block table, each
41
+ # crediting the enthusiast register nrpl.dk. THE TWO TABLES DISAGREE, and
42
+ # PRD-PLATES §5.3 says record disagreements rather than average them, so
43
+ # conflicting rows carry both readings and a `conflict:` note. Nothing here
44
+ # is presented as an instrument.
45
+ #
46
+ # HOW A CONSUMER SHOULD USE THIS
47
+ # 1. Establish the era first. A Danish number gives no era signal of its own,
48
+ # so the era must come from the vehicle record, not from the plate.
49
+ # 2. In the 2012- era, only the diplomatic and taxi blocks are decisive; the
50
+ # general range says "car, van, lorry, motorcycle or approved tractor" and
51
+ # no more.
52
+ # 3. In the pre-2012 era, treat every row below `evidence: secondary-wikipedia`
53
+ # as a hypothesis with a confidence, never as a fact. Old-stock plates from
54
+ # the pre-2012 blocks were still being issued alongside the new ones for
55
+ # years afterwards (Danish Wikipedia reports "frem til i hvert fald 2022"),
56
+ # so a pre-2012-shaped number on a 2020 registration is not an anomaly.
57
+ jurisdiction: dk
58
+ topic: serial-blocks
59
+ authority:
60
+ name: Skatteforvaltningen (Motorstyrelsen) — Køretøjsregisteret
61
+ url: "https://motorst.dk/borger/nummerplader"
62
+ sources:
63
+ - "https://www.retsinformation.dk/eli/lta/2025/663/dan/xml # BEK 663/2025 § 68, stk. 3 — the enacted power to divide registration numbers into series by vehicle kind or use; accessed 2026-08-02"
64
+ - "https://www.retsinformation.dk/eli/lta/2012/504/dan/xml # BEK 504/2012 § 118 — 'Bekendtgørelsen træder i kraft den 6. juni 2012', the hinge date; accessed 2026-08-02"
65
+ - "https://web.archive.org/web/20170917063422/https://www.skat.dk/getFiles.aspx?Id=e6c2c7e8-e7a7-4b5e-b15e-4b67e27d3f66&name=planche_nummerplader_2012.pdf # SKAT, 'Liste over alle pladetyper i Danmark pr. 06.06.2012' — the complete plate-stock poster, source of every 2012- row below; archived capture 2017-09-17; accessed 2026-08-02"
66
+ - "https://web.archive.org/web/20110716080639/http://www.skat.dk/SKAT.aspx?oId=1826647 # skat.dk 'Personbil - EU', Serie 61: nummerrække 20.000-59.999, størrelse 120 x 504, farve Hvid/sort/rød, format '@@ ## ###'; the only pre-2012 row here with an authority source; archived capture 2011-07-16; accessed 2026-08-02"
67
+ - "https://web.archive.org/web/20120127070602/http://www.skat.dk/SKAT.aspx?oId=1826638 # skat.dk 'Nummerplader med EU-symbol', headed 'Aktuelle EU-nummerplader pr. 12. oktober 2009', the index of the per-plate pages; accessed 2026-08-02"
68
+ - "https://en.wikipedia.org/wiki/Vehicle_registration_plates_of_Denmark # secondary-wikipedia: the pre-2012 block table, credited to nrpl.dk; accessed 2026-08-02"
69
+ - "https://da.wikipedia.org/wiki/Nummerplade # secondary-wikipedia: a second, differently-cut pre-2012 block table, also credited to nrpl.dk, plus the note that pre-2012 stock kept being issued 'frem til i hvert fald 2022'; accessed 2026-08-02"
70
+ period: { start: 1976 }
71
+ period_evidence: statutory-date
72
+ period_note: >-
73
+ 1976 is the 1 April 1976 numbering guidelines that the whole two-letter system
74
+ rests on (BEK 663/2025 § 72, stk. 4, nr. 4). The table itself is split into
75
+ two eras at 6 June 2012; each era carries its own dates below. No row here
76
+ claims a date of its own — SKAT publishes ranges, never the day a range
77
+ opened.
78
+
79
+ # ---------------------------------------------------------------------------
80
+ # ERA 2: 6 JUNE 2012 ONWARDS. Primary throughout — every row is a line of
81
+ # SKAT's own plate catalogue, dated by the catalogue's own title.
82
+ # ---------------------------------------------------------------------------
83
+ blocks_2012:
84
+ period: { start: 2012 }
85
+ period_evidence: instrument-in-force
86
+ period_note: >-
87
+ 6 June 2012, from BEK 504/2012 § 118's commencement clause, corroborated by
88
+ the date SKAT put on the catalogue itself ("pr. 06.06.2012").
89
+ evidence: primary-authority
90
+ note: >-
91
+ The consolidation is the point. Before this date a Danish number told you
92
+ the vehicle's kind; after it, the general range covers cars, vans, lorries,
93
+ motorcycles and approved tractors alike, and only the diplomatic and taxi
94
+ carve-outs still decode. Ranges are written here as SKAT prints them.
95
+ rows:
96
+ - range: "10-99"
97
+ digits: 2
98
+ means: "fast prøveskilt (trade plate) — car and motorcycle alike"
99
+ series_ref: dk-dealer-testplate
100
+ - range: "100-999"
101
+ digits: 3
102
+ means: "stor knallert (moped over 30 km/h), and registreret traktor"
103
+ series_ref: [dk-moped-large, dk-tractor-registered]
104
+ note: >-
105
+ SKAT stocks two different plates on one range — the moped's 145x125 mm
106
+ white plate and the tractor's 240x165 mm one — so three digits alone do
107
+ not separate them; the plate SIZE does.
108
+ - range: "1.000-9.999"
109
+ digits: 4
110
+ means: "påhængsvogn, sættevogn and påhængsredskab (incl. campingvogn), and lille knallert"
111
+ series_ref: [dk-trailer-1976, dk-moped-small-2006]
112
+ note: >-
113
+ Again two plates on one range, separated by colour and size rather than
114
+ by number: the trailer plate is 504x120 mm yellow, the small moped's is
115
+ 145x125 mm yellow.
116
+ - range: "10.000-75.999"
117
+ digits: 5
118
+ means: "the general range — personbil, vare-/lastbil, motorcykel, godkendt traktor"
119
+ series_ref: [dk-standard-1976, dk-van-commercial-yellow, dk-van-parrot-2009, dk-motorcycle-1976, dk-tractor-approved]
120
+ note: "DOES NOT DECODE to a vehicle kind. Together with 78.000-97.999 this is the consolidated block; the plate's colour and size carry the class, the number does not."
121
+ - range: "76.000-76.999"
122
+ digits: 5
123
+ means: "diplomatic — foreign states' diplomatic and consular missions"
124
+ series_ref: dk-diplomatic-mission
125
+ evidence: "primary-authority for the 76.000-77.999 block; secondary-wikipedia for the split at 77.000"
126
+ note: >-
127
+ SKAT's catalogue gives the diplomatic block undivided as 76.000-77.999.
128
+ The split into 76 for states' missions and 77 for international
129
+ organisations is reported consistently by both Wikipedia articles and is
130
+ tagged secondary-wikipedia; the block, the blue plate and the compulsory
131
+ EU band are primary (BEK 663/2025 §§ 76 and 68, stk. 5).
132
+ - range: "77.000-77.999"
133
+ digits: 5
134
+ means: "diplomatic — international organisations and institutions"
135
+ series_ref: dk-diplomatic-organisation
136
+ evidence: "primary-authority for the block; secondary-wikipedia for the split"
137
+ - range: "78.000-97.999"
138
+ digits: 5
139
+ means: "the general range, upper half — see 10.000-75.999"
140
+ series_ref: [dk-standard-1976, dk-van-commercial-yellow, dk-van-parrot-2009, dk-motorcycle-1976, dk-tractor-approved]
141
+ - range: "98.000-99.999"
142
+ digits: 5
143
+ means: "taxi and patient transport — SKAT's '20% (Taxi og sygetransportere)', after the reduced registration-tax rate"
144
+ series_ref: dk-taxi
145
+ - range: "RF10000-RF99999"
146
+ digits: 5
147
+ prefix: RF
148
+ means: "airport (airside-only) vehicle"
149
+ series_ref: dk-airport-rf
150
+ - range: "RF1000-RF9999"
151
+ digits: 4
152
+ prefix: RF
153
+ means: "airport (airside-only) trailer"
154
+ series_ref: dk-airport-rf-trailer
155
+ note: "SKAT's catalogue prints this range as 'RF1000-FR9999'; the trailing FR is a transposition in the source, recorded and not silently corrected"
156
+ - range: "100000-999999"
157
+ digits: 6
158
+ means: "blokvogn (heavy haulage) — the only Danish number with six digits, and no letters"
159
+ series_ref: dk-blokvogn
160
+ - range: "2-7 characters, letters and/or digits"
161
+ digits: null
162
+ means: "ønskenummer (personalised) — BEK 663/2025 § 74, stk. 2"
163
+ series_ref: dk-personalized-1992
164
+ evidence: primary-instrument
165
+ note: "the one row in this file whose grammar comes from the instrument rather than from the catalogue"
166
+
167
+ # ---------------------------------------------------------------------------
168
+ # ERA 1: 1 APRIL 1976 TO 5 JUNE 2012. One primary row; the rest is
169
+ # secondary-wikipedia, and the two Wikipedia tables do not agree.
170
+ # ---------------------------------------------------------------------------
171
+ blocks_pre2012:
172
+ period: { start: 1976, end: 2012 }
173
+ period_evidence: statutory-date
174
+ period_note: >-
175
+ Opens with the 1 April 1976 numbering guidelines (BEK 663/2025 § 72, stk. 4,
176
+ nr. 4) and closes on 5 June 2012, the day before BEK 504/2012 came into
177
+ force. The closing date is exact; the opening date is the guidelines' date
178
+ and not a date on which any particular block opened.
179
+ issuance_tail_warning: >-
180
+ THE BLOCKS CLOSED; THE PLATES DID NOT. Danish Wikipedia reports that
181
+ remaining stock from these series kept being issued alongside the new
182
+ allocation "frem til i hvert fald 2022". A number in a pre-2012 block is
183
+ therefore evidence about the PLATE, not about the registration date.
184
+ default_evidence: secondary-wikipedia
185
+ conflict_summary: >-
186
+ The English and Danish Wikipedia tables agree on eight ranges and disagree
187
+ on four. The substantive disagreements are (a) whether 5.500-9.999 was small
188
+ mopeds or trailers/semi-trailers, (b) which of 78.000-87.999 and
189
+ 88.000-97.999 was the square-plate goods vehicle and which the rectangular,
190
+ (c) whether tractors sat at 700-999 or also at 19.000-19.499, and (d) three
191
+ ranges that only the Danish table carries (30.00-49.99 exhausted, the
192
+ prøveskilt ranges, and 19.500-19.999 varemotorcykler). Every disagreement is
193
+ recorded on its row. Nothing is averaged.
194
+ rows:
195
+ - range: "001-699"
196
+ digits: 3
197
+ means: "stor knallert (moped up to 45 km/h)"
198
+ agreement: "en and da agree"
199
+ - range: "700-999"
200
+ digits: 3
201
+ means: "registreret traktor"
202
+ agreement: "en and da agree"
203
+ - range: "1.000-2.999"
204
+ digits: 4
205
+ means: "påhængsredskab, incl. campingvogn"
206
+ agreement: >-
207
+ en gives 'Trailers, 10 00 - 29 99'; da gives '10 00-29 99
208
+ Påhængsredskaber, herunder campingvogne'. Same range, da is the more
209
+ specific reading and is the one written here.
210
+ - range: "3.000-4.999"
211
+ digits: 4
212
+ means: "withdrawn — letter combinations exhausted"
213
+ agreement: "da only; absent from en"
214
+ - range: "5.000-5.399"
215
+ digits: 4
216
+ means: "faste prøveskilte, cars"
217
+ agreement: "da only; absent from en"
218
+ - range: "5.400-5.499"
219
+ digits: 4
220
+ means: "faste prøveskilte, motorcycles"
221
+ agreement: "da only; absent from en"
222
+ note: >-
223
+ Note the tension with the 2012- era, where SKAT gives the prøveskilt
224
+ range as 10-99 (two digits). Either the prøveskilt number was
225
+ renumbered at the consolidation or one of the two sources is wrong; no
226
+ source reached resolves it, and both readings are left standing.
227
+ - range: "5.500-9.999"
228
+ digits: 4
229
+ means: "DISPUTED"
230
+ conflict: >-
231
+ da: 'lille knallert (30-knallert), from letter block VB onwards'.
232
+ en: 'Small mopeds' at 5 500-9 999 AND 'Trailers and semi-trailers' at
233
+ 55 00-99 99. da resolves the overlap by letter block — 55.00-99.99 up to
234
+ UZ is trailers and semi-trailers, 5.500-9.999 from VB is small mopeds —
235
+ which is the only reading that makes both ranges consistent, and is
236
+ therefore the one recorded as most likely. It is still secondary.
237
+ most_likely: "lille knallert from letter block VB; trailers and semi-trailers up to letter block UZ"
238
+ - range: "10.000-18.999"
239
+ digits: 5
240
+ means: "motorcykel"
241
+ agreement: "en and da agree"
242
+ - range: "19.000-19.499"
243
+ digits: 5
244
+ means: "godkendt traktor"
245
+ agreement: "en and da agree"
246
+ - range: "19.500-19.999"
247
+ digits: 5
248
+ means: "varemotorcykel (goods motorcycle)"
249
+ agreement: "da only; absent from en"
250
+ - range: "20.000-59.999"
251
+ digits: 5
252
+ means: "personbil, rectangular plate"
253
+ evidence: primary-authority
254
+ agreement: >-
255
+ THE ONE PRIMARY ROW IN THIS ERA. skat.dk's own 'Personbil - EU' page
256
+ gives Serie 61 with nummerrække 20.000-59.999, and both Wikipedia
257
+ tables agree with it. The agreement is worth recording: where the
258
+ authority can be checked, the secondary tables are right.
259
+ - range: "60.000-75.999"
260
+ digits: 5
261
+ means: "personbil with a square rear plate"
262
+ agreement: "en and da agree"
263
+ - range: "76.000-76.999"
264
+ digits: 5
265
+ means: "diplomatic — states' missions"
266
+ agreement: "en and da agree; unchanged through the consolidation"
267
+ - range: "77.000-77.999"
268
+ digits: 5
269
+ means: "diplomatic — international organisations"
270
+ agreement: "en and da agree; unchanged through the consolidation"
271
+ - range: "78.000-87.999"
272
+ digits: 5
273
+ means: "DISPUTED — vare- and lastbil"
274
+ conflict: >-
275
+ en: 'Trucks, buses, vans (rectangular format)'. da: 'Vare- og lastbiler
276
+ m. kvadratisk bagnummerplade' (SQUARE rear plate). The two articles
277
+ assign the rectangular and square readings to 78.000-87.999 and
278
+ 88.000-97.999 in opposite order. Neither is primary and no authority
279
+ source reached covers either range, so both readings stand.
280
+ most_likely: null
281
+ - range: "88.000-97.999"
282
+ digits: 5
283
+ means: "DISPUTED — vare- and lastbil"
284
+ conflict: "the mirror image of 78.000-87.999; en says square, da says rectangular"
285
+ most_likely: null
286
+ - range: "98.000-99.699"
287
+ digits: 5
288
+ means: "taxi and hire limousine, rectangular plate"
289
+ agreement: "en and da agree"
290
+ - range: "99.700-99.999"
291
+ digits: 5
292
+ means: "taxi and hire limousine with a square rear plate"
293
+ agreement: "en and da agree"
294
+
295
+ # ---------------------------------------------------------------------------
296
+ # WHAT IS NOT IN THIS FILE
297
+ # ---------------------------------------------------------------------------
298
+ not_covered:
299
+ pre_1958_county_letters: >-
300
+ The single letter on a pre-1958 Danish plate WAS geographic — an amt or city
301
+ marker — and that much is corroborated from the instrument side, since BEK
302
+ 633/2009 § 101, stk. 2 and BEK 651/2011 § 102, stk. 2 both keep
303
+ single-letter plates lawful on the road. But no source reached, primary or
304
+ secondary, ENUMERATES the letters against their counties. A decode table
305
+ with no rows is worse than no decode table, so none is shipped and the gap
306
+ is filed in plates/dk.yml under dk-gap-pre1958-county-letters. The
307
+ enthusiast register nrpl.dk, cited by both Wikipedia articles, is the
308
+ likeliest place a full list exists.
309
+ police_district_combinations: >-
310
+ Danish Wikipedia reports that more than a hundred two-letter combinations
311
+ used by the individual police districts before the Centralregisteret for
312
+ Motorkøretøjer centralised registration in the late 1960s are permanently
313
+ skipped in allocation. The list is not reproduced and no claim is made about
314
+ its membership.
315
+ nordic_border_office_codes: >-
316
+ The abolished nordiske grænsenummerplade is reported to have carried the
317
+ issuing motor office in its first two digits. No source enumerates the
318
+ codes; see dk-border-nordic in plates/dk.yml.
319
+ letter_blocks: >-
320
+ NO LETTER-BLOCK DECODE EXISTS AND NONE IS INVENTED. Danish letters are a
321
+ pure serial: they are re-used after twelve years (BEK 663/2025 § 2, stk. 6
322
+ corroborates the twelve), allocation restarted from AA with the digital
323
+ register, and stock from the old per-kind blocks kept being issued for a
324
+ decade afterwards. Wikipedia's "highest assigned serial letters" columns
325
+ record how far allocation had reached in each block at the time of writing;
326
+ they are a moving watermark rather than a decode, and they are deliberately
327
+ not reproduced here.