@libraz/libcantus 0.9.4 → 0.9.5

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 (120) hide show
  1. package/README.md +27 -18
  2. package/README_ja.md +268 -0
  3. package/dist/analyze/index.cjs +7 -7
  4. package/dist/analyze/index.d.cts +9 -99
  5. package/dist/analyze/index.d.ts +9 -99
  6. package/dist/analyze/index.js +6 -6
  7. package/dist/{chunk-36N73KZ3.cjs → chunk-2A2QMA74.cjs} +80 -65
  8. package/dist/chunk-2A2QMA74.cjs.map +1 -0
  9. package/dist/{chunk-YLEMGEFH.js → chunk-2PTFGVD7.js} +50 -35
  10. package/dist/chunk-2PTFGVD7.js.map +1 -0
  11. package/dist/{chunk-ZEJR4TKL.cjs → chunk-357ZDPVU.cjs} +36 -47
  12. package/dist/chunk-357ZDPVU.cjs.map +1 -0
  13. package/dist/{chunk-EHVEBWM5.js → chunk-3KX76RLG.js} +136 -37
  14. package/dist/chunk-3KX76RLG.js.map +1 -0
  15. package/dist/{chunk-RC6GBMCD.cjs → chunk-4VZ5MZAM.cjs} +155 -111
  16. package/dist/chunk-4VZ5MZAM.cjs.map +1 -0
  17. package/dist/{chunk-RK35RIN7.js → chunk-7EONYVI5.js} +115 -28
  18. package/dist/chunk-7EONYVI5.js.map +1 -0
  19. package/dist/{chunk-GQSGS2N4.js → chunk-7JEP3MFY.js} +5 -16
  20. package/dist/chunk-7JEP3MFY.js.map +1 -0
  21. package/dist/{chunk-7NKDPF74.js → chunk-AID75RN3.js} +203 -104
  22. package/dist/chunk-AID75RN3.js.map +1 -0
  23. package/dist/{chunk-FNDWXRRI.cjs → chunk-BSLTLGM3.cjs} +55 -37
  24. package/dist/chunk-BSLTLGM3.cjs.map +1 -0
  25. package/dist/{chunk-NP4NA2FB.cjs → chunk-CU6VG2YM.cjs} +39 -36
  26. package/dist/chunk-CU6VG2YM.cjs.map +1 -0
  27. package/dist/{chunk-NYYWMV2C.js → chunk-DZMHIGI4.js} +27 -17
  28. package/dist/chunk-DZMHIGI4.js.map +1 -0
  29. package/dist/{chunk-I24MV65U.js → chunk-EDOTEABK.js} +18 -15
  30. package/dist/{chunk-I24MV65U.js.map → chunk-EDOTEABK.js.map} +1 -1
  31. package/dist/{chunk-NKIBQ6PT.js → chunk-HN2OEUN2.js} +7 -4
  32. package/dist/chunk-HN2OEUN2.js.map +1 -0
  33. package/dist/{chunk-D2FAJBYL.js → chunk-KBTTEX7Q.js} +30 -12
  34. package/dist/chunk-KBTTEX7Q.js.map +1 -0
  35. package/dist/{chunk-CAN76NCU.cjs → chunk-KQN2ZYND.cjs} +147 -102
  36. package/dist/chunk-KQN2ZYND.cjs.map +1 -0
  37. package/dist/{chunk-4HLLZPXT.cjs → chunk-MPTVJIVG.cjs} +350 -251
  38. package/dist/chunk-MPTVJIVG.cjs.map +1 -0
  39. package/dist/{chunk-RUMU3UA6.cjs → chunk-MTMZTMWM.cjs} +12 -12
  40. package/dist/{chunk-RUMU3UA6.cjs.map → chunk-MTMZTMWM.cjs.map} +1 -1
  41. package/dist/{chunk-KMHOICIY.js → chunk-NNB67XA2.js} +90 -45
  42. package/dist/chunk-NNB67XA2.js.map +1 -0
  43. package/dist/{chunk-LW53AHQU.cjs → chunk-OL3IHHSJ.cjs} +228 -141
  44. package/dist/chunk-OL3IHHSJ.cjs.map +1 -0
  45. package/dist/{chunk-7MGZ7D62.cjs → chunk-PI3UXRWK.cjs} +43 -13
  46. package/dist/chunk-PI3UXRWK.cjs.map +1 -0
  47. package/dist/{chunk-XEBG3G53.js → chunk-R2VVFAIN.js} +42 -12
  48. package/dist/chunk-R2VVFAIN.js.map +1 -0
  49. package/dist/{chunk-Q6OP4U43.cjs → chunk-WFDXOLUB.cjs} +50 -40
  50. package/dist/chunk-WFDXOLUB.cjs.map +1 -0
  51. package/dist/{chunk-NVE34YGZ.cjs → chunk-WTAN4ACG.cjs} +212 -113
  52. package/dist/chunk-WTAN4ACG.cjs.map +1 -0
  53. package/dist/{chunk-FCANXBAT.cjs → chunk-YFJXS3AU.cjs} +8 -5
  54. package/dist/chunk-YFJXS3AU.cjs.map +1 -0
  55. package/dist/{chunk-Q2XUP227.js → chunk-YUE6TJ4M.js} +89 -45
  56. package/dist/chunk-YUE6TJ4M.js.map +1 -0
  57. package/dist/{chunk-HKGYCQ34.js → chunk-ZGLJM4A4.js} +2 -2
  58. package/dist/core/index.cjs +15 -5
  59. package/dist/core/index.cjs.map +1 -1
  60. package/dist/core/index.d.cts +14 -4
  61. package/dist/core/index.d.ts +14 -4
  62. package/dist/core/index.js +14 -4
  63. package/dist/{function-DNugAOrt.d.cts → function-CxixTB02.d.cts} +98 -7
  64. package/dist/{function-BtiZb9i9.d.ts → function-DTCt675z.d.ts} +98 -7
  65. package/dist/generate/index.cjs +10 -10
  66. package/dist/generate/index.d.cts +21 -21
  67. package/dist/generate/index.d.ts +21 -21
  68. package/dist/generate/index.js +9 -9
  69. package/dist/{index-tJhkmQgE.d.cts → index-B2Ulxxpo.d.cts} +3 -2
  70. package/dist/{index-Be74mcon.d.cts → index-BkYJ0xMq.d.cts} +2 -2
  71. package/dist/{index-6VR8-kit.d.ts → index-BuaB-ypt.d.ts} +3 -2
  72. package/dist/{index-70p168VM.d.ts → index-CAN7v-kw.d.ts} +9 -2
  73. package/dist/{index-C83mZI1P.d.ts → index-COw1Ky9g.d.ts} +1 -1
  74. package/dist/{index-tSQh-xwY.d.ts → index-Cfx8xgH0.d.ts} +1 -1
  75. package/dist/{index-C5UBbQ4G.d.ts → index-DRtIhlJj.d.ts} +2 -2
  76. package/dist/{index-BtXT6UQ0.d.cts → index-alrRninU.d.cts} +9 -2
  77. package/dist/{index-y_ak9_Hi.d.cts → index-oTQbYYIs.d.cts} +1 -1
  78. package/dist/{index-OG65ocOr.d.ts → index-tR9jTn26.d.cts} +4 -1
  79. package/dist/{index-OG65ocOr.d.cts → index-tR9jTn26.d.ts} +4 -1
  80. package/dist/{index-D6b6na69.d.cts → index-x2vcsduE.d.cts} +1 -1
  81. package/dist/index.cjs +24 -14
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.d.cts +11 -11
  84. package/dist/index.d.ts +11 -11
  85. package/dist/index.js +23 -13
  86. package/dist/model/index.cjs +7 -7
  87. package/dist/model/index.d.cts +48 -16
  88. package/dist/model/index.d.ts +48 -16
  89. package/dist/model/index.js +6 -6
  90. package/dist/{styled-DIRkk9Uz.d.ts → styled-Bl0ZK28h.d.ts} +40 -3
  91. package/dist/{styled-DJbkJQfj.d.cts → styled-Crv6SA4S.d.cts} +40 -3
  92. package/dist/theory/index.cjs +6 -6
  93. package/dist/theory/index.d.cts +9 -9
  94. package/dist/theory/index.d.ts +9 -9
  95. package/dist/theory/index.js +5 -5
  96. package/package.json +12 -9
  97. package/dist/chunk-36N73KZ3.cjs.map +0 -1
  98. package/dist/chunk-4HLLZPXT.cjs.map +0 -1
  99. package/dist/chunk-7MGZ7D62.cjs.map +0 -1
  100. package/dist/chunk-7NKDPF74.js.map +0 -1
  101. package/dist/chunk-CAN76NCU.cjs.map +0 -1
  102. package/dist/chunk-D2FAJBYL.js.map +0 -1
  103. package/dist/chunk-EHVEBWM5.js.map +0 -1
  104. package/dist/chunk-FCANXBAT.cjs.map +0 -1
  105. package/dist/chunk-FNDWXRRI.cjs.map +0 -1
  106. package/dist/chunk-GQSGS2N4.js.map +0 -1
  107. package/dist/chunk-KMHOICIY.js.map +0 -1
  108. package/dist/chunk-LW53AHQU.cjs.map +0 -1
  109. package/dist/chunk-NKIBQ6PT.js.map +0 -1
  110. package/dist/chunk-NP4NA2FB.cjs.map +0 -1
  111. package/dist/chunk-NVE34YGZ.cjs.map +0 -1
  112. package/dist/chunk-NYYWMV2C.js.map +0 -1
  113. package/dist/chunk-Q2XUP227.js.map +0 -1
  114. package/dist/chunk-Q6OP4U43.cjs.map +0 -1
  115. package/dist/chunk-RC6GBMCD.cjs.map +0 -1
  116. package/dist/chunk-RK35RIN7.js.map +0 -1
  117. package/dist/chunk-XEBG3G53.js.map +0 -1
  118. package/dist/chunk-YLEMGEFH.js.map +0 -1
  119. package/dist/chunk-ZEJR4TKL.cjs.map +0 -1
  120. /package/dist/{chunk-HKGYCQ34.js.map → chunk-ZGLJM4A4.js.map} +0 -0
