@mailwoman/corpus 8.6.0 → 9.1.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 (497) hide show
  1. package/README.md +2 -2
  2. package/data/PROVENANCE.md +214 -0
  3. package/data/sub-venue-lexicon.json +18269 -0
  4. package/out/src/adapters/ban/adapter.d.ts +5 -4
  5. package/out/src/adapters/ban/adapter.d.ts.map +1 -1
  6. package/out/src/adapters/ban/adapter.js +62 -69
  7. package/out/src/adapters/ban/adapter.js.map +1 -1
  8. package/out/src/adapters/ban/street-decompose.d.ts.map +1 -1
  9. package/out/src/adapters/ban/street-decompose.js +18 -25
  10. package/out/src/adapters/ban/street-decompose.js.map +1 -1
  11. package/out/src/adapters/fcc-bdc/adapter.d.ts +1 -7
  12. package/out/src/adapters/fcc-bdc/adapter.d.ts.map +1 -1
  13. package/out/src/adapters/fcc-bdc/adapter.js +4 -26
  14. package/out/src/adapters/fcc-bdc/adapter.js.map +1 -1
  15. package/out/src/adapters/geonames/adapter.d.ts +1 -1
  16. package/out/src/adapters/geonames/adapter.d.ts.map +1 -1
  17. package/out/src/adapters/geonames/adapter.js +72 -78
  18. package/out/src/adapters/geonames/adapter.js.map +1 -1
  19. package/out/src/adapters/geonames-postal/adapter.d.ts +1 -1
  20. package/out/src/adapters/geonames-postal/adapter.d.ts.map +1 -1
  21. package/out/src/adapters/geonames-postal/adapter.js +46 -51
  22. package/out/src/adapters/geonames-postal/adapter.js.map +1 -1
  23. package/out/src/adapters/gnaf/adapter.d.ts +1 -1
  24. package/out/src/adapters/gnaf/adapter.d.ts.map +1 -1
  25. package/out/src/adapters/gnaf/adapter.js +6 -9
  26. package/out/src/adapters/gnaf/adapter.js.map +1 -1
  27. package/out/src/adapters/gnaf/assemble.d.ts.map +1 -1
  28. package/out/src/adapters/gnaf/assemble.js +7 -12
  29. package/out/src/adapters/gnaf/assemble.js.map +1 -1
  30. package/out/src/adapters/index.d.ts +1 -1
  31. package/out/src/adapters/index.d.ts.map +1 -1
  32. package/out/src/adapters/index.js +1 -1
  33. package/out/src/adapters/index.js.map +1 -1
  34. package/out/src/adapters/openaddresses/adapter.d.ts +1 -1
  35. package/out/src/adapters/openaddresses/adapter.d.ts.map +1 -1
  36. package/out/src/adapters/openaddresses/adapter.js +5 -10
  37. package/out/src/adapters/openaddresses/adapter.js.map +1 -1
  38. package/out/src/adapters/overture/adapter.d.ts +1 -1
  39. package/out/src/adapters/overture/adapter.d.ts.map +1 -1
  40. package/out/src/adapters/overture/adapter.js +5 -9
  41. package/out/src/adapters/overture/adapter.js.map +1 -1
  42. package/out/src/adapters/state-hi-schools/adapter.d.ts +1 -1
  43. package/out/src/adapters/state-hi-schools/adapter.d.ts.map +1 -1
  44. package/out/src/adapters/state-hi-schools/adapter.js +57 -75
  45. package/out/src/adapters/state-hi-schools/adapter.js.map +1 -1
  46. package/out/src/adapters/state-ia-contractors/adapter.d.ts +1 -1
  47. package/out/src/adapters/state-ia-contractors/adapter.d.ts.map +1 -1
  48. package/out/src/adapters/state-ia-contractors/adapter.js +60 -78
  49. package/out/src/adapters/state-ia-contractors/adapter.js.map +1 -1
  50. package/out/src/adapters/state-ny-notaries/adapter.d.ts +1 -1
  51. package/out/src/adapters/state-ny-notaries/adapter.d.ts.map +1 -1
  52. package/out/src/adapters/state-ny-notaries/adapter.js +69 -87
  53. package/out/src/adapters/state-ny-notaries/adapter.js.map +1 -1
  54. package/out/src/adapters/state-tx-notaries/adapter.d.ts +1 -1
  55. package/out/src/adapters/state-tx-notaries/adapter.d.ts.map +1 -1
  56. package/out/src/adapters/state-tx-notaries/adapter.js +71 -89
  57. package/out/src/adapters/state-tx-notaries/adapter.js.map +1 -1
  58. package/out/src/adapters/synth-po-box/adapter.d.ts +3 -3
  59. package/out/src/adapters/synth-po-box/adapter.d.ts.map +1 -1
  60. package/out/src/adapters/synth-po-box/adapter.js +10 -18
  61. package/out/src/adapters/synth-po-box/adapter.js.map +1 -1
  62. package/out/src/adapters/tiger/adapter.d.ts +1 -1
  63. package/out/src/adapters/tiger/adapter.d.ts.map +1 -1
  64. package/out/src/adapters/tiger/adapter.js +2 -2
  65. package/out/src/adapters/tiger/adapter.js.map +1 -1
  66. package/out/src/adapters/tiger/street-decompose.d.ts.map +1 -1
  67. package/out/src/adapters/tiger/street-decompose.js +18 -27
  68. package/out/src/adapters/tiger/street-decompose.js.map +1 -1
  69. package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts +4 -4
  70. package/out/src/adapters/usgov-hrsa-fqhc/adapter.d.ts.map +1 -1
  71. package/out/src/adapters/usgov-hrsa-fqhc/adapter.js +64 -82
  72. package/out/src/adapters/usgov-hrsa-fqhc/adapter.js.map +1 -1
  73. package/out/src/adapters/usgov-imls-pls/adapter.d.ts +1 -1
  74. package/out/src/adapters/usgov-imls-pls/adapter.d.ts.map +1 -1
  75. package/out/src/adapters/usgov-imls-pls/adapter.js +62 -84
  76. package/out/src/adapters/usgov-imls-pls/adapter.js.map +1 -1
  77. package/out/src/adapters/usgov-irs-bmf/adapter.d.ts +1 -1
  78. package/out/src/adapters/usgov-irs-bmf/adapter.d.ts.map +1 -1
  79. package/out/src/adapters/usgov-irs-bmf/adapter.js +59 -66
  80. package/out/src/adapters/usgov-irs-bmf/adapter.js.map +1 -1
  81. package/out/src/adapters/usgov-nad/adapter.d.ts +1 -1
  82. package/out/src/adapters/usgov-nad/adapter.d.ts.map +1 -1
  83. package/out/src/adapters/usgov-nad/adapter.js +6 -9
  84. package/out/src/adapters/usgov-nad/adapter.js.map +1 -1
  85. package/out/src/adapters/usgov-nppes/adapter.d.ts +1 -1
  86. package/out/src/adapters/usgov-nppes/adapter.d.ts.map +1 -1
  87. package/out/src/adapters/usgov-nppes/adapter.js +60 -78
  88. package/out/src/adapters/usgov-nppes/adapter.js.map +1 -1
  89. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts +1 -1
  90. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.d.ts.map +1 -1
  91. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js +53 -73
  92. package/out/src/adapters/usgov-samhsa-treatment-locator/adapter.js.map +1 -1
  93. package/out/src/{adapter.d.ts → adapters/utils/index.d.ts} +43 -2
  94. package/out/src/adapters/utils/index.d.ts.map +1 -0
  95. package/out/src/{adapter.js → adapters/utils/index.js} +47 -2
  96. package/out/src/adapters/utils/index.js.map +1 -0
  97. package/out/src/adapters/wof-admin-jp/adapter.d.ts +1 -1
  98. package/out/src/adapters/wof-admin-jp/adapter.d.ts.map +1 -1
  99. package/out/src/adapters/wof-admin-jp/adapter.js +24 -6
  100. package/out/src/adapters/wof-admin-jp/adapter.js.map +1 -1
  101. package/out/src/adapters/wof-admin-json/adapter.d.ts +2 -2
  102. package/out/src/adapters/wof-admin-json/adapter.d.ts.map +1 -1
  103. package/out/src/adapters/wof-admin-json/adapter.js +2 -2
  104. package/out/src/adapters/wof-admin-json/adapter.js.map +1 -1
  105. package/out/src/adapters/wof-postalcode-json/adapter.d.ts +2 -2
  106. package/out/src/adapters/wof-postalcode-json/adapter.d.ts.map +1 -1
  107. package/out/src/adapters/wof-postalcode-json/adapter.js +2 -2
  108. package/out/src/adapters/wof-postalcode-json/adapter.js.map +1 -1
  109. package/out/src/build.d.ts +3 -4
  110. package/out/src/build.d.ts.map +1 -1
  111. package/out/src/build.js +6 -8
  112. package/out/src/build.js.map +1 -1
  113. package/out/src/index.d.ts +3 -17
  114. package/out/src/index.d.ts.map +1 -1
  115. package/out/src/index.js +3 -17
  116. package/out/src/index.js.map +1 -1
  117. package/out/src/name-prone-us-suffixes.d.ts +12 -0
  118. package/out/src/name-prone-us-suffixes.d.ts.map +1 -0
  119. package/out/src/name-prone-us-suffixes.js +12 -0
  120. package/out/src/name-prone-us-suffixes.js.map +1 -0
  121. package/out/src/parquet-wrapper/reader.d.ts +8 -0
  122. package/out/src/parquet-wrapper/reader.d.ts.map +1 -1
  123. package/out/src/parquet-wrapper/reader.js +16 -0
  124. package/out/src/parquet-wrapper/reader.js.map +1 -1
  125. package/out/src/parquet-wrapper/schema.d.ts +4 -0
  126. package/out/src/parquet-wrapper/schema.d.ts.map +1 -1
  127. package/out/src/parquet-wrapper/schema.js.map +1 -1
  128. package/out/src/runner.d.ts +2 -2
  129. package/out/src/runner.d.ts.map +1 -1
  130. package/out/src/runner.js +1 -1
  131. package/out/src/runner.js.map +1 -1
  132. package/out/src/shard-recipes/anchor-absorption.d.ts.map +1 -1
  133. package/out/src/shard-recipes/anchor-absorption.js +5 -4
  134. package/out/src/shard-recipes/anchor-absorption.js.map +1 -1
  135. package/out/src/shard-recipes/boundary-stress.d.ts.map +1 -1
  136. package/out/src/shard-recipes/boundary-stress.js +2 -2
  137. package/out/src/shard-recipes/boundary-stress.js.map +1 -1
  138. package/out/src/shard-recipes/country-balanced.d.ts.map +1 -1
  139. package/out/src/shard-recipes/country-balanced.js +75 -75
  140. package/out/src/shard-recipes/country-balanced.js.map +1 -1
  141. package/out/src/shard-recipes/fr-admin-split.js +2 -2
  142. package/out/src/shard-recipes/fr-admin-split.js.map +1 -1
  143. package/out/src/shard-recipes/fr-fragment.d.ts.map +1 -1
  144. package/out/src/shard-recipes/fr-fragment.js +8 -5
  145. package/out/src/shard-recipes/fr-fragment.js.map +1 -1
  146. package/out/src/shard-recipes/fr-lieudit.js +2 -2
  147. package/out/src/shard-recipes/fr-lieudit.js.map +1 -1
  148. package/out/src/shard-recipes/fr-order.d.ts.map +1 -1
  149. package/out/src/shard-recipes/fr-order.js +18 -72
  150. package/out/src/shard-recipes/fr-order.js.map +1 -1
  151. package/out/src/shard-recipes/german.d.ts.map +1 -1
  152. package/out/src/shard-recipes/german.js +17 -70
  153. package/out/src/shard-recipes/german.js.map +1 -1
  154. package/out/src/shard-recipes/house-venue.d.ts.map +1 -1
  155. package/out/src/shard-recipes/house-venue.js +1 -1
  156. package/out/src/shard-recipes/house-venue.js.map +1 -1
  157. package/out/src/shard-recipes/index.d.ts.map +1 -1
  158. package/out/src/shard-recipes/index.js +4 -1
  159. package/out/src/shard-recipes/index.js.map +1 -1
  160. package/out/src/shard-recipes/intersection.d.ts +2 -2
  161. package/out/src/shard-recipes/intersection.d.ts.map +1 -1
  162. package/out/src/shard-recipes/intersection.js +28 -72
  163. package/out/src/shard-recipes/intersection.js.map +1 -1
  164. package/out/src/shard-recipes/locale.d.ts +5 -5
  165. package/out/src/shard-recipes/locale.d.ts.map +1 -1
  166. package/out/src/shard-recipes/locale.js +25 -35
  167. package/out/src/shard-recipes/locale.js.map +1 -1
  168. package/out/src/shard-recipes/no-fragment.d.ts.map +1 -1
  169. package/out/src/shard-recipes/no-fragment.js +8 -5
  170. package/out/src/shard-recipes/no-fragment.js.map +1 -1
  171. package/out/src/shard-recipes/no-street-led.d.ts.map +1 -1
  172. package/out/src/shard-recipes/no-street-led.js +8 -5
  173. package/out/src/shard-recipes/no-street-led.js.map +1 -1
  174. package/out/src/shard-recipes/no-street.d.ts.map +1 -1
  175. package/out/src/shard-recipes/no-street.js +1 -1
  176. package/out/src/shard-recipes/no-street.js.map +1 -1
  177. package/out/src/shard-recipes/po-box-cedex.d.ts +3 -3
  178. package/out/src/shard-recipes/po-box-cedex.d.ts.map +1 -1
  179. package/out/src/shard-recipes/po-box-cedex.js +101 -127
  180. package/out/src/shard-recipes/po-box-cedex.js.map +1 -1
  181. package/out/src/shard-recipes/po-box.d.ts.map +1 -1
  182. package/out/src/shard-recipes/po-box.js +1 -1
  183. package/out/src/shard-recipes/po-box.js.map +1 -1
  184. package/out/src/shard-recipes/scaffold.d.ts +58 -9
  185. package/out/src/shard-recipes/scaffold.d.ts.map +1 -1
  186. package/out/src/shard-recipes/scaffold.js +87 -29
  187. package/out/src/shard-recipes/scaffold.js.map +1 -1
  188. package/out/src/shard-recipes/street-affix.d.ts +54 -0
  189. package/out/src/shard-recipes/street-affix.d.ts.map +1 -1
  190. package/out/src/shard-recipes/street-affix.js +253 -111
  191. package/out/src/shard-recipes/street-affix.js.map +1 -1
  192. package/out/src/shard-recipes/street-bare.d.ts.map +1 -1
  193. package/out/src/shard-recipes/street-bare.js +3 -3
  194. package/out/src/shard-recipes/street-bare.js.map +1 -1
  195. package/out/src/shard-recipes/street.d.ts.map +1 -1
  196. package/out/src/shard-recipes/street.js +2 -2
  197. package/out/src/shard-recipes/street.js.map +1 -1
  198. package/out/src/shard-recipes/sub-venue-sources.d.ts +228 -0
  199. package/out/src/shard-recipes/sub-venue-sources.d.ts.map +1 -0
  200. package/out/src/shard-recipes/sub-venue-sources.js +664 -0
  201. package/out/src/shard-recipes/sub-venue-sources.js.map +1 -0
  202. package/out/src/shard-recipes/sub-venue.d.ts +269 -0
  203. package/out/src/shard-recipes/sub-venue.d.ts.map +1 -0
  204. package/out/src/shard-recipes/sub-venue.js +709 -0
  205. package/out/src/shard-recipes/sub-venue.js.map +1 -0
  206. package/out/src/shard-recipes/unit.d.ts +1 -1
  207. package/out/src/shard-recipes/unit.d.ts.map +1 -1
  208. package/out/src/shard-recipes/unit.js +26 -74
  209. package/out/src/shard-recipes/unit.js.map +1 -1
  210. package/out/src/{synthesize-anchor-absorption.d.ts → synthesizers/anchor-absorption.d.ts} +1 -1
  211. package/out/src/synthesizers/anchor-absorption.d.ts.map +1 -0
  212. package/out/src/{synthesize-anchor-absorption.js → synthesizers/anchor-absorption.js} +1 -1
  213. package/out/src/synthesizers/anchor-absorption.js.map +1 -0
  214. package/out/src/{synthesize-boundary-stress.d.ts → synthesizers/boundary-stress.d.ts} +3 -3
  215. package/out/src/synthesizers/boundary-stress.d.ts.map +1 -0
  216. package/out/src/{synthesize-boundary-stress.js → synthesizers/boundary-stress.js} +2 -2
  217. package/out/src/synthesizers/boundary-stress.js.map +1 -0
  218. package/out/src/{synthesize-german.d.ts → synthesizers/german.d.ts} +2 -2
  219. package/out/src/synthesizers/german.d.ts.map +1 -0
  220. package/out/src/{synthesize-german.js → synthesizers/german.js} +2 -2
  221. package/out/src/synthesizers/german.js.map +1 -0
  222. package/out/src/{synthesize-house-venue.d.ts → synthesizers/house-venue.d.ts} +4 -4
  223. package/out/src/synthesizers/house-venue.d.ts.map +1 -0
  224. package/out/src/{synthesize-house-venue.js → synthesizers/house-venue.js} +4 -4
  225. package/out/src/synthesizers/house-venue.js.map +1 -0
  226. package/out/src/{synthesize-intersection.d.ts → synthesizers/intersection.d.ts} +2 -2
  227. package/out/src/synthesizers/intersection.d.ts.map +1 -0
  228. package/out/src/{synthesize-intersection.js → synthesizers/intersection.js} +1 -1
  229. package/out/src/synthesizers/intersection.js.map +1 -0
  230. package/out/src/{synthesize-no-street.d.ts → synthesizers/no-street.d.ts} +3 -3
  231. package/out/src/synthesizers/no-street.d.ts.map +1 -0
  232. package/out/src/{synthesize-no-street.js → synthesizers/no-street.js} +2 -2
  233. package/out/src/synthesizers/no-street.js.map +1 -0
  234. package/out/src/{synthesize-po-box.d.ts → synthesizers/po-box.d.ts} +2 -2
  235. package/out/src/synthesizers/po-box.d.ts.map +1 -0
  236. package/out/src/{synthesize-po-box.js → synthesizers/po-box.js} +1 -1
  237. package/out/src/synthesizers/po-box.js.map +1 -0
  238. package/out/src/{synthesize-street.d.ts → synthesizers/street.d.ts} +2 -2
  239. package/out/src/synthesizers/street.d.ts.map +1 -0
  240. package/out/src/{synthesize-street.js → synthesizers/street.js} +2 -2
  241. package/out/src/synthesizers/street.js.map +1 -0
  242. package/out/src/{synthesize.d.ts → synthesizers/utils.d.ts} +3 -3
  243. package/out/src/synthesizers/utils.d.ts.map +1 -0
  244. package/out/src/{synthesize.js → synthesizers/utils.js} +4 -15
  245. package/out/src/synthesizers/utils.js.map +1 -0
  246. package/out/src/tools/align-shard.d.ts.map +1 -1
  247. package/out/src/tools/align-shard.js +4 -8
  248. package/out/src/tools/align-shard.js.map +1 -1
  249. package/out/src/tools/audit.d.ts.map +1 -1
  250. package/out/src/tools/audit.js +4 -4
  251. package/out/src/tools/audit.js.map +1 -1
  252. package/out/src/tools/corpus-stats.d.ts +2 -2
  253. package/out/src/tools/corpus-stats.d.ts.map +1 -1
  254. package/out/src/tools/corpus-stats.js +18 -31
  255. package/out/src/tools/corpus-stats.js.map +1 -1
  256. package/out/src/tools/fetch/download.d.ts.map +1 -1
  257. package/out/src/tools/fetch/download.js +5 -6
  258. package/out/src/tools/fetch/download.js.map +1 -1
  259. package/out/src/tools/fetch/imls-pls.d.ts.map +1 -1
  260. package/out/src/tools/fetch/imls-pls.js +3 -15
  261. package/out/src/tools/fetch/imls-pls.js.map +1 -1
  262. package/out/src/tools/fetch/index.d.ts +14 -1
  263. package/out/src/tools/fetch/index.d.ts.map +1 -1
  264. package/out/src/tools/fetch/index.js +14 -1
  265. package/out/src/tools/fetch/index.js.map +1 -1
  266. package/out/src/tools/fetch/nad.d.ts +1 -1
  267. package/out/src/tools/fetch/nad.js +1 -1
  268. package/out/src/tools/fetch/nppes.d.ts.map +1 -1
  269. package/out/src/tools/fetch/nppes.js +8 -14
  270. package/out/src/tools/fetch/nppes.js.map +1 -1
  271. package/out/src/tools/fetch/openaddresses.d.ts +1 -1
  272. package/out/src/tools/fetch/openaddresses.js +1 -1
  273. package/out/src/tools/fetch/ourairports.d.ts +45 -0
  274. package/out/src/tools/fetch/ourairports.d.ts.map +1 -0
  275. package/out/src/tools/fetch/ourairports.js +123 -0
  276. package/out/src/tools/fetch/ourairports.js.map +1 -0
  277. package/out/src/tools/fetch/wikidata-subvenue.d.ts +171 -0
  278. package/out/src/tools/fetch/wikidata-subvenue.d.ts.map +1 -0
  279. package/out/src/tools/fetch/wikidata-subvenue.js +275 -0
  280. package/out/src/tools/fetch/wikidata-subvenue.js.map +1 -0
  281. package/out/src/tools/golden-expand.d.ts.map +1 -1
  282. package/out/src/tools/golden-expand.js +18 -16
  283. package/out/src/tools/golden-expand.js.map +1 -1
  284. package/out/src/tools/golden-promote.d.ts.map +1 -1
  285. package/out/src/tools/golden-promote.js +12 -6
  286. package/out/src/tools/golden-promote.js.map +1 -1
  287. package/out/src/tools/golden-relabel-street.d.ts +196 -0
  288. package/out/src/tools/golden-relabel-street.d.ts.map +1 -0
  289. package/out/src/tools/golden-relabel-street.js +440 -0
  290. package/out/src/tools/golden-relabel-street.js.map +1 -0
  291. package/out/src/tools/index.d.ts +4 -0
  292. package/out/src/tools/index.d.ts.map +1 -1
  293. package/out/src/tools/index.js +4 -0
  294. package/out/src/tools/index.js.map +1 -1
  295. package/out/src/tools/jsonl-to-parquet.d.ts.map +1 -1
  296. package/out/src/tools/jsonl-to-parquet.js +3 -2
  297. package/out/src/tools/jsonl-to-parquet.js.map +1 -1
  298. package/out/src/tools/lint-shard-vocab.d.ts.map +1 -1
  299. package/out/src/tools/lint-shard-vocab.js +3 -2
  300. package/out/src/tools/lint-shard-vocab.js.map +1 -1
  301. package/out/src/tools/lint-shard.d.ts +3 -3
  302. package/out/src/tools/lint-shard.d.ts.map +1 -1
  303. package/out/src/tools/lint-shard.js +23 -32
  304. package/out/src/tools/lint-shard.js.map +1 -1
  305. package/out/src/tools/overlay-manifest.d.ts.map +1 -1
  306. package/out/src/tools/overlay-manifest.js +2 -1
  307. package/out/src/tools/overlay-manifest.js.map +1 -1
  308. package/out/src/tools/overture-subvenue.d.ts +112 -0
  309. package/out/src/tools/overture-subvenue.d.ts.map +1 -0
  310. package/out/src/tools/overture-subvenue.js +144 -0
  311. package/out/src/tools/overture-subvenue.js.map +1 -0
  312. package/out/src/tools/shard-kryptonite.d.ts +1 -1
  313. package/out/src/tools/shard-kryptonite.d.ts.map +1 -1
  314. package/out/src/tools/shard-kryptonite.js +6 -6
  315. package/out/src/tools/shard-kryptonite.js.map +1 -1
  316. package/out/src/tools/shard-translit.d.ts +6 -3
  317. package/out/src/tools/shard-translit.d.ts.map +1 -1
  318. package/out/src/tools/shard-translit.js +9 -8
  319. package/out/src/tools/shard-translit.js.map +1 -1
  320. package/out/src/tools/sub-venue-lexicon.d.ts +507 -0
  321. package/out/src/tools/sub-venue-lexicon.d.ts.map +1 -0
  322. package/out/src/tools/sub-venue-lexicon.js +817 -0
  323. package/out/src/tools/sub-venue-lexicon.js.map +1 -0
  324. package/out/src/tools/sub-venue-promotions.d.ts +94 -0
  325. package/out/src/tools/sub-venue-promotions.d.ts.map +1 -0
  326. package/out/src/tools/sub-venue-promotions.js +266 -0
  327. package/out/src/tools/sub-venue-promotions.js.map +1 -0
  328. package/out/src/{align.d.ts → utils/align.d.ts} +1 -1
  329. package/out/src/utils/align.d.ts.map +1 -0
  330. package/out/src/utils/align.js.map +1 -0
  331. package/out/src/{golden.d.ts → utils/golden.d.ts} +5 -0
  332. package/out/src/utils/golden.d.ts.map +1 -0
  333. package/out/src/{golden.js → utils/golden.js} +24 -10
  334. package/out/src/utils/golden.js.map +1 -0
  335. package/out/src/utils/index.d.ts +14 -0
  336. package/out/src/utils/index.d.ts.map +1 -0
  337. package/out/src/utils/index.js +14 -0
  338. package/out/src/utils/index.js.map +1 -0
  339. package/out/src/utils/license.d.ts.map +1 -0
  340. package/out/src/utils/license.js.map +1 -0
  341. package/out/src/{parquet.d.ts → utils/parquet.d.ts} +2 -2
  342. package/out/src/utils/parquet.d.ts.map +1 -0
  343. package/out/src/{parquet.js → utils/parquet.js} +3 -15
  344. package/out/src/utils/parquet.js.map +1 -0
  345. package/out/src/{split.d.ts → utils/split.d.ts} +8 -1
  346. package/out/src/utils/split.d.ts.map +1 -0
  347. package/out/src/{split.js → utils/split.js} +7 -0
  348. package/out/src/utils/split.js.map +1 -0
  349. package/out/src/utils/tokenize.d.ts.map +1 -0
  350. package/out/src/utils/tokenize.js.map +1 -0
  351. package/out/src/{wof-json.d.ts → utils/wof-json.d.ts} +2 -2
  352. package/out/src/utils/wof-json.d.ts.map +1 -0
  353. package/out/src/{wof-json.js → utils/wof-json.js} +5 -8
  354. package/out/src/utils/wof-json.js.map +1 -0
  355. package/package.json +66 -20
  356. package/src/adapters/ban/adapter.ts +58 -68
  357. package/src/adapters/ban/street-decompose.ts +17 -25
  358. package/src/adapters/fcc-bdc/adapter.ts +5 -36
  359. package/src/adapters/geonames/adapter.ts +67 -76
  360. package/src/adapters/geonames-postal/adapter.ts +45 -54
  361. package/src/adapters/gnaf/adapter.ts +7 -11
  362. package/src/adapters/gnaf/assemble.ts +7 -11
  363. package/src/adapters/index.ts +3 -2
  364. package/src/adapters/openaddresses/adapter.ts +6 -12
  365. package/src/adapters/overture/adapter.ts +6 -10
  366. package/src/adapters/state-hi-schools/adapter.ts +53 -77
  367. package/src/adapters/state-ia-contractors/adapter.ts +55 -80
  368. package/src/adapters/state-ny-notaries/adapter.ts +64 -89
  369. package/src/adapters/state-tx-notaries/adapter.ts +63 -88
  370. package/src/adapters/synth-po-box/adapter.ts +12 -23
  371. package/src/adapters/tiger/adapter.ts +4 -3
  372. package/src/adapters/tiger/street-decompose.ts +21 -31
  373. package/src/adapters/usgov-hrsa-fqhc/adapter.ts +64 -88
  374. package/src/adapters/usgov-imls-pls/adapter.ts +57 -86
  375. package/src/adapters/usgov-irs-bmf/adapter.ts +55 -66
  376. package/src/adapters/usgov-nad/adapter.ts +7 -11
  377. package/src/adapters/usgov-nppes/adapter.ts +54 -79
  378. package/src/adapters/usgov-samhsa-treatment-locator/adapter.ts +48 -75
  379. package/src/{adapter.ts → adapters/utils/index.ts} +59 -3
  380. package/src/adapters/wof-admin-jp/adapter.ts +35 -9
  381. package/src/adapters/wof-admin-json/adapter.ts +3 -4
  382. package/src/adapters/wof-postalcode-json/adapter.ts +3 -4
  383. package/src/build.ts +12 -11
  384. package/src/index.ts +3 -17
  385. package/src/name-prone-us-suffixes.ts +12 -0
  386. package/src/parquet-wrapper/reader.ts +19 -0
  387. package/src/parquet-wrapper/schema.ts +4 -0
  388. package/src/runner.ts +7 -2
  389. package/src/shard-recipes/anchor-absorption.ts +5 -4
  390. package/src/shard-recipes/boundary-stress.ts +6 -2
  391. package/src/shard-recipes/country-balanced.ts +77 -91
  392. package/src/shard-recipes/fr-admin-split.ts +3 -3
  393. package/src/shard-recipes/fr-fragment.ts +10 -7
  394. package/src/shard-recipes/fr-lieudit.ts +3 -3
  395. package/src/shard-recipes/fr-order.ts +18 -83
  396. package/src/shard-recipes/german.ts +17 -80
  397. package/src/shard-recipes/house-venue.ts +2 -1
  398. package/src/shard-recipes/index.ts +4 -1
  399. package/src/shard-recipes/intersection.ts +37 -74
  400. package/src/shard-recipes/locale.ts +31 -39
  401. package/src/shard-recipes/no-fragment.ts +10 -7
  402. package/src/shard-recipes/no-street-led.ts +10 -7
  403. package/src/shard-recipes/no-street.ts +2 -1
  404. package/src/shard-recipes/po-box-cedex.ts +127 -161
  405. package/src/shard-recipes/po-box.ts +6 -1
  406. package/src/shard-recipes/scaffold.ts +125 -27
  407. package/src/shard-recipes/street-affix.ts +335 -134
  408. package/src/shard-recipes/street-bare.ts +4 -3
  409. package/src/shard-recipes/street.ts +3 -2
  410. package/src/shard-recipes/sub-venue-sources.ts +895 -0
  411. package/src/shard-recipes/sub-venue.ts +982 -0
  412. package/src/shard-recipes/unit.ts +27 -85
  413. package/src/{synthesize-boundary-stress.ts → synthesizers/boundary-stress.ts} +2 -2
  414. package/src/{synthesize-german.ts → synthesizers/german.ts} +2 -2
  415. package/src/{synthesize-house-venue.ts → synthesizers/house-venue.ts} +4 -4
  416. package/src/{synthesize-intersection.ts → synthesizers/intersection.ts} +1 -1
  417. package/src/{synthesize-no-street.ts → synthesizers/no-street.ts} +2 -2
  418. package/src/{synthesize-po-box.ts → synthesizers/po-box.ts} +1 -1
  419. package/src/{synthesize-street.ts → synthesizers/street.ts} +2 -2
  420. package/src/{synthesize.ts → synthesizers/utils.ts} +4 -18
  421. package/src/tools/align-shard.ts +4 -7
  422. package/src/tools/audit.ts +6 -5
  423. package/src/tools/corpus-stats.ts +25 -33
  424. package/src/tools/fetch/download.ts +7 -5
  425. package/src/tools/fetch/imls-pls.ts +4 -18
  426. package/src/tools/fetch/index.ts +14 -1
  427. package/src/tools/fetch/nad.ts +1 -1
  428. package/src/tools/fetch/nppes.ts +9 -16
  429. package/src/tools/fetch/openaddresses.ts +1 -1
  430. package/src/tools/fetch/ourairports.ts +166 -0
  431. package/src/tools/fetch/wikidata-subvenue.ts +386 -0
  432. package/src/tools/golden-expand.ts +18 -13
  433. package/src/tools/golden-promote.ts +15 -6
  434. package/src/tools/golden-relabel-street.ts +685 -0
  435. package/src/tools/index.ts +4 -0
  436. package/src/tools/jsonl-to-parquet.ts +3 -2
  437. package/src/tools/lint-shard-vocab.ts +3 -2
  438. package/src/tools/lint-shard.ts +33 -36
  439. package/src/tools/overlay-manifest.ts +2 -1
  440. package/src/tools/overture-subvenue.ts +215 -0
  441. package/src/tools/shard-kryptonite.ts +8 -9
  442. package/src/tools/shard-translit.ts +22 -11
  443. package/src/tools/sub-venue-lexicon.ts +1250 -0
  444. package/src/tools/sub-venue-promotions.ts +330 -0
  445. package/src/{align.ts → utils/align.ts} +1 -1
  446. package/src/{golden.ts → utils/golden.ts} +25 -11
  447. package/src/utils/index.ts +14 -0
  448. package/src/{parquet.ts → utils/parquet.ts} +5 -19
  449. package/src/{split.ts → utils/split.ts} +8 -2
  450. package/src/{wof-json.ts → utils/wof-json.ts} +5 -8
  451. package/out/src/adapter.d.ts.map +0 -1
  452. package/out/src/adapter.js.map +0 -1
  453. package/out/src/align.d.ts.map +0 -1
  454. package/out/src/align.js.map +0 -1
  455. package/out/src/format.d.ts +0 -14
  456. package/out/src/format.d.ts.map +0 -1
  457. package/out/src/format.js +0 -14
  458. package/out/src/format.js.map +0 -1
  459. package/out/src/golden.d.ts.map +0 -1
  460. package/out/src/golden.js.map +0 -1
  461. package/out/src/license.d.ts.map +0 -1
  462. package/out/src/license.js.map +0 -1
  463. package/out/src/parquet.d.ts.map +0 -1
  464. package/out/src/parquet.js.map +0 -1
  465. package/out/src/split.d.ts.map +0 -1
  466. package/out/src/split.js.map +0 -1
  467. package/out/src/synthesize-anchor-absorption.d.ts.map +0 -1
  468. package/out/src/synthesize-anchor-absorption.js.map +0 -1
  469. package/out/src/synthesize-boundary-stress.d.ts.map +0 -1
  470. package/out/src/synthesize-boundary-stress.js.map +0 -1
  471. package/out/src/synthesize-german.d.ts.map +0 -1
  472. package/out/src/synthesize-german.js.map +0 -1
  473. package/out/src/synthesize-house-venue.d.ts.map +0 -1
  474. package/out/src/synthesize-house-venue.js.map +0 -1
  475. package/out/src/synthesize-intersection.d.ts.map +0 -1
  476. package/out/src/synthesize-intersection.js.map +0 -1
  477. package/out/src/synthesize-no-street.d.ts.map +0 -1
  478. package/out/src/synthesize-no-street.js.map +0 -1
  479. package/out/src/synthesize-po-box.d.ts.map +0 -1
  480. package/out/src/synthesize-po-box.js.map +0 -1
  481. package/out/src/synthesize-street.d.ts.map +0 -1
  482. package/out/src/synthesize-street.js.map +0 -1
  483. package/out/src/synthesize.d.ts.map +0 -1
  484. package/out/src/synthesize.js.map +0 -1
  485. package/out/src/tokenize.d.ts.map +0 -1
  486. package/out/src/tokenize.js.map +0 -1
  487. package/out/src/wof-json.d.ts.map +0 -1
  488. package/out/src/wof-json.js.map +0 -1
  489. package/src/format.ts +0 -14
  490. /package/out/src/{align.js → utils/align.js} +0 -0
  491. /package/out/src/{license.d.ts → utils/license.d.ts} +0 -0
  492. /package/out/src/{license.js → utils/license.js} +0 -0
  493. /package/out/src/{tokenize.d.ts → utils/tokenize.d.ts} +0 -0
  494. /package/out/src/{tokenize.js → utils/tokenize.js} +0 -0
  495. /package/src/{synthesize-anchor-absorption.ts → synthesizers/anchor-absorption.ts} +0 -0
  496. /package/src/{license.ts → utils/license.ts} +0 -0
  497. /package/src/{tokenize.ts → utils/tokenize.ts} +0 -0
