@finbheara/domain 0.9.0 → 0.11.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.
- package/README.md +26 -0
- package/dist/chunks/place-tcgfvemw.js +30 -0
- package/dist/chunks/{place-h7tvdfyp.js → place-tv86hmps.js} +66 -2
- package/dist/person.js +128 -0
- package/dist/place.js +1 -1
- package/dist/school.js +35 -6
- package/dist/types/person.d.ts +14 -0
- package/dist/types/row-sentinels.d.ts +4 -0
- package/dist/types/school-cell-sentinels.d.ts +4 -0
- package/dist/types/school.d.ts +3 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -43,6 +43,7 @@ ESM, Node ≥ 22 or Bun ≥ 1.4.2. MIT. Not affiliated with or endorsed by any d
|
|
|
43
43
|
| `@finbheara/domain/noun-index` | `createIndex`, `indexSchema`, `personEncoder`, and the `SqlHandle`/`NounEncoder` types: a database-backed name map (below) |
|
|
44
44
|
| `@finbheara/domain/dance-types` | `danceTypes()`, `DANCE_TYPES`, `rhythmOfTime`, and the shared `DanceMatch`/`DanceRelation`/`SetRhythm`/`TimeSignature` types |
|
|
45
45
|
| `@finbheara/domain/promotion` | `samePromotedRow`, `samePromotedSchool`, `samePromotedHeir`, `samePromotedName`, `questionMarksRead`, `foldCharSynonyms`: is a row the same row after a promotion (below) |
|
|
46
|
+
| `@finbheara/domain/person` | `seatName`, `dancerName`, `teacherName`, `roleName`, `roleSentinelOf`, the role lists and `SHARED_ROW_SENTINELS`: a person's print read in its role (below) |
|
|
46
47
|
|
|
47
48
|
The library does no I/O and installs nothing process-wide. Every reader has a default and a
|
|
48
49
|
factory: build your own with options when the default is not what you want.
|
|
@@ -457,6 +458,31 @@ Anything else is another row: a different surname or given name, one letter prin
|
|
|
457
458
|
another, a `?` over an ASCII letter, a school that differs anywhere but a trailing `: location`.
|
|
458
459
|
The caller pairs the card; nothing here reads an address.
|
|
459
460
|
|
|
461
|
+
## Read a person's print in its role
|
|
462
|
+
|
|
463
|
+
A person is printed in a role: an adjudicator's seat on a panel sheet, a dancer's name cell, a
|
|
464
|
+
teacher in a school's listing. Each role prints its own sentinels where no one is named, and a
|
|
465
|
+
person-name reader cannot anticipate them. Each role here has its own not-a-name list, asked
|
|
466
|
+
FIRST; a print on no list is handed to `@finbheara/names` unchanged.
|
|
467
|
+
|
|
468
|
+
```ts
|
|
469
|
+
import { dancerName, seatName, teacherName } from "@finbheara/domain/person";
|
|
470
|
+
|
|
471
|
+
seatName("Withdrawn Adjudicator").isPerson(); // false: the seat's own sentinel
|
|
472
|
+
dancerName("Withdrawn Adjudicator").isPerson(); // true: no dancer list holds it
|
|
473
|
+
dancerName("Test Dancer", "given-first").isPerson(); // false: the dancer's own sentinel
|
|
474
|
+
teacherName("N/A").printsNoName(); // true: a shared row sentinel
|
|
475
|
+
seatName("Aoife Mhaolvarna").nn2; // "Mhaolvarna<<Aoife": names' own parse
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
- **A refused print is still a `PersonName`**: `isPerson()` is false, `printsNoName()` is true,
|
|
479
|
+
`refusal.rule` is `"placeholder"`, the print levels keep the print, and every level from NN2
|
|
480
|
+
down is names' refused value. Ask the type, never the string.
|
|
481
|
+
- **One shared list** (`SHARED_ROW_SENTINELS`: `N/A`, `TBA`, `Unknown`) opens every role's list
|
|
482
|
+
and the school cell's (`SCHOOL_CELL_SENTINELS` on `/school`, asked by the school reader before
|
|
483
|
+
its own register), so a sentinel a whole row prints has one definition.
|
|
484
|
+
- Each row is the folded print (`foldNameKey`), what it stands for, and where it was seen.
|
|
485
|
+
|
|
460
486
|
## Known gaps
|
|
461
487
|
|
|
462
488
|
- `place()` reads `"Derry in Ireland"` and `"Calgary in Western Canada"` as `unread`: it does
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { foldNameKey } from "@finbheara/names/normalize";
|
|
2
|
+
var SHARED_ROW_SENTINELS2 = [
|
|
3
|
+
{
|
|
4
|
+
print: "n a",
|
|
5
|
+
authority: "`#N/A`, a spreadsheet's missing-value mark: 66 name cells and 66 school cells of one transcribed sheet set"
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
print: "tba",
|
|
9
|
+
authority: "`TBA`: 1 name cell and 1 school cell"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
print: "unknown",
|
|
13
|
+
authority: "`Unknown`, `unknown`, `*Unknown*`: 4 name cells and 186 school cells"
|
|
14
|
+
}
|
|
15
|
+
];
|
|
16
|
+
function sentinelIn2(list) {
|
|
17
|
+
const exact = new Map;
|
|
18
|
+
for (const row of list)
|
|
19
|
+
if (row.match === undefined && !exact.has(row.print))
|
|
20
|
+
exact.set(row.print, row);
|
|
21
|
+
const prefix = list.filter((row) => row.match === "prefix");
|
|
22
|
+
return (print) => {
|
|
23
|
+
const folded = foldNameKey(print);
|
|
24
|
+
if (folded === "")
|
|
25
|
+
return;
|
|
26
|
+
return exact.get(folded) ?? prefix.find((row) => folded === row.print || folded.startsWith(`${row.print} `));
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { SHARED_ROW_SENTINELS2, sentinelIn2 };
|
|
@@ -199,14 +199,16 @@ var PLACE_NODES = [
|
|
|
199
199
|
geo: "USA",
|
|
200
200
|
admin: "IDTANA",
|
|
201
201
|
prints: [
|
|
202
|
+
"idtama",
|
|
202
203
|
"lar mheiricea",
|
|
203
204
|
"mid america",
|
|
204
205
|
"mid america region",
|
|
205
206
|
"mid america region usa",
|
|
207
|
+
"mid american region",
|
|
206
208
|
"reigiun lar meiricea",
|
|
207
209
|
"usa mid america region"
|
|
208
210
|
],
|
|
209
|
-
codes: ["MAO"],
|
|
211
|
+
codes: ["IDTAMA", "MAO"],
|
|
210
212
|
truncations: ["mid am"],
|
|
211
213
|
oireachtas: "MAO"
|
|
212
214
|
},
|
|
@@ -243,6 +245,7 @@ var PLACE_NODES = [
|
|
|
243
245
|
geo: "USA",
|
|
244
246
|
admin: "IDTANA",
|
|
245
247
|
prints: [
|
|
248
|
+
"idtana sr",
|
|
246
249
|
"reigiun an deiscirt",
|
|
247
250
|
"s usa",
|
|
248
251
|
"so usa",
|
|
@@ -4994,6 +4997,15 @@ var PLACE_NODES = [
|
|
|
4994
4997
|
prints: ["essex"],
|
|
4995
4998
|
codes: []
|
|
4996
4999
|
},
|
|
5000
|
+
{
|
|
5001
|
+
id: "GBR-ENG/surrey",
|
|
5002
|
+
kind: "city",
|
|
5003
|
+
name: "Surrey",
|
|
5004
|
+
geo: "GBR-ENG",
|
|
5005
|
+
admin: "ENG_SOUTH",
|
|
5006
|
+
prints: ["surrey"],
|
|
5007
|
+
codes: []
|
|
5008
|
+
},
|
|
4997
5009
|
{
|
|
4998
5010
|
id: "GBR-ENG/leeds",
|
|
4999
5011
|
kind: "city",
|
|
@@ -6800,7 +6812,7 @@ function createPlaceReader2(options = {}) {
|
|
|
6800
6812
|
return s.normalize("NFD").replace(/\p{M}+/gu, "").toLowerCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
|
|
6801
6813
|
}
|
|
6802
6814
|
function repair(print) {
|
|
6803
|
-
const s = print.normalize("NFC").replace(/\s+/g, " ").trim();
|
|
6815
|
+
const s = print.normalize("NFC").replace(/\p{Cf}+/gu, "").replace(/\p{Cc}+/gu, " ").replace(/\s+/g, " ").trim();
|
|
6804
6816
|
const opens = (s.match(/[([{]/g) ?? []).length;
|
|
6805
6817
|
const closes = (s.match(/[)\]}]/g) ?? []).length;
|
|
6806
6818
|
if (opens === closes)
|
|
@@ -7407,6 +7419,41 @@ function createPlaceReader2(options = {}) {
|
|
|
7407
7419
|
const found = (idx().byRunPrint.get(fold(piece)) ?? []).filter((n) => subs.some((s) => n.id !== s.id && isAncestor(s, n)));
|
|
7408
7420
|
return found.length === 1 ? found[0] : undefined;
|
|
7409
7421
|
}
|
|
7422
|
+
function continentOf(n) {
|
|
7423
|
+
const seen = new Set;
|
|
7424
|
+
for (let at = n;at !== undefined && !seen.has(at.id); ) {
|
|
7425
|
+
if (at.kind === "continent")
|
|
7426
|
+
return at;
|
|
7427
|
+
seen.add(at.id);
|
|
7428
|
+
at = at.geo === null ? undefined : idx().byId.get(at.geo);
|
|
7429
|
+
}
|
|
7430
|
+
return;
|
|
7431
|
+
}
|
|
7432
|
+
const POSTAL_COUNTRIES = new Set(["USA", "CAN"]);
|
|
7433
|
+
function qualifierAlone(left, right) {
|
|
7434
|
+
if (left.length === 0 || right.length === 0)
|
|
7435
|
+
return;
|
|
7436
|
+
if (left.some((l) => right.some((r) => relates(l, r))))
|
|
7437
|
+
return;
|
|
7438
|
+
const postal = right.filter((r) => r.kind === "subdivision" && POSTAL_COUNTRIES.has(countryOf(r)?.id ?? ""));
|
|
7439
|
+
if (postal.length > 0) {
|
|
7440
|
+
const theirs = new Set(postal.map((r) => countryOf(r)?.id));
|
|
7441
|
+
const fits = left.every((l) => l.kind === "city" || (l.kind === "country" || l.kind === "subdivision") && !theirs.has(countryOf(l)?.id));
|
|
7442
|
+
return fits ? postal : undefined;
|
|
7443
|
+
}
|
|
7444
|
+
if (!right.every((r) => r.kind === "country" || r.kind === "subdivision"))
|
|
7445
|
+
return;
|
|
7446
|
+
const continents = new Set(right.map((r) => continentOf(r)?.id));
|
|
7447
|
+
if (continents.has(undefined))
|
|
7448
|
+
return;
|
|
7449
|
+
const abroad = left.every((l) => {
|
|
7450
|
+
if (l.kind !== "city")
|
|
7451
|
+
return false;
|
|
7452
|
+
const c = continentOf(l)?.id;
|
|
7453
|
+
return c !== undefined && !continents.has(c);
|
|
7454
|
+
});
|
|
7455
|
+
return abroad ? right : undefined;
|
|
7456
|
+
}
|
|
7410
7457
|
function read(print, declared = false, smushed = true) {
|
|
7411
7458
|
const core = unbracket(repair(print));
|
|
7412
7459
|
if (fold(core) === "")
|
|
@@ -7432,6 +7479,7 @@ function createPlaceReader2(options = {}) {
|
|
|
7432
7479
|
const seen = new Set;
|
|
7433
7480
|
for (const split of subsets) {
|
|
7434
7481
|
const parts = [];
|
|
7482
|
+
const before = [null];
|
|
7435
7483
|
let space = tokens[0] ?? "";
|
|
7436
7484
|
let conj = space;
|
|
7437
7485
|
for (let i = 0;i < seps.length; i++) {
|
|
@@ -7439,6 +7487,7 @@ function createPlaceReader2(options = {}) {
|
|
|
7439
7487
|
const next = tokens[i + 1] ?? "";
|
|
7440
7488
|
if (split.includes(k)) {
|
|
7441
7489
|
parts.push({ space, conj });
|
|
7490
|
+
before.push(k);
|
|
7442
7491
|
space = next;
|
|
7443
7492
|
conj = next;
|
|
7444
7493
|
} else {
|
|
@@ -7466,6 +7515,21 @@ function createPlaceReader2(options = {}) {
|
|
|
7466
7515
|
refusal: null
|
|
7467
7516
|
};
|
|
7468
7517
|
}
|
|
7518
|
+
const qualified = (k) => k === "comma" || k === "space";
|
|
7519
|
+
const settled = reads.map((r, n) => {
|
|
7520
|
+
const prev = reads[n - 1];
|
|
7521
|
+
if (prev === undefined || !qualified(before[n]) || r.truncated)
|
|
7522
|
+
return;
|
|
7523
|
+
if (n - 1 > 0 && (qualified(before[n - 1]) || !qualified(before[n - 2])))
|
|
7524
|
+
return;
|
|
7525
|
+
return qualifierAlone(prev.heads, r.heads);
|
|
7526
|
+
});
|
|
7527
|
+
settled.forEach((heads, n) => {
|
|
7528
|
+
if (heads === undefined)
|
|
7529
|
+
return;
|
|
7530
|
+
reads[n - 1] = { ...reads[n - 1], heads };
|
|
7531
|
+
reads[n] = { ...reads[n], heads };
|
|
7532
|
+
});
|
|
7469
7533
|
if (reads.some((r) => r.heads.length === 0 || r.refusal !== null))
|
|
7470
7534
|
continue;
|
|
7471
7535
|
const together = combine(reads);
|
package/dist/person.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SHARED_ROW_SENTINELS2,
|
|
3
|
+
sentinelIn2
|
|
4
|
+
} from "./chunks/place-tcgfvemw.js";
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
NAME_REFUSED,
|
|
8
|
+
personName
|
|
9
|
+
} from "@finbheara/names/normalize";
|
|
10
|
+
var ADJUDICATOR_SENTINELS = [
|
|
11
|
+
{
|
|
12
|
+
print: "withdrawn adjudicator",
|
|
13
|
+
authority: "`Withdrawn Adjudicator`: 180 seat cells, one panel sheet's empty seat"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
print: "no school judge",
|
|
17
|
+
authority: "`No School Judge`: an entry form's option for an adjudicator's entry"
|
|
18
|
+
}
|
|
19
|
+
];
|
|
20
|
+
var DANCER_SENTINELS = [
|
|
21
|
+
{
|
|
22
|
+
print: "name withheld",
|
|
23
|
+
authority: "`Name Withheld`: 136 name cells, the entry platform printed that the name was withheld"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
print: "test dancer",
|
|
27
|
+
authority: "`Test Dancer`: 7 name cells, an entry platform's test entry"
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
print: "none none",
|
|
31
|
+
authority: "`none none`: 4 name cells, the sentinel `none` typed into both name fields"
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
print: "not known",
|
|
35
|
+
authority: "`Not known`: 1 name cell"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
print: "don t know",
|
|
39
|
+
authority: "`Don't Know`: 1 name cell"
|
|
40
|
+
}
|
|
41
|
+
];
|
|
42
|
+
var TEACHER_SENTINELS = [];
|
|
43
|
+
var ROLE_SENTINELS = {
|
|
44
|
+
adjudicator: [...SHARED_ROW_SENTINELS2, ...ADJUDICATOR_SENTINELS],
|
|
45
|
+
dancer: [...SHARED_ROW_SENTINELS2, ...DANCER_SENTINELS],
|
|
46
|
+
teacher: [...SHARED_ROW_SENTINELS2, ...TEACHER_SENTINELS]
|
|
47
|
+
};
|
|
48
|
+
var MATCHERS = {
|
|
49
|
+
adjudicator: sentinelIn2(ROLE_SENTINELS.adjudicator),
|
|
50
|
+
dancer: sentinelIn2(ROLE_SENTINELS.dancer),
|
|
51
|
+
teacher: sentinelIn2(ROLE_SENTINELS.teacher)
|
|
52
|
+
};
|
|
53
|
+
function roleSentinelOf(role, print) {
|
|
54
|
+
return MATCHERS[role](print);
|
|
55
|
+
}
|
|
56
|
+
var NO_PART = Object.freeze({ particles: [], base: "", parts: [], tradition: null });
|
|
57
|
+
|
|
58
|
+
class RoleRefusedName {
|
|
59
|
+
[Symbol.toStringTag] = "PersonName";
|
|
60
|
+
nn0;
|
|
61
|
+
nn1;
|
|
62
|
+
nn2 = NAME_REFUSED;
|
|
63
|
+
nn3 = NAME_REFUSED;
|
|
64
|
+
nn4 = NAME_REFUSED;
|
|
65
|
+
surname = NO_PART;
|
|
66
|
+
given = [];
|
|
67
|
+
suffixes = [];
|
|
68
|
+
refusal;
|
|
69
|
+
verdict;
|
|
70
|
+
role;
|
|
71
|
+
sentinel;
|
|
72
|
+
constructor(read, role, sentinel) {
|
|
73
|
+
this.role = role;
|
|
74
|
+
this.sentinel = sentinel;
|
|
75
|
+
this.nn0 = read.nn0;
|
|
76
|
+
this.nn1 = read.nn1;
|
|
77
|
+
this.refusal = { rule: "placeholder", printed: read.nn0, value: NAME_REFUSED };
|
|
78
|
+
this.verdict = { kind: "refused", refusal: this.refusal, rules: read.verdict.rules };
|
|
79
|
+
}
|
|
80
|
+
toString() {
|
|
81
|
+
return this.nn2;
|
|
82
|
+
}
|
|
83
|
+
get length() {
|
|
84
|
+
return this.nn2.length;
|
|
85
|
+
}
|
|
86
|
+
surnameKey() {
|
|
87
|
+
return "";
|
|
88
|
+
}
|
|
89
|
+
givenFields() {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
givenName() {
|
|
93
|
+
return "";
|
|
94
|
+
}
|
|
95
|
+
isTeam() {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
isPerson() {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
isEmpty() {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
printsNoName() {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function roleName(role, print, order) {
|
|
109
|
+
const read = personName(print, order);
|
|
110
|
+
const sentinel = MATCHERS[role](print);
|
|
111
|
+
return sentinel === undefined ? read : new RoleRefusedName(read, role, sentinel);
|
|
112
|
+
}
|
|
113
|
+
var seatName = (print) => roleName("adjudicator", print, "given-first");
|
|
114
|
+
var dancerName = (print, order) => roleName("dancer", print, order);
|
|
115
|
+
var teacherName = (print, order) => roleName("teacher", print, order);
|
|
116
|
+
export {
|
|
117
|
+
ADJUDICATOR_SENTINELS,
|
|
118
|
+
DANCER_SENTINELS,
|
|
119
|
+
ROLE_SENTINELS,
|
|
120
|
+
SHARED_ROW_SENTINELS2 as SHARED_ROW_SENTINELS,
|
|
121
|
+
TEACHER_SENTINELS,
|
|
122
|
+
dancerName,
|
|
123
|
+
roleName,
|
|
124
|
+
roleSentinelOf,
|
|
125
|
+
seatName,
|
|
126
|
+
sentinelIn2 as sentinelIn,
|
|
127
|
+
teacherName
|
|
128
|
+
};
|
package/dist/place.js
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
placesRelation2,
|
|
16
16
|
probablySamePlace2,
|
|
17
17
|
sameReading2
|
|
18
|
-
} from "./chunks/place-
|
|
18
|
+
} from "./chunks/place-tv86hmps.js";
|
|
19
19
|
export {
|
|
20
20
|
DEFAULT_PLACE_CAPACITY2 as DEFAULT_PLACE_CAPACITY,
|
|
21
21
|
DEFAULT_PLACE_READER2 as DEFAULT_PLACE_READER,
|
package/dist/school.js
CHANGED
|
@@ -8,16 +8,41 @@ import {
|
|
|
8
8
|
areAllPlaceTokens2,
|
|
9
9
|
placeRelation2,
|
|
10
10
|
sameReading2
|
|
11
|
-
} from "./chunks/place-
|
|
11
|
+
} from "./chunks/place-tv86hmps.js";
|
|
12
|
+
import {
|
|
13
|
+
SHARED_ROW_SENTINELS2,
|
|
14
|
+
sentinelIn2
|
|
15
|
+
} from "./chunks/place-tcgfvemw.js";
|
|
12
16
|
import {
|
|
13
17
|
validity
|
|
14
18
|
} from "./chunks/place-q9kwsmzd.js";
|
|
15
19
|
|
|
16
|
-
import { normalizeApostrophes } from "@finbheara/names/lexicon";
|
|
20
|
+
import { normalizeApostrophes as normalizeApostrophes2 } from "@finbheara/names/lexicon";
|
|
17
21
|
import { SURNAME_SEPARATOR, lexiconKey, titleCaseNamePart } from "@finbheara/names/normalize";
|
|
18
22
|
import { personName } from "@finbheara/names/normalize";
|
|
19
23
|
|
|
20
24
|
import { placeholderOf } from "@finbheara/names/normalize";
|
|
25
|
+
|
|
26
|
+
var SCHOOL_CELL_OWN_SENTINELS = [
|
|
27
|
+
{
|
|
28
|
+
print: "no school",
|
|
29
|
+
authority: "`No School`: 76 school cells, the dancer entered with no school"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
print: "independent",
|
|
33
|
+
authority: "`Independent`, `independent`, `Independent?`: 5 school cells, no school by the dancer's own description"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
print: "independent dancer",
|
|
37
|
+
authority: "`Independent Dancer`, `Independent dancer`, `Independent Dancer?`: 8 school cells"
|
|
38
|
+
}
|
|
39
|
+
];
|
|
40
|
+
var SCHOOL_CELL_SENTINELS = [
|
|
41
|
+
...SHARED_ROW_SENTINELS2,
|
|
42
|
+
...SCHOOL_CELL_OWN_SENTINELS
|
|
43
|
+
];
|
|
44
|
+
var schoolCellSentinelOf = sentinelIn2(SCHOOL_CELL_SENTINELS);
|
|
45
|
+
|
|
21
46
|
var SCHOOL_NAME_EXCEPTIONS = [
|
|
22
47
|
{
|
|
23
48
|
phrase: "the academy",
|
|
@@ -257,7 +282,7 @@ function notASchoolIn(rows) {
|
|
|
257
282
|
const text = normalizeForRefusal(print);
|
|
258
283
|
if (text === "")
|
|
259
284
|
return;
|
|
260
|
-
const placeholder = placeholderOf(text);
|
|
285
|
+
const placeholder = schoolCellSentinelOf(text) ?? placeholderOf(text);
|
|
261
286
|
if (placeholder !== undefined)
|
|
262
287
|
return placeholderRow(placeholder);
|
|
263
288
|
for (const row of rows) {
|
|
@@ -873,6 +898,7 @@ function truncatedInstitution(tail) {
|
|
|
873
898
|
return found;
|
|
874
899
|
}
|
|
875
900
|
|
|
901
|
+
import { normalizeApostrophes } from "@finbheara/names/lexicon";
|
|
876
902
|
var SCHOOL_FLUFF_WORDS = new Set([
|
|
877
903
|
"academy",
|
|
878
904
|
"irish",
|
|
@@ -929,12 +955,11 @@ function isDiscardedAnyway(token) {
|
|
|
929
955
|
function distinctiveTokens(tokens) {
|
|
930
956
|
return tokens.filter((t) => t.length > 2 && !SCHOOL_FLUFF_WORDS.has(t));
|
|
931
957
|
}
|
|
932
|
-
var APOSTROPHE_VARIANTS = /['`´‘’“”]/g;
|
|
933
958
|
function foldSchoolName(raw) {
|
|
934
959
|
let s = raw.toLowerCase();
|
|
935
960
|
s = s.normalize("NFD").replace(/[̀-ͯ]/g, "");
|
|
936
961
|
s = s.replace(/ß/g, "ss").replace(/æ/g, "ae").replace(/œ/g, "oe").replace(/ø/g, "o");
|
|
937
|
-
s = s
|
|
962
|
+
s = normalizeApostrophes(s);
|
|
938
963
|
s = s.replace(/'/g, "");
|
|
939
964
|
const words = [];
|
|
940
965
|
for (const word of s.split(/[^a-z0-9]+/)) {
|
|
@@ -1057,7 +1082,7 @@ function createSchoolNameReader(options = {}) {
|
|
|
1057
1082
|
return print.replace(SPACING_ACUTE_AFTER_VOWEL, "$1́").replace(SPACING_ACUTE, "'");
|
|
1058
1083
|
}
|
|
1059
1084
|
function renderSn1(print) {
|
|
1060
|
-
return
|
|
1085
|
+
return normalizeApostrophes2(readSpacingAcute(repairMojibake(print)).normalize("NFKC")).replace(/\p{Cf}+/gu, "").replace(/\p{Cc}+/gu, " ").replace(/\s+/gu, " ").trim();
|
|
1061
1086
|
}
|
|
1062
1087
|
const COMPOUND_OPENERS = new Set([
|
|
1063
1088
|
"hyphen",
|
|
@@ -2137,8 +2162,11 @@ export {
|
|
|
2137
2162
|
DEFAULT_SCHOOL_NAME_CAPACITY,
|
|
2138
2163
|
DEFAULT_SCHOOL_NAME_READER,
|
|
2139
2164
|
NOT_A_SCHOOL,
|
|
2165
|
+
SCHOOL_CELL_OWN_SENTINELS,
|
|
2166
|
+
SCHOOL_CELL_SENTINELS,
|
|
2140
2167
|
SCHOOL_LEVEL_COLUMNS,
|
|
2141
2168
|
SCHOOL_NAME_EXCEPTIONS,
|
|
2169
|
+
SHARED_ROW_SENTINELS2 as SHARED_ROW_SENTINELS,
|
|
2142
2170
|
compareSchoolNames,
|
|
2143
2171
|
compareSchools,
|
|
2144
2172
|
createSchoolNameReader,
|
|
@@ -2152,6 +2180,7 @@ export {
|
|
|
2152
2180
|
realWords,
|
|
2153
2181
|
realWordsInPrintOrder,
|
|
2154
2182
|
sameInEveryPart,
|
|
2183
|
+
schoolCellSentinelOf,
|
|
2155
2184
|
schoolColumns,
|
|
2156
2185
|
schoolCompare,
|
|
2157
2186
|
schoolEncoder,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type ParseOrder, type PersonName } from "@finbheara/names/normalize";
|
|
2
|
+
import { type RowSentinel } from "./row-sentinels.ts";
|
|
3
|
+
export { SHARED_ROW_SENTINELS, sentinelIn } from "./row-sentinels.ts";
|
|
4
|
+
export type { RowSentinel } from "./row-sentinels.ts";
|
|
5
|
+
export type PersonRole = "adjudicator" | "dancer" | "teacher";
|
|
6
|
+
export declare const ADJUDICATOR_SENTINELS: readonly RowSentinel[];
|
|
7
|
+
export declare const DANCER_SENTINELS: readonly RowSentinel[];
|
|
8
|
+
export declare const TEACHER_SENTINELS: readonly RowSentinel[];
|
|
9
|
+
export declare const ROLE_SENTINELS: Readonly<Record<PersonRole, readonly RowSentinel[]>>;
|
|
10
|
+
export declare function roleSentinelOf(role: PersonRole, print: string): RowSentinel | undefined;
|
|
11
|
+
export declare function roleName(role: PersonRole, print: string, order?: ParseOrder): PersonName;
|
|
12
|
+
export declare const seatName: (print: string) => PersonName;
|
|
13
|
+
export declare const dancerName: (print: string, order?: ParseOrder) => PersonName;
|
|
14
|
+
export declare const teacherName: (print: string, order?: ParseOrder) => PersonName;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type NamePlaceholder } from "@finbheara/names/normalize";
|
|
2
|
+
export type RowSentinel = NamePlaceholder;
|
|
3
|
+
export declare const SHARED_ROW_SENTINELS: readonly RowSentinel[];
|
|
4
|
+
export declare function sentinelIn(list: readonly RowSentinel[]): (print: string) => RowSentinel | undefined;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type RowSentinel } from "./row-sentinels.ts";
|
|
2
|
+
export declare const SCHOOL_CELL_OWN_SENTINELS: readonly RowSentinel[];
|
|
3
|
+
export declare const SCHOOL_CELL_SENTINELS: readonly RowSentinel[];
|
|
4
|
+
export declare const schoolCellSentinelOf: (print: string) => RowSentinel | undefined;
|
package/dist/types/school.d.ts
CHANGED
|
@@ -8,5 +8,8 @@ export { compareSchoolNames, compareSchools } from "./school-identity.ts";
|
|
|
8
8
|
export type { IdentityResult, IdentityVerdict } from "./school-identity.ts";
|
|
9
9
|
export { foldSchoolName, hasSpecificToken, schoolKeyTokens } from "./school-match-key.ts";
|
|
10
10
|
export { NOT_A_SCHOOL, SCHOOL_NAME_EXCEPTIONS, } from "./school-exception-vocabulary.ts";
|
|
11
|
+
export { SCHOOL_CELL_OWN_SENTINELS, SCHOOL_CELL_SENTINELS, schoolCellSentinelOf, } from "./school-cell-sentinels.ts";
|
|
12
|
+
export { SHARED_ROW_SENTINELS } from "./row-sentinels.ts";
|
|
13
|
+
export type { RowSentinel } from "./row-sentinels.ts";
|
|
11
14
|
export type { EmptyReason, Validated } from "./validated.ts";
|
|
12
15
|
export type { NotASchool, RefusalReason, SchoolNameException, } from "./school-exception-vocabulary.ts";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@finbheara/domain",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Places, CLRG regions, school names, ages and
|
|
3
|
+
"version": "0.11.0",
|
|
4
|
+
"description": "Places, CLRG regions, school names, ages, dances and a person's print in its role, as they are printed: read, compared and told apart",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"places",
|
|
7
7
|
"regions",
|
|
@@ -57,6 +57,10 @@
|
|
|
57
57
|
"types": "./dist/types/promotion.d.ts",
|
|
58
58
|
"default": "./dist/promotion.js"
|
|
59
59
|
},
|
|
60
|
+
"./person": {
|
|
61
|
+
"types": "./dist/types/person.d.ts",
|
|
62
|
+
"default": "./dist/person.js"
|
|
63
|
+
},
|
|
60
64
|
"./package.json": "./package.json"
|
|
61
65
|
},
|
|
62
66
|
"files": ["dist/*.js", "dist/chunks/*.js", "dist/types/**/*.d.ts", "README.md", "LICENSE"],
|