@@ -9,7 +9,7 @@
9
9
 
10
10
 
11
11
 
12
- var _chunkFNDWXRRIcjs = require('./chunk-FNDWXRRI.cjs');
12
+ var _chunkBSLTLGM3cjs = require('./chunk-BSLTLGM3.cjs');
13
13
 
14
14
 
15
15
 
@@ -24,7 +24,9 @@ var _chunkFNDWXRRIcjs = require('./chunk-FNDWXRRI.cjs');
24
24
 
25
25
 
26
26
 
27
- var _chunk7MGZ7D62cjs = require('./chunk-7MGZ7D62.cjs');
27
+
28
+
29
+ var _chunkPI3UXRWKcjs = require('./chunk-PI3UXRWK.cjs');
28
30
 
29
31
  // src/theory/chordscale/index.ts
30
32
  function popcount12(mask) {
@@ -35,7 +37,7 @@ function popcount12(mask) {
35
37
  return count;
36
38
  }
37
39
  function maskHasPitchClass(mask, scaleRootPc, pc) {
38
- const offset = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, pc - scaleRootPc);
40
+ const offset = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, pc - scaleRootPc);
39
41
  return (mask >> offset & 1) === 1;
40
42
  }
41
43
  function scaleMatchesChord(chordPcs, scaleMask, scaleRootPc) {
@@ -59,46 +61,63 @@ var SCALE_PREFERENCE = [
59
61
  "phrygian",
60
62
  "locrian"
61
63
  ];
64
+ var IDIOMATIC_SCALES = {
65
+ aug: ["wholeTone"],
66
+ m7b5: ["locrian"]
67
+ };
62
68
  function conventionalRank(name) {
63
69
  const index = SCALE_PREFERENCE.indexOf(name);
64
70
  return index < 0 ? SCALE_PREFERENCE.length : index;
65
71
  }
72
+ function idiomaticRank(chord, name) {
73
+ const choices = IDIOMATIC_SCALES[chord.quality];
74
+ if (choices === void 0) {
75
+ return 0;
76
+ }
77
+ const index = choices.indexOf(name);
78
+ return index < 0 ? choices.length + 1 : index;
79
+ }
80
+ function isAlteredDominant(chord, scaleName) {
81
+ return chord.quality === "dom7" && scaleName === "altered";
82
+ }
66
83
  function chordScales(chord) {
67
- const chordPcs = _chunkFNDWXRRIcjs.chordPitchClasses.call(void 0, chord);
68
- const rootPc = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, chord.rootPc);
84
+ const chordPcs = _chunkBSLTLGM3cjs.chordPitchClasses.call(void 0, chord);
85
+ const rootPc = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.rootPc);
69
86
  const ranked = [];
70
87
  const seenMasks = /* @__PURE__ */ new Set();
