linked-rolls 0.0.1 → 0.1.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.
Files changed (67) hide show
  1. package/README.md +48 -1
  2. package/lib/Assumption.d.ts +124 -0
  3. package/lib/Assumption.js +34 -0
  4. package/lib/Collation.d.ts +11 -0
  5. package/lib/ConditionState.d.ts +8 -3
  6. package/lib/ConditionState.js +0 -5
  7. package/lib/Edit.d.ts +44 -14
  8. package/lib/Edit.js +2 -95
  9. package/lib/Edition.d.ts +144 -4
  10. package/lib/EditionView.d.ts +51 -0
  11. package/lib/EditionView.js +294 -0
  12. package/lib/Emulation.d.ts +21 -68
  13. package/lib/Emulation.js +94 -386
  14. package/lib/Feature.d.ts +137 -16
  15. package/lib/Feature.js +9 -1
  16. package/lib/Plan.d.ts +190 -0
  17. package/lib/Plan.js +555 -0
  18. package/lib/ReproducingSystem.d.ts +80 -0
  19. package/lib/RollCopy.d.ts +259 -24
  20. package/lib/RollCopy.js +232 -215
  21. package/lib/Symbol.d.ts +70 -37
  22. package/lib/Symbol.js +2 -27
  23. package/lib/TrackCalibration.d.ts +33 -0
  24. package/lib/TrackCalibration.js +14 -0
  25. package/lib/TrackerBar.d.ts +52 -5
  26. package/lib/TrackerBar.js +70 -49
  27. package/lib/Version.d.ts +32 -33
  28. package/lib/Version.js +3 -209
  29. package/lib/alignFeatures.d.ts +3 -2
  30. package/lib/alignFeatures.js +5 -4
  31. package/lib/asJsonLd.d.ts +1 -1
  32. package/lib/asJsonLd.js +13 -26
  33. package/lib/importJsonLd.d.ts +0 -1
  34. package/lib/importJsonLd.js +9 -72
  35. package/lib/index.d.ts +7 -3
  36. package/lib/index.js +7 -3
  37. package/lib/schema.json +1739 -0
  38. package/lib/spec/context.json +125 -144
  39. package/lib/systems/welteT100.d.ts +55 -0
  40. package/lib/systems/welteT100.js +191 -0
  41. package/lib/utils.d.ts +29 -0
  42. package/lib/validate.d.ts +3 -0
  43. package/lib/validate.js +10 -0
  44. package/package.json +41 -8
  45. package/lib/Condition.d.ts +0 -10
  46. package/lib/EditorialAssumption.d.ts +0 -67
  47. package/lib/EditorialAssumption.js +0 -26
  48. package/lib/Measurement.d.ts +0 -9
  49. package/lib/PlaceTimeConversion.d.ts +0 -65
  50. package/lib/PlaceTimeConversion.js +0 -175
  51. package/lib/RollEvent.d.ts +0 -76
  52. package/lib/RollEvent.js +0 -3
  53. package/lib/Stage.d.ts +0 -37
  54. package/lib/Stage.js +0 -165
  55. package/lib/Transcription.d.ts +0 -7
  56. package/lib/Transcription.js +0 -9
  57. package/lib/WithId.d.ts +0 -3
  58. package/lib/WithId.js +0 -1
  59. package/lib/alignRolls.d.ts +0 -7
  60. package/lib/alignRolls.js +0 -49
  61. package/lib/alignSymbols.d.ts +0 -7
  62. package/lib/alignSymbols.js +0 -49
  63. package/lib/aton/AtonParser.test.d.ts +0 -1
  64. package/lib/aton/AtonParser.test.js +0 -16
  65. package/lib/build-schema.cjs +0 -113
  66. /package/lib/{Condition.js → ReproducingSystem.js} +0 -0
  67. /package/lib/{Measurement.js → utils.js} +0 -0
