@mailwoman/corpus 9.4.0 → 10.0.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 (981) hide show
  1. package/README.md +16 -0
  2. package/lib/adapters/geonames/adapter.ts +3 -3
  3. package/lib/adapters/geonames/postal/adapter.ts +122 -0
  4. package/lib/adapters/index.ts +39 -32
  5. package/lib/adapters/openaddresses/adapter.ts +4 -7
  6. package/lib/adapters/osm/adapter.ts +278 -0
  7. package/lib/adapters/overture/adapter.ts +22 -7
  8. package/lib/adapters/utils/index.ts +1 -1
  9. package/lib/adapters/wof/admin/json/adapter.ts +239 -0
  10. package/lib/adapters/wof/json-rows.ts +181 -0
  11. package/lib/adapters/wof/postalcode-json/adapter.ts +196 -0
  12. package/lib/au/adapters/gnaf/adapter.ts +152 -0
  13. package/lib/au/adapters/gnaf/assemble.ts +225 -0
  14. package/lib/de/recipes/locale.ts +360 -0
  15. package/lib/fr/adapters/ban/adapter.ts +159 -0
  16. package/lib/fr/recipes/admin-split.ts +243 -0
  17. package/lib/fr/recipes/bare-street.ts +171 -0
  18. package/lib/fr/recipes/fragment.ts +334 -0
  19. package/lib/fr/recipes/lieudit.ts +274 -0
  20. package/lib/fr/recipes/order.ts +246 -0
  21. package/lib/fr/tools/fetch/ban.ts +289 -0
  22. package/lib/index.ts +1 -1
  23. package/lib/international/recipes/locale.ts +598 -0
  24. package/lib/jp/tools/fetch/houjin.ts +141 -0
  25. package/lib/kr/adapters/juso/label-rows.ts +259 -0
  26. package/lib/kr/adapters/localdata/align.ts +299 -0
  27. package/lib/kr/adapters/localdata/key-index.ts +185 -0
  28. package/lib/kr/adapters/localdata/permit-rows.ts +186 -0
  29. package/lib/kr/tools/fetch/juso.ts +172 -0
  30. package/lib/kr/tools/fetch/localdata.ts +206 -0
  31. package/lib/recipes/bare/postcode/eval.ts +99 -0
  32. package/lib/recipes/bare/postcode/index.ts +327 -0
  33. package/lib/recipes/country-balanced.ts +1 -1
  34. package/lib/recipes/index.ts +28 -21
  35. package/lib/recipes/intersection.ts +1 -1
  36. package/lib/recipes/po/box/cedex/au-nz.ts +82 -0
  37. package/lib/recipes/po/box/cedex/ca.ts +58 -0
  38. package/lib/recipes/po/box/cedex/fr.ts +76 -0
  39. package/lib/recipes/po/box/cedex/phrases.ts +108 -0
  40. package/lib/recipes/po/box/cedex/recipe.ts +203 -0
  41. package/lib/recipes/po/box/cedex/sources.ts +189 -0
  42. package/lib/recipes/po/box/cedex/types.ts +35 -0
  43. package/lib/recipes/po/box/cedex/us.ts +69 -0
  44. package/lib/recipes/po/box/cedex/vocabulary.ts +106 -0
  45. package/lib/recipes/po/box/cedex.ts +9 -0
  46. package/lib/recipes/po/box/index.ts +128 -0
  47. package/lib/recipes/scaffold.ts +18 -41
  48. package/lib/recipes/street/affix.ts +807 -0
  49. package/lib/recipes/sub/venue/context.ts +149 -0
  50. package/lib/recipes/sub/venue/index.ts +997 -0
  51. package/lib/recipes/sub/venue/sources.ts +739 -0
  52. package/lib/recipes/trailing-region.ts +6 -1
  53. package/lib/recipes/unit.ts +1 -1
  54. package/lib/sg/recipes/register.ts +270 -0
  55. package/lib/sg/tools/fetch/acra.ts +179 -0
  56. package/lib/south-asia/recipes/register.ts +214 -0
  57. package/lib/synthesizers/anchor-absorption.ts +1 -1
  58. package/lib/synthesizers/locale.ts +261 -0
  59. package/lib/synthesizers/street.ts +1 -1
  60. package/lib/synthesizers/utils.ts +2 -2
  61. package/lib/tools/audit.ts +3 -2
  62. package/lib/tools/corpus-stats.ts +3 -3
  63. package/lib/tools/fetch/download/index.ts +10 -0
  64. package/lib/tools/fetch/download/manifest.ts +102 -0
  65. package/lib/tools/fetch/download/network.ts +226 -0
  66. package/lib/tools/fetch/download/retry.ts +173 -0
  67. package/lib/tools/fetch/geonames/dump.ts +257 -0
  68. package/lib/tools/fetch/geonames/postal.ts +180 -0
  69. package/lib/tools/fetch/index.ts +30 -30
  70. package/lib/tools/fetch/openaddresses.ts +2 -2
  71. package/lib/tools/fetch/ourairports.ts +2 -2
  72. package/lib/tools/fetch/ppd.ts +1 -3
  73. package/lib/tools/fetch/wikidata-subvenue.ts +2 -2
  74. package/lib/tools/golden/promote.ts +340 -0
  75. package/lib/tools/golden/relabel-street/directory.ts +340 -0
  76. package/lib/tools/golden/relabel-street/index.ts +9 -0
  77. package/lib/tools/golden/relabel-street/row.ts +361 -0
  78. package/lib/tools/index.ts +10 -10
  79. package/lib/tools/ingest-csv.ts +5 -7
  80. package/lib/tools/lint/slice/vocab.ts +376 -0
  81. package/lib/tools/overlay-manifest.ts +92 -25
  82. package/lib/tools/overture-subvenue.ts +1 -1
  83. package/lib/tools/postcode-triples.ts +138 -14
  84. package/lib/tools/sub/venue/harvest.ts +234 -0
  85. package/lib/tools/sub/venue/head-nouns.ts +245 -0
  86. package/lib/tools/sub/venue/lexicon.ts +429 -0
  87. package/lib/tools/sub/venue/surfaces.ts +95 -0
  88. package/lib/tools/sub/venue/table.ts +281 -0
  89. package/lib/tools/sub/venue/wikidata.ts +85 -0
  90. package/lib/tw/tools/fetch/gcis.ts +180 -0
  91. package/lib/types.ts +1 -1
  92. package/lib/us/adapters/fcc-bdc/adapter.ts +173 -0
  93. package/lib/us/adapters/state/hi-schools/adapter.ts +160 -0
  94. package/lib/us/adapters/state/ia-contractors/adapter.ts +136 -0
  95. package/lib/us/adapters/state/ny-notaries/adapter.ts +133 -0
  96. package/lib/us/adapters/state/tx-notaries/adapter.ts +149 -0
  97. package/lib/us/adapters/tiger/adapter.ts +250 -0
  98. package/lib/us/adapters/usgov/hrsa-fqhc/adapter.ts +156 -0
  99. package/lib/us/adapters/usgov/imls-pls/adapter.ts +134 -0
  100. package/lib/us/adapters/usgov/irs-bmf/adapter.ts +145 -0
  101. package/lib/us/adapters/usgov/nad/adapter.ts +324 -0
  102. package/lib/us/adapters/usgov/nppes/adapter.ts +143 -0
  103. package/lib/us/adapters/usgov/samhsa-treatment-locator/adapter.ts +182 -0
  104. package/lib/us/tools/fetch/hrsa.ts +59 -0
  105. package/lib/us/tools/fetch/imls-pls.ts +149 -0
  106. package/lib/us/tools/fetch/nad.ts +341 -0
  107. package/lib/us/tools/fetch/nppes.ts +165 -0
  108. package/lib/us/tools/fetch/state/hi-schools.ts +161 -0
  109. package/lib/us/tools/fetch/state/sources.ts +146 -0
  110. package/lib/us/tools/fetch/tiger-full.ts +308 -0
  111. package/lib/utils/align.ts +1 -1
  112. package/lib/utils/golden.ts +12 -8
  113. package/lib/utils/wof-json.ts +7 -13
  114. package/out/adapters/geonames/adapter.d.ts +1 -1
  115. package/out/adapters/geonames/adapter.js +3 -3
  116. package/out/adapters/geonames/adapter.js.map +1 -1
  117. package/out/adapters/geonames/postal/adapter.d.ts.map +1 -0
  118. package/out/adapters/geonames/postal/adapter.js +107 -0
  119. package/out/adapters/geonames/postal/adapter.js.map +1 -0
  120. package/out/adapters/index.d.ts +16 -16
  121. package/out/adapters/index.d.ts.map +1 -1
  122. package/out/adapters/index.js +34 -32
  123. package/out/adapters/index.js.map +1 -1
  124. package/out/adapters/openaddresses/adapter.d.ts.map +1 -1
  125. package/out/adapters/openaddresses/adapter.js +4 -6
  126. package/out/adapters/openaddresses/adapter.js.map +1 -1
  127. package/out/adapters/osm/adapter.d.ts +95 -0
  128. package/out/adapters/osm/adapter.d.ts.map +1 -0
  129. package/out/adapters/osm/adapter.js +211 -0
  130. package/out/adapters/osm/adapter.js.map +1 -0
  131. package/out/adapters/overture/adapter.d.ts +10 -0
  132. package/out/adapters/overture/adapter.d.ts.map +1 -1
  133. package/out/adapters/overture/adapter.js +20 -7
  134. package/out/adapters/overture/adapter.js.map +1 -1
  135. package/out/adapters/synth-po-box/adapter.js.map +1 -1
  136. package/out/adapters/utils/index.d.ts +1 -1
  137. package/out/adapters/utils/index.d.ts.map +1 -1
  138. package/out/adapters/utils/index.js.map +1 -1
  139. package/out/adapters/wof/admin/json/adapter.d.ts +79 -0
  140. package/out/adapters/wof/admin/json/adapter.d.ts.map +1 -0
  141. package/out/adapters/wof/admin/json/adapter.js +204 -0
  142. package/out/adapters/wof/admin/json/adapter.js.map +1 -0
  143. package/out/adapters/wof/json-rows.d.ts +73 -0
  144. package/out/adapters/wof/json-rows.d.ts.map +1 -0
  145. package/out/adapters/wof/json-rows.js +115 -0
  146. package/out/adapters/wof/json-rows.js.map +1 -0
  147. package/out/adapters/wof/postalcode-json/adapter.d.ts +65 -0
  148. package/out/adapters/wof/postalcode-json/adapter.d.ts.map +1 -0
  149. package/out/adapters/wof/postalcode-json/adapter.js +167 -0
  150. package/out/adapters/wof/postalcode-json/adapter.js.map +1 -0
  151. package/out/au/adapters/gnaf/adapter.d.ts.map +1 -0
  152. package/out/au/adapters/gnaf/adapter.js +127 -0
  153. package/out/au/adapters/gnaf/adapter.js.map +1 -0
  154. package/out/au/adapters/gnaf/assemble.d.ts +65 -0
  155. package/out/au/adapters/gnaf/assemble.d.ts.map +1 -0
  156. package/out/au/adapters/gnaf/assemble.js +154 -0
  157. package/out/au/adapters/gnaf/assemble.js.map +1 -0
  158. package/out/cn/recipes/organizational-units.d.ts +36 -0
  159. package/out/cn/recipes/organizational-units.d.ts.map +1 -0
  160. package/out/cn/recipes/organizational-units.js +159 -0
  161. package/out/cn/recipes/organizational-units.js.map +1 -0
  162. package/out/cz/recipes/pcfirst-preposition.d.ts +22 -0
  163. package/out/cz/recipes/pcfirst-preposition.d.ts.map +1 -0
  164. package/out/cz/recipes/pcfirst-preposition.js +101 -0
  165. package/out/cz/recipes/pcfirst-preposition.js.map +1 -0
  166. package/out/de/recipes/locale.d.ts +44 -0
  167. package/out/de/recipes/locale.d.ts.map +1 -0
  168. package/out/de/recipes/locale.js +289 -0
  169. package/out/de/recipes/locale.js.map +1 -0
  170. package/out/env.d.ts +1 -1
  171. package/out/fr/adapters/ban/adapter.d.ts.map +1 -0
  172. package/out/fr/adapters/ban/adapter.js +123 -0
  173. package/out/fr/adapters/ban/adapter.js.map +1 -0
  174. package/out/fr/adapters/ban/street-decompose.d.ts.map +1 -0
  175. package/out/fr/adapters/ban/street-decompose.js.map +1 -0
  176. package/out/fr/recipes/admin-split.d.ts +38 -0
  177. package/out/fr/recipes/admin-split.d.ts.map +1 -0
  178. package/out/fr/recipes/admin-split.js +192 -0
  179. package/out/fr/recipes/admin-split.js.map +1 -0
  180. package/out/fr/recipes/bare-street.d.ts +28 -0
  181. package/out/fr/recipes/bare-street.d.ts.map +1 -0
  182. package/out/fr/recipes/bare-street.js +144 -0
  183. package/out/fr/recipes/bare-street.js.map +1 -0
  184. package/out/fr/recipes/fragment.d.ts +77 -0
  185. package/out/fr/recipes/fragment.d.ts.map +1 -0
  186. package/out/fr/recipes/fragment.js +277 -0
  187. package/out/fr/recipes/fragment.js.map +1 -0
  188. package/out/fr/recipes/lieudit.d.ts +32 -0
  189. package/out/fr/recipes/lieudit.d.ts.map +1 -0
  190. package/out/fr/recipes/lieudit.js +211 -0
  191. package/out/fr/recipes/lieudit.js.map +1 -0
  192. package/out/fr/recipes/order.d.ts +38 -0
  193. package/out/fr/recipes/order.d.ts.map +1 -0
  194. package/out/fr/recipes/order.js +198 -0
  195. package/out/fr/recipes/order.js.map +1 -0
  196. package/out/fr/tools/fetch/ban.d.ts +31 -0
  197. package/out/fr/tools/fetch/ban.d.ts.map +1 -0
  198. package/out/fr/tools/fetch/ban.js +239 -0
  199. package/out/fr/tools/fetch/ban.js.map +1 -0
  200. package/out/index.d.ts +1 -1
  201. package/out/index.d.ts.map +1 -1
  202. package/out/index.js +1 -1
  203. package/out/index.js.map +1 -1
  204. package/out/international/recipes/locale.d.ts +136 -0
  205. package/out/international/recipes/locale.d.ts.map +1 -0
  206. package/out/international/recipes/locale.js +458 -0
  207. package/out/international/recipes/locale.js.map +1 -0
  208. package/out/jp/adapters/wof-admin/adapter.d.ts.map +1 -0
  209. package/out/jp/adapters/wof-admin/adapter.js.map +1 -0
  210. package/out/jp/tools/fetch/houjin.d.ts +24 -0
  211. package/out/jp/tools/fetch/houjin.d.ts.map +1 -0
  212. package/out/jp/tools/fetch/houjin.js +102 -0
  213. package/out/jp/tools/fetch/houjin.js.map +1 -0
  214. package/out/kr/adapters/juso/label-rows.d.ts +76 -0
  215. package/out/kr/adapters/juso/label-rows.d.ts.map +1 -0
  216. package/out/kr/adapters/juso/label-rows.js +194 -0
  217. package/out/kr/adapters/juso/label-rows.js.map +1 -0
  218. package/out/kr/adapters/localdata/align.d.ts +43 -0
  219. package/out/kr/adapters/localdata/align.d.ts.map +1 -0
  220. package/out/kr/adapters/localdata/align.js +223 -0
  221. package/out/kr/adapters/localdata/align.js.map +1 -0
  222. package/out/kr/adapters/localdata/key-index.d.ts +71 -0
  223. package/out/kr/adapters/localdata/key-index.d.ts.map +1 -0
  224. package/out/kr/adapters/localdata/key-index.js +133 -0
  225. package/out/kr/adapters/localdata/key-index.js.map +1 -0
  226. package/out/kr/adapters/localdata/permit-rows.d.ts +66 -0
  227. package/out/kr/adapters/localdata/permit-rows.d.ts.map +1 -0
  228. package/out/kr/adapters/localdata/permit-rows.js +131 -0
  229. package/out/kr/adapters/localdata/permit-rows.js.map +1 -0
  230. package/out/kr/tools/fetch/juso.d.ts +30 -0
  231. package/out/kr/tools/fetch/juso.d.ts.map +1 -0
  232. package/out/kr/tools/fetch/juso.js +120 -0
  233. package/out/kr/tools/fetch/juso.js.map +1 -0
  234. package/out/kr/tools/fetch/localdata.d.ts +30 -0
  235. package/out/kr/tools/fetch/localdata.d.ts.map +1 -0
  236. package/out/kr/tools/fetch/localdata.js +139 -0
  237. package/out/kr/tools/fetch/localdata.js.map +1 -0
  238. package/out/nl/recipes/postcode.d.ts +26 -0
  239. package/out/nl/recipes/postcode.d.ts.map +1 -0
  240. package/out/nl/recipes/postcode.js +103 -0
  241. package/out/nl/recipes/postcode.js.map +1 -0
  242. package/out/no/recipes/fragment.d.ts +43 -0
  243. package/out/no/recipes/fragment.d.ts.map +1 -0
  244. package/out/no/recipes/fragment.js +183 -0
  245. package/out/no/recipes/fragment.js.map +1 -0
  246. package/out/no/recipes/street/index.d.ts +18 -0
  247. package/out/no/recipes/street/index.d.ts.map +1 -0
  248. package/out/no/recipes/street/index.js +72 -0
  249. package/out/no/recipes/street/index.js.map +1 -0
  250. package/out/no/recipes/street/led.d.ts +24 -0
  251. package/out/no/recipes/street/led.d.ts.map +1 -0
  252. package/out/no/recipes/street/led.js +114 -0
  253. package/out/no/recipes/street/led.js.map +1 -0
  254. package/out/recipes/bare/country.d.ts +25 -0
  255. package/out/recipes/bare/country.d.ts.map +1 -0
  256. package/out/recipes/bare/country.js +88 -0
  257. package/out/recipes/bare/country.js.map +1 -0
  258. package/out/recipes/bare/postcode/eval.d.ts +29 -0
  259. package/out/recipes/bare/postcode/eval.d.ts.map +1 -0
  260. package/out/recipes/bare/postcode/eval.js +85 -0
  261. package/out/recipes/bare/postcode/eval.js.map +1 -0
  262. package/out/recipes/bare/postcode/index.d.ts +62 -0
  263. package/out/recipes/bare/postcode/index.d.ts.map +1 -0
  264. package/out/recipes/bare/postcode/index.js +267 -0
  265. package/out/recipes/bare/postcode/index.js.map +1 -0
  266. package/out/recipes/country-balanced.js.map +1 -1
  267. package/out/recipes/index.d.ts.map +1 -1
  268. package/out/recipes/index.js +28 -21
  269. package/out/recipes/index.js.map +1 -1
  270. package/out/recipes/intersection.js.map +1 -1
  271. package/out/recipes/po/box/cedex/au-nz.d.ts +7 -0
  272. package/out/recipes/po/box/cedex/au-nz.d.ts.map +1 -0
  273. package/out/recipes/po/box/cedex/au-nz.js +56 -0
  274. package/out/recipes/po/box/cedex/au-nz.js.map +1 -0
  275. package/out/recipes/po/box/cedex/ca.d.ts +7 -0
  276. package/out/recipes/po/box/cedex/ca.d.ts.map +1 -0
  277. package/out/recipes/po/box/cedex/ca.js +38 -0
  278. package/out/recipes/po/box/cedex/ca.js.map +1 -0
  279. package/out/recipes/po/box/cedex/fr.d.ts +7 -0
  280. package/out/recipes/po/box/cedex/fr.d.ts.map +1 -0
  281. package/out/recipes/po/box/cedex/fr.js +57 -0
  282. package/out/recipes/po/box/cedex/fr.js.map +1 -0
  283. package/out/recipes/po/box/cedex/phrases.d.ts +8 -0
  284. package/out/recipes/po/box/cedex/phrases.d.ts.map +1 -0
  285. package/out/recipes/po/box/cedex/phrases.js +76 -0
  286. package/out/recipes/po/box/cedex/phrases.js.map +1 -0
  287. package/out/recipes/po/box/cedex/recipe.d.ts +9 -0
  288. package/out/recipes/po/box/cedex/recipe.d.ts.map +1 -0
  289. package/out/recipes/po/box/cedex/recipe.js +153 -0
  290. package/out/recipes/po/box/cedex/recipe.js.map +1 -0
  291. package/out/recipes/po/box/cedex/sources.d.ts +86 -0
  292. package/out/recipes/po/box/cedex/sources.d.ts.map +1 -0
  293. package/out/recipes/po/box/cedex/sources.js +143 -0
  294. package/out/recipes/po/box/cedex/sources.js.map +1 -0
  295. package/out/recipes/po/box/cedex/types.d.ts +31 -0
  296. package/out/recipes/po/box/cedex/types.d.ts.map +1 -0
  297. package/out/recipes/po/box/cedex/types.js +5 -0
  298. package/out/recipes/po/box/cedex/types.js.map +1 -0
  299. package/out/recipes/po/box/cedex/us.d.ts +7 -0
  300. package/out/recipes/po/box/cedex/us.d.ts.map +1 -0
  301. package/out/recipes/po/box/cedex/us.js +51 -0
  302. package/out/recipes/po/box/cedex/us.js.map +1 -0
  303. package/out/recipes/po/box/cedex/vocabulary.d.ts +68 -0
  304. package/out/recipes/po/box/cedex/vocabulary.d.ts.map +1 -0
  305. package/out/recipes/po/box/cedex/vocabulary.js +90 -0
  306. package/out/recipes/po/box/cedex/vocabulary.js.map +1 -0
  307. package/out/recipes/po/box/cedex.d.ts +9 -0
  308. package/out/recipes/po/box/cedex.d.ts.map +1 -0
  309. package/out/recipes/po/box/cedex.js +9 -0
  310. package/out/recipes/po/box/cedex.js.map +1 -0
  311. package/out/recipes/po/box/index.d.ts +17 -0
  312. package/out/recipes/po/box/index.d.ts.map +1 -0
  313. package/out/recipes/po/box/index.js +105 -0
  314. package/out/recipes/po/box/index.js.map +1 -0
  315. package/out/recipes/scaffold.d.ts +20 -0
  316. package/out/recipes/scaffold.d.ts.map +1 -1
  317. package/out/recipes/scaffold.js +18 -37
  318. package/out/recipes/scaffold.js.map +1 -1
  319. package/out/recipes/street/affix.d.ts +89 -0
  320. package/out/recipes/street/affix.d.ts.map +1 -0
  321. package/out/recipes/street/affix.js +565 -0
  322. package/out/recipes/street/affix.js.map +1 -0
  323. package/out/recipes/street/bare.d.ts +25 -0
  324. package/out/recipes/street/bare.d.ts.map +1 -0
  325. package/out/recipes/street/bare.js +87 -0
  326. package/out/recipes/street/bare.js.map +1 -0
  327. package/out/recipes/sub/venue/context.d.ts +29 -0
  328. package/out/recipes/sub/venue/context.d.ts.map +1 -0
  329. package/out/recipes/sub/venue/context.js +106 -0
  330. package/out/recipes/sub/venue/context.js.map +1 -0
  331. package/out/recipes/sub/venue/index.d.ts +270 -0
  332. package/out/recipes/sub/venue/index.d.ts.map +1 -0
  333. package/out/recipes/sub/venue/index.js +728 -0
  334. package/out/recipes/sub/venue/index.js.map +1 -0
  335. package/out/recipes/sub/venue/sources.d.ts +209 -0
  336. package/out/recipes/sub/venue/sources.d.ts.map +1 -0
  337. package/out/recipes/sub/venue/sources.js +555 -0
  338. package/out/recipes/sub/venue/sources.js.map +1 -0
  339. package/out/recipes/trailing-region.d.ts.map +1 -1
  340. package/out/recipes/trailing-region.js +6 -1
  341. package/out/recipes/trailing-region.js.map +1 -1
  342. package/out/recipes/unit.js.map +1 -1
  343. package/out/sg/recipes/register.d.ts +69 -0
  344. package/out/sg/recipes/register.d.ts.map +1 -0
  345. package/out/sg/recipes/register.js +211 -0
  346. package/out/sg/recipes/register.js.map +1 -0
  347. package/out/sg/tools/fetch/acra.d.ts +23 -0
  348. package/out/sg/tools/fetch/acra.d.ts.map +1 -0
  349. package/out/sg/tools/fetch/acra.js +126 -0
  350. package/out/sg/tools/fetch/acra.js.map +1 -0
  351. package/out/si/recipes/bare-village.d.ts +32 -0
  352. package/out/si/recipes/bare-village.d.ts.map +1 -0
  353. package/out/si/recipes/bare-village.js +89 -0
  354. package/out/si/recipes/bare-village.js.map +1 -0
  355. package/out/south-asia/recipes/register.d.ts +51 -0
  356. package/out/south-asia/recipes/register.d.ts.map +1 -0
  357. package/out/south-asia/recipes/register.js +154 -0
  358. package/out/south-asia/recipes/register.js.map +1 -0
  359. package/out/synthesizers/anchor-absorption.d.ts +1 -1
  360. package/out/synthesizers/anchor-absorption.d.ts.map +1 -1
  361. package/out/synthesizers/anchor-absorption.js.map +1 -1
  362. package/out/synthesizers/boundary-stress.js.map +1 -1
  363. package/out/synthesizers/house-venue.js.map +1 -1
  364. package/out/synthesizers/intersection.js.map +1 -1
  365. package/out/synthesizers/locale.d.ts +116 -0
  366. package/out/synthesizers/locale.d.ts.map +1 -0
  367. package/out/synthesizers/locale.js +150 -0
  368. package/out/synthesizers/locale.js.map +1 -0
  369. package/out/synthesizers/no-street.d.ts.map +1 -1
  370. package/out/synthesizers/no-street.js.map +1 -1
  371. package/out/synthesizers/po-box.js.map +1 -1
  372. package/out/synthesizers/street.d.ts.map +1 -1
  373. package/out/synthesizers/street.js +1 -1
  374. package/out/synthesizers/street.js.map +1 -1
  375. package/out/synthesizers/utils.js +1 -1
  376. package/out/synthesizers/utils.js.map +1 -1
  377. package/out/test-kit/corpus-recipe.d.ts.map +1 -1
  378. package/out/test-kit/corpus-recipe.js.map +1 -1
  379. package/out/tools/audit.d.ts.map +1 -1
  380. package/out/tools/audit.js +3 -2
  381. package/out/tools/audit.js.map +1 -1
  382. package/out/tools/corpus-stats.js +3 -3
  383. package/out/tools/corpus-stats.js.map +1 -1
  384. package/out/tools/fetch/download/index.d.ts +10 -0
  385. package/out/tools/fetch/download/index.d.ts.map +1 -0
  386. package/out/tools/fetch/download/index.js +10 -0
  387. package/out/tools/fetch/download/index.js.map +1 -0
  388. package/out/tools/fetch/download/manifest.d.ts +47 -0
  389. package/out/tools/fetch/download/manifest.d.ts.map +1 -0
  390. package/out/tools/fetch/download/manifest.js +74 -0
  391. package/out/tools/fetch/download/manifest.js.map +1 -0
  392. package/out/tools/fetch/download/network.d.ts +105 -0
  393. package/out/tools/fetch/download/network.d.ts.map +1 -0
  394. package/out/tools/fetch/download/network.js +130 -0
  395. package/out/tools/fetch/download/network.js.map +1 -0
  396. package/out/tools/fetch/download/retry.d.ts +45 -0
  397. package/out/tools/fetch/download/retry.d.ts.map +1 -0
  398. package/out/tools/fetch/download/retry.js +136 -0
  399. package/out/tools/fetch/download/retry.js.map +1 -0
  400. package/out/tools/fetch/geonames/dump.d.ts +91 -0
  401. package/out/tools/fetch/geonames/dump.d.ts.map +1 -0
  402. package/out/tools/fetch/geonames/dump.js +171 -0
  403. package/out/tools/fetch/geonames/dump.js.map +1 -0
  404. package/out/tools/fetch/geonames/postal.d.ts +76 -0
  405. package/out/tools/fetch/geonames/postal.d.ts.map +1 -0
  406. package/out/tools/fetch/geonames/postal.js +126 -0
  407. package/out/tools/fetch/geonames/postal.js.map +1 -0
  408. package/out/tools/fetch/index.d.ts +30 -30
  409. package/out/tools/fetch/index.d.ts.map +1 -1
  410. package/out/tools/fetch/index.js +30 -30
  411. package/out/tools/fetch/index.js.map +1 -1
  412. package/out/tools/fetch/openaddresses.d.ts +1 -1
  413. package/out/tools/fetch/openaddresses.d.ts.map +1 -1
  414. package/out/tools/fetch/openaddresses.js +1 -1
  415. package/out/tools/fetch/openaddresses.js.map +1 -1
  416. package/out/tools/fetch/ourairports.d.ts +1 -1
  417. package/out/tools/fetch/ourairports.d.ts.map +1 -1
  418. package/out/tools/fetch/ourairports.js +1 -1
  419. package/out/tools/fetch/ourairports.js.map +1 -1
  420. package/out/tools/fetch/ppd.js +1 -3
  421. package/out/tools/fetch/ppd.js.map +1 -1
  422. package/out/tools/fetch/wikidata-subvenue.d.ts +1 -1
  423. package/out/tools/fetch/wikidata-subvenue.d.ts.map +1 -1
  424. package/out/tools/fetch/wikidata-subvenue.js +1 -1
  425. package/out/tools/fetch/wikidata-subvenue.js.map +1 -1
  426. package/out/tools/golden/expand.d.ts +90 -0
  427. package/out/tools/golden/expand.d.ts.map +1 -0
  428. package/out/tools/golden/expand.js +406 -0
  429. package/out/tools/golden/expand.js.map +1 -0
  430. package/out/tools/golden/promote.d.ts +72 -0
  431. package/out/tools/golden/promote.d.ts.map +1 -0
  432. package/out/tools/golden/promote.js +243 -0
  433. package/out/tools/golden/promote.js.map +1 -0
  434. package/out/tools/golden/relabel-street/directory.d.ts +83 -0
  435. package/out/tools/golden/relabel-street/directory.d.ts.map +1 -0
  436. package/out/tools/golden/relabel-street/directory.js +216 -0
  437. package/out/tools/golden/relabel-street/directory.js.map +1 -0
  438. package/out/tools/golden/relabel-street/index.d.ts +9 -0
  439. package/out/tools/golden/relabel-street/index.d.ts.map +1 -0
  440. package/out/tools/golden/relabel-street/index.js +9 -0
  441. package/out/tools/golden/relabel-street/index.js.map +1 -0
  442. package/out/tools/golden/relabel-street/row.d.ts +121 -0
  443. package/out/tools/golden/relabel-street/row.d.ts.map +1 -0
  444. package/out/tools/golden/relabel-street/row.js +232 -0
  445. package/out/tools/golden/relabel-street/row.js.map +1 -0
  446. package/out/tools/index.d.ts +10 -10
  447. package/out/tools/index.d.ts.map +1 -1
  448. package/out/tools/index.js +10 -10
  449. package/out/tools/index.js.map +1 -1
  450. package/out/tools/ingest-csv.d.ts.map +1 -1
  451. package/out/tools/ingest-csv.js +5 -7
  452. package/out/tools/ingest-csv.js.map +1 -1
  453. package/out/tools/lint/slice/index.d.ts +93 -0
  454. package/out/tools/lint/slice/index.d.ts.map +1 -0
  455. package/out/tools/lint/slice/index.js +322 -0
  456. package/out/tools/lint/slice/index.js.map +1 -0
  457. package/out/tools/lint/slice/vocab.d.ts +90 -0
  458. package/out/tools/lint/slice/vocab.d.ts.map +1 -0
  459. package/out/tools/lint/slice/vocab.js +254 -0
  460. package/out/tools/lint/slice/vocab.js.map +1 -0
  461. package/out/tools/overlay-manifest.d.ts +56 -6
  462. package/out/tools/overlay-manifest.d.ts.map +1 -1
  463. package/out/tools/overlay-manifest.js +56 -15
  464. package/out/tools/overlay-manifest.js.map +1 -1
  465. package/out/tools/overture-subvenue.d.ts +1 -1
  466. package/out/tools/postcode-triples.d.ts +36 -0
  467. package/out/tools/postcode-triples.d.ts.map +1 -1
  468. package/out/tools/postcode-triples.js +91 -12
  469. package/out/tools/postcode-triples.js.map +1 -1
  470. package/out/tools/slice/kryptonite.d.ts +32 -0
  471. package/out/tools/slice/kryptonite.d.ts.map +1 -0
  472. package/out/tools/slice/kryptonite.js +99 -0
  473. package/out/tools/slice/kryptonite.js.map +1 -0
  474. package/out/tools/slice/translit.d.ts +51 -0
  475. package/out/tools/slice/translit.d.ts.map +1 -0
  476. package/out/tools/slice/translit.js +166 -0
  477. package/out/tools/slice/translit.js.map +1 -0
  478. package/out/tools/sub/venue/harvest.d.ts +100 -0
  479. package/out/tools/sub/venue/harvest.d.ts.map +1 -0
  480. package/out/tools/sub/venue/harvest.js +168 -0
  481. package/out/tools/sub/venue/harvest.js.map +1 -0
  482. package/out/tools/sub/venue/head-nouns.d.ts +50 -0
  483. package/out/tools/sub/venue/head-nouns.d.ts.map +1 -0
  484. package/out/tools/sub/venue/head-nouns.js.map +1 -0
  485. package/out/tools/sub/venue/lexicon.d.ts +156 -0
  486. package/out/tools/sub/venue/lexicon.d.ts.map +1 -0
  487. package/out/tools/sub/venue/lexicon.js +283 -0
  488. package/out/tools/sub/venue/lexicon.js.map +1 -0
  489. package/out/tools/sub/venue/promotions.d.ts +94 -0
  490. package/out/tools/sub/venue/promotions.d.ts.map +1 -0
  491. package/out/tools/sub/venue/promotions.js +266 -0
  492. package/out/tools/sub/venue/promotions.js.map +1 -0
  493. package/out/tools/sub/venue/surfaces.d.ts +45 -0
  494. package/out/tools/sub/venue/surfaces.d.ts.map +1 -0
  495. package/out/tools/sub/venue/surfaces.js.map +1 -0
  496. package/out/tools/sub/venue/table.d.ts +229 -0
  497. package/out/tools/sub/venue/table.d.ts.map +1 -0
  498. package/out/tools/sub/venue/table.js.map +1 -0
  499. package/out/tools/sub/venue/wikidata.d.ts +26 -0
  500. package/out/tools/sub/venue/wikidata.d.ts.map +1 -0
  501. package/out/tools/sub/venue/wikidata.js +62 -0
  502. package/out/tools/sub/venue/wikidata.js.map +1 -0
  503. package/out/tw/tools/fetch/gcis.d.ts +23 -0
  504. package/out/tw/tools/fetch/gcis.d.ts.map +1 -0
  505. package/out/tw/tools/fetch/gcis.js +135 -0
  506. package/out/tw/tools/fetch/gcis.js.map +1 -0
  507. package/out/types.d.ts +1 -1
  508. package/out/types.d.ts.map +1 -1
  509. package/out/us/adapters/fcc-bdc/adapter.d.ts.map +1 -0
  510. package/out/us/adapters/fcc-bdc/adapter.js +142 -0
  511. package/out/us/adapters/fcc-bdc/adapter.js.map +1 -0
  512. package/out/us/adapters/state/hi-schools/adapter.d.ts.map +1 -0
  513. package/out/us/adapters/state/hi-schools/adapter.js +136 -0
  514. package/out/us/adapters/state/hi-schools/adapter.js.map +1 -0
  515. package/out/us/adapters/state/hi-schools/workbook.d.ts.map +1 -0
  516. package/out/us/adapters/state/hi-schools/workbook.js.map +1 -0
  517. package/out/us/adapters/state/ia-contractors/adapter.d.ts.map +1 -0
  518. package/out/us/adapters/state/ia-contractors/adapter.js +104 -0
  519. package/out/us/adapters/state/ia-contractors/adapter.js.map +1 -0
  520. package/out/us/adapters/state/ny-notaries/adapter.d.ts.map +1 -0
  521. package/out/us/adapters/state/ny-notaries/adapter.js +112 -0
  522. package/out/us/adapters/state/ny-notaries/adapter.js.map +1 -0
  523. package/out/us/adapters/state/tx-notaries/adapter.d.ts.map +1 -0
  524. package/out/us/adapters/state/tx-notaries/adapter.js +118 -0
  525. package/out/us/adapters/state/tx-notaries/adapter.js.map +1 -0
  526. package/out/us/adapters/tiger/adapter.d.ts +55 -0
  527. package/out/us/adapters/tiger/adapter.d.ts.map +1 -0
  528. package/out/us/adapters/tiger/adapter.js +197 -0
  529. package/out/us/adapters/tiger/adapter.js.map +1 -0
  530. package/out/us/adapters/tiger/street-decompose.d.ts.map +1 -0
  531. package/out/us/adapters/tiger/street-decompose.js.map +1 -0
  532. package/out/us/adapters/usgov/hrsa-fqhc/adapter.d.ts.map +1 -0
  533. package/out/us/adapters/usgov/hrsa-fqhc/adapter.js +121 -0
  534. package/out/us/adapters/usgov/hrsa-fqhc/adapter.js.map +1 -0
  535. package/out/us/adapters/usgov/imls-pls/adapter.d.ts.map +1 -0
  536. package/out/us/adapters/usgov/imls-pls/adapter.js +106 -0
  537. package/out/us/adapters/usgov/imls-pls/adapter.js.map +1 -0
  538. package/out/us/adapters/usgov/irs-bmf/adapter.d.ts.map +1 -0
  539. package/out/us/adapters/usgov/irs-bmf/adapter.js +116 -0
  540. package/out/us/adapters/usgov/irs-bmf/adapter.js.map +1 -0
  541. package/out/us/adapters/usgov/nad/adapter.d.ts.map +1 -0
  542. package/out/us/adapters/usgov/nad/adapter.js +239 -0
  543. package/out/us/adapters/usgov/nad/adapter.js.map +1 -0
  544. package/out/us/adapters/usgov/nppes/adapter.d.ts.map +1 -0
  545. package/out/us/adapters/usgov/nppes/adapter.js +110 -0
  546. package/out/us/adapters/usgov/nppes/adapter.js.map +1 -0
  547. package/out/us/adapters/usgov/samhsa-treatment-locator/adapter.d.ts.map +1 -0
  548. package/out/us/adapters/usgov/samhsa-treatment-locator/adapter.js +143 -0
  549. package/out/us/adapters/usgov/samhsa-treatment-locator/adapter.js.map +1 -0
  550. package/out/us/fips-state.d.ts +41 -0
  551. package/out/us/fips-state.d.ts.map +1 -0
  552. package/out/us/fips-state.js +100 -0
  553. package/out/us/fips-state.js.map +1 -0
  554. package/out/us/tools/fetch/hrsa.d.ts +18 -0
  555. package/out/us/tools/fetch/hrsa.d.ts.map +1 -0
  556. package/out/us/tools/fetch/hrsa.js +46 -0
  557. package/out/us/tools/fetch/hrsa.js.map +1 -0
  558. package/out/us/tools/fetch/imls-pls.d.ts +25 -0
  559. package/out/us/tools/fetch/imls-pls.d.ts.map +1 -0
  560. package/out/us/tools/fetch/imls-pls.js +108 -0
  561. package/out/us/tools/fetch/imls-pls.js.map +1 -0
  562. package/out/us/tools/fetch/nad.d.ts +70 -0
  563. package/out/us/tools/fetch/nad.d.ts.map +1 -0
  564. package/out/us/tools/fetch/nad.js +234 -0
  565. package/out/us/tools/fetch/nad.js.map +1 -0
  566. package/out/us/tools/fetch/nppes.d.ts +26 -0
  567. package/out/us/tools/fetch/nppes.d.ts.map +1 -0
  568. package/out/us/tools/fetch/nppes.js +126 -0
  569. package/out/us/tools/fetch/nppes.js.map +1 -0
  570. package/out/us/tools/fetch/state/hi-schools.d.ts +26 -0
  571. package/out/us/tools/fetch/state/hi-schools.d.ts.map +1 -0
  572. package/out/us/tools/fetch/state/hi-schools.js +112 -0
  573. package/out/us/tools/fetch/state/hi-schools.js.map +1 -0
  574. package/out/us/tools/fetch/state/sources.d.ts +26 -0
  575. package/out/us/tools/fetch/state/sources.d.ts.map +1 -0
  576. package/out/us/tools/fetch/state/sources.js +111 -0
  577. package/out/us/tools/fetch/state/sources.js.map +1 -0
  578. package/out/us/tools/fetch/tiger-full.d.ts +22 -0
  579. package/out/us/tools/fetch/tiger-full.d.ts.map +1 -0
  580. package/out/us/tools/fetch/tiger-full.js +217 -0
  581. package/out/us/tools/fetch/tiger-full.js.map +1 -0
  582. package/out/utils/align.d.ts +1 -1
  583. package/out/utils/align.d.ts.map +1 -1
  584. package/out/utils/align.js.map +1 -1
  585. package/out/utils/golden.d.ts +7 -3
  586. package/out/utils/golden.d.ts.map +1 -1
  587. package/out/utils/golden.js +12 -8
  588. package/out/utils/golden.js.map +1 -1
  589. package/out/utils/parquet.d.ts.map +1 -1
  590. package/out/utils/split.js.map +1 -1
  591. package/out/utils/wof-json.d.ts.map +1 -1
  592. package/out/utils/wof-json.js +7 -12
  593. package/out/utils/wof-json.js.map +1 -1
  594. package/out/ve/recipes/reviewed-postcode-tail.d.ts.map +1 -0
  595. package/out/ve/recipes/reviewed-postcode-tail.js.map +1 -0
  596. package/package.json +196 -46
  597. package/lib/adapters/ban/adapter.ts +0 -190
  598. package/lib/adapters/fcc-bdc/adapter.ts +0 -174
  599. package/lib/adapters/geonames-postal/adapter.ts +0 -122
  600. package/lib/adapters/gnaf/adapter.ts +0 -149
  601. package/lib/adapters/gnaf/assemble.ts +0 -225
  602. package/lib/adapters/state-hi-schools/adapter.ts +0 -170
  603. package/lib/adapters/state-ia-contractors/adapter.ts +0 -144
  604. package/lib/adapters/state-ny-notaries/adapter.ts +0 -141
  605. package/lib/adapters/state-tx-notaries/adapter.ts +0 -157
  606. package/lib/adapters/tiger/adapter.ts +0 -252
  607. package/lib/adapters/usgov-hrsa-fqhc/adapter.ts +0 -167
  608. package/lib/adapters/usgov-imls-pls/adapter.ts +0 -143
  609. package/lib/adapters/usgov-irs-bmf/adapter.ts +0 -151
  610. package/lib/adapters/usgov-nad/adapter.ts +0 -334
  611. package/lib/adapters/usgov-nppes/adapter.ts +0 -151
  612. package/lib/adapters/usgov-samhsa-treatment-locator/adapter.ts +0 -193
  613. package/lib/adapters/wof-admin-json/adapter.ts +0 -231
  614. package/lib/adapters/wof-json-rows.ts +0 -129
  615. package/lib/adapters/wof-postalcode-json/adapter.ts +0 -176
  616. package/lib/recipes/fr-admin-split.ts +0 -243
  617. package/lib/recipes/fr-bare-street.ts +0 -171
  618. package/lib/recipes/fr-fragment.ts +0 -334
  619. package/lib/recipes/fr-lieudit.ts +0 -301
  620. package/lib/recipes/fr-order.ts +0 -246
  621. package/lib/recipes/german.ts +0 -360
  622. package/lib/recipes/locale.ts +0 -600
  623. package/lib/recipes/po-box-cedex.ts +0 -976
  624. package/lib/recipes/po-box.ts +0 -124
  625. package/lib/recipes/street-affix.ts +0 -805
  626. package/lib/recipes/sub-venue-sources.ts +0 -878
  627. package/lib/recipes/sub-venue.ts +0 -998
  628. package/lib/synthesizers/german.ts +0 -260
  629. package/lib/tools/fetch/acra-sg.ts +0 -174
  630. package/lib/tools/fetch/ban.ts +0 -289
  631. package/lib/tools/fetch/download.ts +0 -477
  632. package/lib/tools/fetch/gcis-tw.ts +0 -175
  633. package/lib/tools/fetch/geonames-dump.ts +0 -257
  634. package/lib/tools/fetch/geonames-postal.ts +0 -180
  635. package/lib/tools/fetch/houjin-jp.ts +0 -135
  636. package/lib/tools/fetch/hrsa.ts +0 -59
  637. package/lib/tools/fetch/imls-pls.ts +0 -149
  638. package/lib/tools/fetch/juso-kr.ts +0 -165
  639. package/lib/tools/fetch/localdata-kr.ts +0 -194
  640. package/lib/tools/fetch/nad.ts +0 -341
  641. package/lib/tools/fetch/nppes.ts +0 -165
  642. package/lib/tools/fetch/state-hi-schools.ts +0 -161
  643. package/lib/tools/fetch/state-sources.ts +0 -146
  644. package/lib/tools/fetch/tiger-full.ts +0 -308
  645. package/lib/tools/golden-promote.ts +0 -337
  646. package/lib/tools/golden-relabel-street.ts +0 -686
  647. package/lib/tools/lint-slice-vocab.ts +0 -388
  648. package/lib/tools/sub-venue/harvest.ts +0 -234
  649. package/lib/tools/sub-venue/head-nouns.ts +0 -245
  650. package/lib/tools/sub-venue/surfaces.ts +0 -95
  651. package/lib/tools/sub-venue/table.ts +0 -281
  652. package/lib/tools/sub-venue/wikidata.ts +0 -85
  653. package/lib/tools/sub-venue-lexicon.ts +0 -429
  654. package/out/adapters/ban/adapter.d.ts.map +0 -1
  655. package/out/adapters/ban/adapter.js +0 -149
  656. package/out/adapters/ban/adapter.js.map +0 -1
  657. package/out/adapters/ban/street-decompose.d.ts.map +0 -1
  658. package/out/adapters/ban/street-decompose.js.map +0 -1
  659. package/out/adapters/fcc-bdc/adapter.d.ts.map +0 -1
  660. package/out/adapters/fcc-bdc/adapter.js +0 -144
  661. package/out/adapters/fcc-bdc/adapter.js.map +0 -1
  662. package/out/adapters/geonames-postal/adapter.d.ts.map +0 -1
  663. package/out/adapters/geonames-postal/adapter.js +0 -107
  664. package/out/adapters/geonames-postal/adapter.js.map +0 -1
  665. package/out/adapters/gnaf/adapter.d.ts.map +0 -1
  666. package/out/adapters/gnaf/adapter.js +0 -124
  667. package/out/adapters/gnaf/adapter.js.map +0 -1
  668. package/out/adapters/gnaf/assemble.d.ts +0 -65
  669. package/out/adapters/gnaf/assemble.d.ts.map +0 -1
  670. package/out/adapters/gnaf/assemble.js +0 -154
  671. package/out/adapters/gnaf/assemble.js.map +0 -1
  672. package/out/adapters/state-hi-schools/adapter.d.ts.map +0 -1
  673. package/out/adapters/state-hi-schools/adapter.js +0 -145
  674. package/out/adapters/state-hi-schools/adapter.js.map +0 -1
  675. package/out/adapters/state-hi-schools/workbook.d.ts.map +0 -1
  676. package/out/adapters/state-hi-schools/workbook.js.map +0 -1
  677. package/out/adapters/state-ia-contractors/adapter.d.ts.map +0 -1
  678. package/out/adapters/state-ia-contractors/adapter.js +0 -111
  679. package/out/adapters/state-ia-contractors/adapter.js.map +0 -1
  680. package/out/adapters/state-ny-notaries/adapter.d.ts.map +0 -1
  681. package/out/adapters/state-ny-notaries/adapter.js +0 -119
  682. package/out/adapters/state-ny-notaries/adapter.js.map +0 -1
  683. package/out/adapters/state-tx-notaries/adapter.d.ts.map +0 -1
  684. package/out/adapters/state-tx-notaries/adapter.js +0 -125
  685. package/out/adapters/state-tx-notaries/adapter.js.map +0 -1
  686. package/out/adapters/tiger/adapter.d.ts +0 -55
  687. package/out/adapters/tiger/adapter.d.ts.map +0 -1
  688. package/out/adapters/tiger/adapter.js +0 -201
  689. package/out/adapters/tiger/adapter.js.map +0 -1
  690. package/out/adapters/tiger/street-decompose.d.ts.map +0 -1
  691. package/out/adapters/tiger/street-decompose.js.map +0 -1
  692. package/out/adapters/usgov-hrsa-fqhc/adapter.d.ts.map +0 -1
  693. package/out/adapters/usgov-hrsa-fqhc/adapter.js +0 -132
  694. package/out/adapters/usgov-hrsa-fqhc/adapter.js.map +0 -1
  695. package/out/adapters/usgov-imls-pls/adapter.d.ts.map +0 -1
  696. package/out/adapters/usgov-imls-pls/adapter.js +0 -114
  697. package/out/adapters/usgov-imls-pls/adapter.js.map +0 -1
  698. package/out/adapters/usgov-irs-bmf/adapter.d.ts.map +0 -1
  699. package/out/adapters/usgov-irs-bmf/adapter.js +0 -120
  700. package/out/adapters/usgov-irs-bmf/adapter.js.map +0 -1
  701. package/out/adapters/usgov-nad/adapter.d.ts.map +0 -1
  702. package/out/adapters/usgov-nad/adapter.js +0 -249
  703. package/out/adapters/usgov-nad/adapter.js.map +0 -1
  704. package/out/adapters/usgov-nppes/adapter.d.ts.map +0 -1
  705. package/out/adapters/usgov-nppes/adapter.js +0 -118
  706. package/out/adapters/usgov-nppes/adapter.js.map +0 -1
  707. package/out/adapters/usgov-samhsa-treatment-locator/adapter.d.ts.map +0 -1
  708. package/out/adapters/usgov-samhsa-treatment-locator/adapter.js +0 -154
  709. package/out/adapters/usgov-samhsa-treatment-locator/adapter.js.map +0 -1
  710. package/out/adapters/wof-admin-jp/adapter.d.ts.map +0 -1
  711. package/out/adapters/wof-admin-jp/adapter.js.map +0 -1
  712. package/out/adapters/wof-admin-json/adapter.d.ts +0 -79
  713. package/out/adapters/wof-admin-json/adapter.d.ts.map +0 -1
  714. package/out/adapters/wof-admin-json/adapter.js +0 -197
  715. package/out/adapters/wof-admin-json/adapter.js.map +0 -1
  716. package/out/adapters/wof-json-rows.d.ts +0 -62
  717. package/out/adapters/wof-json-rows.d.ts.map +0 -1
  718. package/out/adapters/wof-json-rows.js +0 -83
  719. package/out/adapters/wof-json-rows.js.map +0 -1
  720. package/out/adapters/wof-postalcode-json/adapter.d.ts +0 -65
  721. package/out/adapters/wof-postalcode-json/adapter.d.ts.map +0 -1
  722. package/out/adapters/wof-postalcode-json/adapter.js +0 -151
  723. package/out/adapters/wof-postalcode-json/adapter.js.map +0 -1
  724. package/out/codex/us-fips-state.d.ts +0 -41
  725. package/out/codex/us-fips-state.d.ts.map +0 -1
  726. package/out/codex/us-fips-state.js +0 -100
  727. package/out/codex/us-fips-state.js.map +0 -1
  728. package/out/recipes/bare-country.d.ts +0 -25
  729. package/out/recipes/bare-country.d.ts.map +0 -1
  730. package/out/recipes/bare-country.js +0 -88
  731. package/out/recipes/bare-country.js.map +0 -1
  732. package/out/recipes/cn-organizational-units.d.ts +0 -36
  733. package/out/recipes/cn-organizational-units.d.ts.map +0 -1
  734. package/out/recipes/cn-organizational-units.js +0 -159
  735. package/out/recipes/cn-organizational-units.js.map +0 -1
  736. package/out/recipes/cz-pcfirst-preposition.d.ts +0 -22
  737. package/out/recipes/cz-pcfirst-preposition.d.ts.map +0 -1
  738. package/out/recipes/cz-pcfirst-preposition.js +0 -101
  739. package/out/recipes/cz-pcfirst-preposition.js.map +0 -1
  740. package/out/recipes/fr-admin-split.d.ts +0 -38
  741. package/out/recipes/fr-admin-split.d.ts.map +0 -1
  742. package/out/recipes/fr-admin-split.js +0 -192
  743. package/out/recipes/fr-admin-split.js.map +0 -1
  744. package/out/recipes/fr-bare-street.d.ts +0 -28
  745. package/out/recipes/fr-bare-street.d.ts.map +0 -1
  746. package/out/recipes/fr-bare-street.js +0 -144
  747. package/out/recipes/fr-bare-street.js.map +0 -1
  748. package/out/recipes/fr-fragment.d.ts +0 -77
  749. package/out/recipes/fr-fragment.d.ts.map +0 -1
  750. package/out/recipes/fr-fragment.js +0 -277
  751. package/out/recipes/fr-fragment.js.map +0 -1
  752. package/out/recipes/fr-lieudit.d.ts +0 -32
  753. package/out/recipes/fr-lieudit.d.ts.map +0 -1
  754. package/out/recipes/fr-lieudit.js +0 -227
  755. package/out/recipes/fr-lieudit.js.map +0 -1
  756. package/out/recipes/fr-order.d.ts +0 -38
  757. package/out/recipes/fr-order.d.ts.map +0 -1
  758. package/out/recipes/fr-order.js +0 -198
  759. package/out/recipes/fr-order.js.map +0 -1
  760. package/out/recipes/german.d.ts +0 -44
  761. package/out/recipes/german.d.ts.map +0 -1
  762. package/out/recipes/german.js +0 -289
  763. package/out/recipes/german.js.map +0 -1
  764. package/out/recipes/locale.d.ts +0 -136
  765. package/out/recipes/locale.d.ts.map +0 -1
  766. package/out/recipes/locale.js +0 -460
  767. package/out/recipes/locale.js.map +0 -1
  768. package/out/recipes/nl-postcode.d.ts +0 -26
  769. package/out/recipes/nl-postcode.d.ts.map +0 -1
  770. package/out/recipes/nl-postcode.js +0 -103
  771. package/out/recipes/nl-postcode.js.map +0 -1
  772. package/out/recipes/no-fragment.d.ts +0 -43
  773. package/out/recipes/no-fragment.d.ts.map +0 -1
  774. package/out/recipes/no-fragment.js +0 -183
  775. package/out/recipes/no-fragment.js.map +0 -1
  776. package/out/recipes/no-street-led.d.ts +0 -24
  777. package/out/recipes/no-street-led.d.ts.map +0 -1
  778. package/out/recipes/no-street-led.js +0 -114
  779. package/out/recipes/no-street-led.js.map +0 -1
  780. package/out/recipes/no-street.d.ts +0 -18
  781. package/out/recipes/no-street.d.ts.map +0 -1
  782. package/out/recipes/no-street.js +0 -72
  783. package/out/recipes/no-street.js.map +0 -1
  784. package/out/recipes/po-box-cedex.d.ts +0 -38
  785. package/out/recipes/po-box-cedex.d.ts.map +0 -1
  786. package/out/recipes/po-box-cedex.js +0 -768
  787. package/out/recipes/po-box-cedex.js.map +0 -1
  788. package/out/recipes/po-box.d.ts +0 -17
  789. package/out/recipes/po-box.d.ts.map +0 -1
  790. package/out/recipes/po-box.js +0 -101
  791. package/out/recipes/po-box.js.map +0 -1
  792. package/out/recipes/reviewed-postcode-tail.d.ts.map +0 -1
  793. package/out/recipes/reviewed-postcode-tail.js.map +0 -1
  794. package/out/recipes/si-bare-village.d.ts +0 -32
  795. package/out/recipes/si-bare-village.d.ts.map +0 -1
  796. package/out/recipes/si-bare-village.js +0 -89
  797. package/out/recipes/si-bare-village.js.map +0 -1
  798. package/out/recipes/street-affix.d.ts +0 -89
  799. package/out/recipes/street-affix.d.ts.map +0 -1
  800. package/out/recipes/street-affix.js +0 -563
  801. package/out/recipes/street-affix.js.map +0 -1
  802. package/out/recipes/street-bare.d.ts +0 -25
  803. package/out/recipes/street-bare.d.ts.map +0 -1
  804. package/out/recipes/street-bare.js +0 -87
  805. package/out/recipes/street-bare.js.map +0 -1
  806. package/out/recipes/sub-venue-sources.d.ts +0 -229
  807. package/out/recipes/sub-venue-sources.d.ts.map +0 -1
  808. package/out/recipes/sub-venue-sources.js +0 -654
  809. package/out/recipes/sub-venue-sources.js.map +0 -1
  810. package/out/recipes/sub-venue.d.ts +0 -269
  811. package/out/recipes/sub-venue.d.ts.map +0 -1
  812. package/out/recipes/sub-venue.js +0 -726
  813. package/out/recipes/sub-venue.js.map +0 -1
  814. package/out/synthesizers/german.d.ts +0 -115
  815. package/out/synthesizers/german.d.ts.map +0 -1
  816. package/out/synthesizers/german.js +0 -149
  817. package/out/synthesizers/german.js.map +0 -1
  818. package/out/tools/fetch/acra-sg.d.ts +0 -23
  819. package/out/tools/fetch/acra-sg.d.ts.map +0 -1
  820. package/out/tools/fetch/acra-sg.js +0 -126
  821. package/out/tools/fetch/acra-sg.js.map +0 -1
  822. package/out/tools/fetch/ban.d.ts +0 -31
  823. package/out/tools/fetch/ban.d.ts.map +0 -1
  824. package/out/tools/fetch/ban.js +0 -239
  825. package/out/tools/fetch/ban.js.map +0 -1
  826. package/out/tools/fetch/download.d.ts +0 -182
  827. package/out/tools/fetch/download.d.ts.map +0 -1
  828. package/out/tools/fetch/download.js +0 -318
  829. package/out/tools/fetch/download.js.map +0 -1
  830. package/out/tools/fetch/gcis-tw.d.ts +0 -23
  831. package/out/tools/fetch/gcis-tw.d.ts.map +0 -1
  832. package/out/tools/fetch/gcis-tw.js +0 -135
  833. package/out/tools/fetch/gcis-tw.js.map +0 -1
  834. package/out/tools/fetch/geonames-dump.d.ts +0 -91
  835. package/out/tools/fetch/geonames-dump.d.ts.map +0 -1
  836. package/out/tools/fetch/geonames-dump.js +0 -171
  837. package/out/tools/fetch/geonames-dump.js.map +0 -1
  838. package/out/tools/fetch/geonames-postal.d.ts +0 -76
  839. package/out/tools/fetch/geonames-postal.d.ts.map +0 -1
  840. package/out/tools/fetch/geonames-postal.js +0 -126
  841. package/out/tools/fetch/geonames-postal.js.map +0 -1
  842. package/out/tools/fetch/houjin-jp.d.ts +0 -24
  843. package/out/tools/fetch/houjin-jp.d.ts.map +0 -1
  844. package/out/tools/fetch/houjin-jp.js +0 -102
  845. package/out/tools/fetch/houjin-jp.js.map +0 -1
  846. package/out/tools/fetch/hrsa.d.ts +0 -18
  847. package/out/tools/fetch/hrsa.d.ts.map +0 -1
  848. package/out/tools/fetch/hrsa.js +0 -46
  849. package/out/tools/fetch/hrsa.js.map +0 -1
  850. package/out/tools/fetch/imls-pls.d.ts +0 -25
  851. package/out/tools/fetch/imls-pls.d.ts.map +0 -1
  852. package/out/tools/fetch/imls-pls.js +0 -108
  853. package/out/tools/fetch/imls-pls.js.map +0 -1
  854. package/out/tools/fetch/juso-kr.d.ts +0 -30
  855. package/out/tools/fetch/juso-kr.d.ts.map +0 -1
  856. package/out/tools/fetch/juso-kr.js +0 -120
  857. package/out/tools/fetch/juso-kr.js.map +0 -1
  858. package/out/tools/fetch/localdata-kr.d.ts +0 -30
  859. package/out/tools/fetch/localdata-kr.d.ts.map +0 -1
  860. package/out/tools/fetch/localdata-kr.js +0 -139
  861. package/out/tools/fetch/localdata-kr.js.map +0 -1
  862. package/out/tools/fetch/nad.d.ts +0 -70
  863. package/out/tools/fetch/nad.d.ts.map +0 -1
  864. package/out/tools/fetch/nad.js +0 -234
  865. package/out/tools/fetch/nad.js.map +0 -1
  866. package/out/tools/fetch/nppes.d.ts +0 -26
  867. package/out/tools/fetch/nppes.d.ts.map +0 -1
  868. package/out/tools/fetch/nppes.js +0 -126
  869. package/out/tools/fetch/nppes.js.map +0 -1
  870. package/out/tools/fetch/state-hi-schools.d.ts +0 -26
  871. package/out/tools/fetch/state-hi-schools.d.ts.map +0 -1
  872. package/out/tools/fetch/state-hi-schools.js +0 -112
  873. package/out/tools/fetch/state-hi-schools.js.map +0 -1
  874. package/out/tools/fetch/state-sources.d.ts +0 -26
  875. package/out/tools/fetch/state-sources.d.ts.map +0 -1
  876. package/out/tools/fetch/state-sources.js +0 -111
  877. package/out/tools/fetch/state-sources.js.map +0 -1
  878. package/out/tools/fetch/tiger-full.d.ts +0 -22
  879. package/out/tools/fetch/tiger-full.d.ts.map +0 -1
  880. package/out/tools/fetch/tiger-full.js +0 -217
  881. package/out/tools/fetch/tiger-full.js.map +0 -1
  882. package/out/tools/golden-expand.d.ts +0 -90
  883. package/out/tools/golden-expand.d.ts.map +0 -1
  884. package/out/tools/golden-expand.js +0 -406
  885. package/out/tools/golden-expand.js.map +0 -1
  886. package/out/tools/golden-promote.d.ts +0 -72
  887. package/out/tools/golden-promote.d.ts.map +0 -1
  888. package/out/tools/golden-promote.js +0 -240
  889. package/out/tools/golden-promote.js.map +0 -1
  890. package/out/tools/golden-relabel-street.d.ts +0 -196
  891. package/out/tools/golden-relabel-street.d.ts.map +0 -1
  892. package/out/tools/golden-relabel-street.js +0 -439
  893. package/out/tools/golden-relabel-street.js.map +0 -1
  894. package/out/tools/lint-slice-vocab.d.ts +0 -90
  895. package/out/tools/lint-slice-vocab.d.ts.map +0 -1
  896. package/out/tools/lint-slice-vocab.js +0 -267
  897. package/out/tools/lint-slice-vocab.js.map +0 -1
  898. package/out/tools/lint-slice.d.ts +0 -93
  899. package/out/tools/lint-slice.d.ts.map +0 -1
  900. package/out/tools/lint-slice.js +0 -322
  901. package/out/tools/lint-slice.js.map +0 -1
  902. package/out/tools/slice-kryptonite.d.ts +0 -32
  903. package/out/tools/slice-kryptonite.d.ts.map +0 -1
  904. package/out/tools/slice-kryptonite.js +0 -99
  905. package/out/tools/slice-kryptonite.js.map +0 -1
  906. package/out/tools/slice-translit.d.ts +0 -51
  907. package/out/tools/slice-translit.d.ts.map +0 -1
  908. package/out/tools/slice-translit.js +0 -166
  909. package/out/tools/slice-translit.js.map +0 -1
  910. package/out/tools/sub-venue/harvest.d.ts +0 -100
  911. package/out/tools/sub-venue/harvest.d.ts.map +0 -1
  912. package/out/tools/sub-venue/harvest.js +0 -168
  913. package/out/tools/sub-venue/harvest.js.map +0 -1
  914. package/out/tools/sub-venue/head-nouns.d.ts +0 -50
  915. package/out/tools/sub-venue/head-nouns.d.ts.map +0 -1
  916. package/out/tools/sub-venue/head-nouns.js.map +0 -1
  917. package/out/tools/sub-venue/surfaces.d.ts +0 -45
  918. package/out/tools/sub-venue/surfaces.d.ts.map +0 -1
  919. package/out/tools/sub-venue/surfaces.js.map +0 -1
  920. package/out/tools/sub-venue/table.d.ts +0 -229
  921. package/out/tools/sub-venue/table.d.ts.map +0 -1
  922. package/out/tools/sub-venue/table.js.map +0 -1
  923. package/out/tools/sub-venue/wikidata.d.ts +0 -26
  924. package/out/tools/sub-venue/wikidata.d.ts.map +0 -1
  925. package/out/tools/sub-venue/wikidata.js +0 -62
  926. package/out/tools/sub-venue/wikidata.js.map +0 -1
  927. package/out/tools/sub-venue-lexicon.d.ts +0 -156
  928. package/out/tools/sub-venue-lexicon.d.ts.map +0 -1
  929. package/out/tools/sub-venue-lexicon.js +0 -283
  930. package/out/tools/sub-venue-lexicon.js.map +0 -1
  931. package/out/tools/sub-venue-promotions.d.ts +0 -94
  932. package/out/tools/sub-venue-promotions.d.ts.map +0 -1
  933. package/out/tools/sub-venue-promotions.js +0 -266
  934. package/out/tools/sub-venue-promotions.js.map +0 -1
  935. /package/lib/{recipes/cn-organizational-units.ts → cn/recipes/organizational-units.ts} +0 -0
  936. /package/lib/{recipes/cz-pcfirst-preposition.ts → cz/recipes/pcfirst-preposition.ts} +0 -0
  937. /package/lib/{adapters → fr/adapters}/ban/street-decompose.ts +0 -0
  938. /package/lib/{adapters/wof-admin-jp → jp/adapters/wof-admin}/adapter.ts +0 -0
  939. /package/lib/{recipes/nl-postcode.ts → nl/recipes/postcode.ts} +0 -0
  940. /package/lib/{recipes/no-fragment.ts → no/recipes/fragment.ts} +0 -0
  941. /package/lib/{recipes/no-street.ts → no/recipes/street/index.ts} +0 -0
  942. /package/lib/{recipes/no-street-led.ts → no/recipes/street/led.ts} +0 -0
  943. /package/lib/recipes/{bare-country.ts → bare/country.ts} +0 -0
  944. /package/lib/recipes/{street-bare.ts → street/bare.ts} +0 -0
  945. /package/lib/{recipes/si-bare-village.ts → si/recipes/bare-village.ts} +0 -0
  946. /package/lib/tools/{golden-expand.ts → golden/expand.ts} +0 -0
  947. /package/lib/tools/{lint-slice.ts → lint/slice/index.ts} +0 -0
  948. /package/lib/tools/{slice-kryptonite.ts → slice/kryptonite.ts} +0 -0
  949. /package/lib/tools/{slice-translit.ts → slice/translit.ts} +0 -0
  950. /package/lib/tools/{sub-venue-promotions.ts → sub/venue/promotions.ts} +0 -0
  951. /package/lib/{adapters/state-hi-schools → us/adapters/state/hi-schools}/workbook.ts +0 -0
  952. /package/lib/{adapters → us/adapters}/tiger/street-decompose.ts +0 -0
  953. /package/lib/{codex/us-fips-state.ts → us/fips-state.ts} +0 -0
  954. /package/lib/{recipes → ve/recipes}/reviewed-postcode-tail.ts +0 -0
  955. /package/out/adapters/{geonames-postal → geonames/postal}/adapter.d.ts +0 -0
  956. /package/out/{adapters → au/adapters}/gnaf/adapter.d.ts +0 -0
  957. /package/out/{adapters → fr/adapters}/ban/adapter.d.ts +0 -0
  958. /package/out/{adapters → fr/adapters}/ban/street-decompose.d.ts +0 -0
  959. /package/out/{adapters → fr/adapters}/ban/street-decompose.js +0 -0
  960. /package/out/{adapters/wof-admin-jp → jp/adapters/wof-admin}/adapter.d.ts +0 -0
  961. /package/out/{adapters/wof-admin-jp → jp/adapters/wof-admin}/adapter.js +0 -0
  962. /package/out/tools/{sub-venue → sub/venue}/head-nouns.js +0 -0
  963. /package/out/tools/{sub-venue → sub/venue}/surfaces.js +0 -0
  964. /package/out/tools/{sub-venue → sub/venue}/table.js +0 -0
  965. /package/out/{adapters → us/adapters}/fcc-bdc/adapter.d.ts +0 -0
  966. /package/out/{adapters/state-hi-schools → us/adapters/state/hi-schools}/adapter.d.ts +0 -0
  967. /package/out/{adapters/state-hi-schools → us/adapters/state/hi-schools}/workbook.d.ts +0 -0
  968. /package/out/{adapters/state-hi-schools → us/adapters/state/hi-schools}/workbook.js +0 -0
  969. /package/out/{adapters/state-ia-contractors → us/adapters/state/ia-contractors}/adapter.d.ts +0 -0
  970. /package/out/{adapters/state-ny-notaries → us/adapters/state/ny-notaries}/adapter.d.ts +0 -0
  971. /package/out/{adapters/state-tx-notaries → us/adapters/state/tx-notaries}/adapter.d.ts +0 -0
  972. /package/out/{adapters → us/adapters}/tiger/street-decompose.d.ts +0 -0
  973. /package/out/{adapters → us/adapters}/tiger/street-decompose.js +0 -0
  974. /package/out/{adapters/usgov-hrsa-fqhc → us/adapters/usgov/hrsa-fqhc}/adapter.d.ts +0 -0
  975. /package/out/{adapters/usgov-imls-pls → us/adapters/usgov/imls-pls}/adapter.d.ts +0 -0
  976. /package/out/{adapters/usgov-irs-bmf → us/adapters/usgov/irs-bmf}/adapter.d.ts +0 -0
  977. /package/out/{adapters/usgov-nad → us/adapters/usgov/nad}/adapter.d.ts +0 -0
  978. /package/out/{adapters/usgov-nppes → us/adapters/usgov/nppes}/adapter.d.ts +0 -0
  979. /package/out/{adapters/usgov-samhsa-treatment-locator → us/adapters/usgov/samhsa-treatment-locator}/adapter.d.ts +0 -0
  980. /package/out/{recipes → ve/recipes}/reviewed-postcode-tail.d.ts +0 -0
  981. /package/out/{recipes → ve/recipes}/reviewed-postcode-tail.js +0 -0
