@finbheara/archive-client 0.24.0 → 0.25.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 +68 -1
- package/dist/chunks/{index-vsk6837c.js → index-2ms980hc.js} +427 -16
- package/dist/cli.js +222 -1
- package/dist/index.js +7 -1
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/people.d.ts +12 -0
- package/dist/types/release.d.ts +4 -0
- package/dist/types/school-bulk.d.ts +80 -0
- package/dist/types/schools.d.ts +33 -0
- package/dist/types/tabs.d.ts +132 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -95,6 +95,13 @@ c.features; // [{ feature: "dancers", state: "full" | "missing", missing: [...
|
|
|
95
95
|
| `teams` | `teams.results`, `teams.rosters`, `teams.resultRosters` | 260 |
|
|
96
96
|
| `teams.fields` | the fields `teams.results` (`age`, `gender`, `printed_status`) and `teams.rosters` (`dance`, `school_printed_as_of`, a member's `gender`) carry; absent, never refused, without it | 266 |
|
|
97
97
|
| `events` | `events.years` | 260 |
|
|
98
|
+
| `tabs`, `panels` | `tabs.query`, `tabs.stream`; `panels.query` | 184 |
|
|
99
|
+
| `feis-panels` | `feisPanels.query` | 260 |
|
|
100
|
+
| `staff.adjudicators` | `staff.adjudicators` | 230 |
|
|
101
|
+
| `schools.registry` | `schools.list` | 260 |
|
|
102
|
+
| `schools.prints`, `schools.redirects` | `schools.prints`; `schools.redirects` | 184 |
|
|
103
|
+
| `schools.lineage` | `schools.links`, `schools.line`, `schools.lineage` | 184 |
|
|
104
|
+
| `schools.associations` | `schools.associations` | 215 |
|
|
98
105
|
|
|
99
106
|
A spec is `pinned` (the default: the user-local pin, else the latest), `latest`, a cut number
|
|
100
107
|
(`42`, or `42.1` for a fraction) or a tag (`archive-YYYY.MM.DD-N`).
|
|
@@ -227,6 +234,29 @@ rows were published under and their rows, so it agrees with each print lookup of
|
|
|
227
234
|
|
|
228
235
|
Every answer carries the release tag it came from.
|
|
229
236
|
|
|
237
|
+
### The schools in bulk
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
await rel.schools.list(); // { schools: [{ school_id, display, regions, places }] }: the registry
|
|
241
|
+
await rel.schools.prints({ event: "<event>", year: 2024 });
|
|
242
|
+
// { prints: [{ event, year, print, school_id, rows }] }
|
|
243
|
+
await rel.schools.redirects(); // { redirects: [{ old_id, new_id, kind, since }] }
|
|
244
|
+
await rel.schools.lineage(); // { edges: [{ id, direction, other, shape, year, provisional,
|
|
245
|
+
// decision, confidence }] }
|
|
246
|
+
await rel.schools.associations({ school_id: "<id>" });
|
|
247
|
+
// { associations: [{ at, seq, date, person, person_printed,
|
|
248
|
+
// person_type, credentials, caption, school_printed, school_id,
|
|
249
|
+
// association_type, src_type, src, candidate_school_id, candidate_rung, ... }] }
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
`prints` is every (print, school id) pair the release's result rows attach in an event-year (the
|
|
253
|
+
print trimmed), with the rows that carry it: an event's (case-blind), a year's, both or every one.
|
|
254
|
+
A row attached to no school is in no pair, and a team result's school is `rel.teams.results`'.
|
|
255
|
+
`lineage` is each edge end as the release publishes it (an edge may carry both ends): `links` and
|
|
256
|
+
`line` are the graph over them. `associations` is the people a directory lists beside a school, as
|
|
257
|
+
evidence of an association, never an identity: `school_id` is the school the print attached to,
|
|
258
|
+
`candidate_school_id` one it reached without attaching.
|
|
259
|
+
|
|
230
260
|
### How two schools are linked
|
|
231
261
|
|
|
232
262
|
```ts
|
|
@@ -550,6 +580,33 @@ await rel.feises.dates(); // every feis id with its first a
|
|
|
550
580
|
await rel.majors.tabulated({ min_true_round: 3 }); // the majors addresses marked to round 3 or later
|
|
551
581
|
```
|
|
552
582
|
|
|
583
|
+
## Marks sheets and panels
|
|
584
|
+
|
|
585
|
+
```ts
|
|
586
|
+
const s = await rel.tabs.query({ competition: "<competition>" }); // or { address }, and a { round }
|
|
587
|
+
s.rows; // [{ address, competition, card, line, event, year, tier, round, true_round, seat_index,
|
|
588
|
+
// section, panel_size, column_order, drop_rule, the judge (name, print, TD number,
|
|
589
|
+
// id, unmatched reason), mark, mark_printed, place, place_printed, tie, points,
|
|
590
|
+
// points_printed }]
|
|
591
|
+
for await (const t of rel.tabs.stream({ tier: ["T1", "T2", "T3"], year: [2015, 2025] })) ...
|
|
592
|
+
await rel.panels.query({ competition: "<competition>" }); // { seats: [{ competition, panel, round,
|
|
593
|
+
// seat_index, address, the judge (print, TD number, id, unmatched reason) }] }
|
|
594
|
+
await rel.feisPanels.query({ address: "fweb:<code>.<comp>" }); // { seats: [{ address, platform, round,
|
|
595
|
+
// seat_index, panel_size, panel_kind, the judge (print, state printed, TD number, id,
|
|
596
|
+
// unmatched reason, basis) }] }
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
A marks sheet is a row per card, round and seat, with the seat's mark, place and points as read
|
|
600
|
+
beside their prints, from `results.sqlite` (every tabulated sheet, the T4 events' too). The stream
|
|
601
|
+
takes an event (or several, case-blind), a year or an inclusive range, tiers, competitions, or
|
|
602
|
+
nothing (every cell), and yields one competition's rows together. A sheet's `event`, `year` and
|
|
603
|
+
`tier` are its competition's: a solo competition's from the results, a team competition's from the
|
|
604
|
+
team results (with the tier the release gives that event-year's solo competitions). A sheet the
|
|
605
|
+
release places in neither carries nulls, and a filter on them never reaches it. `panels` and
|
|
606
|
+
`feisPanels` with nothing named answer every seat. `round` is `rx` where one panel sat every round.
|
|
607
|
+
A seat carries its judge's TD number where the release linked one, else a judge id, else the
|
|
608
|
+
reason it is linked to neither (`TabRow`, `PanelSeat` and `FeisPanelSeat` name the fields).
|
|
609
|
+
|
|
553
610
|
## Teams and event-years
|
|
554
611
|
|
|
555
612
|
```ts
|
|
@@ -596,6 +653,9 @@ release into the `teams` and `events` indexes.
|
|
|
596
653
|
```ts
|
|
597
654
|
await rel.staff.teacher("<name>"); // or a TD number
|
|
598
655
|
await rel.staff.adjudicator("<name>");
|
|
656
|
+
await rel.staff.adjudicators({ year: 2025 }); // the register's rows (or a TD number's, or every one):
|
|
657
|
+
// [{ the TD number, year, cat, name_printed, country, country_printed, country_code, region,
|
|
658
|
+
// region_printed, region_code, geohash, src }] (`RegisterRow`)
|
|
599
659
|
```
|
|
600
660
|
|
|
601
661
|
One person per TD number (else per judge id, else per name): the schools taught at (role,
|
|
@@ -747,6 +807,13 @@ is passed to the dancer resolver as asked (`rel.dancers`, above).
|
|
|
747
807
|
idq records --years [--release <spec>] [--dancer <id,...>] [--year <y>]
|
|
748
808
|
idq feis-dates [--release <spec>]
|
|
749
809
|
idq tabulated [--release <spec>] [--min-round <n>]
|
|
810
|
+
idq tabs [--release <spec>] --comp <competition> | --address <address> [--round <r>]
|
|
811
|
+
idq tabs --stream [--release <spec>] [--comp <c,...>] [--event <e,...>] [--year <y> | --year <from>..<to>] [--tier <t,...>]
|
|
812
|
+
idq panels [--release <spec>] [--comp <competition>]
|
|
813
|
+
idq feis-panels [--release <spec>] [--address <feis competition>] [--platform <p>]
|
|
814
|
+
idq register [--release <spec>] [--year <y>] [--td <TD number>]
|
|
815
|
+
idq schools [--release <spec>] [--prints [--event <e>] [--year <y>] | --redirects | --lineage
|
|
816
|
+
| --associations [--school <school_id>]]
|
|
750
817
|
idq teams [--release <spec>] [--event <e>] [--year <y>] [--rosters | --joins]
|
|
751
818
|
idq events [--release <spec>] [--event <e>] [--year <y>]
|
|
752
819
|
idq teacher [--release <spec>] <name|TD number>
|
|
@@ -759,7 +826,7 @@ is passed to the dancer resolver as asked (`rel.dancers`, above).
|
|
|
759
826
|
[--oireachtas <region>[:<year>]]
|
|
760
827
|
idq resolve registrations
|
|
761
828
|
|
|
762
|
-
`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
|
|
829
|
+
`stream` (and `tabs --stream`) prints one JSON line per row (or entry, or cell), as it reads them. `dancer` prints the results of the one dancer where the answer is unique (every candidate's with
|
|
763
830
|
`--rows`). `--json` prints the call's answer as it is. `--cache` and `--repo` override the defaults.
|
|
764
831
|
|
|
765
832
|
`update` moves to the newest published release, as a package manager's `update` moves to the newest
|
|
@@ -774,6 +774,96 @@ import {
|
|
|
774
774
|
DEFAULT_SCHOOL_NAME_READER,
|
|
775
775
|
schoolEncoder
|
|
776
776
|
} from "@finbheara/domain/school";
|
|
777
|
+
|
|
778
|
+
var str = (v) => typeof v === "string" && v !== "" ? v : null;
|
|
779
|
+
var num = (v) => typeof v === "number" ? v : null;
|
|
780
|
+
var uniq = (xs) => [...new Set(xs)];
|
|
781
|
+
async function registrySchools(rel) {
|
|
782
|
+
await rel.require("schools.registry");
|
|
783
|
+
await rel.fetch("school-registry.jsonl");
|
|
784
|
+
const schools = readJsonl(rel.path("school-registry.jsonl")).map((r) => ({
|
|
785
|
+
school_id: r.school_id,
|
|
786
|
+
display: r.display,
|
|
787
|
+
regions: uniq((r.regions ?? []).map((x) => x.region)),
|
|
788
|
+
places: uniq((r.locations ?? []).map((x) => x.place))
|
|
789
|
+
})).sort((a, b) => a.school_id < b.school_id ? -1 : a.school_id > b.school_id ? 1 : 0);
|
|
790
|
+
return { tag: rel.tag, schools };
|
|
791
|
+
}
|
|
792
|
+
async function schoolPrints(rel, q) {
|
|
793
|
+
await rel.fetch("results");
|
|
794
|
+
await rel.require("schools.prints");
|
|
795
|
+
const where = ["r.school_id IS NOT NULL"];
|
|
796
|
+
const args = [];
|
|
797
|
+
if (q.event !== undefined) {
|
|
798
|
+
where.push("c.event = ? COLLATE NOCASE");
|
|
799
|
+
args.push(q.event);
|
|
800
|
+
}
|
|
801
|
+
if (q.year !== undefined) {
|
|
802
|
+
where.push("c.year = ?");
|
|
803
|
+
args.push(q.year);
|
|
804
|
+
}
|
|
805
|
+
const prints = rel.db("results").query(`SELECT c.event AS event, c.year AS year, trim(r.school_printed) AS print,
|
|
806
|
+
r.school_id AS school_id, count(*) AS rows
|
|
807
|
+
FROM competitions c JOIN results r ON r.file = c.file AND r.competition_line = c.line
|
|
808
|
+
WHERE ${where.join(" AND ")} GROUP BY 1, 2, 3, 4 ORDER BY 2, 1, 3, 4`).all(...args);
|
|
809
|
+
return { tag: rel.tag, asked: q, prints };
|
|
810
|
+
}
|
|
811
|
+
async function schoolRedirects(rel) {
|
|
812
|
+
await rel.require("schools.redirects");
|
|
813
|
+
await rel.fetch("school-redirects.jsonl");
|
|
814
|
+
const redirects = readJsonl(rel.path("school-redirects.jsonl")).map((r) => ({
|
|
815
|
+
old_id: String(r.old_id),
|
|
816
|
+
new_id: String(r.new_id),
|
|
817
|
+
kind: String(r.kind),
|
|
818
|
+
since: num(r.since)
|
|
819
|
+
}));
|
|
820
|
+
return { tag: rel.tag, redirects };
|
|
821
|
+
}
|
|
822
|
+
async function schoolLineage(rel) {
|
|
823
|
+
await rel.require("schools.lineage");
|
|
824
|
+
await rel.fetch("school-lineage.jsonl");
|
|
825
|
+
const edges = readJsonl(rel.path("school-lineage.jsonl")).map((r) => ({
|
|
826
|
+
id: String(r.id),
|
|
827
|
+
direction: String(r.direction),
|
|
828
|
+
other: String(r.other),
|
|
829
|
+
shape: String(r.shape),
|
|
830
|
+
year: num(r.year),
|
|
831
|
+
provisional: r.provisional === true,
|
|
832
|
+
decision: str(r.decision),
|
|
833
|
+
confidence: num(r.confidence)
|
|
834
|
+
}));
|
|
835
|
+
return { tag: rel.tag, edges };
|
|
836
|
+
}
|
|
837
|
+
async function observedAssociations(rel, q) {
|
|
838
|
+
await rel.require("schools.associations");
|
|
839
|
+
await rel.fetch("observed-associations.jsonl");
|
|
840
|
+
const associations = [];
|
|
841
|
+
for (const r of readJsonl(rel.path("observed-associations.jsonl"))) {
|
|
842
|
+
const school_id = str(r.schoolId);
|
|
843
|
+
if (q.school_id !== undefined && school_id !== q.school_id)
|
|
844
|
+
continue;
|
|
845
|
+
associations.push({
|
|
846
|
+
at: String(r.at),
|
|
847
|
+
seq: num(r.seq) ?? 0,
|
|
848
|
+
date: str(r.date),
|
|
849
|
+
person: str(r.person),
|
|
850
|
+
person_printed: typeof r.personPrinted === "string" ? r.personPrinted : "",
|
|
851
|
+
reading: str(r.reading),
|
|
852
|
+
person_type: str(r.personType),
|
|
853
|
+
credentials: str(r.credentials),
|
|
854
|
+
caption: str(r.caption),
|
|
855
|
+
school_printed: str(r.school),
|
|
856
|
+
school_id,
|
|
857
|
+
association_type: str(r.associationType),
|
|
858
|
+
src_type: str(r.srcType),
|
|
859
|
+
src: str(r.src),
|
|
860
|
+
candidate_school_id: str(r.candidateSchoolId),
|
|
861
|
+
candidate_rung: str(r.candidateRung)
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
return { tag: rel.tag, asked: q, associations };
|
|
865
|
+
}
|
|
866
|
+
|
|
777
867
|
function readsSpanishNames2(candidates) {
|
|
778
868
|
return candidates.some((c) => c.spanishNames !== undefined && (c.spanishNames.file || c.prints.some((p) => c.spanishNames?.prints.includes(p.trim()))));
|
|
779
869
|
}
|
|
@@ -846,6 +936,21 @@ class SchoolResolver2 {
|
|
|
846
936
|
this.graph ??= releaseSchoolGraph2(this.rel);
|
|
847
937
|
return { tag: this.rel.tag, ...(await this.graph).line(a.trim(), q) };
|
|
848
938
|
}
|
|
939
|
+
list() {
|
|
940
|
+
return registrySchools(this.rel);
|
|
941
|
+
}
|
|
942
|
+
prints(q = {}) {
|
|
943
|
+
return schoolPrints(this.rel, q);
|
|
944
|
+
}
|
|
945
|
+
redirects() {
|
|
946
|
+
return schoolRedirects(this.rel);
|
|
947
|
+
}
|
|
948
|
+
lineage() {
|
|
949
|
+
return schoolLineage(this.rel);
|
|
950
|
+
}
|
|
951
|
+
associations(q = {}) {
|
|
952
|
+
return observedAssociations(this.rel, q);
|
|
953
|
+
}
|
|
849
954
|
async resolve(asked, q = {}) {
|
|
850
955
|
const db = await this.rel.indexDb("schools");
|
|
851
956
|
const reg = db.query("SELECT display, regions, places, spanish FROM registry WHERE school_id = ?");
|
|
@@ -2246,6 +2351,218 @@ import {
|
|
|
2246
2351
|
roleEncoder
|
|
2247
2352
|
} from "@finbheara/domain/noun-index";
|
|
2248
2353
|
import { roleName } from "@finbheara/domain/person";
|
|
2354
|
+
|
|
2355
|
+
var TAB_COLUMNS = `address, slug AS competition, card, line, round, true_round, seat_index,
|
|
2356
|
+
section, panel_size, column_order, drop_rule, judge_name, judge_name_printed, judge_clrg,
|
|
2357
|
+
judge_id, judge_unmatched, mark, mark_printed, place, place_printed, tie, points, points_printed`;
|
|
2358
|
+
var TAB_NEEDS = [
|
|
2359
|
+
"address",
|
|
2360
|
+
"slug",
|
|
2361
|
+
"card",
|
|
2362
|
+
"line",
|
|
2363
|
+
"round",
|
|
2364
|
+
"true_round",
|
|
2365
|
+
"seat_index",
|
|
2366
|
+
"section",
|
|
2367
|
+
"panel_size",
|
|
2368
|
+
"column_order",
|
|
2369
|
+
"drop_rule",
|
|
2370
|
+
"judge_name",
|
|
2371
|
+
"judge_name_printed",
|
|
2372
|
+
"judge_clrg",
|
|
2373
|
+
"judge_id",
|
|
2374
|
+
"judge_unmatched",
|
|
2375
|
+
"mark",
|
|
2376
|
+
"mark_printed",
|
|
2377
|
+
"place",
|
|
2378
|
+
"place_printed",
|
|
2379
|
+
"tie",
|
|
2380
|
+
"points",
|
|
2381
|
+
"points_printed"
|
|
2382
|
+
].map((c) => `results:tabs.${c}`);
|
|
2383
|
+
var NO_SHEET = { event: null, year: null, tier: null };
|
|
2384
|
+
var cardRange = (competition) => [`${competition}#`, `${competition}$`];
|
|
2385
|
+
|
|
2386
|
+
class TabFinder2 {
|
|
2387
|
+
rel;
|
|
2388
|
+
constructor(rel) {
|
|
2389
|
+
this.rel = rel;
|
|
2390
|
+
}
|
|
2391
|
+
async db() {
|
|
2392
|
+
await this.rel.fetch("results");
|
|
2393
|
+
await this.rel.require("tabs");
|
|
2394
|
+
return this.rel.db("results");
|
|
2395
|
+
}
|
|
2396
|
+
async sheets(db, only) {
|
|
2397
|
+
const out = new Map;
|
|
2398
|
+
const tiers = new Map;
|
|
2399
|
+
const rows = [];
|
|
2400
|
+
if (only === null)
|
|
2401
|
+
rows.push(...db.query("SELECT competition, event, year, tier FROM competitions WHERE competition IN (SELECT DISTINCT slug FROM tabs)").all());
|
|
2402
|
+
else
|
|
2403
|
+
for (let i = 0;i < only.length; i += 500) {
|
|
2404
|
+
const part = only.slice(i, i + 500);
|
|
2405
|
+
rows.push(...db.query(`SELECT competition, event, year, tier FROM competitions WHERE competition IN (${part.map(() => "?").join(", ")})`).all(...part));
|
|
2406
|
+
}
|
|
2407
|
+
for (const r of rows) {
|
|
2408
|
+
out.set(r.competition, { event: r.event, year: r.year, tier: r.tier });
|
|
2409
|
+
tiers.set(`${r.event.toLowerCase()}\x00${r.year}`, r.tier);
|
|
2410
|
+
}
|
|
2411
|
+
const missing = only === null ? null : only.filter((c) => !out.has(c));
|
|
2412
|
+
if (missing !== null && missing.length === 0)
|
|
2413
|
+
return out;
|
|
2414
|
+
if ((await this.rel.capability("teams")).state !== "full")
|
|
2415
|
+
return out;
|
|
2416
|
+
const teams = await this.rel.indexDb("teams");
|
|
2417
|
+
const team = teams.query("SELECT competition, event, year FROM result WHERE competition IS NOT NULL GROUP BY competition");
|
|
2418
|
+
const want = missing === null ? null : new Set(missing);
|
|
2419
|
+
for (const t of team.all()) {
|
|
2420
|
+
if (out.has(t.competition) || want !== null && !want.has(t.competition))
|
|
2421
|
+
continue;
|
|
2422
|
+
out.set(t.competition, {
|
|
2423
|
+
event: t.event,
|
|
2424
|
+
year: t.year,
|
|
2425
|
+
tier: tiers.get(`${t.event.toLowerCase()}\x00${t.year}`) ?? null
|
|
2426
|
+
});
|
|
2427
|
+
}
|
|
2428
|
+
if ([...out.values()].some((s) => s.tier === null && s.event !== null)) {
|
|
2429
|
+
for (const r of db.query("SELECT event, year, min(tier) AS tier FROM competitions GROUP BY event, year").all())
|
|
2430
|
+
tiers.set(`${r.event.toLowerCase()}\x00${r.year}`, r.tier);
|
|
2431
|
+
for (const s of out.values())
|
|
2432
|
+
if (s.tier === null && s.event !== null)
|
|
2433
|
+
s.tier = tiers.get(`${s.event.toLowerCase()}\x00${s.year}`) ?? null;
|
|
2434
|
+
}
|
|
2435
|
+
return out;
|
|
2436
|
+
}
|
|
2437
|
+
async query(q) {
|
|
2438
|
+
const db = await this.db();
|
|
2439
|
+
const where = [];
|
|
2440
|
+
const args = [];
|
|
2441
|
+
if (q.address !== undefined) {
|
|
2442
|
+
where.push("address = ?");
|
|
2443
|
+
args.push(q.address);
|
|
2444
|
+
} else if (q.competition !== undefined) {
|
|
2445
|
+
const [lo, hi] = cardRange(q.competition);
|
|
2446
|
+
where.push("address >= ? AND address < ? AND slug = ?");
|
|
2447
|
+
args.push(lo, hi, q.competition);
|
|
2448
|
+
} else
|
|
2449
|
+
throw new Error("archive-client: a tabs query names a competition or an address");
|
|
2450
|
+
if (q.round !== undefined) {
|
|
2451
|
+
where.push("round = ?");
|
|
2452
|
+
args.push(q.round);
|
|
2453
|
+
}
|
|
2454
|
+
const raw = db.query(`SELECT ${TAB_COLUMNS} FROM tabs WHERE ${where.join(" AND ")} ORDER BY address, round, seat_index, line`).all(...args);
|
|
2455
|
+
const sheets = raw.length === 0 ? new Map : await this.sheets(db, [...new Set(raw.map((r) => r.competition))]);
|
|
2456
|
+
return {
|
|
2457
|
+
tag: this.rel.tag,
|
|
2458
|
+
asked: q,
|
|
2459
|
+
rows: raw.map((r) => ({ ...r, ...sheets.get(r.competition) ?? NO_SHEET }))
|
|
2460
|
+
};
|
|
2461
|
+
}
|
|
2462
|
+
async* stream(q = {}) {
|
|
2463
|
+
const db = await this.db();
|
|
2464
|
+
const sheets = await this.sheets(db, q.competition ?? null);
|
|
2465
|
+
const events = q.event === undefined ? null : new Set((typeof q.event === "string" ? [q.event] : q.event).map((e) => e.toLowerCase()));
|
|
2466
|
+
const tiers = q.tier === undefined ? null : new Set(q.tier);
|
|
2467
|
+
const holds = (s) => {
|
|
2468
|
+
if (events !== null && (s.event === null || !events.has(s.event.toLowerCase())))
|
|
2469
|
+
return false;
|
|
2470
|
+
if (tiers !== null && (s.tier === null || !tiers.has(s.tier)))
|
|
2471
|
+
return false;
|
|
2472
|
+
if (typeof q.year === "number" && s.year !== q.year)
|
|
2473
|
+
return false;
|
|
2474
|
+
if (Array.isArray(q.year) && (s.year === null || s.year < q.year[0] || s.year > q.year[1]))
|
|
2475
|
+
return false;
|
|
2476
|
+
return true;
|
|
2477
|
+
};
|
|
2478
|
+
const filtered = events !== null || tiers !== null || q.year !== undefined;
|
|
2479
|
+
const run = function* (stmt, args) {
|
|
2480
|
+
for (const r of stmt.iterate(...args))
|
|
2481
|
+
yield { ...r, ...sheets.get(r.competition) ?? NO_SHEET };
|
|
2482
|
+
};
|
|
2483
|
+
if (!filtered && q.competition === undefined) {
|
|
2484
|
+
const all = db.prepare(`SELECT ${TAB_COLUMNS} FROM tabs ORDER BY address, round, seat_index, line`);
|
|
2485
|
+
try {
|
|
2486
|
+
yield* run(all, []);
|
|
2487
|
+
} finally {
|
|
2488
|
+
all.finalize();
|
|
2489
|
+
}
|
|
2490
|
+
return;
|
|
2491
|
+
}
|
|
2492
|
+
const asked = [...new Set(q.competition ?? sheets.keys())].filter((c) => holds(sheets.get(c) ?? NO_SHEET));
|
|
2493
|
+
const one = db.prepare(`SELECT ${TAB_COLUMNS} FROM tabs WHERE address >= ? AND address < ? AND slug = ? ORDER BY address, round, seat_index, line`);
|
|
2494
|
+
try {
|
|
2495
|
+
for (const c of asked.sort((a, b) => a < b ? -1 : a > b ? 1 : 0)) {
|
|
2496
|
+
const [lo, hi] = cardRange(c);
|
|
2497
|
+
yield* run(one, [lo, hi, c]);
|
|
2498
|
+
}
|
|
2499
|
+
} finally {
|
|
2500
|
+
one.finalize();
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
|
|
2505
|
+
class PanelFinder2 {
|
|
2506
|
+
rel;
|
|
2507
|
+
constructor(rel) {
|
|
2508
|
+
this.rel = rel;
|
|
2509
|
+
}
|
|
2510
|
+
async query(q = {}) {
|
|
2511
|
+
await this.rel.fetch("results");
|
|
2512
|
+
await this.rel.require("panels");
|
|
2513
|
+
const where = q.competition === undefined ? "" : " WHERE slug = ?";
|
|
2514
|
+
const seats = this.rel.db("results").query(`SELECT slug AS competition, panel, round, seat_index, address, judge_name_printed,
|
|
2515
|
+
judge_clrg, judge_id, judge_unmatched
|
|
2516
|
+
FROM panels${where} ORDER BY slug, panel, round, seat_index`).all(...q.competition === undefined ? [] : [q.competition]);
|
|
2517
|
+
return { tag: this.rel.tag, asked: q, seats };
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2521
|
+
class FeisPanelFinder2 {
|
|
2522
|
+
rel;
|
|
2523
|
+
constructor(rel) {
|
|
2524
|
+
this.rel = rel;
|
|
2525
|
+
}
|
|
2526
|
+
async query(q = {}) {
|
|
2527
|
+
await this.rel.fetch("results");
|
|
2528
|
+
await this.rel.require("feis-panels");
|
|
2529
|
+
const where = [];
|
|
2530
|
+
const args = [];
|
|
2531
|
+
if (q.address !== undefined) {
|
|
2532
|
+
where.push("address = ?");
|
|
2533
|
+
args.push(q.address);
|
|
2534
|
+
}
|
|
2535
|
+
if (q.platform !== undefined) {
|
|
2536
|
+
where.push("platform = ?");
|
|
2537
|
+
args.push(q.platform);
|
|
2538
|
+
}
|
|
2539
|
+
const seats = this.rel.db("results").query(`SELECT address, platform, round, seat_index, panel_size, panel_kind, judge_name_printed,
|
|
2540
|
+
judge_state_printed, judge_clrg, judge_id, judge_unmatched, judge_basis
|
|
2541
|
+
FROM feis_panels${where.length === 0 ? "" : ` WHERE ${where.join(" AND ")}`}
|
|
2542
|
+
ORDER BY address, round, seat_index`).all(...args);
|
|
2543
|
+
return { tag: this.rel.tag, asked: q, seats };
|
|
2544
|
+
}
|
|
2545
|
+
}
|
|
2546
|
+
async function registerRows(rel, q) {
|
|
2547
|
+
await rel.fetch("results");
|
|
2548
|
+
await rel.require("staff.adjudicators");
|
|
2549
|
+
const where = [];
|
|
2550
|
+
const args = [];
|
|
2551
|
+
if (q.judge_clrg !== undefined) {
|
|
2552
|
+
where.push("judge_clrg = ?");
|
|
2553
|
+
args.push(q.judge_clrg);
|
|
2554
|
+
}
|
|
2555
|
+
if (q.year !== undefined) {
|
|
2556
|
+
where.push("year = ?");
|
|
2557
|
+
args.push(q.year);
|
|
2558
|
+
}
|
|
2559
|
+
const rows = rel.db("results").query(`SELECT judge_clrg, year, cat, name_printed, country, country_printed, country_code, region,
|
|
2560
|
+
region_printed, region_code, geohash, src
|
|
2561
|
+
FROM adjudicators${where.length === 0 ? "" : ` WHERE ${where.join(" AND ")}`}
|
|
2562
|
+
ORDER BY judge_clrg, year`).all(...args);
|
|
2563
|
+
return { tag: rel.tag, asked: q, rows };
|
|
2564
|
+
}
|
|
2565
|
+
|
|
2249
2566
|
var ENCODER2 = roleEncoder();
|
|
2250
2567
|
var WHO = { table: "who", value: "entry", valueType: "INTEGER PRIMARY KEY" };
|
|
2251
2568
|
var ASKED2 = ["surname_key", "nn4", "id"];
|
|
@@ -2363,6 +2680,9 @@ class StaffFinder2 {
|
|
|
2363
2680
|
adjudicator(asked) {
|
|
2364
2681
|
return this.find(asked, "adjudicator");
|
|
2365
2682
|
}
|
|
2683
|
+
adjudicators(q = {}) {
|
|
2684
|
+
return registerRows(this.rel, q);
|
|
2685
|
+
}
|
|
2366
2686
|
async find(asked, role) {
|
|
2367
2687
|
const db = await this.rel.indexDb("staff");
|
|
2368
2688
|
const a = asked.trim();
|
|
@@ -2507,8 +2827,8 @@ async function parquetColumns(path) {
|
|
|
2507
2827
|
return new Set(parquetSchema(meta).children.map((c) => c.element.name));
|
|
2508
2828
|
}
|
|
2509
2829
|
|
|
2510
|
-
var
|
|
2511
|
-
var
|
|
2830
|
+
var str2 = (v) => typeof v === "string" && v !== "" ? v : null;
|
|
2831
|
+
var num2 = (v) => typeof v === "number" ? v : null;
|
|
2512
2832
|
var strs = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string") : [];
|
|
2513
2833
|
var scope = (id) => id === null ? null : id >= FEIS_LOCAL_ID_FLOOR2 ? "per-release" : "stable";
|
|
2514
2834
|
var TEAM_TABLES = [
|
|
@@ -2563,9 +2883,9 @@ var teamsIndex = {
|
|
|
2563
2883
|
const ey = new Map;
|
|
2564
2884
|
const putEy = out.prepare("INSERT OR IGNORE INTO event_year VALUES (?, ?, ?)");
|
|
2565
2885
|
for (const r of t.event_years) {
|
|
2566
|
-
const k =
|
|
2567
|
-
const event =
|
|
2568
|
-
const year =
|
|
2886
|
+
const k = str2(r.event_year);
|
|
2887
|
+
const event = str2(r.event);
|
|
2888
|
+
const year = num2(r.year);
|
|
2569
2889
|
if (k === null || event === null || year === null)
|
|
2570
2890
|
continue;
|
|
2571
2891
|
ey.set(k, { event, year });
|
|
@@ -2574,19 +2894,19 @@ var teamsIndex = {
|
|
|
2574
2894
|
const putR = out.prepare("INSERT OR IGNORE INTO result VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
2575
2895
|
let ord = 0;
|
|
2576
2896
|
for (const r of t.team_results)
|
|
2577
|
-
putR.run(
|
|
2897
|
+
putR.run(str2(r.address), str2(r.slug), str2(r.event), num2(r.year), str2(r.card), str2(r.comp_no), str2(r.title), str2(r.category), num2(r.hands), str2(r.letter), str2(r.label), str2(r.name_printed), str2(r.school_printed), str2(r.school_loc), str2(r.school_id), num2(r.place), str2(r.place_printed), num2(r.tie), num2(r.competitors), JSON.stringify(strs(r.atts)), str2(r.age), str2(r.gender), JSON.stringify(strs(r.printed_status)), ord++);
|
|
2578
2898
|
const putT = out.prepare("INSERT OR IGNORE INTO roster_team VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
2579
2899
|
for (const r of t.roster_teams) {
|
|
2580
|
-
const e = ey.get(
|
|
2581
|
-
putT.run(
|
|
2900
|
+
const e = ey.get(str2(r.event_year) ?? "");
|
|
2901
|
+
putT.run(str2(r.team), str2(r.kind), e?.event ?? null, num2(r.year) ?? e?.year ?? null, str2(r.comp_no), str2(r.title), str2(r.team_index), num2(r.seq), str2(r.school_id), str2(r.school_print_materialized), str2(r.dance), str2(r.school_print_as_of), ord++);
|
|
2582
2902
|
}
|
|
2583
2903
|
const putM = out.prepare("INSERT INTO roster_member VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
|
2584
2904
|
for (const r of t.roster_members)
|
|
2585
|
-
putM.run(
|
|
2905
|
+
putM.run(str2(r.team), num2(r.seq), typeof r.name_printed === "string" ? r.name_printed : "", str2(r.name), num2(r.yob), num2(r.dancer_id), str2(r.gender), ord++);
|
|
2586
2906
|
const putJ = out.prepare("INSERT INTO result_roster VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
2587
2907
|
for (const r of t.team_result_rosters) {
|
|
2588
|
-
const e = ey.get(
|
|
2589
|
-
putJ.run(
|
|
2908
|
+
const e = ey.get(str2(r.event_year) ?? "");
|
|
2909
|
+
putJ.run(str2(r.team), e?.event ?? null, e?.year ?? null, str2(r.comp_no), str2(r.school_id), str2(r.result_address), str2(r.join_kind), num2(r.via_split) === 1 ? 1 : 0, num2(r.roster_teams), num2(r.result_teams), str2(r.roster_index), str2(r.result_letter), ord++);
|
|
2590
2910
|
}
|
|
2591
2911
|
for (const s of TEAMS_INDEXES)
|
|
2592
2912
|
out.run(s);
|
|
@@ -2606,11 +2926,11 @@ var eventsIndex = {
|
|
|
2606
2926
|
out.run(EVENTS_SCHEMA);
|
|
2607
2927
|
const put = out.prepare("INSERT OR IGNORE INTO event_year VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
2608
2928
|
for (const r of rows) {
|
|
2609
|
-
const event =
|
|
2610
|
-
const year =
|
|
2929
|
+
const event = str2(r.event);
|
|
2930
|
+
const year = num2(r.year);
|
|
2611
2931
|
if (event === null || year === null)
|
|
2612
2932
|
continue;
|
|
2613
|
-
put.run(event, year,
|
|
2933
|
+
put.run(event, year, str2(r.date_lo), str2(r.date_hi), str2(r.resolution), str2(r.source), JSON.stringify(strs(r.date_printed)), str2(r.place), JSON.stringify(strs(r.place_printed)));
|
|
2614
2934
|
}
|
|
2615
2935
|
out.run("CREATE INDEX event_year_event ON event_year(event COLLATE NOCASE)");
|
|
2616
2936
|
}
|
|
@@ -3238,7 +3558,7 @@ var FEATURES2 = [
|
|
|
3238
3558
|
feature: "schools.lineage",
|
|
3239
3559
|
needs: ["school-lineage.jsonl"],
|
|
3240
3560
|
since: 184,
|
|
3241
|
-
calls: "schools.links and schools.
|
|
3561
|
+
calls: "schools.links, schools.line and schools.lineage (refused on a release without it), and the `lineage` school evidence of dancers.resolve and dancers.search: no school is joined by lineage, never refused, on a release without it"
|
|
3242
3562
|
},
|
|
3243
3563
|
{
|
|
3244
3564
|
feature: "results.stream",
|
|
@@ -3407,6 +3727,91 @@ var FEATURES2 = [
|
|
|
3407
3727
|
],
|
|
3408
3728
|
since: 260,
|
|
3409
3729
|
calls: "staff.teacher, staff.adjudicator (the staff index)"
|
|
3730
|
+
},
|
|
3731
|
+
{ feature: "tabs", needs: TAB_NEEDS, since: 184, calls: "tabs.query, tabs.stream" },
|
|
3732
|
+
{
|
|
3733
|
+
feature: "panels",
|
|
3734
|
+
needs: [
|
|
3735
|
+
"slug",
|
|
3736
|
+
"panel",
|
|
3737
|
+
"round",
|
|
3738
|
+
"seat_index",
|
|
3739
|
+
"address",
|
|
3740
|
+
"judge_name_printed",
|
|
3741
|
+
"judge_clrg",
|
|
3742
|
+
"judge_id",
|
|
3743
|
+
"judge_unmatched"
|
|
3744
|
+
].map((c) => `results:panels.${c}`),
|
|
3745
|
+
since: 184,
|
|
3746
|
+
calls: "panels.query"
|
|
3747
|
+
},
|
|
3748
|
+
{
|
|
3749
|
+
feature: "feis-panels",
|
|
3750
|
+
needs: [
|
|
3751
|
+
"address",
|
|
3752
|
+
"platform",
|
|
3753
|
+
"round",
|
|
3754
|
+
"seat_index",
|
|
3755
|
+
"panel_size",
|
|
3756
|
+
"panel_kind",
|
|
3757
|
+
"judge_name_printed",
|
|
3758
|
+
"judge_state_printed",
|
|
3759
|
+
"judge_clrg",
|
|
3760
|
+
"judge_id",
|
|
3761
|
+
"judge_unmatched",
|
|
3762
|
+
"judge_basis"
|
|
3763
|
+
].map((c) => `results:feis_panels.${c}`),
|
|
3764
|
+
since: 260,
|
|
3765
|
+
calls: "feisPanels.query"
|
|
3766
|
+
},
|
|
3767
|
+
{
|
|
3768
|
+
feature: "staff.adjudicators",
|
|
3769
|
+
needs: [
|
|
3770
|
+
"judge_clrg",
|
|
3771
|
+
"year",
|
|
3772
|
+
"cat",
|
|
3773
|
+
"name_printed",
|
|
3774
|
+
"country",
|
|
3775
|
+
"country_printed",
|
|
3776
|
+
"country_code",
|
|
3777
|
+
"region",
|
|
3778
|
+
"region_printed",
|
|
3779
|
+
"region_code",
|
|
3780
|
+
"geohash",
|
|
3781
|
+
"src"
|
|
3782
|
+
].map((c) => `results:adjudicators.${c}`),
|
|
3783
|
+
since: 230,
|
|
3784
|
+
calls: "staff.adjudicators"
|
|
3785
|
+
},
|
|
3786
|
+
{
|
|
3787
|
+
feature: "schools.registry",
|
|
3788
|
+
needs: ["school-registry.jsonl"],
|
|
3789
|
+
since: 260,
|
|
3790
|
+
calls: "schools.list"
|
|
3791
|
+
},
|
|
3792
|
+
{
|
|
3793
|
+
feature: "schools.prints",
|
|
3794
|
+
needs: [
|
|
3795
|
+
"results:results.school_printed",
|
|
3796
|
+
"results:results.school_id",
|
|
3797
|
+
"results:results.competition_line",
|
|
3798
|
+
"results:competitions.event",
|
|
3799
|
+
"results:competitions.year"
|
|
3800
|
+
],
|
|
3801
|
+
since: 184,
|
|
3802
|
+
calls: "schools.prints"
|
|
3803
|
+
},
|
|
3804
|
+
{
|
|
3805
|
+
feature: "schools.redirects",
|
|
3806
|
+
needs: ["school-redirects.jsonl"],
|
|
3807
|
+
since: 184,
|
|
3808
|
+
calls: "schools.redirects"
|
|
3809
|
+
},
|
|
3810
|
+
{
|
|
3811
|
+
feature: "schools.associations",
|
|
3812
|
+
needs: ["observed-associations.jsonl"],
|
|
3813
|
+
since: 215,
|
|
3814
|
+
calls: "schools.associations"
|
|
3410
3815
|
}
|
|
3411
3816
|
];
|
|
3412
3817
|
async function hasNeed(probe, n) {
|
|
@@ -3490,6 +3895,9 @@ class Release2 {
|
|
|
3490
3895
|
registrations;
|
|
3491
3896
|
teams;
|
|
3492
3897
|
events;
|
|
3898
|
+
tabs;
|
|
3899
|
+
panels;
|
|
3900
|
+
feisPanels;
|
|
3493
3901
|
opts;
|
|
3494
3902
|
handles = new Map;
|
|
3495
3903
|
remoteAssets = null;
|
|
@@ -3512,6 +3920,9 @@ class Release2 {
|
|
|
3512
3920
|
this.registrations = new RegistrationResolver2(this, this.comps, opts.dancerResolver);
|
|
3513
3921
|
this.teams = new TeamFinder2(this);
|
|
3514
3922
|
this.events = new EventFinder2(this);
|
|
3923
|
+
this.tabs = new TabFinder2(this);
|
|
3924
|
+
this.panels = new PanelFinder2(this);
|
|
3925
|
+
this.feisPanels = new FeisPanelFinder2(this);
|
|
3515
3926
|
}
|
|
3516
3927
|
receipt() {
|
|
3517
3928
|
return readReceipt(this.dir) ?? { tag: this.tag, source: "unknown", files: {} };
|
|
@@ -4232,4 +4643,4 @@ function staleWarning2(answered, latest, floor, tags = [], command = "idq") {
|
|
|
4232
4643
|
return `answered from ${answered}. ${floorTag ?? `cut ${floor.cut}`} is required${why}: run \`${command} use ${floor.cut}\` to get it`;
|
|
4233
4644
|
}
|
|
4234
4645
|
|
|
4235
|
-
export { DATABASES2, planAsset2, sha256File2, unzstdTo2, NAME_LEVELS2, nameLevel2, NO_CALENDAR2, FeisFinder2, ADVANCEMENT_DANCES2, entryRank2, FEIS_LOCAL_ID_FLOOR2, ResultFinder2, MajorsFinder2, LINEAGE_FILE2, linksOfLineage2, releaseSchoolGraph2, readsSpanishNames2, SchoolResolver2, initialsOnly2, nameOrderOf, DancerResolver2, readPopulation2, syllabusSourceOf2, canonicalOf2, CompResolver2, StaffFinder2, TeamFinder2, EventFinder2, defaultBuilders2, indexPath2, indexKey2, isCurrent2, buildIndex2, ensureIndex2, listIndexes2, readPin2, youngest2, dancerResolverOf2, RegistrationResolver2, ghRemote2, httpsRemote2, fallbackRemote2, setRemote2, defaultRemote, columnsOf2, FEATURES2, capabilityOf2, needsRelease2, resolveTag2, Release2, openRelease2, openCached2, DEFAULT_KEEP2, ReleaseManager2, releases2, LOCAL_DIR2, localRoot2, newerThan2, incomplete2, releaseVersion2, pickBuild2, buildTag2, lacks, openBuild2, sweepBuilds2, LATEST_CHECK_MS2, LATEST_CHECK_BUDGET_MS2, latestCheckPath2, readLatestCheck2, latestCheck2, within, staleWarning2 };
|
|
4646
|
+
export { DATABASES2, planAsset2, sha256File2, unzstdTo2, NAME_LEVELS2, nameLevel2, NO_CALENDAR2, FeisFinder2, ADVANCEMENT_DANCES2, entryRank2, FEIS_LOCAL_ID_FLOOR2, ResultFinder2, MajorsFinder2, LINEAGE_FILE2, linksOfLineage2, releaseSchoolGraph2, readsSpanishNames2, SchoolResolver2, initialsOnly2, nameOrderOf, DancerResolver2, readPopulation2, syllabusSourceOf2, canonicalOf2, CompResolver2, TabFinder2, PanelFinder2, FeisPanelFinder2, StaffFinder2, TeamFinder2, EventFinder2, defaultBuilders2, indexPath2, indexKey2, isCurrent2, buildIndex2, ensureIndex2, listIndexes2, readPin2, youngest2, dancerResolverOf2, RegistrationResolver2, ghRemote2, httpsRemote2, fallbackRemote2, setRemote2, defaultRemote, columnsOf2, FEATURES2, capabilityOf2, needsRelease2, resolveTag2, Release2, openRelease2, openCached2, DEFAULT_KEEP2, ReleaseManager2, releases2, LOCAL_DIR2, localRoot2, newerThan2, incomplete2, releaseVersion2, pickBuild2, buildTag2, lacks, openBuild2, sweepBuilds2, LATEST_CHECK_MS2, LATEST_CHECK_BUDGET_MS2, latestCheckPath2, readLatestCheck2, latestCheck2, within, staleWarning2 };
|
package/dist/cli.js
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
latestCheck2,
|
|
22
22
|
within,
|
|
23
23
|
staleWarning2
|
|
24
|
-
} from "./chunks/index-
|
|
24
|
+
} from "./chunks/index-2ms980hc.js";
|
|
25
25
|
import"./chunks/index-hghdy980.js";
|
|
26
26
|
|
|
27
27
|
var USAGE_HEADER = "usage: idq <verb> [--cache <dir>] [--repo <owner/name>] [--json] [--live]";
|
|
@@ -285,6 +285,61 @@ var VERBS = [
|
|
|
285
285
|
" or later (default 3)"
|
|
286
286
|
]
|
|
287
287
|
},
|
|
288
|
+
{
|
|
289
|
+
verb: "tabs",
|
|
290
|
+
value: ["--release", "--comp", "--address", "--round", "--event", "--year", "--tier"],
|
|
291
|
+
bool: ["--stream"],
|
|
292
|
+
usage: [
|
|
293
|
+
" tabs [--release <spec>] --comp <competition> | --address <address> [--round <r>]",
|
|
294
|
+
" a marks sheet (or one card of it): every seat's mark,",
|
|
295
|
+
" place and points, with the judge",
|
|
296
|
+
" tabs --stream [--release <spec>] [--comp <c,...>] [--event <e,...>]",
|
|
297
|
+
" [--year <y> | --year <from>..<to>] [--tier <t,...>]",
|
|
298
|
+
" every cell of every sheet named, one JSON line each"
|
|
299
|
+
]
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
verb: "panels",
|
|
303
|
+
value: ["--release", "--comp"],
|
|
304
|
+
bool: [],
|
|
305
|
+
usage: [
|
|
306
|
+
" panels [--release <spec>] [--comp <competition>]",
|
|
307
|
+
" who sat a major's competition (every one's, with no --comp)"
|
|
308
|
+
]
|
|
309
|
+
},
|
|
310
|
+
{
|
|
311
|
+
verb: "feis-panels",
|
|
312
|
+
value: ["--release", "--address", "--platform"],
|
|
313
|
+
bool: [],
|
|
314
|
+
usage: [
|
|
315
|
+
" feis-panels [--release <spec>] [--address <feis competition>] [--platform <p>]",
|
|
316
|
+
" who sat a feis's competition (fweb:ABC24.105)"
|
|
317
|
+
]
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
verb: "register",
|
|
321
|
+
value: ["--release", "--year", "--td"],
|
|
322
|
+
bool: [],
|
|
323
|
+
usage: [
|
|
324
|
+
" register [--release <spec>] [--year <y>] [--td <TD number>]",
|
|
325
|
+
" the adjudicator register's rows: category, country,",
|
|
326
|
+
" region, geohash, per year"
|
|
327
|
+
]
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
verb: "schools",
|
|
331
|
+
value: ["--release", "--event", "--year", "--school"],
|
|
332
|
+
bool: ["--prints", "--redirects", "--lineage", "--associations"],
|
|
333
|
+
usage: [
|
|
334
|
+
" schools [--release <spec>] every school the registry lists: display, regions, places",
|
|
335
|
+
" schools --prints [--release <spec>] [--event <e>] [--year <y>]",
|
|
336
|
+
" the (print, school_id) pairs the rows attach, per event-year",
|
|
337
|
+
" schools --redirects | --lineage [--release <spec>]",
|
|
338
|
+
" the retired ids; the lineage edges",
|
|
339
|
+
" schools --associations [--release <spec>] [--school <school_id>]",
|
|
340
|
+
" the people a directory lists beside a school"
|
|
341
|
+
]
|
|
342
|
+
},
|
|
288
343
|
{
|
|
289
344
|
verb: "teams",
|
|
290
345
|
value: ["--release", "--event", "--year"],
|
|
@@ -662,6 +717,27 @@ function streamQueryOf(p) {
|
|
|
662
717
|
q.primary = true;
|
|
663
718
|
return q;
|
|
664
719
|
}
|
|
720
|
+
function tabStreamQueryOf(p) {
|
|
721
|
+
const q = {};
|
|
722
|
+
const comp = p.flags.get("--comp");
|
|
723
|
+
if (comp !== undefined)
|
|
724
|
+
q.competition = listOf(comp);
|
|
725
|
+
const event = p.flags.get("--event");
|
|
726
|
+
if (event !== undefined)
|
|
727
|
+
q.event = listOf(event);
|
|
728
|
+
const tier = p.flags.get("--tier");
|
|
729
|
+
if (tier !== undefined)
|
|
730
|
+
q.tier = listOf(tier);
|
|
731
|
+
const year = p.flags.get("--year");
|
|
732
|
+
if (year !== undefined) {
|
|
733
|
+
const m = /^(\d{4})\.\.(\d{4})$/.exec(year);
|
|
734
|
+
q.year = m === null ? Number(year) : [Number(m[1]), Number(m[2])];
|
|
735
|
+
if (typeof q.year === "number" && !Number.isInteger(q.year))
|
|
736
|
+
throw new Error(`--year takes a year or <from>..<to>, not "${year}"`);
|
|
737
|
+
}
|
|
738
|
+
return q;
|
|
739
|
+
}
|
|
740
|
+
var tabLine = (t) => ` ${t.address} ${t.round} seat ${t.seat_index}/${t.panel_size} ${t.judge_clrg ?? t.judge_id ?? "-"} ${t.judge_name_printed ?? "-"} mark ${t.mark_printed ?? "-"} place ${t.place_printed ?? "-"}${t.tie === 1 ? "=" : ""} points ${t.points_printed ?? "-"}`;
|
|
665
741
|
function eventYearOf(p) {
|
|
666
742
|
const event = p.flags.get("--event");
|
|
667
743
|
const year = p.flags.get("--year");
|
|
@@ -683,6 +759,11 @@ var ANSWERING = new Set([
|
|
|
683
759
|
"records",
|
|
684
760
|
"feis-dates",
|
|
685
761
|
"tabulated",
|
|
762
|
+
"tabs",
|
|
763
|
+
"panels",
|
|
764
|
+
"feis-panels",
|
|
765
|
+
"register",
|
|
766
|
+
"schools",
|
|
686
767
|
"teams",
|
|
687
768
|
"events",
|
|
688
769
|
"teacher",
|
|
@@ -1163,6 +1244,145 @@ async function main(argv, io = {}) {
|
|
|
1163
1244
|
rel.close();
|
|
1164
1245
|
}
|
|
1165
1246
|
}
|
|
1247
|
+
case "tabs": {
|
|
1248
|
+
const stream = p.bools.has("--stream");
|
|
1249
|
+
const tq = stream ? tabStreamQueryOf(p) : null;
|
|
1250
|
+
const comp = p.flags.get("--comp");
|
|
1251
|
+
const address = p.flags.get("--address");
|
|
1252
|
+
if (!stream && comp === undefined && address === undefined) {
|
|
1253
|
+
log("tabs --comp <competition> | --address <address> [--round <r>], or tabs --stream");
|
|
1254
|
+
return 2;
|
|
1255
|
+
}
|
|
1256
|
+
const rel = await open(spec, { ...opts, assets: [] });
|
|
1257
|
+
try {
|
|
1258
|
+
if (tq !== null) {
|
|
1259
|
+
let n = 0;
|
|
1260
|
+
for await (const t of rel.tabs.stream(tq)) {
|
|
1261
|
+
say(JSON.stringify(t));
|
|
1262
|
+
n++;
|
|
1263
|
+
}
|
|
1264
|
+
log(`${n} cell(s) in ${rel.tag}`);
|
|
1265
|
+
return n === 0 ? 1 : 0;
|
|
1266
|
+
}
|
|
1267
|
+
const round = p.flags.get("--round");
|
|
1268
|
+
const a = await rel.tabs.query({
|
|
1269
|
+
...address !== undefined ? { address } : { competition: comp },
|
|
1270
|
+
...round !== undefined ? { round } : {}
|
|
1271
|
+
});
|
|
1272
|
+
out(a, () => {
|
|
1273
|
+
for (const t of a.rows)
|
|
1274
|
+
say(tabLine(t));
|
|
1275
|
+
say(`${a.rows.length} cell(s) in ${a.tag}`);
|
|
1276
|
+
});
|
|
1277
|
+
return a.rows.length === 0 ? 1 : 0;
|
|
1278
|
+
} finally {
|
|
1279
|
+
rel.close();
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
case "panels": {
|
|
1283
|
+
const rel = await open(spec, { ...opts, assets: [] });
|
|
1284
|
+
try {
|
|
1285
|
+
const comp = p.flags.get("--comp");
|
|
1286
|
+
const a = await rel.panels.query(comp !== undefined ? { competition: comp } : {});
|
|
1287
|
+
out(a, () => {
|
|
1288
|
+
for (const s of a.seats)
|
|
1289
|
+
say(` ${s.competition} ${s.panel} ${s.round} seat ${s.seat_index} ${s.judge_clrg ?? s.judge_id ?? "-"} ${s.judge_name_printed ?? "-"}${s.judge_unmatched === null ? "" : ` (${s.judge_unmatched})`}`);
|
|
1290
|
+
say(`${a.seats.length} seat(s) in ${a.tag}`);
|
|
1291
|
+
});
|
|
1292
|
+
return a.seats.length === 0 ? 1 : 0;
|
|
1293
|
+
} finally {
|
|
1294
|
+
rel.close();
|
|
1295
|
+
}
|
|
1296
|
+
}
|
|
1297
|
+
case "feis-panels": {
|
|
1298
|
+
const rel = await open(spec, { ...opts, assets: [] });
|
|
1299
|
+
try {
|
|
1300
|
+
const address = p.flags.get("--address");
|
|
1301
|
+
const platform = p.flags.get("--platform");
|
|
1302
|
+
const a = await rel.feisPanels.query({
|
|
1303
|
+
...address !== undefined ? { address } : {},
|
|
1304
|
+
...platform !== undefined ? { platform } : {}
|
|
1305
|
+
});
|
|
1306
|
+
out(a, () => {
|
|
1307
|
+
for (const s of a.seats)
|
|
1308
|
+
say(` ${s.address} ${s.round} seat ${s.seat_index}/${s.panel_size} ${s.judge_clrg ?? s.judge_id ?? "-"} ${s.judge_name_printed}${s.judge_basis === null ? "" : ` (${s.judge_basis})`}`);
|
|
1309
|
+
say(`${a.seats.length} seat(s) in ${a.tag}`);
|
|
1310
|
+
});
|
|
1311
|
+
return a.seats.length === 0 ? 1 : 0;
|
|
1312
|
+
} finally {
|
|
1313
|
+
rel.close();
|
|
1314
|
+
}
|
|
1315
|
+
}
|
|
1316
|
+
case "register": {
|
|
1317
|
+
const rel = await open(spec, { ...opts, assets: [] });
|
|
1318
|
+
try {
|
|
1319
|
+
const year = p.flags.get("--year");
|
|
1320
|
+
const td = p.flags.get("--td");
|
|
1321
|
+
const a = await rel.staff.adjudicators({
|
|
1322
|
+
...year !== undefined ? { year: Number(year) } : {},
|
|
1323
|
+
...td !== undefined ? { judge_clrg: Number(td) } : {}
|
|
1324
|
+
});
|
|
1325
|
+
out(a, () => {
|
|
1326
|
+
for (const r of a.rows)
|
|
1327
|
+
say(` ${r.judge_clrg} ${r.year} ${r.cat} ${r.name_printed} ${r.country_code ?? r.country} ${r.region_code ?? r.region} ${r.geohash ?? "-"}`);
|
|
1328
|
+
say(`${a.rows.length} register row(s) in ${a.tag}`);
|
|
1329
|
+
});
|
|
1330
|
+
return a.rows.length === 0 ? 1 : 0;
|
|
1331
|
+
} finally {
|
|
1332
|
+
rel.close();
|
|
1333
|
+
}
|
|
1334
|
+
}
|
|
1335
|
+
case "schools": {
|
|
1336
|
+
const rel = await open(spec, { ...opts, assets: [] });
|
|
1337
|
+
try {
|
|
1338
|
+
if (p.bools.has("--prints")) {
|
|
1339
|
+
const a = await rel.schools.prints(eventYearOf(p));
|
|
1340
|
+
out(a, () => {
|
|
1341
|
+
for (const x of a.prints)
|
|
1342
|
+
say(` ${x.year ?? "?"} ${x.event} ${x.school_id} "${x.print}" ${x.rows} rows`);
|
|
1343
|
+
say(`${a.prints.length} pair(s) in ${a.tag}`);
|
|
1344
|
+
});
|
|
1345
|
+
return a.prints.length === 0 ? 1 : 0;
|
|
1346
|
+
}
|
|
1347
|
+
if (p.bools.has("--redirects")) {
|
|
1348
|
+
const a = await rel.schools.redirects();
|
|
1349
|
+
out(a, () => {
|
|
1350
|
+
for (const r of a.redirects)
|
|
1351
|
+
say(` ${r.old_id} -> ${r.new_id} ${r.kind}${r.since === null ? "" : ` since ${r.since}`}`);
|
|
1352
|
+
say(`${a.redirects.length} redirect(s) in ${a.tag}`);
|
|
1353
|
+
});
|
|
1354
|
+
return a.redirects.length === 0 ? 1 : 0;
|
|
1355
|
+
}
|
|
1356
|
+
if (p.bools.has("--lineage")) {
|
|
1357
|
+
const a = await rel.schools.lineage();
|
|
1358
|
+
out(a, () => {
|
|
1359
|
+
for (const e of a.edges)
|
|
1360
|
+
say(` ${e.id} ${e.direction} ${e.other} ${e.shape} ${e.year ?? "?"}${e.provisional ? " provisional" : ""}`);
|
|
1361
|
+
say(`${a.edges.length} edge end(s) in ${a.tag}`);
|
|
1362
|
+
});
|
|
1363
|
+
return a.edges.length === 0 ? 1 : 0;
|
|
1364
|
+
}
|
|
1365
|
+
if (p.bools.has("--associations")) {
|
|
1366
|
+
const school = p.flags.get("--school");
|
|
1367
|
+
const a = await rel.schools.associations(school !== undefined ? { school_id: school } : {});
|
|
1368
|
+
out(a, () => {
|
|
1369
|
+
for (const x of a.associations)
|
|
1370
|
+
say(` ${x.school_id ?? "(no id)"} "${x.school_printed ?? ""}" ${x.person_printed} (${x.person_type ?? "-"}${x.credentials === null ? "" : `, ${x.credentials}`}) ${x.date ?? "-"} ${x.src_type ?? ""}`);
|
|
1371
|
+
say(`${a.associations.length} association(s) in ${a.tag}`);
|
|
1372
|
+
});
|
|
1373
|
+
return a.associations.length === 0 ? 1 : 0;
|
|
1374
|
+
}
|
|
1375
|
+
const a = await rel.schools.list();
|
|
1376
|
+
out(a, () => {
|
|
1377
|
+
for (const s of a.schools)
|
|
1378
|
+
say(` ${s.school_id} ${s.display} ${s.regions.join(",") || "-"} ${s.places.join(",") || "-"}`);
|
|
1379
|
+
say(`${a.schools.length} school(s) in ${a.tag}`);
|
|
1380
|
+
});
|
|
1381
|
+
return a.schools.length === 0 ? 1 : 0;
|
|
1382
|
+
} finally {
|
|
1383
|
+
rel.close();
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1166
1386
|
case "teams": {
|
|
1167
1387
|
const rel = await open(spec, { ...opts, assets: [] });
|
|
1168
1388
|
try {
|
|
@@ -1320,5 +1540,6 @@ export {
|
|
|
1320
1540
|
parseArgs,
|
|
1321
1541
|
renderUsage,
|
|
1322
1542
|
streamQueryOf,
|
|
1543
|
+
tabStreamQueryOf,
|
|
1323
1544
|
valueFlags
|
|
1324
1545
|
};
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,9 @@ import {
|
|
|
24
24
|
syllabusSourceOf2,
|
|
25
25
|
canonicalOf2,
|
|
26
26
|
CompResolver2,
|
|
27
|
+
TabFinder2,
|
|
28
|
+
PanelFinder2,
|
|
29
|
+
FeisPanelFinder2,
|
|
27
30
|
StaffFinder2,
|
|
28
31
|
TeamFinder2,
|
|
29
32
|
EventFinder2,
|
|
@@ -68,7 +71,7 @@ import {
|
|
|
68
71
|
readLatestCheck2,
|
|
69
72
|
latestCheck2,
|
|
70
73
|
staleWarning2
|
|
71
|
-
} from "./chunks/index-
|
|
74
|
+
} from "./chunks/index-2ms980hc.js";
|
|
72
75
|
import {
|
|
73
76
|
cacheRoot2,
|
|
74
77
|
repoOf2
|
|
@@ -93,6 +96,7 @@ export {
|
|
|
93
96
|
FEATURES2 as FEATURES,
|
|
94
97
|
FEIS_LOCAL_ID_FLOOR2 as FEIS_LOCAL_ID_FLOOR,
|
|
95
98
|
FeisFinder2 as FeisFinder,
|
|
99
|
+
FeisPanelFinder2 as FeisPanelFinder,
|
|
96
100
|
LATEST_CHECK_BUDGET_MS2 as LATEST_CHECK_BUDGET_MS,
|
|
97
101
|
LATEST_CHECK_MS2 as LATEST_CHECK_MS,
|
|
98
102
|
LINEAGE_FILE2 as LINEAGE_FILE,
|
|
@@ -100,12 +104,14 @@ export {
|
|
|
100
104
|
MajorsFinder2 as MajorsFinder,
|
|
101
105
|
NAME_LEVELS2 as NAME_LEVELS,
|
|
102
106
|
NO_CALENDAR2 as NO_CALENDAR,
|
|
107
|
+
PanelFinder2 as PanelFinder,
|
|
103
108
|
RegistrationResolver2 as RegistrationResolver,
|
|
104
109
|
Release2 as Release,
|
|
105
110
|
ReleaseManager2 as ReleaseManager,
|
|
106
111
|
ResultFinder2 as ResultFinder,
|
|
107
112
|
SchoolResolver2 as SchoolResolver,
|
|
108
113
|
StaffFinder2 as StaffFinder,
|
|
114
|
+
TabFinder2 as TabFinder,
|
|
109
115
|
TeamFinder2 as TeamFinder,
|
|
110
116
|
buildIndex2 as buildIndex,
|
|
111
117
|
buildTag2 as buildTag,
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { type FreshnessFloor } from "./freshness.js";
|
|
|
3
3
|
import { type LocalBuild } from "./local.js";
|
|
4
4
|
import type { OpenOptions } from "./release.js";
|
|
5
5
|
import type { StreamQuery } from "./stream.js";
|
|
6
|
+
import type { TabStreamQuery } from "./tabs.js";
|
|
6
7
|
export { GLOBAL_FLAGS, USAGE_FOOTER, USAGE_HEADER, VERBS, type VerbSpec, renderUsage, valueFlags, } from "./cli-spec.js";
|
|
7
8
|
export declare const USAGE: string;
|
|
8
9
|
export interface Parsed {
|
|
@@ -20,6 +21,7 @@ type Line<T> = {
|
|
|
20
21
|
};
|
|
21
22
|
export declare function jsonLines<T>(text: string, check: (v: T) => string | null): Line<T>[];
|
|
22
23
|
export declare function streamQueryOf(p: Parsed): StreamQuery;
|
|
24
|
+
export declare function tabStreamQueryOf(p: Parsed): TabStreamQuery;
|
|
23
25
|
export interface LocalIO {
|
|
24
26
|
builds: () => readonly LocalBuild[];
|
|
25
27
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -16,10 +16,12 @@ export { type Remote, type RemoteAsset, fallbackRemote, ghRemote, httpsRemote, s
|
|
|
16
16
|
export { type OpenOptions, Release, openCached, openRelease, resolveTag, } from "./release.js";
|
|
17
17
|
export { type MajorCompetition, type MajorEvent, MajorsFinder, type ResultAnswer, ResultFinder, type ResultQuery, type ResultRow, } from "./results.js";
|
|
18
18
|
export { type DancerAnswerLike, type DancerQueryLike, type DancerResolverLike, type DancerUnavailable, type RegistrationRow, type ResolvedDancer, RegistrationResolver, type ResolvedRegistration, dancerResolverOf, youngest, } from "./registrations.js";
|
|
19
|
+
export type { LineageEdge, ObservedAssociation, RegistrySchool, SchoolPrint, SchoolRedirect, } from "./school-bulk.js";
|
|
19
20
|
export { type SchoolAnswer, type SchoolCandidate, type SchoolQuery, SchoolResolver, type SchoolRung, readsSpanishNames, type SpanishNames, } from "./schools.js";
|
|
20
21
|
export { LINEAGE_FILE, type SchoolLineAnswer, type SchoolLinksAnswer, linksOfLineage, releaseSchoolGraph, } from "./school-links.js";
|
|
21
22
|
export type { LineCandidate, LinkPath, LinkPolicy, LinkQuery, LinkStep, PathFlags, SchoolLink, StepFlags, StepPolicy, } from "@finbheara/domain/school-graph";
|
|
22
23
|
export { type Capability, FEATURES, type Feature, type SchemaProbe, capabilityOf, columnsOf, needsRelease, } from "./schema.js";
|
|
23
24
|
export { type EntryRow, type StreamQuery, type StreamRow, type StreamScope, entryRank, } from "./stream.js";
|
|
25
|
+
export { type FeisPanelSeat, FeisPanelFinder, PanelFinder, type PanelSeat, type RegisterRow, type TabAnswer, TabFinder, type TabQuery, type TabRow, type TabStreamQuery, } from "./tabs.js";
|
|
24
26
|
export { EventFinder, type EventYear, type EventYearQuery, type ResultRoster, type RosterMember, type RosterTeam, TeamFinder, type TeamResult, } from "./teams.js";
|
|
25
27
|
export { ARCHIVE_TAG, type ArchiveTag, type ReleaseSpec, compareTagsNewestFirst, cutOf, parseArchiveTag, parseReleaseSpec, pickTag, renderArchiveTag, } from "./tag.js";
|
package/dist/types/people.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { type StaffRole } from "@finbheara/domain/noun-index";
|
|
|
2
2
|
import { type NameLevel } from "./dancers-names.js";
|
|
3
3
|
import type { IndexBuilder } from "./indexes.js";
|
|
4
4
|
import type { Release } from "./release.js";
|
|
5
|
+
import { type RegisterRow } from "./tabs.js";
|
|
5
6
|
export interface Taught {
|
|
6
7
|
school_id: string;
|
|
7
8
|
school: string | null;
|
|
@@ -59,6 +60,17 @@ export declare class StaffFinder {
|
|
|
59
60
|
constructor(rel: Release);
|
|
60
61
|
teacher(asked: string): Promise<StaffAnswer>;
|
|
61
62
|
adjudicator(asked: string): Promise<StaffAnswer>;
|
|
63
|
+
adjudicators(q?: {
|
|
64
|
+
year?: number;
|
|
65
|
+
judge_clrg?: number;
|
|
66
|
+
}): Promise<{
|
|
67
|
+
tag: string;
|
|
68
|
+
asked: {
|
|
69
|
+
year?: number;
|
|
70
|
+
judge_clrg?: number;
|
|
71
|
+
};
|
|
72
|
+
rows: RegisterRow[];
|
|
73
|
+
}>;
|
|
62
74
|
private find;
|
|
63
75
|
private person;
|
|
64
76
|
private taughtWhere;
|
package/dist/types/release.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { type Remote } from "./remote.js";
|
|
|
11
11
|
import { MajorsFinder, ResultFinder } from "./results.js";
|
|
12
12
|
import { type Capability } from "./schema.js";
|
|
13
13
|
import { type SchoolReaderChoice, SchoolResolver } from "./schools.js";
|
|
14
|
+
import { FeisPanelFinder, PanelFinder, TabFinder } from "./tabs.js";
|
|
14
15
|
import { type ReleaseSpec } from "./tag.js";
|
|
15
16
|
import { EventFinder, TeamFinder } from "./teams.js";
|
|
16
17
|
export interface OpenOptions extends ClientOptions {
|
|
@@ -44,6 +45,9 @@ export declare class Release {
|
|
|
44
45
|
readonly registrations: RegistrationResolver;
|
|
45
46
|
readonly teams: TeamFinder;
|
|
46
47
|
readonly events: EventFinder;
|
|
48
|
+
readonly tabs: TabFinder;
|
|
49
|
+
readonly panels: PanelFinder;
|
|
50
|
+
readonly feisPanels: FeisPanelFinder;
|
|
47
51
|
private readonly opts;
|
|
48
52
|
private readonly handles;
|
|
49
53
|
private remoteAssets;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { Release } from "./release.js";
|
|
2
|
+
export interface RegistrySchool {
|
|
3
|
+
school_id: string;
|
|
4
|
+
display: string;
|
|
5
|
+
regions: string[];
|
|
6
|
+
places: string[];
|
|
7
|
+
}
|
|
8
|
+
export interface SchoolPrint {
|
|
9
|
+
event: string;
|
|
10
|
+
year: number | null;
|
|
11
|
+
print: string;
|
|
12
|
+
school_id: string;
|
|
13
|
+
rows: number;
|
|
14
|
+
}
|
|
15
|
+
export interface SchoolRedirect {
|
|
16
|
+
old_id: string;
|
|
17
|
+
new_id: string;
|
|
18
|
+
kind: string;
|
|
19
|
+
since: number | null;
|
|
20
|
+
}
|
|
21
|
+
export interface LineageEdge {
|
|
22
|
+
id: string;
|
|
23
|
+
direction: string;
|
|
24
|
+
other: string;
|
|
25
|
+
shape: string;
|
|
26
|
+
year: number | null;
|
|
27
|
+
provisional: boolean;
|
|
28
|
+
decision: string | null;
|
|
29
|
+
confidence: number | null;
|
|
30
|
+
}
|
|
31
|
+
export interface ObservedAssociation {
|
|
32
|
+
at: string;
|
|
33
|
+
seq: number;
|
|
34
|
+
date: string | null;
|
|
35
|
+
person: string | null;
|
|
36
|
+
person_printed: string;
|
|
37
|
+
reading: string | null;
|
|
38
|
+
person_type: string | null;
|
|
39
|
+
credentials: string | null;
|
|
40
|
+
caption: string | null;
|
|
41
|
+
school_printed: string | null;
|
|
42
|
+
school_id: string | null;
|
|
43
|
+
association_type: string | null;
|
|
44
|
+
src_type: string | null;
|
|
45
|
+
src: string | null;
|
|
46
|
+
candidate_school_id: string | null;
|
|
47
|
+
candidate_rung: string | null;
|
|
48
|
+
}
|
|
49
|
+
export declare function registrySchools(rel: Release): Promise<{
|
|
50
|
+
tag: string;
|
|
51
|
+
schools: RegistrySchool[];
|
|
52
|
+
}>;
|
|
53
|
+
export declare function schoolPrints(rel: Release, q: {
|
|
54
|
+
event?: string;
|
|
55
|
+
year?: number;
|
|
56
|
+
}): Promise<{
|
|
57
|
+
tag: string;
|
|
58
|
+
asked: {
|
|
59
|
+
event?: string;
|
|
60
|
+
year?: number;
|
|
61
|
+
};
|
|
62
|
+
prints: SchoolPrint[];
|
|
63
|
+
}>;
|
|
64
|
+
export declare function schoolRedirects(rel: Release): Promise<{
|
|
65
|
+
tag: string;
|
|
66
|
+
redirects: SchoolRedirect[];
|
|
67
|
+
}>;
|
|
68
|
+
export declare function schoolLineage(rel: Release): Promise<{
|
|
69
|
+
tag: string;
|
|
70
|
+
edges: LineageEdge[];
|
|
71
|
+
}>;
|
|
72
|
+
export declare function observedAssociations(rel: Release, q: {
|
|
73
|
+
school_id?: string;
|
|
74
|
+
}): Promise<{
|
|
75
|
+
tag: string;
|
|
76
|
+
asked: {
|
|
77
|
+
school_id?: string;
|
|
78
|
+
};
|
|
79
|
+
associations: ObservedAssociation[];
|
|
80
|
+
}>;
|
package/dist/types/schools.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type SchoolNameParser } from "@finbheara/domain/school";
|
|
2
2
|
import type { IndexBuilder } from "./indexes.js";
|
|
3
3
|
import type { Release } from "./release.js";
|
|
4
|
+
import { type LineageEdge, type ObservedAssociation, type RegistrySchool, type SchoolPrint, type SchoolRedirect } from "./school-bulk.js";
|
|
4
5
|
import { type LinkQuery, type SchoolLineAnswer, type SchoolLinksAnswer } from "./school-links.js";
|
|
5
6
|
export type SchoolRung = "id" | "redirect" | "print" | "sn3" | "realWords";
|
|
6
7
|
export interface SchoolCandidate {
|
|
@@ -57,5 +58,37 @@ export declare class SchoolResolver {
|
|
|
57
58
|
constructor(rel: Release);
|
|
58
59
|
links(a: string, b: string, q?: LinkQuery): Promise<SchoolLinksAnswer>;
|
|
59
60
|
line(a: string, q?: LinkQuery): Promise<SchoolLineAnswer>;
|
|
61
|
+
list(): Promise<{
|
|
62
|
+
tag: string;
|
|
63
|
+
schools: RegistrySchool[];
|
|
64
|
+
}>;
|
|
65
|
+
prints(q?: {
|
|
66
|
+
event?: string;
|
|
67
|
+
year?: number;
|
|
68
|
+
}): Promise<{
|
|
69
|
+
tag: string;
|
|
70
|
+
asked: {
|
|
71
|
+
event?: string;
|
|
72
|
+
year?: number;
|
|
73
|
+
};
|
|
74
|
+
prints: SchoolPrint[];
|
|
75
|
+
}>;
|
|
76
|
+
redirects(): Promise<{
|
|
77
|
+
tag: string;
|
|
78
|
+
redirects: SchoolRedirect[];
|
|
79
|
+
}>;
|
|
80
|
+
lineage(): Promise<{
|
|
81
|
+
tag: string;
|
|
82
|
+
edges: LineageEdge[];
|
|
83
|
+
}>;
|
|
84
|
+
associations(q?: {
|
|
85
|
+
school_id?: string;
|
|
86
|
+
}): Promise<{
|
|
87
|
+
tag: string;
|
|
88
|
+
asked: {
|
|
89
|
+
school_id?: string;
|
|
90
|
+
};
|
|
91
|
+
associations: ObservedAssociation[];
|
|
92
|
+
}>;
|
|
60
93
|
resolve(asked: string, q?: SchoolQuery): Promise<SchoolAnswer>;
|
|
61
94
|
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import type { Release } from "./release.js";
|
|
2
|
+
export interface TabRow {
|
|
3
|
+
address: string;
|
|
4
|
+
competition: string;
|
|
5
|
+
card: string;
|
|
6
|
+
line: number;
|
|
7
|
+
event: string | null;
|
|
8
|
+
year: number | null;
|
|
9
|
+
tier: string | null;
|
|
10
|
+
round: string;
|
|
11
|
+
true_round: number;
|
|
12
|
+
seat_index: number;
|
|
13
|
+
section: string;
|
|
14
|
+
panel_size: number;
|
|
15
|
+
column_order: string;
|
|
16
|
+
drop_rule: string;
|
|
17
|
+
judge_name: string | null;
|
|
18
|
+
judge_name_printed: string | null;
|
|
19
|
+
judge_clrg: number | null;
|
|
20
|
+
judge_id: number | null;
|
|
21
|
+
judge_unmatched: string | null;
|
|
22
|
+
mark: number | null;
|
|
23
|
+
mark_printed: string | null;
|
|
24
|
+
place: number | null;
|
|
25
|
+
place_printed: string | null;
|
|
26
|
+
tie: number;
|
|
27
|
+
points: number | null;
|
|
28
|
+
points_printed: string | null;
|
|
29
|
+
}
|
|
30
|
+
export interface TabQuery {
|
|
31
|
+
competition?: string;
|
|
32
|
+
address?: string;
|
|
33
|
+
round?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface TabStreamQuery {
|
|
36
|
+
event?: string | string[];
|
|
37
|
+
year?: number | [number, number];
|
|
38
|
+
tier?: string[];
|
|
39
|
+
competition?: string[];
|
|
40
|
+
}
|
|
41
|
+
export interface TabAnswer {
|
|
42
|
+
tag: string;
|
|
43
|
+
asked: TabQuery;
|
|
44
|
+
rows: TabRow[];
|
|
45
|
+
}
|
|
46
|
+
export interface PanelSeat {
|
|
47
|
+
competition: string;
|
|
48
|
+
panel: string;
|
|
49
|
+
round: string;
|
|
50
|
+
seat_index: number;
|
|
51
|
+
address: string | null;
|
|
52
|
+
judge_name_printed: string | null;
|
|
53
|
+
judge_clrg: number | null;
|
|
54
|
+
judge_id: number | null;
|
|
55
|
+
judge_unmatched: string | null;
|
|
56
|
+
}
|
|
57
|
+
export interface FeisPanelSeat {
|
|
58
|
+
address: string;
|
|
59
|
+
platform: string;
|
|
60
|
+
round: string;
|
|
61
|
+
seat_index: number;
|
|
62
|
+
panel_size: number;
|
|
63
|
+
panel_kind: string;
|
|
64
|
+
judge_name_printed: string;
|
|
65
|
+
judge_state_printed: string | null;
|
|
66
|
+
judge_clrg: number | null;
|
|
67
|
+
judge_id: number | null;
|
|
68
|
+
judge_unmatched: string | null;
|
|
69
|
+
judge_basis: string | null;
|
|
70
|
+
}
|
|
71
|
+
export interface RegisterRow {
|
|
72
|
+
judge_clrg: number;
|
|
73
|
+
year: number;
|
|
74
|
+
cat: string;
|
|
75
|
+
name_printed: string;
|
|
76
|
+
country: string;
|
|
77
|
+
country_printed: string;
|
|
78
|
+
country_code: string | null;
|
|
79
|
+
region: string;
|
|
80
|
+
region_printed: string;
|
|
81
|
+
region_code: string | null;
|
|
82
|
+
geohash: string | null;
|
|
83
|
+
src: string;
|
|
84
|
+
}
|
|
85
|
+
export declare const TAB_NEEDS: readonly string[];
|
|
86
|
+
export declare class TabFinder {
|
|
87
|
+
private readonly rel;
|
|
88
|
+
constructor(rel: Release);
|
|
89
|
+
private db;
|
|
90
|
+
private sheets;
|
|
91
|
+
query(q: TabQuery): Promise<TabAnswer>;
|
|
92
|
+
stream(q?: TabStreamQuery): AsyncGenerator<TabRow>;
|
|
93
|
+
}
|
|
94
|
+
export declare class PanelFinder {
|
|
95
|
+
private readonly rel;
|
|
96
|
+
constructor(rel: Release);
|
|
97
|
+
query(q?: {
|
|
98
|
+
competition?: string;
|
|
99
|
+
}): Promise<{
|
|
100
|
+
tag: string;
|
|
101
|
+
asked: {
|
|
102
|
+
competition?: string;
|
|
103
|
+
};
|
|
104
|
+
seats: PanelSeat[];
|
|
105
|
+
}>;
|
|
106
|
+
}
|
|
107
|
+
export declare class FeisPanelFinder {
|
|
108
|
+
private readonly rel;
|
|
109
|
+
constructor(rel: Release);
|
|
110
|
+
query(q?: {
|
|
111
|
+
address?: string;
|
|
112
|
+
platform?: string;
|
|
113
|
+
}): Promise<{
|
|
114
|
+
tag: string;
|
|
115
|
+
asked: {
|
|
116
|
+
address?: string;
|
|
117
|
+
platform?: string;
|
|
118
|
+
};
|
|
119
|
+
seats: FeisPanelSeat[];
|
|
120
|
+
}>;
|
|
121
|
+
}
|
|
122
|
+
export declare function registerRows(rel: Release, q: {
|
|
123
|
+
year?: number;
|
|
124
|
+
judge_clrg?: number;
|
|
125
|
+
}): Promise<{
|
|
126
|
+
tag: string;
|
|
127
|
+
asked: {
|
|
128
|
+
year?: number;
|
|
129
|
+
judge_clrg?: number;
|
|
130
|
+
};
|
|
131
|
+
rows: RegisterRow[];
|
|
132
|
+
}>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@finbheara/archive-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.25.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",
|