@finbheara/domain 0.5.0 → 0.6.2

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.
@@ -2,6 +2,8 @@ import {
2
2
  validity
3
3
  } from "./place-q9kwsmzd.js";
4
4
 
5
+ import { isPlaceholderPrint } from "@finbheara/names/normalize";
6
+
5
7
  var PLACE_NODES = [
6
8
  {
7
9
  id: "world",
@@ -164,9 +166,11 @@ var PLACE_NODES = [
164
166
  "serc",
165
167
  "southern england",
166
168
  "southern region",
167
- "southern region england"
169
+ "southern region england",
170
+ "southern region uk"
168
171
  ],
169
172
  codes: ["ENG_SOUTH"],
173
+ headings: ["southern"],
170
174
  truncations: ["southern regi", "southern regio"],
171
175
  oireachtas: "ENG_SOUTH"
172
176
  },
@@ -306,7 +310,7 @@ var PLACE_NODES = [
306
310
  name: "New Zealand",
307
311
  geo: "NZL",
308
312
  admin: "world",
309
- prints: ["tidanz"],
313
+ prints: ["nua shealainn new zealand", "tidanz"],
310
314
  codes: [],
311
315
  oireachtas: "NZ"
312
316
  },
@@ -316,7 +320,14 @@ var PLACE_NODES = [
316
320
  name: "Continental Europe & Asia (RCCEA)",
317
321
  geo: null,
318
322
  admin: "world",
319
- prints: ["an eoraip", "continental europe and asia", "eoraip", "rccea", "rtme"],
323
+ prints: [
324
+ "an eoraip",
325
+ "an eoraip europe",
326
+ "continental europe and asia",
327
+ "eoraip",
328
+ "rccea",
329
+ "rtme"
330
+ ],
320
331
  codes: ["RCCEA"],
321
332
  oireachtas: "RCCEA"
322
333
  },
@@ -336,7 +347,7 @@ var PLACE_NODES = [
336
347
  name: "South Africa",
337
348
  geo: "ZAF",
338
349
  admin: "world",
339
- prints: [],
350
+ prints: ["an afraic theas south africa"],
340
351
  codes: ["SOUTH_AFRICA"],
341
352
  oireachtas: "SOUTH_AFRICA"
342
353
  },
@@ -2635,7 +2646,7 @@ var PLACE_NODES = [
2635
2646
  name: "Russia",
2636
2647
  geo: "europe",
2637
2648
  admin: "RCCEA",
2638
- prints: ["rus", "russia"],
2649
+ prints: ["an ruis russia", "rus", "russia", "russia ruisis"],
2639
2650
  codes: [],
2640
2651
  iso2: "RU",
2641
2652
  iso3: "RUS",
@@ -3378,7 +3389,8 @@ var PLACE_NODES = [
3378
3389
  geo: "AUS",
3379
3390
  admin: "AUSTRALIA",
3380
3391
  prints: ["northern territory"],
3381
- codes: ["AU-NT", "AUS-NT", "NT"]
3392
+ codes: ["AU-NT", "AUS-NT", "NT"],
3393
+ headings: ["nothern territory"]
3382
3394
  },
3383
3395
  {
3384
3396
  id: "AUS-QLD",
@@ -3396,7 +3408,8 @@ var PLACE_NODES = [
3396
3408
  geo: "AUS",
3397
3409
  admin: "AUSTRALIA",
3398
3410
  prints: ["deisceart na hastraile", "reigiun deisceart na hastraile", "south australia"],
3399
- codes: ["AU-SA", "AUS-SA", "SA"]
3411
+ codes: ["AU-SA", "AUS-SA", "SA"],
3412
+ headings: ["south"]
3400
3413
  },
3401
3414
  {
3402
3415
  id: "AUS-TAS",
@@ -3428,7 +3441,8 @@ var PLACE_NODES = [
3428
3441
  "reigiun iarrthar na hastraile",
3429
3442
  "western australia"
3430
3443
  ],
3431
- codes: ["AU-WA", "AUS-WA", "WA"]
3444
+ codes: ["AU-WA", "AUS-WA", "WA"],
3445
+ headings: ["western"]
3432
3446
  },
3433
3447
  {
3434
3448
  id: "CAN-AB",
@@ -3869,6 +3883,15 @@ var PLACE_NODES = [
3869
3883
  prints: ["co wexford", "county wexford", "wexford"],
3870
3884
  codes: ["IE-WX"]
3871
3885
  },
3886
+ {
3887
+ id: "MEX-QUE",
3888
+ kind: "subdivision",
3889
+ name: "Querétaro",
3890
+ geo: "MEX",
3891
+ admin: null,
3892
+ prints: ["queretaro"],
3893
+ codes: ["MX-QUE"]
3894
+ },
3872
3895
  {
3873
3896
  id: "USA-AK",
3874
3897
  kind: "subdivision",
@@ -4538,6 +4561,15 @@ var PLACE_NODES = [
4538
4561
  prints: ["winnipeg"],
4539
4562
  codes: []
4540
4563
  },
4564
+ {
4565
+ id: "CAN-NB/fredericton",
4566
+ kind: "city",
4567
+ name: "Fredericton",
4568
+ geo: "CAN-NB",
4569
+ admin: "IDTANA-ECRO",
4570
+ prints: ["fredericton"],
4571
+ codes: []
4572
+ },
4541
4573
  {
4542
4574
  id: "CAN-NS/halifax",
4543
4575
  kind: "city",
@@ -4592,6 +4624,15 @@ var PLACE_NODES = [
4592
4624
  prints: ["mississauga"],
4593
4625
  codes: []
4594
4626
  },
4627
+ {
4628
+ id: "CAN-ON/niagara-falls",
4629
+ kind: "city",
4630
+ name: "Niagara Falls",
4631
+ geo: "CAN-ON",
4632
+ admin: "IDTANA-ECRO",
4633
+ prints: ["niagara falls"],
4634
+ codes: []
4635
+ },
4595
4636
  {
4596
4637
  id: "CAN-ON/oakville",
4597
4638
  kind: "city",
@@ -4637,13 +4678,31 @@ var PLACE_NODES = [
4637
4678
  prints: ["toronto"],
4638
4679
  codes: []
4639
4680
  },
4681
+ {
4682
+ id: "CAN-ON/whitby",
4683
+ kind: "city",
4684
+ name: "Whitby",
4685
+ geo: "CAN-ON",
4686
+ admin: "IDTANA-ECRO",
4687
+ prints: ["whitby"],
4688
+ codes: []
4689
+ },
4640
4690
  {
4641
4691
  id: "CAN-ON/windsor",
4642
4692
  kind: "city",
4643
4693
  name: "Windsor",
4644
4694
  geo: "CAN-ON",
4645
4695
  admin: "IDTANA-ECRO",
4646
- prints: ["windsor"],
4696
+ prints: ["windsor", "winsor"],
4697
+ codes: []
4698
+ },
4699
+ {
4700
+ id: "CAN-QC/hudson",
4701
+ kind: "city",
4702
+ name: "Hudson",
4703
+ geo: "CAN-QC",
4704
+ admin: "IDTANA-ECRO",
4705
+ prints: ["hudson"],
4647
4706
  codes: []
4648
4707
  },
4649
4708
  {
@@ -4701,6 +4760,15 @@ var PLACE_NODES = [
4701
4760
  prints: ["berlin"],
4702
4761
  codes: []
4703
4762
  },
4763
+ {
4764
+ id: "DEU/landstuhl",
4765
+ kind: "city",
4766
+ name: "Landstuhl",
4767
+ geo: "DEU",
4768
+ admin: "RCCEA",
4769
+ prints: ["landstuhl"],
4770
+ codes: []
4771
+ },
4704
4772
  {
4705
4773
  id: "ESP/barcelona",
4706
4774
  kind: "city",
@@ -5223,6 +5291,15 @@ var PLACE_NODES = [
5223
5291
  prints: ["bay area"],
5224
5292
  codes: []
5225
5293
  },
5294
+ {
5295
+ id: "USA-CA/danville",
5296
+ kind: "city",
5297
+ name: "Danville",
5298
+ geo: "USA-CA",
5299
+ admin: "IDTANA-WUSRO",
5300
+ prints: ["danville"],
5301
+ codes: []
5302
+ },
5226
5303
  {
5227
5304
  id: "USA-CA/dublin",
5228
5305
  kind: "city",
@@ -5332,6 +5409,15 @@ var PLACE_NODES = [
5332
5409
  prints: ["wilmington"],
5333
5410
  codes: []
5334
5411
  },
5412
+ {
5413
+ id: "USA-DE/yorklyn",
5414
+ kind: "city",
5415
+ name: "Yorklyn",
5416
+ geo: "USA-DE",
5417
+ admin: "IDTANA-MARO",
5418
+ prints: ["yorklyn"],
5419
+ codes: []
5420
+ },
5335
5421
  {
5336
5422
  id: "USA-FL/gainesville",
5337
5423
  kind: "city",
@@ -5350,6 +5436,15 @@ var PLACE_NODES = [
5350
5436
  prints: ["jacksonville"],
5351
5437
  codes: []
5352
5438
  },
5439
+ {
5440
+ id: "USA-FL/kissimmee",
5441
+ kind: "city",
5442
+ name: "Kissimmee",
5443
+ geo: "USA-FL",
5444
+ admin: "IDTANA-SRO",
5445
+ prints: ["kissimmee"],
5446
+ codes: []
5447
+ },
5353
5448
  {
5354
5449
  id: "USA-FL/miami",
5355
5450
  kind: "city",
@@ -5404,6 +5499,15 @@ var PLACE_NODES = [
5404
5499
  prints: ["tampa"],
5405
5500
  codes: []
5406
5501
  },
5502
+ {
5503
+ id: "USA-FL/winter-garden",
5504
+ kind: "city",
5505
+ name: "Winter Garden",
5506
+ geo: "USA-FL",
5507
+ admin: "IDTANA-SRO",
5508
+ prints: ["winter garden"],
5509
+ codes: []
5510
+ },
5407
5511
  {
5408
5512
  id: "USA-GA/atlanta",
5409
5513
  kind: "city",
@@ -5458,6 +5562,33 @@ var PLACE_NODES = [
5458
5562
  prints: ["chicago"],
5459
5563
  codes: []
5460
5564
  },
5565
+ {
5566
+ id: "USA-IL/lemont",
5567
+ kind: "city",
5568
+ name: "Lemont",
5569
+ geo: "USA-IL",
5570
+ admin: "IDTANA-MAO",
5571
+ prints: ["lemont"],
5572
+ codes: []
5573
+ },
5574
+ {
5575
+ id: "USA-IL/niles",
5576
+ kind: "city",
5577
+ name: "Niles",
5578
+ geo: "USA-IL",
5579
+ admin: "IDTANA-MAO",
5580
+ prints: ["niles"],
5581
+ codes: []
5582
+ },
5583
+ {
5584
+ id: "USA-IL/o-fallon",
5585
+ kind: "city",
5586
+ name: "O'Fallon",
5587
+ geo: "USA-IL",
5588
+ admin: "IDTANA-MAO",
5589
+ prints: ["o fallon"],
5590
+ codes: []
5591
+ },
5461
5592
  {
5462
5593
  id: "USA-IL/springfield",
5463
5594
  kind: "city",
@@ -5539,6 +5670,15 @@ var PLACE_NODES = [
5539
5670
  prints: ["lexington"],
5540
5671
  codes: []
5541
5672
  },
5673
+ {
5674
+ id: "USA-MA/quincy",
5675
+ kind: "city",
5676
+ name: "Quincy",
5677
+ geo: "USA-MA",
5678
+ admin: "IDTANA-NERO",
5679
+ prints: ["quincy"],
5680
+ codes: []
5681
+ },
5542
5682
  {
5543
5683
  id: "USA-MA/springfield",
5544
5684
  kind: "city",
@@ -5576,6 +5716,24 @@ var PLACE_NODES = [
5576
5716
  codes: [],
5577
5717
  truncations: ["baltimor"]
5578
5718
  },
5719
+ {
5720
+ id: "USA-MD/columbia",
5721
+ kind: "city",
5722
+ name: "Columbia",
5723
+ geo: "USA-MD",
5724
+ admin: "IDTANA-SRO",
5725
+ prints: ["columbia"],
5726
+ codes: []
5727
+ },
5728
+ {
5729
+ id: "USA-MD/salisbury",
5730
+ kind: "city",
5731
+ name: "Salisbury",
5732
+ geo: "USA-MD",
5733
+ admin: "IDTANA-SRO",
5734
+ prints: ["salisbury"],
5735
+ codes: []
5736
+ },
5579
5737
  {
5580
5738
  id: "USA-ME/portland",
5581
5739
  kind: "city",
@@ -5711,6 +5869,16 @@ var PLACE_NODES = [
5711
5869
  prints: ["greensboro"],
5712
5870
  codes: []
5713
5871
  },
5872
+ {
5873
+ id: "USA-NC/mooresville",
5874
+ kind: "city",
5875
+ name: "Mooresville",
5876
+ geo: "USA-NC",
5877
+ admin: "IDTANA-SRO",
5878
+ prints: ["mooresville"],
5879
+ codes: [],
5880
+ listedCutsOnly: true
5881
+ },
5714
5882
  {
5715
5883
  id: "USA-NC/raleigh",
5716
5884
  kind: "city",
@@ -5774,6 +5942,15 @@ var PLACE_NODES = [
5774
5942
  prints: ["trenton"],
5775
5943
  codes: []
5776
5944
  },
5945
+ {
5946
+ id: "USA-NJ/wall-township",
5947
+ kind: "city",
5948
+ name: "Wall Township",
5949
+ geo: "USA-NJ",
5950
+ admin: "IDTANA-MARO",
5951
+ prints: ["wall township"],
5952
+ codes: []
5953
+ },
5777
5954
  {
5778
5955
  id: "USA-NM/albuquerque",
5779
5956
  kind: "city",
@@ -5783,6 +5960,15 @@ var PLACE_NODES = [
5783
5960
  prints: ["albuquerque"],
5784
5961
  codes: []
5785
5962
  },
5963
+ {
5964
+ id: "USA-NM/rio-rancho",
5965
+ kind: "city",
5966
+ name: "Rio Rancho",
5967
+ geo: "USA-NM",
5968
+ admin: "IDTANA-WUSRO",
5969
+ prints: ["rio rancho"],
5970
+ codes: []
5971
+ },
5786
5972
  {
5787
5973
  id: "USA-NM/santa-fe",
5788
5974
  kind: "city",
@@ -5819,6 +6005,15 @@ var PLACE_NODES = [
5819
6005
  prints: ["albany"],
5820
6006
  codes: []
5821
6007
  },
6008
+ {
6009
+ id: "USA-NY/baldwin-place",
6010
+ kind: "city",
6011
+ name: "Baldwin Place",
6012
+ geo: "USA-NY",
6013
+ admin: "IDTANA-MARO",
6014
+ prints: ["baldwin place"],
6015
+ codes: []
6016
+ },
5822
6017
  {
5823
6018
  id: "USA-NY/buffalo",
5824
6019
  kind: "city",
@@ -5828,6 +6023,15 @@ var PLACE_NODES = [
5828
6023
  prints: ["buffalo"],
5829
6024
  codes: []
5830
6025
  },
6026
+ {
6027
+ id: "USA-NY/grand-island",
6028
+ kind: "city",
6029
+ name: "Grand Island",
6030
+ geo: "USA-NY",
6031
+ admin: "IDTANA-MARO",
6032
+ prints: ["grand island"],
6033
+ codes: []
6034
+ },
5831
6035
  {
5832
6036
  id: "USA-NY/kingston",
5833
6037
  kind: "city",
@@ -5900,6 +6104,15 @@ var PLACE_NODES = [
5900
6104
  prints: ["syracuse"],
5901
6105
  codes: []
5902
6106
  },
6107
+ {
6108
+ id: "USA-NY/webster",
6109
+ kind: "city",
6110
+ name: "Webster",
6111
+ geo: "USA-NY",
6112
+ admin: "IDTANA-MARO",
6113
+ prints: ["webster"],
6114
+ codes: []
6115
+ },
5903
6116
  {
5904
6117
  id: "USA-OH/akron",
5905
6118
  kind: "city",
@@ -5954,6 +6167,15 @@ var PLACE_NODES = [
5954
6167
  prints: ["dublin"],
5955
6168
  codes: []
5956
6169
  },
6170
+ {
6171
+ id: "USA-OH/richfield",
6172
+ kind: "city",
6173
+ name: "Richfield",
6174
+ geo: "USA-OH",
6175
+ admin: "IDTANA-MAO",
6176
+ prints: ["richfield"],
6177
+ codes: []
6178
+ },
5957
6179
  {
5958
6180
  id: "USA-OH/toledo",
5959
6181
  kind: "city",
@@ -6017,6 +6239,16 @@ var PLACE_NODES = [
6017
6239
  prints: ["ardmore"],
6018
6240
  codes: []
6019
6241
  },
6242
+ {
6243
+ id: "USA-PA/erie",
6244
+ kind: "city",
6245
+ name: "Erie",
6246
+ geo: "USA-PA",
6247
+ admin: "IDTANA-MARO",
6248
+ prints: ["erie"],
6249
+ codes: [],
6250
+ runPrints: ["eire"]
6251
+ },
6020
6252
  {
6021
6253
  id: "USA-PA/lancaster",
6022
6254
  kind: "city",
@@ -6189,6 +6421,15 @@ var PLACE_NODES = [
6189
6421
  prints: ["north texas"],
6190
6422
  codes: []
6191
6423
  },
6424
+ {
6425
+ id: "USA-TX/richardson",
6426
+ kind: "city",
6427
+ name: "Richardson",
6428
+ geo: "USA-TX",
6429
+ admin: "IDTANA-SRO",
6430
+ prints: ["richardson"],
6431
+ codes: []
6432
+ },
6192
6433
  {
6193
6434
  id: "USA-TX/san-antonio",
6194
6435
  kind: "city",
@@ -6207,6 +6448,15 @@ var PLACE_NODES = [
6207
6448
  prints: ["south texas"],
6208
6449
  codes: []
6209
6450
  },
6451
+ {
6452
+ id: "USA-UT/cedar-hills",
6453
+ kind: "city",
6454
+ name: "Cedar Hills",
6455
+ geo: "USA-UT",
6456
+ admin: "IDTANA-WUSRO",
6457
+ prints: ["cedar hills"],
6458
+ codes: []
6459
+ },
6210
6460
  {
6211
6461
  id: "USA-UT/salt-lake-city",
6212
6462
  kind: "city",
@@ -6306,6 +6556,15 @@ var PLACE_NODES = [
6306
6556
  prints: ["burlington"],
6307
6557
  codes: []
6308
6558
  },
6559
+ {
6560
+ id: "USA-WA/lynnwood",
6561
+ kind: "city",
6562
+ name: "Lynnwood",
6563
+ geo: "USA-WA",
6564
+ admin: "IDTANA-WUSRO",
6565
+ prints: ["lynnwood"],
6566
+ codes: []
6567
+ },
6309
6568
  {
6310
6569
  id: "USA-WA/olympia",
6311
6570
  kind: "city",
@@ -6362,6 +6621,135 @@ var PLACE_NODES = [
6362
6621
  }
6363
6622
  ];
6364
6623
 
6624
+ var QUALIFIER_DELIMITER = /[,;:()[\]/–—-]/;
6625
+ var NEVER_PLACE = new Map([
6626
+ ["de", "name particle: `De <Surname>`, and Spanish `de <Place>`"],
6627
+ ["ni", "Irish patronymic particle: `Ní <Surname>`"],
6628
+ ["mo", "Irish possessive: `Mo <Word>`"],
6629
+ ["na", "Irish article: `Rince na <Word>`"],
6630
+ ["in", "Irish preposition: `<Word> In <Word>`; and `Inc` truncated to `In`"],
6631
+ ["co", "Company: `<Surname> & Co.`. Bracketed `(US-CO)` is still Colorado"],
6632
+ ["id", "Irish Dance: `<Surname> School of ID`"],
6633
+ ["sd", "School of Dance: `<Surname> SD`"]
6634
+ ]);
6635
+ var NEVER_NAME = new Map([
6636
+ ["de", "name particle: `De <Surname>`; and Spanish `de <Place>`"],
6637
+ ["ni", "Irish patronymic particle: `Ní <Surname>`"],
6638
+ ["ui", "Irish patronymic particle: `Uí <Surname>`"],
6639
+ ["mo", "Irish possessive: `Mo <Word>`"],
6640
+ ["na", "Irish article: `Rince na <Word>`"],
6641
+ ["an", "Irish article: `<Word> an Rince`"],
6642
+ ["in", "Irish preposition: `<Word> In <Word>`; and `Inc` truncated to `In`"],
6643
+ ["co", "Company: `<Surname> & Co`"],
6644
+ ["id", "Irish Dance: `ID de <Place>` keys the place, as `Irish Dancing de <Place>` does"],
6645
+ ["sd", "School of Dance: `<Surname> SD`"],
6646
+ ["da", "`Dance` truncated: `<Name> Academy of Irish Da` keys the name"]
6647
+ ]);
6648
+ var GENERIC_TLD = "com|net|org|edu|gov|mil|int|info|biz";
6649
+ var WEB_SPAN = new RegExp([
6650
+ "[A-Za-z][A-Za-z0-9+.-]*://\\S+",
6651
+ "(?:^|[\\s([])www\\.\\S+",
6652
+ "[^\\s@]+@[^\\s@]+\\.[A-Za-z]{2,}",
6653
+ `(?<![A-Za-z0-9.@-])(?:[A-Za-z0-9][A-Za-z0-9-]*\\.)*[A-Za-z0-9][A-Za-z0-9-]+\\.(?:${GENERIC_TLD})(?![A-Za-z0-9-])`
6654
+ ].join("|"), "giu");
6655
+ function printsWeb(raw) {
6656
+ for (const _ of raw.matchAll(WEB_SPAN))
6657
+ return true;
6658
+ return false;
6659
+ }
6660
+ function printZones(raw) {
6661
+ const qualifier = new Set;
6662
+ const bracketed = new Set;
6663
+ const qualifierAny = new Set;
6664
+ const runs = [...raw.matchAll(/[A-Za-z0-9]+/g)];
6665
+ const web = [];
6666
+ for (const m of raw.matchAll(WEB_SPAN))
6667
+ web.push([m.index ?? 0, (m.index ?? 0) + m[0].length]);
6668
+ const inside = new Set;
6669
+ const outside = new Set;
6670
+ const trailing = new Set;
6671
+ for (let i = runs.length - 1;i > 0; i--) {
6672
+ const here = runs[i];
6673
+ const prev = runs[i - 1];
6674
+ if (here === undefined || prev === undefined)
6675
+ break;
6676
+ const gap = raw.slice((prev.index ?? 0) + prev[0].length, here.index ?? 0);
6677
+ if (!QUALIFIER_DELIMITER.test(gap))
6678
+ break;
6679
+ if (i - 1 === 0)
6680
+ break;
6681
+ trailing.add(i - 1);
6682
+ }
6683
+ let depth = 0;
6684
+ let cursor = 0;
6685
+ for (let i = 0;i < runs.length; i++) {
6686
+ const run = runs[i];
6687
+ const text = run?.[0];
6688
+ if (run === undefined || text === undefined)
6689
+ continue;
6690
+ const at = run.index ?? cursor;
6691
+ for (const ch of raw.slice(cursor, at)) {
6692
+ if (ch === "(" || ch === "[")
6693
+ depth++;
6694
+ else if ((ch === ")" || ch === "]") && depth > 0)
6695
+ depth--;
6696
+ }
6697
+ cursor = at + text.length;
6698
+ const folded = text.toLowerCase().normalize("NFD").replace(/[̀-ͯ]/g, "");
6699
+ (web.some(([s, e]) => at >= s && at < e) ? inside : outside).add(folded);
6700
+ const before = raw.slice(0, at).trimEnd().slice(-1);
6701
+ const after = raw.slice(cursor).trimStart().slice(0, 1);
6702
+ const atQualifier = i === runs.length - 1 || before !== "" && QUALIFIER_DELIMITER.test(before) || after !== "" && QUALIFIER_DELIMITER.test(after) && trailing.has(i);
6703
+ if (atQualifier)
6704
+ qualifierAny.add(folded);
6705
+ if (folded.length > 2)
6706
+ continue;
6707
+ if (atQualifier)
6708
+ qualifier.add(folded);
6709
+ if (depth > 0)
6710
+ bracketed.add(folded);
6711
+ }
6712
+ const webOnly = new Set([...inside].filter((f) => !outside.has(f)));
6713
+ return { qualifier, bracketed, qualifierAny, web, webOnly, tailCode: tailCode(raw, runs) };
6714
+ }
6715
+ var GOVERNS_THE_NEXT_WORD = new Set(["de", "mo"]);
6716
+ function tailCode(raw, runs) {
6717
+ const last = runs[runs.length - 1];
6718
+ const prev = runs[runs.length - 2];
6719
+ if (last === undefined || prev === undefined)
6720
+ return null;
6721
+ const text = last[0];
6722
+ if (text.length > 2 || text !== text.toUpperCase() || !/^[A-Z]+$/.test(text))
6723
+ return null;
6724
+ const at = last.index ?? 0;
6725
+ const folded = text.toLowerCase();
6726
+ const gap = raw.slice((prev.index ?? 0) + prev[0].length, at);
6727
+ const marked = /[,;:/\\\u2013\u2014]/u.test(gap) || /\s-|-\s/u.test(gap);
6728
+ const bare = GOVERNS_THE_NEXT_WORD.has(folded) && /^\s+$/u.test(gap) && /\p{Ll}/u.test(raw);
6729
+ if (!marked && !bare)
6730
+ return null;
6731
+ const only = runs.filter((r) => r[0].toLowerCase() === folded).length === 1;
6732
+ return { folded, at, only };
6733
+ }
6734
+ function opensLocation(folded, at, index) {
6735
+ if (index === undefined ? at.webOnly.has(folded) : inWebSpan(at, index))
6736
+ return false;
6737
+ if (folded.length > 2)
6738
+ return true;
6739
+ if (NEVER_PLACE.has(folded))
6740
+ return at.bracketed.has(folded) || isTailCode(folded, at, index);
6741
+ return at.qualifier.has(folded);
6742
+ }
6743
+ function isTailCode(folded, at, index) {
6744
+ const tail = at.tailCode;
6745
+ if (tail === null || tail.folded !== folded)
6746
+ return false;
6747
+ return index === undefined ? tail.only : index === tail.at;
6748
+ }
6749
+ function inWebSpan(at, index) {
6750
+ return at.web.some(([start, end]) => index >= start && index < end);
6751
+ }
6752
+
6365
6753
  var DEFAULT_PLACE_CAPACITY2 = 8192;
6366
6754
  function createPlaceReader2(options = {}) {
6367
6755
  const nodes = options.tree ?? PLACE_NODES;
@@ -6380,8 +6768,34 @@ function createPlaceReader2(options = {}) {
6380
6768
  "none",
6381
6769
  "null",
6382
6770
  "tbd",
6383
- "unknown"
6771
+ "unknown",
6772
+ "address withheld"
6773
+ ]);
6774
+ const ONLINE = new Set([
6775
+ "online",
6776
+ "online feis",
6777
+ "video feis",
6778
+ "virtual",
6779
+ "virtual feis"
6384
6780
  ]);
6781
+ const NOTICE = "change of location";
6782
+ function garbageOf(print) {
6783
+ const raw = repair(print);
6784
+ if (raw === "")
6785
+ return;
6786
+ if (raw.includes("�"))
6787
+ return "damaged";
6788
+ if (printsWeb(raw))
6789
+ return "web";
6790
+ const folded = fold(raw);
6791
+ if (ONLINE.has(folded))
6792
+ return "online";
6793
+ if (folded === NOTICE || folded.startsWith(`${NOTICE} `))
6794
+ return "notice";
6795
+ if (isPlaceholderPrint(raw))
6796
+ return "placeholder";
6797
+ return;
6798
+ }
6385
6799
  function fold(s) {
6386
6800
  return s.normalize("NFD").replace(/\p{M}+/gu, "").toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
6387
6801
  }
@@ -6411,7 +6825,13 @@ function createPlaceReader2(options = {}) {
6411
6825
  const bySubdivisionPart = new Map;
6412
6826
  const byOireachtas = new Map;
6413
6827
  const listedPhrases = new Set;
6828
+ const byHeading = new Map;
6829
+ const byRunPrint = new Map;
6414
6830
  for (const n of source) {
6831
+ for (const h of n.headings ?? [])
6832
+ push(byHeading, fold(h), n);
6833
+ for (const r of n.runPrints ?? [])
6834
+ push(byRunPrint, fold(r), n);
6415
6835
  push(byPrint, fold(n.id), n);
6416
6836
  if (n.kind !== "body")
6417
6837
  push(byPrint, fold(n.name), n);
@@ -6444,28 +6864,50 @@ function createPlaceReader2(options = {}) {
6444
6864
  push(bySubdivisionPart, fold(p), n);
6445
6865
  }
6446
6866
  }
6447
- const ancestorsOf = new Map;
6448
- const walk = (n, seen) => {
6449
- const had = ancestorsOf.get(n.id);
6450
- if (had !== undefined)
6451
- return had;
6452
- const out = new Set;
6867
+ const geoAbove = (n, target) => {
6868
+ const seen = new Set;
6869
+ for (let at = n.geo;at !== null && !seen.has(at); ) {
6870
+ if (at === target)
6871
+ return true;
6872
+ seen.add(at);
6873
+ at = byId.get(at)?.geo ?? null;
6874
+ }
6875
+ return false;
6876
+ };
6877
+ const carries = new Map;
6878
+ const upOf = (n) => {
6879
+ const out = [];
6453
6880
  for (const up of [n.geo, n.admin]) {
6454
- if (up === null || up === undefined || seen.has(up))
6881
+ if (up === null || up === undefined)
6455
6882
  continue;
6456
6883
  const parent = byId.get(up);
6457
6884
  if (parent === undefined)
6458
6885
  continue;
6459
- out.add(parent.id);
6460
- seen.add(parent.id);
6461
- for (const id of walk(parent, seen))
6462
- out.add(id);
6886
+ if (up === n.admin && geoAbove(parent, n.id)) {
6887
+ carries.set(n.id, [...carries.get(n.id) ?? [], parent]);
6888
+ continue;
6889
+ }
6890
+ out.push(parent);
6463
6891
  }
6464
- ancestorsOf.set(n.id, out);
6465
6892
  return out;
6466
6893
  };
6894
+ const parents = new Map;
6467
6895
  for (const n of source)
6468
- walk(n, new Set([n.id]));
6896
+ parents.set(n.id, upOf(n));
6897
+ const ancestorsOf = new Map;
6898
+ for (const n of source) {
6899
+ const out = new Set;
6900
+ const todo = [n];
6901
+ for (let at = todo.pop();at !== undefined; at = todo.pop()) {
6902
+ for (const parent of parents.get(at.id) ?? []) {
6903
+ if (parent.id === n.id || out.has(parent.id))
6904
+ continue;
6905
+ out.add(parent.id);
6906
+ todo.push(parent);
6907
+ }
6908
+ }
6909
+ ancestorsOf.set(n.id, out);
6910
+ }
6469
6911
  const phrases = [...byPrint.keys()].filter((k) => k.includes(" ")).sort((a, b) => b.length - a.length);
6470
6912
  return {
6471
6913
  byId,
@@ -6476,8 +6918,11 @@ function createPlaceReader2(options = {}) {
6476
6918
  bySubdivisionPart,
6477
6919
  byOireachtas,
6478
6920
  ancestorsOf,
6921
+ carries,
6479
6922
  phrases,
6480
- listedPhrases
6923
+ listedPhrases,
6924
+ byHeading,
6925
+ byRunPrint
6481
6926
  };
6482
6927
  }
6483
6928
  function idx() {
@@ -6598,6 +7043,10 @@ function createPlaceReader2(options = {}) {
6598
7043
  if (n !== undefined && CARRIED.has(n.kind))
6599
7044
  out.set(n.id, n);
6600
7045
  }
7046
+ for (const n of [...out.values()])
7047
+ for (const r of idx().carries.get(n.id) ?? [])
7048
+ if (CARRIED.has(r.kind))
7049
+ out.set(r.id, r);
6601
7050
  return { head, nodes: ordered([...out.values()]) };
6602
7051
  }
6603
7052
  const NOTHING = { heads: [], match: null, truncated: false, refusal: null };
@@ -6714,7 +7163,7 @@ function createPlaceReader2(options = {}) {
6714
7163
  if (key[folded.length] === " ")
6715
7164
  continue;
6716
7165
  for (const n of found)
6717
- if (n.kind !== "body")
7166
+ if (n.kind !== "body" && n.listedCutsOnly !== true)
6718
7167
  out.push({ node: n, length: key.length });
6719
7168
  }
6720
7169
  return out;
@@ -6910,7 +7359,55 @@ function createPlaceReader2(options = {}) {
6910
7359
  }
6911
7360
  return;
6912
7361
  }
6913
- function read(print, declared = false) {
7362
+ const SMUSH = /\p{Ll}(?=\p{Lu})/gu;
7363
+ function smushes(s) {
7364
+ return [...s.matchAll(SMUSH)].map((m) => m.index + 1).reverse();
7365
+ }
7366
+ function namedInside(piece, outer, kinds) {
7367
+ return (idx().byPrint.get(fold(piece)) ?? []).filter((n) => n.id !== outer.id && isAncestor(outer, n) && (kinds === undefined || kinds.includes(n.kind)));
7368
+ }
7369
+ function desmush(core, declared) {
7370
+ for (const b of smushes(core)) {
7371
+ const countries = (idx().byPrint.get(fold(core.slice(b))) ?? []).filter((n) => n.kind === "country");
7372
+ if (countries.length !== 1)
7373
+ continue;
7374
+ const country = countries[0];
7375
+ const left = core.slice(0, b).trim();
7376
+ if (left === "")
7377
+ return;
7378
+ const pieces = pieced(left, country);
7379
+ if (pieces === undefined)
7380
+ return;
7381
+ const r = read([...pieces, core.slice(b).trim()].join(", "), declared, false);
7382
+ if (r.heads.length === 0 || r.refusal !== null)
7383
+ return;
7384
+ return { ...r, match: "desmushed" };
7385
+ }
7386
+ return;
7387
+ }
7388
+ function pieced(left, country) {
7389
+ if (namedInside(left, country).length > 0)
7390
+ return [left];
7391
+ for (const b of smushes(left)) {
7392
+ const subs = namedInside(left.slice(b), country, ["subdivision"]);
7393
+ if (subs.length === 0)
7394
+ continue;
7395
+ const head = left.slice(0, b).trim();
7396
+ if (head === "")
7397
+ return;
7398
+ const sub = left.slice(b).trim();
7399
+ if (subs.some((s) => namedInside(head, s).length > 0))
7400
+ return [head, sub];
7401
+ const run = runInside(head, subs);
7402
+ return run === undefined ? undefined : [run.name, sub];
7403
+ }
7404
+ return;
7405
+ }
7406
+ function runInside(piece, subs) {
7407
+ const found = (idx().byRunPrint.get(fold(piece)) ?? []).filter((n) => subs.some((s) => n.id !== s.id && isAncestor(s, n)));
7408
+ return found.length === 1 ? found[0] : undefined;
7409
+ }
7410
+ function read(print, declared = false, smushed = true) {
6914
7411
  const core = unbracket(repair(print));
6915
7412
  if (fold(core) === "")
6916
7413
  return NOTHING;
@@ -6990,7 +7487,7 @@ function createPlaceReader2(options = {}) {
6990
7487
  }
6991
7488
  const first = sane[0];
6992
7489
  if (first === undefined)
6993
- return NOTHING;
7490
+ return (smushed ? desmush(core, declared) : undefined) ?? NOTHING;
6994
7491
  if (sane.length === 1)
6995
7492
  return first;
6996
7493
  const heads = [];
@@ -7209,6 +7706,11 @@ function createPlaceReader2(options = {}) {
7209
7706
  let evictions = 0;
7210
7707
  function place(print, ctx) {
7211
7708
  const declared = typeof ctx === "object" && ctx.declared === true;
7709
+ if (declared && typeof ctx === "object") {
7710
+ const h = heading(print, ctx);
7711
+ if (h !== undefined)
7712
+ return h;
7713
+ }
7212
7714
  const key = declared ? `\x01d\x01${print}` : print;
7213
7715
  const hit = cache.get(key);
7214
7716
  const base = hit ?? built(print, declared, key);
@@ -7216,6 +7718,21 @@ function createPlaceReader2(options = {}) {
7216
7718
  hits++;
7217
7719
  return ctx === undefined ? base : base.refine(ctx);
7218
7720
  }
7721
+ function heading(print, ctx) {
7722
+ const held = idx().byHeading.get(fold(repair(print)));
7723
+ if (held === undefined)
7724
+ return;
7725
+ const within = [ctx.country, ctx.near].filter((w) => w !== undefined && w.trim() !== "").flatMap((w) => headsOf(w));
7726
+ const hits = held.filter((n) => {
7727
+ const parent = n.geo === null ? undefined : idx().byId.get(n.geo);
7728
+ return parent !== undefined && within.some((o) => isAncestor(parent, o));
7729
+ });
7730
+ const hit = hits.length === 1 ? hits[0] : undefined;
7731
+ if (hit === undefined)
7732
+ return;
7733
+ const r = { heads: [hit], match: "print", truncated: false, refusal: null };
7734
+ return build(print, [chainOf(hit)], r, []);
7735
+ }
7219
7736
  function isPlaceToken(token, cut = false, declared = false) {
7220
7737
  const i = idx();
7221
7738
  const t = token.trim();
@@ -7248,7 +7765,9 @@ function createPlaceReader2(options = {}) {
7248
7765
  const CONNECTOR = new Set(["and", "&", "+", "/", ",", "-", "y", "agus"]);
7249
7766
  function built(print, declared = false, key = print) {
7250
7767
  misses++;
7251
- const r = read(print, declared);
7768
+ const store = read(print, declared);
7769
+ const garbage = store.heads.length === 0 && store.refusal === null ? garbageOf(print) : undefined;
7770
+ const r = garbage === undefined ? store : { ...NOTHING, refusal: garbage };
7252
7771
  const chains = chainsFor(r.heads);
7253
7772
  const made = build(print, chains, r, []);
7254
7773
  if (capacity > 0) {
@@ -7413,4 +7932,4 @@ function sameReading2(a, b) {
7413
7932
  return DEFAULT_PLACE_READER2.sameReading(a, b);
7414
7933
  }
7415
7934
 
7416
- export { DEFAULT_PLACE_CAPACITY2, createPlaceReader2, DEFAULT_PLACE_READER2, place2, isPlaceToken2, countryCodeOf2, areAllPlaceTokens2, placeFromId2, oireachtasOfRegion2, regionOfOireachtas2, placeStats2, resetPlaceCache2, placeRelation2, placesRelation2, probablySamePlace2, sameReading2 };
7935
+ export { NEVER_NAME, printZones, opensLocation, DEFAULT_PLACE_CAPACITY2, createPlaceReader2, DEFAULT_PLACE_READER2, place2, isPlaceToken2, countryCodeOf2, areAllPlaceTokens2, placeFromId2, oireachtasOfRegion2, regionOfOireachtas2, placeStats2, resetPlaceCache2, placeRelation2, placesRelation2, probablySamePlace2, sameReading2 };