package/lib/Feature.d.ts CHANGED
@@ -1,37 +1,158 @@
1
+ import { ObjectAssumption } from "./Assumption";
1
2
  import { ConditionState } from "./ConditionState";
2
- import { EditorialAssumption } from "./EditorialAssumption";
3
- import { WithId } from "./WithId";
4
- export interface FeatureCondition extends ConditionState<'missing-perforation' | 'damaged-perforation' | 'illegible'> {
5
- }
6
- export type FeatureConditionAssignment = EditorialAssumption<'conditionAssignment', FeatureCondition>;
3
+ import { Text } from "./Symbol";
4
+ import { PartialBy, WithId, WithType } from "./utils";
5
+ /**
6
+ * Describes the horizontal extent of a feature on the roll,
7
+ * measured in millimeters from the beginning of the roll.
8
+ * The `from` value is the start position and `to` is the end position.
9
+ */
7
10
  export interface HorizontalSpan {
11
+ /**
12
+ * The unit of measurement for horizontal positions.
13
+ * Always 'mm' (millimeters).
14
+ * @see crm:P91 has unit
15
+ */
8
16
  unit: 'mm';
17
+ /**
18
+ * The start position of the feature in millimeters
19
+ * from the beginning of the roll.
20
+ */
9
21
  from: number;
22
+ /**
23
+ * The end position of the feature in millimeters
24
+ * from the beginning of the roll.
25
+ */
10
26
  to: number;
11
27
  }
28
+ /**
29
+ * Describes the vertical extent of a feature on the roll,
30
+ * measured in track numbers. Track numbers correspond to
31
+ * positions on the tracker bar.
32
+ */
12
33
  export interface VerticalSpan {
34
+ /**
35
+ * The unit of measurement for horizontal positions.
36
+ * @see crm:P91 has unit
37
+ */
13
38
  unit: 'track';
39
+ /**
40
+ * The start track number of the feature.
41
+ */
14
42
  from: number;
43
+ /**
44
+ * The end track number, if the feature spans multiple tracks.
45
+ * If omitted, the feature occupies a single track.
46
+ */
15
47
  to?: number;
16
48
  }