@@ -4,7 +4,7 @@
4
4
  * @author Teffen Ellis, et al.
5
5
  *
6
6
  * `unit` shard recipe — US secondary-unit coverage (#451, the v0-parity `unit` gap). Onto REAL US
7
- * OpenAddresses skeletons (cached zips under `/tmp/oa-cache`) it INJECTS a USPS Pub-28 Appendix
7
+ * OpenAddresses skeletons (cached zips under `$MAILWOMAN_DATA_ROOT/oa-cache`) it INJECTS a USPS Pub-28 Appendix
8
8
  * C2 secondary-unit designator (the `@mailwoman/codex/us` table), varying the surface form
9
9
  * (canonical "Apartment" vs approved "Apt") AND the unit's POSITION (after-street / unit-first /
10
10
  * bare / venue-prefixed) per row, so the model learns to RECOGNIZE the designator wherever it
@@ -21,15 +21,14 @@
21
21
  * framework LCG) is consumed in the exact call order the legacy script used.
22
22
  */
23
23
 
24
- import { spawnSync } from "node:child_process"
25
-
26
24
  import { US_UNIT_DESIGNATOR_PREFERRED_ABBR, type USUnitDesignator } from "@mailwoman/codex/us"
27
25
  import type { ComponentTag } from "@mailwoman/core/types"
