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,287 @@
1
+ # plates/_decode/at-districts.yml — Austrian Behördenbezeichnungen im Kennzeichen.
2
+ #
3
+ # THE SOURCE FINDING, and it is the opposite of Germany's: the Austrian
4
+ # district code list IS IN THE REGULATION. § 48 Abs. 5 KFG 1967 delegates it
5
+ # ("Durch Verordnung sind die Bezeichnung der Behörde und die sachlichen
6
+ # Bereiche, das System der Zeichen, unter denen die Fahrzeuge bei der Behörde
7
+ # vorzumerken sind (Abs. 4) ... festzusetzen"), and § 26 Abs. 1 KDV 1967
8
+ # discharges the delegation by pointing at ANLAGE 5d: "Die Bezeichnung der den
9
+ # Zulassungsschein ausstellenden Behörde im Kennzeichen bestimmt sich nach
10
+ # Anlage 5d." Anlage 5d is a CLOSED, PRIMARY, 98-row table printed inside the
11
+ # regulation — so unlike the German ~400-code Bundesanzeiger list (PRD-PLATES
12
+ # §2.4), it is authored here in full, verbatim, in the annex's own order
13
+ # (by Bundesland, then as the annex prints them).
14
+ #
15
+ # The non-geographic prefixes are NOT in Anlage 5d — they are in § 26 KDV
16
+ # itself (Abs. 2 the federal letter A, Abs. 3 the nine Land letters, Abs. 4 the
17
+ # seven sachliche Bereiche, Abs. 5 the diplomatic D and consular K suffixes).
18
+ # They are recorded below in their own blocks, because a parse API needs all
19
+ # four sets to resolve a prefix and because several of them COLLIDE with
20
+ # Anlage 5d district codes (see `collisions`).
21
+ #
22
+ # Referenced by: plates/at.yml (at-standard, at-motorcycle, at-moped,
23
+ # at-historic, at-electric, at-dealer-probefahrt, at-temporary-*,
24
+ # at-trailer-foreign, at-wunschkennzeichen) via region_encoding.
25
+ #
26
+ # PERIOD DISCIPLINE (PRD-PLATES §2.4): these are the codes in the CONSOLIDATED
27
+ # Anlage 5d in force on the access date (Fassung im RIS seit 26.09.2024,
28
+ # NOR40265416). Austrian district reform has repeatedly merged Bezirke
29
+ # (Bruck-Mürzzuschlag, Hartberg-Fürstenfeld, Murtal and Südoststeiermark are
30
+ # themselves 2012/2013 merger codes), and codes withdrawn from the annex stay
31
+ # on the road because a plate is only exchanged on re-registration. WITHDRAWN
32
+ # CODES ARE THEREFORE NOT IN THIS TABLE AND ARE A RECORDED GAP for L4 — a
33
+ # decode of a physical plate whose prefix is absent here must be treated as
34
+ # unresolved, never as invalid.
35
+ jurisdiction: at
36
+ topic: districts
37
+ authority:
38
+ name: "Kraftfahrgesetz-Durchführungsverordnung 1967 (KDV 1967), Anlage 5d (zu § 26 Abs. 1)"
39
+ url: "https://www.ris.bka.gv.at/NormDokument.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10011385&Anlage=5d"
40
+ sources:
41
+ - "https://www.ris.bka.gv.at/NormDokument.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10011385&Anlage=5d # Anlage 5d 'Bezeichnung der Behörde im Kennzeichen', all 98 rows in nine Bundesland blocks; Dokumentnummer NOR40265416, im RIS seit 26.09.2024. Accessed 2026-08-02"
42
+ - "https://www.ris.bka.gv.at/NormDokument.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10011385&Paragraf=26 # § 26 KDV 1967: Abs. 1 (delegation to Anlage 5d), Abs. 2 (letter A), Abs. 3 (nine Land letters), Abs. 4 (sachliche Bereiche BP/FV/PT/BD/BH/JW/FW), Abs. 5 (diplomatic D / consular K, and the Graz exception), Abs. 6 (the Vormerkzeichen grammar), Abs. 7 (hyphen for the Wappen in writing). Accessed 2026-08-02"
43
+ - "https://www.ris.bka.gv.at/NormDokument.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10011384&Paragraf=48 # § 48 Abs. 4 KFG 1967: the prefix is 'einem oder zwei Buchstaben als Bezeichnung der Behörde, in deren örtlichem Wirkungsbereich das Fahrzeug zugelassen ist'; Abs. 5 the delegation. Accessed 2026-08-02"
44
+ period: { start: 1989 }
45
+ period_evidence: enacted-commencement
46
+ period_note: >-
47
+ 1989 is the commencement of the CODE SYSTEM these rows belong to, not of the
48
+ individual rows: BGBl. Nr. 375/1988 (11. KFG-Novelle) Artikel V Abs. 4 lit. b
49
+ put the rewritten § 48 Abs. 4 KFG (one or two letters for the AUTHORITY, in
50
+ place of the pre-1989 single BUNDESLAND letter) into force on 1 January 1989.
51
+ Individual rows are younger or older than that; per-row periods are a
52
+ recorded gap.
53
+
54
+ # A parse API must carry these, because Austrian prefixes are NOT
55
+ # self-delimiting the way German ones are.
56
+ maximal_munch: true
57
+ maximal_munch_note: >-
58
+ Take the LONGEST matching code. The split point is unambiguous for ORDINARY
59
+ registrations because § 26 Abs. 6 Z 2 lit. e KDV requires the Vormerkzeichen
60
+ to BEGIN WITH A DIGIT — so the prefix is exactly the leading letter run. It is
61
+ genuinely AMBIGUOUS for WUNSCHKENNZEICHEN, whose Vormerkzeichen must begin
62
+ with a LETTER (Z 3 lit. e): "BZAB1" is both B (Bregenz) + "ZAB1" and BZ
63
+ (Bludenz) + "AB1", and nothing in the string resolves it. Record the
64
+ ambiguity; do not average it away.
65
+
66
+ collisions:
67
+ - "B — BH Bregenz (Anlage 5d, Vorarlberg) AND the Burgenland Land letter (§ 26 Abs. 3)"
68
+ - "K — LPD Kärnten/Klagenfurt (Anlage 5d) AND the Kärnten Land letter (§ 26 Abs. 3) AND the consular suffix letter (§ 26 Abs. 5 lit. b)"
69
+ - "S — LPD Salzburg/Salzburg (Anlage 5d) AND the Salzburg Land letter (§ 26 Abs. 3)"
70
+ - "W — Landespolizeidirektion Wien (Anlage 5d) AND the Wien Land letter (§ 26 Abs. 3)"
71
+ - "G — LPD Steiermark/Graz (Anlage 5d) AND, per the § 26 Abs. 5 Graz exception, the base of the diplomatic prefix GD and consular prefix GK"
72
+ - "BD — Bundesbus sachlicher Bereich (§ 26 Abs. 4 lit. f) AND the Burgenland diplomatic prefix B+D (§ 26 Abs. 5 lit. a)"
73
+ - "ND — BH Neusiedl am See (Anlage 5d) AND the Niederösterreich diplomatic prefix N+D"
74
+ - "SD — BH Schärding (Anlage 5d) AND the Salzburg diplomatic prefix S+D"
75
+ - "GD — BH Gmünd (Anlage 5d) AND the Graz diplomatic prefix G+D"
76
+ - "NK — BH Neunkirchen (Anlage 5d) AND the Niederösterreich consular prefix N+K"
77
+ - "VK — BH Völkermarkt (Anlage 5d) AND the Vorarlberg consular prefix V+K"
78
+ - "BH — Heeresfahrzeuge (§ 26 Abs. 4 lit. g) AND, in the annex's own prose, the abbreviation for Bezirkshauptmannschaft (which is NOT a code) AND an expressly forbidden Wunschkennzeichen combination (§ 26 Abs. 8 Z 2, 'Blood and Honour')"
79
+ collisions_resolution: >-
80
+ The diplomatic/consular collisions resolve on the SERIAL, not the prefix:
81
+ § 26 Abs. 6 Z 2 lit. d and e require an ordinary Vormerkzeichen to contain one
82
+ to three letters and to END WITH A LETTER, whereas the Abs. 5
83
+ (diplomatic/consular) Vormerkzeichen need only begin with a digit and is in
84
+ practice digits-only — so "ND-12345" is Niederösterreich diplomatic and
85
+ "ND-123XY" is Neusiedl am See. Where an Abs. 5 Vormerkzeichen does carry a
86
+ trailing letter block the collision is UNRESOLVABLE from the string alone.
87
+
88
+ # ---------------------------------------------------------------------------
89
+ # ANLAGE 5d — the 98 authority codes, verbatim, in the annex's own order.
90
+ # `authority` is the annex's own wording, abbreviations expanded once:
91
+ # BH. = Bezirkshauptmannschaft, Mag. = Magistrat, Exp. = Expositur,
92
+ # LPD = Landespolizeidirektion.
93
+ # ---------------------------------------------------------------------------
94
+ codes:
95
+ # I. BURGENLAND
96
+ - { code: E, land: Burgenland, authority: "Landespolizeidirektion Burgenland für das Gebiet der Gemeinden Eisenstadt und Rust", landeshauptstadt: true }
97
+ - { code: EU, land: Burgenland, authority: "BH. Eisenstadt" }
98
+ - { code: ND, land: Burgenland, authority: "BH. Neusiedl am See" }
99
+ - { code: MA, land: Burgenland, authority: "BH. Mattersburg" }
100
+ - { code: OP, land: Burgenland, authority: "BH. Oberpullendorf" }
101
+ - { code: OW, land: Burgenland, authority: "BH. Oberwart" }
102
+ - { code: GS, land: Burgenland, authority: "BH. Güssing" }
103
+ - { code: JE, land: Burgenland, authority: "BH. Jennersdorf" }
104
+ # II. KÄRNTEN
105
+ - { code: K, land: Kärnten, authority: "Landespolizeidirektion Kärnten für das Gebiet der Gemeinde Klagenfurt am Wörthersee", landeshauptstadt: true }
106
+ - { code: VI, land: Kärnten, authority: "Landespolizeidirektion Kärnten für das Gebiet der Gemeinde Villach" }
107
+ - { code: VL, land: Kärnten, authority: "BH. Villach" }
108
+ - { code: WO, land: Kärnten, authority: "BH. Wolfsberg" }
109
+ - { code: SP, land: Kärnten, authority: "BH. Spittal an der Drau" }
110
+ - { code: FE, land: Kärnten, authority: "BH. Feldkirchen" }
111
+ - { code: HE, land: Kärnten, authority: "BH. Hermagor" }
112
+ - { code: SV, land: Kärnten, authority: "BH. St. Veit an der Glan" }
113
+ - { code: KL, land: Kärnten, authority: "BH. Klagenfurt" }
114
+ - { code: VK, land: Kärnten, authority: "BH. Völkermarkt" }
115
+ # III. NIEDERÖSTERREICH
116
+ - { code: P, land: Niederösterreich, authority: "Landespolizeidirektion Niederösterreich für das Gebiet der Gemeinde St. Pölten", landeshauptstadt: true }
117
+ - { code: AM, land: Niederösterreich, authority: "BH. Amstetten" }
118
+ - { code: BN, land: Niederösterreich, authority: "BH. Baden" }
119
+ - { code: BL, land: Niederösterreich, authority: "BH. Bruck an der Leitha" }
120
+ - { code: GF, land: Niederösterreich, authority: "BH. Gänserndorf" }
121
+ - { code: GD, land: Niederösterreich, authority: "BH. Gmünd" }
122
+ - { code: HL, land: Niederösterreich, authority: "BH. Hollabrunn" }
123
+ - { code: HO, land: Niederösterreich, authority: "BH. Horn" }
124
+ - { code: KO, land: Niederösterreich, authority: "BH. Korneuburg" }
125
+ - { code: KR, land: Niederösterreich, authority: "BH. Krems an der Donau" }
126
+ - { code: LF, land: Niederösterreich, authority: "BH. Lilienfeld" }
127
+ - { code: ME, land: Niederösterreich, authority: "BH. Melk" }
128
+ - { code: MI, land: Niederösterreich, authority: "BH. Mistelbach" }
129
+ - { code: MD, land: Niederösterreich, authority: "BH. Mödling" }
130
+ - { code: NK, land: Niederösterreich, authority: "BH. Neunkirchen" }
131
+ - { code: PL, land: Niederösterreich, authority: "BH. St. Pölten" }
132
+ - { code: SB, land: Niederösterreich, authority: "BH. Scheibbs" }
133
+ - { code: TU, land: Niederösterreich, authority: "BH. Tulln" }
134
+ - { code: WT, land: Niederösterreich, authority: "BH. Waidhofen an der Thaya" }
135
+ - { code: WB, land: Niederösterreich, authority: "BH. Wiener Neustadt" }
136
+ - { code: ZT, land: Niederösterreich, authority: "BH. Zwettl" }
137
+ - { code: WN, land: Niederösterreich, authority: "Landespolizeidirektion Niederösterreich für das Gebiet der Gemeinde Wr. Neustadt" }
138
+ - { code: KS, land: Niederösterreich, authority: "Mag. Krems an der Donau" }
139
+ - { code: WY, land: Niederösterreich, authority: "Mag. Waidhofen an der Ybbs" }
140
+ - { code: SW, land: Niederösterreich, authority: "Landespolizeidirektion Niederösterreich für das Gebiet der Gemeinde Schwechat und die im Gebiet der Gemeinden Fischamend, Klein-Neusiedl und Schwadorf gelegenen Teile des Flughafens Wien-Schwechat" }
141
+ - { code: KG, land: Niederösterreich, authority: "BH Tulln für das Gebiet der Gemeinde Klosterneuburg (Außenstelle Klosterneuburg)" }
142
+ # IV. OBERÖSTERREICH
143
+ - { code: L, land: Oberösterreich, authority: "Landespolizeidirektion Oberösterreich für das Gebiet der Gemeinde Linz", landeshauptstadt: true }
144
+ - { code: BR, land: Oberösterreich, authority: "BH. Braunau am Inn" }
145
+ - { code: EF, land: Oberösterreich, authority: "BH. Eferding" }
146
+ - { code: FR, land: Oberösterreich, authority: "BH. Freistadt" }
147
+ - { code: GM, land: Oberösterreich, authority: "BH. Gmunden" }
148
+ - { code: GR, land: Oberösterreich, authority: "BH. Grieskirchen" }
149
+ - { code: KI, land: Oberösterreich, authority: "BH. Kirchdorf an der Krems" }
150
+ - { code: LL, land: Oberösterreich, authority: "BH. Linz-Land" }
151
+ - { code: PE, land: Oberösterreich, authority: "BH. Perg" }
152
+ - { code: RI, land: Oberösterreich, authority: "BH. Ried im Innkreis" }
153
+ - { code: RO, land: Oberösterreich, authority: "BH. Rohrbach im Mühlkreis" }
154
+ - { code: SD, land: Oberösterreich, authority: "BH. Schärding" }
155
+ - { code: SE, land: Oberösterreich, authority: "BH. Steyr-Land" }
156
+ - { code: UU, land: Oberösterreich, authority: "BH. Urfahr-Umgebung" }
157
+ - { code: VB, land: Oberösterreich, authority: "BH. Vöcklabruck" }
158
+ - { code: WL, land: Oberösterreich, authority: "BH. Wels" }
159
+ - { code: SR, land: Oberösterreich, authority: "Landespolizeidirektion Oberösterreich für das Gebiet der Gemeinde Steyr" }
160
+ - { code: WE, land: Oberösterreich, authority: "Landespolizeidirektion Oberösterreich für das Gebiet der Gemeinde Wels" }
161
+ # V. SALZBURG
162
+ - { code: S, land: Salzburg, authority: "Landespolizeidirektion Salzburg für das Gebiet der Gemeinde Salzburg", landeshauptstadt: true }
163
+ - { code: SL, land: Salzburg, authority: "BH. Salzburg-Umgebung" }
164
+ - { code: HA, land: Salzburg, authority: "BH. Hallein" }
165
+ - { code: JO, land: Salzburg, authority: "BH. St. Johann" }
166
+ - { code: ZE, land: Salzburg, authority: "BH. Zell am See" }
167
+ - { code: TA, land: Salzburg, authority: "BH. Tamsweg", note: "the consolidated annex prints 'BH- Tamsweg' — a typo in the instrument, reproduced here as a finding, not corrected in the source" }
168
+ # VI. STEIERMARK
169
+ - { code: G, land: Steiermark, authority: "Landespolizeidirektion Steiermark für das Gebiet der Gemeinde Graz", landeshauptstadt: true }
170
+ - { code: GU, land: Steiermark, authority: "BH. Graz-Umgebung" }
171
+ - { code: BM, land: Steiermark, authority: "BH. Bruck-Mürzzuschlag" }
172
+ - { code: DL, land: Steiermark, authority: "BH. Deutschlandsberg" }
173
+ - { code: HF, land: Steiermark, authority: "BH. Hartberg-Fürstenfeld" }
174
+ - { code: MT, land: Steiermark, authority: "BH. Murtal" }
175
+ - { code: LB, land: Steiermark, authority: "BH. Leibnitz" }
176
+ - { code: LN, land: Steiermark, authority: "BH. Leoben" }
177
+ - { code: LI, land: Steiermark, authority: "BH. Liezen" }
178
+ - { code: MU, land: Steiermark, authority: "BH. Murau" }
179
+ - { code: SO, land: Steiermark, authority: "BH. Südoststeiermark" }
180
+ - { code: VO, land: Steiermark, authority: "BH. Voitsberg" }
181
+ - { code: WZ, land: Steiermark, authority: "BH. Weiz" }
182
+ - { code: GB, land: Steiermark, authority: "Exp. Gröbming" }
183
+ - { code: LE, land: Steiermark, authority: "Landespolizeidirektion Steiermark für das Gebiet der Gemeinde Leoben" }
184
+ - { code: BA, land: Steiermark, authority: "BH Liezen für das Gebiet der Gemeinden Bad Aussee, Altaussee, Grundlsee und Bad Mitterndorf (Außenstelle Bad Aussee)" }
185
+ # VII. TIROL
186
+ - { code: I, land: Tirol, authority: "Landespolizeidirektion Tirol für das Gebiet der Gemeinde Innsbruck", landeshauptstadt: true }
187
+ - { code: IL, land: Tirol, authority: "BH. Innsbruck" }
188
+ - { code: IM, land: Tirol, authority: "BH. Imst" }
189
+ - { code: KB, land: Tirol, authority: "BH. Kitzbühel" }
190
+ - { code: KU, land: Tirol, authority: "BH. Kufstein" }
191
+ - { code: LA, land: Tirol, authority: "BH. Landeck" }
192
+ - { code: RE, land: Tirol, authority: "BH. Reutte" }
193
+ - { code: SZ, land: Tirol, authority: "BH. Schwaz" }
194
+ - { code: LZ, land: Tirol, authority: "BH. Lienz" }
195
+ # VIII. VORARLBERG
196
+ - { code: B, land: Vorarlberg, authority: "BH. Bregenz" }
197
+ - { code: FK, land: Vorarlberg, authority: "BH. Feldkirch" }
198
+ - { code: BZ, land: Vorarlberg, authority: "BH. Bludenz" }
199
+ - { code: DO, land: Vorarlberg, authority: "BH. Dornbirn" }
200
+ # IX. WIEN
201
+ - { code: W, land: Wien, authority: "Landespolizeidirektion Wien", landeshauptstadt: true }
202
+
203
+ landeshauptstadt_note: >-
204
+ `landeshauptstadt: true` marks the codes this pass reads as
205
+ "in den Landeshauptstädten ... zugewiesen" for the purposes of § 26 Abs. 6
206
+ Z 2 lit. a KDV (one Vormerkzeichen character MORE than elsewhere). It is
207
+ flagged as an INFERENCE, not a primary: the annex names those authorities
208
+ "Landespolizeidirektion X für das Gebiet der Gemeinde <Landeshauptstadt>",
209
+ which is why the nine are picked out, but the KDV never says that the
210
+ extra character attaches to those CODES. Vorarlberg is the case that proves
211
+ the inference is not safe: its Landeshauptstadt is Bregenz, whose plates
212
+ are issued by "BH. Bregenz" (code B) over a whole district, and the annex
213
+ gives Vorarlberg no Landespolizeidirektion row at all — so B is left
214
+ unmarked here and the question is a recorded gap.
215
+
216
+ # ---------------------------------------------------------------------------
217
+ # THE NON-GEOGRAPHIC PREFIXES — § 26 KDV itself, not Anlage 5d.
218
+ # ---------------------------------------------------------------------------
219
+ federal_letter:
220
+ source: "https://www.ris.bka.gv.at/NormDokument.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10011385&Paragraf=26 # § 26 Abs. 2"
221
+ A: >-
222
+ Fahrzeuge, die zur Verwendung für den Bundespräsidenten, die Präsidenten des
223
+ Nationalrates, die Präsidenten des Bundesrates, die Mitglieder der
224
+ Bundesregierung, die Staatssekretäre, die Mitglieder der Volksanwaltschaft,
225
+ den Präsidenten oder Vizepräsidenten des Rechnungshofes, des
226
+ Verfassungsgerichtshofes und Verwaltungsgerichtshofes oder des Obersten
227
+ Gerichtshofes bestimmt sind
228
+
229
+ land_letters:
230
+ source: "https://www.ris.bka.gv.at/NormDokument.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10011385&Paragraf=26 # § 26 Abs. 3, verbatim list"
231
+ scope: >-
232
+ Fahrzeuge, die zur Verwendung für die Präsidenten der Landtage sowie für die
233
+ Mitglieder der Landesregierungen sowie für die Mitglieder der
234
+ Landesvolksanwaltschaften bestimmt sind
235
+ codes:
236
+ B: Burgenland
237
+ K: Kärnten
238
+ N: Niederösterreich
239
+ O: Oberösterreich
240
+ S: Salzburg
241
+ ST: Steiermark
242
+ T: Tirol
243
+ V: Vorarlberg
244
+ W: Wien
245
+ note: >-
246
+ ST is the only THREE-position prefix base in the system and the reason the
247
+ § 26 Abs. 5 Graz exception exists (see diplomatic_consular below). N and O
248
+ appear ONLY here — no Anlage 5d district carries them.
249
+
250
+ sachliche_bereiche:
251
+ source: "https://www.ris.bka.gv.at/NormDokument.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10011385&Paragraf=26 # § 26 Abs. 4 lit. a-i (lit. b repealed by BGBl. II Nr. 275/2007, lit. d by BGBl. II Nr. 376/2002)"
252
+ codes:
253
+ BP: "Fahrzeuge, die zur Verwendung im Bereich der Bundespolizei bestimmt sind"
254
+ FV: "Fahrzeuge, die zur Verwendung im Bereich der Finanzverwaltung bestimmt sind"
255
+ PT: "Fahrzeuge, die zur Verwendung im Bereich der Post bestimmt sind"
256
+ BD: "Omnibusse, die zur Verwendung im Kraftfahrlinienverkehr der Österreichischen Bundesbahnen und der Post- und Telegraphenverwaltung (Bundesbusdienst) bestimmt sind"
257
+ BH: "Heeresfahrzeuge"
258
+ JW: "Fahrzeuge, die zur Verwendung im Bereich der Justizwache bestimmt sind"
259
+ FW: "Fahrzeuge, die zur Verwendung für die Feuerwehr bestimmt sind"
260
+ note: >-
261
+ FW is the ONE prefix whose serial encodes geography: § 26 Abs. 6 Z 1 lit. b
262
+ requires a fire-brigade Vormerkzeichen to "mit zwei oder drei Ziffern
263
+ beginnen und es folgen ein oder zwei Buchstaben, die der Bezeichnung der
264
+ Behörde im Sinne der Anlage 5d entsprechen müssen, in deren Sprengel das
265
+ Fahrzeug zugelassen ist" — so the district code moves to the END of the
266
+ string and the `codes` table above decodes the SUFFIX, not the prefix.
267
+
268
+ diplomatic_consular:
269
+ source: "https://www.ris.bka.gv.at/NormDokument.wxe?Abfrage=Bundesnormen&Gesetzesnummer=10011385&Paragraf=26 # § 26 Abs. 5 lit. a (D) and lit. b (K), plus the Graz exception in the opening sentence"
270
+ mechanism: >-
271
+ For the vehicles listed in § 54 Abs. 3 and Abs. 3a lit. a und b KFG 1967
272
+ (the CD and CC entitlement classes), the sachlicher Bereich is "die
273
+ Buchstaben gemäß Abs. 3" — i.e. the LAND letter — "bei Fahrzeugen mit dem
274
+ Standort in Graz ist an Stelle der Buchstaben gemäß Abs. 3 die Bezeichnung
275
+ der Behörde gemäß Anlage 5d zu verwenden" (so G, not ST). That base letter
276
+ is then followed by D for the diplomatic corps and internationally
277
+ equivalent officials, or K for the consular corps.
278
+ diplomatic_prefixes: [BD, KD, ND, OD, SD, STD, TD, VD, WD, GD]
279
+ consular_prefixes: [BK, KK, NK, OK, SK, STK, TK, VK, WK, GK]
280
+ derivation_note: >-
281
+ The twenty prefixes above are DERIVED by applying the § 26 Abs. 5 rule to
282
+ the § 26 Abs. 3 list plus the Graz exception; the KDV nowhere prints them as
283
+ a table. They are recorded here because a parse API needs them, and marked
284
+ as derived, not quoted. WD is overwhelmingly the populated one (the
285
+ diplomatic corps and the Vienna-based international organisations), and
286
+ several of the others may never have been issued — an unverified claim,
287
+ left unverified.
@@ -0,0 +1,110 @@
1
+ # plates/_decode/ch-cantons.yml — the Swiss canton letters. DRAFT for verification.
2
+ #
3
+ # THE SOURCE FINDING, and it is the good kind: this table is NOT a Wikipedia
4
+ # scrape and not an enthusiast list. It is enacted law, printed as a two-column
5
+ # table inside the ordinance itself — Verkehrszulassungsverordnung (VZV),
6
+ # SR 741.51, Art. 84 Abs. 1: "Jeder Kanton wird mit zwei grossen Buchstaben wie
7
+ # folgt bezeichnet:" followed by exactly the 26 rows below, in exactly this
8
+ # order. Every row here is that table, verbatim, in the ordinance's own order
9
+ # (the constitutional order of precedence, NOT alphabetical), with the French
10
+ # and Italian canton names taken from the FR and IT language versions of the
11
+ # same consolidated article.
12
+ #
13
+ # This is the German-Anlage-2 case and not the German-district case, and the
14
+ # contrast is worth stating because it drives the schema choice: § 9 Abs. 3 FZV
15
+ # delegates the ~400 German district codes to Bundesanzeiger publications, so
16
+ # plates/de.yml can only cite the MECHANISM; VZV Art. 84 Abs. 1 enumerates all
17
+ # 26 Swiss codes inside the regulation, so this table is closed, primary and
18
+ # complete on its face. There is no delegation, no open tail and no "on
19
+ # application by the canton" clause.
20
+ #
21
+ # Referenced by: plates/ch.yml (ch-standard, ch-standard-trailer, ch-motorcycle,
22
+ # ch-lightmotor-yellow, ch-motorfahrrad, ch-workvehicle-blue,
23
+ # ch-exceptional-brown, ch-agricultural-green, ch-diplomatic-cd,
24
+ # ch-consular-cc, ch-diplomatic-at, ch-provisional, ch-provisional-z,
25
+ # ch-dealer-u, ch-dealer-pre1977, ch-rental-1977) via region_encoding.
26
+ # NOT referenced by ch-military-m: federal military plates carry the single
27
+ # letter M and no canton code at all (VZV Art. 84 Abs. 3).
28
+ jurisdiction: ch
29
+ topic: cantons
30
+ authority:
31
+ name: Verkehrszulassungsverordnung (VZV), SR 741.51, Art. 84 Abs. 1
32
+ url: "https://www.fedlex.admin.ch/eli/cc/1976/2423_2423_2423/de"
33
+ sources:
34
+ - "https://www.fedlex.admin.ch/eli/cc/1976/2423_2423_2423/de # VZV Art. 84 Abs. 1 — the 26-row table, German names and codes, in the ordinance's own order; and the Jura footnote 'Kanton eingefügt durch Ziff. I der V vom 15. Nov. 1978, in Kraft seit 1. Jan. 1979 (AS 1978 1805)'"
35
+ - "https://www.fedlex.admin.ch/eli/cc/1976/2423_2423_2423/fr # OAC art. 84 al. 1 — the same table with the FRENCH canton names"
36
+ - "https://www.fedlex.admin.ch/eli/cc/1976/2423_2423_2423/it # OAC art. 84 cpv. 1 — the same table with the ITALIAN canton names"
37
+ accessed: "2026-08-02"
38
+ period: { start: 1977 }
39
+ period_evidence: instrument-in-force
40
+ period_note: >-
41
+ 1977 is the VZV's entry into force (1 January 1977), not the date the two-letter
42
+ canton abbreviations came into use — they are the ordinary Swiss cantonal
43
+ abbreviations and long predate the ordinance. No primary for their origin was
44
+ secured in this pass, so none is asserted. The ONE row with a real, dated,
45
+ primary start is JU: the ordinance's own footnote records the Jura row as
46
+ "Kanton eingefügt durch Ziff. I der V vom 15. Nov. 1978, in Kraft seit
47
+ 1. Jan. 1979 (AS 1978 1805)" — the canton of Jura separated from Bern and the
48
+ code entered the table on 1 January 1979. A plate allocated before that date
49
+ cannot read JU, and the territory JU covers read BE.
50
+
51
+ # Decode facts a parse API must carry.
52
+ maximal_munch: false
53
+ maximal_munch_note: >-
54
+ Not applicable, and that is a genuine simplification over Spain: every Swiss
55
+ code is EXACTLY two capital letters (VZV Art. 84 Abs. 1: "mit zwei grossen
56
+ Buchstaben"), so the letter/number boundary is fixed at position 2 and there is
57
+ no longest-match ambiguity of the C / CA / CC / CE kind that es-provinces.yml
58
+ has to warn about.
59
+ decode_semantics: >-
60
+ The code identifies the canton of the KEEPER's Standort, not the vehicle's
61
+ location, origin or manufacture. VZV Art. 77 Abs. 1 defines Standort as "der
62
+ Ort, wo das Fahrzeug nach Gebrauch in der Regel für die Nacht abgestellt wird",
63
+ with the keeper's domicile deemed the Standort in the three cases of Abs. 2.
64
+ Because the plate binds to the keeper (VZV Art. 87 Abs. 1), the code moves when
65
+ the KEEPER moves: VZV Art. 120 returns the annulled certificate and plates to
66
+ the former canton when a vehicle is admitted in another, and VZV Art. 95 Abs. 2
67
+ makes the same rule explicit for mopeds. A decoded canton is therefore a claim
68
+ about a person, not about a vehicle — the sharpest practical consequence of
69
+ Switzerland's owner-binding, and one a vehicle-keyed consumer will get wrong by
70
+ default.
71
+ collisions:
72
+ - "AG (Aargau), AI (Appenzell Innerrhoden), AR (Appenzell Ausserrhoden) — no collision with the diplomatic sign AT, which occupies its own field ahead of the canton letters (VZV Art. 85 Abs. 4), but a naive left-anchored parser reading 'AT BE 12-34' will try AT as a canton code and must not."
73
+ - "The letter M is NOT a canton code: it is the federal military marker of VZV Art. 84 Abs. 3, and it is a SINGLE letter, which is what distinguishes it structurally."
74
+ - "The letter U (dealer marking, VZV Art. 82 Abs. 2 lit. c) and the letter Z (uncleared provisional vehicle, VVV Anhang 2 A Ziff. 3) are markings, not canton codes; the ordinance does not fix their position, so a parser must not assume they trail the number even though that is the observed form."
75
+ codes:
76
+ - { code: ZH, de: "Zürich", fr: "Zurich", it: "Zurigo", period: { start: 1977 } }
77
+ - { code: BE, de: "Bern", fr: "Berne", it: "Berna", period: { start: 1977 } }
78
+ - { code: LU, de: "Luzern", fr: "Lucerne", it: "Lucerna", period: { start: 1977 } }
79
+ - { code: UR, de: "Uri", fr: "Uri", it: "Uri", period: { start: 1977 } }
80
+ - { code: SZ, de: "Schwyz", fr: "Schwyz", it: "Svitto", period: { start: 1977 } }
81
+ - { code: OW, de: "Obwalden", fr: "Obwald", it: "Obvaldo", period: { start: 1977 } }
82
+ - { code: NW, de: "Nidwalden", fr: "Nidwald", it: "Nidvaldo", period: { start: 1977 } }
83
+ - { code: GL, de: "Glarus", fr: "Glaris", it: "Glarona", period: { start: 1977 } }
84
+ - { code: ZG, de: "Zug", fr: "Zoug", it: "Zugo", period: { start: 1977 } }
85
+ - { code: FR, de: "Freiburg", fr: "Fribourg", it: "Friburgo", period: { start: 1977 } }
86
+ - { code: SO, de: "Solothurn", fr: "Soleure", it: "Soletta", period: { start: 1977 } }
87
+ - { code: BS, de: "Basel-Stadt", fr: "Bâle-Ville", it: "Basilea Città", period: { start: 1977 } }
88
+ - { code: BL, de: "Basel-Landschaft", fr: "Bâle-Campagne", it: "Basilea Campagna", period: { start: 1977 } }
89
+ - { code: SH, de: "Schaffhausen", fr: "Schaffhouse", it: "Sciaffusa", period: { start: 1977 } }
90
+ - { code: AR, de: "Appenzell A. Rh", fr: "Appenzell, Rhodes extérieures", it: "Appenzello esterno", period: { start: 1977 } }
91
+ - { code: AI, de: "Appenzell I. Rh.", fr: "Appenzell, Rhodes intérieures", it: "Appenzello interno", period: { start: 1977 } }
92
+ - { code: SG, de: "St. Gallen", fr: "Saint-Gall", it: "San Gallo", period: { start: 1977 } }
93
+ - { code: GR, de: "Graubünden", fr: "Grisons", it: "Grigioni", period: { start: 1977 } }
94
+ - { code: AG, de: "Aargau", fr: "Argovie", it: "Argovia", period: { start: 1977 } }
95
+ - { code: TG, de: "Thurgau", fr: "Thurgovie", it: "Turgovia", period: { start: 1977 } }
96
+ - { code: TI, de: "Tessin", fr: "Tessin", it: "Ticino", period: { start: 1977 } }
97
+ - { code: VD, de: "Waadt", fr: "Vaud", it: "Vaud", period: { start: 1977 } }
98
+ - { code: VS, de: "Wallis", fr: "Valais", it: "Vallese", period: { start: 1977 } }
99
+ - { code: NE, de: "Neuenburg", fr: "Neuchâtel", it: "Neuchâtel", period: { start: 1977 } }
100
+ - { code: GE, de: "Genf", fr: "Genève", it: "Ginevra", period: { start: 1977 } }
101
+ - { code: JU, de: "Jura", fr: "Jura", it: "Giura", period: { start: 1979 }, period_evidence: enabling-amendment, note: "row inserted by Ziff. I der V vom 15. Nov. 1978, in force 1 Jan. 1979 (AS 1978 1805); before that the territory registered as BE" }
102
+
103
+ # Not a decode dimension, recorded so nobody looks for one: the Swiss plate
104
+ # carries NO date, NO issuing-office code below canton level and NO vehicle-type
105
+ # code inside the serial. Vehicle type is signalled by the plate's BACKGROUND
106
+ # COLOUR and SIZE (VZV Art. 82 Abs. 1, Art. 83 Abs. 3), both of which are
107
+ # properties of the physical object rather than of the string. Number ranges are
108
+ # not published: VZV Art. 84 Abs. 2 says only that each per-canton, per-colour,
109
+ # per-marking counter starts "in der Regel mit der Zahl 1".
110
+ no_further_decode: true