@sudobility/music_drawing 0.0.30 → 0.0.31

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/dist/index.d.ts CHANGED
@@ -22,6 +22,7 @@ export * from './layout.js';
22
22
  export * from './pagination.js';
23
23
  export * from './print-layout.js';
24
24
  export * from './note-colors.js';
25
+ export * from './out-of-range.js';
25
26
  export * from './hit-test.js';
26
27
  export * from './track-gutter.js';
27
28
  export * from './note-drag.js';
@@ -40,4 +41,10 @@ export * from './icon-canvas.js';
40
41
  * between them. Shared by the web and native apps, which both draw one.
41
42
  */
42
43
  export * from './keyboard-geometry.js';
44
+ /**
45
+ * And what those keys are called, which is the staff's convention rather than
46
+ * the geometry's: a transposing part read in written pitch letters its keys
47
+ * where its player reads them.
48
+ */
49
+ export * from './keyboard-labels.js';
43
50
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AAEjC;;;GAGG;AACH,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AAEjC;;;GAGG;AACH,cAAc,wBAAwB,CAAC;AAEvC;;;;GAIG;AACH,cAAc,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -22,6 +22,7 @@ export * from './layout.js';
22
22
  export * from './pagination.js';
23
23
  export * from './print-layout.js';
24
24
  export * from './note-colors.js';
25
+ export * from './out-of-range.js';
25
26
  export * from './hit-test.js';
26
27
  export * from './track-gutter.js';
27
28
  export * from './note-drag.js';
@@ -40,4 +41,10 @@ export * from './icon-canvas.js';
40
41
  * between them. Shared by the web and native apps, which both draw one.
41
42
  */
42
43
  export * from './keyboard-geometry.js';
44
+ /**
45
+ * And what those keys are called, which is the staff's convention rather than
46
+ * the geometry's: a transposing part read in written pitch letters its keys
47
+ * where its player reads them.
48
+ */
49
+ export * from './keyboard-labels.js';
43
50
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AAEjC;;;GAGG;AACH,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,cAAc,CAAC;AAC7B,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AAEjC;;;GAGG;AACH,cAAc,wBAAwB,CAAC;AAEvC;;;;GAIG;AACH,cAAc,sBAAsB,CAAC"}
@@ -1,19 +1,50 @@
1
- /** A0 — the lowest key on a standard 88-key piano. */
2
- export declare const KEYBOARD_MIN_MIDI = 21;
3
- /** C8 — the highest. */
4
- export declare const KEYBOARD_MAX_MIDI = 108;
5
- /** The 88 keys span 52 whites; the blacks overlay them and add no width. */
6
- export declare const WHITE_KEY_COUNT = 52;
1
+ /**
2
+ * Physical piano-keyboard layout. Pure arithmetic — no React, no store — so
3
+ * the key positions are unit-testable on their own.
4
+ *
5
+ * Here rather than in an app because two of them now draw a keyboard, and a
6
+ * second copy of this would drift from the first the moment either was tuned.
7
+ * It sits in music_drawing beside the score layout for the same reason that
8
+ * does: it answers where something is drawn, and it needs only music_types.
9
+ *
10
+ * The piano roll modelled pitch as one uniform row per semitone. A real
11
+ * keyboard cannot: white keys tile edge to edge and each black key straddles
12
+ * the boundary *between* two whites, overlapping both.
13
+ *
14
+ * ┌─┬─┬─┬─┬─┬─┬─┐
15
+ * │ │█│ │█│ │ │█│ white: x = whiteIndex * w
16
+ * │ └┬┘ └┬┘ │ └┬┘ black: x = (whiteIndex + 1) * w - blackWidth / 2
17
+ * │C │D │E │F │G │
18
+ * └──┴──┴──┴──┴──┘
19
+ */
20
+ import { type MidiRange } from '@sudobility/music_types';
7
21
  /**
8
22
  * The keyboard is drawn over a caller-chosen range, not always all 88 keys:
9
23
  * the active track's instrument decides it, so a piccolo part does not present
10
24
  * three octaves of keys that will never sound.
25
+ *
26
+ * An **alias** of music_types' `MidiRange`, not a structural twin of it. What
27
+ * a caller passes is almost always `trackKeyboardRange(track)`, so the two were
28
+ * already the same shape by coincidence; saying so outright means a change to
29
+ * `MidiRange` reaches the keyboard rather than being silently accepted by a
30
+ * local copy that happens still to match.
31
+ */
32
+ export type KeyboardRange = MidiRange;
33
+ /**
34
+ * The 88-key piano — `FULL_KEYBOARD` **by identity**, not a second pair of
35
+ * numbers that agrees with it today.
36
+ *
37
+ * Kept under this name because both apps' keyboards import `FULL_RANGE`, and
38
+ * because it reads as this module's default range (`computeKeys(w, h)`) where
39
+ * `FULL_KEYBOARD` reads as a fact about instruments.
11
40
  */
12
- export type KeyboardRange = {
13
- min: number;
14
- max: number;
15
- };
16
41
  export declare const FULL_RANGE: KeyboardRange;
42
+ /** A0 — the lowest key on a standard 88-key piano. */
43
+ export declare const KEYBOARD_MIN_MIDI: number;
44
+ /** C8 — the highest. */
45
+ export declare const KEYBOARD_MAX_MIDI: number;
46
+ /** The 88 keys span 52 whites; the blacks overlay them and add no width. */
47
+ export declare const WHITE_KEY_COUNT = 52;
17
48
  /**
18
49
  * Widens `range` so it begins and ends on a white key, and clamps it to the
19
50
  * 88-key piano.
@@ -21,6 +52,11 @@ export declare const FULL_RANGE: KeyboardRange;
21
52
  * A keyboard whose first or last key is black looks broken — a black key has no
22
53
  * white neighbour to hang off on that side, so it would float. Widening is
23
54
  * always safe: it only ever adds a key the instrument nearly reaches.
55
+ *
56
+ * Clamped against `FULL_KEYBOARD` rather than against literals of its own: the
57
+ * ranges arriving here come from the same catalogue that bounds itself by that
58
+ * constant, so a local pair of numbers would be a second opinion on where the
59
+ * piano ends.
24
60
  */
25
61
  export declare function snapToWhiteKeys(range: KeyboardRange): KeyboardRange;
26
62
  /** How many white keys a range spans, which is what sets the keyboard's width. */