26
+ import { dataRootPath } from "@mailwoman/core/utils"
27
+ import { stableSourceID } from "@mailwoman/corpus/adapters/utils"
28
+ import type { CanonicalRow } from "@mailwoman/corpus/types"
29
+ import { alignRow } from "@mailwoman/corpus/utils"
28
30
 
29
- import { stableSourceID } from "../adapter.ts"
30
- import { alignRow } from "../align.ts"
31
- import type { CanonicalRow } from "../types.ts"
32
- import { makeMulberry32, type ShardRecipe } from "./scaffold.ts"
31
+ import { makeMulberry32, readZippedCSVRecords, type ShardRecipe } from "./scaffold.ts"
33
32
 
34
33
  /**
35
34
  * A cached OpenAddresses extract: the zip, the CSV member, and the implied (file-level) region.
@@ -58,16 +57,20 @@ interface UnitSource {
58
57
  * state cached; eval is Vermont only (the corpus holdout).
59
58
  */
60
59
  const TRAIN_SOURCES: readonly UnitSource[] = [
61
- { zip: "/tmp/oa-cache/us__ca__berkeley.zip", csv: "us/ca/berkeley.csv", region: "CA" },
62
- { zip: "/tmp/oa-cache/us__ca__marin.zip", csv: "us/ca/marin.csv", region: "CA" },
63
- { zip: "/tmp/oa-cache/us__dc__statewide.zip", csv: "us/dc/statewide.csv", region: "DC" },
64
- { zip: "/tmp/oa-cache/us__ia__statewide.zip", csv: "us/ia/statewide.csv", region: "IA" },
65
- { zip: "/tmp/oa-cache/us__il__cook.zip", csv: "us/il/cook.csv", region: "IL" },
66
- { zip: "/tmp/oa-cache/us__mt__statewide.zip", csv: "us/mt/statewide.csv", region: "MT" },
67
- { zip: "/tmp/oa-cache/us__sd__statewide.zip", csv: "us/sd/statewide.csv", region: "SD" },
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" },
68
67
  ]