@@ -0,0 +1,807 @@
1
+ /**
2
+ * @copyright Sister Software
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * `street-affix` slice recipe — the US street-affix coverage slice (the v0-parity `street_prefix` /
7
+ * `street_suffix` gap — both ~0% F1 in the #15 assessment, collapsed into `street`). Raises
8
+ * PREVALENCE of affix-split streets with format diversity so the model learns to split "N Main
9
+ * St" → street_prefix="N" + street="Main" + street_suffix="St", and (negative space) sharpens
10
+ * `street` itself. Ported from scripts/build-street-affix-slice.mjs.
11
+ *
12
+ * Reads REAL US OpenAddresses tuples and SPLITS the OA `street` field via the codex:
13
+ * `matchLeadingDirectional` (USPS Pub-28 C1) for the prefix, `matchTrailingSuffix` (Pub-28 C2
14
+ * street suffixes) for the suffix. OA streets nearly all carry a suffix; only ~10-20% carry a
15
+ * directional, so we INJECT a directional prefix onto a fraction of prefix-less streets to give
16
+ * `street_prefix` real signal. Each row varies surface form per affix — abbreviated ("N", "St")
17
+ * vs expanded ("North", "Street") — and varies the layout (full address / bare / street-only /
18
+ * venue-prefixed).
19
+ *
20
+ * LEAKAGE-SAFE EVAL (`--golden`): held-out eval uses the VERMONT source only (the corpus
21
+ * defaultHoldout), a different seed, and emits {raw, components} for per-locale-f1. Train uses
22
+ * every NON-Vermont US source.
23
+ *
24
+ * Multi-locale BALANCE (`--multilocale-count`, opts.multilocaleCount > 0): appends NO-affix
25
+ * native-order rows (FR/DE/IT/NL) AFTER the US affix rows, riding the same source weight, purely
26
+ * to keep the postcode-ORDER distribution multi-locale so a US-heavy affix slice doesn't dilute
27
+ * FR/DE postcode (the v0.9.8 blemish).
28
+ */
29
+
30
+ import type { ComponentTag } from "@mailwoman/codex/component"
31
+ import {
32
+ DirectionalAbbreviation,
33
+ lookupDirectional,
34
+ matchCase,
35
+ matchLeadingDirectional,
36
+ matchTrailingSuffix,
37
+ renderDirectional,
38
+ US_STREET_SUFFIX_PREFERRED_ABBR,
39
+ NAME_PRONE_US_SUFFIXES,
40
+ } from "@mailwoman/codex/us"
41
+ import { dataRootPath } from "@mailwoman/core/data-root"
42
+ import { mulberry32 as makeMulberry32 } from "@mailwoman/core/utils"
43
+ import type { PathBuilderLike } from "path-ts"
44
+
45
+ import { stableSourceID } from "#adapters/utils"
46
+ import { readCSVRecords, readOATuples, sliceSourceID, type CorpusRecipe } from "#recipes/scaffold"
47
+ import { pick } from "#synthesizers/utils"
48
+ import type { CanonicalRow } from "#types"
49
+ import { alignRow } from "#utils"
50
+
51
+ // Same OA cache as the unit slice. Train = every NON-Vermont state; eval = Vermont (the holdout).
52
+
53
+ interface USSource {
54
+ zip: PathBuilderLike
55
+ csv: string
56
+ region: string
57
+ }
58
+
59
+ const TRAIN_SOURCES: readonly USSource[] = [
60
+ { zip: dataRootPath("oa-cache", "us__ca__berkeley.zip"), csv: "us/ca/berkeley.csv", region: "CA" },
61
+ { zip: dataRootPath("oa-cache", "us__ca__marin.zip"), csv: "us/ca/marin.csv", region: "CA" },
62
+ { zip: dataRootPath("oa-cache", "us__dc__statewide.zip"), csv: "us/dc/statewide.csv", region: "DC" },
63
+ { zip: dataRootPath("oa-cache", "us__ia__statewide.zip"), csv: "us/ia/statewide.csv", region: "IA" },
64
+ { zip: dataRootPath("oa-cache", "us__il__cook.zip"), csv: "us/il/cook.csv", region: "IL" },
65
+ { zip: dataRootPath("oa-cache", "us__mt__statewide.zip"), csv: "us/mt/statewide.csv", region: "MT" },
66
+ { zip: dataRootPath("oa-cache", "us__sd__statewide.zip"), csv: "us/sd/statewide.csv", region: "SD" },
67
+ ]
68
+
69
+ const EVAL_SOURCE: USSource = {
70
+ zip: dataRootPath("oa-cache", "us__vt__statewide.zip"),
71
+ csv: "us/vt/statewide.csv",
72
+ region: "VT",
73
+ }
74
+
75
+ // Multi-locale BALANCE sources (--multilocale-count > 0). These rows carry NO affix split — they exist
76
+ // only to keep the postcode-ORDER distribution multi-locale. Native-order rendering mirrors
77
+ // build-country-slice-balanced.mjs: FR = number-street, postcode-city; DE/IT/NL = street-number,
78
+ // postcode-city. `order` drives the body.
79
+ interface BalanceSource {
80
+ zip: PathBuilderLike
81
+ csv: string
82
+ iso2: string
83
+ region: string
84
+ order: string
85
+ }
86
+
87
+ const MULTILOCALE_SOURCES: readonly BalanceSource[] = [
88
+ {
89
+ zip: dataRootPath("oa-cache", "de__sn__statewide.zip"),
90
+ csv: "de/sn/statewide.csv",
91
+ iso2: "DE",
92
+ region: "",
93
+ order: "eu",
94
+ },
95
+ {
96
+ zip: dataRootPath("oa-cache", "fr__countrywide.zip"),
97
+ csv: "fr/countrywide.csv",
98
+ iso2: "FR",
99
+ region: "",
100
+ order: "fr",
101
+ },
102
+ {
103
+ zip: dataRootPath("oa-cache", "it__countrywide.zip"),
104
+ csv: "it/countrywide.csv",
105
+ iso2: "IT",
106
+ region: "",
107
+ order: "eu",
108
+ },
109
+ {
110
+ zip: dataRootPath("oa-cache", "nl__countrywide.zip"),
111
+ csv: "nl/countrywide.csv",
112
+ iso2: "NL",
113
+ region: "",
114
+ order: "eu",
115
+ },
116
+ ]
117
+
118
+ const MULTILOCALE_EVAL_SOURCES: readonly BalanceSource[] = [
119
+ { zip: dataRootPath("oa-cache", "de__berlin.zip"), csv: "de/berlin.csv", iso2: "DE", region: "", order: "eu" },
120
+ ]
121
+
122
+ /**
123
+ * ["N","E","S","W","NE","NW","SE","SW"].
124
+ */
125
+ const DIRECTIONAL_ABBRS = Object.values(DirectionalAbbreviation)
126
+ /**
127
+ * Fraction of prefix-less streets that get a synthetic directional.
128
+ */
129
+ const INJECT_PREFIX_PROB = 0.3
130
+
131
+ /**
132
+ * A real US skeleton tuple read from a cached OA zip.
133
+ */
134
+ interface USTuple {
135
+ house_number: string
136
+ street: string
137
+ locality: string
138
+ region: string
139
+ postcode: string
140
+ base_source_id: string
141
+ }
142
+
143
+ /**
144
+ * A non-US BALANCE tuple (carries a postcode + native order).
145
+ */
146
+ interface BalanceTuple {
147
+ house_number: string
148
+ street: string
149
+ locality: string
150
+ region: string
151
+ postcode: string
152
+ iso2: string
153
+ order: string
154
+ }
155
+
156
+ /**
157
+ * Prefix carried through render — the (canonical, abbreviation) pair `renderDirectional` consumes.
158
+ */
159
+ type Prefix = Pick<NonNullable<ReturnType<typeof matchLeadingDirectional>>, "canonical" | "abbreviation">
160
+
161
+ /**
162
+ * Stream real US tuples (number/street/city/postcode) out of a cached OA zip.
163
+ */
164
+ async function readTuples(source: USSource): Promise<USTuple[]> {
165
+ return readOATuples(source, {
166
+ extra: (fields, _row, key) => ({
167
+ ...fields,
168
+ region: source.region,
169
+ base_source_id: `openaddresses:${source.csv}:${key}`,
170
+ }),
171
+ })
172
+ }
173
+
174
+ const title = (s: string): string =>
175
+ s
176
+ .toLowerCase()
177
+ .split(/\s+/)
178
+ .map((w) => (w ? w.charAt(0).toUpperCase() + w.slice(1) : w))
179
+ .join(" ")
180
+
181
+ const isSuffixOrDirectional = (word: string): boolean =>
182
+ matchTrailingSuffix(word) !== null || matchLeadingDirectional(word) !== null
183
+
184
+ /**
185
+ * Split an OA street into { prefix?, name, suffix } using the codex. Requires a trailing suffix and a non-empty name
186
+ * that isn't itself an affix token. Returns null when the street has no usable suffix.
187
+ */
188
+ function parseStreet(
189
+ street: string,
190
+ opts: { allowNameProneTail?: boolean } = {}
191
+ ): { prefix: Prefix | null; name: string; suffix: string } | null {
192
+ let words = street.trim().split(/\s+/)
193
+
194
+ if (words.length < 2) return null
195
+ let prefix: Prefix | null = null
196
+ // Leading directional — only if it leaves ≥2 words behind (room for a name + suffix).
197
+ const lead = matchLeadingDirectional(street)
198
+
199
+ if (lead && words.length > 2) {
200
+ prefix = { canonical: lead.canonical, abbreviation: lead.abbreviation }
201
+ words = words.slice(1)
202
+ }
203
+
204
+ // Trailing USPS suffix — only if it leaves ≥1 word for the name.
205
+ const trail = matchTrailingSuffix(words.join(" "))
206
+
207
+ if (!trail || words.length < 2) return null
208
+ const suffix = trail.canonical
209
+ const name = words.slice(0, -1).join(" ")
210
+
211
+ if (!name) return null
212
+
213
+ if (isSuffixOrDirectional(name)) {
214
+ const nameTail = matchTrailingSuffix(name)
215
+
216
+ if (!opts.allowNameProneTail || !nameTail || !NAME_PRONE_US_SUFFIXES.has(nameTail.canonical)) return null
217
+ }
218
+
219
+ return { prefix, name, suffix }
220
+ }
221
+
222
+ export type SuffixBoundaryClass = "terminal-only" | "terminal-contrast"
223
+
224
+ // A terminal-only surface needs a name word before the penultimate suffix (`Blue Hill Rd`): three words at least.
225
+ const TERMINAL_ONLY_MIN_WORDS = 3
226
+
227
+ /**
228
+ * Classify a real street surface for #1569. `terminal-only` has an ambiguous suffix-eligible name word immediately
229
+ * before a different terminal type (`Blue Hill Rd`); `terminal-contrast` ends at the ambiguous word itself (`Sutton
230
+ * Hollow`). The contrast check intentionally wins when both final words are name-prone: only the LAST token is the
231
+ * suffix under the canonical rule.
232
+ */
233
+ export function classifySuffixBoundaryStreet(street: string): SuffixBoundaryClass | null {
234
+ const words = street.trim().split(/\s+/)
235
+
236
+ if (words.length < 2) return null
237
+ const terminal = matchTrailingSuffix(words.at(-1)!)
238
+
239
+ if (!terminal) return null
240
+
241
+ if (NAME_PRONE_US_SUFFIXES.has(terminal.canonical)) return "terminal-contrast"
242
+
243
+ if (words.length < TERMINAL_ONLY_MIN_WORDS) return null
244
+
245
+ const penultimate = matchTrailingSuffix(words.at(-2)!)
246
+
247
+ return penultimate && NAME_PRONE_US_SUFFIXES.has(penultimate.canonical) ? "terminal-only" : null
248
+ }
249
+
250
+ /**
251
+ * Render the affix-split street in random surface forms (abbrev vs expanded per affix), Title-cased.
252
+ */
253
+ function renderStreet(
254
+ random: () => number,
255
+ parsed: { prefix: Prefix | null; name: string; suffix: string }
256
+ ): { street: string; components: Partial<Record<ComponentTag, string>> } {
257
+ const name = title(parsed.name)
258
+ const parts: string[] = []
259
+ const components: Partial<Record<ComponentTag, string>> = { street: name }
260
+
261
+ // Prefix: natural (from parse) or injected onto a prefix-less street to boost street_prefix signal.
262
+ let prefix = parsed.prefix
263
+
264
+ if (!prefix && random() < INJECT_PREFIX_PROB) {
265
+ const m = lookupDirectional(pick(DIRECTIONAL_ABBRS, random))!
266
+ prefix = { canonical: m.directional, abbreviation: m.abbreviation }
267
+ }
268
+
269
+ if (prefix) {
270
+ const rendered = renderDirectional(prefix, random() < 0.5 ? "abbr" : "full", "Aa") // "Aa" → Title-case
271
+ components.street_prefix = rendered
272
+ parts.push(rendered)
273
+ }
274
+
275
+ parts.push(name)
276
+
277
+ // Suffix: abbreviated ("St") vs expanded ("Street"), Title-cased to match the name.
278
+ const full = title(parsed.suffix)
279
+
280
+ // canonical is uppercase word → "Street"
281
+ const abbr = matchCase(
282
+ US_STREET_SUFFIX_PREFERRED_ABBR[parsed.suffix as keyof typeof US_STREET_SUFFIX_PREFERRED_ABBR],
283
+ "Aa"
284
+ )
285
+
286
+ // "AVE" → "Ave"
287
+ const renderedSuffix = random() < 0.5 ? abbr : full
288
+ components.street_suffix = renderedSuffix
289
+ parts.push(renderedSuffix)
290
+
291
+ return { street: parts.join(" "), components }
292
+ }
293
+
294
+ /**
295
+ * Synthetic recipient/venue prefixes — the arena's "JOHN DOE, ACME INC, …" pattern.
296
+ */
297
+ const VENUES = ["John Doe", "Jane Smith", "Acme Inc", "Wayne Enterprises", "Maria Garcia", "Riverside Clinic"]
298
+
299
+ /**
300
+ * Real-venue pool for the suffix-boundary v2 venue shell (corpus 0.19.0). The 2026-08-10 recipe review found the
301
+ * v0.18.x slice's venue-led rows detectable as templates (six fixed venue strings), and the frozen B1 board's failures
302
+ * concentrate in exactly that shell (rich rows 5/43 vs bare 53/65 at v4.3.3 step-40k). HRSA's health-center site file
303
+ * supplies thousands of REAL US facility names ('Alburg Health Center'-register), US-government public domain, already
304
+ * a corpus source (`usgov-hrsa-fqhc`). Kept verbatim (including the ~11% all-caps names — real register diversity);
305
+ * comma-carrying names are dropped because the venue layout uses commas as its field delimiter.
306
+ */
307
+ const VENUE_POOL_CSV = dataRootPath(
308
+ "corpus",
309
+ "sources",
310
+ "usgov-hrsa-fqhc",
311
+ "Health_Center_Service_Delivery_and_LookAlike_Sites.csv"
312
+ )
313
+
314
+ // Facility-name length window: shorter reads as an initialism, longer as a sentence.
315
+ const VENUE_NAME_MIN_LENGTH = 3
316
+ const VENUE_NAME_MAX_LENGTH = 60
317
+
318
+ async function readVenuePool(csvPath: PathBuilderLike): Promise<string[]> {
319
+ const seen = new Set<string>()
320
+ const pool: string[] = []
321
+
322
+ for await (const record of readCSVRecords(csvPath)) {
323
+ // One key, where the source's `Site Name` and `SITE NAME` both used to need naming: the reader snake-cases and
324
+ // lower-cases a header, so either spelling arrives here as `site_name`.
325
+ const name = (record.site_name ?? "").trim().replaceAll(/\s+/gu, " ")
326
+
327
+ if (
328
+ name.length < VENUE_NAME_MIN_LENGTH ||
329
+ name.length > VENUE_NAME_MAX_LENGTH ||
330
+ name.includes(",") ||
331
+ !/\p{L}/u.test(name)
332
+ )
333
+ continue
334
+
335
+ const key = name.toLowerCase()
336
+
337
+ if (seen.has(key)) continue
338
+ seen.add(key)
339
+ pool.push(name)
340
+ }
341
+
342
+ return pool
343
+ }
344
+
345
+ const tail = (loc: string, reg: string, pc: string): string => (pc ? `${loc}, ${reg} ${pc}` : `${loc}, ${reg}`)
346
+
347
+ /**
348
+ * Layout-shell options for {@link renderRow}. `cutoffs` are the cumulative random() boundaries for [full, bare,
349
+ * street-only] — the remainder is the venue shell. Defaults reproduce the original street-affix distribution
350
+ * (40/25/20/15) with the six template venues.
351
+ */
352
+ interface RenderRowOpts {
353
+ venues?: readonly string[]
354
+ cutoffs?: readonly [number, number, number]
355
+ }
356
+
357
+ /**
358
+ * Embed the rendered street in a RANDOM layout so the model recognizes affixes wherever the street sits: full address,
359
+ * bare house+street, street-only (pure affix parse), or venue-prefixed.
360
+ */
361
+ export function renderRow(
362
+ random: () => number,
363
+ base: USTuple,
364
+ street: string,
365
+ streetComponents: Partial<Record<ComponentTag, string>>,
366
+ opts: RenderRowOpts = {}
367
+ ): { fmt: string; raw: string; components: Partial<Record<ComponentTag, string>> } {
368
+ const venues = opts.venues ?? VENUES
369
+ const [fullCutoff, bareCutoff, streetOnlyCutoff] = opts.cutoffs ?? [0.4, 0.65, 0.85]
370
+
371
+ const hn = base.house_number,
372
+ loc = base.locality,
373
+ reg = base.region,
374
+ pc = base.postcode
375
+
376
+ const road = `${hn} ${street}`
377
+ const withRoad: Partial<Record<ComponentTag, string>> = { house_number: hn, ...streetComponents }
378
+ const r = random()
379
+
380
+ if (r < fullCutoff)
381
+ return {
382
+ fmt: "full",
383
+ raw: `${road}, ${tail(loc, reg, pc)}`,
384
+ components: { ...withRoad, locality: loc, region: reg, ...(pc ? { postcode: pc } : {}) },
385
+ }
386
+
387
+ if (r < bareCutoff) return { fmt: "bare", raw: road, components: withRoad }
388
+
389
+ if (r < streetOnlyCutoff) return { fmt: "street-only", raw: street, components: { ...streetComponents } }
390
+ const v = pick(venues, random)
391
+
392
+ return {
393
+ fmt: "venue",
394
+ raw: `${v}, ${road}, ${tail(loc, reg, pc)}`,
395
+ components: { venue: v, ...withRoad, locality: loc, region: reg, ...(pc ? { postcode: pc } : {}) },
396
+ }
397
+ }
398
+
399
+ /**
400
+ * Capped reader for the multi-locale BALANCE sources. The FR/IT/NL countrywide extracts are GB-scale, so this reads
401
+ * only as far as `limit` distinct tuples — the `break` closes the reader and releases the archive. Only keeps tuples
402
+ * that carry a POSTCODE.
403
+ */
404
+ async function readBalanceTuples(source: BalanceSource, limit: number): Promise<BalanceTuple[]> {
405
+ return readOATuples(source, {
406
+ limit,
407
+ requirePostcode: true,
408
+ extra: (fields, row) => ({
409
+ ...fields,
410
+ region: row.region || source.region,
411
+ iso2: source.iso2,
412
+ order: source.order,
413
+ }),
414
+ })
415
+ }
416
+
417
+ /**
418
+ * Render a non-US BALANCE row in native order — NO affix split, NO country token. `street` is the OA value verbatim.
419
+ * The sole job is to put a postcode in its native position so the slice doesn't pull the model US-ward.
420
+ */
421
+ function renderBalanceRow(t: BalanceTuple): { raw: string; components: Partial<Record<ComponentTag, string>> } {
422
+ const { house_number: hn, street, locality: loc, postcode: pc, order } = t
423
+ // region is intentionally omitted — it isn't rendered in `raw`, so labeling it would fail alignment.
424
+ const components: Partial<Record<ComponentTag, string>> = { house_number: hn, street, locality: loc, postcode: pc }
425
+
426
+ const raw =
427
+ order === "fr"
428
+ ? `${hn} ${street}, ${pc} ${loc}` // French: number-street, postcode-city
429
+ : `${street} ${hn}, ${pc} ${loc}`
430
+
431
+ // DE/IT/NL: street-number, postcode-city
432
+ return { raw, components }
433
+ }
434
+
435
+ /**
436
+ * Slice recipe registered with the corpus builder — see the file header for the parse behaviour it exists to exercise,
437
+ * and `description` below for the surface form it generates.
438
+ */
439
+ export const streetAffixRecipe: CorpusRecipe = {
440
+ name: "street-affix",
441
+ description: "US street-affix rows: OA streets split into street_prefix/street/street_suffix (+ multilocale balance)",
442
+ mode: "generate",
443
+ options: [
444
+ {
445
+ flag: "--multilocale-count <N>",
446
+ description: "Append N no-affix native-order balance rows (FR/DE/IT/NL). Default 0",
447
+ },
448
+ ],
449
+ async run(opts, write) {
450
+ // Legacy build-street-affix-slice.mjs seeded `mulberry32(opts.seed)`.
451
+ const random = makeMulberry32(opts.seed)
452
+ const count = opts.count ?? 50_000
453
+ const source = opts.sourceName ?? "synth-affix"
454
+ const multilocaleCount = opts.multilocaleCount ?? 0
455
+ const sources = opts.golden ? [EVAL_SOURCE] : TRAIN_SOURCES
456
+
457
+ const pool: USTuple[] = []
458
+
459
+ for (const s of sources) {
460
+ const t = await readTuples(s)
461
+
462
+ console.error(` ${s.csv}: ${t.length} unique tuples`)
463
+
464
+ for (const x of t) {
465
+ pool.push(x)
466
+ }
467
+ }
468
+
469
+ if (!pool.length) {
470
+ throw new Error(`No US tuples found — are the cached OA zips present in ${dataRootPath("oa-cache")}?`)
471
+ }
472
+
473
+ let emitted = 0
474
+ let skipped = 0
475
+ let noAffix = 0
476
+ let guard = 0
477
+ const formatCounts: Record<string, number> = {}
478
+ const affixCounts = { prefix: 0, suffix: 0, both: 0 }
479
+ const N = pool.length
480
+
481
+ while (emitted < count && guard++ < count * 10) {
482
+ const base = pool[Math.floor(random() * N)]!
483
+ const parsed = parseStreet(base.street)
484
+
485
+ if (!parsed) {
486
+ noAffix++
487
+
488
+ continue
489
+ }
490
+
491
+ const { street, components: streetComponents } = renderStreet(random, parsed)
492
+ const { fmt, raw, components } = renderRow(random, base, street, streetComponents)
493
+
494
+ // Every affix surface form must survive verbatim in raw, else alignment can't label it.
495
+ const surfaces = [streetComponents.street_prefix, streetComponents.street, streetComponents.street_suffix].filter(
496
+ (s): s is string => Boolean(s)
497
+ )
498
+
499
+ if (!surfaces.every((s) => raw.includes(s))) {
500
+ skipped++
501
+
502
+ continue
503
+ }
504
+
505
+ formatCounts[fmt] = (formatCounts[fmt] ?? 0) + 1
506
+ const hasP = !!streetComponents.street_prefix
507
+
508
+ if (hasP && streetComponents.street_suffix) {
509
+ affixCounts.both++
510
+ } else if (hasP) {
511
+ affixCounts.prefix++
512
+ } else {
513
+ affixCounts.suffix++
514
+ }
515
+
516
+ if (opts.golden) {
517
+ write(JSON.stringify({ raw, components, country: "US" }) + "\n")
518
+
519
+ emitted++
520
+
521
+ continue
522
+ }
523
+
524
+ const canonical: CanonicalRow = {
525
+ raw,
526
+ components,
527
+ country: "US",
528
+ locale: "en-US",
529
+ source,
530
+ source_id: stableSourceID(source, components),
531
+ corpus_version: "0.4.0",
532
+ license: "OpenAddresses US (non-VT) skeletons, street split via USPS Pub-28 C1/C2 (codex)",
533
+ }
534
+
535
+ const aligned = alignRow(canonical)
536
+
537
+ if (aligned.kind !== "labeled" || !aligned.row) {
538
+ skipped++
539
+
540
+ continue
541
+ }
542
+
543
+ write(JSON.stringify({ ...aligned.row, synth_method: "affix", synth_base_id: null }) + "\n")
544
+
545
+ emitted++
546
+ }
547
+
548
+ // ── Multi-locale balance rows (--multilocale-count) ─────────────────────────────────────────────
549
+ // Appended AFTER the US affix rows so the US affix signal is unchanged (same `--count`), and the
550
+ // non-US rows ride the SAME source weight. Native-order postcodes, no affix labels.
551
+ let balanceEmitted = 0
552
+ let balanceSkipped = 0
553
+ const balanceISO: Record<string, number> = {}
554
+
555
+ if (multilocaleCount > 0) {
556
+ const mlSources = opts.golden ? MULTILOCALE_EVAL_SOURCES : MULTILOCALE_SOURCES
557
+ const perSource = Math.ceil((multilocaleCount * 3) / mlSources.length) // over-read; balance locales
558
+ const mlPool: BalanceTuple[] = []
559
+
560
+ for (const s of mlSources) {
561
+ const t = await readBalanceTuples(s, perSource)
562
+
563
+ console.error(` balance ${s.csv} (${s.iso2}): ${t.length} tuples`)
564
+
565
+ for (const x of t) {
566
+ mlPool.push(x)
567
+ }
568
+ }
569
+
570
+ const M = mlPool.length
571
+ let mlGuard = 0
572
+
573
+ // oxlint-disable-next-line eslint/no-unmodified-loop-condition -- `M > 0` is an invariant guard against an empty pool, not a progress condition
574
+ while (M > 0 && balanceEmitted < multilocaleCount && mlGuard++ < multilocaleCount * 10) {
575
+ const t = mlPool[Math.floor(random() * M)]!
576
+ const { raw, components } = renderBalanceRow(t)
577
+
578
+ // Every component surface must survive in raw, else alignment can't label it.
579
+ if (![components.street, components.locality, components.postcode].every((s) => !!s && raw.includes(s))) {
580
+ balanceSkipped++
581
+
582
+ continue
583
+ }
584
+
585
+ balanceISO[t.iso2] = (balanceISO[t.iso2] ?? 0) + 1
586
+ const locale = `${t.iso2.toLowerCase()}-${t.iso2}`
587
+
588
+ if (opts.golden) {
589
+ write(JSON.stringify({ raw, components, country: t.iso2 }) + "\n")
590
+
591
+ balanceEmitted++
592
+
593
+ continue
594
+ }
595
+
596
+ const canonical: CanonicalRow = {
597
+ raw,
598
+ components,
599
+ country: t.iso2,
600
+ locale,
601
+ source,
602
+ source_id: stableSourceID(source, components),
603
+ corpus_version: "0.4.0",
604
+ license: "OpenAddresses non-US skeletons (native-order postcode balance for the affix slice)",
605
+ }
606
+
607
+ const aligned = alignRow(canonical)
608
+
609
+ if (aligned.kind !== "labeled" || !aligned.row) {
610
+ balanceSkipped++
611
+
612
+ continue
613
+ }
614
+
615
+ write(JSON.stringify({ ...aligned.row, synth_method: "affix-balance", synth_base_id: null }) + "\n")
616
+
617
+ balanceEmitted++
618
+ }
619
+ }
620
+
621
+ console.error(
622
+ `Done: emitted ${emitted} affix rows, skipped ${skipped}, no-affix ${noAffix} (pool ${pool.length}).\n` +
623
+ ` formats: ${JSON.stringify(formatCounts)}\n` +
624
+ ` affix mix: ${JSON.stringify(affixCounts)}` +
625
+ (multilocaleCount > 0
626
+ ? `\n balance: emitted ${balanceEmitted}, skipped ${balanceSkipped}, iso ${JSON.stringify(balanceISO)}`
627
+ : "")
628
+ )
629
+
630
+ return { emitted: emitted + balanceEmitted, skipped: skipped + balanceSkipped }
631
+ },
632
+ }
633
+
634
+ // The venue shell needs a real register: fewer names than this and the rows read as templates again.
635
+ const VENUE_POOL_MIN_SIZE = 500
636
+ // While both classes are open: 80% terminal-only, 20% terminal-contrast.
637
+ const TERMINAL_ONLY_SHARE = 0.8
638
+
639
+ /**
640
+ * #1569 root-fix slice. Both classes come from real non-Vermont OA streets and use the affix recipe's existing layout
641
+ * diversity. v4.3.1 makes terminal-only 80% of the mix: the first 40/60 run moved a 100-row TRAIN sample only 4→11
642
+ * while contrast was already 95/100 before training (93/100 after). Post-run audit found that the global affix relabel
643
+ * pass corrupts many already-decomposed target rows into double suffixes; do not retrain this recipe until relabel is
644
+ * idempotent over a decomposed street family. The 20% contrast leg remains explicit, additive to the already-strong
645
+ * base distribution, and B2 still checks it unchanged.
646
+ *
647
+ * V2 (corpus 0.19.0, 2026-08-10 recipe review): the v4.3.3 board split (rich venue-led rows 5/43 vs bare 53/65) showed
648
+ * the model separating template rows from real ones, and the venue shell was the giveaway — six fixed venue strings. v2
649
+ * draws the venue shell from thousands of REAL HRSA facility names and raises its share (venue 30%, full 35%, bare 20%,
650
+ * street-only 15%). Dose policy moved to the recipe's config side: weight ≤4 effective passes per run (Muennighoff
651
+ * 2023's repetition knee) and the source is excluded from the augmentation pool — see the v4.4.0 config.
652
+ */
653
+ export const suffixBoundaryRecipe: CorpusRecipe = {
654
+ name: "suffix-boundary",
655
+ description: "US #1569 suffix boundary: OA terminal-only positives + over-sampled terminal contrasts",
656
+ mode: "generate",
657
+ async run(opts, write) {
658
+ const random = makeMulberry32(opts.seed)
659
+ const count = opts.count ?? 30_000
660
+ const source = opts.sourceName ?? "synth-suffix-boundary"
661
+ const sources = opts.golden ? [EVAL_SOURCE] : TRAIN_SOURCES
662
+
663
+ // v2 venue shell: real facility names, loud when the source file is missing or thin.
664
+ const venuePool = await readVenuePool(VENUE_POOL_CSV)
665
+
666
+ if (venuePool.length < VENUE_POOL_MIN_SIZE) {
667
+ throw new Error(
668
+ `suffix-boundary v2 venue pool too thin: ${venuePool.length} names from ${VENUE_POOL_CSV} — ` +
669
+ "is the usgov-hrsa-fqhc source present?"
670
+ )
671
+ }
672
+
673
+ const shell: RenderRowOpts = { venues: venuePool, cutoffs: [0.35, 0.55, 0.7] }
674
+
675
+ const pool: Record<SuffixBoundaryClass, USTuple[]> = {
676
+ "terminal-only": [],
677
+ "terminal-contrast": [],
678
+ }
679
+
680
+ for (const s of sources) {
681
+ for (const tuple of await readTuples(s)) {
682
+ const rowClass = classifySuffixBoundaryStreet(tuple.street)
683
+
684
+ if (rowClass) {
685
+ pool[rowClass].push(tuple)
686
+ }
687
+ }
688
+ }
689
+
690
+ if (!pool["terminal-only"].length || !pool["terminal-contrast"].length) {
691
+ throw new Error(
692
+ `Suffix-boundary source class missing: terminal-only=${pool["terminal-only"].length}, ` +
693
+ `terminal-contrast=${pool["terminal-contrast"].length}`
694
+ )
695
+ }
696
+
697
+ let emitted = 0
698
+ let skipped = 0
699
+ const classCounts: Record<SuffixBoundaryClass, number> = { "terminal-only": 0, "terminal-contrast": 0 }
700
+ const terminalOnlyTarget = Math.round(count * 0.8)
701
+
702
+ const classTargets: Record<SuffixBoundaryClass, number> = {
703
+ "terminal-only": terminalOnlyTarget,
704
+ "terminal-contrast": count - terminalOnlyTarget,
705
+ }
706
+
707
+ const formatCounts: Record<string, number> = {}
708
+ let stemPairs = 0
709
+
710
+ const emitOne = (
711
+ rowClass: SuffixBoundaryClass,
712
+ base: USTuple,
713
+ parsed: NonNullable<ReturnType<typeof parseStreet>>,
714
+ method: string
715
+ ): boolean => {
716
+ const { street, components: streetComponents } = renderStreet(random, parsed)
717
+ const { fmt, raw, components } = renderRow(random, base, street, streetComponents, shell)
718
+
719
+ const canonical: CanonicalRow = {
720
+ raw,
721
+ components,
722
+ country: "US",
723
+ locale: "en-US",
724
+ source,
725
+ source_id: sliceSourceID(source, { ...components, class: rowClass, n: String(emitted) }),
726
+ corpus_version: "0.19.0",
727
+ license:
728
+ "OpenAddresses US (non-VT) skeletons; terminal suffix labels via USPS Pub-28 codex; venue shell from HRSA site names (US public domain)",
729
+ }
730
+
731
+ const aligned = alignRow(canonical)
732
+
733
+ if (aligned.kind !== "labeled" || !aligned.row) {
734
+ skipped++
735
+
736
+ return false
737
+ }
738
+
739
+ write(JSON.stringify({ ...aligned.row, synth_method: method, synth_base_id: base.base_source_id }) + "\n")
740
+
741
+ classCounts[rowClass]++
742
+ formatCounts[fmt] = (formatCounts[fmt] ?? 0) + 1
743
+
744
+ emitted++
745
+
746
+ return true
747
+ }
748
+
749
+ // oxlint-disable-next-line eslint/no-unmodified-loop-condition -- emitted/skipped advance inside emitOne (a closure); the rule cannot see through the call
750
+ while (emitted < count && emitted + skipped < count * 10) {
751
+ const terminalOnlyOpen = classCounts["terminal-only"] < classTargets["terminal-only"]
752
+ const terminalContrastOpen = classCounts["terminal-contrast"] < classTargets["terminal-contrast"]
753
+
754
+ const rowClass: SuffixBoundaryClass =
755
+ terminalOnlyOpen && terminalContrastOpen
756
+ ? random() < TERMINAL_ONLY_SHARE
757
+ ? "terminal-only"
758
+ : "terminal-contrast"
759
+ : terminalContrastOpen
760
+ ? "terminal-contrast"
761
+ : "terminal-only"
762
+
763
+ const classPool = pool[rowClass]
764
+ const base = pick(classPool, random)
765
+ const parsed = parseStreet(base.street, { allowNameProneTail: rowClass === "terminal-only" })
766
+
767
+ if (!parsed) {
768
+ skipped++
769
+
770
+ continue
771
+ }
772
+
773
+ if (!emitOne(rowClass, base, parsed, `suffix-boundary:${rowClass}`)) continue
774
+
775
+ // Stem-pair hard negative (v2, 2026-08-10 recipe review): after a terminal-only row
776
+ // ('Menlo Park' + 'Road'), also emit the SAME stem without its true suffix as a
777
+ // contrast row ('Menlo' + 'Park' under the canonical last-token rule). Sharing the stem
778
+ // forces the model to key on the licensing evidence — the trailing true suffix — rather
779
+ // than on name identity. Dose-neutral: these fill the existing 20% contrast target.
780
+ if (
781
+ rowClass === "terminal-only" &&
782
+ classCounts["terminal-contrast"] < classTargets["terminal-contrast"] &&
783
+ emitted < count &&
784
+ random() < 0.5
785
+ ) {
786
+ const stemParsed = parseStreet(parsed.name)
787
+
788
+ if (
789
+ stemParsed &&
790
+ emitOne("terminal-contrast", base, stemParsed, "suffix-boundary:terminal-contrast:stem-pair")
791
+ ) {
792
+ stemPairs++
793
+ }
794
+ }
795
+ }
796
+
797
+ console.error(
798
+ `Done: emitted ${emitted}, skipped ${skipped}; source pools ${JSON.stringify({
799
+ terminalOnly: pool["terminal-only"].length,
800
+ terminalContrast: pool["terminal-contrast"].length,
801
+ })}; classes ${JSON.stringify(classCounts)}; stem pairs ${stemPairs}; ` +
802
+ `venue pool ${venuePool.length}; formats ${JSON.stringify(formatCounts)}`
803
+ )
804
+
805
+ return { emitted, skipped }
806
+ },
807
+ }