71
- for (const name of Object.keys(_chunkFNDWXRRIcjs.NAMED_SCALES)) {
88
+ for (const name of Object.keys(_chunkBSLTLGM3cjs.NAMED_SCALES)) {
72
89
  if (name === "chromatic" || ALIASED_SCALE_NAMES.has(name)) {
73
90
  continue;
74
91
  }
75
- const mask = _chunkFNDWXRRIcjs.namedScaleMask.call(void 0, name);
92
+ const mask = _chunkBSLTLGM3cjs.namedScaleMask.call(void 0, name);
76
93
  if (mask === void 0 || seenMasks.has(mask)) {
77
94
  continue;
78
95
  }
79
96
  seenMasks.add(mask);
80
- if (scaleMatchesChord(chordPcs, mask, rootPc)) {
97
+ if (scaleMatchesChord(chordPcs, mask, rootPc) || isAlteredDominant(chord, name)) {
81
98
  const size = popcount12(mask);
82
99
  ranked.push({ name, extra: size - chordPcs.length, size });
83
100
  }
84
101
  }
85
102
  if (ranked.length === 0) {
86
- if (_chunkFNDWXRRIcjs.NAMED_SCALES.chromatic !== void 0) {
103
+ if (_chunkBSLTLGM3cjs.NAMED_SCALES.chromatic !== void 0) {
87
104
  return [{ name: "chromatic", rootPc }];
88
105
  }
89
106
  return [];
90
107
  }
91
108
  const preferHeptatonic = chordPcs.length <= 3;
92
109
  ranked.sort((a, b) => {
110
+ const idiomaticA = idiomaticRank(chord, a.name);
111
+ const idiomaticB = idiomaticRank(chord, b.name);
112
+ if (idiomaticA !== idiomaticB) {
113
+ return idiomaticA - idiomaticB;
114
+ }
93
115
  if (preferHeptatonic && a.size === HEPTATONIC_SIZE !== (b.size === HEPTATONIC_SIZE)) {
94
116
  return a.size === HEPTATONIC_SIZE ? -1 : 1;
95
117
  }
96
118
  if (a.extra !== b.extra) {
97
119
  return a.extra - b.extra;
98
120
  }
99
- if (a.size !== b.size) {
100
- return a.size - b.size;
101
- }
102
121
  const rankA = conventionalRank(a.name);
103
122
  const rankB = conventionalRank(b.name);
104
123
  if (rankA !== rankB) {
@@ -109,10 +128,11 @@ function chordScales(chord) {
109
128
  return ranked.map((entry) => ({ name: entry.name, rootPc }));
110
129
  }
111
130
  function avoidNotes(chord, scaleName) {
112
- const mask = _chunkFNDWXRRIcjs.requireScaleMask.call(void 0, scaleName);
113
- const rootPc = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, chord.rootPc);
114
- const chordPcs = _chunkFNDWXRRIcjs.chordPitchClasses.call(void 0, chord);
115
- if (!scaleMatchesChord(chordPcs, mask, rootPc)) {
131
+ const mask = _chunkBSLTLGM3cjs.requireScaleMask.call(void 0, scaleName);
132
+ const rootPc = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.rootPc);
133
+ const chordPcs = _chunkBSLTLGM3cjs.chordPitchClasses.call(void 0, chord);
134
+ const alteredDominant = isAlteredDominant(chord, scaleName);
135
+ if (!scaleMatchesChord(chordPcs, mask, rootPc) && !alteredDominant) {
116
136
  return [];
117
137
  }
118
138
  const chordSet = new Set(chordPcs);
@@ -121,21 +141,23 @@ function avoidNotes(chord, scaleName) {
121
141
  if (!maskHasPitchClass(mask, rootPc, pc) || chordSet.has(pc)) {
122
142
  continue;
123
143
  }
124
- if (chordSet.has(_chunk7MGZ7D62cjs.pitchClassOf.call(void 0, pc - 1))) {
144
+ const suspendedThird = chord.quality === "sus4" || chord.quality === "7sus4" ? pc === _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, rootPc + 4) : false;
145
+ if (!alteredDominant && (chordSet.has(_chunkPI3UXRWKcjs.pitchClassOf.call(void 0, pc - 1)) || suspendedThird)) {
125
146
  avoid.push(pc);
126
147
  }
127
148
  }
128
149
  return avoid.sort((a, b) => a - b);
129
150
  }
130
151
  function availableTensions(chord, scaleName) {
131
- const mask = _chunkFNDWXRRIcjs.requireScaleMask.call(void 0, scaleName);
132
- const rootPc = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, chord.rootPc);
133
- const chordPcs = _chunkFNDWXRRIcjs.chordPitchClasses.call(void 0, chord);
134
- if (!scaleMatchesChord(chordPcs, mask, rootPc)) {
152
+ const mask = _chunkBSLTLGM3cjs.requireScaleMask.call(void 0, scaleName);
153
+ const rootPc = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.rootPc);
154
+ const chordPcs = _chunkBSLTLGM3cjs.chordPitchClasses.call(void 0, chord);
155
+ const alteredDominant = isAlteredDominant(chord, scaleName);
156
+ if (!scaleMatchesChord(chordPcs, mask, rootPc) && !alteredDominant) {
135
157
  return [];
136
158
  }
137
159
  const chordSet = new Set(chordPcs);
138
- const avoidSet = new Set(avoidNotes(chord, scaleName));
160
+ const avoidSet = alteredDominant ? /* @__PURE__ */ new Set() : new Set(avoidNotes(chord, scaleName));
139
161
  const tensions = [];
140
162
  for (let pc = 0; pc < 12; pc += 1) {
141
163
  if (!maskHasPitchClass(mask, rootPc, pc) || chordSet.has(pc) || avoidSet.has(pc)) {
@@ -146,8 +168,11 @@ function availableTensions(chord, scaleName) {
146
168
  return tensions.sort((a, b) => a - b);
147
169
  }
148
170
  function chordScaleReport(chord, limit) {
171
+ if (limit !== void 0) {
172
+ _chunkPI3UXRWKcjs.assertPositiveInt.call(void 0, limit, "chord-scale report limit");
173
+ }
149
174
  const matches = chordScales(chord);
150
- const chosen = limit === void 0 ? matches : matches.slice(0, Math.max(0, limit));
175
+ const chosen = limit === void 0 ? matches : matches.slice(0, limit);
151
176
  return chosen.map((match) => ({
152
177
  name: match.name,
153
178
  rootPc: match.rootPc,
@@ -157,14 +182,14 @@ function chordScaleReport(chord, limit) {
157
182
  }
158
183
  var RANK_PENALTY = 0.01;
159
184
  function scalePitchClassSet(name, rootPc) {
160
- const mask = _chunkFNDWXRRIcjs.namedScaleMask.call(void 0, name);
185
+ const mask = _chunkBSLTLGM3cjs.namedScaleMask.call(void 0, name);
161
186
  const pcs = /* @__PURE__ */ new Set();
162
187
  if (mask === void 0) {
163
188
  return pcs;
164
189
  }
165
190
  for (let n = 0; n < 12; n += 1) {
166
191
  if ((mask >> n & 1) === 1) {
167
- pcs.add(_chunk7MGZ7D62cjs.pitchClassOf.call(void 0, rootPc + n));
192
+ pcs.add(_chunkPI3UXRWKcjs.pitchClassOf.call(void 0, rootPc + n));
168
193
  }
169
194
  }
170
195
  return pcs;
@@ -184,6 +209,7 @@ function symmetricDifferenceSize(a, b) {
184
209
  return count;
185
210
  }
186
211
  function scalesForChanges(chords) {
212
+ _chunkPI3UXRWKcjs.assertGenerationBudget.call(void 0, chords.length, "chord-scale changes");
187
213
  if (chords.length === 0) {
188
214
  return [];
189
215
  }
@@ -296,7 +322,7 @@ var CHROMATIC_SPELLING_SHARP = {
296
322
  // M7
297
323
  };
298
324
  function alterFor(letter, pc) {
299
- let d = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, pc - _chunk7MGZ7D62cjs.naturalPitchClassOf.call(void 0, letter));
325
+ let d = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, pc - _chunkPI3UXRWKcjs.naturalPitchClassOf.call(void 0, letter));
300
326
  if (d > 6) {
301
327
  d -= 12;
302
328
  }
@@ -306,7 +332,7 @@ function letterFor(tonic, degreeOffset, pc) {
306
332
  if (degreeOffset === void 0) {
307
333
  return void 0;
308
334
  }
309
- const letter = _chunk7MGZ7D62cjs.diatonicLetterOf.call(void 0, tonic.letter + degreeOffset);
335
+ const letter = _chunkPI3UXRWKcjs.diatonicLetterOf.call(void 0, tonic.letter + degreeOffset);
310
336
  return { letter, alter: alterFor(letter, pc) };
311
337
  }
312
338
  function pickSpelling(flat, sharp, preferFlat) {
@@ -318,31 +344,37 @@ function pickSpelling(flat, sharp, preferFlat) {
318
344
  }
319
345
  return preferFlat ? flat : sharp;
320
346
  }
347
+ function capChromaticAccidentals(preferred, alternative) {
348
+ return alternative !== void 0 && Math.abs(preferred.alter) - Math.abs(alternative.alter) >= 2 ? alternative : preferred;
349
+ }
321
350
  function isHeptatonic(key) {
322
- return _chunkFNDWXRRIcjs.scaleTonesInDegreeOrder.call(void 0, key).length === 7;
351
+ return _chunkBSLTLGM3cjs.scaleTonesInDegreeOrder.call(void 0, key).length === 7;
323
352
  }
324
353
  function hasMinorThird(key) {
325
- const tones = _chunkFNDWXRRIcjs.scaleTonesInDegreeOrder.call(void 0, key);
326
- const root = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, key.rootPc);
327
- return tones.includes(_chunk7MGZ7D62cjs.pitchClassOf.call(void 0, root + 3)) && !tones.includes(_chunk7MGZ7D62cjs.pitchClassOf.call(void 0, root + 4));
354
+ const tones = _chunkBSLTLGM3cjs.scaleTonesInDegreeOrder.call(void 0, key);
355
+ const root = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, key.rootPc);
356
+ return tones.includes(_chunkPI3UXRWKcjs.pitchClassOf.call(void 0, root + 3)) && !tones.includes(_chunkPI3UXRWKcjs.pitchClassOf.call(void 0, root + 4));
328
357
  }
329
358
  function spellPitchClass(pc, tonic, key) {
330
- const tonicPc = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, _chunk7MGZ7D62cjs.naturalPitchClassOf.call(void 0, tonic.letter) + tonic.alter);
331
- const offset = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, pc - tonicPc);
359
+ const tonicPc = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, _chunkPI3UXRWKcjs.naturalPitchClassOf.call(void 0, tonic.letter) + tonic.alter);
360
+ const offset = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, pc - tonicPc);
332
361
  if (offset === 0) {
333
- return { letter: _chunk7MGZ7D62cjs.diatonicLetterOf.call(void 0, tonic.letter), alter: tonic.alter };
362
+ return { letter: _chunkPI3UXRWKcjs.diatonicLetterOf.call(void 0, tonic.letter), alter: tonic.alter };
334
363
  }
335
364
  const heptatonic = isHeptatonic(key);
336
365
  if (heptatonic) {
337
- const degree = _chunkFNDWXRRIcjs.scaleTonesInDegreeOrder.call(void 0, key).indexOf(_chunk7MGZ7D62cjs.pitchClassOf.call(void 0, pc));
366
+ const degree = _chunkBSLTLGM3cjs.scaleTonesInDegreeOrder.call(void 0, key).indexOf(_chunkPI3UXRWKcjs.pitchClassOf.call(void 0, pc));
338
367
  if (degree >= 0) {
339
- const letter = _chunk7MGZ7D62cjs.diatonicLetterOf.call(void 0, tonic.letter + degree);
368
+ const letter = _chunkPI3UXRWKcjs.diatonicLetterOf.call(void 0, tonic.letter + degree);
340
369
  return { letter, alter: alterFor(letter, pc) };
341
370
  }
342
371
  const degreeOffset = CHROMATIC_SPELLING[offset];
343
- if (degreeOffset !== void 0) {
344
- const letter = _chunk7MGZ7D62cjs.diatonicLetterOf.call(void 0, tonic.letter + degreeOffset);
345
- return { letter, alter: alterFor(letter, pc) };
372
+ const preferred = letterFor(tonic, degreeOffset, pc);
373
+ if (preferred !== void 0) {
374
+ const flat = letterFor(tonic, CHROMATIC_SPELLING_FLAT[offset], pc);
375
+ const sharp = letterFor(tonic, CHROMATIC_SPELLING_SHARP[offset], pc);
376
+ const alternative = _optionalChain([flat, 'optionalAccess', _4 => _4.letter]) === preferred.letter ? sharp : _optionalChain([sharp, 'optionalAccess', _5 => _5.letter]) === preferred.letter ? flat : void 0;
377
+ return capChromaticAccidentals(preferred, alternative);
346
378
  }
347
379
  } else {
348
380
  const flat = letterFor(tonic, CHROMATIC_SPELLING_FLAT[offset], pc);
@@ -352,11 +384,11 @@ function spellPitchClass(pc, tonic, key) {
352
384
  return best;
353
385
  }
354
386
  }
355
- const belowLetter = _chunk7MGZ7D62cjs.diatonicLetterOf.call(void 0, _nullishCoalesce([0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6][_chunk7MGZ7D62cjs.pitchClassOf.call(void 0, pc)], () => ( 0)));
387
+ const belowLetter = _chunkPI3UXRWKcjs.diatonicLetterOf.call(void 0, _nullishCoalesce([0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6][_chunkPI3UXRWKcjs.pitchClassOf.call(void 0, pc)], () => ( 0)));
356
388
  return { letter: belowLetter, alter: alterFor(belowLetter, pc) };
357
389
  }
358
390
  function spellScale(tonic, key) {
359
- return _chunkFNDWXRRIcjs.scaleTonesInDegreeOrder.call(void 0, key).map((pc) => spellPitchClass(pc, tonic, key));
391
+ return _chunkBSLTLGM3cjs.scaleTonesInDegreeOrder.call(void 0, key).map((pc) => spellPitchClass(pc, tonic, key));
360
392
  }
361
393
  function spellPitchClasses(pcs, tonic, key) {
362
394
  return pcs.map((pc) => spellPitchClass(pc, tonic, key));
@@ -398,16 +430,19 @@ function chordLetterOffset(interval, chord) {
398
430
  return 6;
399
431
  default: {
400
432
  const octaves = Math.floor(Math.max(0, interval) / 12);
401
- const simple = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, interval);
433
+ const simple = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, interval);
402
434
  const simpleOffset = _nullishCoalesce([0, 1, 1, 2, 2, 3, 4, 4, 4, 5, 6, 6][simple], () => ( 0));
403
435
  return octaves * 7 + simpleOffset;
404
436
  }
405
437
  }
406
438
  }
407
439
  function spellChordFromRoot(chord, root) {
440
+ if (_chunkPI3UXRWKcjs.pitchClassOf.call(void 0, _chunkPI3UXRWKcjs.naturalPitchClassOf.call(void 0, root.letter) + root.alter) !== _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.rootPc)) {
441
+ throw new (0, _chunkPI3UXRWKcjs.InvalidInputError)("chord root spelling must match chord.rootPc");
442
+ }
408
443
  return chord.intervals.map((interval) => {
409
- const letter = _chunk7MGZ7D62cjs.diatonicLetterOf.call(void 0, root.letter + chordLetterOffset(interval, chord));
410
- const pc = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, chord.rootPc + interval);
444
+ const letter = _chunkPI3UXRWKcjs.diatonicLetterOf.call(void 0, root.letter + chordLetterOffset(interval, chord));
445
+ const pc = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
411
446
  return { letter, alter: alterFor(letter, pc) };
412
447
  });
413
448
  }
@@ -416,26 +451,27 @@ function spellChord(chord, tonic, key) {
416
451
  }
417
452
  function chordRootSpelling(chord, tonic, key) {
418
453
  const hint = chord.rootSpelling;
419
- if (hint !== void 0 && _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, _chunk7MGZ7D62cjs.naturalPitchClassOf.call(void 0, hint.letter) + hint.alter) === _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, chord.rootPc)) {
420
- return { letter: _chunk7MGZ7D62cjs.diatonicLetterOf.call(void 0, hint.letter), alter: hint.alter };
454
+ if (hint !== void 0 && _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, _chunkPI3UXRWKcjs.naturalPitchClassOf.call(void 0, hint.letter) + hint.alter) === _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.rootPc)) {
455
+ return { letter: _chunkPI3UXRWKcjs.diatonicLetterOf.call(void 0, hint.letter), alter: hint.alter };
421
456
  }
422
457
  return spellPitchClass(chord.rootPc, tonic, key);
423
458
  }
