@finbheara/domain 0.4.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.
@@ -1,3 +1,9 @@
1
+ import {
2
+ validity
3
+ } from "./place-q9kwsmzd.js";
4
+
5
+ import { isPlaceholderPrint } from "@finbheara/names/normalize";
6
+
1
7
  var PLACE_NODES = [
2
8
  {
3
9
  id: "world",
@@ -160,9 +166,11 @@ var PLACE_NODES = [
160
166
  "serc",
161
167
  "southern england",
162
168
  "southern region",
163
- "southern region england"
169
+ "southern region england",
170
+ "southern region uk"
164
171
  ],
165
172
  codes: ["ENG_SOUTH"],
173
+ headings: ["southern"],
166
174
  truncations: ["southern regi", "southern regio"],
167
175
  oireachtas: "ENG_SOUTH"
168
176
  },
@@ -302,7 +310,7 @@ var PLACE_NODES = [
302
310
  name: "New Zealand",
303
311
  geo: "NZL",
304
312
  admin: "world",
305
- prints: ["tidanz"],
313
+ prints: ["nua shealainn new zealand", "tidanz"],
306
314
  codes: [],
307
315
  oireachtas: "NZ"
308
316
  },
@@ -312,7 +320,14 @@ var PLACE_NODES = [
312
320
  name: "Continental Europe & Asia (RCCEA)",
313
321
  geo: null,
314
322
  admin: "world",
315
- 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
+ ],
316
331
  codes: ["RCCEA"],
317
332
  oireachtas: "RCCEA"
318
333
  },
@@ -332,7 +347,7 @@ var PLACE_NODES = [
332
347
  name: "South Africa",
333
348
  geo: "ZAF",
334
349
  admin: "world",
335
- prints: [],
350
+ prints: ["an afraic theas south africa"],
336
351
  codes: ["SOUTH_AFRICA"],
337
352
  oireachtas: "SOUTH_AFRICA"
338
353
  },