69
68
 
70
- const EVAL_SOURCE: UnitSource = { zip: "/tmp/oa-cache/us__vt__statewide.zip", csv: "us/vt/statewide.csv", region: "VT" }
69
+ const EVAL_SOURCE: UnitSource = {
70
+ zip: dataRootPath("oa-cache", "us__vt__statewide.zip"),
71
+ csv: "us/vt/statewide.csv",
72
+ region: "VT",
73
+ }
71
74
 
72
75
  /**
73
76
  * USPS Pub-28 C2 designators that take a secondary identifier ("Apt 4B"). Weighted toward the common ones the v0-parity
@@ -114,78 +117,17 @@ interface UnitTuple {
114
117
  oaUnit: string
115
118
  }
116
119
 
117
- /**
118
- * Minimal RFC-4180-ish splitter (handles quoted fields).
119
- */
120
- function splitCSV(line: string): string[] {
121
- const out: string[] = []
122
- let cur = ""
123
- let inQ = false
124
-
125
- for (let i = 0; i < line.length; i++) {
126
- const c = line[i]
127
-
128
- if (inQ) {
129
- if (c === '"') {
130
- if (line[i + 1] === '"') {
131
- cur += '"'
132
-
133
- i++
134
- } else {
135
- inQ = false
136
- }
137
- } else {
138
- cur += c
139
- }
140
- } else if (c === '"') {
141
- inQ = true
142
- } else if (c === ",") {
143
- out.push(cur)
144
- cur = ""
145
- } else {
146
- cur += c
147
- }
148
- }
149
-
150
- out.push(cur)
151
-
152
- return out
153
- }
154
-
155
120
  /**
156
121
  * Stream real US tuples (number/street/city/postcode + the bare OA unit id) out of a cached OA zip.
157
122
  */
