@sudobility/music_types 0.11.30 → 0.11.32

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 (251) hide show
  1. package/dist/domain/commands/edit-commands.d.ts +3 -3
  2. package/dist/domain/commands/edit-commands.d.ts.map +1 -1
  3. package/dist/domain/commands/edit-commands.js +25 -25
  4. package/dist/domain/commands/edit-commands.js.map +1 -1
  5. package/dist/domain/commands/history.d.ts +32 -0
  6. package/dist/domain/commands/history.d.ts.map +1 -0
  7. package/dist/domain/commands/history.js +63 -0
  8. package/dist/domain/commands/history.js.map +1 -0
  9. package/dist/domain/commands/note-commands.d.ts +9 -12
  10. package/dist/domain/commands/note-commands.d.ts.map +1 -1
  11. package/dist/domain/commands/note-commands.js +42 -72
  12. package/dist/domain/commands/note-commands.js.map +1 -1
  13. package/dist/domain/commands/note-marks.d.ts +171 -0
  14. package/dist/domain/commands/note-marks.d.ts.map +1 -0
  15. package/dist/domain/commands/note-marks.js +427 -0
  16. package/dist/domain/commands/note-marks.js.map +1 -0
  17. package/dist/domain/commands/reflow.d.ts +1 -1
  18. package/dist/domain/commands/reflow.js +17 -17
  19. package/dist/domain/commands/reflow.js.map +1 -1
  20. package/dist/domain/commands/region-commands.d.ts +4 -4
  21. package/dist/domain/commands/region-commands.d.ts.map +1 -1
  22. package/dist/domain/commands/region-commands.js +7 -7
  23. package/dist/domain/commands/region-commands.js.map +1 -1
  24. package/dist/domain/commands/relocate-commands.d.ts +3 -3
  25. package/dist/domain/commands/relocate-commands.js +15 -15
  26. package/dist/domain/commands/relocate-commands.js.map +1 -1
  27. package/dist/domain/commands/ripple-commands.d.ts +2 -2
  28. package/dist/domain/commands/ripple-commands.js +13 -13
  29. package/dist/domain/commands/ripple-commands.js.map +1 -1
  30. package/dist/domain/commands/snapshot.d.ts +3 -3
  31. package/dist/domain/commands/snapshot.js +5 -5
  32. package/dist/domain/commands/snapshot.js.map +1 -1
  33. package/dist/domain/commands/structure-commands.d.ts +86 -5
  34. package/dist/domain/commands/structure-commands.d.ts.map +1 -1
  35. package/dist/domain/commands/structure-commands.js +272 -36
  36. package/dist/domain/commands/structure-commands.js.map +1 -1
  37. package/dist/domain/commands/track-commands.d.ts +2 -2
  38. package/dist/domain/commands/track-commands.js +7 -7
  39. package/dist/domain/commands/track-commands.js.map +1 -1
  40. package/dist/domain/commands/types.d.ts +2 -2
  41. package/dist/domain/generation/replacement-region.d.ts +32 -0
  42. package/dist/domain/generation/replacement-region.d.ts.map +1 -0
  43. package/dist/domain/generation/replacement-region.js +79 -0
  44. package/dist/domain/generation/replacement-region.js.map +1 -0
  45. package/dist/domain/instruments/gm-icon.d.ts +12 -0
  46. package/dist/domain/instruments/gm-icon.d.ts.map +1 -0
  47. package/dist/domain/instruments/gm-icon.js +327 -0
  48. package/dist/domain/instruments/gm-icon.js.map +1 -0
  49. package/dist/domain/instruments/gm-kit.js +9 -9
  50. package/dist/domain/instruments/gm-kit.js.map +1 -1
  51. package/dist/domain/instruments/gm-percussion.js +48 -48
  52. package/dist/domain/instruments/gm-percussion.js.map +1 -1
  53. package/dist/domain/instruments/gm-polyphony.js +6 -6
  54. package/dist/domain/instruments/gm-range.js +6 -6
  55. package/dist/domain/instruments/gm-transposition.js +1 -1
  56. package/dist/domain/instruments/gm.d.ts +1 -1
  57. package/dist/domain/instruments/gm.js +161 -161
  58. package/dist/domain/instruments/gm.js.map +1 -1
  59. package/dist/domain/instruments/icon-art.d.ts +75 -0
  60. package/dist/domain/instruments/icon-art.d.ts.map +1 -0
  61. package/dist/domain/instruments/icon-art.js +93 -0
  62. package/dist/domain/instruments/icon-art.js.map +1 -0
  63. package/dist/domain/instruments/instrument-fit.d.ts +31 -0
  64. package/dist/domain/instruments/instrument-fit.d.ts.map +1 -0
  65. package/dist/domain/instruments/instrument-fit.js +117 -0
  66. package/dist/domain/instruments/instrument-fit.js.map +1 -0
  67. package/dist/domain/instruments/instrument-options.d.ts +62 -0
  68. package/dist/domain/instruments/instrument-options.d.ts.map +1 -0
  69. package/dist/domain/instruments/instrument-options.js +69 -0
  70. package/dist/domain/instruments/instrument-options.js.map +1 -0
  71. package/dist/domain/instruments/track-instrument.d.ts +80 -0
  72. package/dist/domain/instruments/track-instrument.d.ts.map +1 -0
  73. package/dist/domain/instruments/track-instrument.js +102 -0
  74. package/dist/domain/instruments/track-instrument.js.map +1 -0
  75. package/dist/domain/notation/chord-symbol.d.ts +26 -0
  76. package/dist/domain/notation/chord-symbol.d.ts.map +1 -0
  77. package/dist/domain/notation/chord-symbol.js +32 -0
  78. package/dist/domain/notation/chord-symbol.js.map +1 -0
  79. package/dist/domain/notation/lyric-syllables.d.ts +15 -0
  80. package/dist/domain/notation/lyric-syllables.d.ts.map +1 -0
  81. package/dist/domain/notation/lyric-syllables.js +15 -0
  82. package/dist/domain/notation/lyric-syllables.js.map +1 -0
  83. package/dist/domain/notation/music-vocabulary.d.ts +59 -0
  84. package/dist/domain/notation/music-vocabulary.d.ts.map +1 -0
  85. package/dist/domain/notation/music-vocabulary.js +164 -0
  86. package/dist/domain/notation/music-vocabulary.js.map +1 -0
  87. package/dist/domain/pitch/pitch.d.ts +1 -1
  88. package/dist/domain/pitch/pitch.js +29 -29
  89. package/dist/domain/pitch/transpose.d.ts +1 -1
  90. package/dist/domain/pitch/transpose.js +2 -2
  91. package/dist/domain/quantization/quantize.d.ts +2 -2
  92. package/dist/domain/quantization/quantize.js +9 -9
  93. package/dist/domain/quantization/quantize.js.map +1 -1
  94. package/dist/domain/score/articulation.d.ts +56 -0
  95. package/dist/domain/score/articulation.d.ts.map +1 -0
  96. package/dist/domain/score/articulation.js +56 -0
  97. package/dist/domain/score/articulation.js.map +1 -0
  98. package/dist/domain/score/bar-numbers.d.ts +38 -0
  99. package/dist/domain/score/bar-numbers.d.ts.map +1 -0
  100. package/dist/domain/score/bar-numbers.js +49 -0
  101. package/dist/domain/score/bar-numbers.js.map +1 -0
  102. package/dist/domain/score/collapse-rests.d.ts +23 -0
  103. package/dist/domain/score/collapse-rests.d.ts.map +1 -0
  104. package/dist/domain/score/collapse-rests.js +78 -0
  105. package/dist/domain/score/collapse-rests.js.map +1 -0
  106. package/dist/domain/score/cue-notes.d.ts +24 -0
  107. package/dist/domain/score/cue-notes.d.ts.map +1 -0
  108. package/dist/domain/score/cue-notes.js +105 -0
  109. package/dist/domain/score/cue-notes.js.map +1 -0
  110. package/dist/domain/score/dynamics.d.ts +62 -0
  111. package/dist/domain/score/dynamics.d.ts.map +1 -0
  112. package/dist/domain/score/dynamics.js +142 -0
  113. package/dist/domain/score/dynamics.js.map +1 -0
  114. package/dist/domain/score/effective-clef.d.ts +42 -0
  115. package/dist/domain/score/effective-clef.d.ts.map +1 -0
  116. package/dist/domain/score/effective-clef.js +39 -0
  117. package/dist/domain/score/effective-clef.js.map +1 -0
  118. package/dist/domain/score/extract-part.d.ts +10 -0
  119. package/dist/domain/score/extract-part.d.ts.map +1 -0
  120. package/dist/domain/score/extract-part.js +44 -0
  121. package/dist/domain/score/extract-part.js.map +1 -0
  122. package/dist/domain/score/factory.d.ts +1 -1
  123. package/dist/domain/score/factory.js +12 -12
  124. package/dist/domain/score/factory.js.map +1 -1
  125. package/dist/domain/score/fermata-tempo.d.ts +40 -0
  126. package/dist/domain/score/fermata-tempo.d.ts.map +1 -0
  127. package/dist/domain/score/fermata-tempo.js +95 -0
  128. package/dist/domain/score/fermata-tempo.js.map +1 -0
  129. package/dist/domain/score/flatten.d.ts +32 -0
  130. package/dist/domain/score/flatten.d.ts.map +1 -0
  131. package/dist/domain/score/flatten.js +132 -0
  132. package/dist/domain/score/flatten.js.map +1 -0
  133. package/dist/domain/score/fragment.d.ts +4 -8
  134. package/dist/domain/score/fragment.d.ts.map +1 -1
  135. package/dist/domain/score/fragment.js +8 -8
  136. package/dist/domain/score/fragment.js.map +1 -1
  137. package/dist/domain/score/ids.d.ts +1 -1
  138. package/dist/domain/score/ids.js +6 -6
  139. package/dist/domain/score/ottava.d.ts +41 -0
  140. package/dist/domain/score/ottava.d.ts.map +1 -0
  141. package/dist/domain/score/ottava.js +98 -0
  142. package/dist/domain/score/ottava.js.map +1 -0
  143. package/dist/domain/score/performance-timeline.d.ts +42 -0
  144. package/dist/domain/score/performance-timeline.d.ts.map +1 -0
  145. package/dist/domain/score/performance-timeline.js +78 -0
  146. package/dist/domain/score/performance-timeline.js.map +1 -0
  147. package/dist/domain/score/queries.d.ts +2 -2
  148. package/dist/domain/score/queries.js +7 -7
  149. package/dist/domain/score/queries.js.map +1 -1
  150. package/dist/domain/score/rehearsal-marks.d.ts +30 -0
  151. package/dist/domain/score/rehearsal-marks.d.ts.map +1 -0
  152. package/dist/domain/score/rehearsal-marks.js +126 -0
  153. package/dist/domain/score/rehearsal-marks.js.map +1 -0
  154. package/dist/domain/score/repeat-order.d.ts +21 -0
  155. package/dist/domain/score/repeat-order.d.ts.map +1 -0
  156. package/dist/domain/score/repeat-order.js +123 -0
  157. package/dist/domain/score/repeat-order.js.map +1 -0
  158. package/dist/domain/score/snapshot-tree.d.ts +23 -0
  159. package/dist/domain/score/snapshot-tree.d.ts.map +1 -0
  160. package/dist/domain/score/snapshot-tree.js +45 -0
  161. package/dist/domain/score/snapshot-tree.js.map +1 -0
  162. package/dist/domain/score/ties.d.ts +1 -1
  163. package/dist/domain/score/ties.js +7 -7
  164. package/dist/domain/score/ties.js.map +1 -1
  165. package/dist/domain/score/written-pitch.d.ts +33 -0
  166. package/dist/domain/score/written-pitch.d.ts.map +1 -0
  167. package/dist/domain/score/written-pitch.js +110 -0
  168. package/dist/domain/score/written-pitch.js.map +1 -0
  169. package/dist/domain/selection/range-select.d.ts +13 -0
  170. package/dist/domain/selection/range-select.d.ts.map +1 -0
  171. package/dist/domain/selection/range-select.js +40 -0
  172. package/dist/domain/selection/range-select.js.map +1 -0
  173. package/dist/domain/selection/selection-editing.d.ts +30 -0
  174. package/dist/domain/selection/selection-editing.d.ts.map +1 -0
  175. package/dist/domain/selection/selection-editing.js +31 -0
  176. package/dist/domain/selection/selection-editing.js.map +1 -0
  177. package/dist/domain/selection/selection.d.ts +2 -2
  178. package/dist/domain/selection/selection.js +7 -7
  179. package/dist/domain/selection/selection.js.map +1 -1
  180. package/dist/domain/selection/types.d.ts +2 -2
  181. package/dist/domain/selection/types.d.ts.map +1 -1
  182. package/dist/domain/time/duration-modifiers.d.ts +40 -0
  183. package/dist/domain/time/duration-modifiers.d.ts.map +1 -0
  184. package/dist/domain/time/duration-modifiers.js +50 -0
  185. package/dist/domain/time/duration-modifiers.js.map +1 -0
  186. package/dist/domain/time/duration-selection.d.ts +23 -0
  187. package/dist/domain/time/duration-selection.d.ts.map +1 -0
  188. package/dist/domain/time/duration-selection.js +50 -0
  189. package/dist/domain/time/duration-selection.js.map +1 -0
  190. package/dist/domain/time/durations.js +6 -6
  191. package/dist/domain/time/durations.js.map +1 -1
  192. package/dist/domain/time/fraction.d.ts +1 -1
  193. package/dist/domain/time/fraction.js +1 -1
  194. package/dist/domain/time/tap-to-note.d.ts +21 -0
  195. package/dist/domain/time/tap-to-note.d.ts.map +1 -0
  196. package/dist/domain/time/tap-to-note.js +43 -0
  197. package/dist/domain/time/tap-to-note.js.map +1 -0
  198. package/dist/domain/time/tempo-map.d.ts +1 -1
  199. package/dist/domain/time/ticks.d.ts +1 -1
  200. package/dist/domain/time/ticks.d.ts.map +1 -1
  201. package/dist/domain/time/ticks.js +14 -14
  202. package/dist/domain/time/ticks.js.map +1 -1
  203. package/dist/domain/time/tuplets.d.ts +42 -0
  204. package/dist/domain/time/tuplets.d.ts.map +1 -0
  205. package/dist/domain/time/tuplets.js +53 -0
  206. package/dist/domain/time/tuplets.js.map +1 -0
  207. package/dist/domain/validation/issues.d.ts +1 -1
  208. package/dist/domain/validation/issues.js +20 -20
  209. package/dist/domain/validation/validator.d.ts +2 -2
  210. package/dist/domain/validation/validator.d.ts.map +1 -1
  211. package/dist/domain/validation/validator.js +31 -31
  212. package/dist/domain/validation/validator.js.map +1 -1
  213. package/dist/domain/voicing/allocate.d.ts +2 -2
  214. package/dist/domain/voicing/allocate.js +6 -6
  215. package/dist/domain/voicing/allocate.js.map +1 -1
  216. package/dist/index.d.ts +72 -5535
  217. package/dist/index.d.ts.map +1 -1
  218. package/dist/index.js +79 -462
  219. package/dist/index.js.map +1 -1
  220. package/dist/model/api.d.ts +1696 -0
  221. package/dist/model/api.d.ts.map +1 -0
  222. package/dist/model/api.js +125 -0
  223. package/dist/model/api.js.map +1 -0
  224. package/dist/model/generation.d.ts +2178 -0
  225. package/dist/model/generation.d.ts.map +1 -0
  226. package/dist/model/generation.js +142 -0
  227. package/dist/model/generation.js.map +1 -0
  228. package/dist/model/schemas.d.ts +1200 -0
  229. package/dist/model/schemas.d.ts.map +1 -0
  230. package/dist/model/schemas.js +200 -0
  231. package/dist/model/schemas.js.map +1 -0
  232. package/dist/model/score.d.ts +462 -0
  233. package/dist/model/score.d.ts.map +1 -0
  234. package/dist/model/score.js +34 -0
  235. package/dist/model/score.js.map +1 -0
  236. package/dist/platform/audio.d.ts.map +1 -1
  237. package/dist/platform/file.d.ts.map +1 -1
  238. package/dist/platform/index.d.ts +7 -7
  239. package/dist/platform/index.js +7 -7
  240. package/dist/platform/midi-input.d.ts +2 -2
  241. package/dist/platform/midi.d.ts.map +1 -1
  242. package/dist/platform/mod.d.ts +2 -2
  243. package/dist/platform/playback.d.ts +7 -7
  244. package/dist/platform/xml.js +1 -1
  245. package/dist/services/regeneration/controller.d.ts +6 -6
  246. package/dist/services/regeneration/controller.js +12 -12
  247. package/dist/services/regeneration/controller.js.map +1 -1
  248. package/dist/test/fixtures.d.ts +1 -1
  249. package/dist/test/fixtures.js +103 -103
  250. package/dist/test/fixtures.js.map +1 -1
  251. package/package.json +1 -1
