linked-rolls 0.71.0 → 0.72.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 +86 -0
- package/lib/filiation/adoption.d.ts +47 -0
- package/lib/filiation/adoption.js +190 -0
- package/lib/filiation/changes.d.ts +33 -0
- package/lib/filiation/changes.js +38 -0
- package/lib/filiation/index.d.ts +12 -0
- package/lib/filiation/index.js +12 -0
- package/lib/filiation/presence.d.ts +50 -0
- package/lib/filiation/presence.js +122 -0
- package/lib/filiation/proposal.d.ts +132 -0
- package/lib/filiation/proposal.js +376 -0
- package/lib/filiation/readings.d.ts +108 -0
- package/lib/filiation/readings.js +281 -0
- package/lib/filiation/search.d.ts +113 -0
- package/lib/filiation/search.js +268 -0
- package/lib/filiation/systems.d.ts +21 -0
- package/lib/filiation/systems.js +39 -0
- package/lib/filiation/trees.d.ts +20 -0
- package/lib/filiation/trees.js +69 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** Which reproducing system a version of the stemma is coded for, and which systems a roll was re-cut into. */
|
|
2
|
+
import { procedures } from "../model/procedures.js";
|
|
3
|
+
import { trackerBars } from "../systems/index.js";
|
|
4
|
+
const TRANSFER = /\/umstanzung\/(.+)-to-(.+)$/;
|
|
5
|
+
/**
|
|
6
|
+
* By system, the systems a roll of it was re-cut for, as the procedures
|
|
7
|
+
* of the vocabulary name them: a red roll was re-punched for the
|
|
8
|
+
* Licensee system and for the green one, and never the other way round.
|
|
9
|
+
* @category Filiation
|
|
10
|
+
*/
|
|
11
|
+
export const transfersOf = () => {
|
|
12
|
+
const transfers = new Map();
|
|
13
|
+
for (const procedure of procedures) {
|
|
14
|
+
const match = TRANSFER.exec(procedure.id ?? "");
|
|
15
|
+
if (!match)
|
|
16
|
+
continue;
|
|
17
|
+
const [from, to] = [match[1], match[2]];
|
|
18
|
+
transfers.set(from, new Set([...(transfers.get(from) ?? []), to]));
|
|
19
|
+
}
|
|
20
|
+
return transfers;
|
|
21
|
+
};
|
|
22
|
+
/** Whether a version of the one system can stand above a version of the other: the same system, or one re-cut from it. */
|
|
23
|
+
export const leadsTo = (transfers, from, to) => from === to || (transfers.get(from)?.has(to) ?? false);
|
|
24
|
+
/**
|
|
25
|
+
* The system of a lost version above versions of the given systems: the
|
|
26
|
+
* one they share, or else the one they were all re-cut from. A lost
|
|
27
|
+
* state above a red and a Licensee version is red, since a Licensee
|
|
28
|
+
* version is never re-cut into red. Where no system leads to all of
|
|
29
|
+
* them, nothing.
|
|
30
|
+
* @category Filiation
|
|
31
|
+
*/
|
|
32
|
+
export const systemAbove = (transfers, systems) => {
|
|
33
|
+
if (systems.size === 1)
|
|
34
|
+
return [...systems][0];
|
|
35
|
+
const candidates = new Set([...systems, ...transfers.keys()]);
|
|
36
|
+
return [...candidates].sort().find(candidate => [...systems].every(system => leadsTo(transfers, candidate, system)));
|
|
37
|
+
};
|
|
38
|
+
/** The bar of a system the library knows, by its identifier. */
|
|
39
|
+
export const barNamed = (id) => trackerBars.find(bar => bar.id === id);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every stemma a handful of copies can stand in: rooted trees whose
|
|
3
|
+
* nodes are versions, a copy carrying any of them, a lost one above
|
|
4
|
+
* any two or more.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* A node of a stemma: the copy carrying it at first hand, by its number,
|
|
8
|
+
* or none for a lost state, and the nodes derived from it.
|
|
9
|
+
*/
|
|
10
|
+
export interface StemmaNode {
|
|
11
|
+
readonly copy?: number;
|
|
12
|
+
readonly children: readonly StemmaNode[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Every stemma of n copies: 3 for two copies, 91,984 for six. They are
|
|
16
|
+
* produced one by one, so that only the leaf trees, far fewer, are held.
|
|
17
|
+
*/
|
|
18
|
+
export declare function stemmataOf(n: number): Generator<StemmaNode>;
|
|
19
|
+
/** How many stemmata the exhaustive search scores, at most. */
|
|
20
|
+
export declare const MAX_COPIES = 7;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every stemma a handful of copies can stand in: rooted trees whose
|
|
3
|
+
* nodes are versions, a copy carrying any of them, a lost one above
|
|
4
|
+
* any two or more.
|
|
5
|
+
*/
|
|
6
|
+
const leaf = (copy) => ({ copy, children: [] });
|
|
7
|
+
/** Every way to add the copy to the tree: as a further child of a lost node, or on an edge, above any subtree. */
|
|
8
|
+
function* insertions(tree, copy) {
|
|
9
|
+
yield { children: [tree, leaf(copy)] };
|
|
10
|
+
if (tree.children.length === 0)
|
|
11
|
+
return;
|
|
12
|
+
yield { ...tree, children: [...tree.children, leaf(copy)] };
|
|
13
|
+
for (let i = 0; i < tree.children.length; i++) {
|
|
14
|
+
for (const child of insertions(tree.children[i], copy)) {
|
|
15
|
+
yield { ...tree, children: [...tree.children.slice(0, i), child, ...tree.children.slice(i + 1)] };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** The trees whose leaves are the copies 0 to n − 1 and whose inner nodes are all lost, each once. */
|
|
20
|
+
const leafTrees = (n) => {
|
|
21
|
+
if (n === 1)
|
|
22
|
+
return [leaf(0)];
|
|
23
|
+
let trees = [{ children: [leaf(0), leaf(1)] }];
|
|
24
|
+
for (let copy = 2; copy < n; copy++) {
|
|
25
|
+
trees = trees.flatMap(tree => [...insertions(tree, copy)]);
|
|
26
|
+
}
|
|
27
|
+
return trees;
|
|
28
|
+
};
|
|
29
|
+
const product = (lists) => lists.reduce((combos, list) => combos.flatMap(combo => list.map(item => [...combo, item])), [[]]);
|
|
30
|
+
/**
|
|
31
|
+
* The tree with as many of its copies moved up as it allows: at each
|
|
32
|
+
* lost node, at most one copy among its leaf children may come to carry
|
|
33
|
+
* it instead, making that copy's text the ancestor of the others'.
|
|
34
|
+
* Every stemma arises from exactly one leaf tree in exactly one way.
|
|
35
|
+
*/
|
|
36
|
+
function* promotions(tree) {
|
|
37
|
+
if (tree.children.length === 0) {
|
|
38
|
+
yield tree;
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const options = tree.children.map(child => [...promotions(child)]);
|
|
42
|
+
const leaves = tree.children.flatMap((child, index) => child.children.length === 0 ? [index] : []);
|
|
43
|
+
for (const combo of product(options)) {
|
|
44
|
+
yield { children: combo };
|
|
45
|
+
for (const index of leaves) {
|
|
46
|
+
yield { copy: tree.children[index].copy, children: combo.filter((_, i) => i !== index) };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const cache = new Map();
|
|
51
|
+
/**
|
|
52
|
+
* Every stemma of n copies: 3 for two copies, 91,984 for six. They are
|
|
53
|
+
* produced one by one, so that only the leaf trees, far fewer, are held.
|
|
54
|
+
*/
|
|
55
|
+
export function* stemmataOf(n) {
|
|
56
|
+
let trees = cache.get(n);
|
|
57
|
+
if (!trees) {
|
|
58
|
+
trees = leafTrees(n);
|
|
59
|
+
cache.set(n, trees);
|
|
60
|
+
}
|
|
61
|
+
if (n === 1) {
|
|
62
|
+
yield trees[0];
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
for (const tree of trees)
|
|
66
|
+
yield* promotions(tree);
|
|
67
|
+
}
|
|
68
|
+
/** How many stemmata the exhaustive search scores, at most. */
|
|
69
|
+
export const MAX_COPIES = 7;
|
package/lib/index.d.ts
CHANGED
|
@@ -76,6 +76,7 @@ export { validate, type ValidateEdition } from './validate.js';
|
|
|
76
76
|
export * from './analysis/constraints.js';
|
|
77
77
|
export * from './collation/substitution.js';
|
|
78
78
|
export * from './io/context.js';
|
|
79
|
+
export * from './filiation/index.js';
|
|
79
80
|
export * from './analysis/sigla.js';
|
|
80
81
|
export * from './model/notes.js';
|
|
81
82
|
export { asJsonLd } from './io/asJsonLd.js';
|
package/lib/index.js
CHANGED
|
@@ -39,6 +39,7 @@ export { validate } from './validate.js';
|
|
|
39
39
|
export * from './analysis/constraints.js';
|
|
40
40
|
export * from './collation/substitution.js';
|
|
41
41
|
export * from './io/context.js';
|
|
42
|
+
export * from './filiation/index.js';
|
|
42
43
|
export * from './analysis/sigla.js';
|
|
43
44
|
export * from './model/notes.js';
|
|
44
45
|
export { asJsonLd } from './io/asJsonLd.js';
|
package/package.json
CHANGED