@finbheara/archive-client 0.8.0 → 0.10.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 +84 -6
- package/dist/chunks/{index-mg6dw0y5.js → index-hs72zekf.js} +267 -24
- package/dist/cli.js +26 -7
- package/dist/index.js +3 -1
- package/dist/types/cli.d.ts +1 -1
- package/dist/types/dancers.d.ts +39 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/presence.d.ts +2 -0
- package/dist/types/registrations.d.ts +2 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -216,11 +216,13 @@ const r = await rel.dancers.resolve({
|
|
|
216
216
|
age: { band: "U10", year: 2026 }, // or { yob: 2016 }, or { comp: "<competition>" }
|
|
217
217
|
asOf: "2026-10-17", // the school as of then
|
|
218
218
|
population: "girls", // or "boys": only a contradiction excludes
|
|
219
|
+
oireachtas: { region: "SRO", year: 2026 }, // the regional the roster is for (below)
|
|
219
220
|
});
|
|
220
221
|
r.arm; // "unique" | "ambiguous" | "none"
|
|
221
|
-
r.candidates; // [{ dancer_id, display, scope, score, evidence: { nameLevel, age, school }, prints, ... }]
|
|
222
|
-
r.excluded; // the candidates a contradiction set aside (why: "age" | "population")
|
|
223
|
-
r.preferred; // NON-BINDING: { dancer_id, why } where the school singles one out
|
|
222
|
+
r.candidates; // [{ dancer_id, display, scope, score, evidence: { nameLevel, age, school, population, region }, prints, ... }]
|
|
223
|
+
r.excluded; // the candidates a contradiction set aside (why: "age" | "population" | "region" | "school")
|
|
224
|
+
r.preferred; // NON-BINDING: { dancer_id, why } where the school (else the region, else recent rows) singles one out
|
|
225
|
+
r.initials; // an initials-only name with a school: { open, heldByDanceUp, refuted: [{ dancer_id, why, fact }], year }
|
|
224
226
|
r.unlinked; // rows printing a matched name that the release linked to no dancer
|
|
225
227
|
|
|
226
228
|
await rel.dancers.search({ surname: "Quellan" }); // or { like: "a* quellan" }, or { name }
|
|
@@ -270,6 +272,79 @@ for a caller to weigh, and `arm` stays as counted. A `lineage` match ranks with
|
|
|
270
272
|
each singles out neither. The `score` orders candidates and is no
|
|
271
273
|
probability.
|
|
272
274
|
|
|
275
|
+
AN INITIALS-ONLY NAME (`Butler, A`, every given field one letter) with a school the release
|
|
276
|
+
resolves is narrowed by the evidence the question itself carries, where more than one candidate
|
|
277
|
+
is left. A candidate is REFUTED only by a hard fact (`r.initials.refuted`, each with its `fact` in
|
|
278
|
+
words):
|
|
279
|
+
|
|
280
|
+
- `school`: every school row of the dancer up to the asked year reads to a school id (an id
|
|
281
|
+
followed through the redirects, a print read by `rel.schools`), and none of them is the asked
|
|
282
|
+
school or a school its line had joined by that year (lineage edges dated in or before the asked
|
|
283
|
+
year). A dancer with no school row, or a print no school reads, is unknown and never refuted. A
|
|
284
|
+
dancer that ever danced for the asked school's line is never refuted by the school.
|
|
285
|
+
- `age`: the birth window misses the asked band even with one band's dance-up (`DANCE_UP_YEARS`
|
|
286
|
+
of `@finbheara/domain/age`: a dancer may enter the band one year older than the dancer's own). A
|
|
287
|
+
candidate the age set aside that the dance-up holds stays open (`r.initials.heldByDanceUp`).
|
|
288
|
+
- `population`, `region`: the contradictions above.
|
|
289
|
+
|
|
290
|
+
`r.initials.open` is every candidate no hard fact refutes. The arm is `unique` ONLY where exactly
|
|
291
|
+
one candidate is open and the age did not set it aside: the candidates the school refuted then
|
|
292
|
+
move to `excluded` (`why: "school"`). Otherwise the arm stays `ambiguous` with every candidate,
|
|
293
|
+
and where the school and the region single out no one, `preferred` names the only open candidate
|
|
294
|
+
with a row in the asked year or the year before. A full given name is never narrowed this way: two
|
|
295
|
+
full given names that differ are two names, and the school only orders them.
|
|
296
|
+
|
|
297
|
+
THE REGIONAL OIREACHTAS (`oireachtas: { region, year? }`). A dancer enters one
|
|
298
|
+
residence-qualifying regional Oireachtas a year. Two regionals in one year are two dancers, the
|
|
299
|
+
overseas entry excepted. The release already applies that rule to each dancer-year it publishes:
|
|
300
|
+
`dancer_years.region` with `region_source = "current"` is the one regional the dancer attended that
|
|
301
|
+
year, the dancer's own overseas entries left out and a year with two regionals given no `current`
|
|
302
|
+
region. Where a year has no regional, an Australian or New Zealand national stands in. The client
|
|
303
|
+
reads those rows and nothing else (`rel.dancers.years` serves them all).
|
|
304
|
+
|
|
305
|
+
- `region` is the release's own spelling, the codes `dancer_years.region` prints (`SRO`, `MAO`,
|
|
306
|
+
`ENG_SOUTH`, ...), case folded. A region the release reads no attended year in narrows and orders
|
|
307
|
+
nothing, and `r.oireachtas.note` says so.
|
|
308
|
+
- `year` is the regional's own calendar year, `asOf`'s year where none is given. The calendar year
|
|
309
|
+
is the only unit (an age is an age on 1 January of the competition's year, as
|
|
310
|
+
`@finbheara/domain/age` reads it), so a regional held in December 2026 is `year: 2026`, read
|
|
311
|
+
against `dancer_years.year` as it is, never shifted by month.
|
|
312
|
+
- THE DENOMINATOR is the candidate's attended (`current`) dancer-years at or before the asked
|
|
313
|
+
year, counted on the candidate (`region.attended`). Later years are not read. A `carried` or
|
|
314
|
+
`carried-back` row is not read: it repeats an attended year, which is read directly. A `school`
|
|
315
|
+
or `cocompetitor` row is not read: it is a vote of other dancers' regions, a prior for a
|
|
316
|
+
dancer-year with no card of its own, not evidence about this one.
|
|
317
|
+
- A `current` year may rest on a registration alone: a no-show still says where the dancer lives.
|
|
318
|
+
So it decides the region, and never alone a contradiction.
|
|
319
|
+
- A DANCED REGIONAL is a row at a `T3` competition that year whose address is on the floor. The
|
|
320
|
+
release publishes no residence flag, and on the event roster every `T3` event is a residence
|
|
321
|
+
qualifier and every residence qualifier is `T3`, so an attended year with a `T3` row was read from
|
|
322
|
+
a regional, and one without from a national standing in for one. ON THE FLOOR is the release's
|
|
323
|
+
own absence rule, read from the row's `place_printed`, `atts` and `withdrawn`: an address with a
|
|
324
|
+
printed absence (`NS`, `DNS`, `DNA`, `No Show`, `Did Not Attend`, `Did Not Compete`, in the place
|
|
325
|
+
cell or as an `atts` token) or a DNT (`withdrawn` `DNT`, or `did-not-start` in older releases) on
|
|
326
|
+
any of its rows danced nothing there. A bare `NP` or `NR` is a dancer placed nowhere, on the
|
|
327
|
+
floor.
|
|
328
|
+
|
|
329
|
+
`evidence.region` is one of:
|
|
330
|
+
|
|
331
|
+
| word | counts | weight |
|
|
332
|
+
|---|---|---|
|
|
333
|
+
| `contradicts` | the asked year is attended in another region, and the dancer danced a regional that year: set aside (`why: "region"`) | excluded |
|
|
334
|
+
| `same` | the latest attended year's region is the asked one | 2 where that year is the asked year, 1 where earlier |
|
|
335
|
+
| `moved` | the latest attended year's region is another one (an earlier year, or a national in the asked year) | 0 |
|
|
336
|
+
| `unknown` | no attended year at or before the asked year | 0 |
|
|
337
|
+
| `unasked` | no `oireachtas` asked | 0 |
|
|
338
|
+
|
|
339
|
+
`region` on a candidate is the deciding dancer-year (`{ year, region, regional, attended }`): the
|
|
340
|
+
asked year where it contradicts, else the latest attended one. `moved` weighs nothing: dancers
|
|
341
|
+
move, and no rate at which dancers move is measured, so it is said and never scored. Candidates
|
|
342
|
+
sort by the school first, then `same` before every other region word, then `score`. Where the
|
|
343
|
+
school singles out no one, `preferred` names the only candidate of the school's first rank (every
|
|
344
|
+
candidate where no school is asked) whose region is `same`. The asked entry's own printed location
|
|
345
|
+
is not asked, so an overseas entrant is asked without `oireachtas`. A release that publishes no
|
|
346
|
+
dancer-years (feature `dancers.years`) reads every candidate `unknown`, with the note.
|
|
347
|
+
|
|
273
348
|
A FEIS-LOCAL ID (`FEIS_LOCAL_ID_FLOOR`, 2^34, and up) is valid in its release only: a candidate and a result row
|
|
274
349
|
carrying one say `scope: "per-release"` (`dancer_scope` on a row), so a caller never stores one
|
|
275
350
|
across releases. Every answer carries the release tag.
|
|
@@ -485,7 +560,8 @@ feis's championships), the band is read from the row's own titles (`titles`, by
|
|
|
485
560
|
domain package's title reader, the youngest again, and `age.from` says `title`. Nothing else
|
|
486
561
|
stands in for a band. The dancer resolver is the release's own (`rel.dancers`, above), or the
|
|
487
562
|
`dancerResolver` option. With `dancerResolver: null`, each row's dancer answers `unavailable`
|
|
488
|
-
and the competitions still resolve.
|
|
563
|
+
and the competitions still resolve. A row's `oireachtas`, where the list is a regional's roster,
|
|
564
|
+
is passed to the dancer resolver as asked (`rel.dancers`, above).
|
|
489
565
|
|
|
490
566
|
## The command line
|
|
491
567
|
|
|
@@ -506,7 +582,7 @@ and the competitions still resolve.
|
|
|
506
582
|
idq dancer [--release <spec>] <name> | --surname <s> | --like <glob> | --id <dancer_id>
|
|
507
583
|
[--order surname-first|given-first] [--school <print|id>]
|
|
508
584
|
[--yob <y> | --band <band> [--year <y>] | --comp <competition>] [--as-of <date>]
|
|
509
|
-
[--population girls|boys] [--rows]
|
|
585
|
+
[--population girls|boys] [--oireachtas <region>[:<year>]] [--rows]
|
|
510
586
|
idq results [--release <spec>] [--dancer <id>] [--feis <id>] [--comp <c>] [--school <s>] [--year <y>] [--limit <n>]
|
|
511
587
|
idq majors [--release <spec>] [--event <e>] [--year <y>] [--comp <c>] [--dancer <id>] [--rows]
|
|
512
588
|
idq stream [--release <spec>] --scope majors|transcribed|platform|all [--entries] [--event <e,...>]
|
|
@@ -525,6 +601,7 @@ and the competitions still resolve.
|
|
|
525
601
|
idq syllabus [--release <spec>] --for <series> [year]
|
|
526
602
|
idq resolve comp [<feis> <code>] [--year y] [--title t]
|
|
527
603
|
idq resolve dancer [<name>] [--school s] [--comp <feis>/<code> | --yob y | --band b --year y]
|
|
604
|
+
[--oireachtas <region>[:<year>]]
|
|
528
605
|
idq resolve registrations
|
|
529
606
|
|
|
530
607
|
`stream` prints one JSON line per row (or entry), as it reads them. `dancer` prints the results of the one dancer where the answer is unique (every candidate's with
|
|
@@ -532,7 +609,8 @@ and the competitions still resolve.
|
|
|
532
609
|
|
|
533
610
|
`resolve` speaks JSON lines: one answer per line out, and with no positional question the
|
|
534
611
|
questions are JSON lines on stdin, one per line (`{feis, code, year?, title?}`,
|
|
535
|
-
`{name, school?, age?, population
|
|
612
|
+
`{name, school?, age?, population?, oireachtas?}`,
|
|
613
|
+
`{name, school?, codes, feis, year?, population?, oireachtas?}`). A line that is no JSON object,
|
|
536
614
|
or no question of its kind, answers `{tag, line, error}` and the other lines still answer. The
|
|
537
615
|
exit is non-zero where any line erred. A dancer's age may be given as a comp
|
|
538
616
|
(`{"comp": "<feis>/<code>"}`, or `--comp` on the command line): `rel.registrations.dancer` reads
|
|
@@ -67,7 +67,7 @@ function sha256OfDigest(digest) {
|
|
|
67
67
|
return m === null ? null : m[1].toLowerCase();
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
import { Age } from "@finbheara/domain/age";
|
|
70
|
+
import { Age, DANCE_UP_YEARS, birthYearsMeet } from "@finbheara/domain/age";
|
|
71
71
|
import { createIndex, indexSchema, personEncoder } from "@finbheara/domain/noun-index";
|
|
72
72
|
import domainPkg from "@finbheara/domain/package.json";
|
|
73
73
|
import { dancerName } from "@finbheara/domain/person";
|
|
@@ -315,6 +315,30 @@ class FeisFinder2 {
|
|
|
315
315
|
}
|
|
316
316
|
}
|
|
317
317
|
|
|
318
|
+
var NO_PLACE = new Set(["NP", "NR", "N/A", "NA", "NO RANK", "NORANK", "NO PLACE", "-", "--"]);
|
|
319
|
+
var ABSENT = new Set(["DID NOT COMPETE", "DID NOT ATTEND", "NO SHOW", "DNA", "DNS", "NS"]);
|
|
320
|
+
var ABSENT_WORDS = /not\s*attend|no\s*show/i;
|
|
321
|
+
var DID_NOT_TABULATE = new Set(["DNT", "did-not-start"]);
|
|
322
|
+
function printsAbsence(print) {
|
|
323
|
+
const s = print.trim();
|
|
324
|
+
if (s === "")
|
|
325
|
+
return false;
|
|
326
|
+
const upper = s.toUpperCase();
|
|
327
|
+
if (NO_PLACE.has(upper))
|
|
328
|
+
return false;
|
|
329
|
+
return ABSENT.has(upper) || ABSENT_WORDS.test(s);
|
|
330
|
+
}
|
|
331
|
+
function notOnTheFloor(placePrinted, atts, withdrawn) {
|
|
332
|
+
if (printsAbsence(placePrinted ?? ""))
|
|
333
|
+
return true;
|
|
334
|
+
if (atts !== null && atts !== "") {
|
|
335
|
+
for (const a of atts.split(","))
|
|
336
|
+
if (printsAbsence(a))
|
|
337
|
+
return true;
|
|
338
|
+
}
|
|
339
|
+
return withdrawn !== null && DID_NOT_TABULATE.has(withdrawn);
|
|
340
|
+
}
|
|
341
|
+
|
|
318
342
|
var ENTRY_RANK = new Map([
|
|
319
343
|
["final", 0],
|
|
320
344
|
["", 1],
|
|
@@ -585,6 +609,21 @@ class MajorsFinder2 {
|
|
|
585
609
|
}
|
|
586
610
|
|
|
587
611
|
var LINEAGE_FILE = "school-lineage.jsonl";
|
|
612
|
+
function schoolLine(lineage, ids, year) {
|
|
613
|
+
const reached = new Set(ids);
|
|
614
|
+
const todo = [...ids];
|
|
615
|
+
for (let id = todo.pop();id !== undefined; id = todo.pop())
|
|
616
|
+
for (const [o, y] of lineage.get(id) ?? [])
|
|
617
|
+
if (!reached.has(o) && (year === null || y === null || y <= year)) {
|
|
618
|
+
reached.add(o);
|
|
619
|
+
todo.push(o);
|
|
620
|
+
}
|
|
621
|
+
return reached;
|
|
622
|
+
}
|
|
623
|
+
function initialsOnly2(name) {
|
|
624
|
+
const g = name.givenFields();
|
|
625
|
+
return g.length > 0 && g.every((f) => f.length === 1);
|
|
626
|
+
}
|
|
588
627
|
function nameOrderOf(s) {
|
|
589
628
|
return s === "surname-first" || s === "given-first" || s === "unknown" ? s : undefined;
|
|
590
629
|
}
|
|
@@ -597,7 +636,7 @@ var PERSON = { table: "person", value: "id", valueType: "INTEGER PRIMARY KEY" };
|
|
|
597
636
|
var ASKED = ["surname_key", "nn4", "blk_surname"];
|
|
598
637
|
var dancersIndex = {
|
|
599
638
|
name: "dancers",
|
|
600
|
-
version: "
|
|
639
|
+
version: "4",
|
|
601
640
|
inputs: ["results"],
|
|
602
641
|
keyParts: () => [...PACKAGE_KEY_PARTS],
|
|
603
642
|
says: "every published dancer print at the names package's keys, its dancers, schools and years",
|
|
@@ -608,6 +647,7 @@ var dancersIndex = {
|
|
|
608
647
|
out.run("CREATE TABLE dancer(dancer_id INTEGER PRIMARY KEY, display TEXT NOT NULL, names_printed TEXT NOT NULL, genders TEXT NOT NULL, appearances INTEGER NOT NULL, kind TEXT, birth_lo INTEGER, birth_hi INTEGER, birth_source TEXT NOT NULL, birth_conflict INTEGER NOT NULL, rows INTEGER NOT NULL, year_lo INTEGER, year_hi INTEGER)");
|
|
609
648
|
out.run("CREATE TABLE dancer_school(dancer_id INTEGER NOT NULL, school_id TEXT, print TEXT NOT NULL, rows INTEGER NOT NULL, year_lo INTEGER, year_hi INTEGER)");
|
|
610
649
|
out.run("CREATE TABLE dancer_population(dancer_id INTEGER NOT NULL, population TEXT NOT NULL, rows INTEGER NOT NULL, PRIMARY KEY(dancer_id, population)) WITHOUT ROWID");
|
|
650
|
+
out.run("CREATE TABLE dancer_regional(dancer_id INTEGER NOT NULL, year INTEGER NOT NULL, region TEXT NOT NULL, regional INTEGER NOT NULL, PRIMARY KEY(dancer_id, year)) WITHOUT ROWID");
|
|
611
651
|
const src = rel.db("results");
|
|
612
652
|
const groups = src.query(`SELECT r.name_printed AS p, r.name_order_resolved AS o, r.dancer_id AS d,
|
|
613
653
|
r.school_printed AS sp, r.school_id AS s,
|
|
@@ -682,6 +722,25 @@ var dancersIndex = {
|
|
|
682
722
|
if (pop === "girls" || pop === "boys")
|
|
683
723
|
putPop.run(r.d, pop, r.n);
|
|
684
724
|
}
|
|
725
|
+
if (src.query("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'dancer_years'").get() !== null) {
|
|
726
|
+
const cols = new Set(src.query("PRAGMA table_info(results)").all().map((c) => c.name));
|
|
727
|
+
const col = (c) => cols.has(c) ? `r.${c}` : "NULL";
|
|
728
|
+
const rows = src.query(`SELECT r.dancer_id AS d, c.year AS y, r.address AS a, ${col("place_printed")} AS p,
|
|
729
|
+
${col("atts")} AS t, ${col("withdrawn")} AS w
|
|
730
|
+
FROM results r JOIN competitions c ON c.file = r.file AND c.line = r.competition_line
|
|
731
|
+
WHERE r.dancer_id IS NOT NULL AND c.tier = 'T3' AND c.year IS NOT NULL`).all();
|
|
732
|
+
const absent = new Set;
|
|
733
|
+
for (const r of rows)
|
|
734
|
+
if (notOnTheFloor(r.p, r.t, r.w))
|
|
735
|
+
absent.add(r.a);
|
|
736
|
+
const t3 = new Set;
|
|
737
|
+
for (const r of rows)
|
|
738
|
+
if (!absent.has(r.a))
|
|
739
|
+
t3.add(`${r.d}\x00${r.y}`);
|
|
740
|
+
const putReg = out.prepare("INSERT INTO dancer_regional VALUES (?, ?, ?, ?)");
|
|
741
|
+
for (const r of src.query("SELECT dancer_id AS d, year AS y, region AS r FROM dancer_years WHERE region_source = 'current' AND region IS NOT NULL").all())
|
|
742
|
+
putReg.run(r.d, r.y, r.r, t3.has(`${r.d}\x00${r.y}`) ? 1 : 0);
|
|
743
|
+
}
|
|
685
744
|
for (const s of schema.indexes)
|
|
686
745
|
if (ASKED.some((c) => s.endsWith(`(${c})`)))
|
|
687
746
|
out.run(s);
|
|
@@ -734,6 +793,21 @@ var POPULATION_WEIGHT = {
|
|
|
734
793
|
unasked: 0,
|
|
735
794
|
contradicts: -10
|
|
736
795
|
};
|
|
796
|
+
var REGION_WEIGHT = {
|
|
797
|
+
same: 1,
|
|
798
|
+
unknown: 0,
|
|
799
|
+
unasked: 0,
|
|
800
|
+
moved: 0,
|
|
801
|
+
contradicts: -10
|
|
802
|
+
};
|
|
803
|
+
var REGION_SAME_THAT_YEAR = 2;
|
|
804
|
+
var REGION_RANK = {
|
|
805
|
+
same: 0,
|
|
806
|
+
unknown: 1,
|
|
807
|
+
unasked: 1,
|
|
808
|
+
moved: 1,
|
|
809
|
+
contradicts: 2
|
|
810
|
+
};
|
|
737
811
|
var SCHOOL_WEIGHT = {
|
|
738
812
|
same: 2,
|
|
739
813
|
lineage: 2,
|
|
@@ -752,7 +826,9 @@ function idChunks(ids) {
|
|
|
752
826
|
class DancerResolver2 {
|
|
753
827
|
rel;
|
|
754
828
|
printIds = new Map;
|
|
829
|
+
rowIds = new Map;
|
|
755
830
|
lineageOf;
|
|
831
|
+
regions;
|
|
756
832
|
constructor(rel) {
|
|
757
833
|
this.rel = rel;
|
|
758
834
|
}
|
|
@@ -762,15 +838,17 @@ class DancerResolver2 {
|
|
|
762
838
|
return null;
|
|
763
839
|
await this.rel.fetch(LINEAGE_FILE);
|
|
764
840
|
const out = new Map;
|
|
765
|
-
const join = (a, b) => {
|
|
766
|
-
const
|
|
767
|
-
|
|
768
|
-
|
|
841
|
+
const join = (a, b, year) => {
|
|
842
|
+
const m = out.get(a) ?? new Map;
|
|
843
|
+
const was = m.get(b);
|
|
844
|
+
m.set(b, was === undefined ? year : was === null || year === null ? null : Math.min(was, year));
|
|
845
|
+
out.set(a, m);
|
|
769
846
|
};
|
|
770
847
|
for (const r of readJsonl(this.rel.path(LINEAGE_FILE)))
|
|
771
848
|
if (r.id !== r.other) {
|
|
772
|
-
|
|
773
|
-
join(r.
|
|
849
|
+
const year = typeof r.year === "number" ? r.year : null;
|
|
850
|
+
join(r.id, r.other, year);
|
|
851
|
+
join(r.other, r.id, year);
|
|
774
852
|
}
|
|
775
853
|
return out;
|
|
776
854
|
})();
|
|
@@ -880,6 +958,7 @@ class DancerResolver2 {
|
|
|
880
958
|
const asOf = yearOf(q.asOf);
|
|
881
959
|
const age = q.age === undefined ? undefined : this.readAge(q.age, asOf);
|
|
882
960
|
const population = q.population === undefined ? undefined : readPopulation2(q.population);
|
|
961
|
+
const oireachtas = q.oireachtas === undefined ? undefined : await this.readOireachtas(db, q.oireachtas, asOf);
|
|
883
962
|
let schoolIds = null;
|
|
884
963
|
let lineageIds = [];
|
|
885
964
|
let school;
|
|
@@ -891,15 +970,7 @@ class DancerResolver2 {
|
|
|
891
970
|
school = { arm: s.arm, ids: schoolIds };
|
|
892
971
|
else {
|
|
893
972
|
const asked = new Set(schoolIds);
|
|
894
|
-
|
|
895
|
-
const todo = [...schoolIds];
|
|
896
|
-
for (let id = todo.pop();id !== undefined; id = todo.pop())
|
|
897
|
-
for (const o of lineage.get(id) ?? [])
|
|
898
|
-
if (!reached.has(o)) {
|
|
899
|
-
reached.add(o);
|
|
900
|
-
todo.push(o);
|
|
901
|
-
}
|
|
902
|
-
lineageIds = [...reached].filter((id) => !asked.has(id)).sort();
|
|
973
|
+
lineageIds = [...schoolLine(lineage, schoolIds, null)].filter((id) => !asked.has(id)).sort();
|
|
903
974
|
school = { arm: s.arm, ids: schoolIds, lineage: lineageIds };
|
|
904
975
|
}
|
|
905
976
|
}
|
|
@@ -929,23 +1000,36 @@ class DancerResolver2 {
|
|
|
929
1000
|
const pop = populationOf(db, id);
|
|
930
1001
|
const popEv = populationEvidence(pop, population?.read ?? null);
|
|
931
1002
|
const schoolEv = schoolIds === null ? "unasked" : schoolIds.length === 0 ? "unresolved" : await this.schoolEvidence(schools, schoolIds, lineageIds, asOf);
|
|
1003
|
+
const reg = oireachtas === undefined ? null : oireachtas.read === null ? {
|
|
1004
|
+
word: "unknown",
|
|
1005
|
+
region: { year: null, region: null, regional: false, attended: 0 }
|
|
1006
|
+
} : regionEvidence(db, id, oireachtas.read, oireachtas.year);
|
|
1007
|
+
const regionEv = reg === null ? "unasked" : reg.word;
|
|
1008
|
+
const regionWeight = regionEv === "same" && reg?.region.year === oireachtas?.year ? REGION_SAME_THAT_YEAR : REGION_WEIGHT[regionEv];
|
|
932
1009
|
all.push({
|
|
933
1010
|
dancer_id: id,
|
|
934
1011
|
display: d.display,
|
|
935
1012
|
scope: id >= FEIS_LOCAL_ID_FLOOR2 ? "per-release" : "stable",
|
|
936
1013
|
kind: d.kind,
|
|
937
|
-
score: NAME_WEIGHT[e.level] + AGE_WEIGHT[ageEv] + SCHOOL_WEIGHT[schoolEv] + POPULATION_WEIGHT[popEv],
|
|
938
|
-
evidence: {
|
|
1014
|
+
score: NAME_WEIGHT[e.level] + AGE_WEIGHT[ageEv] + SCHOOL_WEIGHT[schoolEv] + POPULATION_WEIGHT[popEv] + regionWeight,
|
|
1015
|
+
evidence: {
|
|
1016
|
+
nameLevel: e.level,
|
|
1017
|
+
age: ageEv,
|
|
1018
|
+
school: schoolEv,
|
|
1019
|
+
population: popEv,
|
|
1020
|
+
region: regionEv
|
|
1021
|
+
},
|
|
939
1022
|
prints: e.prints.sort((a, b) => b.rows - a.rows || (a.print < b.print ? -1 : 1)),
|
|
940
1023
|
rows: d.rows,
|
|
941
1024
|
year_lo: d.year_lo,
|
|
942
1025
|
year_hi: d.year_hi,
|
|
943
1026
|
birth: birthOf(d),
|
|
944
1027
|
population: pop,
|
|
945
|
-
school: latest
|
|
1028
|
+
school: latest,
|
|
1029
|
+
...reg !== null ? { region: reg.region } : {}
|
|
946
1030
|
});
|
|
947
1031
|
}
|
|
948
|
-
all.sort((a, b) => SCHOOL_RANK[a.evidence.school] - SCHOOL_RANK[b.evidence.school] || b.score - a.score || b.rows - a.rows || a.dancer_id - b.dancer_id);
|
|
1032
|
+
all.sort((a, b) => SCHOOL_RANK[a.evidence.school] - SCHOOL_RANK[b.evidence.school] || REGION_RANK[a.evidence.region] - REGION_RANK[b.evidence.region] || b.score - a.score || b.rows - a.rows || a.dancer_id - b.dancer_id);
|
|
949
1033
|
const excluded = [];
|
|
950
1034
|
let kept = all;
|
|
951
1035
|
if (narrow)
|
|
@@ -954,10 +1038,61 @@ class DancerResolver2 {
|
|
|
954
1038
|
excluded.push({ candidate: c, why: "age" });
|
|
955
1039
|
else if (c.evidence.population === "contradicts")
|
|
956
1040
|
excluded.push({ candidate: c, why: "population" });
|
|
1041
|
+
else if (c.evidence.region === "contradicts")
|
|
1042
|
+
excluded.push({ candidate: c, why: "region" });
|
|
957
1043
|
else
|
|
958
1044
|
return true;
|
|
959
1045
|
return false;
|
|
960
1046
|
});
|
|
1047
|
+
const year = askedYear(q, asOf);
|
|
1048
|
+
let initials;
|
|
1049
|
+
if (narrow && kept.length > 1 && schoolIds !== null && schoolIds.length > 0 && initialsOnly2(dancerName(q.name, q.order === "unknown" ? undefined : q.order))) {
|
|
1050
|
+
const lineage = await this.lineage();
|
|
1051
|
+
const line = lineage === null ? new Set(schoolIds) : schoolLine(lineage, schoolIds, year);
|
|
1052
|
+
const band = age?.age?.birthYears() ?? null;
|
|
1053
|
+
const slack = q.age !== undefined && !("yob" in q.age) ? DANCE_UP_YEARS : 0;
|
|
1054
|
+
const open = [];
|
|
1055
|
+
const held = [];
|
|
1056
|
+
const refuted = [];
|
|
1057
|
+
const bySchool = new Set;
|
|
1058
|
+
const schoolFact = async (c) => {
|
|
1059
|
+
const fact = await this.schoolRefutes(schoolsOf(db, c.dancer_id), line, year, q.school);
|
|
1060
|
+
if (fact === null)
|
|
1061
|
+
return false;
|
|
1062
|
+
refuted.push({ dancer_id: c.dancer_id, why: "school", fact });
|
|
1063
|
+
bySchool.add(c.dancer_id);
|
|
1064
|
+
return true;
|
|
1065
|
+
};
|
|
1066
|
+
for (const c of kept)
|
|
1067
|
+
if (!await schoolFact(c))
|
|
1068
|
+
open.push(c);
|
|
1069
|
+
for (const x of excluded) {
|
|
1070
|
+
const c = x.candidate;
|
|
1071
|
+
const own = { from: c.birth.lo, to: c.birth.hi };
|
|
1072
|
+
if (x.why === "age" && band !== null && slack > 0 && birthYearsMeet(band, own, slack)) {
|
|
1073
|
+
if (!await schoolFact(c))
|
|
1074
|
+
held.push(c.dancer_id);
|
|
1075
|
+
continue;
|
|
1076
|
+
}
|
|
1077
|
+
refuted.push({
|
|
1078
|
+
dancer_id: c.dancer_id,
|
|
1079
|
+
why: x.why,
|
|
1080
|
+
fact: contradictionFact(x, age, slack)
|
|
1081
|
+
});
|
|
1082
|
+
}
|
|
1083
|
+
initials = {
|
|
1084
|
+
open: [...open.map((c) => c.dancer_id), ...held],
|
|
1085
|
+
heldByDanceUp: held,
|
|
1086
|
+
refuted,
|
|
1087
|
+
year
|
|
1088
|
+
};
|
|
1089
|
+
if (open.length === 1 && held.length === 0) {
|
|
1090
|
+
for (const c of kept)
|
|
1091
|
+
if (bySchool.has(c.dancer_id))
|
|
1092
|
+
excluded.push({ candidate: c, why: "school" });
|
|
1093
|
+
kept = open;
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
961
1096
|
let preferred;
|
|
962
1097
|
if (kept.length > 1 && school !== undefined)
|
|
963
1098
|
for (const rank of [SCHOOL_RANK.same, SCHOOL_RANK.moved]) {
|
|
@@ -973,6 +1108,28 @@ class DancerResolver2 {
|
|
|
973
1108
|
}
|
|
974
1109
|
break;
|
|
975
1110
|
}
|
|
1111
|
+
if (preferred === undefined && kept.length > 1 && oireachtas?.read != null) {
|
|
1112
|
+
const best = Math.min(...kept.map((c) => SCHOOL_RANK[c.evidence.school]));
|
|
1113
|
+
const hit = kept.filter((c) => SCHOOL_RANK[c.evidence.school] === best && c.evidence.region === "same");
|
|
1114
|
+
if (hit.length === 1) {
|
|
1115
|
+
const c = hit[0];
|
|
1116
|
+
preferred = {
|
|
1117
|
+
dancer_id: c.dancer_id,
|
|
1118
|
+
why: `the only candidate${school !== undefined ? " of the school's first rank" : ""} whose latest attended region is ${oireachtas.read}: ${c.region?.year} of ${c.region?.attended} attended year(s) to ${oireachtas.year}`
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
if (preferred === undefined && kept.length > 1 && initials !== undefined) {
|
|
1123
|
+
const openIds = new Set(initials.open);
|
|
1124
|
+
const hit = kept.filter((c) => openIds.has(c.dancer_id) && c.year_hi !== null && c.year_hi >= year - 1);
|
|
1125
|
+
if (hit.length === 1) {
|
|
1126
|
+
const c = hit[0];
|
|
1127
|
+
preferred = {
|
|
1128
|
+
dancer_id: c.dancer_id,
|
|
1129
|
+
why: `the only candidate no hard fact refutes with a row in ${year - 1} or ${year}`
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
976
1133
|
return {
|
|
977
1134
|
tag: this.rel.tag,
|
|
978
1135
|
asked: q,
|
|
@@ -983,9 +1140,33 @@ class DancerResolver2 {
|
|
|
983
1140
|
unlinked: [...unlinked].map(([print, rows]) => ({ print, rows })).sort((a, b) => b.rows - a.rows || (a.print < b.print ? -1 : 1)),
|
|
984
1141
|
...age !== undefined ? { age: age.answer } : {},
|
|
985
1142
|
...population !== undefined ? { population } : {},
|
|
986
|
-
...
|
|
1143
|
+
...oireachtas !== undefined ? { oireachtas } : {},
|
|
1144
|
+
...school !== undefined ? { school } : {},
|
|
1145
|
+
...initials !== undefined ? { initials } : {}
|
|
987
1146
|
};
|
|
988
1147
|
}
|
|
1148
|
+
async readOireachtas(db, o, asOf) {
|
|
1149
|
+
const year = o.year ?? asOf ?? new Date().getFullYear();
|
|
1150
|
+
const asked = o.region;
|
|
1151
|
+
if ((await this.rel.capability("dancers.years")).state !== "full")
|
|
1152
|
+
return {
|
|
1153
|
+
asked,
|
|
1154
|
+
read: null,
|
|
1155
|
+
year,
|
|
1156
|
+
note: "this release publishes no dancer-years: the region narrows and orders nothing"
|
|
1157
|
+
};
|
|
1158
|
+
this.regions ??= db.query("SELECT DISTINCT region FROM dancer_regional ORDER BY region").all().map((r) => r.region);
|
|
1159
|
+
const want = asked.trim().toUpperCase();
|
|
1160
|
+
const hit = this.regions.find((r) => r.toUpperCase() === want);
|
|
1161
|
+
if (hit === undefined)
|
|
1162
|
+
return {
|
|
1163
|
+
asked,
|
|
1164
|
+
read: null,
|
|
1165
|
+
year,
|
|
1166
|
+
note: `the release reads no attended year in a region "${asked}" (its spelling is dancer_years.region): it narrows and orders nothing`
|
|
1167
|
+
};
|
|
1168
|
+
return { asked, read: hit, year };
|
|
1169
|
+
}
|
|
989
1170
|
async schoolEvidence(schools, ids, lineage, asOf) {
|
|
990
1171
|
const rows = schools.filter((s) => asOf === null || s.year_lo === null || s.year_lo <= asOf);
|
|
991
1172
|
const idsOf = async (s) => {
|
|
@@ -1014,6 +1195,31 @@ class DancerResolver2 {
|
|
|
1014
1195
|
}
|
|
1015
1196
|
return joined ? "lineage" : earlier ? "moved" : "none";
|
|
1016
1197
|
}
|
|
1198
|
+
async schoolRefutes(schools, line, year, asked) {
|
|
1199
|
+
const rows = schools.filter((s) => s.year_lo === null || s.year_lo <= year);
|
|
1200
|
+
if (rows.length === 0)
|
|
1201
|
+
return null;
|
|
1202
|
+
const seen = new Set;
|
|
1203
|
+
for (const s of rows) {
|
|
1204
|
+
const own = await this.schoolIdsOf(s);
|
|
1205
|
+
if (own.length === 0 || own.some((id) => line.has(id)))
|
|
1206
|
+
return null;
|
|
1207
|
+
for (const id of own)
|
|
1208
|
+
seen.add(id);
|
|
1209
|
+
}
|
|
1210
|
+
const last = latestSchool(rows, year);
|
|
1211
|
+
return `every school row to ${year} reads ${[...seen].sort().join(", ")} (the latest ${last?.school_id ?? last?.print} in ${last?.year_hi}), none of them ${asked ?? "the asked school"} or a school its line joined by ${year}`;
|
|
1212
|
+
}
|
|
1213
|
+
async schoolIdsOf(s) {
|
|
1214
|
+
const key = s.school_id ?? s.print;
|
|
1215
|
+
let read = this.rowIds.get(key);
|
|
1216
|
+
if (read === undefined) {
|
|
1217
|
+
const got = (await this.rel.schools.resolve(key)).candidates.map((c) => c.school_id);
|
|
1218
|
+
read = s.school_id === null ? got : [...new Set([s.school_id, ...got])];
|
|
1219
|
+
this.rowIds.set(key, read);
|
|
1220
|
+
}
|
|
1221
|
+
return read;
|
|
1222
|
+
}
|
|
1017
1223
|
readAge(a, asOf) {
|
|
1018
1224
|
const done = (age, note) => {
|
|
1019
1225
|
const read = age?.isAge() ? age : null;
|
|
@@ -1092,6 +1298,22 @@ function populationEvidence(own, asked) {
|
|
|
1092
1298
|
return "unknown";
|
|
1093
1299
|
return populationRelation(asked, mine) === "disjoint" ? "contradicts" : "same";
|
|
1094
1300
|
}
|
|
1301
|
+
function regionEvidence(db, dancerId, region, year) {
|
|
1302
|
+
const rows = db.query("SELECT year, region, regional FROM dancer_regional WHERE dancer_id = ? AND year <= ? ORDER BY year").all(dancerId, year);
|
|
1303
|
+
const attended = rows.length;
|
|
1304
|
+
const at = (r) => ({
|
|
1305
|
+
year: r.year,
|
|
1306
|
+
region: r.region,
|
|
1307
|
+
regional: r.regional === 1,
|
|
1308
|
+
attended
|
|
1309
|
+
});
|
|
1310
|
+
const latest = rows.at(-1);
|
|
1311
|
+
if (latest === undefined)
|
|
1312
|
+
return { word: "unknown", region: { year: null, region: null, regional: false, attended } };
|
|
1313
|
+
if (latest.year === year && latest.regional === 1 && latest.region !== region)
|
|
1314
|
+
return { word: "contradicts", region: at(latest) };
|
|
1315
|
+
return { word: latest.region === region ? "same" : "moved", region: at(latest) };
|
|
1316
|
+
}
|
|
1095
1317
|
function ageEvidence(d, asked) {
|
|
1096
1318
|
if (asked === null)
|
|
1097
1319
|
return "unasked";
|
|
@@ -1106,6 +1328,26 @@ function ageEvidence(d, asked) {
|
|
|
1106
1328
|
return "overlaps";
|
|
1107
1329
|
return "contradicts";
|
|
1108
1330
|
}
|
|
1331
|
+
function askedYear(q, asOf) {
|
|
1332
|
+
if (asOf !== null)
|
|
1333
|
+
return asOf;
|
|
1334
|
+
const a = q.age;
|
|
1335
|
+
if (a !== undefined && !("yob" in a) && typeof a.year === "number")
|
|
1336
|
+
return a.year;
|
|
1337
|
+
return new Date().getFullYear();
|
|
1338
|
+
}
|
|
1339
|
+
function contradictionFact(x, age, slack) {
|
|
1340
|
+
const c = x.candidate;
|
|
1341
|
+
if (x.why === "age") {
|
|
1342
|
+
const w = age?.answer.birth;
|
|
1343
|
+
return `born ${c.birth.lo ?? "?"}-${c.birth.hi ?? "?"}, outside ${age?.answer.read ?? "the asked age"} (born ${w?.from ?? "any"}-${w?.to ?? "any"})${slack > 0 ? ` even with ${slack} year's dance-up` : ""}`;
|
|
1344
|
+
}
|
|
1345
|
+
if (x.why === "population")
|
|
1346
|
+
return `published in the other population's majors solo competitions only (girls ${c.population.girls}, boys ${c.population.boys})`;
|
|
1347
|
+
if (x.why === "region")
|
|
1348
|
+
return `danced the ${c.region?.region} regional in ${c.region?.year}, another regional that year`;
|
|
1349
|
+
return "set aside by the school";
|
|
1350
|
+
}
|
|
1109
1351
|
|
|
1110
1352
|
import { Age as Age2 } from "@finbheara/domain/age";
|
|
1111
1353
|
import {
|
|
@@ -2337,7 +2579,8 @@ class RegistrationResolver2 {
|
|
|
2337
2579
|
...row.school !== undefined ? { school: row.school } : {},
|
|
2338
2580
|
...age !== null ? { age: { band: age.band, year: age.year } } : {},
|
|
2339
2581
|
...row.asOf !== undefined ? { asOf: row.asOf } : {},
|
|
2340
|
-
...population !== null && "asked" in population ? { population: population.asked } : {}
|
|
2582
|
+
...population !== null && "asked" in population ? { population: population.asked } : {},
|
|
2583
|
+
...row.oireachtas !== undefined ? { oireachtas: row.oireachtas } : {}
|
|
2341
2584
|
};
|
|
2342
2585
|
const { dancer } = await this.dancer(asked);
|
|
2343
2586
|
out.push({
|
|
@@ -3286,4 +3529,4 @@ function releases2(opts = {}) {
|
|
|
3286
3529
|
return new ReleaseManager2(opts);
|
|
3287
3530
|
}
|
|
3288
3531
|
|
|
3289
|
-
export { DATABASES2, planAsset2, sha256File2, unzstdTo2, NAME_LEVELS2, nameLevel2, NO_CALENDAR2, FeisFinder2, entryRank2, FEIS_LOCAL_ID_FLOOR2, ResultFinder2, MajorsFinder2, nameOrderOf, DancerResolver2, readPopulation2, canonicalOf2, CompResolver2, StaffFinder2, SchoolResolver2, TeamFinder2, EventFinder2, defaultBuilders2, indexPath2, indexKey2, isCurrent2, buildIndex2, ensureIndex2, listIndexes2, readPin2, youngest2, dancerResolverOf2, RegistrationResolver2, ghRemote2, httpsRemote2, fallbackRemote2, setRemote2, columnsOf2, FEATURES2, capabilityOf2, needsRelease2, resolveTag2, Release2, openRelease2, openCached2, ReleaseManager2, releases2 };
|
|
3532
|
+
export { DATABASES2, planAsset2, sha256File2, unzstdTo2, NAME_LEVELS2, nameLevel2, NO_CALENDAR2, FeisFinder2, entryRank2, FEIS_LOCAL_ID_FLOOR2, ResultFinder2, MajorsFinder2, initialsOnly2, nameOrderOf, DancerResolver2, readPopulation2, canonicalOf2, CompResolver2, StaffFinder2, SchoolResolver2, TeamFinder2, EventFinder2, defaultBuilders2, indexPath2, indexKey2, isCurrent2, buildIndex2, ensureIndex2, listIndexes2, readPin2, youngest2, dancerResolverOf2, RegistrationResolver2, ghRemote2, httpsRemote2, fallbackRemote2, setRemote2, columnsOf2, FEATURES2, capabilityOf2, needsRelease2, resolveTag2, Release2, openRelease2, openCached2, ReleaseManager2, releases2 };
|
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
nameOrderOf,
|
|
5
5
|
openRelease2,
|
|
6
6
|
releases2
|
|
7
|
-
} from "./chunks/index-
|
|
7
|
+
} from "./chunks/index-hs72zekf.js";
|
|
8
8
|
import"./chunks/index-hne1wadw.js";
|
|
9
9
|
import"./chunks/index-hghdy980.js";
|
|
10
10
|
|
|
@@ -40,9 +40,12 @@ var USAGE = `usage: idq <verb> [--cache <dir>] [--repo <owner/name>] [--json]
|
|
|
40
40
|
dancer [--release <spec>] <name> | --surname <s> | --like <glob> | --id <dancer_id>
|
|
41
41
|
[--order surname-first|given-first] [--school <print|id>]
|
|
42
42
|
[--yob <y> | --band <U10> [--year <y>] | --comp <competition>] [--as-of <date>]
|
|
43
|
-
[--population girls|boys] [--rows]
|
|
43
|
+
[--population girls|boys] [--oireachtas <region>[:<year>]] [--rows]
|
|
44
44
|
the dancers a name reaches, each with its evidence
|
|
45
|
-
(name level, age, school, population) and the arm;
|
|
45
|
+
(name level, age, school, population, region) and the arm;
|
|
46
|
+
--oireachtas is the regional the roster is for, its region in
|
|
47
|
+
the release's spelling (SRO, MAO), its year the --as-of year
|
|
48
|
+
where none is given; the results of
|
|
46
49
|
the one dancer where one answers (or --rows for each)
|
|
47
50
|
results [--release <spec>] [--dancer <id>] [--feis <id>] [--comp <competition>]
|
|
48
51
|
[--school <print|id>] [--year <y>] [--limit <n>]
|
|
@@ -87,12 +90,13 @@ var USAGE = `usage: idq <verb> [--cache <dir>] [--repo <owner/name>] [--json]
|
|
|
87
90
|
resolve comp [<feis> <code>] [--year <y>] [--title <t>]
|
|
88
91
|
resolve dancer [<name>] [--school <s>] [--comp <feis>/<code> | --yob <y> | --band <b> --year <y>]
|
|
89
92
|
[--order <o>] [--as-of <date>] [--population girls|boys]
|
|
93
|
+
[--oireachtas <region>[:<year>]]
|
|
90
94
|
resolve registrations
|
|
91
95
|
JSONL out, one answer per line; with no positional the
|
|
92
96
|
questions are JSONL on stdin, one per line (a comp:
|
|
93
97
|
{feis, code, year?, title?}, a dancer: {name, school?, age?,
|
|
94
|
-
population?}, a registration: {name, school?,
|
|
95
|
-
year?, population?})
|
|
98
|
+
population?, oireachtas?}, a registration: {name, school?,
|
|
99
|
+
codes[], feis, year?, population?, oireachtas?})
|
|
96
100
|
|
|
97
101
|
<spec>: pinned (the default) | latest | a cut (42, 42.1) | a tag (archive-YYYY.MM.DD-N)`;
|
|
98
102
|
var VALUE = new Set([
|
|
@@ -117,6 +121,7 @@ var VALUE = new Set([
|
|
|
117
121
|
"--comp",
|
|
118
122
|
"--as-of",
|
|
119
123
|
"--population",
|
|
124
|
+
"--oireachtas",
|
|
120
125
|
"--dancer",
|
|
121
126
|
"--feis",
|
|
122
127
|
"--limit",
|
|
@@ -169,7 +174,9 @@ function printCached(c, say) {
|
|
|
169
174
|
}
|
|
170
175
|
var span = (lo, hi) => lo === null ? "-" : lo === hi ? `${lo}` : `${lo}-${hi ?? "?"}`;
|
|
171
176
|
function printCandidate(c, say, pad = " ") {
|
|
172
|
-
say(`${pad}${c.dancer_id} ${c.display}${c.scope === "per-release" ? " [per-release id]" : ""} score ${c.score} name ${c.evidence.nameLevel} age ${c.evidence.age} school ${c.evidence.school} population ${c.evidence.population}`);
|
|
177
|
+
say(`${pad}${c.dancer_id} ${c.display}${c.scope === "per-release" ? " [per-release id]" : ""} score ${c.score} name ${c.evidence.nameLevel} age ${c.evidence.age} school ${c.evidence.school} population ${c.evidence.population} region ${c.evidence.region}`);
|
|
178
|
+
if (c.region !== undefined)
|
|
179
|
+
say(`${pad} region ${c.region.region === null ? "-" : `${c.region.region} ${c.region.year}${c.region.regional ? " (regional)" : ""}`} attended ${c.region.attended} year(s)`);
|
|
173
180
|
say(`${pad} ${c.rows} rows ${span(c.year_lo, c.year_hi)} born ${span(c.birth.lo, c.birth.hi)} (${c.birth.source}) majors girls ${c.population.girls} boys ${c.population.boys} school ${c.school === null ? "-" : `${c.school.school_id ?? "(no id)"} "${c.school.print}" ${span(c.school.year_lo, c.school.year_hi)}`}`);
|
|
174
181
|
say(`${pad} prints ${c.prints.slice(0, 5).map((p) => `"${p.print}" (${p.rows}, ${p.level})`).join(", ")}${c.prints.length > 5 ? `, +${c.prints.length - 5} more` : ""}`);
|
|
175
182
|
}
|
|
@@ -181,6 +188,8 @@ function printDancers(a, say) {
|
|
|
181
188
|
say(` school asked: ${a.school.arm} ${a.school.ids.join(", ") || "-"}${a.school.lineage !== undefined && a.school.lineage.length > 0 ? ` (lineage: ${a.school.lineage.join(", ")})` : ""}`);
|
|
182
189
|
if (a.population !== undefined)
|
|
183
190
|
say(` population asked: ${a.population.read ?? "(unread)"}${a.population.note !== undefined ? ` (${a.population.note})` : ""}`);
|
|
191
|
+
if (a.oireachtas !== undefined)
|
|
192
|
+
say(` oireachtas asked: ${a.oireachtas.read ?? "(unread)"} ${a.oireachtas.year}${a.oireachtas.note !== undefined ? ` (${a.oireachtas.note})` : ""}`);
|
|
184
193
|
for (const c of a.candidates)
|
|
185
194
|
printCandidate(c, say);
|
|
186
195
|
if (a.preferred !== undefined)
|
|
@@ -253,6 +262,14 @@ function jsonLines(text, check) {
|
|
|
253
262
|
return out;
|
|
254
263
|
}
|
|
255
264
|
var checkComp = (q) => typeof q.feis !== "string" || q.feis.trim() === "" ? "a comp question needs feis" : q.code === undefined || q.code === null || String(q.code).trim() === "" ? "a comp question needs code" : null;
|
|
265
|
+
function oireachtasFlag(v) {
|
|
266
|
+
if (v === undefined)
|
|
267
|
+
return {};
|
|
268
|
+
const m = /^(.*?):(\d{4})$/.exec(v.trim());
|
|
269
|
+
return {
|
|
270
|
+
oireachtas: m === null ? { region: v.trim() } : { region: m[1], year: Number(m[2]) }
|
|
271
|
+
};
|
|
272
|
+
}
|
|
256
273
|
var checkDancer = (q) => typeof q.name !== "string" || q.name.trim() === "" ? "a dancer question needs name" : null;
|
|
257
274
|
var checkRegistration = (r) => typeof r.name !== "string" || r.name.trim() === "" ? "a registration row needs name" : typeof r.feis !== "string" || r.feis.trim() === "" ? "a registration row needs feis" : !Array.isArray(r.codes) ? "a registration row needs codes[]" : null;
|
|
258
275
|
async function resolveVerb(rel, what, args, p, say, stdin) {
|
|
@@ -312,7 +329,8 @@ async function resolveVerb(rel, what, args, p, say, stdin) {
|
|
|
312
329
|
...p.flags.has("--school") ? { school: p.flags.get("--school") } : {},
|
|
313
330
|
...age !== undefined ? { age } : {},
|
|
314
331
|
...p.flags.has("--as-of") ? { asOf: p.flags.get("--as-of") } : {},
|
|
315
|
-
...p.flags.has("--population") ? { population: p.flags.get("--population") } : {}
|
|
332
|
+
...p.flags.has("--population") ? { population: p.flags.get("--population") } : {},
|
|
333
|
+
...oireachtasFlag(p.flags.get("--oireachtas"))
|
|
316
334
|
}
|
|
317
335
|
}
|
|
318
336
|
];
|
|
@@ -619,6 +637,7 @@ async function main(argv, io = {}) {
|
|
|
619
637
|
...age !== undefined ? { age } : {},
|
|
620
638
|
...p.flags.has("--as-of") ? { asOf: p.flags.get("--as-of") } : {},
|
|
621
639
|
...p.flags.has("--population") ? { population: p.flags.get("--population") } : {},
|
|
640
|
+
...oireachtasFlag(p.flags.get("--oireachtas")),
|
|
622
641
|
...p.flags.has("--limit") ? { limit: Number(p.flags.get("--limit")) } : {}
|
|
623
642
|
};
|
|
624
643
|
const surname = p.flags.get("--surname");
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
FEIS_LOCAL_ID_FLOOR2,
|
|
13
13
|
ResultFinder2,
|
|
14
14
|
MajorsFinder2,
|
|
15
|
+
initialsOnly2,
|
|
15
16
|
DancerResolver2,
|
|
16
17
|
readPopulation2,
|
|
17
18
|
canonicalOf2,
|
|
@@ -45,7 +46,7 @@ import {
|
|
|
45
46
|
openCached2,
|
|
46
47
|
ReleaseManager2,
|
|
47
48
|
releases2
|
|
48
|
-
} from "./chunks/index-
|
|
49
|
+
} from "./chunks/index-hs72zekf.js";
|
|
49
50
|
import {
|
|
50
51
|
cacheRoot2,
|
|
51
52
|
repoOf2
|
|
@@ -94,6 +95,7 @@ export {
|
|
|
94
95
|
httpsRemote2 as httpsRemote,
|
|
95
96
|
indexKey2 as indexKey,
|
|
96
97
|
indexPath2 as indexPath,
|
|
98
|
+
initialsOnly2 as initialsOnly,
|
|
97
99
|
isCurrent2 as isCurrent,
|
|
98
100
|
listIndexes2 as listIndexes,
|
|
99
101
|
nameLevel2 as nameLevel,
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import type { OpenOptions } from "./release.js";
|
|
3
3
|
import type { StreamQuery } from "./stream.js";
|
|
4
|
-
export declare const USAGE = "usage: idq <verb> [--cache <dir>] [--repo <owner/name>] [--json]\n\n config repo <owner/name> set the user-local repository the releases come from\n list [--remote] the cached releases (size, files, indexes, the pin), and\n with --remote the published tags\n fetch [--release <spec>] [--assets results,majors,<file>...]\n download, verify and cache a release (default: results)\n pin <spec> the user-local pin: what a bare open (spec \"pinned\") opens\n unpin remove the pin (a bare open is then \"latest\")\n current the pin, and whether it is cached\n add <dir> --tag <tag> add a release built locally (its MANIFEST.json and files)\n to the cache under its tag\n index [--release <spec>] [<name>...] [--force]\n build the per-tag indexes (default: every one)\n verify [--release <spec>] re-hash every cached file against its receipt\n capabilities [--release <spec>] what the release carries of what the client reads, from\n its own schema: each feature full or missing (its calls\n refuse, naming the first cut that publishes it)\n prune [--keep N] [--dry-run] remove all but the N newest cached releases (default 1)\n and the pinned one\n rm <tag> [--dry-run] remove one cached release (not the pinned one)\n drop-indexes [<tag>] [--dry-run] remove the index files (of one release, or of every one)\n feis [--release <spec>] [--platform <p>] [--code <c>] [--id <id>] [--name <glob>] [--year <y>]\n the feises a query names\n series [--release <spec>] <name|host code|feis id>\n the series a name, a host code (fweb:ABC) or any feis id\n names: its years, hosts, codes and next instance\n school [--release <spec>] <print|school_id> [--region <code>]\n a school print or id to the published schools\n dancer [--release <spec>] <name> | --surname <s> | --like <glob> | --id <dancer_id>\n [--order surname-first|given-first] [--school <print|id>]\n [--yob <y> | --band <U10> [--year <y>] | --comp <competition>] [--as-of <date>]\n [--population girls|boys] [--rows]\n the dancers a name reaches, each with its evidence\n (name level, age, school, population) and the arm; the results of\n the one dancer where one answers (or --rows for each)\n results [--release <spec>] [--dancer <id>] [--feis <id>] [--comp <competition>]\n [--school <print|id>] [--year <y>] [--limit <n>]\n the published result rows, prints and ids\n majors [--release <spec>] [--event <e>] [--year <y>] [--comp <competition>] [--dancer <id>]\n the majors: every event and its years; an event's\n competitions; a competition's, an event's or a dancer's rows\n stream [--release <spec>] --scope majors|transcribed|platform|all [--entries] [--event <e,...>]\n [--year <y> | --year <from>..<to>] [--tier <t,...>] [--category <c,...>]\n [--level <feis_level,...>] [--dancer <id,...>] [--school <school_id>] [--primary]\n every row a scope holds, one JSON line each, never the\n whole table in memory; --entries one per address (the row\n it stands for, with its recall order)\n records [--release <spec>] [--dancer <id,...>]\n every dancer's record: display, appearances, birth window,\n populations\n records --years [--release <spec>] [--dancer <id,...>] [--year <y>]\n each dancer's region, nationals and place per year\n feis-dates [--release <spec>] every feis's first and last day\n tabulated [--release <spec>] [--min-round <n>]\n the majors addresses the marks sheets tabulate to round n\n or later (default 3)\n teams [--release <spec>] [--event <e>] [--year <y>] [--rosters | --joins]\n the team result rows of an event-year; with --rosters its\n roster teams and their dancers; with --joins how each roster\n team meets the results\n events [--release <spec>] [--event <e>] [--year <y>]\n each event-year's dates and place\n teacher [--release <spec>] <name|TD number>\n the staff lists' people: where they taught, the register,\n where they sat\n adjudicator [--release <spec>] <name|TD number>\n the register's and the panels' people: the same answer\n comp [--release <spec>] <feis> <code> [--year <y>] [--title <t>]\n a feis's own comp code to the comp it names, through that\n feis's syllabus (or the prior year's)\n syllabus [--release <spec>] <feis> [year]\n one feis-year's comps, in printed order\n syllabus [--release <spec>] --for <series> [year]\n a series' syllabus for a year: that year's where held,\n else the newest, saying which and what it is read from\n resolve comp [<feis> <code>] [--year <y>] [--title <t>]\n resolve dancer [<name>] [--school <s>] [--comp <feis>/<code> | --yob <y> | --band <b> --year <y>]\n [--order <o>] [--as-of <date>] [--population girls|boys]\n resolve registrations\n JSONL out, one answer per line; with no positional the\n questions are JSONL on stdin, one per line (a comp:\n {feis, code, year?, title?}, a dancer: {name, school?, age?,\n population?}, a registration: {name, school
|
|
4
|
+
export declare const USAGE = "usage: idq <verb> [--cache <dir>] [--repo <owner/name>] [--json]\n\n config repo <owner/name> set the user-local repository the releases come from\n list [--remote] the cached releases (size, files, indexes, the pin), and\n with --remote the published tags\n fetch [--release <spec>] [--assets results,majors,<file>...]\n download, verify and cache a release (default: results)\n pin <spec> the user-local pin: what a bare open (spec \"pinned\") opens\n unpin remove the pin (a bare open is then \"latest\")\n current the pin, and whether it is cached\n add <dir> --tag <tag> add a release built locally (its MANIFEST.json and files)\n to the cache under its tag\n index [--release <spec>] [<name>...] [--force]\n build the per-tag indexes (default: every one)\n verify [--release <spec>] re-hash every cached file against its receipt\n capabilities [--release <spec>] what the release carries of what the client reads, from\n its own schema: each feature full or missing (its calls\n refuse, naming the first cut that publishes it)\n prune [--keep N] [--dry-run] remove all but the N newest cached releases (default 1)\n and the pinned one\n rm <tag> [--dry-run] remove one cached release (not the pinned one)\n drop-indexes [<tag>] [--dry-run] remove the index files (of one release, or of every one)\n feis [--release <spec>] [--platform <p>] [--code <c>] [--id <id>] [--name <glob>] [--year <y>]\n the feises a query names\n series [--release <spec>] <name|host code|feis id>\n the series a name, a host code (fweb:ABC) or any feis id\n names: its years, hosts, codes and next instance\n school [--release <spec>] <print|school_id> [--region <code>]\n a school print or id to the published schools\n dancer [--release <spec>] <name> | --surname <s> | --like <glob> | --id <dancer_id>\n [--order surname-first|given-first] [--school <print|id>]\n [--yob <y> | --band <U10> [--year <y>] | --comp <competition>] [--as-of <date>]\n [--population girls|boys] [--oireachtas <region>[:<year>]] [--rows]\n the dancers a name reaches, each with its evidence\n (name level, age, school, population, region) and the arm;\n --oireachtas is the regional the roster is for, its region in\n the release's spelling (SRO, MAO), its year the --as-of year\n where none is given; the results of\n the one dancer where one answers (or --rows for each)\n results [--release <spec>] [--dancer <id>] [--feis <id>] [--comp <competition>]\n [--school <print|id>] [--year <y>] [--limit <n>]\n the published result rows, prints and ids\n majors [--release <spec>] [--event <e>] [--year <y>] [--comp <competition>] [--dancer <id>]\n the majors: every event and its years; an event's\n competitions; a competition's, an event's or a dancer's rows\n stream [--release <spec>] --scope majors|transcribed|platform|all [--entries] [--event <e,...>]\n [--year <y> | --year <from>..<to>] [--tier <t,...>] [--category <c,...>]\n [--level <feis_level,...>] [--dancer <id,...>] [--school <school_id>] [--primary]\n every row a scope holds, one JSON line each, never the\n whole table in memory; --entries one per address (the row\n it stands for, with its recall order)\n records [--release <spec>] [--dancer <id,...>]\n every dancer's record: display, appearances, birth window,\n populations\n records --years [--release <spec>] [--dancer <id,...>] [--year <y>]\n each dancer's region, nationals and place per year\n feis-dates [--release <spec>] every feis's first and last day\n tabulated [--release <spec>] [--min-round <n>]\n the majors addresses the marks sheets tabulate to round n\n or later (default 3)\n teams [--release <spec>] [--event <e>] [--year <y>] [--rosters | --joins]\n the team result rows of an event-year; with --rosters its\n roster teams and their dancers; with --joins how each roster\n team meets the results\n events [--release <spec>] [--event <e>] [--year <y>]\n each event-year's dates and place\n teacher [--release <spec>] <name|TD number>\n the staff lists' people: where they taught, the register,\n where they sat\n adjudicator [--release <spec>] <name|TD number>\n the register's and the panels' people: the same answer\n comp [--release <spec>] <feis> <code> [--year <y>] [--title <t>]\n a feis's own comp code to the comp it names, through that\n feis's syllabus (or the prior year's)\n syllabus [--release <spec>] <feis> [year]\n one feis-year's comps, in printed order\n syllabus [--release <spec>] --for <series> [year]\n a series' syllabus for a year: that year's where held,\n else the newest, saying which and what it is read from\n resolve comp [<feis> <code>] [--year <y>] [--title <t>]\n resolve dancer [<name>] [--school <s>] [--comp <feis>/<code> | --yob <y> | --band <b> --year <y>]\n [--order <o>] [--as-of <date>] [--population girls|boys]\n [--oireachtas <region>[:<year>]]\n resolve registrations\n JSONL out, one answer per line; with no positional the\n questions are JSONL on stdin, one per line (a comp:\n {feis, code, year?, title?}, a dancer: {name, school?, age?,\n population?, oireachtas?}, a registration: {name, school?,\n codes[], feis, year?, population?, oireachtas?})\n\n <spec>: pinned (the default) | latest | a cut (42, 42.1) | a tag (archive-YYYY.MM.DD-N)";
|
|
5
5
|
export interface Parsed {
|
|
6
6
|
positional: string[];
|
|
7
7
|
flags: Map<string, string>;
|
package/dist/types/dancers.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { type PersonName } from "@finbheara/names/normalize";
|
|
1
2
|
import { type NameLevel } from "./dancers-names.js";
|
|
2
3
|
import type { IndexBuilder } from "./indexes.js";
|
|
3
4
|
import type { Release } from "./release.js";
|
|
4
5
|
import { FEIS_LOCAL_ID_FLOOR } from "./results.js";
|
|
6
|
+
export declare function initialsOnly(name: PersonName): boolean;
|
|
5
7
|
export { FEIS_LOCAL_ID_FLOOR };
|
|
6
8
|
export type NameOrderAsked = "surname-first" | "given-first" | "unknown";
|
|
7
9
|
export type AgeAsked = {
|
|
@@ -20,8 +22,14 @@ export interface DancerQuery {
|
|
|
20
22
|
school?: string;
|
|
21
23
|
age?: AgeAsked;
|
|
22
24
|
asOf?: string;
|
|
25
|
+
oireachtas?: OireachtasAsked;
|
|
23
26
|
population?: string;
|
|
24
27
|
}
|
|
28
|
+
export interface OireachtasAsked {
|
|
29
|
+
region: string;
|
|
30
|
+
year?: number;
|
|
31
|
+
}
|
|
32
|
+
export type RegionEvidence = "same" | "moved" | "contradicts" | "unknown" | "unasked";
|
|
25
33
|
export type AgeEvidence = "fits" | "overlaps" | "contradicts" | "unknown" | "unasked";
|
|
26
34
|
export type PopulationEvidence = "same" | "contradicts" | "both" | "unknown" | "unasked";
|
|
27
35
|
export type SchoolEvidence = "same" | "lineage" | "moved" | "none" | "unresolved" | "unasked";
|
|
@@ -43,6 +51,7 @@ export interface DancerCandidate {
|
|
|
43
51
|
age: AgeEvidence;
|
|
44
52
|
school: SchoolEvidence;
|
|
45
53
|
population: PopulationEvidence;
|
|
54
|
+
region: RegionEvidence;
|
|
46
55
|
};
|
|
47
56
|
prints: {
|
|
48
57
|
print: string;
|
|
@@ -63,10 +72,22 @@ export interface DancerCandidate {
|
|
|
63
72
|
boys: number;
|
|
64
73
|
};
|
|
65
74
|
school: DancerSchool | null;
|
|
75
|
+
region?: DancerRegion;
|
|
76
|
+
}
|
|
77
|
+
export interface DancerRegion {
|
|
78
|
+
year: number | null;
|
|
79
|
+
region: string | null;
|
|
80
|
+
regional: boolean;
|
|
81
|
+
attended: number;
|
|
66
82
|
}
|
|
67
83
|
export interface ExcludedCandidate {
|
|
68
84
|
candidate: DancerCandidate;
|
|
69
|
-
why: "age" | "population";
|
|
85
|
+
why: "age" | "population" | "region" | "school";
|
|
86
|
+
}
|
|
87
|
+
export interface InitialsRefuted {
|
|
88
|
+
dancer_id: number;
|
|
89
|
+
why: "school" | "age" | "population" | "region";
|
|
90
|
+
fact: string;
|
|
70
91
|
}
|
|
71
92
|
export interface DancerAnswer {
|
|
72
93
|
tag: string;
|
|
@@ -95,12 +116,24 @@ export interface DancerAnswer {
|
|
|
95
116
|
read: "girls" | "boys" | null;
|
|
96
117
|
note?: string;
|
|
97
118
|
};
|
|
119
|
+
oireachtas?: {
|
|
120
|
+
asked: string;
|
|
121
|
+
read: string | null;
|
|
122
|
+
year: number;
|
|
123
|
+
note?: string;
|
|
124
|
+
};
|
|
98
125
|
school?: {
|
|
99
126
|
arm: string;
|
|
100
127
|
ids: string[];
|
|
101
128
|
lineage?: string[];
|
|
102
129
|
};
|
|
103
130
|
refused?: string;
|
|
131
|
+
initials?: {
|
|
132
|
+
open: number[];
|
|
133
|
+
heldByDanceUp: number[];
|
|
134
|
+
refuted: InitialsRefuted[];
|
|
135
|
+
year: number;
|
|
136
|
+
};
|
|
104
137
|
}
|
|
105
138
|
export interface DancerSearchQuery extends Omit<DancerQuery, "name"> {
|
|
106
139
|
name?: string;
|
|
@@ -164,7 +197,9 @@ export interface DancerYear {
|
|
|
164
197
|
export declare class DancerResolver {
|
|
165
198
|
private readonly rel;
|
|
166
199
|
private readonly printIds;
|
|
200
|
+
private readonly rowIds;
|
|
167
201
|
private lineageOf;
|
|
202
|
+
private regions;
|
|
168
203
|
constructor(rel: Release);
|
|
169
204
|
private lineage;
|
|
170
205
|
records(q?: {
|
|
@@ -185,7 +220,10 @@ export declare class DancerResolver {
|
|
|
185
220
|
private capped;
|
|
186
221
|
get(dancerId: number): Promise<DancerRecord | null>;
|
|
187
222
|
private answer;
|
|
223
|
+
private readOireachtas;
|
|
188
224
|
private schoolEvidence;
|
|
225
|
+
private schoolRefutes;
|
|
226
|
+
private schoolIdsOf;
|
|
189
227
|
private readAge;
|
|
190
228
|
}
|
|
191
229
|
export declare function readPopulation(asked: string): NonNullable<DancerAnswer["population"]>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { type AssetPlan, DATABASES, type DatabaseName, type LandedFile, type Receipt, type ReleaseManifest, planAsset, } from "./assets.js";
|
|
2
2
|
export { sha256File, unzstdTo } from "./bytes.js";
|
|
3
|
-
export { type AgeAsked, type AgeEvidence, type DancerAnswer, type DancerBulkRecord, type DancerCandidate, type DancerQuery, type DancerRecord, DancerResolver, type DancerSchool, type DancerSearchQuery, type DancerYear, type ExcludedCandidate, FEIS_LOCAL_ID_FLOOR, type PopulationEvidence, type SchoolEvidence, readPopulation, } from "./dancers.js";
|
|
3
|
+
export { type AgeAsked, type AgeEvidence, type DancerAnswer, type DancerBulkRecord, type DancerCandidate, type DancerQuery, type DancerRecord, DancerResolver, type DancerRegion, type DancerSchool, type DancerSearchQuery, type DancerYear, type ExcludedCandidate, FEIS_LOCAL_ID_FLOOR, type InitialsRefuted, initialsOnly, type OireachtasAsked, type PopulationEvidence, type RegionEvidence, type SchoolEvidence, readPopulation, } from "./dancers.js";
|
|
4
4
|
export { NAME_LEVELS, type NameLevel, nameLevel } from "./dancers-names.js";
|
|
5
5
|
export { type Comp, type CompAnswer, type CompDance, type CompKind, type CompQuery, CompResolver, type CompSource, type FeisPlace, type SyllabusAnswer, type SyllabusForAnswer, type SyllabusSource, type TitleCheck, canonicalOf, } from "./comps.js";
|
|
6
6
|
export { type ClientOptions, cacheRoot, repoOf } from "./config.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CompAnswer, CompResolver } from "./comps.js";
|
|
2
|
-
import { type DancerAnswer, type DancerQuery } from "./dancers.js";
|
|
2
|
+
import { type DancerAnswer, type DancerQuery, type OireachtasAsked } from "./dancers.js";
|
|
3
3
|
import type { Release } from "./release.js";
|
|
4
4
|
export interface RegistrationRow {
|
|
5
5
|
name: string;
|
|
@@ -11,6 +11,7 @@ export interface RegistrationRow {
|
|
|
11
11
|
titles?: Readonly<Record<string, string>>;
|
|
12
12
|
asOf?: string;
|
|
13
13
|
population?: string;
|
|
14
|
+
oireachtas?: OireachtasAsked;
|
|
14
15
|
[k: string]: unknown;
|
|
15
16
|
}
|
|
16
17
|
export type DancerQueryLike = DancerQuery;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@finbheara/archive-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Open a versioned release of an Irish dance results archive: download, verify, decompress and cache it by tag, keep the cache, and resolve feises and schools against it",
|
|
5
5
|
"keywords": ["irish-dance", "results", "release", "cache", "sqlite"],
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@finbheara/domain": "0.50.0",
|
|
48
|
-
"@finbheara/names": "0.
|
|
48
|
+
"@finbheara/names": "0.24.0",
|
|
49
49
|
"hyparquet": "1.31.2"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|