424
459
  function spellPitch(pitch, tonic, key) {
425
460
  const rounded = Math.round(pitch);
426
- const spelled = spellPitchClass(_chunk7MGZ7D62cjs.pitchClassOf.call(void 0, rounded), tonic, key);
427
- const octave = (rounded - _chunk7MGZ7D62cjs.naturalPitchClassOf.call(void 0, spelled.letter) - spelled.alter) / 12 - 1;
461
+ const spelled = spellPitchClass(_chunkPI3UXRWKcjs.pitchClassOf.call(void 0, rounded), tonic, key);
462
+ const octave = (rounded - _chunkPI3UXRWKcjs.naturalPitchClassOf.call(void 0, spelled.letter) - spelled.alter) / 12 - 1;
428
463
  return { letter: spelled.letter, alter: spelled.alter, octave };
429
464
  }
430
465
  function noteNames(notes) {
431
- return notes.map(_chunk7MGZ7D62cjs.formatNote);
466
+ return notes.map(_chunkPI3UXRWKcjs.formatNote);
432
467
  }
433
468
 
434
469
  // src/theory/symbol/index.ts
435
- var ROOT_RE = /^[A-Ga-g](?:#{1,2}|b{1,2})?/;
436
- var BASS_RE = /^[A-Ga-g](?:#{1,2}|b{1,2})?$/;
470
+ var ROOT_RE = /^[A-Ga-g](?:#{1,2}|b{1,2}|x)?/;
471
+ var BASS_RE = /^[A-Ga-g](?:#{1,2}|b{1,2}|x)?$/;
437
472
  var QUALITY_MAP = {
438
473
  "": "maj",
474
+ maj: "maj",
439
475
  m: "min",
440
476
  min: "min",
441
477
  "-": "min",
@@ -460,6 +496,15 @@ var QUALITY_MAP = {
460
496
  mMaj7: "minMaj7",
461
497
  mM7: "minMaj7",
462
498
  minMaj7: "minMaj7",
499
+ mMaj9: "minMaj9",
500
+ mM9: "minMaj9",
501
+ minMaj9: "minMaj9",
502
+ mMaj11: "minMaj11",
503
+ mM11: "minMaj11",
504
+ minMaj11: "minMaj11",
505
+ mMaj13: "minMaj13",
506
+ mM13: "minMaj13",
507
+ minMaj13: "minMaj13",
463
508
  aug7: "aug7",
464
509
  "+7": "aug7",
465
510
  "7#5": "aug7",
@@ -533,6 +578,9 @@ var CANONICAL_SUFFIX = {
533
578
  dim7: "dim7",
534
579
  m7b5: "m7b5",
535
580
  minMaj7: "mMaj7",
581
+ minMaj9: "mMaj9",
582
+ minMaj11: "mMaj11",
583
+ minMaj13: "mMaj13",
536
584
  aug7: "aug7",
537
585
  augMaj7: "augMaj7",
538
586
  majb5: "maj(b5)",
@@ -568,10 +616,10 @@ function knownQuality(suffix) {
568
616
  return Object.hasOwn(QUALITY_MAP, suffix) ? QUALITY_MAP[suffix] : void 0;
569
617
  }
570
618
  function makeSpelledChord(root, quality, bass) {
571
- const chord = _chunkFNDWXRRIcjs.makeChord.call(void 0,
572
- _chunk7MGZ7D62cjs.noteToPitchClass.call(void 0, root),
619
+ const chord = _chunkBSLTLGM3cjs.makeChord.call(void 0,
620
+ _chunkPI3UXRWKcjs.noteToPitchClass.call(void 0, root),
573
621
  quality,
574
- bass === void 0 ? void 0 : _chunk7MGZ7D62cjs.noteToPitchClass.call(void 0, bass)
622
+ bass === void 0 ? void 0 : _chunkPI3UXRWKcjs.noteToPitchClass.call(void 0, bass)
575
623
  );
576
624
  chord.rootSpelling = { letter: root.letter, alter: root.alter };
577
625
  if (bass !== void 0) {
@@ -580,13 +628,13 @@ function makeSpelledChord(root, quality, bass) {
580
628
  return chord;
581
629
  }
582
630
  function parseChordSymbol(text) {
583
- const trimmed = text.trim();
631
+ const trimmed = text.trim().replaceAll("\u266F", "#").replaceAll("\u266D", "b").replaceAll("\u{1D12A}", "x").replaceAll("\u{1D12B}", "bb");
584
632
  const rootMatch = ROOT_RE.exec(trimmed);
585
633
  if (!rootMatch) {
586
- throw new (0, _chunk7MGZ7D62cjs.InvalidInputError)(`Invalid chord symbol: ${text}`);
634
+ throw new (0, _chunkPI3UXRWKcjs.InvalidInputError)(`Invalid chord symbol: ${text}`);
587
635
  }
588
636
  const rootToken = rootMatch[0];
589
- const rootNote = _chunk7MGZ7D62cjs.parseNote.call(void 0, rootToken);
637
+ const rootNote = _chunkPI3UXRWKcjs.parseNote.call(void 0, rootToken);
590
638
  const rest = trimmed.slice(rootToken.length);
591
639
  const slashIndex = rest.lastIndexOf("/");
592
640
  if (slashIndex !== -1) {
@@ -594,46 +642,55 @@ function parseChordSymbol(text) {
594
642
  const after = rest.slice(slashIndex + 1);
595
643
  const beforeQuality = knownQuality(before);
596
644
  if (beforeQuality !== void 0 && BASS_RE.test(after)) {
597
- return makeSpelledChord(rootNote, beforeQuality, _chunk7MGZ7D62cjs.parseNote.call(void 0, after));
645
+ return makeSpelledChord(rootNote, beforeQuality, _chunkPI3UXRWKcjs.parseNote.call(void 0, after));
598
646
  }
599
647
  }
600
648
  const quality = knownQuality(rest);
601
649
  if (quality === void 0) {
602
- throw new (0, _chunk7MGZ7D62cjs.InvalidInputError)(`Unrecognized chord quality: ${text}`);
650
+ throw new (0, _chunkPI3UXRWKcjs.InvalidInputError)(`Unrecognized chord quality: ${text}`);
603
651
  }
604
652
  return makeSpelledChord(rootNote, quality);
605
653
  }
606
654
  function pitchClassName(pc, hint, flats, inheritFlats) {
607
- if (flats === void 0 && hint !== void 0 && _chunk7MGZ7D62cjs.noteToPitchClass.call(void 0, hint) === pc) {
608
- return _chunk7MGZ7D62cjs.formatNote.call(void 0, hint);
655
+ if (flats === void 0 && hint !== void 0 && _chunkPI3UXRWKcjs.noteToPitchClass.call(void 0, hint) === pc) {
656
+ return _chunkPI3UXRWKcjs.formatNote.call(void 0, hint);
609
657
  }
610
- const note = _chunk7MGZ7D62cjs.midiToNote.call(void 0, 60 + pc, _nullishCoalesce(flats, () => ( inheritFlats)) ? "flat" : "sharp");
611
- return _chunk7MGZ7D62cjs.formatNote.call(void 0, { letter: note.letter, alter: note.alter });
658
+ const note = _chunkPI3UXRWKcjs.midiToNote.call(void 0, 60 + pc, _nullishCoalesce(flats, () => ( inheritFlats)) ? "flat" : "sharp");
659
+ return _chunkPI3UXRWKcjs.formatNote.call(void 0, { letter: note.letter, alter: note.alter });
612
660
  }
613
661
  function formatChordSymbol(chord, opts) {
614
- _chunk7MGZ7D62cjs.assertFiniteNumber.call(void 0, chord.rootPc, "chord rootPc");
662
+ _chunkPI3UXRWKcjs.assertFiniteNumber.call(void 0, chord.rootPc, "chord rootPc");
615
663
  if (chord.bassPc !== void 0) {
616
- _chunk7MGZ7D62cjs.assertFiniteNumber.call(void 0, chord.bassPc, "chord bassPc");
664
+ _chunkPI3UXRWKcjs.assertFiniteNumber.call(void 0, chord.bassPc, "chord bassPc");
617
665
  }
618
666
  if (!Object.hasOwn(CANONICAL_SUFFIX, chord.quality)) {
619
- throw new (0, _chunk7MGZ7D62cjs.InvalidInputError)(`Unknown chord quality: ${String(chord.quality)}`);
667
+ throw new (0, _chunkPI3UXRWKcjs.InvalidInputError)(`Unknown chord quality: ${String(chord.quality)}`);
620
668
  }
621
- const rootPc = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, chord.rootPc);
669
+ const rootPc = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.rootPc);
622
670
  const rootHint = chord.rootSpelling;
623
- const rootName = pitchClassName(rootPc, rootHint, _optionalChain([opts, 'optionalAccess', _4 => _4.flats]));
671
+ const rootName = pitchClassName(rootPc, rootHint, _optionalChain([opts, 'optionalAccess', _6 => _6.flats]));
624
672
  const suffix = CANONICAL_SUFFIX[chord.quality];
625
673
  let symbol = `${rootName}${suffix}`;
626
- if (chord.bassPc !== void 0 && _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, chord.bassPc) !== rootPc) {
627
- const inheritFlats = rootHint !== void 0 && _chunk7MGZ7D62cjs.noteToPitchClass.call(void 0, rootHint) === rootPc ? rootHint.alter < 0 : void 0;
628
- symbol += `/${pitchClassName(_chunk7MGZ7D62cjs.pitchClassOf.call(void 0, chord.bassPc), chord.bassSpelling, _optionalChain([opts, 'optionalAccess', _5 => _5.flats]), inheritFlats)}`;
674
+ if (chord.bassPc !== void 0 && _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.bassPc) !== rootPc) {
675
+ const inheritFlats = rootHint !== void 0 && _chunkPI3UXRWKcjs.noteToPitchClass.call(void 0, rootHint) === rootPc ? rootHint.alter < 0 : void 0;
676
+ symbol += `/${pitchClassName(_chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.bassPc), chord.bassSpelling, _optionalChain([opts, 'optionalAccess', _7 => _7.flats]), inheritFlats)}`;
629
677
  }
630
678
  return symbol;
631
679
  }
632
680
  function transposeChordSymbol(text, semitones, opts) {
681
+ _chunkPI3UXRWKcjs.assertFiniteSemitones.call(void 0, semitones);
633
682
  const chord = parseChordSymbol(text);
634
- const transposed = { ...chord, rootPc: _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, chord.rootPc + semitones) };
683
+ const transposed = { ...chord, rootPc: _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.rootPc + semitones) };
684
+ if (chord.rootSpelling !== void 0) {
685
+ const hint = _chunkPI3UXRWKcjs.transposeNote.call(void 0, chord.rootSpelling, semitones);
686
+ transposed.rootSpelling = { letter: hint.letter, alter: hint.alter };
687
+ }
635
688
  if (chord.bassPc !== void 0) {
636
- transposed.bassPc = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, chord.bassPc + semitones);
689
+ transposed.bassPc = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.bassPc + semitones);
690
+ }
691
+ if (chord.bassSpelling !== void 0) {
692
+ const hint = _chunkPI3UXRWKcjs.transposeNote.call(void 0, chord.bassSpelling, semitones);
693
+ transposed.bassSpelling = { letter: hint.letter, alter: hint.alter };
637
694
  }
638
695
  return formatChordSymbol(transposed, opts);
639
696
  }
@@ -644,14 +701,15 @@ var VIOLATION_PENALTY = 1e3;
644
701
  var MISSING_TONE_PENALTY = 500;
645
702
  var MISSING_FIFTH_PENALTY = 20;
646
703
  var POOR_DOUBLING_PENALTY = 4;
704
+ var UNISON_PENALTY = 100;
647
705
  var LEADING_TONE_DOUBLING_PENALTY = 200;
648
- var RESOLUTION_PENALTY = 40;
649
- var MAX_CANDIDATES = 4e3;
650
- var MAX_SEARCH_NODES = MAX_CANDIDATES * 16;
706
+ var RESOLUTION_PENALTY = 200;
707
+ var DEFAULT_MAX_CANDIDATES = 4e3;
708
+ var SEARCH_NODES_PER_CANDIDATE = 16;
651
709
  function pitchesForPc(pc, range) {
652
710
  const result = [];
653
711
  for (let midi = Math.ceil(range.min); midi <= range.max; midi += 1) {
654
- if (_chunk7MGZ7D62cjs.pitchClassOf.call(void 0, midi) === pc) {
712
+ if (_chunkPI3UXRWKcjs.pitchClassOf.call(void 0, midi) === pc) {
655
713
  result.push(midi);
656
714
  }
657
715
  }
@@ -662,23 +720,24 @@ function pitchesForPc(pc, range) {
662
720
  return da === db ? a - b : da - db;
663
721
  });
664
722
  }
665
- function enumerateVoicings(chord, ranges, maxSpacing) {
666
- const chordPcs = _chunkFNDWXRRIcjs.chordPitchClasses.call(void 0, chord);
667
- const bassPc = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, _nullishCoalesce(chord.bassPc, () => ( chord.rootPc)));
723
+ function enumerateVoicings(chord, ranges, maxSpacing, maxCandidates = DEFAULT_MAX_CANDIDATES) {
724
+ const chordPcs = _chunkBSLTLGM3cjs.chordPitchClasses.call(void 0, chord);
725
+ const bassPc = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, _nullishCoalesce(chord.bassPc, () => ( chord.rootPc)));
668
726
  const byVoice = ranges.map(
669
727
  (range, voice) => (voice === 0 ? [bassPc] : chordPcs).flatMap((pc) => pitchesForPc(pc, range))
670
728
  );
671
729
  for (let voice = 0; voice < byVoice.length; voice += 1) {
672
730
  if ((_nullishCoalesce(byVoice[voice], () => ( []))).length === 0) {
673
- throw new (0, _chunk7MGZ7D62cjs.NoSolutionError)("no voicing satisfies the given ranges");
731
+ throw new (0, _chunkPI3UXRWKcjs.NoSolutionError)("no voicing satisfies the given ranges");
674
732
  }
675
733
  }
676
734
  const results = [];
677
735
  const current = [];
678
736
  let nodes = 0;
737
+ const maxSearchNodes = maxCandidates * SEARCH_NODES_PER_CANDIDATE;
679
738
  const build = (voice) => {
680
739
  nodes += 1;
681
- if (results.length >= MAX_CANDIDATES || nodes > MAX_SEARCH_NODES) {
740
+ if (results.length >= maxCandidates || nodes > maxSearchNodes) {
682
741
  return;
683
742
  }
684
743
  if (voice === ranges.length) {
@@ -707,17 +766,22 @@ function enumerateVoicings(chord, ranges, maxSpacing) {
707
766
  function structuralPenalty(pitches, chord, key) {
708
767
  const counts = /* @__PURE__ */ new Map();
709
768
  for (const pitch of pitches) {
710
- const pc = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, pitch);
769
+ const pc = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, pitch);
711
770
  counts.set(pc, (_nullishCoalesce(counts.get(pc), () => ( 0))) + 1);
712
771
  }
713
772
  let penalty = 0;
714
- for (const pc of _chunkFNDWXRRIcjs.chordPitchClasses.call(void 0, chord)) {
773
+ for (let index = 1; index < pitches.length; index += 1) {
774
+ if (pitches[index] === pitches[index - 1]) {
775
+ penalty += UNISON_PENALTY;
776
+ }
777
+ }
778
+ for (const pc of _chunkBSLTLGM3cjs.chordPitchClasses.call(void 0, chord)) {
715
779
  if (!counts.has(pc)) {
716
- penalty += _chunkFNDWXRRIcjs.chordToneRole.call(void 0, pc, chord) === "fifth" ? MISSING_FIFTH_PENALTY : MISSING_TONE_PENALTY;
780
+ penalty += _chunkBSLTLGM3cjs.chordToneRole.call(void 0, pc, chord) === "fifth" ? MISSING_FIFTH_PENALTY : MISSING_TONE_PENALTY;
717
781
  }
718
782
  }
719
- const rootPc = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, chord.rootPc);
720
- const leadingTonePc = key === void 0 ? void 0 : _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, key.rootPc - 1);
783
+ const rootPc = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.rootPc);
784
+ const leadingTonePc = key === void 0 ? void 0 : _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, key.rootPc - 1);
721
785
  for (const [pc, count] of counts) {
722
786
  if (count <= 1) {
723
787
  continue;
@@ -726,7 +790,7 @@ function structuralPenalty(pitches, chord, key) {
726
790
  penalty += (count - 1) * LEADING_TONE_DOUBLING_PENALTY;
727
791
  continue;
728
792
  }
729
- if (pc !== rootPc && _chunkFNDWXRRIcjs.chordToneRole.call(void 0, pc, chord) !== "fifth") {
793
+ if (pc !== rootPc && _chunkBSLTLGM3cjs.chordToneRole.call(void 0, pc, chord) !== "fifth") {
730
794
  penalty += (count - 1) * POOR_DOUBLING_PENALTY;
731
795
  }
732
796
  }
@@ -734,8 +798,8 @@ function structuralPenalty(pitches, chord, key) {
734
798
  }
735
799
  function seventhPcOf(chord) {
736
800
  for (const interval of chord.intervals) {
737
- const pc = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, chord.rootPc + interval);
738
- if (_chunkFNDWXRRIcjs.chordToneRole.call(void 0, pc, chord) === "seventh") {
801
+ const pc = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
802
+ if (_chunkBSLTLGM3cjs.chordToneRole.call(void 0, pc, chord) === "seventh") {
739
803
  return pc;
740
804
  }
741
805
  }
@@ -743,9 +807,9 @@ function seventhPcOf(chord) {
743
807
  }
744
808
  function resolutionViolations(prev, cur, prevChord, nextChord, key) {
745
809
  const seventhPc = seventhPcOf(prevChord);
746
- const leadingTonePc = key === void 0 ? void 0 : _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, key.rootPc - 1);
747
- const tonicPc = key === void 0 ? void 0 : _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, key.rootPc);
748
- const nextPcs = new Set(_chunkFNDWXRRIcjs.chordPitchClasses.call(void 0, nextChord));
810
+ const leadingTonePc = key === void 0 ? void 0 : _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, key.rootPc - 1);
811
+ const tonicPc = key === void 0 ? void 0 : _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, key.rootPc);
812
+ const nextPcs = new Set(_chunkBSLTLGM3cjs.chordPitchClasses.call(void 0, nextChord));
749
813
  let count = 0;
750
814
  for (let voice = 0; voice < prev.length && voice < cur.length; voice += 1) {
751
815
  const from = prev[voice];
@@ -753,7 +817,7 @@ function resolutionViolations(prev, cur, prevChord, nextChord, key) {
753
817
  if (from === void 0 || to === void 0) {
754
818
  continue;
755
819
  }
756
- const fromPc = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, from);
820
+ const fromPc = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, from);
757
821
  const motion = to - from;
758
822
  if (fromPc === seventhPc && !nextPcs.has(fromPc) && motion !== -1 && motion !== -2) {
759
823
  count += 1;
@@ -775,11 +839,11 @@ function violationCount(prev, cur) {
775
839
  if (prevLower === void 0 || prevUpper === void 0 || curLower === void 0 || curUpper === void 0) {
776
840
  continue;
777
841
  }
778
- if (_chunkFNDWXRRIcjs.createsParallelPerfect.call(void 0, prevUpper, curUpper, prevLower, curLower)) {
842
+ if (_chunkBSLTLGM3cjs.createsParallelPerfect.call(void 0, prevUpper, curUpper, prevLower, curLower)) {
779
843
  count += 1;
780
844
  }
781
845
  if (upper === lower + 1) {
782
- if (_chunkFNDWXRRIcjs.createsVoiceOverlap.call(void 0, prevUpper, curUpper, prevLower, curLower)) {
846
+ if (_chunkBSLTLGM3cjs.createsVoiceOverlap.call(void 0, prevUpper, curUpper, prevLower, curLower)) {
783
847
  count += 1;
784
848
  }
785
849
  }
@@ -808,39 +872,52 @@ function voiceLeadingCost(from, to) {
808
872
  const bassCur = to[0];
809
873
  const sopPrev = from[from.length - 1];
810
874
  const sopCur = to[to.length - 1];
811
- if (bassPrev !== void 0 && bassCur !== void 0 && sopPrev !== void 0 && sopCur !== void 0 && _chunkFNDWXRRIcjs.createsHiddenParallelPerfect.call(void 0, bassPrev, bassCur, sopPrev, sopCur)) {
875
+ if (bassPrev !== void 0 && bassCur !== void 0 && sopPrev !== void 0 && sopCur !== void 0 && _chunkBSLTLGM3cjs.createsHiddenParallelPerfect.call(void 0, bassPrev, bassCur, sopPrev, sopCur)) {
812
876
  total += HIDDEN_PERFECT_PENALTY;
813
877
  }
814
878
  }
815
879
  return total;
816
880
  }
817
881
  function nextVoicing(current, chord, opts) {
818
- const derived = _optionalChain([opts, 'optionalAccess', _6 => _6.ranges]) === void 0 && _optionalChain([opts, 'optionalAccess', _7 => _7.voices]) === void 0;
882
+ const derived = _optionalChain([opts, 'optionalAccess', _8 => _8.ranges]) === void 0 && _optionalChain([opts, 'optionalAccess', _9 => _9.voices]) === void 0;
819
883
  if (derived) {
820
884
  if (current.length === 0) {
821
- throw new (0, _chunk7MGZ7D62cjs.InvalidInputError)("current must contain at least one pitch");
885
+ throw new (0, _chunkPI3UXRWKcjs.InvalidInputError)("current must contain at least one pitch");
822
886
  }
823
887
  for (let index = 0; index < current.length; index += 1) {
824
- _chunk7MGZ7D62cjs.assertFiniteNumber.call(void 0, _nullishCoalesce(current[index], () => ( Number.NaN)), `current[${index}]`);
888
+ _chunkPI3UXRWKcjs.assertFiniteNumber.call(void 0, _nullishCoalesce(current[index], () => ( Number.NaN)), `current[${index}]`);
825
889
  }
826
890
  }
827
891
  const ranges = derived ? current.map((pitch) => {
828
892
  const centre = Math.min(127, Math.max(0, pitch));
829
893
  return { min: Math.max(0, centre - 12), max: Math.min(127, centre + 12) };
830
894
  }) : resolveRanges(opts);
895
+ for (let index = 0; index < current.length; index += 1) {
896
+ _chunkPI3UXRWKcjs.assertFiniteNumber.call(void 0, _nullishCoalesce(current[index], () => ( Number.NaN)), `current[${index}]`);
897
+ }
898
+ if (current.length < ranges.length) {
899
+ throw new (0, _chunkPI3UXRWKcjs.InvalidInputError)(
900
+ `current has ${current.length} voices but the requested ranges require ${ranges.length}`
901
+ );
902
+ }
903
+ const source = current.length === ranges.length ? current : ranges.length === 1 ? [_nullishCoalesce(current[0], () => ( Number.NaN))] : ranges.map((_, index) => {
904
+ const sourceIndex = Math.round(index * (current.length - 1) / (ranges.length - 1));
905
+ return _nullishCoalesce(current[sourceIndex], () => ( Number.NaN));
906
+ });
831
907
  const maxSpacing = resolveMaxSpacing(opts);
832
- const candidates = enumerateVoicings(chord, ranges, maxSpacing);
908
+ const candidates = enumerateVoicings(chord, ranges, maxSpacing, resolveMaxCandidates(opts));
909
+ const previousChord = _optionalChain([opts, 'optionalAccess', _10 => _10.previousChord]);
833
910
  let best;
834
911
  let bestScore = Number.POSITIVE_INFINITY;
835
912
  for (const candidate of candidates) {
836
- const score = structuralPenalty(candidate, chord, _optionalChain([opts, 'optionalAccess', _8 => _8.key])) + voiceLeadingCost(current, candidate) + VIOLATION_PENALTY * violationCount(current, candidate);
913
+ const score = structuralPenalty(candidate, chord, _optionalChain([opts, 'optionalAccess', _11 => _11.key])) + voiceLeadingCost(source, candidate) + VIOLATION_PENALTY * violationCount(source, candidate) + RESOLUTION_PENALTY * (previousChord === void 0 ? 0 : resolutionViolations(source, candidate, previousChord, chord, _optionalChain([opts, 'optionalAccess', _12 => _12.key])));
837
914
  if (score < bestScore) {
838
915
  bestScore = score;
839
916
  best = candidate;
840
917
  }
841
918
  }
842
919
  if (best === void 0) {
843
- throw new (0, _chunk7MGZ7D62cjs.NoSolutionError)("no voicing satisfies the given ranges");
920
+ throw new (0, _chunkPI3UXRWKcjs.NoSolutionError)("no voicing satisfies the given ranges");
844
921
  }
845
922
  return best;
846
923
  }
@@ -856,18 +933,18 @@ var DERIVED_LOW = 40;
856
933
  var DERIVED_HIGH = 79;
857
934
  var DERIVED_SPAN = 19;
858
935
  function resolveRanges(opts) {
859
- if (_optionalChain([opts, 'optionalAccess', _9 => _9.ranges]) !== void 0) {
936
+ if (_optionalChain([opts, 'optionalAccess', _13 => _13.ranges]) !== void 0) {
860
937
  if (opts.ranges.length === 0) {
861
- throw new (0, _chunk7MGZ7D62cjs.InvalidInputError)("ranges must contain at least one voice range");
938
+ throw new (0, _chunkPI3UXRWKcjs.InvalidInputError)("ranges must contain at least one voice range");
862
939
  }
863
- _chunk7MGZ7D62cjs.assertGenerationBudget.call(void 0, opts.ranges.length, "voice ranges", 128);
940
+ _chunkPI3UXRWKcjs.assertGenerationBudget.call(void 0, opts.ranges.length, "voice ranges", 128);
864
941
  return opts.ranges.map((range, index) => {
865
- _chunk7MGZ7D62cjs.assertFiniteNumber.call(void 0, range.min, `ranges[${index}].min`);
866
- _chunk7MGZ7D62cjs.assertFiniteNumber.call(void 0, range.max, `ranges[${index}].max`);
942
+ _chunkPI3UXRWKcjs.assertFiniteNumber.call(void 0, range.min, `ranges[${index}].min`);
943
+ _chunkPI3UXRWKcjs.assertFiniteNumber.call(void 0, range.max, `ranges[${index}].max`);
867
944
  if (range.min > range.max) {
868
- throw new (0, _chunk7MGZ7D62cjs.InvalidInputError)(`ranges[${index}].min must not exceed max`);
945
+ throw new (0, _chunkPI3UXRWKcjs.InvalidInputError)(`ranges[${index}].min must not exceed max`);
869
946
  }
870
- _chunk7MGZ7D62cjs.assertGenerationBudget.call(void 0,
947
+ _chunkPI3UXRWKcjs.assertGenerationBudget.call(void 0,
871
948
  Math.floor(range.max) - Math.ceil(range.min) + 1,
872
949
  `ranges[${index}] span`,
873
950
  4096
@@ -875,8 +952,8 @@ function resolveRanges(opts) {
875
952
  return { ...range };
876
953
  });
877
954
  }
878
- const voices = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _10 => _10.voices]), () => ( 4));
879
- _chunk7MGZ7D62cjs.assertPositiveInt.call(void 0, voices, "voices", 128);
955
+ const voices = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _14 => _14.voices]), () => ( 4));
956
+ _chunkPI3UXRWKcjs.assertPositiveInt.call(void 0, voices, "voices", 128);
880
957
  if (voices === 4) {
881
958
  return SATB_RANGES.map((range) => ({ ...range }));
882
959
  }
@@ -893,21 +970,26 @@ function resolveRanges(opts) {
893
970
  return ranges;
894
971
  }
895
972
  function resolveMaxSpacing(opts) {
896
- const maxSpacing = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _11 => _11.maxSpacing]), () => ( DEFAULT_MAX_SPACING));
897
- _chunk7MGZ7D62cjs.assertFiniteNumber.call(void 0, maxSpacing, "maxSpacing");
973
+ const maxSpacing = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _15 => _15.maxSpacing]), () => ( DEFAULT_MAX_SPACING));
974
+ _chunkPI3UXRWKcjs.assertFiniteNumber.call(void 0, maxSpacing, "maxSpacing");
898
975
  if (maxSpacing < 0) {
899
- throw new (0, _chunk7MGZ7D62cjs.InvalidInputError)("maxSpacing must be non-negative");
976
+ throw new (0, _chunkPI3UXRWKcjs.InvalidInputError)("maxSpacing must be non-negative");
900
977
  }
901
978
  return maxSpacing;
902
979
  }
980
+ function resolveMaxCandidates(opts) {
981
+ if (_optionalChain([opts, 'optionalAccess', _16 => _16.maxCandidates]) === void 0) return void 0;
982
+ _chunkPI3UXRWKcjs.assertPositiveInt.call(void 0, opts.maxCandidates, "maxCandidates", 1e6);
983
+ return opts.maxCandidates;
984
+ }
903
985
  function voiceChord(chord, opts) {
904
986
  const ranges = resolveRanges(opts);
905
987
  const maxSpacing = resolveMaxSpacing(opts);
906
- const candidates = enumerateVoicings(chord, ranges, maxSpacing);
988
+ const candidates = enumerateVoicings(chord, ranges, maxSpacing, resolveMaxCandidates(opts));
907
989
  let best;
908
990
  let bestScore = Number.POSITIVE_INFINITY;
909
991
  for (const candidate of candidates) {
910
- let score = structuralPenalty(candidate, chord, _optionalChain([opts, 'optionalAccess', _12 => _12.key]));
992
+ let score = structuralPenalty(candidate, chord, _optionalChain([opts, 'optionalAccess', _17 => _17.key]));
911
993
  for (let i = 0; i < candidate.length; i += 1) {
912
994
  const pitch = candidate[i];
913
995
  const range = ranges[i];
@@ -922,14 +1004,14 @@ function voiceChord(chord, opts) {
922
1004
  }
923
1005
  }
924
1006
  if (best === void 0) {
925
- throw new (0, _chunk7MGZ7D62cjs.NoSolutionError)(
1007
+ throw new (0, _chunkPI3UXRWKcjs.NoSolutionError)(
926
1008
  `no voicing satisfies the given ranges for ${formatChordSymbol(chord)}`
927
1009
  );
928
1010
  }
929
1011
  return best;
930
1012
  }
931
1013
  function noSolutionAt(index, chord) {
932
- return new (0, _chunk7MGZ7D62cjs.NoSolutionError)(
1014
+ return new (0, _chunkPI3UXRWKcjs.NoSolutionError)(
933
1015
  `no voicing satisfies the given ranges for ${formatChordSymbol(chord)} at index ${index}`,
934
1016
  { at: index }
935
1017
  );
@@ -938,16 +1020,17 @@ function locate(index, chord, work) {
938
1020
  try {
939
1021
  return work();
940
1022
  } catch (error) {
941
- if (error instanceof _chunk7MGZ7D62cjs.NoSolutionError) {
1023
+ if (error instanceof _chunkPI3UXRWKcjs.NoSolutionError) {
942
1024
  throw noSolutionAt(index, chord);
943
1025
  }
944
1026
  throw error;
945
1027
  }
946
1028
  }
947
1029
  function voiceProgression(chords, opts) {
948
- _chunk7MGZ7D62cjs.assertGenerationBudget.call(void 0, chords.length, "voiced progression chords", _optionalChain([opts, 'optionalAccess', _13 => _13.budget]));
1030
+ _chunkPI3UXRWKcjs.assertGenerationBudget.call(void 0, chords.length, "voiced progression chords", _optionalChain([opts, 'optionalAccess', _18 => _18.budget]));
949
1031
  const ranges = resolveRanges(opts);
950
1032
  const maxSpacing = resolveMaxSpacing(opts);
1033
+ const maxCandidates = resolveMaxCandidates(opts);
951
1034
  const result = [];
952
1035
  let prev;
953
1036
  let prevChord;
@@ -962,12 +1045,16 @@ function voiceProgression(chords, opts) {
962
1045
  result.push(prev);
963
1046
  continue;
964
1047
  }
965
- const candidates = locate(index, chord, () => enumerateVoicings(chord, ranges, maxSpacing));
1048
+ const candidates = locate(
1049
+ index,
1050
+ chord,
1051
+ () => enumerateVoicings(chord, ranges, maxSpacing, maxCandidates)
1052
+ );
966
1053
  let best;
967
1054
  let bestScore = Number.POSITIVE_INFINITY;
968
1055
  for (const candidate of candidates) {
969
- const unresolved = prevChord === void 0 ? 0 : resolutionViolations(prev, candidate, prevChord, chord, _optionalChain([opts, 'optionalAccess', _14 => _14.key]));
970
- const score = structuralPenalty(candidate, chord, _optionalChain([opts, 'optionalAccess', _15 => _15.key])) + voiceLeadingCost(prev, candidate) + VIOLATION_PENALTY * violationCount(prev, candidate) + RESOLUTION_PENALTY * unresolved;
1056
+ const unresolved = prevChord === void 0 ? 0 : resolutionViolations(prev, candidate, prevChord, chord, _optionalChain([opts, 'optionalAccess', _19 => _19.key]));
1057
+ const score = structuralPenalty(candidate, chord, _optionalChain([opts, 'optionalAccess', _20 => _20.key])) + voiceLeadingCost(prev, candidate) + VIOLATION_PENALTY * violationCount(prev, candidate) + RESOLUTION_PENALTY * unresolved;
971
1058
  if (score < bestScore) {
972
1059
  bestScore = score;
973
1060
  best = candidate;
@@ -997,7 +1084,7 @@ function dedupePcs(pcs) {
997
1084
  return result;
998
1085
  }
999
1086
  function lowestPitchAtOrAbove(pc, floor) {
1000
- return floor + ((pc - _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, floor)) % 12 + 12) % 12;
1087
+ return floor + ((pc - _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, floor)) % 12 + 12) % 12;
1001
1088
  }
1002
1089
  function nearestPc(target, pcs) {
1003
1090
  let best = _nullishCoalesce(pcs[0], () => ( target));
@@ -1012,17 +1099,17 @@ function nearestPc(target, pcs) {
1012
1099
  return best;
1013
1100
  }
1014
1101
  function voiceChordStyled(chord, opts) {
1015
- const style = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _16 => _16.style]), () => ( "close"));
1016
- const octave = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _17 => _17.octave]), () => ( DEFAULT_STYLE_OCTAVE));
1017
- _chunk7MGZ7D62cjs.assertInteger.call(void 0, octave, "styled voicing octave", -10, 10);
1018
- if (_optionalChain([opts, 'optionalAccess', _18 => _18.topNote]) !== void 0) {
1019
- _chunk7MGZ7D62cjs.assertFiniteNumber.call(void 0, opts.topNote, "styled voicing topNote");
1102
+ const style = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _21 => _21.style]), () => ( "close"));
1103
+ const octave = _nullishCoalesce(_optionalChain([opts, 'optionalAccess', _22 => _22.octave]), () => ( DEFAULT_STYLE_OCTAVE));
1104
+ _chunkPI3UXRWKcjs.assertInteger.call(void 0, octave, "styled voicing octave", -10, 10);
1105
+ if (_optionalChain([opts, 'optionalAccess', _23 => _23.topNote]) !== void 0) {
1106
+ _chunkPI3UXRWKcjs.assertFiniteNumber.call(void 0, opts.topNote, "styled voicing topNote");
1020
1107
  }
1021
1108
  const base = 12 * (octave + 1);
1022
- const rootPc = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, chord.rootPc);
1023
- const bassPc = _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, _nullishCoalesce(chord.bassPc, () => ( chord.rootPc)));
1024
- const omitRoot = style === "rootless" || _optionalChain([opts, 'optionalAccess', _19 => _19.rootless]) === true;
1025
- let order = dedupePcs(chord.intervals.map((interval) => _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, chord.rootPc + interval)));
1109
+ const rootPc = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.rootPc);
1110
+ const bassPc = _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, _nullishCoalesce(chord.bassPc, () => ( chord.rootPc)));
1111
+ const omitRoot = style === "rootless" || _optionalChain([opts, 'optionalAccess', _24 => _24.rootless]) === true;
1112
+ let order = dedupePcs(chord.intervals.map((interval) => _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, chord.rootPc + interval)));
1026
1113
  const bassIndex = order.indexOf(bassPc);
