@mailwoman/resolver-wof-sqlite 10.0.0 → 10.2.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 (477) hide show
  1. package/README.md +9 -8
  2. package/lib/address/point/interpolation.ts +45 -39
  3. package/lib/address/point/schema.ts +17 -40
  4. package/lib/address/point.ts +316 -0
  5. package/lib/{address/index.ts → address.ts} +1 -1
  6. package/lib/ancestry/backfill.ts +20 -86
  7. package/lib/{ancestry/index.ts → ancestry.ts} +19 -15
  8. package/lib/build/candidate.ts +122 -174
  9. package/lib/build/population-corrections.ts +64 -0
  10. package/lib/build/slim.ts +44 -114
  11. package/lib/candidate/alias-bags.ts +16 -17
  12. package/lib/candidate/ancestors/schema.ts +77 -61
  13. package/lib/candidate/ancestors/sidecar.ts +15 -22
  14. package/lib/candidate/country-display-names.ts +6 -20
  15. package/lib/candidate/extract-fold.ts +10 -55
  16. package/lib/candidate/fts.ts +5 -23
  17. package/lib/candidate/importance.ts +65 -68
  18. package/lib/candidate/lookup.ts +124 -415
  19. package/lib/candidate/name-roles.ts +15 -33
  20. package/lib/candidate/own-name.ts +35 -32
  21. package/lib/candidate/place-attrs.ts +20 -13
  22. package/lib/candidate/schema.ts +29 -65
  23. package/lib/candidate/scoring.ts +54 -93
  24. package/lib/capital-schema.ts +21 -17
  25. package/lib/capitals.ts +29 -27
  26. package/lib/coincident-roles.ts +85 -55
  27. package/lib/convention/schema.ts +15 -16
  28. package/lib/convention.ts +144 -0
  29. package/lib/coverage-manifest-schema.ts +40 -45
  30. package/lib/currency-backfill.ts +34 -79
  31. package/lib/env.ts +1 -1
  32. package/lib/exact-match.ts +32 -21
  33. package/lib/extracts.ts +97 -74
  34. package/lib/fst/autocomplete.ts +54 -37
  35. package/lib/fst/builder.ts +37 -41
  36. package/lib/fst/deserialize-web.ts +16 -17
  37. package/lib/fst/format.ts +41 -23
  38. package/lib/fst/freshness.ts +43 -120
  39. package/lib/fst/matcher.ts +7 -5
  40. package/lib/fst/serialize.ts +54 -74
  41. package/lib/fst/types.ts +78 -75
  42. package/lib/{fst/index.ts → fst.ts} +1 -0
  43. package/lib/fts/query.ts +5 -36
  44. package/lib/fts.ts +280 -0
  45. package/lib/geonames/aliases.ts +73 -144
  46. package/lib/geonames/postal.ts +162 -71
  47. package/lib/index.ts +9 -8
  48. package/lib/interpolation.ts +48 -100
  49. package/lib/lookup.ts +155 -270
  50. package/lib/name-score.ts +9 -7
  51. package/lib/nsul/lookup.ts +37 -54
  52. package/lib/nsul/schema.ts +16 -43
  53. package/lib/paths.ts +159 -0
  54. package/lib/place-importance-schema.ts +62 -169
  55. package/lib/poi/lookup.ts +104 -121
  56. package/lib/poi/schema.ts +42 -26
  57. package/lib/polygon-schema.ts +10 -6
  58. package/lib/postal/city/alias/lookup.ts +22 -40
  59. package/lib/postal/city/alias/schema.ts +14 -10
  60. package/lib/postal/city/candidate-schema.ts +26 -20
  61. package/lib/postcode-point-lookup.ts +8 -27
  62. package/lib/primary-preference.ts +46 -126
  63. package/lib/proximity-rerank.ts +44 -33
  64. package/lib/ranking-weights.ts +105 -78
  65. package/lib/region-keys.ts +70 -42
  66. package/lib/reverse.ts +149 -86
  67. package/lib/schema.ts +73 -50
  68. package/lib/search-fetch.ts +90 -68
  69. package/lib/sqlite/convention-source.ts +15 -23
  70. package/lib/sqlite/utils.ts +19 -22
  71. package/lib/street/centroid/schema.ts +37 -42
  72. package/lib/street/{centroid/index.ts → centroid.ts} +16 -25
  73. package/lib/street/morphology/fst/builder.ts +60 -42
  74. package/lib/street/morphology/fst/loader.ts +40 -32
  75. package/lib/street/name-lookup.ts +45 -41
  76. package/lib/street/normalize.ts +88 -219
  77. package/lib/street/segment-schema.ts +116 -43
  78. package/lib/{street/index.ts → street.ts} +1 -1
  79. package/lib/types.ts +109 -150
  80. package/lib/unified-schema.ts +29 -29
  81. package/lib/uprn/existence.ts +30 -19
  82. package/lib/uprn/lookup.ts +29 -68
  83. package/lib/uprn/schema.ts +18 -40
  84. package/lib/weights-overlay-linker.ts +236 -252
  85. package/out/address/point/interpolation.d.ts +20 -23
  86. package/out/address/point/interpolation.d.ts.map +1 -1
  87. package/out/address/point/interpolation.js +42 -39
  88. package/out/address/point/interpolation.js.map +1 -1
  89. package/out/address/point/schema.d.ts +12 -35
  90. package/out/address/point/schema.d.ts.map +1 -1
  91. package/out/address/point/schema.js +3 -19
  92. package/out/address/point/schema.js.map +1 -1
  93. package/out/address/point.d.ts +57 -0
  94. package/out/address/point.d.ts.map +1 -0
  95. package/out/address/point.js +206 -0
  96. package/out/address/point.js.map +1 -0
  97. package/out/{address/index.js → address.d.ts} +2 -2
  98. package/out/address.d.ts.map +1 -0
  99. package/out/{address/index.d.ts → address.js} +2 -2
  100. package/out/address.js.map +1 -0
  101. package/out/ancestry/backfill.d.ts +11 -64
  102. package/out/ancestry/backfill.d.ts.map +1 -1
  103. package/out/ancestry/backfill.js +14 -74
  104. package/out/ancestry/backfill.js.map +1 -1
  105. package/out/ancestry.d.ts +49 -0
  106. package/out/ancestry.d.ts.map +1 -0
  107. package/out/ancestry.js +59 -0
  108. package/out/ancestry.js.map +1 -0
  109. package/out/build/candidate.d.ts +82 -112
  110. package/out/build/candidate.d.ts.map +1 -1
  111. package/out/build/candidate.js +17 -100
  112. package/out/build/candidate.js.map +1 -1
  113. package/out/build/population-corrections.d.ts +52 -0
  114. package/out/build/population-corrections.d.ts.map +1 -0
  115. package/out/build/population-corrections.js +40 -0
  116. package/out/build/population-corrections.js.map +1 -0
  117. package/out/build/slim.d.ts +8 -44
  118. package/out/build/slim.d.ts.map +1 -1
  119. package/out/build/slim.js +33 -94
  120. package/out/build/slim.js.map +1 -1
  121. package/out/candidate/alias-bags.d.ts +6 -6
  122. package/out/candidate/alias-bags.d.ts.map +1 -1
  123. package/out/candidate/alias-bags.js +16 -17
  124. package/out/candidate/alias-bags.js.map +1 -1
  125. package/out/candidate/ancestors/schema.d.ts +73 -57
  126. package/out/candidate/ancestors/schema.d.ts.map +1 -1
  127. package/out/candidate/ancestors/schema.js +56 -48
  128. package/out/candidate/ancestors/schema.js.map +1 -1
  129. package/out/candidate/ancestors/sidecar.d.ts +3 -8
  130. package/out/candidate/ancestors/sidecar.d.ts.map +1 -1
  131. package/out/candidate/ancestors/sidecar.js +15 -22
  132. package/out/candidate/ancestors/sidecar.js.map +1 -1
  133. package/out/candidate/country-display-names.d.ts +5 -15
  134. package/out/candidate/country-display-names.d.ts.map +1 -1
  135. package/out/candidate/country-display-names.js +6 -20
  136. package/out/candidate/country-display-names.js.map +1 -1
  137. package/out/candidate/extract-fold.d.ts +7 -15
  138. package/out/candidate/extract-fold.d.ts.map +1 -1
  139. package/out/candidate/extract-fold.js +5 -47
  140. package/out/candidate/extract-fold.js.map +1 -1
  141. package/out/candidate/fts.d.ts +5 -23
  142. package/out/candidate/fts.d.ts.map +1 -1
  143. package/out/candidate/fts.js +5 -23
  144. package/out/candidate/fts.js.map +1 -1
  145. package/out/candidate/importance.d.ts +60 -65
  146. package/out/candidate/importance.d.ts.map +1 -1
  147. package/out/candidate/importance.js +56 -63
  148. package/out/candidate/importance.js.map +1 -1
  149. package/out/candidate/lookup.d.ts +18 -55
  150. package/out/candidate/lookup.d.ts.map +1 -1
  151. package/out/candidate/lookup.js +82 -385
  152. package/out/candidate/lookup.js.map +1 -1
  153. package/out/candidate/name-roles.d.ts +9 -21
  154. package/out/candidate/name-roles.d.ts.map +1 -1
  155. package/out/candidate/name-roles.js +15 -33
  156. package/out/candidate/name-roles.js.map +1 -1
  157. package/out/candidate/own-name.d.ts +23 -25
  158. package/out/candidate/own-name.d.ts.map +1 -1
  159. package/out/candidate/own-name.js +35 -32
  160. package/out/candidate/own-name.js.map +1 -1
  161. package/out/candidate/place-attrs.d.ts +20 -13
  162. package/out/candidate/place-attrs.d.ts.map +1 -1
  163. package/out/candidate/place-attrs.js +4 -5
  164. package/out/candidate/place-attrs.js.map +1 -1
  165. package/out/candidate/schema.d.ts +27 -62
  166. package/out/candidate/schema.d.ts.map +1 -1
  167. package/out/candidate/schema.js +10 -22
  168. package/out/candidate/schema.js.map +1 -1
  169. package/out/candidate/scoring.d.ts +7 -8
  170. package/out/candidate/scoring.d.ts.map +1 -1
  171. package/out/candidate/scoring.js +52 -89
  172. package/out/candidate/scoring.js.map +1 -1
  173. package/out/capital-schema.d.ts +21 -17
  174. package/out/capital-schema.d.ts.map +1 -1
  175. package/out/capital-schema.js +17 -15
  176. package/out/capital-schema.js.map +1 -1
  177. package/out/capitals.d.ts +27 -25
  178. package/out/capitals.d.ts.map +1 -1
  179. package/out/capitals.js +23 -21
  180. package/out/capitals.js.map +1 -1
  181. package/out/coincident-roles.d.ts +60 -43
  182. package/out/coincident-roles.d.ts.map +1 -1
  183. package/out/coincident-roles.js +72 -50
  184. package/out/coincident-roles.js.map +1 -1
  185. package/out/convention/schema.d.ts +14 -14
  186. package/out/convention/schema.d.ts.map +1 -1
  187. package/out/convention/schema.js +6 -4
  188. package/out/convention/schema.js.map +1 -1
  189. package/out/convention.d.ts +97 -0
  190. package/out/convention.d.ts.map +1 -0
  191. package/out/convention.js +81 -0
  192. package/out/convention.js.map +1 -0
  193. package/out/coverage-manifest-schema.d.ts +34 -39
  194. package/out/coverage-manifest-schema.d.ts.map +1 -1
  195. package/out/coverage-manifest-schema.js +25 -34
  196. package/out/coverage-manifest-schema.js.map +1 -1
  197. package/out/currency-backfill.d.ts +16 -38
  198. package/out/currency-backfill.d.ts.map +1 -1
  199. package/out/currency-backfill.js +19 -46
  200. package/out/currency-backfill.js.map +1 -1
  201. package/out/env.d.ts +1 -1
  202. package/out/env.js +1 -1
  203. package/out/exact-match.d.ts +19 -10
  204. package/out/exact-match.d.ts.map +1 -1
  205. package/out/exact-match.js +32 -21
  206. package/out/exact-match.js.map +1 -1
  207. package/out/extracts.d.ts +66 -55
  208. package/out/extracts.d.ts.map +1 -1
  209. package/out/extracts.js +63 -55
  210. package/out/extracts.js.map +1 -1
  211. package/out/fst/autocomplete.d.ts +29 -21
  212. package/out/fst/autocomplete.d.ts.map +1 -1
  213. package/out/fst/autocomplete.js +39 -28
  214. package/out/fst/autocomplete.js.map +1 -1
  215. package/out/fst/builder.d.ts.map +1 -1
  216. package/out/fst/builder.js +37 -41
  217. package/out/fst/builder.js.map +1 -1
  218. package/out/fst/deserialize-web.d.ts +4 -4
  219. package/out/fst/deserialize-web.d.ts.map +1 -1
  220. package/out/fst/deserialize-web.js +15 -16
  221. package/out/fst/deserialize-web.js.map +1 -1
  222. package/out/fst/format.d.ts +41 -23
  223. package/out/fst/format.d.ts.map +1 -1
  224. package/out/fst/format.js +41 -23
  225. package/out/fst/format.js.map +1 -1
  226. package/out/fst/freshness.d.ts +19 -81
  227. package/out/fst/freshness.d.ts.map +1 -1
  228. package/out/fst/freshness.js +31 -94
  229. package/out/fst/freshness.js.map +1 -1
  230. package/out/fst/matcher.d.ts +5 -4
  231. package/out/fst/matcher.d.ts.map +1 -1
  232. package/out/fst/matcher.js +2 -2
  233. package/out/fst/matcher.js.map +1 -1
  234. package/out/fst/serialize.d.ts +28 -28
  235. package/out/fst/serialize.d.ts.map +1 -1
  236. package/out/fst/serialize.js +53 -71
  237. package/out/fst/serialize.js.map +1 -1
  238. package/out/fst/types.d.ts +78 -74
  239. package/out/fst/types.d.ts.map +1 -1
  240. package/out/fst/types.js +1 -4
  241. package/out/fst/types.js.map +1 -1
  242. package/out/{fst/index.js → fst.d.ts} +2 -1
  243. package/out/fst.d.ts.map +1 -0
  244. package/out/{fst/index.d.ts → fst.js} +2 -1
  245. package/out/fst.js.map +1 -0
  246. package/out/fts/query.d.ts +2 -27
  247. package/out/fts/query.d.ts.map +1 -1
  248. package/out/fts/query.js +5 -36
  249. package/out/fts/query.js.map +1 -1
  250. package/out/fts.d.ts +126 -0
  251. package/out/fts.d.ts.map +1 -0
  252. package/out/fts.js +188 -0
  253. package/out/fts.js.map +1 -0
  254. package/out/geonames/aliases.d.ts +26 -62
  255. package/out/geonames/aliases.d.ts.map +1 -1
  256. package/out/geonames/aliases.js +45 -117
  257. package/out/geonames/aliases.js.map +1 -1
  258. package/out/geonames/postal.d.ts +84 -44
  259. package/out/geonames/postal.d.ts.map +1 -1
  260. package/out/geonames/postal.js +115 -73
  261. package/out/geonames/postal.js.map +1 -1
  262. package/out/{geonames/index.js → geonames.d.ts} +1 -1
  263. package/out/geonames.d.ts.map +1 -0
  264. package/out/{geonames/index.d.ts → geonames.js} +1 -1
  265. package/out/geonames.js.map +1 -0
  266. package/out/index.d.ts +9 -8
  267. package/out/index.d.ts.map +1 -1
  268. package/out/index.js +6 -5
  269. package/out/index.js.map +1 -1
  270. package/out/interpolation.d.ts +18 -55
  271. package/out/interpolation.d.ts.map +1 -1
  272. package/out/interpolation.js +27 -69
  273. package/out/interpolation.js.map +1 -1
  274. package/out/lookup.d.ts +23 -51
  275. package/out/lookup.d.ts.map +1 -1
  276. package/out/lookup.js +136 -234
  277. package/out/lookup.js.map +1 -1
  278. package/out/name-score.d.ts +2 -2
  279. package/out/name-score.d.ts.map +1 -1
  280. package/out/name-score.js +9 -7
  281. package/out/name-score.js.map +1 -1
  282. package/out/nsul/lookup.d.ts +33 -34
  283. package/out/nsul/lookup.d.ts.map +1 -1
  284. package/out/nsul/lookup.js +26 -40
  285. package/out/nsul/lookup.js.map +1 -1
  286. package/out/nsul/schema.d.ts +16 -43
  287. package/out/nsul/schema.d.ts.map +1 -1
  288. package/out/nsul/schema.js +9 -35
  289. package/out/nsul/schema.js.map +1 -1
  290. package/out/{nsul/index.d.ts → nsul.d.ts} +1 -1
  291. package/out/nsul.d.ts.map +1 -0
  292. package/out/{nsul/index.js → nsul.js} +1 -1
  293. package/out/nsul.js.map +1 -0
  294. package/out/paths.d.ts +124 -0
  295. package/out/paths.d.ts.map +1 -0
  296. package/out/paths.js +104 -0
  297. package/out/paths.js.map +1 -0
  298. package/out/place-importance-schema.d.ts +51 -143
  299. package/out/place-importance-schema.d.ts.map +1 -1
  300. package/out/place-importance-schema.js +28 -143
  301. package/out/place-importance-schema.js.map +1 -1
  302. package/out/poi/lookup.d.ts +40 -47
  303. package/out/poi/lookup.d.ts.map +1 -1
  304. package/out/poi/lookup.js +69 -96
  305. package/out/poi/lookup.js.map +1 -1
  306. package/out/poi/schema.d.ts +41 -25
  307. package/out/poi/schema.d.ts.map +1 -1
  308. package/out/poi/schema.js +25 -17
  309. package/out/poi/schema.js.map +1 -1
  310. package/out/{poi/index.js → poi.d.ts} +1 -1
  311. package/out/poi.d.ts.map +1 -0
  312. package/out/{poi/index.d.ts → poi.js} +1 -1
  313. package/out/poi.js.map +1 -0
  314. package/out/polygon-schema.d.ts +10 -6
  315. package/out/polygon-schema.d.ts.map +1 -1
  316. package/out/polygon-schema.js +2 -2
  317. package/out/polygon-schema.js.map +1 -1
  318. package/out/postal/city/alias/lookup.d.ts +20 -23
  319. package/out/postal/city/alias/lookup.d.ts.map +1 -1
  320. package/out/postal/city/alias/lookup.js +17 -30
  321. package/out/postal/city/alias/lookup.js.map +1 -1
  322. package/out/postal/city/alias/schema.d.ts +14 -10
  323. package/out/postal/city/alias/schema.d.ts.map +1 -1
  324. package/out/postal/city/alias/schema.js +10 -8
  325. package/out/postal/city/alias/schema.js.map +1 -1
  326. package/out/postal/city/candidate-schema.d.ts +25 -19
  327. package/out/postal/city/candidate-schema.d.ts.map +1 -1
  328. package/out/postal/city/candidate-schema.js +21 -17
  329. package/out/postal/city/candidate-schema.js.map +1 -1
  330. package/out/{postal/index.d.ts → postal.d.ts} +1 -1
  331. package/out/postal.d.ts.map +1 -0
  332. package/out/{postal/index.js → postal.js} +1 -1
  333. package/out/postal.js.map +1 -0
  334. package/out/postcode-point-lookup.d.ts +6 -24
  335. package/out/postcode-point-lookup.d.ts.map +1 -1
  336. package/out/postcode-point-lookup.js +5 -17
  337. package/out/postcode-point-lookup.js.map +1 -1
  338. package/out/primary-preference.d.ts +38 -92
  339. package/out/primary-preference.d.ts.map +1 -1
  340. package/out/primary-preference.js +15 -99
  341. package/out/primary-preference.js.map +1 -1
  342. package/out/proximity-rerank.d.ts +41 -30
  343. package/out/proximity-rerank.d.ts.map +1 -1
  344. package/out/proximity-rerank.js +38 -29
  345. package/out/proximity-rerank.js.map +1 -1
  346. package/out/ranking-weights.d.ts +98 -64
  347. package/out/ranking-weights.d.ts.map +1 -1
  348. package/out/ranking-weights.js +26 -25
  349. package/out/ranking-weights.js.map +1 -1
  350. package/out/region-keys.d.ts +50 -31
  351. package/out/region-keys.d.ts.map +1 -1
  352. package/out/region-keys.js +68 -40
  353. package/out/region-keys.js.map +1 -1
  354. package/out/reverse.d.ts +78 -50
  355. package/out/reverse.d.ts.map +1 -1
  356. package/out/reverse.js +98 -61
  357. package/out/reverse.js.map +1 -1
  358. package/out/schema.d.ts +72 -49
  359. package/out/schema.d.ts.map +1 -1
  360. package/out/schema.js +4 -5
  361. package/out/schema.js.map +1 -1
  362. package/out/search-fetch.d.ts +16 -12
  363. package/out/search-fetch.d.ts.map +1 -1
  364. package/out/search-fetch.js +83 -63
  365. package/out/search-fetch.js.map +1 -1
  366. package/out/sqlite/convention-source.d.ts +12 -16
  367. package/out/sqlite/convention-source.d.ts.map +1 -1
  368. package/out/sqlite/convention-source.js +13 -22
  369. package/out/sqlite/convention-source.js.map +1 -1
  370. package/out/sqlite/utils.d.ts +19 -19
  371. package/out/sqlite/utils.d.ts.map +1 -1
  372. package/out/sqlite/utils.js +14 -15
  373. package/out/sqlite/utils.js.map +1 -1
  374. package/out/street/centroid/schema.d.ts +37 -42
  375. package/out/street/centroid/schema.d.ts.map +1 -1
  376. package/out/street/centroid/schema.js +9 -21
  377. package/out/street/centroid/schema.js.map +1 -1
  378. package/out/street/centroid.d.ts +30 -0
  379. package/out/street/centroid.d.ts.map +1 -0
  380. package/out/street/{centroid/index.js → centroid.js} +13 -24
  381. package/out/street/centroid.js.map +1 -0
  382. package/out/street/morphology/fst/builder.d.ts +20 -10
  383. package/out/street/morphology/fst/builder.d.ts.map +1 -1
  384. package/out/street/morphology/fst/builder.js +44 -34
  385. package/out/street/morphology/fst/builder.js.map +1 -1
  386. package/out/street/morphology/fst/loader.d.ts +33 -26
  387. package/out/street/morphology/fst/loader.d.ts.map +1 -1
  388. package/out/street/morphology/fst/loader.js +23 -22
  389. package/out/street/morphology/fst/loader.js.map +1 -1
  390. package/out/street/name-lookup.d.ts +24 -18
  391. package/out/street/name-lookup.d.ts.map +1 -1
  392. package/out/street/name-lookup.js +34 -35
  393. package/out/street/name-lookup.js.map +1 -1
  394. package/out/street/normalize.d.ts +35 -136
  395. package/out/street/normalize.d.ts.map +1 -1
  396. package/out/street/normalize.js +77 -194
  397. package/out/street/normalize.js.map +1 -1
  398. package/out/street/segment-schema.d.ts +79 -39
  399. package/out/street/segment-schema.d.ts.map +1 -1
  400. package/out/street/segment-schema.js +71 -21
  401. package/out/street/segment-schema.js.map +1 -1
  402. package/out/{street/index.js → street.d.ts} +2 -2
  403. package/out/street.d.ts.map +1 -0
  404. package/out/{street/index.d.ts → street.js} +2 -2
  405. package/out/street.js.map +1 -0
  406. package/out/types.d.ts +84 -149
  407. package/out/types.d.ts.map +1 -1
  408. package/out/types.js +0 -6
  409. package/out/types.js.map +1 -1
  410. package/out/unified-schema.d.ts +8 -12
  411. package/out/unified-schema.d.ts.map +1 -1
  412. package/out/unified-schema.js +29 -29
  413. package/out/unified-schema.js.map +1 -1
  414. package/out/uprn/existence.d.ts +28 -17
  415. package/out/uprn/existence.d.ts.map +1 -1
  416. package/out/uprn/existence.js +26 -16
  417. package/out/uprn/existence.js.map +1 -1
  418. package/out/uprn/lookup.d.ts +14 -44
  419. package/out/uprn/lookup.d.ts.map +1 -1
  420. package/out/uprn/lookup.js +21 -57
  421. package/out/uprn/lookup.js.map +1 -1
  422. package/out/uprn/schema.d.ts +18 -40
  423. package/out/uprn/schema.d.ts.map +1 -1
  424. package/out/uprn/schema.js +10 -32
  425. package/out/uprn/schema.js.map +1 -1
  426. package/out/{uprn/index.d.ts → uprn.d.ts} +1 -1
  427. package/out/uprn.d.ts.map +1 -0
  428. package/out/{uprn/index.js → uprn.js} +1 -1
  429. package/out/uprn.js.map +1 -0
  430. package/out/weights-overlay-linker.d.ts +138 -144
  431. package/out/weights-overlay-linker.d.ts.map +1 -1
  432. package/out/weights-overlay-linker.js +105 -159
  433. package/out/weights-overlay-linker.js.map +1 -1
  434. package/package.json +91 -596
  435. package/lib/address/point/index.ts +0 -328
  436. package/lib/convention/index.ts +0 -154
  437. package/lib/fts/index.ts +0 -361
  438. package/out/address/index.d.ts.map +0 -1
  439. package/out/address/index.js.map +0 -1
  440. package/out/address/point/index.d.ts +0 -53
  441. package/out/address/point/index.d.ts.map +0 -1
  442. package/out/address/point/index.js +0 -222
  443. package/out/address/point/index.js.map +0 -1
  444. package/out/ancestry/index.d.ts +0 -45
  445. package/out/ancestry/index.d.ts.map +0 -1
  446. package/out/ancestry/index.js +0 -55
  447. package/out/ancestry/index.js.map +0 -1
  448. package/out/convention/index.d.ts +0 -106
  449. package/out/convention/index.d.ts.map +0 -1
  450. package/out/convention/index.js +0 -93
  451. package/out/convention/index.js.map +0 -1
  452. package/out/fst/index.d.ts.map +0 -1
  453. package/out/fst/index.js.map +0 -1
  454. package/out/fts/index.d.ts +0 -184
  455. package/out/fts/index.d.ts.map +0 -1
  456. package/out/fts/index.js +0 -277
  457. package/out/fts/index.js.map +0 -1
  458. package/out/geonames/index.d.ts.map +0 -1
  459. package/out/geonames/index.js.map +0 -1
  460. package/out/nsul/index.d.ts.map +0 -1
  461. package/out/nsul/index.js.map +0 -1
  462. package/out/poi/index.d.ts.map +0 -1
  463. package/out/poi/index.js.map +0 -1
  464. package/out/postal/index.d.ts.map +0 -1
  465. package/out/postal/index.js.map +0 -1
  466. package/out/street/centroid/index.d.ts +0 -40
  467. package/out/street/centroid/index.d.ts.map +0 -1
  468. package/out/street/centroid/index.js.map +0 -1
  469. package/out/street/index.d.ts.map +0 -1
  470. package/out/street/index.js.map +0 -1
  471. package/out/uprn/index.d.ts.map +0 -1
  472. package/out/uprn/index.js.map +0 -1
  473. /package/lib/{geonames/index.ts → geonames.ts} +0 -0
  474. /package/lib/{nsul/index.ts → nsul.ts} +0 -0
  475. /package/lib/{poi/index.ts → poi.ts} +0 -0
  476. /package/lib/{postal/index.ts → postal.ts} +0 -0
  477. /package/lib/{uprn/index.ts → uprn.ts} +0 -0
