linked-rolls 0.1.0 → 0.2.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/LICENSE +26 -0
- package/README.md +35 -0
- package/lib/Assumption.d.ts +7 -2
- package/lib/ConditionState.d.ts +8 -1
- package/lib/Edit.d.ts +4 -3
- package/lib/Edition.d.ts +65 -35
- package/lib/Edition.js +1 -1
- package/lib/Emulation.js +32 -10
- package/lib/Feature.d.ts +19 -4
- package/lib/Plan.js +2 -1
- package/lib/RollCopy.d.ts +65 -27
- package/lib/RollCopy.js +51 -7
- package/lib/Symbol.d.ts +37 -20
- package/lib/Symbol.js +12 -0
- package/lib/TrackerBar.d.ts +18 -0
- package/lib/TrackerBar.js +27 -0
- package/lib/Version.d.ts +12 -4
- package/lib/asJsonLd.js +16 -2
- package/lib/context.d.ts +2 -0
- package/lib/context.js +2 -0
- package/lib/importJsonLd.js +19 -5
- package/lib/migrate.d.ts +15 -0
- package/lib/migrate.js +77 -0
- package/lib/schema.json +322 -276
- package/lib/spec/context.json +201 -131
- package/lib/spec/welte-t100.context.json +10 -0
- package/lib/systems/welteT100.js +19 -17
- package/lib/validate.d.ts +26 -0
- package/lib/validate.js +46 -0
- package/package.json +2 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-2026 Niels Pfeffer
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
The ontology and type vocabulary in the ontology directory and the
|
|
24
|
+
documentation generated from them are licensed separately under
|
|
25
|
+
Creative Commons Attribution 4.0 International,
|
|
26
|
+
https://creativecommons.org/licenses/by/4.0/.
|
package/README.md
CHANGED
|
@@ -13,6 +13,26 @@ and exporting digital editions of piano roll. In particular it allows to:
|
|
|
13
13
|
This library is the foundation of the
|
|
14
14
|
[Roll Desk](https://github.com/pfefferniels/roll-desk).
|
|
15
15
|
|
|
16
|
+
## Vocabulary
|
|
17
|
+
|
|
18
|
+
The JSON-LD export uses the Roll Edition Ontology (REO), namespace
|
|
19
|
+
`https://w3id.org/reo/`, prefix `reo`, alongside CIDOC CRM, LRMoo and
|
|
20
|
+
CRMinf. The ontology lives in `ontology/`, and the context every
|
|
21
|
+
export references is `https://w3id.org/reo/context.jsonld`. The
|
|
22
|
+
ontology, its type vocabulary and the context are published at
|
|
23
|
+
https://pfefferniels.github.io/linked-rolls/reo/; the w3id.org
|
|
24
|
+
identifiers are not registered yet. `ontology/README.md` records the
|
|
25
|
+
naming decisions.
|
|
26
|
+
|
|
27
|
+
## Format revisions
|
|
28
|
+
|
|
29
|
+
Files written by linked-rolls 0.1 load unchanged: `importJsonLd`
|
|
30
|
+
recognises their shapes and brings them to the current format, in
|
|
31
|
+
which versions and conditions carry a typology key beside their type,
|
|
32
|
+
the keeper and the production metadata are nodes with a name and
|
|
33
|
+
authority links, and the roll names its reproducing system. Exports
|
|
34
|
+
are always in the current format.
|
|
35
|
+
|
|
16
36
|
## Emulation
|
|
17
37
|
|
|
18
38
|
`Emulation` turns a version of the edition into MIDI. The core of the
|
|
@@ -49,6 +69,21 @@ reads editions does not need it. For development on both at once, a
|
|
|
49
69
|
checkout of [welte-t100](https://github.com/pfefferniels/welte-t100)
|
|
50
70
|
beside this repository, declared as `file:../welte-t100`, works too.
|
|
51
71
|
|
|
72
|
+
### Alignment and pairing
|
|
73
|
+
|
|
74
|
+
A perforation takes its place from the holes that carry it. Two fields
|
|
75
|
+
on a perforation let an editor state where the measurement should give
|
|
76
|
+
way. `alignedWith` names another perforation whose onset this one takes
|
|
77
|
+
in the performance, as a "crescendo off" is meant to fall on the note
|
|
78
|
+
it belongs to. `pairedWith` names a partner whose distance to this one
|
|
79
|
+
is fixed, as a "forzando on" belongs with its "forzando off": whatever
|
|
80
|
+
displaces the one displaces the other. Any two perforations may be
|
|
81
|
+
paired, the relation is symmetric, and it is stated on one side only.
|
|
82
|
+
Both are applied when a version is emulated. `constraintProblems` lists,
|
|
83
|
+
version by version, the cases in which the statements cannot hold: a
|
|
84
|
+
reference or partner that is absent, a perforation claimed by several
|
|
85
|
+
pairs, or a pair whose members are both aligned.
|
|
86
|
+
|
|
52
87
|
## Building
|
|
53
88
|
```
|
|
54
89
|
npm i
|
package/lib/Assumption.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export interface Argumentation<T extends string = 'simpleArgumentation'> extends
|
|
|
18
18
|
* symbols or features. For example, interpreting a pencil mark
|
|
19
19
|
* as an instruction to add or remove a perforation or as the dating
|
|
20
20
|
* of the roll.
|
|
21
|
+
* @see crminf:I16 Meaning Comprehension
|
|
21
22
|
*/
|
|
22
23
|
export interface MeaningComprehension extends Argumentation<'meaningComprehension'> {
|
|
23
24
|
/**
|
|
@@ -73,7 +74,7 @@ export interface Belief extends WithId {
|
|
|
73
74
|
certainty: Certainty;
|
|
74
75
|
/**
|
|
75
76
|
* The argumentations providing reasons for this belief.
|
|
76
|
-
* @see crminf:
|
|
77
|
+
* @see crminf:J2i was concluded by
|
|
77
78
|
*/
|
|
78
79
|
reasons: AnyArgumentation[];
|
|
79
80
|
}
|
|
@@ -90,13 +91,17 @@ export interface Assumption {
|
|
|
90
91
|
* epistemic metadata (certainty and reasons) to any triple.
|
|
91
92
|
*/
|
|
92
93
|
'@annotation'?: WithId & {
|
|
94
|
+
/**
|
|
95
|
+
* The belief held about the annotated statement.
|
|
96
|
+
* @see crminf:J4i is subject of
|
|
97
|
+
*/
|
|
93
98
|
belief: Belief;
|
|
94
99
|
};
|
|
95
100
|
}
|
|
96
101
|
/**
|
|
97
102
|
* A value assumption wraps a literal value, e.g. a string, a number, a date, with an optional annotation.
|
|
98
103
|
* Used for properties where the value itself may be uncertain,
|
|
99
|
-
* e.g. dates
|
|
104
|
+
* e.g. dates.
|
|
100
105
|
*/
|
|
101
106
|
export interface ValueAssumption<ValueT> extends Assumption {
|
|
102
107
|
/**
|
package/lib/ConditionState.d.ts
CHANGED
|
@@ -3,8 +3,15 @@ import { WithType } from "./utils";
|
|
|
3
3
|
* Physical condition of a roll or
|
|
4
4
|
* of a feature on the roll (e.g. a damaged
|
|
5
5
|
* or unsuccessful perforation).
|
|
6
|
+
* @see crm:E3 Condition State
|
|
6
7
|
*/
|
|
7
|
-
export interface ConditionState<T extends string> extends WithType<
|
|
8
|
+
export interface ConditionState<T extends string> extends WithType<'ConditionState'> {
|
|
9
|
+
/**
|
|
10
|
+
* The kind of condition, from the list the roll or
|
|
11
|
+
* the kind of feature allows.
|
|
12
|
+
* @see crm:P2 has type
|
|
13
|
+
*/
|
|
14
|
+
conditionType: T;
|
|
8
15
|
/**
|
|
9
16
|
* A free-text description of the condition, providing
|
|
10
17
|
* details beyond the type classification.
|
package/lib/Edit.d.ts
CHANGED
|
@@ -23,12 +23,13 @@ export type ActorAssignment = ObjectAssumption<Person>;
|
|
|
23
23
|
* If an edit is the interpretation of a metamark,
|
|
24
24
|
* such as a pencil mark, this should be made explicit
|
|
25
25
|
* using a meaning comprehension on the `@annotation` field.
|
|
26
|
-
* @see reo:
|
|
26
|
+
* @see reo:Edit
|
|
27
27
|
*/
|
|
28
28
|
export interface Edit extends WithId, Assumption {
|
|
29
29
|
type: 'edit';
|
|
30
30
|
/**
|
|
31
31
|
* The type of editorial change (e.g. 'correct-error', 'additional-accent').
|
|
32
|
+
* @see crm:P2 has type
|
|
32
33
|
*/
|
|
33
34
|
editType?: EditType;
|
|
34
35
|
/**
|
|
@@ -39,12 +40,12 @@ export interface Edit extends WithId, Assumption {
|
|
|
39
40
|
motivation?: string;
|
|
40
41
|
/**
|
|
41
42
|
* The symbols to be inserted by this edit.
|
|
42
|
-
* @see reo:
|
|
43
|
+
* @see reo:added
|
|
43
44
|
*/
|
|
44
45
|
insert?: AnySymbol[];
|
|
45
46
|
/**
|
|
46
47
|
* References (by `@id`) to the symbols to be deleted by this edit.
|
|
47
|
-
* @see reo:
|
|
48
|
+
* @see reo:removed
|
|
48
49
|
*/
|
|
49
50
|
delete?: string[];
|
|
50
51
|
}
|
package/lib/Edition.d.ts
CHANGED
|
@@ -4,50 +4,60 @@ import { Version } from "./Version";
|
|
|
4
4
|
import { CollationTolerance } from "./Collation";
|
|
5
5
|
import { ObjectAssumption } from "./Assumption";
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
* @see crm:E21 Person
|
|
7
|
+
* Something with a name and, where one exists, an authority record.
|
|
9
8
|
*/
|
|
10
|
-
export interface
|
|
9
|
+
export interface Named {
|
|
11
10
|
/**
|
|
12
|
-
* The
|
|
11
|
+
* The name, e.g. "Grünfeld, Alfred", "Wien", "M. Welte & Söhne".
|
|
13
12
|
* @see rdfs:label
|
|
14
|
-
* @example "Grünfeld, Alfred"
|
|
15
13
|
*/
|
|
16
14
|
name: string;
|
|
17
15
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* Authority records for the same thing: GND, Wikidata,
|
|
17
|
+
* geonames or similar.
|
|
20
18
|
* @see owl:sameAs
|
|
21
19
|
* @example "https://d-nb.info/gnd/116888652"
|
|
22
20
|
*/
|
|
23
21
|
sameAs: string[];
|
|
22
|
+
}
|
|
23
|
+
export declare const agentRoles: readonly ["pianist", "editor", "publisher"];
|
|
24
|
+
/**
|
|
25
|
+
* The role an agent plays in the context of the edition.
|
|
26
|
+
*/
|
|
27
|
+
export type AgentRole = typeof agentRoles[number];
|
|
28
|
+
/**
|
|
29
|
+
* A person or a group: a pianist, an editor, a publisher,
|
|
30
|
+
* a manufacturer, a library.
|
|
31
|
+
* @see crm:E39 Actor
|
|
32
|
+
*/
|
|
33
|
+
export interface Agent extends Named, Partial<WithId> {
|
|
24
34
|
/**
|
|
25
|
-
* The role of the
|
|
26
|
-
* e.g. 'pianist', 'editor', 'publisher', etc.
|
|
35
|
+
* The role of the agent in the context of the edition.
|
|
27
36
|
* @see crm:P2 has type
|
|
28
37
|
*/
|
|
29
|
-
role?:
|
|
38
|
+
role?: AgentRole;
|
|
30
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* An agent that is a person.
|
|
42
|
+
*/
|
|
43
|
+
export type Person = Agent;
|
|
31
44
|
/**
|
|
32
45
|
* A place, e.g. a recording location, publishing location, etc.
|
|
33
46
|
* @see crm:E53 Place
|
|
34
47
|
*/
|
|
35
|
-
export interface Place {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
* geonames or wikidata entry.
|
|
44
|
-
*/
|
|
45
|
-
sameAs: string[];
|
|
48
|
+
export interface Place extends Named {
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A term from a vocabulary, such as a roll system or a kind of
|
|
52
|
+
* paper. A term the type vocabulary knows carries its IRI as `id`.
|
|
53
|
+
* @see crm:E55 Type
|
|
54
|
+
*/
|
|
55
|
+
export interface Concept extends Named, Partial<WithId> {
|
|
46
56
|
}
|
|
47
57
|
/**
|
|
48
58
|
* This type describes the creation of an edition,
|
|
49
59
|
* i.e. the editor, publisher, and publication date.
|
|
50
|
-
* @see
|
|
60
|
+
* @see lrmoo:F28 Expression Creation
|
|
51
61
|
*/
|
|
52
62
|
export interface EditionCreation {
|
|
53
63
|
/**
|
|
@@ -58,13 +68,13 @@ export interface EditionCreation {
|
|
|
58
68
|
/**
|
|
59
69
|
* The date on which the edition was published.
|
|
60
70
|
* @format date
|
|
61
|
-
* @see
|
|
71
|
+
* @see dcterms:date
|
|
62
72
|
*/
|
|
63
73
|
publicationDate: Date;
|
|
64
74
|
/**
|
|
65
75
|
* The tolerance parameters used when collating (aligning)
|
|
66
76
|
* the different roll copies for this edition.
|
|
67
|
-
*
|
|
77
|
+
* Not exported to RDF.
|
|
68
78
|
*/
|
|
69
79
|
collationTolerance?: CollationTolerance;
|
|
70
80
|
}
|
|
@@ -72,18 +82,23 @@ export interface EditionCreation {
|
|
|
72
82
|
* Describes the event of recording and documents
|
|
73
83
|
* the persons involved in the process (e.g. pianist),
|
|
74
84
|
* the place, and the date of the recording.
|
|
75
|
-
* @see
|
|
85
|
+
* @see lrmoo:F28 Expression Creation
|
|
76
86
|
*/
|
|
77
87
|
export interface RecordingEvent {
|
|
78
88
|
/**
|
|
79
89
|
* Documents the performance which was recorded.
|
|
80
|
-
* @see
|
|
90
|
+
* @see lrmoo:R81 recorded
|
|
81
91
|
*/
|
|
82
92
|
recorded: {
|
|
93
|
+
/**
|
|
94
|
+
* The pianist who gave the recorded performance.
|
|
95
|
+
* @see crm:P14 carried out by
|
|
96
|
+
*/
|
|
83
97
|
pianist: Person;
|
|
84
98
|
/**
|
|
85
99
|
* This property should point to a standard
|
|
86
100
|
* URI, e.g. the GND.
|
|
101
|
+
* @see lrmoo:R80 performed
|
|
87
102
|
*/
|
|
88
103
|
playing: string;
|
|
89
104
|
};
|
|
@@ -96,30 +111,39 @@ export interface RecordingEvent {
|
|
|
96
111
|
* The recording date of the roll. This is a date
|
|
97
112
|
* assignment so that we can state e.g. the catalogue
|
|
98
113
|
* or the roll label which indicates the date of the recording.
|
|
99
|
-
* @see
|
|
114
|
+
* @see dcterms:date
|
|
100
115
|
*/
|
|
101
116
|
date: DateAssignment;
|
|
102
117
|
/**
|
|
103
118
|
* The version of the roll which was created in
|
|
104
119
|
* the recording. Since it is usually not handed
|
|
105
120
|
* down, this is an optional property.
|
|
106
|
-
* @see
|
|
121
|
+
* @see lrmoo:R17 created
|
|
107
122
|
*/
|
|
108
123
|
created?: Version;
|
|
109
124
|
}
|
|
110
125
|
/**
|
|
111
126
|
* The abstract concept of a roll, identified
|
|
112
127
|
* by its catalogue number.
|
|
113
|
-
* @see
|
|
128
|
+
* @see lrmoo:F1 Work
|
|
114
129
|
*/
|
|
115
130
|
export interface Roll {
|
|
116
131
|
/**
|
|
117
132
|
* The catalogue number of the roll.
|
|
118
133
|
* @example "WM 225"
|
|
134
|
+
* @see dcterms:identifier
|
|
119
135
|
*/
|
|
120
136
|
catalogueNumber: string;
|
|
121
137
|
/**
|
|
122
|
-
*
|
|
138
|
+
* The reproducing system the roll was cut for. A system the
|
|
139
|
+
* type vocabulary knows carries the IRI of its concept as `id`,
|
|
140
|
+
* from which the export takes the system's own context, so that
|
|
141
|
+
* the expression types are read as that system's.
|
|
142
|
+
* @see crm:P2 has type
|
|
143
|
+
*/
|
|
144
|
+
system: Concept;
|
|
145
|
+
/**
|
|
146
|
+
* @see lrmoo:R19i was realised through
|
|
123
147
|
*/
|
|
124
148
|
recordingEvent: RecordingEvent;
|
|
125
149
|
}
|
|
@@ -127,24 +151,28 @@ export interface Roll {
|
|
|
127
151
|
* The playback tempo of the roll, specified as a starting
|
|
128
152
|
* and ending speed. The tempo may change over the course
|
|
129
153
|
* of the roll due to acceleration effects.
|
|
154
|
+
* @see crm:E54 Dimension
|
|
130
155
|
*/
|
|
131
156
|
export interface RollTempo {
|
|
132
157
|
/**
|
|
133
158
|
* The tempo at the beginning of the roll.
|
|
159
|
+
* @see reo:from
|
|
134
160
|
*/
|
|
135
161
|
startsWith: number;
|
|
136
162
|
/**
|
|
137
163
|
* The tempo at the end of the roll.
|
|
164
|
+
* @see reo:to
|
|
138
165
|
*/
|
|
139
166
|
endsWith: number;
|
|
140
167
|
/**
|
|
141
168
|
* The unit of the tempo measurement (e.g. 'ft/min', 'm/min').
|
|
169
|
+
* @see crm:P91 has unit
|
|
142
170
|
*/
|
|
143
171
|
unit: string;
|
|
144
172
|
}
|
|
145
173
|
/**
|
|
146
174
|
* Describes the specific digital edition of a piano roll.
|
|
147
|
-
* @see
|
|
175
|
+
* @see lrmoo:F2 Expression
|
|
148
176
|
*/
|
|
149
177
|
export interface Edition {
|
|
150
178
|
/**
|
|
@@ -155,12 +183,12 @@ export interface Edition {
|
|
|
155
183
|
/**
|
|
156
184
|
* Information about the creation of this edition,
|
|
157
185
|
* including publisher and publication date.
|
|
158
|
-
* @see
|
|
186
|
+
* @see lrmoo:R17i was created by
|
|
159
187
|
*/
|
|
160
188
|
creation: EditionCreation;
|
|
161
189
|
/**
|
|
162
190
|
* The title of the edition.
|
|
163
|
-
* @see
|
|
191
|
+
* @see dcterms:title
|
|
164
192
|
* @example "Alfred Grünfeld spielt Robert Schumann, Träumerei"
|
|
165
193
|
*/
|
|
166
194
|
title: string;
|
|
@@ -172,22 +200,24 @@ export interface Edition {
|
|
|
172
200
|
license: string;
|
|
173
201
|
/**
|
|
174
202
|
* The roll which is edited in this edition.
|
|
175
|
-
* @see
|
|
203
|
+
* @see lrmoo:R3i realises
|
|
176
204
|
*/
|
|
177
205
|
roll: Roll;
|
|
178
206
|
/**
|
|
179
207
|
* The physical roll copies on which this edition is based.
|
|
208
|
+
* @see reo:witness
|
|
180
209
|
*/
|
|
181
210
|
copies: RollCopy[];
|
|
182
211
|
/**
|
|
183
212
|
* The different versions of the roll on which
|
|
184
213
|
* this edition is based.
|
|
185
|
-
* @see
|
|
214
|
+
* @see lrmoo:R75 incorporates
|
|
186
215
|
*/
|
|
187
216
|
versions: Version[];
|
|
188
217
|
/**
|
|
189
218
|
* An optional tempo adjustment for playback of the roll,
|
|
190
219
|
* annotatable with a belief about its correctness.
|
|
220
|
+
* @see reo:tempo
|
|
191
221
|
*/
|
|
192
222
|
tempoAdjustment?: ObjectAssumption<RollTempo>;
|
|
193
223
|
}
|
package/lib/Edition.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export const agentRoles = ['pianist', 'editor', 'publisher'];
|
package/lib/Emulation.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MIDIControlEvents } from "midifile-ts";
|
|
2
|
-
import {
|
|
2
|
+
import { idOf } from "./Assumption";
|
|
3
|
+
import { pairsAmong } from "./Symbol";
|
|
3
4
|
/** The punch diameter the edition's copies report, where any of them does. */
|
|
4
5
|
const punchDiameterOf = (view) => {
|
|
5
6
|
const measured = view.edition.copies
|
|
@@ -13,6 +14,33 @@ const propertiesOf = (view) => ({
|
|
|
13
14
|
punchDiameter: punchDiameterOf(view),
|
|
14
15
|
tempo: view.edition.tempoAdjustment
|
|
15
16
|
});
|
|
17
|
+
/**
|
|
18
|
+
* How far each event has to move, in mm, for the alignments to hold:
|
|
19
|
+
* an aligned event takes the onset of its reference, and a paired
|
|
20
|
+
* event follows its partner so that the distance between the two
|
|
21
|
+
* is kept. Events that stay where they are do not appear.
|
|
22
|
+
*/
|
|
23
|
+
const displacementsOf = (events) => {
|
|
24
|
+
const byId = new Map(events.map(event => [event.id, event]));
|
|
25
|
+
const referenceOf = (event) => event.alignedWith && byId.get(idOf(event.alignedWith));
|
|
26
|
+
const alignedOnsetOf = (event, visited = new Set()) => {
|
|
27
|
+
const reference = referenceOf(event);
|
|
28
|
+
if (!reference || visited.has(event.id))
|
|
29
|
+
return event.horizontal.from;
|
|
30
|
+
return alignedOnsetOf(reference, visited.add(event.id));
|
|
31
|
+
};
|
|
32
|
+
const displacements = new Map(events
|
|
33
|
+
.filter(event => referenceOf(event) !== undefined)
|
|
34
|
+
.map((event) => [event, alignedOnsetOf(event) - event.horizontal.from]));
|
|
35
|
+
pairsAmong(events).forEach(([one, other]) => {
|
|
36
|
+
const shared = displacements.get(one) ?? displacements.get(other);
|
|
37
|
+
if (shared === undefined)
|
|
38
|
+
return;
|
|
39
|
+
displacements.set(one, shared);
|
|
40
|
+
displacements.set(other, shared);
|
|
41
|
+
});
|
|
42
|
+
return displacements;
|
|
43
|
+
};
|
|
16
44
|
/**
|
|
17
45
|
* A version of the edition, performed: the symbols are negotiated into
|
|
18
46
|
* placed events, the reproducing system plays them, and the result goes
|
|
@@ -62,15 +90,9 @@ export class Emulation {
|
|
|
62
90
|
this.options = options;
|
|
63
91
|
}
|
|
64
92
|
applyConstraints() {
|
|
65
|
-
this.negotiatedEvents
|
|
66
|
-
.
|
|
67
|
-
.
|
|
68
|
-
const ref = this.negotiatedEvents.find(ev => ev.id === valueOf(e.alignedWith));
|
|
69
|
-
if (!ref)
|
|
70
|
-
return;
|
|
71
|
-
const distance = ref.horizontal.from - e.horizontal.from;
|
|
72
|
-
e.horizontal.from += distance;
|
|
73
|
-
e.horizontal.to += distance;
|
|
93
|
+
displacementsOf(this.negotiatedEvents).forEach((distance, event) => {
|
|
94
|
+
event.horizontal.from += distance;
|
|
95
|
+
event.horizontal.to += distance;
|
|
74
96
|
});
|
|
75
97
|
}
|
|
76
98
|
emulateVersion(version, view, { range, skipToFirstNote = false } = {}) {
|
package/lib/Feature.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import { PartialBy, WithId, WithType } from "./utils";
|
|
|
6
6
|
* Describes the horizontal extent of a feature on the roll,
|
|
7
7
|
* measured in millimeters from the beginning of the roll.
|
|
8
8
|
* The `from` value is the start position and `to` is the end position.
|
|
9
|
+
* @see crm:E54 Dimension
|
|
9
10
|
*/
|
|
10
11
|
export interface HorizontalSpan {
|
|
11
12
|
/**
|
|
@@ -17,11 +18,13 @@ export interface HorizontalSpan {
|
|
|
17
18
|
/**
|
|
18
19
|
* The start position of the feature in millimeters
|
|
19
20
|
* from the beginning of the roll.
|
|
21
|
+
* @see reo:from
|
|
20
22
|
*/
|
|
21
23
|
from: number;
|
|
22
24
|
/**
|
|
23
25
|
* The end position of the feature in millimeters
|
|
24
26
|
* from the beginning of the roll.
|
|
27
|
+
* @see reo:to
|
|
25
28
|
*/
|
|
26
29
|
to: number;
|
|
27
30
|
}
|
|
@@ -29,20 +32,23 @@ export interface HorizontalSpan {
|
|
|
29
32
|
* Describes the vertical extent of a feature on the roll,
|
|
30
33
|
* measured in track numbers. Track numbers correspond to
|
|
31
34
|
* positions on the tracker bar.
|
|
35
|
+
* @see crm:E54 Dimension
|
|
32
36
|
*/
|
|
33
37
|
export interface VerticalSpan {
|
|
34
38
|
/**
|
|
35
|
-
* The unit of measurement for
|
|
39
|
+
* The unit of measurement for vertical positions.
|
|
36
40
|
* @see crm:P91 has unit
|
|
37
41
|
*/
|
|
38
42
|
unit: 'track';
|
|
39
43
|
/**
|
|
40
44
|
* The start track number of the feature.
|
|
45
|
+
* @see reo:from
|
|
41
46
|
*/
|
|
42
47
|
from: number;
|
|
43
48
|
/**
|
|
44
49
|
* The end track number, if the feature spans multiple tracks.
|
|
45
50
|
* If omitted, the feature occupies a single track.
|
|
51
|
+
* @see reo:to
|
|
46
52
|
*/
|
|
47
53
|
to?: number;
|
|
48
54
|
}
|
|
@@ -51,12 +57,12 @@ export type FeatureType = typeof featureTypes[number];
|
|
|
51
57
|
/**
|
|
52
58
|
* A physical feature on the roll, e.g. a perforation, a tear, a mark, etc.,
|
|
53
59
|
* defined by its horizontal and vertical position and extent.
|
|
54
|
-
* @see
|
|
60
|
+
* @see crm:E26 Physical Feature
|
|
55
61
|
*/
|
|
56
62
|
export interface RollFeature<T extends FeatureType, DamageT extends string> extends WithId, WithType<T> {
|
|
57
63
|
/**
|
|
58
64
|
* IIIF region pointing to a depiction of this feature in the scan.
|
|
59
|
-
* @see crm:
|
|
65
|
+
* @see crm:P138i has representation
|
|
60
66
|
*/
|
|
61
67
|
depiction?: string;
|
|
62
68
|
/**
|
|
@@ -72,6 +78,7 @@ export interface RollFeature<T extends FeatureType, DamageT extends string> exte
|
|
|
72
78
|
/**
|
|
73
79
|
* This can be used e.g. to indicate a perforation
|
|
74
80
|
* which is torn out or in any other way damaged.
|
|
81
|
+
* @see crm:P44 has condition
|
|
75
82
|
*/
|
|
76
83
|
condition?: ObjectAssumption<ConditionState<DamageT>>;
|
|
77
84
|
}
|
|
@@ -90,7 +97,10 @@ export interface Hole extends RollFeature<'Hole', typeof conditions.Hole[number]
|
|
|
90
97
|
/**
|
|
91
98
|
* The punching pattern of the hole. Regular holes have evenly-spaced
|
|
92
99
|
* bridges, accelerating holes have decreasing bridge widths, and
|
|
93
|
-
* staggering holes
|
|
100
|
+
* staggering holes do not align in rows across the tracks, the mark
|
|
101
|
+
* of an asynchronous perforator with a separate driver for each
|
|
102
|
+
* punch (Phillips 2016, p. 112).
|
|
103
|
+
* @see reo:pattern
|
|
94
104
|
*/
|
|
95
105
|
pattern?: 'regular' | 'accelerating' | 'staggering';
|
|
96
106
|
}
|
|
@@ -110,23 +120,27 @@ export type WritingMethod = typeof writingMethods[number];
|
|
|
110
120
|
* A piece of writing found on the roll, such as a label,
|
|
111
121
|
* catalogue number, or annotation. Writings have a method
|
|
112
122
|
* of production and a transcription of their content.
|
|
123
|
+
* @see crm:E25 Human-Made Feature
|
|
113
124
|
*/
|
|
114
125
|
export interface Writing extends Trace<'Writing'> {
|
|
115
126
|
/**
|
|
116
127
|
* The method by which this writing was produced
|
|
117
128
|
* (e.g. through print, handwriting, or stamping).
|
|
129
|
+
* @see crm:P2 has type
|
|
118
130
|
*/
|
|
119
131
|
method: WritingMethod;
|
|
120
132
|
/**
|
|
121
133
|
* A transcription of the text content of the writing.
|
|
122
134
|
* This is an object assumption so that the transcription
|
|
123
135
|
* can be annotated with a belief about its correctness.
|
|
136
|
+
* @see crm:P128 carries
|
|
124
137
|
*/
|
|
125
138
|
transcription: ObjectAssumption<Omit<Text, 'carriers'>>;
|
|
126
139
|
}
|
|
127
140
|
/**
|
|
128
141
|
* A visible mark on the roll, such as a pencil mark,
|
|
129
142
|
* ink mark, or other non-textual annotation.
|
|
143
|
+
* @see crm:E25 Human-Made Feature
|
|
130
144
|
*/
|
|
131
145
|
export interface Mark extends Trace<'Mark'> {
|
|
132
146
|
}
|
|
@@ -135,6 +149,7 @@ export interface Mark extends Trace<'Mark'> {
|
|
|
135
149
|
* Glued-on features are typically used to cover perforations (for corrections)
|
|
136
150
|
* or to reinforce damaged areas. They may themselves carry other features
|
|
137
151
|
* such as writings or additional holes.
|
|
152
|
+
* @see crm:E22 Human-Made Object
|
|
138
153
|
*/
|
|
139
154
|
export interface GluedOn extends RollFeature<'GluedOn', typeof conditions.GluedOn[number]> {
|
|
140
155
|
/**
|
package/lib/Plan.js
CHANGED
|
@@ -158,6 +158,7 @@ export class CreateVersion extends BasePlan {
|
|
|
158
158
|
result.push(draft => {
|
|
159
159
|
draft.copies.push(this.copy);
|
|
160
160
|
const newVersion = {
|
|
161
|
+
type: 'Version',
|
|
161
162
|
siglum: this.siglum,
|
|
162
163
|
id: v4(),
|
|
163
164
|
edits: asSymbols(this.copy.features).map((symbol) => {
|
|
@@ -168,7 +169,7 @@ export class CreateVersion extends BasePlan {
|
|
|
168
169
|
delete: [],
|
|
169
170
|
};
|
|
170
171
|
}),
|
|
171
|
-
|
|
172
|
+
versionType: 'edition',
|
|
172
173
|
motivations: []
|
|
173
174
|
};
|
|
174
175
|
draft.versions.push(newVersion);
|