1027
1114
  if (bassIndex > 0) {
1028
1115
  order = [...order.slice(bassIndex), ...order.slice(0, bassIndex)];
@@ -1030,7 +1117,7 @@ function voiceChordStyled(chord, opts) {
1030
1117
  order = [bassPc, ...order];
1031
1118
  }
1032
1119
  if (style === "shell") {
1033
- const roles = order.map((pc) => _chunkFNDWXRRIcjs.chordToneRole.call(void 0, pc, chord));
1120
+ const roles = order.map((pc) => _chunkBSLTLGM3cjs.chordToneRole.call(void 0, pc, chord));
1034
1121
  const guide = roles.includes("seventh") ? "seventh" : roles.includes("sixth") ? "sixth" : "fifth";
1035
1122
  order = order.filter((_pc, i) => {
1036
1123
  const role = roles[i];
@@ -1043,8 +1130,8 @@ function voiceChordStyled(chord, opts) {
1043
1130
  if (order.length === 0) {
1044
1131
  return [];
1045
1132
  }
1046
- if (_optionalChain([opts, 'optionalAccess', _20 => _20.topNote]) !== void 0) {
1047
- const target = order.includes(_chunk7MGZ7D62cjs.pitchClassOf.call(void 0, opts.topNote)) ? _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, opts.topNote) : nearestPc(_chunk7MGZ7D62cjs.pitchClassOf.call(void 0, opts.topNote), order);
1133
+ if (_optionalChain([opts, 'optionalAccess', _25 => _25.topNote]) !== void 0) {
1134
+ const target = order.includes(_chunkPI3UXRWKcjs.pitchClassOf.call(void 0, opts.topNote)) ? _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, opts.topNote) : nearestPc(_chunkPI3UXRWKcjs.pitchClassOf.call(void 0, opts.topNote), order);
1048
1135
  const targetIndex = order.indexOf(target);
1049
1136
  order = [...order.slice(targetIndex + 1), ...order.slice(0, targetIndex + 1)];
1050
1137
  }
@@ -1054,7 +1141,7 @@ function voiceChordStyled(chord, opts) {
1054
1141
  if (prev === void 0) {
1055
1142
  prev = lowestPitchAtOrAbove(pc, base);
1056
1143
  } else {
1057
- let delta = ((pc - _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, prev)) % 12 + 12) % 12;
1144
+ let delta = ((pc - _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, prev)) % 12 + 12) % 12;
1058
1145
  if (delta === 0) {
1059
1146
  delta = 12;
1060
1147
  }
@@ -1068,7 +1155,7 @@ function voiceChordStyled(chord, opts) {
1068
1155
  stack[stack.length - 3] = (_nullishCoalesce(stack[stack.length - 3], () => ( 0))) - 12;
1069
1156
  }
1070
1157
  if (chord.bassPc !== void 0) {
1071
- const bassIndexInStack = stack.findIndex((pitch) => _chunk7MGZ7D62cjs.pitchClassOf.call(void 0, pitch) === bassPc);
1158
+ const bassIndexInStack = stack.findIndex((pitch) => _chunkPI3UXRWKcjs.pitchClassOf.call(void 0, pitch) === bassPc);
1072
1159
  if (bassIndexInStack >= 0) {
1073
1160
  const otherLowest = Math.min(
1074
1161
  ...stack.filter((_pitch, index) => index !== bassIndexInStack),
@@ -1083,7 +1170,7 @@ function voiceChordStyled(chord, opts) {
1083
1170
  const lowest = _nullishCoalesce(voicing[0], () => ( 0));
1084
1171
  const highest = _nullishCoalesce(voicing[voicing.length - 1], () => ( 0));
1085
1172
  if (lowest < 0 || highest > 127) {
1086
- throw new (0, _chunk7MGZ7D62cjs.InvalidInputError)(
1173
+ throw new (0, _chunkPI3UXRWKcjs.InvalidInputError)(
1087
1174
  `styled voicing at octave ${octave} spans MIDI ${lowest}..${highest}, outside 0..127`
1088
1175
  );
1089
1176
  }
@@ -1114,4 +1201,4 @@ function voiceChordStyled(chord, opts) {
1114
1201
 
1115
1202
 
1116
1203
  exports.scaleMatchesChord = scaleMatchesChord; exports.chordScales = chordScales; exports.avoidNotes = avoidNotes; exports.availableTensions = availableTensions; exports.chordScaleReport = chordScaleReport; exports.scalesForChanges = scalesForChanges; exports.spellPitchClass = spellPitchClass; exports.spellScale = spellScale; exports.spellPitchClasses = spellPitchClasses; exports.spellChordFromRoot = spellChordFromRoot; exports.spellChord = spellChord; exports.spellPitch = spellPitch; exports.noteNames = noteNames; exports.parseChordSymbol = parseChordSymbol; exports.formatChordSymbol = formatChordSymbol; exports.transposeChordSymbol = transposeChordSymbol; exports.SATB_RANGES = SATB_RANGES; exports.voiceChord = voiceChord; exports.voiceProgression = voiceProgression; exports.voiceLeadingCost = voiceLeadingCost; exports.nextVoicing = nextVoicing; exports.voiceChordStyled = voiceChordStyled;
1117
- //# sourceMappingURL=chunk-LW53AHQU.cjs.map
1204
+ //# sourceMappingURL=chunk-OL3IHHSJ.cjs.map