17
- export interface RollFeature extends WithId {
49
+ export declare const featureTypes: readonly ["Hole", "Writing", "Mark", "GluedOn"];
50
+ export type FeatureType = typeof featureTypes[number];
51
+ /**
52
+ * A physical feature on the roll, e.g. a perforation, a tear, a mark, etc.,
53
+ * defined by its horizontal and vertical position and extent.
54
+ * @see reo:C2 Feature
55
+ */
56
+ export interface RollFeature<T extends FeatureType, DamageT extends string> extends WithId, WithType<T> {
57
+ /**
58
+ * IIIF region pointing to a depiction of this feature in the scan.
59
+ * @see crm:P62 is depicted by
60
+ */
61
+ depiction?: string;
18
62
  /**
19
- * IIIF region in string form.
63
+ * Horizontal span of the feature on the roll.
64
+ * @see crm:P43 has dimension
20
65
  */
21
- annotates?: string;
22
66
  horizontal: HorizontalSpan;
23
- vertical: VerticalSpan;
24
67
  /**
25
- * Describes whether the event takes place
26
- * on the verso or recto side of the roll.
27
- * Since the same perforation is present on both
28
- * sides, this property is left optional for now.
68
+ * Vertical span of the feature on the roll.
69
+ * @see crm:P43 has dimension
29
70
  */
30
- side?: 'verso' | 'recto';
71
+ vertical: VerticalSpan;
31
72
  /**
32
73
  * This can be used e.g. to indicate a perforation
33
74
  * which is torn out or in any other way damaged.
34
75
  */
35
- condition?: FeatureConditionAssignment;
76
+ condition?: ObjectAssumption<ConditionState<DamageT>>;
77
+ }
78
+ export declare const conditions: {
79
+ readonly Hole: readonly ["partially-torn", "missing-perforation"];
80
+ readonly Writing: readonly ["illegible"];
81
+ readonly Mark: readonly ["faded"];
82
+ readonly GluedOn: readonly ["detaching", "ripped"];
83
+ };
84
+ /**
85
+ * A hole (perforation) in the roll paper. Holes are the primary
86
+ * carriers of musical information on piano rolls, as they trigger
87
+ * notes and expression controls when passing over the tracker bar.
88
+ */
89
+ export interface Hole extends RollFeature<'Hole', typeof conditions.Hole[number]> {
90
+ /**
91
+ * The punching pattern of the hole. Regular holes have evenly-spaced
92
+ * bridges, accelerating holes have decreasing bridge widths, and
93
+ * staggering holes alternate between adjacent tracks (cf. Phillips).
94
+ */
95
+ pattern?: 'regular' | 'accelerating' | 'staggering';
96
+ }
97
+ /**
98
+ * A trace is a visible mark or writing on the roll surface.
99
+ * Traces may fade over time.
100
+ */
101
+ export interface Trace<T extends FeatureType> extends RollFeature<T, typeof conditions.Mark[number]> {
102
+ }
103
+ export declare const writingMethods: readonly ["Print", "Handwriting", "Stamp"];
104
+ /**
105
+ * The method by which a writing was produced on the roll:
106
+ * printed, handwritten, or stamped.
107
+ */
108
+ export type WritingMethod = typeof writingMethods[number];
109
+ /**
110
+ * A piece of writing found on the roll, such as a label,
111
+ * catalogue number, or annotation. Writings have a method
112
+ * of production and a transcription of their content.
113
+ */
114
+ export interface Writing extends Trace<'Writing'> {
115
+ /**
116
+ * The method by which this writing was produced
117
+ * (e.g. through print, handwriting, or stamping).
118
+ */
119
+ method: WritingMethod;
120
+ /**
121
+ * A transcription of the text content of the writing.
122
+ * This is an object assumption so that the transcription
123
+ * can be annotated with a belief about its correctness.
124
+ */
125
+ transcription: ObjectAssumption<Omit<Text, 'carriers'>>;
126
+ }
127
+ /**
128
+ * A visible mark on the roll, such as a pencil mark,
129
+ * ink mark, or other non-textual annotation.
130
+ */
131
+ export interface Mark extends Trace<'Mark'> {
132
+ }
133
+ /**
134
+ * A piece of material (paper or tape) glued onto the roll surface.
135
+ * Glued-on features are typically used to cover perforations (for corrections)
136
+ * or to reinforce damaged areas. They may themselves carry other features
137
+ * such as writings or additional holes.
138
+ */
139
+ export interface GluedOn extends RollFeature<'GluedOn', typeof conditions.GluedOn[number]> {
140
+ /**
141
+ * The material of the glued-on feature.
142
+ * @see crm:P45 consists of
143
+ */
144
+ material: 'Paper' | 'Tape';
145
+ /**
146
+ * A glued-on feature itself may carry other features.
147
+ * Nested features do not need to be positioned explicitly.
148
+ * @see crm:P56 bears feature
149
+ */
150
+ features?: PartialBy<AnyFeature, 'horizontal' | 'vertical'>[];
36
151
  }
37
- export declare const isRollFeature: (obj: object) => obj is RollFeature;
152
+ /**
153
+ * The union of all physical feature types that can appear on a roll:
154
+ * holes (perforations), writings (labels, annotations), marks (pencil, ink),
155
+ * and glued-on patches (paper, tape).
156
+ */
157
+ export type AnyFeature = Hole | Writing | Mark | GluedOn;
158
+ export declare const isRollFeature: (obj: object) => obj is AnyFeature;
package/lib/Feature.js CHANGED
@@ -1,3 +1,11 @@
1
+ export const featureTypes = ['Hole', 'Writing', 'Mark', 'GluedOn'];
2
+ export const conditions = {
3
+ Hole: ['partially-torn', 'missing-perforation'],
4
+ Writing: ['illegible'],
5
+ Mark: ['faded'],
6
+ GluedOn: ['detaching', 'ripped']
7
+ };
8
+ export const writingMethods = ['Print', 'Handwriting', 'Stamp'];
1
9
  export const isRollFeature = (obj) => {
2
- return 'horizontal' in obj && 'vertical' in obj;
10
+ return 'type' in obj && featureTypes.includes(obj.type);
3
11
  };
package/lib/Plan.d.ts ADDED
@@ -0,0 +1,190 @@
1
+ import { Draft } from "immer";
2
+ import { EditionView } from "./EditionView";
3
+ import { Edition } from "./Edition";
4
+ import { CollationTolerance } from "./Collation";
5
+ import { Edit } from "./Edit";
6
+ import { RollCopy } from "./RollCopy";
7
+ export type EditionOp = (d: Draft<Edition>) => void;
8
+ export interface Plan {
9
+ build(): EditionOp[];
10
+ setView: (view: EditionView) => void;
11
+ }
12
+ export declare const isPlan: (obj: any) => obj is Plan;
13
+ export declare abstract class BasePlan implements Plan {
14
+ protected view: EditionView | null;
15
+ setView: (view: EditionView) => void;
16
+ abstract build(): EditionOp[];
17
+ }
18
+ /**
19
+ * Walks through the versions. If it finds a symbol that is still
20
+ * part of the tradition (i.e. it is included in the current snapshot)
21
+ * and is equivalent with the given symbol, it will add the feature
22
+ * carrying the symbol to the collated symbol. Otherwise, the
23
+ * given symbol will be added to the current version's insertions.
24
+ *
25
+ * All symbols of the tradition that are not included in the given
26
+ * symbols are considered to be deleted.
27
+ *
28
+ * @param creation
29
+ * @param symbols
30
+ * @returns
31
+ */
32
+ export declare class ConnectVersions extends BasePlan {
33
+ private childId;
34
+ private parentId;
35
+ private tolerance;
36
+ constructor(childId: string, parentId: string, tolerance?: CollationTolerance);
37
+ build(): EditionOp[];
38
+ }
39
+ /**
40
+ * Walks through the versions. If it finds a symbol that is still
41
+ * part of the tradition (i.e. it is included in the current snapshot)
42
+ * and is equivalent with the given symbol, it will add the feature
43
+ * carrying the symbol to the collated symbol. Otherwise, the
44
+ * given symbol will be added to the current version's insertions.
45
+ *
46
+ * All symbols of the tradition that are not included in the given
47
+ * symbols are considered to be deleted.
48
+ *
49
+ * @param creation
50
+ * @param symbols
51
+ * @returns
52
+ */
53
+ export declare class CreateVersion extends BasePlan {
54
+ private siglum;
55
+ private copy;
56
+ constructor(siglum: string, copy: RollCopy);
57
+ build(): EditionOp[];
58
+ }
59
+ /**
60
+ * Creates a new version based on the given version
61
+ * calculating the effect of a cover on existing symbols.
62
+
63
+ export class CoverPerforation extends BasePlan {
64
+ constructor(
65
+ private copyId: string,
66
+ private versionId: string,
67
+ private coverDimension: { horizontal: HorizontalSpan, vertical: VerticalSpan },
68
+ private material: string | undefined = undefined,
69
+ ) {
70
+ super()
71
+ }
72
+
73
+ build(): EditionOp[] {
74
+ const view = this.view
75
+ if (!view) return []
76
+
77
+ return [
78
+ (draft: Draft<Edition>): void => {
79
+ const version = draft.versions.find(v => v.id === this.versionId)
80
+ const copy = draft.copies.find(c => c.id === this.copyId)
81
+ if (!version || !copy) return
82
+
83
+ // find perforations in the snapshot that
84
+ // overlap with the cover
85
+ const overlappingSymbols =
86
+ view.snapshot(this.versionId)
87
+ .filter(symbol => {
88
+ const dimension = view.dimensionOf(symbol)
89
+ if (!dimension) return false
90
+
91
+ return (
92
+ (symbol.type === 'note' || symbol.type === 'expression') &&
93
+ overlaps(dimension, this.coverDimension)
94
+ )
95
+ })
96
+
97
+ if (!overlappingSymbols.length) return undefined
98
+
99
+ const deepClone = JSON.parse(JSON.stringify(overlappingSymbols)) as AnySymbol[]
100
+
101
+ for (const symbol of deepClone) {
102
+ //symbol.id = v4();
103
+ const dimension = structuredClone(view.dimensionOf(symbol))
104
+ if (!dimension) continue
105
+
106
+ // check if the cover partially covers the beginning
107
+ if (dimension.horizontal.from >= this.coverDimension.horizontal.from &&
108
+ dimension.horizontal.from <= this.coverDimension.horizontal.to
109
+ ) {
110
+ dimension.horizontal.from = this.coverDimension.horizontal.to
111
+ }
112
+
113
+ // check if the cover partially covers the ending
114
+ if (dimension.horizontal.to >= this.coverDimension.horizontal.from &&
115
+ dimension.horizontal.to <= this.coverDimension.horizontal.to
116
+ ) {
117
+ dimension.horizontal.to = this.coverDimension.horizontal.from
118
+ }
119
+
120
+ const newFeature: RollFeature = {
121
+ ...dimension,
122
+ id: v4(),
123
+ }
124
+
125
+ copy.features.push(newFeature)
126
+ symbol.id = `symbol-${v4().slice(0, 8)}`
127
+ symbol.carriers = [assignReference(newFeature.id)]
128
+ }
129
+
130
+ const coverId = `cover-${v4().slice(0, 8)}`
131
+ copy.features.push({
132
+ ...this.coverDimension,
133
+ id: coverId,
134
+ })
135
+
136
+ const edit: Edit = {
137
+ type: 'edit',
138
+ id: v4(),
139
+ delete: overlappingSymbols.map(s => s.id),
140
+ insert: deepClone,
141
+ intentionOf: [{
142
+ type: 'cover',
143
+ id: v4(),
144
+ note: this.material,
145
+ carriers: [assignReference(coverId)],
146
+ }]
147
+ }
148
+
149
+ draft.versions.push({
150
+ edits: [edit],
151
+ id: v4(),
152
+ basedOn: assignReference(version.id),
153
+ siglum: version.siglum + ' rev',
154
+ type: 'authorised-revision',
155
+ motivations: [
156
+ {
157
+ type: 'motivation',
158
+ note: 'Stanzfehler korrigiert',
159
+ id: v4(),
160
+ }
161
+ ],
162
+ })
163
+ }]
164
+ }
165
+ }
166
+ */
167
+ export declare class DetachVersion extends BasePlan {
168
+ private versionId;
169
+ constructor(versionId: string);
170
+ build(): EditionOp[];
171
+ }
172
+ export declare class RemoveFeature extends BasePlan {
173
+ private copyID;
174
+ private featureIDs;
175
+ constructor(copyID: string, featureIDs: string[]);
176
+ build(): EditionOp[];
177
+ }
178
+ export declare class MergeEdits extends BasePlan {
179
+ private versionId;
180
+ private toMerge;
181
+ constructor(versionId: string, toMerge: Edit[]);
182
+ private guessMotivation;
183
+ build(): EditionOp[];
184
+ }
185
+ export declare class SplitEdit extends BasePlan {
186
+ private versionId;
187
+ private toSplit;
188
+ constructor(versionId: string, toSplit: Edit);
189
+ build(): EditionOp[];
190
+ }