158
- function readTuples(source: UnitSource): UnitTuple[] {
159
- const r = spawnSync("unzip", ["-p", source.zip, source.csv], { maxBuffer: 1024 * 1024 * 1024, encoding: "buffer" })
160
-
161
- if (r.status !== 0) {
162
- console.error(` WARN: unzip failed for ${source.zip} (status ${r.status})`)
163
-
164
- return []
165
- }
166
-
167
- const lines = r.stdout.toString("utf8").split(/\r?\n/)
168
-
169
- if (lines.length < 2) return []
170
- const header = splitCSV(lines[0]!).map((h) => h.trim().toLowerCase())
171
- const idx = (name: string): number => header.indexOf(name)
172
-
173
- const iNum = idx("number"),
174
- iStreet = idx("street"),
175
- iUnit = idx("unit"),
176
- iCity = idx("city"),
177
- iPost = idx("postcode")
178
-
179
- const get = (cells: string[], i: number): string => (i >= 0 && i < cells.length ? (cells[i] ?? "").trim() : "")
123
+ async function readTuples(source: UnitSource): Promise<UnitTuple[]> {
180
124
  const tuples: UnitTuple[] = []
181
125
  const seen = new Set<string>()
182
126
 
183
- for (let li = 1; li < lines.length; li++) {
184
- if (!lines[li]) continue
185
- const cells = splitCSV(lines[li]!)
186
- const street = get(cells, iStreet)
187
- const locality = get(cells, iCity)
188
- const house_number = get(cells, iNum)
127
+ for await (const row of readZippedCSVRecords(source.zip, source.csv)) {
128
+ const street = row.street ?? ""
129
+ const locality = row.city ?? ""
130
+ const house_number = row.number ?? ""
189
131
 
190
132
  if (!street || !locality || !house_number) continue
191
133
  const key = `${house_number}|${street}|${locality}`.toLowerCase()
@@ -198,8 +140,8 @@ function readTuples(source: UnitSource): UnitTuple[] {
198
140
  street,
199
141
  locality,
200
142
  region: source.region,
201
- postcode: get(cells, iPost),
202
- oaUnit: get(cells, iUnit),
143
+ postcode: row.postcode ?? "",
144
+ oaUnit: row.unit ?? "",
203
145
  })
204
146
  }
205
147
 
@@ -311,7 +253,7 @@ export const unitRecipe: ShardRecipe = {
311
253
  const pool: UnitTuple[] = []
312
254
 
313
255
  for (const s of sources) {
314
- const t = readTuples(s)
256
+ const t = await readTuples(s)
315
257
 
316
258
  console.error(` ${s.csv}: ${t.length} unique tuples`)
317
259
 
@@ -321,7 +263,7 @@ export const unitRecipe: ShardRecipe = {
321
263
  }
322
264
 
323
265
  if (!pool.length) {
324
- throw new Error("No US tuples found — are the cached OA zips present in /tmp/oa-cache?")
266
+ throw new Error(`No US tuples found — are the cached OA zips present in ${dataRootPath("oa-cache")}?`)
325
267
  }
326
268
 
327
269
  let emitted = 0
@@ -46,10 +46,10 @@
46
46
  * tokenizer splits `/`) and is the worst within-token class — but it inherently requires non-base
47
47
  * AU/NZ/UK locales, which contradict the US/FR/DE base (the lint catch). It belongs in a
48
48
  * separately-scoped AU/NZ/UK boundary-coverage shard that ALSO adds AU base coverage, not in this
49
- * base-locale shard. `synthesize-boundary-stress.test.ts` proves the alignments.
49
+ * base-locale shard. `synthesizers/boundary-stress.test.ts` proves the alignments.
50
50
  */
51
51
 
52
- import type { CanonicalRow } from "./types.ts"
52
+ import type { CanonicalRow } from "@mailwoman/corpus/types"
53
53
 
54
54
  /* oxlint-disable sister-software/no-unnamed-threshold -- the bare decimals below are weighted-sampler
55
55
  cutoffs, not thresholds: `const r = random()` followed by a cascade of `r < 0.4` branches IS the
@@ -22,8 +22,8 @@
22
22
  * `raw` so alignment lands.
23
23
  */
24
24
 
25
- import { formatAddress } from "./format.ts"
26
- import type { CanonicalRow } from "./types.ts"
25
+ import type { CanonicalRow } from "@mailwoman/corpus/types"
26
+ import { formatAddress } from "@mailwoman/formatter"
27
27
 
28
28
  /**
29
29
  * A real address tuple (e.g. one OpenAddresses row): street + locality required, rest optional.
@@ -9,7 +9,7 @@
9
9
  * house_number recall by ~4-5pp. DeepSeek's turn-8 root-cause:
10
10
  *
11
11
  * 1. Direct: `5th Avenue Theatre`-style adversarial venues teach the model that tokens like "5th"
12
- * belong to venues, not house_numbers. (Fixed in `synthesize-no-street.ts` by removing
12
+ * belong to venues, not house_numbers. (Fixed in `no-street.ts` by removing
13
13
  * digit+ordinal venue patterns.)
14
14
  * 2. Distributional dilution: synth-no-street adds 122K rows where house_number is absent. The model's
15
15
  * training distribution shifts toward "house_number is rare," and it under-emits the tag at
@@ -23,12 +23,12 @@
23
23
  * Real-world shape: business cards, mailing labels, store directories — `"123 Main St, Sunrise
24
24
  * Bakery, Springfield, IL 62701"` is a perfectly ordinary address form.
25
25
  *
26
- * Venue pool: PLAIN_VENUES from `synthesize-no-street.ts` (re-exported here). Adversarial venues
26
+ * Venue pool: PLAIN_VENUES from `no-street.ts` (re-exported here). Adversarial venues
27
27
  * are deliberately NOT used here — the point is to teach co-occurrence, not to re-introduce
28
28
  * decompose-mode pressure.
29
29
  */
30
30
 
31
- import type { CanonicalRow } from "./types.ts"
31
+ import type { CanonicalRow } from "@mailwoman/corpus/types"
32
32
 
33
33
  export interface HouseVenueBaseTuple {
34
34
  locality: string
@@ -61,7 +61,7 @@ export interface SynthesizedHouseVenueRow {
61
61
 
62
62
  /**
63
63
  * PLAIN venue names, carrying no street-typing tokens. This shard teaches house_number + venue coexistence, NOT
64
- * decompose-mode pressure — adversarial venue names live in `synthesize-no-street.ts`.
64
+ * decompose-mode pressure — adversarial venue names live in `no-street.ts`.
65
65
  */
66
66
  const PLAIN_VENUES: ReadonlyArray<string> = [
67
67
  "Bob's Pizza",
@@ -19,7 +19,7 @@
19
19
  * US-idiomatic only (the harness intersection cases are US: "X & Y, City, ST ZIP").
20
20
  */
21
21
 
22
- import type { CanonicalRow } from "./types.ts"
22
+ import type { CanonicalRow } from "@mailwoman/corpus/types"
23
23
 
24
24
  /**
25
25
  * Street name cores (no suffix) — proper-noun streets that often appear bare.
@@ -34,10 +34,10 @@
34
34
  * counter-example signal the model is missing.
35
35
  *
36
36
  * This complements (does not replace) the existing US-base-tuple source used by
37
- * `synthesize-po-box.ts`; the same `NoStreetBaseTuple` shape is consumed.
37
+ * `po-box.ts`; the same `NoStreetBaseTuple` shape is consumed.
38
38
  */
39
39
 
40
- import type { CanonicalRow } from "./types.ts"
40
+ import type { CanonicalRow } from "@mailwoman/corpus/types"
41
41
 
42
42
  //#region Types
43
43
 
@@ -24,7 +24,7 @@
24
24
  * - USPS DMM 508 §4.1.4 / §4.5.4 — PO Box and street-addressed PO Box
25
25
  */
26
26
 
27
- import type { CanonicalRow } from "./types.ts"
27
+ import type { CanonicalRow } from "@mailwoman/corpus/types"
28
28
 
29
29
  /**
30
30
  * Digits a box number needs before a thousands comma is plausible (`1,234`).
@@ -19,8 +19,8 @@
19
19
  * adapter.
20
20
  */
21
21
 
22
- import { decomposeStreet } from "./adapters/tiger/street-decompose.ts"
23
- import type { CanonicalRow } from "./types.ts"
22
+ import { decomposeStreet } from "@mailwoman/corpus/adapters/tiger/street-decompose"
23
+ import type { CanonicalRow } from "@mailwoman/corpus/types"
24
24
 
25
25
  // Hand-curated US street name pool. Real frequency-weighted street names — sampled
26
26
  // from US Census TIGER 2024 top-1000 by occurrence count. Keep ~50 entries so the
@@ -34,10 +34,11 @@ import {
34
34
  matchTrailingSuffix,
35
35
  } from "@mailwoman/codex/us"
36
36
  import type { BIOLabel, ComponentTag } from "@mailwoman/core/types"
37
+ import { mulberry32 } from "@mailwoman/core/utils"
38
+ import type { CanonicalRow, LabeledRow, QuarantinedRow } from "@mailwoman/corpus/types"
39
+ import { alignRow, assertSpanInvariants, type ComponentSpan } from "@mailwoman/corpus/utils"
37
40
 
38
- import { alignRow, assertSpanInvariants, type ComponentSpan } from "./align.ts"
39
- import { whitespaceTokenizer, type Tokenizer } from "./tokenize.ts"
40
- import type { CanonicalRow, LabeledRow, QuarantinedRow } from "./types.ts"
41
+ import { whitespaceTokenizer, type Tokenizer } from "../utils/tokenize.ts"
41
42
 
42
43
  /**
43
44
  * An augmentation transforms a single row. Return `null` if the augmentation doesn't apply (e.g. accent-strip on a row
@@ -213,21 +214,6 @@ function hashString(s: string): number {
213
214
  return h >>> 0
214
215
  }
215
216
 
216
- /**
217
- * Mulberry32 — a tiny seeded PRNG. Same seed → same stream → reproducible typos.
218
- */
219
- function mulberry32(seed: number): () => number {
220
- let a = seed >>> 0
221
-
222
- return () => {
223
- a = (a + 0x6d_2b_79_f5) | 0
224
- let t = Math.imul(a ^ (a >>> 15), 1 | a)
225
- t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t
226
-
227
- return ((t ^ (t >>> 14)) >>> 0) / 4_294_967_296
228
- }
229
- }
230
-
231
217
  /**
232
218
  * Inject ONE realistic typo — an adjacent-QWERTY-key substitution OR an adjacent-character transposition — into a
233
219
  * single alpha name component (street/locality/region…), teaching the model to recover from real-world misspellings
@@ -26,8 +26,8 @@ import { createWriteStream } from "node:fs"
26
26
  * --output /tmp/kryptonite-labeled.jsonl\
27
27
  * --corpus-version 0.5.0
28
28
  */
29
- import { alignRow } from "@mailwoman/corpus"
30
- import { TextSpliterator } from "spliterator"
29
+ import { alignRow } from "@mailwoman/corpus/utils"
30
+ import { JSONSpliterator } from "spliterator"
31
31
 
32
32
  export interface AlignShardOptions {
33
33
  input: string
@@ -36,16 +36,13 @@ export interface AlignShardOptions {
36
36
  }
37
37
 
38
38
  export async function alignCanonicalShard(args: AlignShardOptions): Promise<void> {
39
- // Read phase only — the write path stays on createWriteStream. TextSpliterator + JSON.parse keeps the
40
- // original tolerance: the `!line.trim()` guard skips blank lines and a trailing CR is valid JSON whitespace.
39
+ // Read phase only — the write path stays on createWriteStream.
41
40
  const outStream = createWriteStream(args.output, { encoding: "utf8" })
42
41
  let labeled = 0
43
42
  let quarantined = 0
44
43
  const quarantineReasons: Record<string, number> = {}
45
44
 
46
- for await (const line of TextSpliterator.fromAsync(args.input)) {
47
- if (!line.trim()) continue
48
- const canonical = JSON.parse(line) as Parameters<typeof alignRow>[0]
45
+ for await (const canonical of JSONSpliterator.fromAsync<Parameters<typeof alignRow>[0]>(args.input)) {
49
46
  // Stamp the target corpus version so the emitted row's provenance matches the run it joins.
50
47
  canonical.corpus_version = args.corpusVersion
51
48
  const result = alignRow(canonical)
@@ -18,6 +18,9 @@
18
18
  import { existsSync, readFileSync, readdirSync } from "node:fs"
19
19
  import { basename, join } from "node:path"
20
20
 
21
+ import { parseJSONStrict } from "@mailwoman/core/objects"
22
+ import { TextSpliterator } from "spliterator"
23
+
21
24
  /**
22
25
  * Share of a shard one source may hold before the mix is flagged as dominated by it.
23
26
  */
@@ -66,13 +69,11 @@ interface ParsedConfig {
66
69
  */
67
70
  function parseConfig(configPath: string): ParsedConfig | null {
68
71
  if (!existsSync(configPath)) return null
69
- const text = readFileSync(configPath, "utf8")
70
- const lines = text.split("\n")
71
72
  const weights: Record<string, number> = {}
72
73
  let inBlock = false
73
74
  let blockIndent = -1
74
75
 
75
- for (const raw of lines) {
76
+ for (const raw of TextSpliterator.from(readFileSync(configPath))) {
76
77
  const sourceWeightsMatch = raw.match(/^([\t ]*)source_weights:\s*$/)
77
78
 
78
79
  if (sourceWeightsMatch) {
@@ -217,9 +218,9 @@ function manifestScan(corpusDir: string, knownPrefixes: readonly string[]): Shar
217
218
 
218
219
  if (!existsSync(manifestPath)) return null
219
220
 
220
- const manifest = JSON.parse(readFileSync(manifestPath, "utf8")) as {
221
+ const manifest = parseJSONStrict<{
221
222
  shards?: Array<{ split: string; source?: string | null; first_source_id?: string | null }>
222
- }
223
+ }>(readFileSync(manifestPath, "utf8"))
223
224
 
224
225
  if (!Array.isArray(manifest.shards)) return null
225
226
  const bySplit: Record<string, Record<string, number>> = {}
@@ -32,14 +32,15 @@
32
32
  *
33
33
  * For a quick local-corpus baseline (limited but useful for linter testing): node
34
34
  * scripts/build-corpus-stats.ts\
35
- * --shards /mnt/playpen/mailwoman-data/corpus/versioned/v0.4.0/corpus-v0.4.0/train/\
35
+ * --shards $MAILWOMAN_DATA_ROOT/corpus/versioned/v0.4.0/corpus-v0.4.0/train/\
36
36
  * --output /tmp/corpus-stats-local.json
37
37
  */
38
38
 
39
- import { execSync } from "node:child_process"
40
39
  import { readdirSync, statSync, writeFileSync } from "node:fs"
41
40
  import { join } from "node:path"
42
41
 
42
+ import { ParquetReader } from "../parquet-wrapper/index.ts"
43
+
43
44
  const SEP = ""
44
45
  const MIN_BIGRAM_COUNT = 2
45
46
 
@@ -65,36 +66,28 @@ function discoverShards(shardsArg: string): string[] {
65
66
  }
66
67
 
67
68
  /**
68
- * Use a Python subprocess to read parquet (pyarrow is heavier than parquet-wasm but already on the path here, and we
69
- * have nothing in the JS ecosystem that reads parquet cleanly at this scale). Emits one JSON object per line: `{tokens:
70
- * [...], labels: [...]}`.
69
+ * Stream a shard's `tokens`/`labels` columns.
70
+ *
71
+ * `limit` stops the iteration rather than filtering afterwards, so a capped run reads only the row groups it needs.
71
72
  */
72
- function streamShardRows(shardPath: string, limit?: number): Array<{ tokens: string[]; labels: string[] }> {
73
- // Pipe the python script via stdin instead of `-c` to preserve newlines verbatim
74
- // (JSON-encoding the script for -c collapses real newlines into literal `\n`).
75
- const py = `
76
- import pyarrow.parquet as pq
77
- import json, sys
78
- t = pq.read_table(${JSON.stringify(shardPath)}, columns=['tokens', 'labels'])
79
- tokens_col = t['tokens'].to_pylist()
80
- labels_col = t['labels'].to_pylist()
81
- n = min(len(tokens_col), ${limit ?? "len(tokens_col)"})
82
- for i in range(n):
83
- sys.stdout.write(json.dumps({"tokens": tokens_col[i], "labels": labels_col[i]}) + "\\n")
84
- `
85
-
86
- const buf = execSync(`python3`, { input: py, maxBuffer: 1024 * 1024 * 1024 })
87
- const rows: Array<{ tokens: string[]; labels: string[] }> = []
88
-
89
- for (const line of buf.toString("utf8").split("\n")) {
90
- if (!line) continue
91
- rows.push(JSON.parse(line))
92
- }
73
+ async function* streamShardRows(
74
+ shardPath: string,
75
+ limit?: number
76
+ ): AsyncIterable<{ tokens: string[]; labels: string[] }> {
77
+ await using reader = await ParquetReader.openFile<{ tokens: string[]; labels: string[] }>(shardPath)
78
+
79
+ let emitted = 0
93
80
 
94
- return rows
81
+ for await (const row of reader.project("tokens", "labels")) {
82
+ if (limit !== undefined && emitted >= limit) break
83
+
84
+ yield row
85
+
86
+ emitted++
87
+ }
95
88
  }
96
89
 
97
- export function buildCorpusStats(args: CorpusStatsOptions): void {
90
+ export async function buildCorpusStats(args: CorpusStatsOptions): Promise<void> {
98
91
  const shardPaths = discoverShards(args.shardsArg)
99
92
 
100
93
  console.error(`Discovered ${shardPaths.length} parquet shard(s)`)
@@ -106,11 +99,10 @@ export function buildCorpusStats(args: CorpusStatsOptions): void {
106
99
  for (const path of shardPaths) {
107
100
  console.error(`Reading ${path}...`)
108
101
 
109
- const rows = streamShardRows(path, args.limitPerShard)
110
- totalRows += rows.length
102
+ const before = totalRows
111
103
 
112
- for (const row of rows) {
113
- const { tokens, labels } = row
104
+ for await (const { tokens, labels } of streamShardRows(path, args.limitPerShard)) {
105
+ totalRows++
114
106
 
115
107
  if (tokens.length !== labels.length) continue
116
108
 
@@ -143,7 +135,7 @@ export function buildCorpusStats(args: CorpusStatsOptions): void {
143
135
  }
144
136
 
145
137
  console.error(
146
- ` ${rows.length} rows; running totals: ${tokenStats.size} unique tokens, ${bigramStats.size} unique bigrams`
138
+ ` ${totalRows - before} rows; running totals: ${tokenStats.size} unique tokens, ${bigramStats.size} unique bigrams`
147
139
  )
148
140
  }
149
141
 
@@ -12,6 +12,8 @@ import { existsSync } from "node:fs"
12
12
  import { readFile, writeFile } from "node:fs/promises"
13
13
  import { setTimeout as sleep } from "node:timers/promises"
14
14
 
15
+ import { tryParsingJSON } from "@mailwoman/core/objects"
16
+
15
17
  /**
16
18
  * Rate limited — retryable, the server is asking us to back off.
17
19
  */
@@ -127,11 +129,11 @@ export async function downloadToFile(options: DownloadOptions): Promise<{ bytes:
127
129
  export async function readManifest<T>(path: string): Promise<T | null> {
128
130
  if (!existsSync(path)) return null
129
131
 
130
- try {
131
- return JSON.parse(await readFile(path, "utf8")) as T
132
- } catch {
133
- return null
134
- }
132
+ // A read failure (e.g. the file vanished after the existsSync probe) maps to null like corrupt
133
+ // JSON does; tryParsingJSON returns null for the non-string sentinel.
134
+ const text = await readFile(path, "utf8").catch(() => null)
135
+
136
+ return tryParsingJSON<T>(text)
135
137
  }
136
138
 
137
139
  /**
@@ -23,12 +23,11 @@
23
23
  /* oxlint-disable sister-software/prefer-region-over-marks -- these markers label steps inside one
24
24
  procedure, not sections of declarations. A region there folds nothing a reader wants folded. */
25
25
 
26
- import { execFile } from "node:child_process"
27
26
  import { existsSync, mkdirSync, statSync } from "node:fs"
28
27
  import { rm } from "node:fs/promises"
29
28
  import { basename, join } from "node:path"
30
- import { promisify } from "node:util"
31
29
 
30
+ import { extractZipEntry, listZipEntries } from "@mailwoman/core/fs/zip"
32
31
  import { sha256File } from "@mailwoman/core/utils"
33
32
 
34
33
  import type { BaseFetchOptions, FetchSummary } from "./download.ts"
@@ -40,8 +39,6 @@ import { downloadToFile, readManifest, writeManifest } from "./download.ts"
40
39
  */
41
40
  const BYTES_PER_KIB = 1024
42
41
 
43
- const execFileAsync = promisify(execFile)
44
-
45
42
  /**
46
43
  * The PLS FY 2023 bulk CSV ZIP (most recent as of 2026-05). If IMLS publishes a newer year, update this URL.
47
44
  */
@@ -58,18 +55,6 @@ interface SourceManifest {
58
55
  bytes: number
59
56
  }
60
57
 
61
- /**
62
- * Return the filenames listed inside a ZIP (the trailing column of each `unzip -l` row).
63
- */
64
- async function listZipEntries(zipPath: string): Promise<string[]> {
65
- const listing = await execFileAsync("unzip", ["-l", zipPath])
66
-
67
- return listing.stdout
68
- .split("\n")
69
- .map((line) => line.trim().split(/\s+/).pop() ?? "")
70
- .filter((name) => name.length > 0)
71
- }
72
-
73
58
  export async function fetchIMLSPLS(
74
59
  options: FetchIMLSPLSOptions,
75
60
  report?: (line: string) => void
@@ -120,7 +105,7 @@ export async function fetchIMLSPLS(
120
105
  // Outlet files match: pls_fy*outlet*.csv (case-insensitive)
121
106
  // Administrative-entity files match: pls_fy*ae*.csv — we skip those.
122
107
  report?.(" Inspecting ZIP contents ...")
123
- const entries = await listZipEntries(zipDest)
108
+ const entries = (await listZipEntries(zipDest)).map((entry) => entry.name)
124
109
 
125
110
  let csvName = entries.find((name) => /pls_fy.*outlet.*\.csv/i.test(name))
126
111
 
@@ -142,9 +127,10 @@ export async function fetchIMLSPLS(
142
127
  }
143
128
 
144
129
  report?.(` Extracting outlet CSV: ${csvName}`)
145
- await execFileAsync("unzip", ["-o", "-j", zipDest, csvName, "-d", destDir])
146
130
 
147
131
  const csvDest = join(destDir, basename(csvName))
132
+
133
+ await extractZipEntry(zipDest, csvName, csvDest)
148
134
  const csvSize = statSync(csvDest).size
149
135
  const csvSha = await sha256File(csvDest)
150
136
 
@@ -40,6 +40,13 @@
40
40
  * Tier A (US PD).
41
41
  * - `openaddresses` — OpenAddresses country collections (default: Canada / `ca`). Tier B/C mixed
42
42
  * — per-row filter.
43
+ * - `ourairports` — OurAirports global airport CSVs (~83K airports + the country/region/runway
44
+ * joins). Tier A (public domain). The VENUE half of the sub-venue arc (#35); it carries no
45
+ * interior structure, which comes from `@mailwoman/osm/sdk`'s `extractOSMSubVenues`.
46
+ * - `wikidata-subvenue` — the multilingual sub-venue DESIGNATOR vocabulary, pulled as the labels
47
+ * and aliases of eight Wikidata concepts (terminal, gate, concourse, campus, …) plus the
48
+ * airport-terminal instance labels as attested usage. Tier A (CC0). The only module in this
49
+ * family built on `APIClient` — see its docstring for why.
43
50
  * - `state-sources` — NY/TX/DE/OR notaries, IA contractors, WA health providers, HI lobbyists.
44
51
  * Tier A (state PD-equivalent).
45
52
  * - `state-hi-schools` — Hawaii DOE school directory (XLSX → CSV via openpyxl). Tier A (state
@@ -65,7 +72,7 @@
65
72
  *
66
73
  * # Download Canada (~2 GiB compressed, ~7 GiB uncompressed)
67
74
  * mailwoman corpus fetch openaddresses --country ca \
68
- * --out-root /mnt/playpen/mailwoman-data/corpus/sources
75
+ * --out-root $MAILWOMAN_DATA_ROOT/corpus/sources
69
76
  *
70
77
  * # Or any other OA country code
71
78
  * mailwoman corpus fetch openaddresses --country fr
@@ -91,9 +98,11 @@ import { fetchIMLSPLS } from "./imls-pls.ts"
91
98
  import { fetchNAD } from "./nad.ts"
92
99
  import { fetchNPPES } from "./nppes.ts"
93
100
  import { fetchOpenAddresses } from "./openaddresses.ts"
101
+ import { fetchOurAirports } from "./ourairports.ts"
94
102
  import { fetchStateHISchools } from "./state-hi-schools.ts"
95
103
  import { fetchStateSources } from "./state-sources.ts"
96
104
  import { fetchTigerFull } from "./tiger-full.ts"
105
+ import { fetchWikidataSubVenue } from "./wikidata-subvenue.ts"
97
106
 
98
107
  export * from "./ban.ts"
99
108
  export * from "./hrsa.ts"
@@ -101,9 +110,11 @@ export * from "./imls-pls.ts"
101
110
  export * from "./nad.ts"
102
111
  export * from "./nppes.ts"
103
112
  export * from "./openaddresses.ts"
113
+ export * from "./ourairports.ts"
104
114
  export * from "./state-hi-schools.ts"
105
115
  export * from "./state-sources.ts"
106
116
  export * from "./tiger-full.ts"
117
+ export * from "./wikidata-subvenue.ts"
107
118
 
108
119
  /**
109
120
  * The fetch-source registry: id → module entry point. Each entry point takes its own options interface.
@@ -115,9 +126,11 @@ export const FETCH_SOURCES = {
115
126
  "imls-pls": fetchIMLSPLS,
116
127
  nppes: fetchNPPES,
117
128
  openaddresses: fetchOpenAddresses,
129
+ ourairports: fetchOurAirports,
118
130
  "state-sources": fetchStateSources,
119
131
  "state-hi-schools": fetchStateHISchools,
120
132
  "tiger-full": fetchTigerFull,
133
+ "wikidata-subvenue": fetchWikidataSubVenue,
121
134
  } as const
122
135
 
123
136
  export type FetchSourceID = keyof typeof FETCH_SOURCES
@@ -26,7 +26,7 @@
26
26
  * ## Usage
27
27
  *
28
28
  * ```sh
29
- * mailwoman corpus fetch nad --out-root /mnt/playpen/mailwoman-data/corpus/sources
29
+ * mailwoman corpus fetch nad --out-root $MAILWOMAN_DATA_ROOT/corpus/sources
30
30
  *
31
31
  * # Resume from an OID
32
32
  * mailwoman corpus fetch nad --start-oid 34400001