@@ -0,0 +1,102 @@
1
+ import { gmInstrumentRange } from "./gm-range.js";
2
+ import { gmMaxPolyphony, UNLIMITED_POLYPHONY } from "./gm-polyphony.js";
3
+ import { gmWrittenTransposition } from "./gm-transposition.js";
4
+ import { gmKit, gmKitAt } from "./gm-kit.js";
5
+ import { GM_PERCUSSION_RANGE } from "./gm-percussion.js";
6
+ import { gmInstrumentIcon, gmKitIcon } from "./gm-icon.js";
7
+ import { gmInstrument } from "./gm.js";
8
+ /** Whether `track`'s `midiProgram` addresses a drum kit rather than an instrument. */
9
+ export function isPercussionTrack(track) {
10
+ return track.clef === "percussion";
11
+ }
12
+ /**
13
+ * The notes worth showing for `track` — General MIDI's drum range on a
14
+ * percussion track, the instrument's compass otherwise.
15
+ */
16
+ export function trackKeyboardRange(track) {
17
+ if (isPercussionTrack(track))
18
+ return { ...GM_PERCUSSION_RANGE };
19
+ return gmInstrumentRange(track.midiProgram);
20
+ }
21
+ /**
22
+ * How many notes `track` can sound at once.
23
+ *
24
+ * Unlimited on a drum track: the limit exists to stop a part being written that
25
+ * nobody could play, and a kit is played with two hands and two feet across
26
+ * pieces that are all struck separately. Nothing about a kit address says
27
+ * otherwise.
28
+ */
29
+ export function trackMaxPolyphony(track) {
30
+ if (isPercussionTrack(track))
31
+ return UNLIMITED_POLYPHONY;
32
+ return gmMaxPolyphony(track.midiProgram);
33
+ }
34
+ /**
35
+ * Semitones between `track`'s sounding and written pitch.
36
+ *
37
+ * Always zero on a drum track. A percussion staff's positions name drums, so
38
+ * transposing one does not move a part into a reader's key — it renames every
39
+ * drum in it.
40
+ */
41
+ export function trackWrittenTransposition(track) {
42
+ if (isPercussionTrack(track))
43
+ return 0;
44
+ return gmWrittenTransposition(track.midiProgram);
45
+ }
46
+ /**
47
+ * `track`'s program, corrected to something its clef can actually mean.
48
+ *
49
+ * On a percussion track that is the kit whose region the address falls in; a
50
+ * MIDI file is free to set program 45 on channel 10, and the kit that resolves
51
+ * to is Brush. Off a percussion track the program is already an instrument and
52
+ * is returned untouched.
53
+ */
54
+ export function trackProgramForClef(track) {
55
+ return isPercussionTrack(track)
56
+ ? gmKitAt(track.midiProgram).program
57
+ : track.midiProgram;
58
+ }
59
+ /** The icon for `track` — a kit on a percussion track, its instrument's art otherwise. */
60
+ export function trackInstrumentIcon(track) {
61
+ return isPercussionTrack(track)
62
+ ? gmKitIcon()
63
+ : gmInstrumentIcon(track.midiProgram);
64
+ }
65
+ /** What to call `track`'s sound: its kit's name on a percussion track, its instrument's otherwise. */
66
+ export function trackInstrumentLabel(track) {
67
+ if (isPercussionTrack(track))
68
+ return gmKitAt(track.midiProgram).name;
69
+ return gmInstrument(track.midiProgram)?.name ?? "Instrument";
70
+ }
71
+ /**
72
+ * `score` with every percussion track's program resolved to a real kit.
73
+ *
74
+ * A drum track can arrive holding an address no kit sits at: a MIDI file sets
75
+ * whatever program it likes on channel 10, and nothing before this treated that
76
+ * number as a kit at all. The picker would then have to show something the
77
+ * score does not say, so the score is corrected instead of the display fudged.
78
+ *
79
+ * A track already on a kit address is returned untouched — including its
80
+ * `instrumentName`, which is the user's description of a sound that is not
81
+ * changing. Only a track being corrected has its name rewritten, because the
82
+ * old one described a different kit.
83
+ *
84
+ * Returns the **identical object** when nothing needs correcting, which is the
85
+ * usual case: `computeLayout` is cached by score identity, and a fresh object
86
+ * on every load would also read as a change to the autosaver.
87
+ */
88
+ export function scoreWithResolvedKits(score) {
89
+ const needsWork = score.tracks.some((track) => isPercussionTrack(track) && gmKit(track.midiProgram) === null);
90
+ if (!needsWork)
91
+ return score;
92
+ return {
93
+ ...score,
94
+ tracks: score.tracks.map((track) => {
95
+ if (!isPercussionTrack(track) || gmKit(track.midiProgram) !== null)
96
+ return track;
97
+ const kit = gmKitAt(track.midiProgram);
98
+ return { ...track, midiProgram: kit.program, instrumentName: kit.name };
99
+ }),
100
+ };
101
+ }
102
+ //# sourceMappingURL=track-instrument.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"track-instrument.js","sourceRoot":"","sources":["../../../src/domain/instruments/track-instrument.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Splitting a chord symbol into the parts MusicXML wants.
3
+ *
4
+ * The model stores the symbol as typed, because a lead sheet's vocabulary is
5
+ * wide and inconsistent and nothing a player writes should be refused. But
6
+ * MusicXML's `<harmony>` wants a `<root-step>` and an `<alter>` — so the root
7
+ * has to come out of the string for export, and only the root.
8
+ *
9
+ * The rest is carried verbatim as the kind's display text with `kind="other"`.
10
+ * That is a deliberate refusal to guess: mapping `-7`, `min7`, `m7`, `mi7` and
11
+ * `−7` onto MusicXML's enumeration is a dictionary that is wrong for somebody,
12
+ * and a symbol that round-trips as the exact text it was typed as is worth
13
+ * more here than one classified into a taxonomy. A reader that understands
14
+ * only the enumeration still sees the right root and the right printed text.
15
+ */
16
+ /** What a chord symbol decomposes into. `null` when it does not start on a note letter. */
17
+ export type ParsedChordSymbol = {
18
+ /** A–G. */
19
+ step: string;
20
+ /** -1 for flat, 1 for sharp, 0 for neither. */
21
+ alter: number;
22
+ /** Everything after the root, e.g. `maj7` or `-7/Bb`. May be empty. */
23
+ quality: string;
24
+ };
25
+ export declare function parseChordSymbol(symbol: string): ParsedChordSymbol | null;
26
+ //# sourceMappingURL=chord-symbol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chord-symbol.d.ts","sourceRoot":"","sources":["../../../src/domain/notation/chord-symbol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,2FAA2F;AAC3F,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW;IACX,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAIF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAezE"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Splitting a chord symbol into the parts MusicXML wants.
3
+ *
4
+ * The model stores the symbol as typed, because a lead sheet's vocabulary is
5
+ * wide and inconsistent and nothing a player writes should be refused. But
6
+ * MusicXML's `<harmony>` wants a `<root-step>` and an `<alter>` — so the root
7
+ * has to come out of the string for export, and only the root.
8
+ *
9
+ * The rest is carried verbatim as the kind's display text with `kind="other"`.
10
+ * That is a deliberate refusal to guess: mapping `-7`, `min7`, `m7`, `mi7` and
11
+ * `−7` onto MusicXML's enumeration is a dictionary that is wrong for somebody,
12
+ * and a symbol that round-trips as the exact text it was typed as is worth
13
+ * more here than one classified into a taxonomy. A reader that understands
14
+ * only the enumeration still sees the right root and the right printed text.
15
+ */
16
+ const ROOT = /^([A-G])([#b♯♭]?)(.*)$/;
17
+ export function parseChordSymbol(symbol) {
18
+ const match = ROOT.exec(symbol.trim());
19
+ if (!match)
20
+ return null;
21
+ const [, step, accidental, quality] = match;
22
+ return {
23
+ step,
24
+ alter: accidental === "#" || accidental === "♯"
25
+ ? 1
26
+ : accidental === "b" || accidental === "♭"
27
+ ? -1
28
+ : 0,
29
+ quality: quality.trim(),
30
+ };
31
+ }
32
+ //# sourceMappingURL=chord-symbol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chord-symbol.js","sourceRoot":"","sources":["../../../src/domain/notation/chord-symbol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAYH,MAAM,IAAI,GAAG,wBAAwB,CAAC;AAEtC,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC;IAC5C,OAAO;QACL,IAAI;QACJ,KAAK,EACH,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,GAAG;YACtC,CAAC,CAAC,CAAC;YACH,CAAC,CAAC,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,GAAG;gBACxC,CAAC,CAAC,CAAC,CAAC;gBACJ,CAAC,CAAC,CAAC;QACT,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE;KACxB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * How a typed syllable joins its neighbours.
3
+ *
4
+ * Its own module rather than living beside the entry bar: it is a pure rule
5
+ * about words, the entry bar is a component, and keeping them together costs
6
+ * that file its fast refresh.
7
+ */
8
+ import type { Syllabic } from "../../index.js";
9
+ /**
10
+ * Derived from whether the writer hyphenated this syllable and whether they
11
+ * hyphenated the one before — a writer knows they are in the middle of
12
+ * "beau-ti-ful" and should not also have to say so.
13
+ */
14
+ export declare function syllabicFor(previousHyphenated: boolean, hyphenated: boolean): Syllabic;
15
+ //# sourceMappingURL=lyric-syllables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lyric-syllables.d.ts","sourceRoot":"","sources":["../../../src/domain/notation/lyric-syllables.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,kBAAkB,EAAE,OAAO,EAC3B,UAAU,EAAE,OAAO,GAClB,QAAQ,CAKV"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Derived from whether the writer hyphenated this syllable and whether they
3
+ * hyphenated the one before — a writer knows they are in the middle of
4
+ * "beau-ti-ful" and should not also have to say so.
5
+ */
6
+ export function syllabicFor(previousHyphenated, hyphenated) {
7
+ if (previousHyphenated && hyphenated)
8
+ return "middle";
9
+ if (previousHyphenated)
10
+ return "end";
11
+ if (hyphenated)
12
+ return "begin";
13
+ return "single";
14
+ }
15
+ //# sourceMappingURL=lyric-syllables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lyric-syllables.js","sourceRoot":"","sources":["../../../src/domain/notation/lyric-syllables.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,kBAA2B,EAC3B,UAAmB;IAEnB,IAAI,kBAAkB,IAAI,UAAU;QAAE,OAAO,QAAQ,CAAC;IACtD,IAAI,kBAAkB;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,UAAU;QAAE,OAAO,OAAO,CAAC;IAC/B,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Saying score values the way a musician says them.
3
+ *
4
+ * A score stores ticks, fifths and zero-based voice indexes because those are
5
+ * the right things to compute with. None of them is the right thing to *show*:
6
+ * a property panel that reads "Duration 480" and "Key (fifths) 2" is stating
7
+ * the storage format, and the reader has to convert in their head to know they
8
+ * are looking at a quarter note in D major.
9
+ *
10
+ * These are the conversions, kept in one place so every surface agrees — and
11
+ * kept here rather than in an app, because which tick count is a quarter note
12
+ * and how many sharps D major has are facts about music, not about a panel.
13
+ *
14
+ * No user-facing prose lives here: note values and key names are the terms of
15
+ * the domain, fixed across locales the way General MIDI's instrument names are.
16
+ */
17
+ import type { Clef, DurationName, KeySignature, Pitch, Score } from "../../index.js";
18
+ /** Every duration name, longest first, so a picker reads top to bottom. */
19
+ export declare const DURATION_NAMES: DurationName[];
20
+ /** What to call `name` in a picker. */
21
+ export declare function durationLabel(name: DurationName): string;
22
+ /** The number of sharps or flats a signature carries, as a phrase. */
23
+ export declare function accidentalCountLabel(fifths: number): string;
24
+ /** e.g. `D major`. Falls back to the fifths count for a signature outside ±7. */
25
+ export declare function keySignatureName(key: KeySignature): string;
26
+ /** Every key a picker should offer, from seven flats to seven sharps. */
27
+ export declare function keySignatureOptions(mode: KeySignature["mode"]): Array<{
28
+ fifths: number;
29
+ label: string;
30
+ }>;
31
+ /**
32
+ * Where `tick` falls, counted the way a player counts: bar 1 upwards, beat 1
33
+ * upwards, with a fraction when it lands between beats.
34
+ *
35
+ * Read off the first track, since every track shares the measure grid once
36
+ * `rebuildMeasureTicks` has run. `null` when the score has no measures, or the
37
+ * tick lies past the end of them.
38
+ */
39
+ export type BarBeat = {
40
+ bar: number;
41
+ beat: number;
42
+ };
43
+ export declare function barBeatForTick(score: Score, tick: number): BarBeat | null;
44
+ /**
45
+ * The tick at `bar`/`beat`, both counted from 1. `null` when that bar does not
46
+ * exist; a beat past the end of its bar is clamped into it, because a typed
47
+ * "beat 9" in 4/4 means the end of the bar rather than an error.
48
+ */
49
+ export declare function tickForBarBeat(score: Score, bar: number, beat: number): number | null;
50
+ /**
51
+ * The pitch at a staff position, counted in half-spaces below the top line.
52
+ *
53
+ * `0` is the top line itself, `1` the space beneath it, `2` the next line down,
54
+ * and negative values are ledger positions above. Diatonic throughout, because
55
+ * a staff position names a letter rather than a semitone — what makes it an F♯
56
+ * rather than an F is the key signature, which is applied elsewhere.
57
+ */
58
+ export declare function pitchAtStavePosition(clef: Clef, positionsBelowTopLine: number): Pitch;
59
+ //# sourceMappingURL=music-vocabulary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"music-vocabulary.d.ts","sourceRoot":"","sources":["../../../src/domain/notation/music-vocabulary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EACV,IAAI,EACJ,YAAY,EACZ,YAAY,EACZ,KAAK,EACL,KAAK,EAEN,MAAM,gBAAgB,CAAC;AAOxB,2EAA2E;AAC3E,eAAO,MAAM,cAAc,EAA6B,YAAY,EAAE,CAAC;AAuBvE,uCAAuC;AACvC,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAExD;AAyCD,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAK3D;AAED,iFAAiF;AACjF,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAI1D;AAED,yEAAyE;AACzE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC,CASD;AAID;;;;;;;GAOG;AACH,MAAM,MAAM,OAAO,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,wBAAgB,cAAc,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CA2BzE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,KAAK,EACZ,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,IAAI,CAef;AAuBD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,IAAI,EACV,qBAAqB,EAAE,MAAM,GAC5B,KAAK,CAEP"}
@@ -0,0 +1,164 @@
1
+ import { DURATIONS, beatDurationTicks } from "../time/ticks.js";
2
+ import { barNumberAt, indexOfBarNumber } from "../score/bar-numbers.js";
3
+ import { shiftDiatonic } from "../pitch/transpose.js";
4
+ // ---- durations -------------------------------------------------------------
5
+ /** Every duration name, longest first, so a picker reads top to bottom. */
6
+ export const DURATION_NAMES = Object.keys(DURATIONS);
7
+ const DURATION_LABELS = {
8
+ whole: "Whole",
9
+ half: "Half",
10
+ quarter: "Quarter",
11
+ eighth: "Eighth",
12
+ sixteenth: "16th",
13
+ thirtysecond: "32nd",
14
+ "dotted-whole": "Dotted whole",
15
+ "dotted-half": "Dotted half",
16
+ "dotted-quarter": "Dotted quarter",
17
+ "dotted-eighth": "Dotted eighth",
18
+ "dotted-sixteenth": "Dotted 16th",
19
+ "dotted-thirtysecond": "Dotted 32nd",
20
+ "triplet-whole": "Whole triplet",
21
+ "triplet-half": "Half triplet",
22
+ "triplet-quarter": "Quarter triplet",
23
+ "triplet-eighth": "Eighth triplet",
24
+ "triplet-sixteenth": "16th triplet",
25
+ "triplet-thirtysecond": "32nd triplet",
26
+ };
27
+ /** What to call `name` in a picker. */
28
+ export function durationLabel(name) {
29
+ return DURATION_LABELS[name];
30
+ }
31
+ // ---- key signatures --------------------------------------------------------
32
+ /** Sharps are positive, flats negative — the MusicXML convention the model stores. */
33
+ const MAJOR_KEYS = {
34
+ [-7]: "C♭",
35
+ [-6]: "G♭",
36
+ [-5]: "D♭",
37
+ [-4]: "A♭",
38
+ [-3]: "E♭",
39
+ [-2]: "B♭",
40
+ [-1]: "F",
41
+ 0: "C",
42
+ 1: "G",
43
+ 2: "D",
44
+ 3: "A",
45
+ 4: "E",
46
+ 5: "B",
47
+ 6: "F♯",
48
+ 7: "C♯",
49
+ };
50
+ const MINOR_KEYS = {
51
+ [-7]: "A♭",
52
+ [-6]: "E♭",
53
+ [-5]: "B♭",
54
+ [-4]: "F",
55
+ [-3]: "C",
56
+ [-2]: "G",
57
+ [-1]: "D",
58
+ 0: "A",
59
+ 1: "E",
60
+ 2: "B",
61
+ 3: "F♯",
62
+ 4: "C♯",
63
+ 5: "G♯",
64
+ 6: "D♯",
65
+ 7: "A♯",
66
+ };
67
+ /** The number of sharps or flats a signature carries, as a phrase. */
68
+ export function accidentalCountLabel(fifths) {
69
+ if (fifths === 0)
70
+ return "no sharps or flats";
71
+ const count = Math.abs(fifths);
72
+ const kind = fifths > 0 ? "sharp" : "flat";
73
+ return `${count} ${kind}${count === 1 ? "" : "s"}`;
74
+ }
75
+ /** e.g. `D major`. Falls back to the fifths count for a signature outside ±7. */
76
+ export function keySignatureName(key) {
77
+ const table = key.mode === "minor" ? MINOR_KEYS : MAJOR_KEYS;
78
+ const tonic = table[key.fifths];
79
+ return tonic ? `${tonic} ${key.mode}` : `${key.fifths} fifths`;
80
+ }
81
+ /** Every key a picker should offer, from seven flats to seven sharps. */
82
+ export function keySignatureOptions(mode) {
83
+ const table = mode === "minor" ? MINOR_KEYS : MAJOR_KEYS;
84
+ return Object.keys(table)
85
+ .map(Number)
86
+ .sort((a, b) => a - b)
87
+ .map((fifths) => ({
88
+ fifths,
89
+ label: `${table[fifths]} ${mode} — ${accidentalCountLabel(fifths)}`,
90
+ }));
91
+ }
92
+ export function barBeatForTick(score, tick) {
93
+ const track = score.tracks[0];
94
+ if (!track || track.measures.length === 0)
95
+ return null;
96
+ const measure = track.measures.find((m) => tick >= m.startTick && tick < m.startTick + m.durationTicks);
97
+ if (!measure)
98
+ return null;
99
+ const beatTicks = beatDurationTicks(measure.timeSignature, score.ppq);
100
+ /*
101
+ Through `barNumberAt`, not `index + 1`: a pickup is not counted, so every
102
+ bar after one is a bar lower than its position. The readout has to say the
103
+ number the player's part says, or "go to bar 33" and the bar shown in the
104
+ inspector mean two different places.
105
+
106
+ A pickup itself has no number; it reports bar 0, which is what a player
107
+ calls it when they have to call it something.
108
+ */
109
+ const index = track.measures.indexOf(measure);
110
+ return {
111
+ bar: barNumberAt(track.measures, index) ?? 0,
112
+ beat: (tick - measure.startTick) / beatTicks + 1,
113
+ };
114
+ }
115
+ /**
116
+ * The tick at `bar`/`beat`, both counted from 1. `null` when that bar does not
117
+ * exist; a beat past the end of its bar is clamped into it, because a typed
118
+ * "beat 9" in 4/4 means the end of the bar rather than an error.
119
+ */
120
+ export function tickForBarBeat(score, bar, beat) {
121
+ const track = score.tracks[0];
122
+ if (!track)
123
+ return null;
124
+ // The inverse of the numbering above, so a typed bar number and a displayed
125
+ // one always name the same bar.
126
+ const index = indexOfBarNumber(track.measures, Math.round(bar));
127
+ const measure = index === null ? undefined : track.measures[index];
128
+ if (!measure)
129
+ return null;
130
+ const beatTicks = beatDurationTicks(measure.timeSignature, score.ppq);
131
+ const offset = Math.max(0, (beat - 1) * beatTicks);
132
+ return measure.startTick + Math.min(offset, measure.durationTicks - 1);
133
+ }
134
+ // ---- staff positions -------------------------------------------------------
135
+ /**
136
+ * The pitch printed on each clef's top staff line.
137
+ *
138
+ * Everything a click on the stave means is measured from here: a staff
139
+ * position is a line or the space below it, and the pitch is that many
140
+ * diatonic steps down from this note.
141
+ *
142
+ * Percussion has no pitch — a drum staff's lines are instruments, not notes —
143
+ * so it borrows treble's geometry and the caller decides what a position means
144
+ * on it.
145
+ */
146
+ const TOP_LINE_PITCH = {
147
+ treble: { step: "F", accidental: 0, octave: 5 },
148
+ bass: { step: "A", accidental: 0, octave: 3 },
149
+ alto: { step: "G", accidental: 0, octave: 4 },
150
+ tenor: { step: "E", accidental: 0, octave: 4 },
151
+ percussion: { step: "F", accidental: 0, octave: 5 },
152
+ };
153
+ /**
154
+ * The pitch at a staff position, counted in half-spaces below the top line.
155
+ *
156
+ * `0` is the top line itself, `1` the space beneath it, `2` the next line down,
157
+ * and negative values are ledger positions above. Diatonic throughout, because
158
+ * a staff position names a letter rather than a semitone — what makes it an F♯
159
+ * rather than an F is the key signature, which is applied elsewhere.
160
+ */
161
+ export function pitchAtStavePosition(clef, positionsBelowTopLine) {
162
+ return shiftDiatonic(TOP_LINE_PITCH[clef], -positionsBelowTopLine);
163
+ }
164
+ //# sourceMappingURL=music-vocabulary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"music-vocabulary.js","sourceRoot":"","sources":["../../../src/domain/notation/music-vocabulary.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { KeySignature, Pitch } from '../../index.js';
1
+ import type { KeySignature, Pitch } from "../../index.js";
2
2
  /** Converts a `Pitch` to its MIDI note number (C4 = 60, A4 = 69). */
3
3
  export declare function pitchToMidi(p: Pitch): number;
4
4
  /**
@@ -20,33 +20,33 @@ export function pitchToMidi(p) {
20
20
  }
21
21
  /** step/accidental spelling for each pitch class 0-11, preferring sharps. */
22
22
  const SHARP_SPELLING = [
23
- { step: 'C', accidental: 0 },
24
- { step: 'C', accidental: 1 },
25
- { step: 'D', accidental: 0 },
26
- { step: 'D', accidental: 1 },
27
- { step: 'E', accidental: 0 },
28
- { step: 'F', accidental: 0 },
29
- { step: 'F', accidental: 1 },
30
- { step: 'G', accidental: 0 },
31
- { step: 'G', accidental: 1 },
32
- { step: 'A', accidental: 0 },
33
- { step: 'A', accidental: 1 },
34
- { step: 'B', accidental: 0 },
23
+ { step: "C", accidental: 0 },
24
+ { step: "C", accidental: 1 },
25
+ { step: "D", accidental: 0 },
26
+ { step: "D", accidental: 1 },
27
+ { step: "E", accidental: 0 },
28
+ { step: "F", accidental: 0 },
29
+ { step: "F", accidental: 1 },
30
+ { step: "G", accidental: 0 },
31
+ { step: "G", accidental: 1 },
32
+ { step: "A", accidental: 0 },
33
+ { step: "A", accidental: 1 },
34
+ { step: "B", accidental: 0 },
35
35
  ];
36
36
  /** step/accidental spelling for each pitch class 0-11, preferring flats. */
37
37
  const FLAT_SPELLING = [
38
- { step: 'C', accidental: 0 },
39
- { step: 'D', accidental: -1 },
40
- { step: 'D', accidental: 0 },
41
- { step: 'E', accidental: -1 },
42
- { step: 'E', accidental: 0 },
43
- { step: 'F', accidental: 0 },
44
- { step: 'G', accidental: -1 },
45
- { step: 'G', accidental: 0 },
46
- { step: 'A', accidental: -1 },
47
- { step: 'A', accidental: 0 },
48
- { step: 'B', accidental: -1 },
49
- { step: 'B', accidental: 0 },
38
+ { step: "C", accidental: 0 },
39
+ { step: "D", accidental: -1 },
40
+ { step: "D", accidental: 0 },
41
+ { step: "E", accidental: -1 },
42
+ { step: "E", accidental: 0 },
43
+ { step: "F", accidental: 0 },
44
+ { step: "G", accidental: -1 },
45
+ { step: "G", accidental: 0 },
46
+ { step: "A", accidental: -1 },
47
+ { step: "A", accidental: 0 },
48
+ { step: "B", accidental: -1 },
49
+ { step: "B", accidental: 0 },
50
50
  ];
51
51
  /**
52
52
  * Converts a MIDI note number to a `Pitch`, choosing an enharmonic spelling
@@ -63,11 +63,11 @@ export function midiToPitch(midi, keySignature) {
63
63
  return { step, accidental, octave };
64
64
  }
65
65
  const ACCIDENTAL_SYMBOLS = {
66
- [-2]: 'bb',
67
- [-1]: 'b',
68
- [0]: '',
69
- [1]: '#',
70
- [2]: '##',
66
+ [-2]: "bb",
67
+ [-1]: "b",
68
+ [0]: "",
69
+ [1]: "#",
70
+ [2]: "##",
71
71
  };
72
72
  /** Formats a `Pitch` as a string, e.g. `C4`, `F#3`, `Bb4`, `F##4`. */
73
73
  export function pitchToString(p) {
@@ -1,4 +1,4 @@
1
- import type { KeySignature, Pitch } from '../../index.js';
1
+ import type { KeySignature, Pitch } from "../../index.js";
2
2
  /**
3
3
  * Transposes a pitch by a number of semitones (may be negative), re-spelling
4
4
  * the result according to the given key signature (see `midiToPitch`).
@@ -1,4 +1,4 @@
1
- import { midiToPitch, pitchToMidi } from './pitch.js';
1
+ import { midiToPitch, pitchToMidi } from "./pitch.js";
2
2
  /**
3
3
  * Transposes a pitch by a number of semitones (may be negative), re-spelling
4
4
  * the result according to the given key signature (see `midiToPitch`).
@@ -14,7 +14,7 @@ export function transposeDiatonicOctave(p, octaves) {
14
14
  return { ...p, octave: p.octave + octaves };
15
15
  }
16
16
  /** The seven letter names, in order, for diatonic movement. */
17
- const STEPS = ['C', 'D', 'E', 'F', 'G', 'A', 'B'];
17
+ const STEPS = ["C", "D", "E", "F", "G", "A", "B"];
18
18
  /**
19
19
  * Moves `p` by `steps` positions on the staff — one step per line-to-adjacent-
20
20
  * space — keeping its accidental.
@@ -1,5 +1,5 @@
1
- import type { MusicalEvent } from '../../index.js';
2
- import type { QuantizeOptions } from './options.js';
1
+ import type { MusicalEvent } from "../../index.js";
2
+ import type { QuantizeOptions } from "./options.js";
3
3
  /**
4
4
  * Quantizes `events` per `opts` (spec §24): drops undersized notes, snaps
5
5
  * starts (grid/triplet/swing/humanize tolerance) and durations (grid,
@@ -5,8 +5,8 @@
5
5
  * means a deterministic "already close enough, leave it" tolerance, not
6
6
  * random jitter). Exposed for both MIDI import cleanup and manual editing.
7
7
  */
8
- import { createId } from '../score/ids.js';
9
- import { isNoteEvent } from '../../index.js';
8
+ import { createId } from "../score/ids.js";
9
+ import { isNoteEvent } from "../../index.js";
10
10
  /** `tripletGrid` subdivides `grid` into thirds-of-two (2/3 of `grid`); otherwise the grid unit is used as-is. */
11
11
  function effectiveGridTicks(opts) {
12
12
  return opts.tripletGrid ? (opts.grid * 2) / 3 : opts.grid;
@@ -53,7 +53,7 @@ function computeSnappedDuration(original, opts) {
53
53
  function dropShortNotes(events, minDurationTicks) {
54
54
  if (minDurationTicks === undefined)
55
55
  return events;
56
- return events.filter(event => !isNoteEvent(event) || event.durationTicks >= minDurationTicks);
56
+ return events.filter((event) => !isNoteEvent(event) || event.durationTicks >= minDurationTicks);
57
57
  }
58
58
  /** Groups events by (trackId, voiceId), preserving each group's first-seen order. */
59
59
  function groupByVoice(events) {
@@ -69,7 +69,7 @@ function groupByVoice(events) {
69
69
  }
70
70
  group.push(event);
71
71
  }
72
- return order.map(key => groups.get(key));
72
+ return order.map((key) => groups.get(key));
73
73
  }
74
74
  /**
75
75
  * Clusters near-simultaneous onsets (already sorted by `startTick`) onto a
@@ -101,7 +101,7 @@ function applyChordGrouping(sorted, tolerance) {
101
101
  * into the next one" meaning of overlap resolution.
102
102
  */
103
103
  function applyResolveOverlaps(sorted) {
104
- const result = sorted.map(event => ({ ...event }));
104
+ const result = sorted.map((event) => ({ ...event }));
105
105
  for (let i = 0; i < result.length - 1; i += 1) {
106
106
  const current = result[i];
107
107
  const next = result[i + 1];
@@ -121,7 +121,7 @@ function applyResolveOverlaps(sorted) {
121
121
  * next one. Events sharing an exact start tick (a chord) are left alone.
122
122
  */
123
123
  function applyLegatoCleanup(sorted) {
124
- const result = sorted.map(event => ({ ...event }));
124
+ const result = sorted.map((event) => ({ ...event }));
125
125
  for (let i = 0; i < result.length - 1; i += 1) {
126
126
  const current = result[i];
127
127
  const next = result[i + 1];
@@ -183,17 +183,17 @@ function processVoiceGroup(group, opts) {
183
183
  */
184
184
  export function quantizeEvents(events, opts) {
185
185
  const survivors = dropShortNotes(events, opts.minDurationTicks);
186
- const withStarts = survivors.map(event => opts.quantizeStarts
186
+ const withStarts = survivors.map((event) => opts.quantizeStarts
187
187
  ? { ...event, startTick: computeSnappedStart(event.startTick, opts) }
188
188
  : { ...event });
189
- const withDurations = withStarts.map(event => opts.quantizeDurations
189
+ const withDurations = withStarts.map((event) => opts.quantizeDurations
190
190
  ? {
191
191
  ...event,
192
192
  durationTicks: computeSnappedDuration(event.durationTicks, opts),
193
193
  }
194
194
  : event);
195
195
  return groupByVoice(withDurations)
196
- .map(group => processVoiceGroup(group, opts))
196
+ .map((group) => processVoiceGroup(group, opts))
197
197
  .flat();
198
198
  }
199
199
  //# sourceMappingURL=quantize.js.map