@@ -1 +1 @@
1
- {"version":3,"file":"keyboard-geometry.d.ts","sourceRoot":"","sources":["../src/keyboard-geometry.ts"],"names":[],"mappings":"AA0BA,sDAAsD;AACtD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,wBAAwB;AACxB,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,4EAA4E;AAC5E,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzD,eAAO,MAAM,UAAU,EAAE,aAGxB,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,CASnE;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,KAAK,GAAE,aAA0B,GAAG,MAAM,CAKvE;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,oDAAoD;AACpD,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,uDAAuD;IACvD,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;;;;;;OAOG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;OAQG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,sFAAsF;AACtF,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,YAAY,CAAC;AAE/C,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGhD;AAED,kIAAkI;AAClI,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,aAA0B,GAChC,MAAM,CAER;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,KAAK,GAAE,aAA0B,EACjC,MAAM,GAAE,SAAmB,GAC1B,QAAQ,EAAE,CAwDZ"}
1
+ {"version":3,"file":"keyboard-geometry.d.ts","sourceRoot":"","sources":["../src/keyboard-geometry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAML,KAAK,SAAS,EACf,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;GAUG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,CAAC;AAEtC;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,EAAE,aAA6B,CAAC;AAEvD,sDAAsD;AACtD,eAAO,MAAM,iBAAiB,QAAoB,CAAC;AACnD,wBAAwB;AACxB,eAAO,MAAM,iBAAiB,QAAoB,CAAC;AACnD,4EAA4E;AAC5E,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,CASnE;AAED,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,KAAK,GAAE,aAA0B,GAAG,MAAM,CAKvE;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAEtC,oDAAoD;AACpD,eAAO,MAAM,qBAAqB,MAAM,CAAC;AACzC,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,uDAAuD;IACvD,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;;;;;;OAOG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;OAQG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,sFAAsF;AACtF,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,YAAY,CAAC;AAE/C,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGhD;AAED,kIAAkI;AAClI,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,8DAA8D;AAC9D,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,aAA0B,GAChC,MAAM,CAER;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,KAAK,GAAE,aAA0B,EACjC,MAAM,GAAE,SAAmB,GAC1B,QAAQ,EAAE,CAwDZ"}
@@ -17,17 +17,22 @@
17
17
  * │C │D │E │F │G │
18
18
  * └──┴──┴──┴──┴──┘
19
19
  */
20
- import { gmPercussion, gmPercussionName, midiToPitch, pitchToString, } from '@sudobility/music_types';
20
+ import { FULL_KEYBOARD, gmPercussion, gmPercussionName, midiToPitch, pitchToString, } from '@sudobility/music_types';
21
+ /**
22
+ * The 88-key piano — `FULL_KEYBOARD` **by identity**, not a second pair of
23
+ * numbers that agrees with it today.
24
+ *
25
+ * Kept under this name because both apps' keyboards import `FULL_RANGE`, and
26
+ * because it reads as this module's default range (`computeKeys(w, h)`) where
27
+ * `FULL_KEYBOARD` reads as a fact about instruments.
28
+ */
29
+ export const FULL_RANGE = FULL_KEYBOARD;
21
30
  /** A0 — the lowest key on a standard 88-key piano. */
22
- export const KEYBOARD_MIN_MIDI = 21;
31
+ export const KEYBOARD_MIN_MIDI = FULL_KEYBOARD.min;
23
32
  /** C8 — the highest. */
24
- export const KEYBOARD_MAX_MIDI = 108;
33
+ export const KEYBOARD_MAX_MIDI = FULL_KEYBOARD.max;
25
34
  /** The 88 keys span 52 whites; the blacks overlay them and add no width. */
26
35
  export const WHITE_KEY_COUNT = 52;
27
- export const FULL_RANGE = {
28
- min: KEYBOARD_MIN_MIDI,
29
- max: KEYBOARD_MAX_MIDI,
30
- };
31
36
  /**
32
37
  * Widens `range` so it begins and ends on a white key, and clamps it to the
33
38
  * 88-key piano.
@@ -35,13 +40,18 @@ export const FULL_RANGE = {
35
40
  * A keyboard whose first or last key is black looks broken — a black key has no
36
41
  * white neighbour to hang off on that side, so it would float. Widening is
37
42
  * always safe: it only ever adds a key the instrument nearly reaches.
43
+ *
44
+ * Clamped against `FULL_KEYBOARD` rather than against literals of its own: the
45
+ * ranges arriving here come from the same catalogue that bounds itself by that
46
+ * constant, so a local pair of numbers would be a second opinion on where the
47
+ * piano ends.
38
48
  */
39
49
  export function snapToWhiteKeys(range) {
40
- let min = Math.max(KEYBOARD_MIN_MIDI, Math.min(range.min, range.max));
41
- let max = Math.min(KEYBOARD_MAX_MIDI, Math.max(range.min, range.max));
42
- while (min > KEYBOARD_MIN_MIDI && isBlackKey(min))
50
+ let min = Math.max(FULL_KEYBOARD.min, Math.min(range.min, range.max));
51
+ let max = Math.min(FULL_KEYBOARD.max, Math.max(range.min, range.max));
52
+ while (min > FULL_KEYBOARD.min && isBlackKey(min))
43
53
  min -= 1;
44
- while (max < KEYBOARD_MAX_MIDI && isBlackKey(max))
54
+ while (max < FULL_KEYBOARD.max && isBlackKey(max))
45
55
  max += 1;
46
56
  // If clamping left an edge black (the very ends of the piano), step inward.
47
57
  while (isBlackKey(min) && min < max)
@@ -1 +1 @@
1
- {"version":3,"file":"keyboard-geometry.js","sourceRoot":"","sources":["../src/keyboard-geometry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keyboard-geometry.js","sourceRoot":"","sources":["../src/keyboard-geometry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,aAAa,GAEd,MAAM,yBAAyB,CAAC;AAejC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,UAAU,GAAkB,aAAa,CAAC;AAEvD,sDAAsD;AACtD,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC,GAAG,CAAC;AACnD,wBAAwB;AACxB,MAAM,CAAC,MAAM,iBAAiB,GAAG,aAAa,CAAC,GAAG,CAAC;AACnD,4EAA4E;AAC5E,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAElC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAAC,KAAoB;IAClD,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACtE,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IACtE,OAAO,GAAG,GAAG,aAAa,CAAC,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC;QAAE,GAAG,IAAI,CAAC,CAAC;IAC5D,OAAO,GAAG,GAAG,aAAa,CAAC,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC;QAAE,GAAG,IAAI,CAAC,CAAC;IAC5D,4EAA4E;IAC5E,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,GAAG;QAAE,GAAG,IAAI,CAAC,CAAC;IAC9C,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,GAAG;QAAE,GAAG,IAAI,CAAC,CAAC;IAC9C,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;AACtB,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,aAAa,CAAC,QAAuB,UAAU;IAC7D,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,IAAI,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,IAAI,KAAK,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC;QACrD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,KAAK,IAAI,CAAC,CAAC;IACpC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,CAAC;AAEtC,oDAAoD;AACpD,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AACzC,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAuC3C,sFAAsF;AACtF,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAWnC,8EAA8E;AAC9E,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,UAAU,GAAG,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;IAC3C,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AAC/C,CAAC;AAED,kIAAkI;AAClI,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,aAAa,CAC3B,aAAqB,EACrB,QAAuB,UAAU;IAEjC,OAAO,aAAa,CAAC,KAAK,CAAC,GAAG,aAAa,CAAC;AAC9C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,aAAqB,EACrB,cAAsB,EACtB,QAAuB,UAAU,EACjC,SAAoB,OAAO;IAE3B,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,MAAM,UAAU,GAAG,aAAa,GAAG,qBAAqB,CAAC;IACzD,MAAM,WAAW,GAAG,cAAc,GAAG,sBAAsB,CAAC;IAC5D,MAAM,KAAK,GAAG,MAAM,KAAK,YAAY,CAAC;IAEtC,2EAA2E;IAC3E,uEAAuE;IACvE,6CAA6C;IAC7C,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,IAAI,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,IAAI,KAAK,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC;QACxD,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,UAAU,GACd,KAAK,CAAC,UAAU,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC;QACvE,2EAA2E;QAC3E,2EAA2E;QAC3E,4CAA4C;QAC5C,MAAM,KAAK,GAAG,KAAK;YACjB,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC;YACrC,CAAC,CAAC,UAAU;gBACV,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC;gBACjB,CAAC,CAAC,IAAI,CAAC;QACX,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAE9D,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,OAAO,EAAE,IAAI;gBACb,CAAC,EAAE,UAAU,GAAG,aAAa,GAAG,UAAU,GAAG,CAAC;gBAC9C,KAAK,EAAE,UAAU;gBACjB,MAAM,EAAE,WAAW;gBACnB,sEAAsE;gBACtE,uEAAuE;gBACvE,8CAA8C;gBAC9C,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;gBAC3B,IAAI;gBACJ,2DAA2D;gBAC3D,QAAQ,EAAE,cAAc,GAAG,CAAC,GAAG,gBAAgB;aAChD,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,OAAO,EAAE,KAAK;gBACd,CAAC,EAAE,UAAU,GAAG,aAAa;gBAC7B,KAAK,EAAE,aAAa;gBACpB,MAAM,EAAE,cAAc;gBACtB,KAAK;gBACL,IAAI;gBACJ,QAAQ,EAAE,cAAc,GAAG,CAAC;aAC7B,CAAC,CAAC;YACH,UAAU,IAAI,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * What the keys are *called*, as against where they are.
3
+ *
4
+ * `keyboard-geometry.ts` answers where each key sits and names it from its own
5
+ * midi number — which is **sounding** pitch, because that is the one convention
6
+ * the model stores and the compass (`trackKeyboardRange`) is quoted in. That is
7
+ * right for everything except the one thing a reader compares a key against:
8
+ * the staff beside it, which in written-pitch mode is drawn through
9
+ * `writtenScore` and so disagrees with the keyboard by the instrument's
10
+ * interval.
11
+ *
12
+ * On a B-flat trumpet that disagreement is a whole tone, and it is silent: the
13
+ * key said `C4`, pressing it stored a sounding C4 — correctly, since the store
14
+ * holds sounding pitch — and the staff then drew the D4 the player reads. The
15
+ * note was right and the label was wrong, which is the worse of the two to
16
+ * debug because nothing about the score is broken.
17
+ *
18
+ * So the keys keep their sounding midi numbers — the audition, the lit keys
19
+ * during playback and the selected-chord marks are all keyed by it, and note
20
+ * entry stores it unconverted — and only the *labels* move. Press the key that
21
+ * reads `C4` and a C4 appears on the staff, because that key is the sounding
22
+ * B-flat 3 the trumpet writes as C.
23
+ *
24
+ * This is the same "one convention internally, converted at the edges" rule the
25
+ * inspector follows through `displayedPitchForNote`. The keyboard's edge is its
26
+ * lettering, so that is the only place the conversion belongs.
27
+ *
28
+ * A separate module from the geometry on purpose: nothing here is about
29
+ * position, and the geometry has no business knowing what a transposing
30
+ * instrument is.
31
+ */
32
+ import { type PitchDisplay, type Track } from '@sudobility/music_types';
33
+ import type { PianoKey } from './keyboard-geometry.js';
34
+ /**
35
+ * How far a keyboard's labels move for `track`, given what the staff is showing.
36
+ *
37
+ * Zero in concert-pitch mode, zero with no track, and zero on a percussion
38
+ * track — `trackWrittenTransposition` already answers the last of those, since
39
+ * a drum staff's positions name drums rather than places in a compass. That
40
+ * zero is what keeps a kit's key labels ("Cl HH", "Bass Drum") out of
41
+ * `relabelKeys`' hands.
42
+ */
43
+ export declare function keyboardLabelSemitones(track: Pick<Track, 'clef' | 'midiProgram'> | null | undefined, pitchDisplay: PitchDisplay): number;
44
+ /**
45
+ * `keys` lettered `semitones` away from what they sound.
46
+ *
47
+ * Returns the **identical array** at zero, which is every concert-pitch
48
+ * keyboard and every non-transposing instrument — the geometry is memoized on
49
+ * its inputs in both apps, and a fresh array per render would re-reconcile 88
50
+ * keys for nothing.
51
+ *
52
+ * Two things are deliberately left alone. Which keys carry a printed `label` is
53
+ * unchanged: those are the C and F landmarks of the black-key groups, and they
54
+ * are landmarks because of where they *are* — relabelling by written name would
55
+ * put the printed reference on a black key with no room for it. And the
56
+ * spelling stays sharp, like `noteLabel`'s, because a keyboard has no key
57
+ * signature to spell against; this moves a name by an interval, it does not
58
+ * respell a score.
59
+ */
60
+ export declare function relabelKeys(keys: PianoKey[], semitones: number): PianoKey[];
61
+ //# sourceMappingURL=keyboard-labels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyboard-labels.d.ts","sourceRoot":"","sources":["../src/keyboard-labels.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,KAAK,EACX,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAEvD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,GAAG,IAAI,GAAG,SAAS,EAC7D,YAAY,EAAE,YAAY,GACzB,MAAM,CAGR;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,EAAE,CAU3E"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * What the keys are *called*, as against where they are.
3
+ *
4
+ * `keyboard-geometry.ts` answers where each key sits and names it from its own
5
+ * midi number — which is **sounding** pitch, because that is the one convention
6
+ * the model stores and the compass (`trackKeyboardRange`) is quoted in. That is
7
+ * right for everything except the one thing a reader compares a key against:
8
+ * the staff beside it, which in written-pitch mode is drawn through
9
+ * `writtenScore` and so disagrees with the keyboard by the instrument's
10
+ * interval.
11
+ *
12
+ * On a B-flat trumpet that disagreement is a whole tone, and it is silent: the
13
+ * key said `C4`, pressing it stored a sounding C4 — correctly, since the store
14
+ * holds sounding pitch — and the staff then drew the D4 the player reads. The
15
+ * note was right and the label was wrong, which is the worse of the two to
16
+ * debug because nothing about the score is broken.
17
+ *
18
+ * So the keys keep their sounding midi numbers — the audition, the lit keys
19
+ * during playback and the selected-chord marks are all keyed by it, and note
20
+ * entry stores it unconverted — and only the *labels* move. Press the key that
21
+ * reads `C4` and a C4 appears on the staff, because that key is the sounding
22
+ * B-flat 3 the trumpet writes as C.
23
+ *
24
+ * This is the same "one convention internally, converted at the edges" rule the
25
+ * inspector follows through `displayedPitchForNote`. The keyboard's edge is its
26
+ * lettering, so that is the only place the conversion belongs.
27
+ *
28
+ * A separate module from the geometry on purpose: nothing here is about
29
+ * position, and the geometry has no business knowing what a transposing
30
+ * instrument is.
31
+ */
32
+ import { midiToPitch, pitchToString, trackWrittenTransposition, } from '@sudobility/music_types';
33
+ /**
34
+ * How far a keyboard's labels move for `track`, given what the staff is showing.
35
+ *
36
+ * Zero in concert-pitch mode, zero with no track, and zero on a percussion
37
+ * track — `trackWrittenTransposition` already answers the last of those, since
38
+ * a drum staff's positions name drums rather than places in a compass. That
39
+ * zero is what keeps a kit's key labels ("Cl HH", "Bass Drum") out of
40
+ * `relabelKeys`' hands.
41
+ */
42
+ export function keyboardLabelSemitones(track, pitchDisplay) {
43
+ if (!track || pitchDisplay !== 'written')
44
+ return 0;
45
+ return trackWrittenTransposition(track);
46
+ }
47
+ /**
48
+ * `keys` lettered `semitones` away from what they sound.
49
+ *
50
+ * Returns the **identical array** at zero, which is every concert-pitch
51
+ * keyboard and every non-transposing instrument — the geometry is memoized on
52
+ * its inputs in both apps, and a fresh array per render would re-reconcile 88
53
+ * keys for nothing.
54
+ *
55
+ * Two things are deliberately left alone. Which keys carry a printed `label` is
56
+ * unchanged: those are the C and F landmarks of the black-key groups, and they
57
+ * are landmarks because of where they *are* — relabelling by written name would
58
+ * put the printed reference on a black key with no room for it. And the
59
+ * spelling stays sharp, like `noteLabel`'s, because a keyboard has no key
60
+ * signature to spell against; this moves a name by an interval, it does not
61
+ * respell a score.
62
+ */
63
+ export function relabelKeys(keys, semitones) {
64
+ if (semitones === 0)
65
+ return keys;
66
+ return keys.map(key => {
67
+ const written = pitchToString(midiToPitch(key.midi + semitones));
68
+ return {
69
+ ...key,
70
+ label: key.label === null ? null : written,
71
+ name: written,
72
+ };
73
+ });
74
+ }
75
+ //# sourceMappingURL=keyboard-labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyboard-labels.js","sourceRoot":"","sources":["../src/keyboard-labels.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EACL,WAAW,EACX,aAAa,EACb,yBAAyB,GAG1B,MAAM,yBAAyB,CAAC;AAGjC;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CACpC,KAA6D,EAC7D,YAA0B;IAE1B,IAAI,CAAC,KAAK,IAAI,YAAY,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC;IACnD,OAAO,yBAAyB,CAAC,KAAK,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,WAAW,CAAC,IAAgB,EAAE,SAAiB;IAC7D,IAAI,SAAS,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QACpB,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC;QACjE,OAAO;YACL,GAAG,GAAG;YACN,KAAK,EAAE,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO;YAC1C,IAAI,EAAE,OAAO;SACd,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"note-color.d.ts","sourceRoot":"","sources":["../src/note-color.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAkB7D;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,SAAS,GACzD,aAAa,CAUf;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAE1E;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,WAAW,EAClB,aAAa,UAAO,GACnB,MAAM,CAWR"}
1
+ {"version":3,"file":"note-color.d.ts","sourceRoot":"","sources":["../src/note-color.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAwB7D;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,SAAS,GACzD,aAAa,CAUf;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,aAAa,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAE1E;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,WAAW,EAClB,aAAa,UAAO,GACnB,MAAM,CAaR"}
@@ -6,11 +6,17 @@
6
6
  * Pressing play clears the selection, so `playing` and `selected` do not
7
7
  * normally coexist — this ordering only resolves the case where the user
8
8
  * selects notes while playback is already running.
9
+ *
10
+ * `outOfRange` sits below all three and above `normal`: it is a property of
11
+ * the music rather than something the reader just did, so selecting a note the
12
+ * instrument cannot play still reads as selected — but an unselected one has
13
+ * to be visible, or the mark is worth nothing.
9
14
  */
10
15
  const PRECEDENCE = [
11
16
  'playing',
12
17
  'regenerated',
13
18
  'selected',
19
+ 'outOfRange',
14
20
  'normal',
15
21
  ];
16
22
  /**
@@ -74,6 +80,8 @@ export function noteColorFor(role, theme, onActiveTrack = true) {
74
80
  return theme.noteRegenerated;
75
81
  case 'selected':
76
82
  return theme.noteSelected;
83
+ case 'outOfRange':
84
+ return theme.noteOutOfRange;
77
85
  case 'normal':
78
86
  return onActiveTrack ? theme.noteNormal : theme.noteInactive;
79
87
  }
@@ -1 +1 @@
1
- {"version":3,"file":"note-color.js","sourceRoot":"","sources":["../src/note-color.ts"],"names":[],"mappings":"AAOA;;;;;;;;GAQG;AACH,MAAM,UAAU,GAA6B;IAC3C,SAAS;IACT,aAAa;IACb,UAAU;IACV,QAAQ;CACT,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAA2B,EAC3B,UAA0D;IAE1D,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC1D,IAAI,IAAI,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;IACjC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,GAAG,IAAI;YAAE,IAAI,GAAG,IAAI,CAAC;IAC9C,CAAC;IACD,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,eAAe,CAAC,IAAmB;IACjD,OAAO,EAAE,SAAS,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;AACpD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAmB,EACnB,KAAkB,EAClB,aAAa,GAAG,IAAI;IAEpB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,WAAW,CAAC;QAC3B,KAAK,aAAa;YAChB,OAAO,KAAK,CAAC,eAAe,CAAC;QAC/B,KAAK,UAAU;YACb,OAAO,KAAK,CAAC,YAAY,CAAC;QAC5B,KAAK,QAAQ;YACX,OAAO,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;IACjE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"note-color.js","sourceRoot":"","sources":["../src/note-color.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,GAA6B;IAC3C,SAAS;IACT,aAAa;IACb,UAAU;IACV,YAAY;IACZ,QAAQ;CACT,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAA2B,EAC3B,UAA0D;IAE1D,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC1D,IAAI,IAAI,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;IACjC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,GAAG,IAAI;YAAE,IAAI,GAAG,IAAI,CAAC;IAC9C,CAAC;IACD,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,eAAe,CAAC,IAAmB;IACjD,OAAO,EAAE,SAAS,EAAE,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;AACpD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAmB,EACnB,KAAkB,EAClB,aAAa,GAAG,IAAI;IAEpB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,SAAS;YACZ,OAAO,KAAK,CAAC,WAAW,CAAC;QAC3B,KAAK,aAAa;YAChB,OAAO,KAAK,CAAC,eAAe,CAAC;QAC/B,KAAK,UAAU;YACb,OAAO,KAAK,CAAC,YAAY,CAAC;QAC5B,KAAK,YAAY;YACf,OAAO,KAAK,CAAC,cAAc,CAAC;QAC9B,KAAK,QAAQ;YACX,OAAO,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC;IACjE,CAAC;AACH,CAAC"}
@@ -21,12 +21,22 @@ import type { NoteColorRole } from './types.js';
21
21
  export type BuildNoteColorsParams = {
22
22
  selectedIds: readonly string[];
23
23
  playingIds: readonly string[];
24
+ /**
25
+ * Notes the instrument cannot play, outside its measured compass.
26
+ *
27
+ * Written FIRST, so anything the reader did — selecting, regenerating,
28
+ * playing — paints over it. A note being unplayable is a property of the
29
+ * music and keeps; a selection is what they are doing right now.
30
+ */
31
+ outOfRangeIds?: readonly string[];
24
32
  /** When true, selected notes colour as `regenerated` rather than `selected`. */
25
33
  regenerated: boolean;
26
34
  };
27
- export declare function buildNoteColors({ selectedIds, playingIds, regenerated, }: BuildNoteColorsParams): Map<string, NoteColorRole>;
35
+ export declare function buildNoteColors({ selectedIds, playingIds, outOfRangeIds, regenerated, }: BuildNoteColorsParams): Map<string, NoteColorRole>;
28
36
  export type NoteColorsForParams = {
29
37
  selectedIds: readonly string[];
38
+ /** Notes outside their instrument's measured compass. */
39
+ outOfRangeIds?: readonly string[];
30
40
  /** What the engine reports as sounding right now, across every track. */
31
41
  sounding: readonly SoundingNote[];
32
42
  /**
@@ -51,5 +61,5 @@ export type NoteColorsForParams = {
51
61
  * being read goes dark whenever it rests. The piano keyboard already showed
52
62
  * the active track alone, and this is what makes the notation agree with it.
53
63
  */
54
- export declare function noteColorsFor({ selectedIds, sounding, activeTrackId, regenerated, }: NoteColorsForParams): Map<string, NoteColorRole>;
64
+ export declare function noteColorsFor({ selectedIds, outOfRangeIds, sounding, activeTrackId, regenerated, }: NoteColorsForParams): Map<string, NoteColorRole>;
55
65
  //# sourceMappingURL=note-colors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"note-colors.d.ts","sourceRoot":"","sources":["../src/note-colors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,MAAM,qBAAqB,GAAG;IAClC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,gFAAgF;IAChF,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAC9B,WAAW,EACX,UAAU,EACV,WAAW,GACZ,EAAE,qBAAqB,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAMpD;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,yEAAyE;IACzE,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAClC;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAC5B,WAAW,EACX,QAAQ,EACR,aAAa,EACb,WAAW,GACZ,EAAE,mBAAmB,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAQlD"}
1
+ {"version":3,"file":"note-colors.d.ts","sourceRoot":"","sources":["../src/note-colors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,MAAM,qBAAqB,GAAG;IAClC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,gFAAgF;IAChF,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF,wBAAgB,eAAe,CAAC,EAC9B,WAAW,EACX,UAAU,EACV,aAAa,EACb,WAAW,GACZ,EAAE,qBAAqB,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAOpD;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,yDAAyD;IACzD,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,yEAAyE;IACzE,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAClC;;;;;;OAMG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,EAC5B,WAAW,EACX,aAAa,EACb,QAAQ,EACR,aAAa,EACb,WAAW,GACZ,EAAE,mBAAmB,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CASlD"}
@@ -1,6 +1,8 @@
1
- export function buildNoteColors({ selectedIds, playingIds, regenerated, }) {
1
+ export function buildNoteColors({ selectedIds, playingIds, outOfRangeIds, regenerated, }) {
2
2
  const colors = new Map();
3
3
  const selectedRole = regenerated ? 'regenerated' : 'selected';
4
+ for (const id of outOfRangeIds ?? [])
5
+ colors.set(id, 'outOfRange');
4
6
  for (const id of selectedIds)
5
7
  colors.set(id, selectedRole);
6
8
  for (const id of playingIds)
@@ -19,9 +21,10 @@ export function buildNoteColors({ selectedIds, playingIds, regenerated, }) {
19
21
  * being read goes dark whenever it rests. The piano keyboard already showed
20
22
  * the active track alone, and this is what makes the notation agree with it.
21
23
  */
22
- export function noteColorsFor({ selectedIds, sounding, activeTrackId, regenerated, }) {
24
+ export function noteColorsFor({ selectedIds, outOfRangeIds, sounding, activeTrackId, regenerated, }) {
23
25
  return buildNoteColors({
24
26
  selectedIds,
27
+ ...(outOfRangeIds ? { outOfRangeIds } : {}),
25
28
  playingIds: sounding
26
29
  .filter(note => note.trackId === activeTrackId)
27
30
  .map(note => note.noteId),
@@ -1 +1 @@
1
- {"version":3,"file":"note-colors.js","sourceRoot":"","sources":["../src/note-colors.ts"],"names":[],"mappings":"AA4BA,MAAM,UAAU,eAAe,CAAC,EAC9B,WAAW,EACX,UAAU,EACV,WAAW,GACW;IACtB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAChD,MAAM,YAAY,GAAkB,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC;IAC7E,KAAK,MAAM,EAAE,IAAI,WAAW;QAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;IAC3D,KAAK,MAAM,EAAE,IAAI,UAAU;QAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IACvD,OAAO,MAAM,CAAC;AAChB,CAAC;AAiBD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,WAAW,EACX,QAAQ,EACR,aAAa,EACb,WAAW,GACS;IACpB,OAAO,eAAe,CAAC;QACrB,WAAW;QACX,UAAU,EAAE,QAAQ;aACjB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,aAAa,CAAC;aAC9C,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;QAC3B,WAAW;KACZ,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"note-colors.js","sourceRoot":"","sources":["../src/note-colors.ts"],"names":[],"mappings":"AAoCA,MAAM,UAAU,eAAe,CAAC,EAC9B,WAAW,EACX,UAAU,EACV,aAAa,EACb,WAAW,GACW;IACtB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAChD,MAAM,YAAY,GAAkB,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC;IAC7E,KAAK,MAAM,EAAE,IAAI,aAAa,IAAI,EAAE;QAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;IACnE,KAAK,MAAM,EAAE,IAAI,WAAW;QAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,YAAY,CAAC,CAAC;IAC3D,KAAK,MAAM,EAAE,IAAI,UAAU;QAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IACvD,OAAO,MAAM,CAAC;AAChB,CAAC;AAmBD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,WAAW,EACX,aAAa,EACb,QAAQ,EACR,aAAa,EACb,WAAW,GACS;IACpB,OAAO,eAAe,CAAC;QACrB,WAAW;QACX,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,UAAU,EAAE,QAAQ;aACjB,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,KAAK,aAAa,CAAC;aAC9C,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;QAC3B,WAAW;KACZ,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Notes an instrument cannot play, found in a score that already holds them.
3
+ *
4
+ * Here rather than in an app for the reason `note-colors.ts` beside it gives:
5
+ * two apps draw this score, and "which notes are lit, and why" having two
6
+ * answers is how the native app came to light nothing at all during playback.
7
+ *
8
+ * The compass lives in one place — `gm-catalogue.ts`, reached through
9
+ * `trackKeyboardRange` — and three of the four surfaces that care already read
10
+ * it: the keyboard shows exactly that span, generation now states it in the
11
+ * prompt, and `inspect.ts` judges a generated part against it. The notation is
12
+ * the exception, by design: it draws what the score holds, because a score is
13
+ * not only ever a generated one.
14
+ *
15
+ * That is the disagreement a reader actually meets. A timpani part written a
16
+ * fifth below its lowest drum draws perfectly well on the stave and cannot
17
+ * light a single key on the keyboard — measured on one project, 482 of 1,067
18
+ * notes. Nothing here rewrites those notes: they are marked, and moving them
19
+ * by an octave is a musical decision that belongs to the person reading, not
20
+ * to a scan.
21
+ *
22
+ * Gated on `trackRangeIsBinding`, the same condition the server applies, so the
23
+ * page and the server cannot disagree about what counts as out of range. A
24
+ * compass nobody verified marks nothing.
25
+ *
26
+ * ## Sounding pitch, and so the STORED score
27
+ *
28
+ * Every number in `gm-catalogue.ts` is sounding pitch, and `midiIsInRange` is
29
+ * documented as taking one. The score this package *draws* is not: the app
30
+ * hands `render` a `displayScore(score, pitchDisplay)`, which in written mode
31
+ * has moved a B-flat clarinet up a tone and, in every mode, has moved an
32
+ * `8va`'s noteheads down an octave. Scanning that would place a clarinet's
33
+ * whole part a tone above where it sounds and mark the top of it wrongly.
34
+ *
35
+ * So this takes the **stored** score — the one the app holds, before the
36
+ * lenses — and the result stays correct in either display mode because it is
37
+ * expressed as event **ids**, which both lenses preserve: `transposeEvents`
38
+ * and `ottavaScore` spread `...event` and replace only `pitch`. The renderer
39
+ * colours by id, so "which notes" survives a transposition that changes what
40
+ * those notes look like. `out-of-range.test.ts` pins that with a clarinet.
41
+ */
42
+ import { type MidiRange, type Score } from '@sudobility/music_types';
43
+ export type OutOfRangeTrack = {
44
+ trackId: string;
45
+ name: string;
46
+ /** What the instrument can play. */
47
+ compass: MidiRange;
48
+ /** How many notes fall outside it. */
49
+ count: number;
50
+ /** The distinct pitches that do, lowest first. */
51
+ midis: number[];
52
+ };
53
+ export type OutOfRangeScan = {
54
+ /** Every offending note id, for the notation's colours. */
55
+ ids: string[];
56
+ /** One entry per track that has any, for the inspector's sentence. */
57
+ byTrack: OutOfRangeTrack[];
58
+ };
59
+ /**
60
+ * Every note `score` holds that its own instrument cannot play.
61
+ *
62
+ * `score` is the **stored** score — sounding pitch, before `displayScore`. Do
63
+ * not pass the score handed to `render`; see this module's doc for why, and
64
+ * why the ids come back usable in either display mode anyway.
65
+ */
66
+ export declare function outOfRangeNoteIds(score: Score | null): OutOfRangeScan;
67
+ //# sourceMappingURL=out-of-range.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"out-of-range.d.ts","sourceRoot":"","sources":["../src/out-of-range.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EAOL,KAAK,SAAS,EACd,KAAK,KAAK,EACX,MAAM,yBAAyB,CAAC;AAEjC,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,OAAO,EAAE,SAAS,CAAC;IACnB,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,2DAA2D;IAC3D,GAAG,EAAE,MAAM,EAAE,CAAC;IACd,sEAAsE;IACtE,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B,CAAC;AAIF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,cAAc,CAiDrE"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Notes an instrument cannot play, found in a score that already holds them.
3
+ *
4
+ * Here rather than in an app for the reason `note-colors.ts` beside it gives:
5
+ * two apps draw this score, and "which notes are lit, and why" having two
6
+ * answers is how the native app came to light nothing at all during playback.
7
+ *
8
+ * The compass lives in one place — `gm-catalogue.ts`, reached through
9
+ * `trackKeyboardRange` — and three of the four surfaces that care already read
10
+ * it: the keyboard shows exactly that span, generation now states it in the
11
+ * prompt, and `inspect.ts` judges a generated part against it. The notation is
12
+ * the exception, by design: it draws what the score holds, because a score is
13
+ * not only ever a generated one.
14
+ *
15
+ * That is the disagreement a reader actually meets. A timpani part written a
16
+ * fifth below its lowest drum draws perfectly well on the stave and cannot
17
+ * light a single key on the keyboard — measured on one project, 482 of 1,067
18
+ * notes. Nothing here rewrites those notes: they are marked, and moving them
19
+ * by an octave is a musical decision that belongs to the person reading, not
20
+ * to a scan.
21
+ *
22
+ * Gated on `trackRangeIsBinding`, the same condition the server applies, so the
23
+ * page and the server cannot disagree about what counts as out of range. A
24
+ * compass nobody verified marks nothing.
25
+ *
26
+ * ## Sounding pitch, and so the STORED score
27
+ *
28
+ * Every number in `gm-catalogue.ts` is sounding pitch, and `midiIsInRange` is
29
+ * documented as taking one. The score this package *draws* is not: the app
30
+ * hands `render` a `displayScore(score, pitchDisplay)`, which in written mode
31
+ * has moved a B-flat clarinet up a tone and, in every mode, has moved an
32
+ * `8va`'s noteheads down an octave. Scanning that would place a clarinet's
33
+ * whole part a tone above where it sounds and mark the top of it wrongly.
34
+ *
35
+ * So this takes the **stored** score — the one the app holds, before the
36
+ * lenses — and the result stays correct in either display mode because it is
37
+ * expressed as event **ids**, which both lenses preserve: `transposeEvents`
38
+ * and `ottavaScore` spread `...event` and replace only `pitch`. The renderer
39
+ * colours by id, so "which notes" survives a transposition that changes what
40
+ * those notes look like. `out-of-range.test.ts` pins that with a clarinet.
41
+ */
42
+ import { isNoteEvent, isPercussionTrack, midiIsInRange, pitchToMidi, trackKeyboardRange, trackRangeIsBinding, } from '@sudobility/music_types';
43
+ const EMPTY = { ids: [], byTrack: [] };
44
+ /**
45
+ * Every note `score` holds that its own instrument cannot play.
46
+ *
47
+ * `score` is the **stored** score — sounding pitch, before `displayScore`. Do
48
+ * not pass the score handed to `render`; see this module's doc for why, and
49
+ * why the ids come back usable in either display mode anyway.
50
+ */
51
+ export function outOfRangeNoteIds(score) {
52
+ if (!score)
53
+ return EMPTY;
54
+ const ids = [];
55
+ const byTrack = [];
56
+ for (const track of score.tracks) {
57
+ /*
58
+ * A drum pitch names a drum rather than a place in a compass, so this test
59
+ * comes FIRST and is not folded into the gate below it.
60
+ *
61
+ * `trackRangeIsBinding` answers **true** for percussion on purpose — a kit
62
+ * has the pieces it has, which is the right answer for note entry and for
63
+ * generation, where refusing an address no drum sits at is a service. It is
64
+ * the wrong answer here: `percussion.ts` already handles a drum outside
65
+ * `GM_PERCUSSION_RANGE` by parking it on the middle line as `UNMAPPED`, and
66
+ * colouring it as well would be two marks for one fact.
67
+ */
68
+ if (isPercussionTrack(track))
69
+ continue;
70
+ if (!trackRangeIsBinding(track))
71
+ continue;
72
+ const compass = trackKeyboardRange(track);
73
+ const midis = new Set();
74
+ let count = 0;
75
+ for (const measure of track.measures) {
76
+ for (const voice of measure.voices) {
77
+ for (const event of voice.events) {
78
+ if (!isNoteEvent(event))
79
+ continue;
80
+ const midi = pitchToMidi(event.pitch);
81
+ if (midiIsInRange(midi, compass))
82
+ continue;
83
+ ids.push(event.id);
84
+ midis.add(midi);
85
+ count += 1;
86
+ }
87
+ }
88
+ }
89
+ if (count > 0) {
90
+ byTrack.push({
91
+ trackId: track.id,
92
+ name: track.name,
93
+ compass,
94
+ count,
95
+ midis: [...midis].sort((a, b) => a - b),
96
+ });
97
+ }
98
+ }
99
+ return ids.length > 0 ? { ids, byTrack } : EMPTY;
100
+ }
101
+ //# sourceMappingURL=out-of-range.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"out-of-range.js","sourceRoot":"","sources":["../src/out-of-range.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,mBAAmB,GAGpB,MAAM,yBAAyB,CAAC;AAoBjC,MAAM,KAAK,GAAmB,EAAE,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AAEvD;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAmB;IACnD,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,OAAO,GAAsB,EAAE,CAAC;IAEtC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC;;;;;;;;;;WAUG;QACH,IAAI,iBAAiB,CAAC,KAAK,CAAC;YAAE,SAAS;QACvC,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC;YAAE,SAAS;QAE1C,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;QAChC,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACrC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;oBACjC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;wBAAE,SAAS;oBAClC,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;oBACtC,IAAI,aAAa,CAAC,IAAI,EAAE,OAAO,CAAC;wBAAE,SAAS;oBAC3C,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;oBACnB,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAChB,KAAK,IAAI,CAAC,CAAC;gBACb,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC;gBACX,OAAO,EAAE,KAAK,CAAC,EAAE;gBACjB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO;gBACP,KAAK;gBACL,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;aACxC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;AACnD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"render-theme.d.ts","sourceRoot":"","sources":["../src/render-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,eAAO,MAAM,kBAAkB,EAAE,WAUhC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,WAU/B,CAAC"}
1
+ {"version":3,"file":"render-theme.d.ts","sourceRoot":"","sources":["../src/render-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,eAAO,MAAM,kBAAkB,EAAE,WAWhC,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,WAW/B,CAAC"}
@@ -5,6 +5,7 @@ export const LIGHT_RENDER_THEME = {
5
5
  noteSelected: '#6d28d9',
6
6
  noteRegenerated: '#8b5a2b',
7
7
  notePlaying: '#1565c0',
8
+ noteOutOfRange: '#c2185b',
8
9
  staveActive: '#000000',
9
10
  staveInactive: '#71717a',
10
11
  caret: '#d32f2f',
@@ -16,6 +17,7 @@ export const DARK_RENDER_THEME = {
16
17
  noteSelected: '#a78bfa',
17
18
  noteRegenerated: '#d9a066',
18
19
  notePlaying: '#64b5f6',
20
+ noteOutOfRange: '#f06292',
19
21
  staveActive: '#ffffff',
20
22
  staveInactive: '#8a8a93',
21
23
  caret: '#ef5350',
@@ -1 +1 @@
1
- {"version":3,"file":"render-theme.js","sourceRoot":"","sources":["../src/render-theme.ts"],"names":[],"mappings":"AA4BA,MAAM,CAAC,MAAM,kBAAkB,GAAgB;IAC7C,UAAU,EAAE,SAAS;IACrB,UAAU,EAAE,SAAS;IACrB,YAAY,EAAE,SAAS;IACvB,YAAY,EAAE,SAAS;IACvB,eAAe,EAAE,SAAS;IAC1B,WAAW,EAAE,SAAS;IACtB,WAAW,EAAE,SAAS;IACtB,aAAa,EAAE,SAAS;IACxB,KAAK,EAAE,SAAS;CACjB,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAgB;IAC5C,UAAU,EAAE,SAAS;IACrB,UAAU,EAAE,SAAS;IACrB,YAAY,EAAE,SAAS;IACvB,YAAY,EAAE,SAAS;IACvB,eAAe,EAAE,SAAS;IAC1B,WAAW,EAAE,SAAS;IACtB,WAAW,EAAE,SAAS;IACtB,aAAa,EAAE,SAAS;IACxB,KAAK,EAAE,SAAS;CACjB,CAAC"}
1
+ {"version":3,"file":"render-theme.js","sourceRoot":"","sources":["../src/render-theme.ts"],"names":[],"mappings":"AA4BA,MAAM,CAAC,MAAM,kBAAkB,GAAgB;IAC7C,UAAU,EAAE,SAAS;IACrB,UAAU,EAAE,SAAS;IACrB,YAAY,EAAE,SAAS;IACvB,YAAY,EAAE,SAAS;IACvB,eAAe,EAAE,SAAS;IAC1B,WAAW,EAAE,SAAS;IACtB,cAAc,EAAE,SAAS;IACzB,WAAW,EAAE,SAAS;IACtB,aAAa,EAAE,SAAS;IACxB,KAAK,EAAE,SAAS;CACjB,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAgB;IAC5C,UAAU,EAAE,SAAS;IACrB,UAAU,EAAE,SAAS;IACrB,YAAY,EAAE,SAAS;IACvB,YAAY,EAAE,SAAS;IACvB,eAAe,EAAE,SAAS;IAC1B,WAAW,EAAE,SAAS;IACtB,cAAc,EAAE,SAAS;IACzB,WAAW,EAAE,SAAS;IACtB,aAAa,EAAE,SAAS;IACxB,KAAK,EAAE,SAAS;CACjB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../src/test/fixtures.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,8BAA8B,CAAC;AAc7C,OAAO,KAAK,EAAsB,KAAK,EAAS,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAgB,eAAe,IAAI,WAAW,CAY7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,YAAY,SAAK,GAAG,KAAK,CAuFlD"}
1
+ {"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../src/test/fixtures.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,8BAA8B,CAAC;AAc7C,OAAO,KAAK,EAAsB,KAAK,EAAS,MAAM,yBAAyB,CAAC;AAChF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;GAMG;AACH,wBAAgB,eAAe,IAAI,WAAW,CAa7C;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,YAAY,SAAK,GAAG,KAAK,CAuFlD"}
@@ -25,6 +25,7 @@ export function testRenderTheme() {
25
25
  noteSelected: '#333333',
26
26
  noteRegenerated: '#444444',
27
27
  notePlaying: '#555555',
28
+ noteOutOfRange: '#999999',
28
29
  staveActive: '#666666',
29
30
  staveInactive: '#777777',
30
31
  caret: '#888888',
@@ -1 +1 @@
1
- {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../src/test/fixtures.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../src/test/fixtures.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,8BAA8B,CAAC;AAE7C,OAAO,EACL,oBAAoB,EACpB,WAAW,EACX,QAAQ,GACT,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,OAAO,EACP,eAAe,EACf,SAAS,EACT,aAAa,EACb,YAAY,GACb,MAAM,8BAA8B,CAAC;AAItC;;;;;;GAMG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL,UAAU,EAAE,SAAS;QACrB,UAAU,EAAE,SAAS;QACrB,YAAY,EAAE,SAAS;QACvB,YAAY,EAAE,SAAS;QACvB,eAAe,EAAE,SAAS;QAC1B,WAAW,EAAE,SAAS;QACtB,cAAc,EAAE,SAAS;QACzB,WAAW,EAAE,SAAS;QACtB,aAAa,EAAE,SAAS;QACxB,KAAK,EAAE,SAAS;KACjB,CAAC;AACJ,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CAAC,YAAY,GAAG,EAAE;IACzC,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;IAC5B,MAAM,GAAG,GAAG,GAAG,CAAC;IAChB,MAAM,YAAY,GAAG,oBAAoB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,WAAW,CAAC;IAE1B,MAAM,MAAM,GAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;QACrC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,MAAM,SAAS,GAAG,CAAC,GAAG,YAAY,CAAC;YACnC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAClC,MAAM,MAAM,GAAgB,EAAE,CAAC;YAC/B,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC;gBACvC,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,CAAC;gBAC9B,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,CAAC;gBAC/B,mEAAmE;gBACnE,sEAAsE;gBACtE,2DAA2D;gBAC3D,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;gBACnB,MAAM,CAAC,IAAI,CAAC;oBACV,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;oBACpB,kEAAkE;oBAClE,yDAAyD;oBACzD,KAAK,EAAE,YAAY,CACjB,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,EACvD,CAAC,CACF;oBACD,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,YAAY;oBAC1C,aAAa,EAAE,YAAY;oBAC3B,QAAQ,EAAE,EAAE;oBACZ,OAAO;oBACP,OAAO;oBACP,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACvD,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,WAAW,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAChE,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACxD,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,WAAW,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACjE,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,UAAU;wBAC1B,CAAC,CAAC,EAAE,YAAY,EAAE,WAAoB,EAAE;wBACxC,CAAC,CAAC,EAAE,CAAC;oBACP,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,WAAW,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACpE,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACpE,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,WAAW,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACnE,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC7D,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,WAAW,IAAI,CAAC,GAAG,CAAC;wBACpC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE;wBACzB,CAAC,CAAC,EAAE,CAAC;iBACR,CAAC,CAAC;YACL,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC;gBACZ,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;gBACvB,KAAK,EAAE,CAAC;gBACR,SAAS;gBACT,aAAa,EAAE,YAAY;gBAC3B,aAAa,EAAE,SAAS;gBACxB,YAAY,EAAE,OAAO;gBACrB,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;aACnD,CAAC,CAAC;QACL,CAAC;QACD,OAAO;YACL,EAAE,EAAE,OAAO;YACX,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE;YACrB,cAAc,EAAE,OAAO;YACvB,WAAW,EAAE,CAAC;YACd,WAAW,EAAE,CAAC;YACd,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,QAAkB,CAAC,CAAC,CAAE,MAAgB;YACvD,MAAM,EAAE,CAAC;YACT,GAAG,EAAE,CAAC;YACN,KAAK,EAAE,KAAK;YACZ,IAAI,EAAE,KAAK;YACX,QAAQ;SACT,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC;QACrB,OAAO,EAAE,CAAC;QACV,GAAG;QACH,QAAQ,EAAE;YACR,KAAK,EAAE,OAAO;YACd,SAAS,EAAE,eAAe;YAC1B,SAAS,EAAE,eAAe;SAC3B;QACD,QAAQ,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;QACxD,MAAM;KACP,CAAC;AACJ,CAAC"}
package/dist/types.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  * them rather than by editing their fields.
7
7
  */
8
8
  /** How a note is colored, by state. See `note-color.ts`'s `resolveNoteColorRole` for precedence. */
9
- export type NoteColorRole = 'normal' | 'selected' | 'regenerated' | 'playing';
9
+ export type NoteColorRole = 'normal' | 'selected' | 'regenerated' | 'playing' | 'outOfRange';
10
10
  export type RenderMode = 'screen' | 'print';
11
11
  type RenderDisplayOptions = {
12
12
  renderMode?: RenderMode;
@@ -48,6 +48,18 @@ export type RenderTheme = {
48
48
  noteSelected: string;
49
49
  noteRegenerated: string;
50
50
  notePlaying: string;
51
+ /**
52
+ * A note the instrument cannot play — outside its compass in
53
+ * `gm-catalogue.ts`, on a program whose compass was actually measured.
54
+ *
55
+ * The notation is the one surface that will draw anything it is given: the
56
+ * keyboard knows the compass and simply cannot light such a note, which is
57
+ * what made a timpani part written a fifth too low invisible until somebody
58
+ * compared the two. Colour rather than an overlay, because every other note
59
+ * state here is colour and a second mechanism would be a second thing to
60
+ * reason about.
61
+ */
62
+ noteOutOfRange: string;
51
63
  /**
52
64
  * Large translucent fill behind a selected measure. Defaults to
53
65
  * `noteSelected` for existing callers, but can be softer than the selected
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,oGAAoG;AACpG,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,CAAC;AAE9E,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE5C,KAAK,oBAAoB,GAAG;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,UAAU,CAIvE;AAED,yEAAyE;AACzE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAE1E;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;OAUG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,oHAAoH;IACpH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,uCAAuC;AACvC,eAAO,MAAM,SAAS,YAAY,CAAC;AAEnC;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,EAAE,WAYzC,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,0BAA0B,EAAE,WAYxC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,iCAAkC,CAAC;AAE5D,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,MAAM,MAAM,aAAa,GAAG;IAC1B,gGAAgG;IAChG,IAAI,EAAE,MAAM,CAAC;IACb,mGAAmG;IACnG,UAAU,EAAE,UAAU,CAAC;IACvB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,kGAAkG;IAClG,KAAK,EAAE,MAAM,CAAC;IACd,sHAAsH;IACtH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAChD,sGAAsG;IACtG,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,4IAA4I;IAC5I,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACzC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,EAAE,WAAW,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,oGAAoG;AACpG,MAAM,MAAM,aAAa,GACvB,QAAQ,GAAG,UAAU,GAAG,aAAa,GAAG,SAAS,GAAG,YAAY,CAAC;AAEnE,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE5C,KAAK,oBAAoB,GAAG;IAC1B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,UAAU,CAIvE;AAED,yEAAyE;AACzE,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAE1E;AAED;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,CAAC;IACnB,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;OAUG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;;;;OAUG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,mDAAmD;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,oHAAoH;IACpH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,uCAAuC;AACvC,eAAO,MAAM,SAAS,YAAY,CAAC;AAEnC;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,EAAE,WAazC,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,0BAA0B,EAAE,WAkBxC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,iCAAkC,CAAC;AAE5D,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,MAAM,MAAM,aAAa,GAAG;IAC1B,gGAAgG;IAChG,IAAI,EAAE,MAAM,CAAC;IACb,mGAAmG;IACnG,UAAU,EAAE,UAAU,CAAC;IACvB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,kGAAkG;IAClG,KAAK,EAAE,MAAM,CAAC;IACd,sHAAsH;IACtH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAChD,sGAAsG;IACtG,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,4IAA4I;IAC5I,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACzC;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,EAAE,WAAW,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,IAAI,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC"}
package/dist/types.js CHANGED
@@ -33,6 +33,7 @@ export const DEFAULT_SCREEN_RENDER_THEME = {
33
33
  noteSelected: '#050816',
34
34
  noteRegenerated: '#2563eb',
35
35
  notePlaying: '#0f766e',
36
+ noteOutOfRange: '#b91c1c',
36
37
  measureSelection: '#f59e0b',
37
38
  staveActive: '#64748b',
38
39
  staveInactive: '#c3ccd8',
@@ -47,6 +48,12 @@ export const DEFAULT_PRINT_RENDER_THEME = {
47
48
  noteSelected: PRINT_INK,
48
49
  noteRegenerated: PRINT_INK,
49
50
  notePlaying: PRINT_INK,
51
+ /*
52
+ Ink on paper, like every other state here: a printed part has no compass
53
+ warning to give, and a grey note among black ones reads as a mistake in
54
+ the printing rather than in the music.
55
+ */
56
+ noteOutOfRange: PRINT_INK,
50
57
  measureSelection: PRINT_INK,
51
58
  staveActive: PRINT_INK,
52
59
  staveInactive: PRINT_INK,
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,OAA6B;IACzD,OAAO,CACL,OAAO,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAC7E,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,mBAAmB,CAAC,OAA6B;IAC/D,OAAO,OAAO,CAAC,aAAa,IAAI,aAAa,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;AACtE,CAAC;AAiDD,uCAAuC;AACvC,MAAM,CAAC,MAAM,SAAS,GAAG,SAAS,CAAC;AAEnC;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAgB;IACtD,UAAU,EAAE,SAAS;IACrB,UAAU,EAAE,SAAS;IACrB,YAAY,EAAE,SAAS;IACvB,YAAY,EAAE,SAAS;IACvB,eAAe,EAAE,SAAS;IAC1B,WAAW,EAAE,SAAS;IACtB,gBAAgB,EAAE,SAAS;IAC3B,WAAW,EAAE,SAAS;IACtB,aAAa,EAAE,SAAS;IACxB,KAAK,EAAE,SAAS;IAChB,eAAe,EAAE,SAAS;CAC3B,CAAC;AAEF,uEAAuE;AACvE,MAAM,CAAC,MAAM,0BAA0B,GAAgB;IACrD,UAAU,EAAE,SAAS;IACrB,UAAU,EAAE,SAAS;IACrB,YAAY,EAAE,SAAS;IACvB,YAAY,EAAE,SAAS;IACvB,eAAe,EAAE,SAAS;IAC1B,WAAW,EAAE,SAAS;IACtB,gBAAgB,EAAE,SAAS;IAC3B,WAAW,EAAE,SAAS;IACtB,aAAa,EAAE,SAAS;IACxB,KAAK,EAAE,SAAS;IAChB,eAAe,EAAE,SAAS;CAC3B,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,YAAY,CAAU,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAaH;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,OAA6B;IACzD,OAAO,CACL,OAAO,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAC7E,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,mBAAmB,CAAC,OAA6B;IAC/D,OAAO,OAAO,CAAC,aAAa,IAAI,aAAa,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;AACtE,CAAC;AA6DD,uCAAuC;AACvC,MAAM,CAAC,MAAM,SAAS,GAAG,SAAS,CAAC;AAEnC;;;;GAIG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAgB;IACtD,UAAU,EAAE,SAAS;IACrB,UAAU,EAAE,SAAS;IACrB,YAAY,EAAE,SAAS;IACvB,YAAY,EAAE,SAAS;IACvB,eAAe,EAAE,SAAS;IAC1B,WAAW,EAAE,SAAS;IACtB,cAAc,EAAE,SAAS;IACzB,gBAAgB,EAAE,SAAS;IAC3B,WAAW,EAAE,SAAS;IACtB,aAAa,EAAE,SAAS;IACxB,KAAK,EAAE,SAAS;IAChB,eAAe,EAAE,SAAS;CAC3B,CAAC;AAEF,uEAAuE;AACvE,MAAM,CAAC,MAAM,0BAA0B,GAAgB;IACrD,UAAU,EAAE,SAAS;IACrB,UAAU,EAAE,SAAS;IACrB,YAAY,EAAE,SAAS;IACvB,YAAY,EAAE,SAAS;IACvB,eAAe,EAAE,SAAS;IAC1B,WAAW,EAAE,SAAS;IACtB;;;;MAIE;IACF,cAAc,EAAE,SAAS;IACzB,gBAAgB,EAAE,SAAS;IAC3B,WAAW,EAAE,SAAS;IACtB,aAAa,EAAE,SAAS;IACxB,KAAK,EAAE,SAAS;IAChB,eAAe,EAAE,SAAS;CAC3B,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,YAAY,CAAU,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sudobility/music_drawing",
3
- "version": "0.0.30",
3
+ "version": "0.0.31",
4
4
  "description": "Canvas score rendering for Moosiac: layout, VexFlow drawing and the paint loop.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -44,11 +44,11 @@
44
44
  "vexflow": "^4.2.5"
45
45
  },
46
46
  "peerDependencies": {
47
- "@sudobility/music_types": "^0.13.21"
47
+ "@sudobility/music_types": "^0.13.22"
48
48
  },
49
49
  "devDependencies": {
50
50
  "@eslint/js": "^9.38.0",
51
- "@sudobility/music_types": "^0.13.21",
51
+ "@sudobility/music_types": "^0.13.22",
52
52
  "@sudobility/types": "^1.9.67",
53
53
  "@tonejs/midi": "^2.0.28",
54
54
  "@types/jsdom": "^30.0.0",