@@ -2,63 +2,26 @@
2
2
  * @copyright Sister Software
3
3
  * @license AGPL-3.0
4
4
  * @author Teffen Ellis, et al.
5
- *
6
- * #743/#193 — fold GeoNames bilingual / alt-language place-names into a WOF/unified admin DB as
7
- * first-class places. The hard-filter recall gap on bilingual countries (the address says
8
- * "Karjaa" but the table holds the Swedish "Karis") is missing alt-LANGUAGE names, not missing
9
- * places: the WOF/Overture `names` carried only the primary, so the candidate build's Latin-alias
10
- * explode (build-candidate pass 2) had nothing to widen. GeoNames' per-country dump carries the
11
- * variants inline (the Karis row's `alternatenames` includes "Karjaa").
12
- *
13
- * For each POPULATED place (feature class `P`) this writes an `spr` row + `names` rows (primary +
14
- * Latin alt-names) + population into the SAME tables the WOF/Overture paths use — synthetic ids
15
- * based at {@link GEONAMES_ID_BASE} so the three sources never collide. The caller then rebuilds
16
- * `place_search` ({@link buildPlaceSearchFTS} with `drop: true`) so the candidate build carries
17
- * Karjaa↔Karis. Proven (FI hard-resolve 69.5 → 85.8 %, coverage 74.4 → 94.0 %); duplicating a
18
- * place already held under another source is benign — the rows share name_key+coord and the
19
- * candidate ranking dedupes by score.
20
- *
21
- * This is the package home so the canonical `build-unified-wof --geonames-countries`, the
22
- * pipeline fold (`gazetteer-pipeline/admin/fold-geonames`), AND the `mailwoman gazetteer` commands all share
23
- * ONE implementation. GeoNames dump = `download.geonames.org/export/dump/<CC>.zip` → `<CC>.txt`
24
- * (TSV).
25
5
  */
26
6
 
27
7
  import { isOfficialLanguage } from "@mailwoman/codex/country"
28
- import { pathExists } from "@mailwoman/core/fs/readers"
8
+ import { readUnquotedTSV } from "@mailwoman/core/fs/delimited"
9
+ import { pathExists } from "@mailwoman/core/fs/readers/stat"
29
10
  import { GEONAMES_ID_BASE, GEONAMES_POSTAL_ID_BASE } from "@mailwoman/core/resolver/synthetic-id-ranges"
30
11
  import type { DatabaseClient } from "@mailwoman/sqlite/client"
31
- import { join, type PathBuilderLike } from "path-ts"
32
- import { TSVSpliterator } from "spliterator"
12
+ import { type PathBuilderLike, resolvePathBuilder } from "path-ts"
33
13
 
34
14
  import type { WOFDatabase } from "#schema"
35
15
 
36
- /**
37
- * The four tables the alias fold writes into the range it owns. The purge and the ingest must agree on this list — a
38
- * table written but not purged is exactly the #1514 defect.
39
- */
40
16
  const FOLD_OWNED_TABLES = ["spr", "names", "place_population", "ancestors"] as const
41
17
 
42
18
  /**
43
- * Clear everything the alias fold owns — `[GEONAMES_ID_BASE, GEONAMES_POSTAL_ID_BASE)` across {@link
44
- * FOLD_OWNED_TABLES}
45
- * — so a fold's output is a function of its country list and dumps ALONE, never of what the DB happened to hold first.
46
- * Returns the rows removed per table.
47
- *
48
- * This exists because the synthetic id is a POSITION (`GEONAMES_ID_BASE + n`, counted across the country list in
49
- * order), not a derivation from the geonameid: change the list, its order, or a dump's contents and every subsequent id
50
- * shifts. Without the purge, a second fold overwrote the `spr` PREFIX it reached (`INSERT OR REPLACE`) while its
51
- * `names`/`ancestors` rows merely appended (bare `INSERT`) and `place_population` skipped unpopulated places entirely —
52
- * so the previous run's names, ancestry and populations stayed bound to ids now describing other places.
19
+ * Deletes every row the GeoNames alias fold owns, with ids in
20
+ * `[GEONAMES_ID_BASE, GEONAMES_POSTAL_ID_BASE)`, and returns the count removed per table.
53
21
  *
54
- * Measured on the live 2026-08-05 artifact: a 14-country re-fold over the 161-country fold baked into
55
- * `admin-global-priority.db` put 522,184 of 2,110,096 name rows in the range (24.7 %) on a place from a different
56
- * country. Gaborone/BW at id 9000000121151 became Aichegg/AT and kept all 26 of its names; Kinshasa's 16,000,000
57
- * population landed on a Lithuanian hamlet.
58
- *
59
- * The upper bound is NOT the end of the id space. Each later extract owns a range above this one — GeoNames-postal @
60
- * 9.5e12, NL-PC6 @ 9.6e12, Code-Point @ 9.7e12, NI @ 9.8e12 — and a purge that ran past {@link GEONAMES_POSTAL_ID_BASE}
61
- * would delete them.
22
+ * Fold ids are assigned sequentially, so a re-fold without this purge would attach
23
+ * stale names, ancestors and populations to other places.
24
+ * The upper bound leaves the postal and postcode id ranges above it untouched.
62
25
  */
63
26
  export function purgeGeonamesAliasRange<DB>(db: DatabaseClient<DB>): Record<string, number> {
64
27
  const removed: Record<string, number> = {}
@@ -75,59 +38,61 @@ export function purgeGeonamesAliasRange<DB>(db: DatabaseClient<DB>): Record<stri
75
38
  }
76
39
 
77
40
  /**
78
- * Per-country progress for the ingest — one event per country dump processed (or skipped).
41
+ * One progress event per country dump that the ingest processed or skipped.
79
42
  */
80
43
  export interface GeonamesIngestProgress {
81
44
  /**
82
- * ISO 3166-1 alpha-2 code.
45
+ * The ISO 3166-1 alpha-2 country code.
83
46
  */
84
47
  country: string
48
+
85
49
  /**
86
- * Populated places ingested from this country's dump (0 when skipped).
50
+ * The number of populated places ingested from this country's dump, or 0 when it was skipped.
87
51
  */
88
52
  places: number
53
+
89
54
  /**
90
- * True when the country's `<CC>.txt` dump was missing — the country is skipped, not fatal.
55
+ * Whether the country's `<CC>.txt` dump was missing.
56
+ *
57
+ * A missing dump skips the country without failing the ingest.
91
58
  */
92
59
  skipped: boolean
60
+
61
+ /**
62
+ * The number of alternate names that the alias filter rejected.
63
+ *
64
+ * It distinguishes a sparse source from aliases that the fold discarded.
65
+ */
66
+ aliasesRefused: number | null
93
67
  }
94
68
 
95
69
  /**
96
- * One spelling's language attribution, as reconciled across every alternate-names row that carries it.
70
+ * Formats a GeoNames fold progress event as one log line.
97
71
  */
72
+ export function formatGeonamesIngestProgress(event: GeonamesIngestProgress, missingFile?: PathBuilderLike): string {
73
+ if (event.skipped) {
74
+ return `${event.country}: ${missingFile ? `${missingFile} missing` : "dump missing"} — download from download.geonames.org/export/dump/${event.country}.zip; skipped`
75
+ }
76
+
77
+ return `${event.country}: ${event.places.toLocaleString()} places, ${(event.aliasesRefused ?? 0).toLocaleString()} alt-names refused`
78
+ }
79
+
98
80
  interface V2Alias {
99
81
  language: string
100
82
  privateuse: string
101
83
  official: number
102
84
  }
103
85
 
104
- /**
105
- * Parse a country's alternateNamesV2 file into `geonameid -> spelling -> attribution`, restricted to the populated
106
- * places (`P`) in `wanted`.
107
- */
108
86
  async function parseAlternateNamesV2(
109
- v2File: string,
87
+ v2File: PathBuilderLike,
110
88
  cc: string,
111
89
  wanted: ReadonlySet<number>
112
90
  ): Promise<Map<number, Map<string, V2Alias>>> {
113
91
  const v2 = new Map<number, Map<string, V2Alias>>()
114
92
 
115
- // V2 columns (0-indexed): 1 geonameid, 2 isolanguage, 3 name, 4 isPreferredName, 5 isShortName,
116
- // 6 isColloquial, 7 isHistoric, 8 from, 9 to.
117
- //
118
- // Two passes, because historic-ness is a fact about the NAME, not the row: GeoNames splits one
119
- // spelling across rows — Malabo carries "Santa Isabel" as (es, unflagged) AND as (no-language,
120
- // isHistoric=1, to=1973). Officialness must see the flags from EVERY row for the spelling, or the
121
- // colonial-era name sails through on the language-tagged row (the #936 review's Malabo finding).
122
- // Do NOT condition on isPreferredName instead — it's sparse annotation, not a signal (Turku's sv "Åbo"
123
- // is unflagged; FI has 1,746 flags across the whole dump).
124
- //
125
- // Both passes STREAM the file rather than sharing one materialized array: NO's V2 dump is 33 MB,
126
- // and a second read off the page cache costs less than holding half a million line strings.
127
- // `header: false` — the dump is headerless.
128
93
  const historicNames = new Set<string>()
129
94
 
130
- for await (const f of TSVSpliterator.fromAsync(v2File, { header: false })) {
95
+ for await (const f of readUnquotedTSV(v2File)) {
131
96
  if (f[6] === "1" || f[7] === "1" || (f[9] ?? "").trim() !== "") {
132
97
  const alt = (f[3] ?? "").trim()
133
98
 
@@ -137,13 +102,12 @@ async function parseAlternateNamesV2(
137
102
  }
138
103
  }
139
104
 
140
- for await (const f of TSVSpliterator.fromAsync(v2File, { header: false })) {
105
+ for await (const f of readUnquotedTSV(v2File)) {
141
106
  const gid = Number(f[1])
142
107
 
143
108
  if (!wanted.has(gid)) continue
144
109
  const lang = f[2] ?? ""
145
110
 
146
- // ISO 639 codes are 2-3 letters; GeoNames' pseudo-codes (post, link, iata, wkdt, …) are 4+.
147
111
  if (!/^[a-z]{2,3}$/.test(lang)) continue
148
112
  const alt = (f[3] ?? "").trim()
149
113
 
@@ -176,12 +140,12 @@ async function parseAlternateNamesV2(
176
140
  }
177
141
 
178
142
  /**
179
- * Fold the GeoNames `P`-class places (+ their Latin alt-names) for `countries` into `db`'s `spr` / `names` /
180
- * `place_population` tables. Returns the total places ingested.
143
+ * Purges the fold's id range, then adds GeoNames `P`-class places and their
144
+ * alternate names for `countries` to `db`.
145
+ * It returns the number of places ingested.
181
146
  *
182
- * `onProgress` receives one event per country (default: a stderr line, matching the build scripts' legacy output). The
183
- * caller MUST rebuild `place_search` afterward (`buildPlaceSearchFTS(db, { drop: true })`) for the new names to reach
184
- * the candidate build's alias pass.
147
+ * The caller must then rebuild `place_search` with `buildPlaceSearchFTS(db, { drop: true })`
148
+ * to make the new names searchable.
185
149
  */
186
150
  export async function ingestGeonamesAliases(
187
151
  db: DatabaseClient<WOFDatabase>,
@@ -189,27 +153,11 @@ export async function ingestGeonamesAliases(
189
153
  geonamesDir: PathBuilderLike,
190
154
  onProgress?: (event: GeonamesIngestProgress) => void,
191
155
  opts?: {
192
- /**
193
- * #267: the countries for which to ALSO fold the GeoNames A-class admin (PCLI country + ADM1 regions) and link each
194
- * locality's `parent_id` + ancestry chain (locality → region → country). PER-COUNTRY because a country that already
195
- * carries WOF admin would double up — pass only the ZERO-COVERAGE gap countries (the coverage-expansion targets),
196
- * never the EU alias set. Without admin, a gap country's localities are orphans (`parent_id=-1`, no ancestors), so
197
- * `parentID` scoping and adminCoherence can't reach them and "Tbilisi, GE" can't resolve.
198
- */
199
156
  adminForCountries?: ReadonlySet<string>
200
- /**
201
- * #936: directory of per-country alternateNamesV2 dumps
202
- * (`download.geonames.org/export/dump/alternatenames/<CC>.zip` → `<CC>.txt`). When a country's file is present,
203
- * alias rows gain their language tag, `privateuse` ("preferred" from `isPreferredName`), and the `official` bit
204
- * (language is CLDR-official for the country, colloquial/historic excluded — the rule the #936 risk probe measured
205
- * at 7 new name-exact collisions globally). The main dump's bare `alternatenames` list still decides WHICH rows
206
- * exist; V2 only decorates them. Missing file = the pre-#936 untagged behavior, not an error.
207
- */
157
+
208
158
  alternateDir?: PathBuilderLike
209
159
  }
210
160
  ): Promise<number> {
211
- // Latin-only, no bracket/paren noise GeoNames packs into `alternatenames` ("(( Karis Landskommun ))",
212
- // airport codes), 2–60 chars, at least one letter (drops bare postcodes/numbers).
213
161
  const LATIN_NAME = /^[\p{Script=Latin}\p{M}\s\-'.]{2,60}$/u
214
162
 
215
163
  const clean = (s: string): string | null => {
@@ -218,6 +166,19 @@ export async function ingestGeonamesAliases(
218
166
  return t && LATIN_NAME.test(t) && /\p{L}/u.test(t) ? t : null
219
167
  }
220
168
 
169
+ const NAME_NOISE = /[()[\]{}<>|/\\_@#$%^*+=~`"]/u
170
+
171
+ const NAME_MIN_LENGTH = 2
172
+ const NAME_MAX_LENGTH = 60
173
+
174
+ const cleanAlias = (s: string): string | null => {
175
+ const t = s.trim()
176
+
177
+ return t.length >= NAME_MIN_LENGTH && t.length <= NAME_MAX_LENGTH && /\p{L}/u.test(t) && !NAME_NOISE.test(t)
178
+ ? t
179
+ : null
180
+ }
181
+
221
182
  const sprInsert = db.prepare(
222
183
  `INSERT OR REPLACE INTO spr (id, parent_id, name, placetype, country, latitude, longitude, min_latitude, min_longitude, max_latitude, max_longitude, is_current, is_deprecated, is_ceased, is_superseded, is_superseding, lastmodified) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
223
184
  )
@@ -228,23 +189,15 @@ export async function ingestGeonamesAliases(
228
189
 
229
190
  const populationInsert = db.prepare(`INSERT OR REPLACE INTO place_population (id, population) VALUES (?, ?)`)
230
191
 
231
- // #267 admin linkage: ancestor rows (locality→region→country) so parentID scoping + adminCoherence reach
232
- // the gap countries. Only used for a country in opts.adminForCountries.
233
192
  const ancestorInsert = db.prepare(
234
193
  `INSERT INTO ancestors (id, ancestor_id, ancestor_placetype, lastmodified) VALUES (?, ?, ?, 0)`
235
194
  )
236
195
 
237
- const report = (event: GeonamesIngestProgress, missingFile?: string): void => {
196
+ const report = (event: GeonamesIngestProgress, missingFile?: PathBuilderLike): void => {
238
197
  if (onProgress) {
239
198
  onProgress(event)
240
- } else if (event.skipped) {
241
- console.error(
242
- ` GeoNames ${event.country}: ${missingFile} missing — download from download.geonames.org/export/dump/${event.country}.zip; skipped`
243
- )
244
199
  } else {
245
- console.error(
246
- ` GeoNames ${event.country}: ${event.places.toLocaleString()} populated places (+ Latin alt-names)`
247
- )
200
+ console.error(` GeoNames ${formatGeonamesIngestProgress(event, missingFile)}`)
248
201
  }
249
202
  }
250
203
 
@@ -252,41 +205,29 @@ export async function ingestGeonamesAliases(
252
205
  let total = 0
253
206
  db.exec("BEGIN")
254
207
 
255
- // #1514: clear the range before writing it. Inside the transaction, so a fold that throws leaves the
256
- // DB as it found it rather than half-purged. See purgeGeonamesAliasRange for why the ids demand this.
257
208
  purgeGeonamesAliasRange(db)
258
209
 
259
210
  for (const cc of countries) {
260
- const file = join(geonamesDir, `${cc}.txt`)
211
+ const file = resolvePathBuilder(geonamesDir, `${cc}.txt`)
261
212
 
262
213
  if (!(await pathExists(file))) {
263
- report({ country: cc, places: 0, skipped: true }, file)
214
+ report({ country: cc, places: 0, skipped: true, aliasesRefused: null }, file)
264
215
 
265
216
  continue
266
217
  }
267
218
 
268
219
  let nc = 0
269
- // #267: add A-class admin + ancestry only for the gap countries this country is in (never the EU set).
220
+ let refused = 0
221
+
270
222
  const addAdmin = opts?.adminForCountries?.has(cc) ?? false
271
- const v2File = opts?.alternateDir ? join(opts.alternateDir, `${cc}.txt`) : undefined
223
+ const v2File = opts?.alternateDir ? resolvePathBuilder(opts.alternateDir, `${cc}.txt`) : undefined
272
224
  const readV2 = Boolean(v2File && (await pathExists(v2File)))
273
225
 
274
- // Survey pass. The dump is STREAMED — NO's is 71 MB and only the caller knows which country
275
- // comes next — so what a later pass needs has to be collected here rather than re-scanned off a
276
- // materialized array. Two things qualify, and both are small: the P-class geonameid set the V2
277
- // decoration is restricted to, and the handful of A-class rows the admin pre-pass writes (one
278
- // PCL* + the ADM1s). Everything else is re-read in the emit pass below. Neither is wanted
279
- // without V2 tags or admin, and then the pass is skipped rather than read for nothing.
280
- //
281
- // GeoNames dump columns (0-indexed): 0 geonameid, 1 name, 2 asciiname, 3 alternatenames, 4 lat, 5 lon,
282
- // 6 feature_class, 7 feature_code, 10 admin1 code, 14 pop.
283
- //
284
- // `header: false` — the dump is headerless, so row 1 is a place, not column names.
285
226
  const wanted = new Set<number>()
286
227
  const adminRows: string[][] = []
287
228
 
288
229
  if (readV2 || addAdmin) {
289
- for await (const f of TSVSpliterator.fromAsync(file, { header: false })) {
230
+ for await (const f of readUnquotedTSV(file)) {
290
231
  if (f[6] === "P") {
291
232
  if (readV2) {
292
233
  wanted.add(Number(f[0]))
@@ -301,13 +242,8 @@ export async function ingestGeonamesAliases(
301
242
  }
302
243
  }
303
244
 
304
- // #936: V2 tags for this country's P-class rows — geonameid → exact alias spelling → tag. The V2
305
- // dump repeats one spelling under several languages ("Åbo" sv/da/no); the merged tag is official /
306
- // preferred if ANY qualifying row is.
307
245
  const v2 = readV2 ? await parseAlternateNamesV2(v2File!, cc, wanted) : undefined
308
246
 
309
- // #267 admin pre-pass (gap countries): fold the country (PCLI) + regions (ADM1), self+ancestry them, and
310
- // build the admin1→region map the localities link through. Point bbox (GeoNames gives a centroid only).
311
247
  let countryID = -1
312
248
  const adminMap = new Map<string, number>()
313
249
 
@@ -320,10 +256,7 @@ export async function ingestGeonamesAliases(
320
256
  const lon = Number(f[5]) || 0
321
257
 
322
258
  if (f[7]?.startsWith("PCL")) {
323
- // Any country-level political entity — PCLI (independent), PCLD (dependent territory),
324
- // PCLF (freely associated), PCLS (special administrative region: HK/MO/PS). All are the
325
- // country tier; restricting to PCLI left those ~17 territories without a country row.
326
- if (countryID >= 0) continue // one country row
259
+ if (countryID >= 0) continue
327
260
  countryID = id++
328
261
  sprInsert.run(countryID, -1, aname, "country", cc, lat, lon, lat, lon, lat, lon, 1, 0, 0, 0, 0, 0)
329
262
  namesInsert.run(countryID, aname, "country", cc, "", "", 0, 0)
@@ -337,7 +270,6 @@ export async function ingestGeonamesAliases(
337
270
  }
338
271
  }
339
272
 
340
- // Re-parent regions + ancestor them to the (now-known) country.
341
273
  if (countryID >= 0) {
342
274
  for (const rid of adminMap.values()) {
343
275
  db.prepare("UPDATE spr SET parent_id = ? WHERE id = ?").run(countryID, rid)
@@ -346,9 +278,8 @@ export async function ingestGeonamesAliases(
346
278
  }
347
279
  }
348
280
 
349
- // Emit pass — a second stream over the same file, off the page cache the survey pass just warmed.
350
- for await (const f of TSVSpliterator.fromAsync(file, { header: false })) {
351
- if (f[6] !== "P") continue // populated places only
281
+ for await (const f of readUnquotedTSV(file)) {
282
+ if (f[6] !== "P") continue
352
283
  const lat = Number(f[4])
353
284
  const lon = Number(f[5])
354
285
 
@@ -357,19 +288,13 @@ export async function ingestGeonamesAliases(
357
288
 
358
289
  if (!name) continue
359
290
  const nid = id++
360
- // #267: link to the locality's region (else country) for gap countries; -1 (orphan) otherwise.
291
+
361
292
  const regionID = addAdmin ? (adminMap.get(f[10] ?? "") ?? -1) : -1
362
293
  const parentID = regionID >= 0 ? regionID : addAdmin && countryID >= 0 ? countryID : -1
363
- // Point bbox — a GeoNames row is a centroid; the candidate's region-bbox disambiguation just
364
- // sees it as contained in itself, fine for a locality.
294
+
365
295
  sprInsert.run(nid, parentID, name, "locality", cc, lat, lon, lat, lon, lat, lon, 1, 0, 0, 0, 0, 0)
366
296
  namesInsert.run(nid, name, "locality", cc, "", "", 0, 0)
367
297
 
368
- // The SELF row is unconditional (#1514). `populateAncestors` writes one for every spr row it
369
- // sees, so a full build's freeze phase produces it either way — but the freeze does not run on
370
- // the fold-on-copy path, and since the purge now clears this range the fold has to emit
371
- // everything the closure would. Measured on the 161-country fold: 212,993 self rows, exactly the
372
- // non-gap countries' localities, which is what the base artifact carried and a fold-on-copy lost.
373
298
  ancestorInsert.run(nid, nid, "locality")
374
299
 
375
300
  if (addAdmin) {
@@ -387,7 +312,11 @@ export async function ingestGeonamesAliases(
387
312
  const tags = v2?.get(Number(f[0]))
388
313
 
389
314
  for (const raw of [f[2] ?? "", ...(f[3] ? f[3].split(",") : [])]) {
390
- const alt = clean(raw)
315
+ const alt = cleanAlias(raw)
316
+
317
+ if (!alt && raw.trim()) {
318
+ refused++
319
+ }
391
320
 
392
321
  if (alt && !seen.has(alt)) {
393
322
  seen.add(alt)
@@ -406,7 +335,7 @@ export async function ingestGeonamesAliases(
406
335
  nc++
407
336
  }
408
337
 
409
- report({ country: cc, places: nc, skipped: false })
338
+ report({ country: cc, places: nc, skipped: false, aliasesRefused: refused })
410
339
  total += nc
411
340
  }
412
341