@@ -2631,7 +2646,7 @@ var PLACE_NODES = [
2631
2646
  name: "Russia",
2632
2647
  geo: "europe",
2633
2648
  admin: "RCCEA",
2634
- prints: ["rus", "russia"],
2649
+ prints: ["an ruis russia", "rus", "russia", "russia ruisis"],
2635
2650
  codes: [],
2636
2651
  iso2: "RU",
2637
2652
  iso3: "RUS",
@@ -3374,7 +3389,8 @@ var PLACE_NODES = [
3374
3389
  geo: "AUS",
3375
3390
  admin: "AUSTRALIA",
3376
3391
  prints: ["northern territory"],
3377
- codes: ["AU-NT", "AUS-NT", "NT"]
3392
+ codes: ["AU-NT", "AUS-NT", "NT"],
3393
+ headings: ["nothern territory"]
3378
3394
  },
3379
3395
  {
3380
3396
  id: "AUS-QLD",
@@ -3392,7 +3408,8 @@ var PLACE_NODES = [
3392
3408
  geo: "AUS",
3393
3409
  admin: "AUSTRALIA",
3394
3410
  prints: ["deisceart na hastraile", "reigiun deisceart na hastraile", "south australia"],
3395
- codes: ["AU-SA", "AUS-SA", "SA"]
3411
+ codes: ["AU-SA", "AUS-SA", "SA"],
3412
+ headings: ["south"]
3396
3413
  },
3397
3414
  {
3398
3415
  id: "AUS-TAS",
@@ -3424,7 +3441,8 @@ var PLACE_NODES = [
3424
3441
  "reigiun iarrthar na hastraile",
3425
3442
  "western australia"
3426
3443
  ],
3427
- codes: ["AU-WA", "AUS-WA", "WA"]
3444
+ codes: ["AU-WA", "AUS-WA", "WA"],
3445
+ headings: ["western"]
3428
3446
  },
3429
3447
  {
3430
3448
  id: "CAN-AB",
@@ -3865,6 +3883,15 @@ var PLACE_NODES = [
3865
3883
  prints: ["co wexford", "county wexford", "wexford"],
3866
3884
  codes: ["IE-WX"]
3867
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
+ },
3868
3895
  {
3869
3896
  id: "USA-AK",
3870
3897
  kind: "subdivision",
@@ -4534,6 +4561,15 @@ var PLACE_NODES = [
4534
4561
  prints: ["winnipeg"],
4535
4562
  codes: []
4536
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
+ },
4537
4573
  {
4538
4574
  id: "CAN-NS/halifax",
4539
4575
  kind: "city",
@@ -4588,6 +4624,15 @@ var PLACE_NODES = [
4588
4624
  prints: ["mississauga"],
4589
4625
  codes: []
4590
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
+ },
4591
4636
  {
4592
4637
  id: "CAN-ON/oakville",
4593
4638
  kind: "city",
@@ -4633,13 +4678,31 @@ var PLACE_NODES = [
4633
4678
  prints: ["toronto"],
4634
4679
  codes: []
4635
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
+ },
4636
4690
  {
4637
4691
  id: "CAN-ON/windsor",
4638
4692
  kind: "city",
4639
4693
  name: "Windsor",
4640
4694
  geo: "CAN-ON",
4641
4695
  admin: "IDTANA-ECRO",
4642
- 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"],
4643
4706
  codes: []
4644
4707
  },
4645
4708
  {
@@ -4697,6 +4760,15 @@ var PLACE_NODES = [
4697
4760
  prints: ["berlin"],
4698
4761
  codes: []
4699
4762
  },
4763
+ {
4764
+ id: "DEU/landstuhl",
4765
+ kind: "city",
4766
+ name: "Landstuhl",
4767
+ geo: "DEU",
4768
+ admin: "RCCEA",
4769
+ prints: ["landstuhl"],
4770
+ codes: []
4771
+ },
4700
4772
  {
4701
4773
  id: "ESP/barcelona",
4702
4774
  kind: "city",
@@ -5219,6 +5291,15 @@ var PLACE_NODES = [
5219
5291
  prints: ["bay area"],
5220
5292
  codes: []
5221
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
+ },
5222
5303
  {
5223
5304
  id: "USA-CA/dublin",
5224
5305
  kind: "city",
@@ -5328,6 +5409,15 @@ var PLACE_NODES = [
5328
5409
  prints: ["wilmington"],
5329
5410
  codes: []
5330
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
+ },
5331
5421
  {
5332
5422
  id: "USA-FL/gainesville",
5333
5423
  kind: "city",
@@ -5346,6 +5436,15 @@ var PLACE_NODES = [
5346
5436
  prints: ["jacksonville"],
5347
5437
  codes: []
5348
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
+ },
5349
5448
  {
5350
5449
  id: "USA-FL/miami",
5351
5450
  kind: "city",
@@ -5400,6 +5499,15 @@ var PLACE_NODES = [
5400
5499
  prints: ["tampa"],
5401
5500
  codes: []
5402
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
+ },
5403
5511
  {
5404
5512
  id: "USA-GA/atlanta",
5405
5513
  kind: "city",
@@ -5454,6 +5562,33 @@ var PLACE_NODES = [
5454
5562
  prints: ["chicago"],
5455
5563
  codes: []
5456
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
+ },
5457
5592
  {
5458
5593
  id: "USA-IL/springfield",
5459
5594
  kind: "city",
@@ -5535,6 +5670,15 @@ var PLACE_NODES = [
5535
5670
  prints: ["lexington"],
5536
5671
  codes: []
5537
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
+ },
5538
5682
  {
5539
5683
  id: "USA-MA/springfield",
5540
5684
  kind: "city",
@@ -5572,6 +5716,24 @@ var PLACE_NODES = [
5572
5716
  codes: [],
5573
5717
  truncations: ["baltimor"]
5574
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
+ },
5575
5737
  {
5576
5738
  id: "USA-ME/portland",
5577
5739
  kind: "city",
@@ -5707,6 +5869,16 @@ var PLACE_NODES = [
5707
5869
  prints: ["greensboro"],
5708
5870
  codes: []
5709
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
+ },
5710
5882
  {
5711
5883
  id: "USA-NC/raleigh",
5712
5884
  kind: "city",
@@ -5770,6 +5942,15 @@ var PLACE_NODES = [
5770
5942
  prints: ["trenton"],
5771
5943
  codes: []
5772
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
+ },
5773
5954
  {
5774
5955
  id: "USA-NM/albuquerque",
5775
5956
  kind: "city",
@@ -5779,6 +5960,15 @@ var PLACE_NODES = [
5779
5960
  prints: ["albuquerque"],
5780
5961
  codes: []
5781
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
+ },
5782
5972
  {
5783
5973
  id: "USA-NM/santa-fe",
5784
5974
  kind: "city",
@@ -5815,6 +6005,15 @@ var PLACE_NODES = [
5815
6005
  prints: ["albany"],
5816
6006
  codes: []
5817
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
+ },
5818
6017
  {
5819
6018
  id: "USA-NY/buffalo",
5820
6019
  kind: "city",
@@ -5824,6 +6023,15 @@ var PLACE_NODES = [
5824
6023
  prints: ["buffalo"],
5825
6024
  codes: []
5826
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
+ },
5827
6035
  {
5828
6036
  id: "USA-NY/kingston",
5829
6037
  kind: "city",
@@ -5896,6 +6104,15 @@ var PLACE_NODES = [
5896
6104
  prints: ["syracuse"],
5897
6105
  codes: []
5898
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
+ },
5899
6116
  {
5900
6117
  id: "USA-OH/akron",
5901
6118
  kind: "city",
@@ -5950,6 +6167,15 @@ var PLACE_NODES = [
5950
6167
  prints: ["dublin"],
5951
6168
  codes: []
5952
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
+ },
5953
6179
  {
5954
6180
  id: "USA-OH/toledo",
5955
6181
  kind: "city",
@@ -6013,6 +6239,16 @@ var PLACE_NODES = [
6013
6239
  prints: ["ardmore"],
6014
6240
  codes: []
6015
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
+ },
6016
6252
  {
6017
6253
  id: "USA-PA/lancaster",
6018
6254
  kind: "city",
@@ -6185,6 +6421,15 @@ var PLACE_NODES = [
6185
6421
  prints: ["north texas"],
6186
6422
  codes: []
6187
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
+ },
6188
6433
  {
6189
6434
  id: "USA-TX/san-antonio",
6190
6435
  kind: "city",
@@ -6203,6 +6448,15 @@ var PLACE_NODES = [
6203
6448
  prints: ["south texas"],
6204
6449
  codes: []
6205
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
+ },
6206
6460
  {
6207
6461
  id: "USA-UT/salt-lake-city",
6208
6462
  kind: "city",
@@ -6302,6 +6556,15 @@ var PLACE_NODES = [
6302
6556
  prints: ["burlington"],
6303
6557
  codes: []
6304
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
+ },
6305
6568
  {
6306
6569
  id: "USA-WA/olympia",
6307
6570
  kind: "city",
@@ -6358,6 +6621,135 @@ var PLACE_NODES = [
6358
6621
  }
6359
6622
  ];
6360
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
+
6361
6753
  var DEFAULT_PLACE_CAPACITY2 = 8192;
6362
6754
  function createPlaceReader2(options = {}) {
6363
6755
  const nodes = options.tree ?? PLACE_NODES;
@@ -6376,8 +6768,34 @@ function createPlaceReader2(options = {}) {
6376
6768
  "none",
6377
6769
  "null",
6378
6770
  "tbd",
6379
- "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"
6380
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
+ }
6381
6799
  function fold(s) {
6382
6800
  return s.normalize("NFD").replace(/\p{M}+/gu, "").toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
6383
6801
  }
@@ -6407,7 +6825,13 @@ function createPlaceReader2(options = {}) {
6407
6825
  const bySubdivisionPart = new Map;
6408
6826
  const byOireachtas = new Map;
6409
6827
  const listedPhrases = new Set;
6828
+ const byHeading = new Map;
6829
+ const byRunPrint = new Map;
6410
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);
6411
6835
  push(byPrint, fold(n.id), n);
6412
6836
  if (n.kind !== "body")
6413
6837
  push(byPrint, fold(n.name), n);
@@ -6440,28 +6864,50 @@ function createPlaceReader2(options = {}) {
6440
6864
  push(bySubdivisionPart, fold(p), n);
6441
6865
  }
6442
6866
  }
6443
- const ancestorsOf = new Map;
6444
- const walk = (n, seen) => {
6445
- const had = ancestorsOf.get(n.id);
6446
- if (had !== undefined)
6447
- return had;
6448
- 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 = [];
6449
6880
  for (const up of [n.geo, n.admin]) {
6450
- if (up === null || up === undefined || seen.has(up))
6881
+ if (up === null || up === undefined)
6451
6882
  continue;
6452
6883
  const parent = byId.get(up);
6453
6884
  if (parent === undefined)
6454
6885
  continue;
6455
- out.add(parent.id);
6456
- seen.add(parent.id);
6457
- for (const id of walk(parent, seen))
6458
- 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);
6459
6891
  }
6460
- ancestorsOf.set(n.id, out);
6461
6892
  return out;
6462
6893
  };
6894
+ const parents = new Map;
6463
6895
  for (const n of source)
6464
- 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
+ }
6465
6911
  const phrases = [...byPrint.keys()].filter((k) => k.includes(" ")).sort((a, b) => b.length - a.length);
6466
6912
  return {
6467
6913
  byId,
@@ -6472,8 +6918,11 @@ function createPlaceReader2(options = {}) {
6472
6918
  bySubdivisionPart,
6473
6919
  byOireachtas,
6474
6920
  ancestorsOf,
6921
+ carries,
6475
6922
  phrases,
6476
- listedPhrases
6923
+ listedPhrases,
6924
+ byHeading,
6925
+ byRunPrint
6477
6926
  };
6478
6927
  }
6479
6928
  function idx() {
@@ -6594,6 +7043,10 @@ function createPlaceReader2(options = {}) {
6594
7043
  if (n !== undefined && CARRIED.has(n.kind))
6595
7044
  out.set(n.id, n);
6596
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);
6597
7050
  return { head, nodes: ordered([...out.values()]) };
6598
7051
  }
6599
7052
  const NOTHING = { heads: [], match: null, truncated: false, refusal: null };
@@ -6710,7 +7163,7 @@ function createPlaceReader2(options = {}) {
6710
7163
  if (key[folded.length] === " ")
6711
7164
  continue;
6712
7165
  for (const n of found)
6713
- if (n.kind !== "body")
7166
+ if (n.kind !== "body" && n.listedCutsOnly !== true)
6714
7167
  out.push({ node: n, length: key.length });
6715
7168
  }
6716
7169
  return out;
@@ -6906,7 +7359,55 @@ function createPlaceReader2(options = {}) {
6906
7359
  }
6907
7360
  return;
6908
7361
  }
6909
- 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) {
6910
7411
  const core = unbracket(repair(print));
6911
7412
  if (fold(core) === "")
6912
7413
  return NOTHING;
@@ -6986,7 +7487,7 @@ function createPlaceReader2(options = {}) {
6986
7487
  }
6987
7488
  const first = sane[0];
6988
7489
  if (first === undefined)
6989
- return NOTHING;
7490
+ return (smushed ? desmush(core, declared) : undefined) ?? NOTHING;
6990
7491
  if (sane.length === 1)
6991
7492
  return first;
6992
7493
  const heads = [];
@@ -7098,7 +7599,7 @@ function createPlaceReader2(options = {}) {
7098
7599
  refusal: r.refusal,
7099
7600
  misses,
7100
7601
  length: pl2.length,
7101
- isEmpty: () => pl1 === "",
7602
+ ...validity(pl1 === "", r.refusal),
7102
7603
  isPlace: () => pl1 !== "" && r.refusal === null && chains.length > 0,
7103
7604
  isSingular() {
7104
7605
  return this.arm === "resolved";
@@ -7205,6 +7706,11 @@ function createPlaceReader2(options = {}) {
7205
7706
  let evictions = 0;
7206
7707
  function place(print, ctx) {
7207
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
+ }
7208
7714
  const key = declared ? `\x01d\x01${print}` : print;
7209
7715
  const hit = cache.get(key);
7210
7716
  const base = hit ?? built(print, declared, key);
@@ -7212,6 +7718,21 @@ function createPlaceReader2(options = {}) {
7212
7718
  hits++;
7213
7719
  return ctx === undefined ? base : base.refine(ctx);
7214
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
+ }
7215
7736
  function isPlaceToken(token, cut = false, declared = false) {
7216
7737
  const i = idx();
7217
7738
  const t = token.trim();
@@ -7244,7 +7765,9 @@ function createPlaceReader2(options = {}) {
7244
7765
  const CONNECTOR = new Set(["and", "&", "+", "/", ",", "-", "y", "agus"]);
7245
7766
  function built(print, declared = false, key = print) {
7246
7767
  misses++;
7247
- 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 };
7248
7771
  const chains = chainsFor(r.heads);
7249
7772
  const made = build(print, chains, r, []);
7250
7773
  if (capacity > 0) {
@@ -7409,4 +7932,4 @@ function sameReading2(a, b) {
7409
7932
  return DEFAULT_PLACE_READER2.sameReading(a, b);
7410
7933
  }
7411
7934
 
7412
- 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 };