@libraz/libcantus 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/NOTICE +63 -0
  2. package/README.md +7 -1
  3. package/README_ja.md +17 -11
  4. package/dist/analyze/index.cjs +31 -7
  5. package/dist/analyze/index.cjs.map +1 -1
  6. package/dist/analyze/index.d.cts +161 -13
  7. package/dist/analyze/index.d.ts +161 -13
  8. package/dist/analyze/index.js +37 -13
  9. package/dist/{chunk-NB25P3EH.js → chunk-2G5MCGYU.js} +33 -11
  10. package/dist/chunk-2G5MCGYU.js.map +1 -0
  11. package/dist/{chunk-NM7UAMC3.cjs → chunk-3FDBMIPR.cjs} +64 -64
  12. package/dist/chunk-3FDBMIPR.cjs.map +1 -0
  13. package/dist/{chunk-HPVSH7SF.cjs → chunk-3MDOEFIQ.cjs} +618 -954
  14. package/dist/chunk-3MDOEFIQ.cjs.map +1 -0
  15. package/dist/{chunk-FBH75DAY.js → chunk-5MWRBYAT.js} +560 -159
  16. package/dist/chunk-5MWRBYAT.js.map +1 -0
  17. package/dist/{chunk-J7FHVZII.cjs → chunk-6TTBEON3.cjs} +3074 -740
  18. package/dist/chunk-6TTBEON3.cjs.map +1 -0
  19. package/dist/{chunk-UMWZ4ZET.js → chunk-7NQ6AL3H.js} +4 -4
  20. package/dist/chunk-7NQ6AL3H.js.map +1 -0
  21. package/dist/{chunk-HWHGOVO6.cjs → chunk-E3QO3UET.cjs} +31 -23
  22. package/dist/chunk-E3QO3UET.cjs.map +1 -0
  23. package/dist/{chunk-H2KJHBW4.js → chunk-FJFULJZE.js} +2375 -191
  24. package/dist/chunk-FJFULJZE.js.map +1 -0
  25. package/dist/{chunk-Q6LFSAKV.js → chunk-FK3DGAIZ.js} +2657 -323
  26. package/dist/chunk-FK3DGAIZ.js.map +1 -0
  27. package/dist/chunk-GEDTJHAC.cjs.map +1 -1
  28. package/dist/{chunk-RFIBF2RR.js → chunk-H7FVMBUC.js} +138 -65
  29. package/dist/chunk-H7FVMBUC.js.map +1 -0
  30. package/dist/{chunk-DSMJRXCZ.cjs → chunk-HYSVSFNI.cjs} +931 -530
  31. package/dist/chunk-HYSVSFNI.cjs.map +1 -0
  32. package/dist/{chunk-35NBV2FT.cjs → chunk-KMYGRFZ6.cjs} +47 -24
  33. package/dist/chunk-KMYGRFZ6.cjs.map +1 -0
  34. package/dist/chunk-LQZQDBCD.cjs +5513 -0
  35. package/dist/chunk-LQZQDBCD.cjs.map +1 -0
  36. package/dist/{chunk-PM4XJE2Y.cjs → chunk-P3CPXAJ5.cjs} +76 -54
  37. package/dist/chunk-P3CPXAJ5.cjs.map +1 -0
  38. package/dist/{chunk-S5BKZZGM.cjs → chunk-S3QELJUE.cjs} +72 -56
  39. package/dist/chunk-S3QELJUE.cjs.map +1 -0
  40. package/dist/{chunk-PUKJP2Z5.js → chunk-TXFWSU5D.js} +31 -8
  41. package/dist/chunk-TXFWSU5D.js.map +1 -0
  42. package/dist/{chunk-76ZBTRG2.cjs → chunk-U4EQTDGN.cjs} +258 -218
  43. package/dist/chunk-U4EQTDGN.cjs.map +1 -0
  44. package/dist/chunk-UGLFDG7L.cjs.map +1 -1
  45. package/dist/{chunk-HYJJ2V2I.js → chunk-UTE5A36R.js} +483 -819
  46. package/dist/chunk-UTE5A36R.js.map +1 -0
  47. package/dist/{chunk-NFJ4P6ZZ.js → chunk-UZKQISRF.js} +17 -9
  48. package/dist/chunk-UZKQISRF.js.map +1 -0
  49. package/dist/{chunk-7KG3RTYS.js → chunk-VL5NXVCN.js} +281 -155
  50. package/dist/chunk-VL5NXVCN.js.map +1 -0
  51. package/dist/{chunk-CGBADIO5.cjs → chunk-WOMCXN2W.cjs} +328 -202
  52. package/dist/chunk-WOMCXN2W.cjs.map +1 -0
  53. package/dist/{chunk-3R3QVKY5.cjs → chunk-YDGMWH43.cjs} +397 -324
  54. package/dist/chunk-YDGMWH43.cjs.map +1 -0
  55. package/dist/{chunk-AGOVW7U6.js → chunk-YYVXRV3V.js} +72 -56
  56. package/dist/chunk-YYVXRV3V.js.map +1 -0
  57. package/dist/{chunk-M5RYMAFI.js → chunk-ZLNSH4UL.js} +71 -31
  58. package/dist/chunk-ZLNSH4UL.js.map +1 -0
  59. package/dist/{coerce-DRERzdve.d.cts → coerce-CUhHc3Tu.d.ts} +16 -8
  60. package/dist/{coerce-DP0vYu-x.d.ts → coerce-Ytt2Eiq9.d.cts} +16 -8
  61. package/dist/core/index.cjs +5 -5
  62. package/dist/core/index.cjs.map +1 -1
  63. package/dist/core/index.d.cts +9 -8
  64. package/dist/core/index.d.ts +9 -8
  65. package/dist/core/index.js +4 -4
  66. package/dist/generate/index.cjs +20 -8
  67. package/dist/generate/index.cjs.map +1 -1
  68. package/dist/generate/index.d.cts +105 -17
  69. package/dist/generate/index.d.ts +105 -17
  70. package/dist/generate/index.js +19 -7
  71. package/dist/{index-CL4b4gUQ.d.ts → index-5VJgKz_Q.d.cts} +6 -2
  72. package/dist/{index-B9QLziDe.d.cts → index-BLuDesVG.d.ts} +20 -13
  73. package/dist/{index-BHIUyjhZ.d.ts → index-BV6APVa6.d.cts} +20 -13
  74. package/dist/{index-BMweUlm5.d.cts → index-Bf0Sv8a9.d.ts} +6 -2
  75. package/dist/{index-Dw2DP7vm.d.ts → index-BkT21EMv.d.cts} +3 -2
  76. package/dist/{index-BL5N2Oyz.d.cts → index-C7KCaTRz.d.ts} +3 -2
  77. package/dist/{index-Cy15oTvh.d.ts → index-C9MYbuKS.d.cts} +7 -3
  78. package/dist/{index-Cy15oTvh.d.cts → index-C9MYbuKS.d.ts} +7 -3
  79. package/dist/{index-BNSM-DSk.d.cts → index-DVInzCDS.d.cts} +533 -28
  80. package/dist/{index-9eoQs2C1.d.ts → index-Dg-SAfhz.d.ts} +6 -4
  81. package/dist/{index-BJgP97N1.d.ts → index-jgeug9EA.d.ts} +533 -28
  82. package/dist/{index-cHvbYgJI.d.cts → index-pQihL4z7.d.cts} +6 -4
  83. package/dist/index.cjs +49 -13
  84. package/dist/index.cjs.map +1 -1
  85. package/dist/index.d.cts +13 -13
  86. package/dist/index.d.ts +13 -13
  87. package/dist/index.js +55 -19
  88. package/dist/{masks-Cc7-MzzY.d.ts → masks-BnzXnBj0.d.cts} +3 -2
  89. package/dist/{masks-pADfTOiD.d.cts → masks-tycmkrgs.d.ts} +3 -2
  90. package/dist/model/index.cjs +12 -12
  91. package/dist/model/index.cjs.map +1 -1
  92. package/dist/model/index.d.cts +259 -48
  93. package/dist/model/index.d.ts +259 -48
  94. package/dist/model/index.js +11 -11
  95. package/dist/{positional-DJgs6ltD.d.ts → positional-CscpxtlE.d.cts} +3 -2
  96. package/dist/{positional-DMZer-FM.d.cts → positional-DLnfUgqG.d.ts} +3 -2
  97. package/dist/{index-BRMbPkHE.d.ts → profile-B4WqcM4H.d.ts} +85 -610
  98. package/dist/{index-DGCNKAUr.d.cts → profile-BJd1XkPB.d.cts} +85 -610
  99. package/dist/theory/index.cjs +5 -5
  100. package/dist/theory/index.cjs.map +1 -1
  101. package/dist/theory/index.d.cts +18 -14
  102. package/dist/theory/index.d.ts +18 -14
  103. package/dist/theory/index.js +4 -4
  104. package/dist/{index-CJBBiAmU.d.ts → types-7mGFwvMm.d.ts} +1210 -31
  105. package/dist/{index-BBWNZS0f.d.cts → types-_ofpb2be.d.cts} +1210 -31
  106. package/package.json +13 -13
  107. package/dist/chunk-35NBV2FT.cjs.map +0 -1
  108. package/dist/chunk-3R3QVKY5.cjs.map +0 -1
  109. package/dist/chunk-76ZBTRG2.cjs.map +0 -1
  110. package/dist/chunk-7KG3RTYS.js.map +0 -1
  111. package/dist/chunk-AGOVW7U6.js.map +0 -1
  112. package/dist/chunk-CGBADIO5.cjs.map +0 -1
  113. package/dist/chunk-DSMJRXCZ.cjs.map +0 -1
  114. package/dist/chunk-FBH75DAY.js.map +0 -1
  115. package/dist/chunk-H2KJHBW4.js.map +0 -1
  116. package/dist/chunk-HPVSH7SF.cjs.map +0 -1
  117. package/dist/chunk-HWHGOVO6.cjs.map +0 -1
  118. package/dist/chunk-HYJJ2V2I.js.map +0 -1
  119. package/dist/chunk-J7FHVZII.cjs.map +0 -1
  120. package/dist/chunk-M5RYMAFI.js.map +0 -1
  121. package/dist/chunk-NB25P3EH.js.map +0 -1
  122. package/dist/chunk-NFJ4P6ZZ.js.map +0 -1
  123. package/dist/chunk-NM7UAMC3.cjs.map +0 -1
  124. package/dist/chunk-PM4XJE2Y.cjs.map +0 -1
  125. package/dist/chunk-PUKJP2Z5.js.map +0 -1
  126. package/dist/chunk-Q6LFSAKV.js.map +0 -1
  127. package/dist/chunk-RFIBF2RR.js.map +0 -1
  128. package/dist/chunk-S5BKZZGM.cjs.map +0 -1
  129. package/dist/chunk-SGLEQVJH.cjs +0 -3329
  130. package/dist/chunk-SGLEQVJH.cjs.map +0 -1
  131. package/dist/chunk-UMWZ4ZET.js.map +0 -1
@@ -33,14 +33,14 @@
33
33
 
34
34
 
35
35
 
36
- var _chunkS5BKZZGMcjs = require('./chunk-S5BKZZGM.cjs');
36
+ var _chunkS3QELJUEcjs = require('./chunk-S3QELJUE.cjs');
37
37
 
38
38
  // src/theory/scale/masks.ts
39
39
  function maskFromOffsets(offsets) {
40
- _chunkS5BKZZGMcjs.assertArray.call(void 0, offsets, "offsets");
40
+ _chunkS3QELJUEcjs.assertArray.call(void 0, offsets, "offsets");
41
41
  let mask = 1;
42
42
  for (const [index, offset] of offsets.entries()) {
43
- _chunkS5BKZZGMcjs.assertInteger.call(void 0, offset, `offsets[${index}]`);
43
+ _chunkS3QELJUEcjs.assertInteger.call(void 0, offset, `offsets[${index}]`);
44
44
  mask |= 1 << (offset % 12 + 12) % 12;
45
45
  }
46
46
  return mask;
@@ -62,10 +62,10 @@ var OCTATONIC_HALF_WHOLE_MASK = maskFromOffsets([0, 1, 3, 4, 6, 7, 9, 10]);
62
62
  var OCTATONIC_WHOLE_HALF_MASK = maskFromOffsets([0, 2, 3, 5, 6, 8, 9, 11]);
63
63
  var CHROMATIC_MASK = 4095;
64
64
  function assertModeMask(modeMask12, name = "modeMask12") {
65
- return _chunkS5BKZZGMcjs.assertInteger.call(void 0, modeMask12, name, 1, CHROMATIC_MASK);
65
+ return _chunkS3QELJUEcjs.assertInteger.call(void 0, modeMask12, name, 1, CHROMATIC_MASK);
66
66
  }
67
67
  function maskOf(scale, name = "key") {
68
- return assertModeMask(_chunkS5BKZZGMcjs.assertRecord.call(void 0, scale, name).modeMask12, `${name}.modeMask12`);
68
+ return assertModeMask(_chunkS3QELJUEcjs.assertRecord.call(void 0, scale, name).modeMask12, `${name}.modeMask12`);
69
69
  }
70
70
  var LYDIAN_DOMINANT_MASK = maskFromOffsets([0, 2, 4, 6, 7, 9, 10]);
71
71
  var MIXOLYDIAN_B13_MASK = maskFromOffsets([0, 2, 4, 5, 7, 8, 10]);
@@ -173,7 +173,7 @@ var SCALE_ALIASES = Object.freeze({
173
173
  });
174
174
  function resolveScaleName(name) {
175
175
  if (typeof name !== "string") {
176
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`scale name must be a string; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, name)}`);
176
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`scale name must be a string; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, name)}`);
177
177
  }
178
178
  if (Object.hasOwn(NAMED_SCALES, name)) {
179
179
  return name;
@@ -193,7 +193,7 @@ function namedScaleMask(name) {
193
193
  function requireScaleMask(name, label = "scale") {
194
194
  const mask = namedScaleMask(name);
195
195
  if (mask === void 0) {
196
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Unknown ${label}: ${String(name)}`);
196
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`Unknown ${label}: ${String(name)}`);
197
197
  }
198
198
  return mask;
199
199
  }
@@ -220,12 +220,12 @@ var KEY_VARIANTS = [
220
220
  "modal"
221
221
  ];
222
222
  function assertKeyVariant(variant, modeMask12) {
223
- _chunkS5BKZZGMcjs.assertOneOf.call(void 0, variant, KEY_VARIANTS, "variant");
223
+ _chunkS3QELJUEcjs.assertOneOf.call(void 0, variant, KEY_VARIANTS, "variant");
224
224
  assertModeMask(modeMask12);
225
225
  const named = VARIANT_MASKS[variant];
226
226
  const matches = named === void 0 ? !Object.values(VARIANT_MASKS).includes(modeMask12) : named === modeMask12;
227
227
  if (!matches) {
228
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
228
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
229
229
  `variant ${variant} does not match the scale mask ${modeMask12}; pass the scale that variant names, or omit the variant`
230
230
  );
231
231
  }
@@ -233,13 +233,13 @@ function assertKeyVariant(variant, modeMask12) {
233
233
 
234
234
  // src/theory/scale/scales.ts
235
235
  function majorScale(rootPc) {
236
- return { rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, rootPc), modeMask12: MAJOR_MASK };
236
+ return { rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, rootPc), modeMask12: MAJOR_MASK };
237
237
  }
238
238
  function minorScale(rootPc) {
239
- return { rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, rootPc), modeMask12: NATURAL_MINOR_MASK };
239
+ return { rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, rootPc), modeMask12: NATURAL_MINOR_MASK };
240
240
  }
241
241
  function namedScale(name, rootPc) {
242
- return { rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, rootPc), modeMask12: requireScaleMask(name) };
242
+ return { rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, rootPc), modeMask12: requireScaleMask(name) };
243
243
  }
244
244
 
245
245
  // src/theory/scale/name.ts
@@ -280,43 +280,43 @@ function tryNamedScaleKey(text) {
280
280
  if (name === void 0) {
281
281
  return null;
282
282
  }
283
- const tonic = _chunkS5BKZZGMcjs.tryParseNote.call(void 0, trimmed.slice(0, separator));
283
+ const tonic = _chunkS3QELJUEcjs.tryParseNote.call(void 0, trimmed.slice(0, separator));
284
284
  if (!tonic.ok) {
285
285
  return null;
286
286
  }
287
- const scale = namedScale(name, _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, tonic.value));
287
+ const scale = namedScale(name, _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, tonic.value));
288
288
  return { scale, tonic: bareTonic(tonic.value), variant: variantOfMask(scale.modeMask12) };
289
289
  }
290
290
  function tryResolveKeyName(text, opts) {
291
- const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
291
+ const asked = _chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "opts");
292
292
  if (typeof text === "string" && (asked.system === void 0 || asked.system === "english")) {
293
293
  const named = tryNamedScaleKey(text);
294
294
  if (named !== null) {
295
295
  return { ok: true, value: named };
296
296
  }
297
297
  }
298
- const parsed = _chunkS5BKZZGMcjs.tryParseKeyName.call(void 0, text, asked);
298
+ const parsed = _chunkS3QELJUEcjs.tryParseKeyName.call(void 0, text, asked);
299
299
  if (!parsed.ok) {
300
300
  return parsed;
301
301
  }
302
302
  const tonic = bareTonic(parsed.value.tonic);
303
- const rootPc = _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, tonic);
303
+ const rootPc = _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, tonic);
304
304
  return parsed.value.mode === "major" ? { ok: true, value: { scale: majorScale(rootPc), tonic, variant: "major" } } : { ok: true, value: { scale: minorScale(rootPc), tonic, variant: "natural" } };
305
305
  }
306
306
  function resolveKeyName(text, opts) {
307
- return _chunkS5BKZZGMcjs.unwrapParse.call(void 0, tryResolveKeyName(text, opts));
307
+ return _chunkS3QELJUEcjs.unwrapParse.call(void 0, tryResolveKeyName(text, opts));
308
308
  }
309
309
 
310
310
  // src/theory/scale/coerce.ts
311
311
  function normalizedKeyScale(scale) {
312
312
  assertModeMask(scale.modeMask12, "key.modeMask12");
313
313
  if ((scale.modeMask12 & 1) === 0) {
314
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
314
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
315
315
  `key.modeMask12 must include its root; received ${scale.modeMask12}`
316
316
  );
317
317
  }
318
- _chunkS5BKZZGMcjs.assertInteger.call(void 0, scale.rootPc, "key.rootPc");
319
- return { rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, scale.rootPc), modeMask12: scale.modeMask12 };
318
+ _chunkS3QELJUEcjs.assertInteger.call(void 0, scale.rootPc, "key.rootPc");
319
+ return { rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, scale.rootPc), modeMask12: scale.modeMask12 };
320
320
  }
321
321
  function toKeyScale(value) {
322
322
  if (typeof value === "string") {
@@ -328,12 +328,14 @@ function toKeyScale(value) {
328
328
  return normalizedKeyScale(data);
329
329
  }
330
330
  }
331
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`key must be a key name or a key/scale; received ${typeof value}`);
331
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
332
+ `key must be a key name or a key/scale; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, value)}`
333
+ );
332
334
  }
333
335
 
334
336
  // src/theory/scale/degrees.ts
335
337
  function scaleOffset(pitch, key) {
336
- return (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch) - _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc) + 12) % 12;
338
+ return (_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pitch) - _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc) + 12) % 12;
337
339
  }
338
340
  function inScale(pitch, scale) {
339
341
  return (scale.modeMask12 >> scaleOffset(pitch, scale) & 1) === 1;
@@ -343,8 +345,8 @@ function isScaleTone(pitch, key) {
343
345
  }
344
346
  function nearestScaleTone(pitch, key) {
345
347
  const scale = toKeyScale(key);
346
- _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, pitch, "pitch");
347
- const base = _chunkS5BKZZGMcjs.clampToMidi.call(void 0, Math.round(pitch), "pitch");
348
+ _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, pitch, "pitch");
349
+ const base = _chunkS3QELJUEcjs.clampToMidi.call(void 0, Math.round(pitch), "pitch");
348
350
  for (let distance = 0; distance < 12; distance += 1) {
349
351
  const lower = base - distance;
350
352
  if (lower >= 0 && inScale(lower, scale)) {
@@ -370,13 +372,13 @@ function scaleLadderPosition(pitch, key) {
370
372
  return ladderPosition(pitch, toKeyScale(key));
371
373
  }
372
374
  function ladderPosition(pitch, key) {
373
- _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, pitch, "pitch");
375
+ _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, pitch, "pitch");
374
376
  const offsets = scaleOffsets(key);
375
377
  const size = offsets.length;
376
378
  if (size === 0) {
377
379
  return { rung: 0, offset: 0 };
378
380
  }
379
- const relative = pitch - _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc);
381
+ const relative = pitch - _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc);
380
382
  const octave = Math.floor(relative / 12);
381
383
  const within = relative - octave * 12;
382
384
  let degree = 0;
@@ -391,19 +393,19 @@ function scaleLadderPitch(rung, key) {
391
393
  return ladderPitch(rung, toKeyScale(key));
392
394
  }
393
395
  function ladderPitch(rung, key) {
394
- _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, rung, "rung");
396
+ _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, rung, "rung");
395
397
  const offsets = scaleOffsets(key);
396
398
  const size = offsets.length;
397
399
  if (size === 0) {
398
- return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc);
400
+ return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc);
399
401
  }
400
402
  const octave = Math.floor(rung / size);
401
403
  const degree = rung - octave * size;
402
- return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc) + octave * 12 + (_nullishCoalesce(offsets[degree], () => ( 0)));
404
+ return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc) + octave * 12 + (_nullishCoalesce(offsets[degree], () => ( 0)));
403
405
  }
404
406
  function shiftByScaleDegrees(pitch, degrees, key) {
405
407
  const scale = toKeyScale(key);
406
- const steps = Math.trunc(_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, degrees, "degrees"));
408
+ const steps = Math.trunc(_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, degrees, "degrees"));
407
409
  if (steps === 0) {
408
410
  return pitch;
409
411
  }
@@ -429,7 +431,7 @@ function diatonicPitchClasses(key) {
429
431
  }
430
432
  function scaleTonesInDegreeOrder(key) {
431
433
  const scale = toKeyScale(key);
432
- const root = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, scale.rootPc);
434
+ const root = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, scale.rootPc);
433
435
  const pcs = [];
434
436
  for (let n = 0; n < 12; n += 1) {
435
437
  if ((scale.modeMask12 >> n & 1) === 1) {
@@ -449,7 +451,7 @@ function rotateMask(mask, semitones) {
449
451
  const steps = (semitones % 12 + 12) % 12;
450
452
  return (mask >> steps | mask << 12 - steps) & 4095;
451
453
  }
452
- var DIATONIC_MODE_OFFSETS = /* @__PURE__ */ new Map([
454
+ var DIATONIC_MODE_OFFSET_ENTRIES = [
453
455
  [rotateMask(MAJOR_MASK, 5), 1],
454
456
  // lydian
455
457
  [MAJOR_MASK, 0],
@@ -464,7 +466,8 @@ var DIATONIC_MODE_OFFSETS = /* @__PURE__ */ new Map([
464
466
  // phrygian
465
467
  [rotateMask(MAJOR_MASK, 11), -5]
466
468
  // locrian
467
- ]);
469
+ ];
470
+ var DIATONIC_MODE_OFFSETS = new Map(DIATONIC_MODE_OFFSET_ENTRIES);
468
471
  function modeOffset(key) {
469
472
  const diatonic = DIATONIC_MODE_OFFSETS.get(key.modeMask12);
470
473
  if (diatonic !== void 0) {
@@ -477,20 +480,20 @@ function isSignatureKey(key) {
477
480
  return DIATONIC_MODE_OFFSETS.has(mask) || mask === HARMONIC_MINOR_MASK || mask === MELODIC_MINOR_MASK;
478
481
  }
479
482
  function keySignatureFifths(tonic, key) {
480
- const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
483
+ const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
481
484
  const scale = toKeyScale(key);
482
- const letter = _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, note.letter);
483
- _chunkS5BKZZGMcjs.assertInteger.call(void 0, note.alter, "tonic.alter");
484
- _chunkS5BKZZGMcjs.assertInteger.call(void 0, scale.modeMask12, "key.modeMask12", 1, 4095);
485
+ const letter = _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, note.letter);
486
+ _chunkS3QELJUEcjs.assertInteger.call(void 0, note.alter, "tonic.alter");
487
+ _chunkS3QELJUEcjs.assertInteger.call(void 0, scale.modeMask12, "key.modeMask12", 1, 4095);
485
488
  return (_nullishCoalesce(LETTER_FIFTHS[letter], () => ( 0))) + FIFTHS_PER_ALTERATION * note.alter + modeOffset(scale);
486
489
  }
487
490
  function keyFromFifths(fifths, mode = "major") {
488
- _chunkS5BKZZGMcjs.assertInteger.call(void 0, fifths, "fifths", -MAX_FIFTHS, MAX_FIFTHS);
489
- const which = _chunkS5BKZZGMcjs.assertOneOf.call(void 0, mode, ["major", "minor"], "mode");
491
+ _chunkS3QELJUEcjs.assertInteger.call(void 0, fifths, "fifths", -MAX_FIFTHS, MAX_FIFTHS);
492
+ const which = _chunkS3QELJUEcjs.assertOneOf.call(void 0, mode, ["major", "minor"], "mode");
490
493
  const index = fifths + 1 + (which === "minor" ? -MINOR_MODE_OFFSET : 0);
491
494
  const letter = _nullishCoalesce(FIFTHS_LETTERS[(index % 7 + 7) % 7], () => ( 0));
492
495
  const alter = Math.floor(index / 7);
493
- const rootPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, letter) + alter);
496
+ const rootPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, letter) + alter);
494
497
  const scale = which === "minor" ? minorScale(rootPc) : majorScale(rootPc);
495
498
  return {
496
499
  tonic: { letter, alter },
@@ -512,10 +515,10 @@ function oppositeMode(mode) {
512
515
  return mode === "major" ? "minor" : "major";
513
516
  }
514
517
  function soundsLike(a, b) {
515
- return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, a.rootPc) === _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, b.rootPc) && isMinorMask(a.modeMask12) === isMinorMask(b.modeMask12);
518
+ return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, a.rootPc) === _chunkS3QELJUEcjs.pitchClassOf.call(void 0, b.rootPc) && isMinorMask(a.modeMask12) === isMinorMask(b.modeMask12);
516
519
  }
517
520
  function spelledLike(a, b) {
518
- return _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, a.letter) === _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, b.letter) && a.alter === b.alter;
521
+ return _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, a.letter) === _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, b.letter) && a.alter === b.alter;
519
522
  }
520
523
  function tonicCost(tonic, key) {
521
524
  let doubles = 0;
@@ -523,7 +526,7 @@ function tonicCost(tonic, key) {
523
526
  for (const note of spellScale(tonic, key)) {
524
527
  const alter = Math.abs(note.alter);
525
528
  accidentals += alter;
526
- if (alter >= _chunkS5BKZZGMcjs.MAX_NAME_ACCIDENTALS) {
529
+ if (alter >= _chunkS3QELJUEcjs.MAX_NAME_ACCIDENTALS) {
527
530
  doubles += 1;
528
531
  }
529
532
  }
@@ -539,14 +542,14 @@ function spellsBetter(a, b, signatureKey) {
539
542
  return false;
540
543
  }
541
544
  function spelledKeyOf(key) {
542
- const scale = _chunkS5BKZZGMcjs.assertRecord.call(void 0, key, "key");
543
- const rootPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, scale.rootPc);
545
+ const scale = _chunkS3QELJUEcjs.assertRecord.call(void 0, key, "key");
546
+ const rootPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, scale.rootPc);
544
547
  const signatureKey = isSignatureKey(scale);
545
548
  let tonic = keyFromFifths(0).tonic;
546
549
  let best;
547
550
  for (let fifths = FLATTEST_TONIC_FIFTHS; fifths <= SHARPEST_TONIC_FIFTHS; fifths += 1) {
548
551
  const candidate = keyFromFifths(fifths).tonic;
549
- if (_chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, candidate) !== rootPc) {
552
+ if (_chunkS3QELJUEcjs.noteToPitchClass.call(void 0, candidate) !== rootPc) {
550
553
  continue;
551
554
  }
552
555
  const cost = tonicCost(candidate, scale);
@@ -559,21 +562,21 @@ function spelledKeyOf(key) {
559
562
  }
560
563
  function relativeKeyOf(tonic, key) {
561
564
  const mode = modeOf(toKeyScale(key));
562
- return keyFromFifths(tonicFifths(_chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic), mode), oppositeMode(mode));
565
+ return keyFromFifths(tonicFifths(_chunkS3QELJUEcjs.toNoteData.call(void 0, tonic), mode), oppositeMode(mode));
563
566
  }
564
567
  function parallelKeyOf(tonic, key) {
565
- const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
568
+ const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
566
569
  const mode = oppositeMode(modeOf(toKeyScale(key)));
567
- const rootPc = _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, note);
570
+ const rootPc = _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, note);
568
571
  const scale = mode === "minor" ? minorScale(rootPc) : majorScale(rootPc);
569
572
  return {
570
- tonic: { letter: _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, note.letter), alter: note.alter },
573
+ tonic: { letter: _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, note.letter), alter: note.alter },
571
574
  scale,
572
575
  variant: variantOfMask(scale.modeMask12)
573
576
  };
574
577
  }
575
578
  function tonicPosition(tonic) {
576
- return keySignatureFifths(tonic, majorScale(_chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, tonic)));
579
+ return keySignatureFifths(tonic, majorScale(_chunkS3QELJUEcjs.noteToPitchClass.call(void 0, tonic)));
577
580
  }
578
581
  function tonicFifths(tonic, mode) {
579
582
  return tonicPosition(tonic) - (mode === "minor" ? MINOR_TONIC_FIFTHS : 0);
@@ -583,18 +586,18 @@ function isWrittenTonic(tonic, key) {
583
586
  if (isSignatureKey(key)) {
584
587
  return Math.abs(position) <= MAX_FIFTHS && Math.abs(keySignatureFifths(tonic, key)) <= MAX_CONVENTIONAL_FIFTHS;
585
588
  }
586
- return position >= FLATTEST_TONIC_FIFTHS && position <= SHARPEST_TONIC_FIFTHS && tonicCost(tonic, { rootPc: _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, tonic), modeMask12: key.modeMask12 }).doubles === 0;
589
+ return position >= FLATTEST_TONIC_FIFTHS && position <= SHARPEST_TONIC_FIFTHS && tonicCost(tonic, { rootPc: _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, tonic), modeMask12: key.modeMask12 }).doubles === 0;
587
590
  }
588
591
  function dominantKeyOf(tonic, key) {
589
592
  const mode = modeOf(toKeyScale(key));
590
- return keyFromFifths(tonicFifths(_chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic), mode) + 1, mode);
593
+ return keyFromFifths(tonicFifths(_chunkS3QELJUEcjs.toNoteData.call(void 0, tonic), mode) + 1, mode);
591
594
  }
592
595
  function subdominantKeyOf(tonic, key) {
593
596
  const mode = modeOf(toKeyScale(key));
594
- return keyFromFifths(tonicFifths(_chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic), mode) - 1, mode);
597
+ return keyFromFifths(tonicFifths(_chunkS3QELJUEcjs.toNoteData.call(void 0, tonic), mode) - 1, mode);
595
598
  }
596
599
  function enharmonicKeyOf(tonic, key) {
597
- const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
600
+ const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
598
601
  const scale = toKeyScale(key);
599
602
  maskOf(scale);
600
603
  for (const position of [
@@ -612,7 +615,7 @@ function enharmonicKeyOf(tonic, key) {
612
615
  tonic: spelled2,
613
616
  // The mask is the caller's; only the root is re-read, so a tonic that did
614
617
  // not spell the mask's own root still comes back consistent.
615
- scale: { rootPc: _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, spelled2), modeMask12: scale.modeMask12 },
618
+ scale: { rootPc: _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, spelled2), modeMask12: scale.modeMask12 },
616
619
  variant: variantOfMask(scale.modeMask12)
617
620
  };
618
621
  }
@@ -635,13 +638,13 @@ var CLOSELY_RELATED = [
635
638
  { relation: "relativeOfSubdominant", of: relativeOfSubdominantKeyOf }
636
639
  ];
637
640
  function relatedKeysOf(tonic, key) {
638
- const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
641
+ const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
639
642
  const scale = toKeyScale(key);
640
643
  return CLOSELY_RELATED.map(({ relation, of }) => ({ ...of(note, scale), relation }));
641
644
  }
642
645
  function keyRelationBetween(a, b) {
643
- const from = _chunkS5BKZZGMcjs.assertRecord.call(void 0, a, "a");
644
- const to = _chunkS5BKZZGMcjs.assertRecord.call(void 0, b, "b");
646
+ const from = _chunkS3QELJUEcjs.assertRecord.call(void 0, a, "a");
647
+ const to = _chunkS3QELJUEcjs.assertRecord.call(void 0, b, "b");
645
648
  maskOf(from.scale, "a.scale");
646
649
  maskOf(to.scale, "b.scale");
647
650
  if (soundsLike(from.scale, to.scale)) {
@@ -660,9 +663,9 @@ function carriesIdentity(value) {
660
663
  return typeof value === "object" && value !== null;
661
664
  }
662
665
  function carriedTonic(tonic, scale) {
663
- if (_chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, tonic) !== scale.rootPc) {
664
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
665
- `tonic ${_chunkS5BKZZGMcjs.formatNote.call(void 0, tonic)} does not match the scale root pitch class ${scale.rootPc}; pass a tonic that spells the scale root, or omit it to have one chosen`
666
+ if (_chunkS3QELJUEcjs.noteToPitchClass.call(void 0, tonic) !== scale.rootPc) {
667
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
668
+ `tonic ${_chunkS3QELJUEcjs.formatNote.call(void 0, tonic)} does not match the scale root pitch class ${scale.rootPc}; pass a tonic that spells the scale root, or omit it to have one chosen`
666
669
  );
667
670
  }
668
671
  return { letter: tonic.letter, alter: tonic.alter };
@@ -682,7 +685,7 @@ function resolveKey(value) {
682
685
  return { scale, tonic, variant };
683
686
  }
684
687
  function scaleOf(key) {
685
- const scale = _chunkS5BKZZGMcjs.assertRecord.call(void 0, key, "key").scale;
688
+ const scale = _chunkS3QELJUEcjs.assertRecord.call(void 0, key, "key").scale;
686
689
  maskOf(scale, "key.scale");
687
690
  return scale;
688
691
  }
@@ -765,7 +768,7 @@ function scaleSystemOf(scale) {
765
768
  if (typeof scale === "string") {
766
769
  const canonical = resolveScaleName(scale);
767
770
  if (canonical === void 0) {
768
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Unknown scale: ${scale}`);
771
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`Unknown scale: ${scale}`);
769
772
  }
770
773
  return SCALE_SYSTEMS[canonical];
771
774
  }
@@ -1067,7 +1070,7 @@ var QUALITY_BY_KEY = new Map(
1067
1070
  function chordSpecForQuality(quality, rootPc, bassPc) {
1068
1071
  const named = SPEC_BY_QUALITY.get(quality);
1069
1072
  if (named === void 0) {
1070
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Unknown chord quality: ${String(quality)}`);
1073
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`Unknown chord quality: ${String(quality)}`);
1071
1074
  }
1072
1075
  const spec = normalizeChordSpec(named);
1073
1076
  spec.rootPc = rootPc;
@@ -1097,7 +1100,7 @@ function chordSpecQuality(spec) {
1097
1100
  }
1098
1101
  return _nullishCoalesce(nearest, () => ( BASE_QUALITY[checked.base]));
1099
1102
  }
1100
- var EXTENSION_BY_SEMITONE = /* @__PURE__ */ new Map([
1103
+ var EXTENSION_ENTRIES = [
1101
1104
  [13, { degree: 9, alter: -1 }],
1102
1105
  [14, { degree: 9, alter: 0 }],
1103
1106
  [15, { degree: 9, alter: 1 }],
@@ -1107,7 +1110,8 @@ var EXTENSION_BY_SEMITONE = /* @__PURE__ */ new Map([
1107
1110
  [20, { degree: 13, alter: -1 }],
1108
1111
  [21, { degree: 13, alter: 0 }],
1109
1112
  [22, { degree: 13, alter: 1 }]
1110
- ]);
1113
+ ];
1114
+ var EXTENSION_BY_SEMITONE = new Map(EXTENSION_ENTRIES);
1111
1115
  function sameOffsets(a, b) {
1112
1116
  return a.length === b.length && a.every((offset, index) => offset === b[index]);
1113
1117
  }
@@ -1172,17 +1176,20 @@ function chordSpecFromIntervals(intervals) {
1172
1176
  const normalized = normalizeChordSpec(spec);
1173
1177
  return sameOffsets(specIntervals(normalized), offsets) ? normalized : void 0;
1174
1178
  }
1179
+ var ALTERABLE_DEGREES = [5, 9, 11, 13];
1180
+ var ALTERATION_STEPS = [-1, 0, 1];
1181
+ var ADDABLE_DEGREES = [6, 9, 11, 13];
1175
1182
  function assertPart(value, allowed, name) {
1176
1183
  if (!allowed.includes(value)) {
1177
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
1178
- `${name} must be one of ${allowed.join(", ")}; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, value)}`
1184
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
1185
+ `${name} must be one of ${allowed.join(", ")}; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, value)}`
1179
1186
  );
1180
1187
  }
1181
1188
  return value;
1182
1189
  }
1183
1190
  function assertDegreeIn(value, allowed, name) {
1184
1191
  if (!allowed.includes(value)) {
1185
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
1192
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
1186
1193
  `${name} must be one of ${allowed.join(", ")}; received ${String(value)}`
1187
1194
  );
1188
1195
  }
@@ -1190,7 +1197,7 @@ function assertDegreeIn(value, allowed, name) {
1190
1197
  }
1191
1198
  function assertDegreeList(value, allowed, name) {
1192
1199
  if (!Array.isArray(value)) {
1193
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name} must be an array; received ${typeof value}`);
1200
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`${name} must be an array; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, value)}`);
1194
1201
  }
1195
1202
  for (const degree of value) {
1196
1203
  assertDegreeIn(degree, allowed, name);
@@ -1198,11 +1205,11 @@ function assertDegreeList(value, allowed, name) {
1198
1205
  }
1199
1206
  function assertChordSpec(spec) {
1200
1207
  if (spec === null || typeof spec !== "object") {
1201
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`chord spec must be an object; received ${typeof spec}`);
1208
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`chord spec must be an object; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, spec)}`);
1202
1209
  }
1203
- _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, spec.rootPc, "chord spec rootPc");
1210
+ _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, spec.rootPc, "chord spec rootPc");
1204
1211
  if (spec.bassPc !== void 0) {
1205
- _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, spec.bassPc, "chord spec bassPc");
1212
+ _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, spec.bassPc, "chord spec bassPc");
1206
1213
  }
1207
1214
  assertPart(spec.base, Object.keys(BASE_TONES), "chord spec base");
1208
1215
  if (spec.seventh !== void 0) {
@@ -1213,13 +1220,13 @@ function assertChordSpec(spec) {
1213
1220
  );
1214
1221
  }
1215
1222
  if (!Array.isArray(spec.alterations)) {
1216
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)("chord spec alterations must be an array");
1223
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)("chord spec alterations must be an array");
1217
1224
  }
1218
1225
  for (const alteration of spec.alterations) {
1219
- assertDegreeIn(_optionalChain([alteration, 'optionalAccess', _5 => _5.degree]), [5, 9, 11, 13], "chord spec alteration degree");
1220
- assertDegreeIn(alteration.alter, [-1, 0, 1], "chord spec alteration");
1226
+ assertDegreeIn(_optionalChain([alteration, 'optionalAccess', _5 => _5.degree]), ALTERABLE_DEGREES, "chord spec alteration degree");
1227
+ assertDegreeIn(alteration.alter, ALTERATION_STEPS, "chord spec alteration");
1221
1228
  }
1222
- assertDegreeList(spec.additions, [6, 9, 11, 13], "chord spec additions");
1229
+ assertDegreeList(spec.additions, ADDABLE_DEGREES, "chord spec additions");
1223
1230
  assertDegreeList(spec.omissions, OMITTABLE_DEGREES, "chord spec omissions");
1224
1231
  return normalizeChordSpec(spec);
1225
1232
  }
@@ -1230,60 +1237,84 @@ function chordQualities() {
1230
1237
  return [...QUALITY_ORDER];
1231
1238
  }
1232
1239
  function assertChordQuality(quality) {
1233
- if (!Object.hasOwn(QUALITY_INTERVALS, quality)) {
1234
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Unknown chord quality: ${String(quality)}`);
1240
+ if (typeof quality !== "string" || !Object.hasOwn(QUALITY_INTERVALS, quality)) {
1241
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`Unknown chord quality: ${String(quality)}`);
1235
1242
  }
1236
1243
  return quality;
1237
1244
  }
1238
1245
  function assertChord(chord, name = "chord") {
1239
- const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, chord, name);
1240
- _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, read.rootPc, `${name}.rootPc`);
1246
+ const read = _chunkS3QELJUEcjs.assertRecord.call(void 0, chord, name);
1247
+ _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, read.rootPc, `${name}.rootPc`);
1241
1248
  assertChordQuality(read.quality);
1242
1249
  return read;
1243
1250
  }
1244
1251
  function chordFromDegree(degree, ext, key) {
1245
- _chunkS5BKZZGMcjs.assertDegree.call(void 0, degree, "chord degree");
1252
+ _chunkS3QELJUEcjs.assertDegree.call(void 0, degree, "chord degree");
1246
1253
  assertChordQuality(ext);
1247
- const scale = toKeyScale(key);
1248
- const tones = scaleTonesInDegreeOrder(scale);
1254
+ const resolved = resolveKey(key);
1255
+ const tones = scaleTonesInDegreeOrder(resolved.scale);
1249
1256
  const length = tones.length;
1250
1257
  const index = length > 0 ? (degree - 1) % length : 0;
1251
- const rootPc = _nullishCoalesce(tones[index], () => ( _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, scale.rootPc)));
1252
- return { rootPc, quality: ext, intervals: [...QUALITY_INTERVALS[ext]] };
1258
+ const rootPc = _nullishCoalesce(tones[index], () => ( _chunkS3QELJUEcjs.pitchClassOf.call(void 0, resolved.scale.rootPc)));
1259
+ return makeSpelledChord(rootPc, ext, { rootSpelling: keySpelling(rootPc, resolved) });
1253
1260
  }
1254
1261
  function makeChord(rootPc, quality, bassPc) {
1255
- _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, rootPc, "chord rootPc");
1256
- if (bassPc !== void 0) {
1257
- _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, bassPc, "chord bassPc");
1262
+ return makeSpelledChord(rootPc, quality, { bassPc });
1263
+ }
1264
+ function makeSpelledChord(rootPc, quality, parts2 = {}) {
1265
+ _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, rootPc, "chord rootPc");
1266
+ if (parts2.bassPc !== void 0) {
1267
+ _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, parts2.bassPc, "chord bassPc");
1258
1268
  }
1259
1269
  assertChordQuality(quality);
1260
1270
  const chord = {
1261
- rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, rootPc),
1271
+ rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, rootPc),
1262
1272
  quality,
1263
1273
  intervals: [..._nullishCoalesce(QUALITY_INTERVALS[quality], () => ( []))]
1264
1274
  };
1265
- if (bassPc !== void 0) {
1266
- chord.bassPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, bassPc);
1275
+ if (parts2.bassPc !== void 0) {
1276
+ chord.bassPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, parts2.bassPc);
1277
+ }
1278
+ if (parts2.rootSpelling !== void 0) {
1279
+ chord.rootSpelling = { letter: parts2.rootSpelling.letter, alter: parts2.rootSpelling.alter };
1280
+ }
1281
+ if (parts2.bassSpelling !== void 0) {
1282
+ chord.bassSpelling = { letter: parts2.bassSpelling.letter, alter: parts2.bassSpelling.alter };
1283
+ } else if (chord.rootSpelling !== void 0 && chord.bassPc !== void 0) {
1284
+ const index = chord.intervals.findIndex(
1285
+ (interval) => _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval) === chord.bassPc
1286
+ );
1287
+ const tone = index >= 0 ? spellChordFromRoot(chord, chord.rootSpelling)[index] : void 0;
1288
+ if (tone !== void 0) {
1289
+ chord.bassSpelling = { letter: tone.letter, alter: tone.alter };
1290
+ }
1291
+ }
1292
+ if (parts2.toneSpellings !== void 0) {
1293
+ chord.toneSpellings = parts2.toneSpellings.map(({ letter, alter }) => ({ letter, alter }));
1267
1294
  }
1268
1295
  return chord;
1269
1296
  }
1297
+ function keySpelling(pc, key) {
1298
+ const { letter, alter } = spellPitchClass(pc, key.tonic, key.scale);
1299
+ return { letter, alter };
1300
+ }
1270
1301
  function chordFromSpec(spec) {
1271
1302
  const checked = assertChordSpec(spec);
1272
1303
  const chord = {
1273
- rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, checked.rootPc),
1304
+ rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, checked.rootPc),
1274
1305
  quality: chordSpecQuality(checked),
1275
1306
  intervals: chordSpecIntervals(checked)
1276
1307
  };
1277
1308
  if (checked.bassPc !== void 0) {
1278
- chord.bassPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, checked.bassPc);
1309
+ chord.bassPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, checked.bassPc);
1279
1310
  }
1280
1311
  return chord;
1281
1312
  }
1282
1313
  function chordSpecOf(chord) {
1283
- _chunkS5BKZZGMcjs.assertRecord.call(void 0, chord, "chord");
1284
- _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, chord.rootPc, "chord rootPc");
1285
- const rootPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc);
1286
- const bassPc = chord.bassPc === void 0 ? void 0 : _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.bassPc);
1314
+ _chunkS3QELJUEcjs.assertRecord.call(void 0, chord, "chord");
1315
+ _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, chord.rootPc, "chord rootPc");
1316
+ const rootPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc);
1317
+ const bassPc = chord.bassPc === void 0 ? void 0 : _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.bassPc);
1287
1318
  const intervals = _nullishCoalesce(chord.intervals, () => ( []));
1288
1319
  const read = intervals.length === 0 ? void 0 : chordSpecFromIntervals(intervals);
1289
1320
  if (read === void 0) {
@@ -1298,21 +1329,23 @@ function chordSpecOf(chord) {
1298
1329
  function copySpanIntervals(intervals) {
1299
1330
  const name = "chord span intervals";
1300
1331
  if (!Array.isArray(intervals)) {
1301
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name} must be an array; received ${typeof intervals}`);
1332
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
1333
+ `${name} must be an array; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, intervals)}`
1334
+ );
1302
1335
  }
1303
1336
  if (intervals.length === 0) {
1304
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name} must name at least one interval`);
1337
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`${name} must name at least one interval`);
1305
1338
  }
1306
1339
  const copy = [];
1307
1340
  for (let index = 0; index < intervals.length; index += 1) {
1308
1341
  const interval = intervals[index];
1309
1342
  if (interval === void 0) {
1310
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
1343
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
1311
1344
  `${name}[${index}] must be a semitone offset; received undefined`
1312
1345
  );
1313
1346
  }
1314
1347
  copy.push(
1315
- _chunkS5BKZZGMcjs.assertInteger.call(void 0, interval, `${name}[${index}]`, -MAX_CHORD_INTERVAL, MAX_CHORD_INTERVAL)
1348
+ _chunkS3QELJUEcjs.assertInteger.call(void 0, interval, `${name}[${index}]`, -MAX_CHORD_INTERVAL, MAX_CHORD_INTERVAL)
1316
1349
  );
1317
1350
  }
1318
1351
  return copy;
@@ -1321,15 +1354,15 @@ function hasCustomIntervals(chord) {
1321
1354
  return !matchesQualityIntervals(chord.quality, chord.intervals);
1322
1355
  }
1323
1356
  function chordFromSpan(span) {
1324
- _chunkS5BKZZGMcjs.assertRecord.call(void 0, span, "chord span");
1325
- const chord = makeChord(span.rootPc, span.quality, span.bassPc);
1357
+ _chunkS3QELJUEcjs.assertRecord.call(void 0, span, "chord span");
1358
+ const chord = makeSpelledChord(span.rootPc, span.quality, { bassPc: span.bassPc });
1326
1359
  if (span.intervals !== void 0) {
1327
1360
  chord.intervals = copySpanIntervals(span.intervals);
1328
1361
  }
1329
1362
  return chord;
1330
1363
  }
1331
1364
  function spanFromChord(chord, startBeat) {
1332
- _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, startBeat, "chord span startBeat");
1365
+ _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, startBeat, "chord span startBeat");
1333
1366
  assertChord(chord);
1334
1367
  const span = { rootPc: chord.rootPc, quality: chord.quality, startBeat };
1335
1368
  if (chord.bassPc !== void 0) {
@@ -1342,15 +1375,15 @@ function spanFromChord(chord, startBeat) {
1342
1375
  }
1343
1376
  function transposeChord(chord, semitones) {
1344
1377
  assertChord(chord);
1345
- _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, semitones, "semitones");
1378
+ _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, semitones, "semitones");
1346
1379
  const steps = Math.round(semitones);
1347
1380
  const moved = {
1348
- rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + steps),
1381
+ rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + steps),
1349
1382
  quality: chord.quality,
1350
1383
  intervals: [...chord.intervals]
1351
1384
  };
1352
1385
  if (chord.bassPc !== void 0) {
1353
- moved.bassPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.bassPc + steps);
1386
+ moved.bassPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.bassPc + steps);
1354
1387
  }
1355
1388
  return moved;
1356
1389
  }
@@ -1366,20 +1399,20 @@ function chordToneSpellings(chord) {
1366
1399
  if (hint === void 0 || interval === void 0) {
1367
1400
  return void 0;
1368
1401
  }
1369
- if (_chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, hint) !== _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval)) {
1402
+ if (_chunkS3QELJUEcjs.noteToPitchClass.call(void 0, hint) !== _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval)) {
1370
1403
  return void 0;
1371
1404
  }
1372
- usable.push({ letter: _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, hint.letter), alter: hint.alter });
1405
+ usable.push({ letter: _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, hint.letter), alter: hint.alter });
1373
1406
  }
1374
1407
  return usable;
1375
1408
  }
1376
1409
  function chordToneLetterOffsets(chord) {
1377
1410
  const hints = chordToneSpellings(chord);
1378
- const rootHint = _optionalChain([hints, 'optionalAccess', _6 => _6[chord.intervals.findIndex((interval) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, interval) === 0)]]);
1411
+ const rootHint = _optionalChain([hints, 'optionalAccess', _6 => _6[chord.intervals.findIndex((interval) => _chunkS3QELJUEcjs.pitchClassOf.call(void 0, interval) === 0)]]);
1379
1412
  if (hints === void 0 || rootHint === void 0) {
1380
1413
  return void 0;
1381
1414
  }
1382
- return hints.map((hint) => _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, hint.letter - rootHint.letter));
1415
+ return hints.map((hint) => _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, hint.letter - rootHint.letter));
1383
1416
  }
1384
1417
  var ROLE_BY_LETTER_OFFSET = {
1385
1418
  0: "root",
@@ -1394,20 +1427,20 @@ function spelledToneRole(pitch, chord) {
1394
1427
  return void 0;
1395
1428
  }
1396
1429
  const index = chord.intervals.findIndex(
1397
- (interval) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval) === _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch)
1430
+ (interval) => _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval) === _chunkS3QELJUEcjs.pitchClassOf.call(void 0, pitch)
1398
1431
  );
1399
1432
  const offset = offsets[index];
1400
1433
  return offset === void 0 ? void 0 : _nullishCoalesce(ROLE_BY_LETTER_OFFSET[offset], () => ( null));
1401
1434
  }
1402
1435
  function chordPcMask(chord, opts = {}) {
1403
- _chunkS5BKZZGMcjs.assertRecord.call(void 0, chord, "chord");
1404
- _chunkS5BKZZGMcjs.assertArray.call(void 0, chord.intervals, "chord intervals");
1436
+ _chunkS3QELJUEcjs.assertRecord.call(void 0, chord, "chord");
1437
+ _chunkS3QELJUEcjs.assertArray.call(void 0, chord.intervals, "chord intervals");
1405
1438
  let mask = 0;
1406
1439
  for (const interval of chord.intervals) {
1407
- mask |= 1 << _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
1440
+ mask |= 1 << _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
1408
1441
  }
1409
1442
  if (opts.includeBass !== false && chord.bassPc !== void 0) {
1410
- mask |= 1 << _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.bassPc);
1443
+ mask |= 1 << _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.bassPc);
1411
1444
  }
1412
1445
  return mask;
1413
1446
  }
@@ -1422,7 +1455,7 @@ function chordIntervalMask(chord) {
1422
1455
  return mask;
1423
1456
  }
1424
1457
  function chordPitchClasses(chord, opts = {}) {
1425
- const mask = chordPcMask(assertChord(chord), _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts"));
1458
+ const mask = chordPcMask(assertChord(chord), _chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "opts"));
1426
1459
  const pcs = [];
1427
1460
  for (let pc = 0; pc < 12; pc += 1) {
1428
1461
  if (hasPitchClass(mask, pc)) {
@@ -1432,18 +1465,18 @@ function chordPitchClasses(chord, opts = {}) {
1432
1465
  return pcs;
1433
1466
  }
1434
1467
  function intervalAboveRoot(pitch, chord) {
1435
- return ((_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch) - _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, assertChord(chord).rootPc)) % 12 + 12) % 12;
1468
+ return ((_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pitch) - _chunkS3QELJUEcjs.pitchClassOf.call(void 0, assertChord(chord).rootPc)) % 12 + 12) % 12;
1436
1469
  }
1437
1470
  function isChordMember(pitch, chord) {
1438
- return chord === null ? false : hasPitchClass(chordPcMask(chord), _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch));
1471
+ return chord === null ? false : hasPitchClass(chordPcMask(chord), _chunkS3QELJUEcjs.pitchClassOf.call(void 0, pitch));
1439
1472
  }
1440
1473
  function chordToneRole(pitch, chord) {
1441
- _chunkS5BKZZGMcjs.assertRecord.call(void 0, chord, "chord");
1474
+ _chunkS3QELJUEcjs.assertRecord.call(void 0, chord, "chord");
1442
1475
  const spelled2 = spelledToneRole(pitch, chord);
1443
1476
  if (spelled2 !== void 0) {
1444
1477
  return spelled2;
1445
1478
  }
1446
- const interval = (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch) - _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc) + 12) % 12;
1479
+ const interval = (_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pitch) - _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc) + 12) % 12;
1447
1480
  const tones = chordIntervalMask(chord);
1448
1481
  const sounds = (ic) => hasPitchClass(tones, ic);
1449
1482
  if (interval === 0) {
@@ -1486,7 +1519,7 @@ var DEGREE_BY_ROLE = {
1486
1519
  };
1487
1520
  var TENSION_DEGREE = [1, 2, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7];
1488
1521
  function degreeOfInterval(interval, chord) {
1489
- const role = chordToneRole(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval), chord);
1522
+ const role = chordToneRole(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval), chord);
1490
1523
  if (role !== null) {
1491
1524
  return DEGREE_BY_ROLE[role];
1492
1525
  }
@@ -1510,7 +1543,7 @@ function thirdSlotOf(chord) {
1510
1543
  return { kind: "none" };
1511
1544
  }
1512
1545
  function displacedThirds(chord) {
1513
- return thirdSlotOf(chord).kind === "suspension" ? [_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + 3), _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + 4)] : [];
1546
+ return thirdSlotOf(chord).kind === "suspension" ? [_chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + 3), _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + 4)] : [];
1514
1547
  }
1515
1548
  function classifyTriad(thirdIc, fifthIc) {
1516
1549
  if (thirdIc === 4 && fifthIc === 8) {
@@ -1558,17 +1591,18 @@ function matchesQualityIntervals(quality, intervals) {
1558
1591
  const template = QUALITY_INTERVALS[quality];
1559
1592
  return template.length === intervals.length && template.every((interval, index) => interval === intervals[index]);
1560
1593
  }
1561
- function stackThirds(degree, key, size) {
1562
- _chunkS5BKZZGMcjs.assertDegree.call(void 0, degree, "chord degree");
1594
+ function stackThirds(degree, resolved, size) {
1595
+ _chunkS3QELJUEcjs.assertDegree.call(void 0, degree, "chord degree");
1596
+ const key = resolved.scale;
1563
1597
  const tones = scaleTonesInDegreeOrder(key);
1564
1598
  const length = tones.length;
1565
1599
  if (length !== 7) {
1566
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
1600
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
1567
1601
  `diatonic chord stacking requires a heptatonic scale (received ${length} tones)`
1568
1602
  );
1569
1603
  }
1570
1604
  const idx = (step) => (degree - 1 + step) % length;
1571
- const rootPc = _nullishCoalesce(tones[idx(0)], () => ( _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc)));
1605
+ const rootPc = _nullishCoalesce(tones[idx(0)], () => ( _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc)));
1572
1606
  const offsets = [0, 2, 4, 6].slice(0, size).map((step) => {
1573
1607
  const pc = _nullishCoalesce(tones[idx(step)], () => ( rootPc));
1574
1608
  return ((pc - rootPc) % 12 + 12) % 12;
@@ -1577,17 +1611,17 @@ function stackThirds(degree, key, size) {
1577
1611
  const fifthIc = _nullishCoalesce(offsets[2], () => ( 7));
1578
1612
  const quality = size === 3 ? classifyTriad(thirdIc, fifthIc) : classifySeventh(thirdIc, fifthIc, _nullishCoalesce(offsets[3], () => ( 11)));
1579
1613
  if (!matchesQualityIntervals(quality, offsets)) {
1580
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
1614
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
1581
1615
  `scale thirds at degree ${degree} produce unsupported intervals [${offsets.join(", ")}]`
1582
1616
  );
1583
1617
  }
1584
- return { rootPc, quality, intervals: offsets };
1618
+ return makeSpelledChord(rootPc, quality, { rootSpelling: keySpelling(rootPc, resolved) });
1585
1619
  }
1586
1620
  function diatonicTriad(degree, key) {
1587
- return stackThirds(degree, toKeyScale(key), 3);
1621
+ return stackThirds(degree, resolveKey(key), 3);
1588
1622
  }
1589
1623
  function diatonicSeventh(degree, key) {
1590
- return stackThirds(degree, toKeyScale(key), 4);
1624
+ return stackThirds(degree, resolveKey(key), 4);
1591
1625
  }
1592
1626
 
1593
1627
  // src/theory/spelling/index.ts
@@ -1645,20 +1679,20 @@ var CHROMATIC_SPELLING_SHARP = {
1645
1679
  // M7
1646
1680
  };
1647
1681
  function notePitchClass(note) {
1648
- return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, note.letter) + note.alter);
1682
+ return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, note.letter) + note.alter);
1649
1683
  }
1650
1684
  function assertTonicOf(tonic, key, source) {
1651
1685
  const tonicPc = notePitchClass(tonic);
1652
- const rootPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc);
1686
+ const rootPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc);
1653
1687
  if (tonicPc !== rootPc) {
1654
- const name = _chunkS5BKZZGMcjs.formatNote.call(void 0, { letter: _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, tonic.letter), alter: tonic.alter });
1655
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
1688
+ const name = _chunkS3QELJUEcjs.formatNote.call(void 0, { letter: _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, tonic.letter), alter: tonic.alter });
1689
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
1656
1690
  `${source}: tonic ${name} sounds pitch class ${tonicPc}, not the key root ${rootPc}; pass a tonic that spells the key root, or take one from spelledKeyOf`
1657
1691
  );
1658
1692
  }
1659
1693
  }
1660
1694
  function alterFor(letter, pc) {
1661
- let d = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, letter));
1695
+ let d = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc - _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, letter));
1662
1696
  if (d > 6) {
1663
1697
  d -= 12;
1664
1698
  }
@@ -1668,7 +1702,7 @@ function letterFor(tonic, degreeOffset, pc) {
1668
1702
  if (degreeOffset === void 0) {
1669
1703
  return void 0;
1670
1704
  }
1671
- const letter = _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, tonic.letter + degreeOffset);
1705
+ const letter = _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, tonic.letter + degreeOffset);
1672
1706
  return { letter, alter: alterFor(letter, pc) };
1673
1707
  }
1674
1708
  function pickSpelling(flat, sharp, preferFlat) {
@@ -1686,14 +1720,15 @@ function capChromaticAccidentals(preferred, alternative) {
1686
1720
  var DIATONIC_LETTER_COUNT = 7;
1687
1721
  var MAX_JOINT_TONE_COUNT = DIATONIC_LETTER_COUNT + 1;
1688
1722
  var MAJOR_SEMITONES = [0, 2, 4, 5, 7, 9, 11];
1689
- var IMPERFECT_DEGREES = /* @__PURE__ */ new Set([1, 2, 5, 6]);
1723
+ var IMPERFECT_DEGREE_LIST = [1, 2, 5, 6];
1724
+ var IMPERFECT_DEGREES = new Set(IMPERFECT_DEGREE_LIST);
1690
1725
  var DIATONIC_MODE_OFFSETS2 = MAJOR_SEMITONES.map(
1691
- (tonic, mode) => MAJOR_SEMITONES.map((_, degree) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, (_nullishCoalesce(MAJOR_SEMITONES[(mode + degree) % 7], () => ( 0))) - tonic))
1726
+ (tonic, mode) => MAJOR_SEMITONES.map((_, degree) => _chunkS3QELJUEcjs.pitchClassOf.call(void 0, (_nullishCoalesce(MAJOR_SEMITONES[(mode + degree) % 7], () => ( 0))) - tonic))
1692
1727
  );
1693
1728
  function degreeStrain(tonic, note) {
1694
- const letterOffset = _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, note.letter - tonic.letter);
1695
- const offset = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, notePitchClass(note) - notePitchClass(tonic));
1696
- let deviation = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, offset - (_nullishCoalesce(MAJOR_SEMITONES[letterOffset], () => ( 0))));
1729
+ const letterOffset = _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, note.letter - tonic.letter);
1730
+ const offset = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, notePitchClass(note) - notePitchClass(tonic));
1731
+ let deviation = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, offset - (_nullishCoalesce(MAJOR_SEMITONES[letterOffset], () => ( 0))));
1697
1732
  if (deviation > 6) {
1698
1733
  deviation -= 12;
1699
1734
  }
@@ -1705,8 +1740,8 @@ function isHeptatonic(key) {
1705
1740
  }
1706
1741
  function hasMinorThird(key) {
1707
1742
  const tones = scaleTonesInDegreeOrder(key);
1708
- const root = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc);
1709
- return tones.includes(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, root + 3)) && !tones.includes(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, root + 4));
1743
+ const root = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc);
1744
+ return tones.includes(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, root + 3)) && !tones.includes(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, root + 4));
1710
1745
  }
1711
1746
  function leansFlat(tonic, key) {
1712
1747
  return tonic.alter < 0 || hasMinorThird(key);
@@ -1731,7 +1766,7 @@ function spellByParentMode(tonic, pcs, preferFlat) {
1731
1766
  let alter = 0;
1732
1767
  let signed = 0;
1733
1768
  for (const pc of pcs) {
1734
- const degree = offsets.indexOf(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - tonicPc));
1769
+ const degree = offsets.indexOf(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc - tonicPc));
1735
1770
  const note = letterFor(tonic, degree < 0 ? void 0 : degree, pc);
1736
1771
  if (note === void 0) {
1737
1772
  break;
@@ -1754,7 +1789,7 @@ function spellByParentMode(tonic, pcs, preferFlat) {
1754
1789
  return best;
1755
1790
  }
1756
1791
  function assignDistinctLetters(candidates, tonic, duplicates) {
1757
- const reserved = 1 << _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, tonic.letter);
1792
+ const reserved = 1 << _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, tonic.letter);
1758
1793
  let best;
1759
1794
  let bestStrain = 0;
1760
1795
  let bestAlter = 0;
@@ -1797,7 +1832,7 @@ function assignDistinctLetters(candidates, tonic, duplicates) {
1797
1832
  return best;
1798
1833
  }
1799
1834
  function spellGappedScale(tonic, key) {
1800
- const cacheKey = `${_chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, tonic.letter)}:${tonic.alter}:${key.rootPc}:${key.modeMask12}`;
1835
+ const cacheKey = `${_chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, tonic.letter)}:${tonic.alter}:${key.rootPc}:${key.modeMask12}`;
1801
1836
  const cached = JOINT_SPELLINGS.get(cacheKey);
1802
1837
  if (cached !== void 0) {
1803
1838
  return cached.spellings;
@@ -1816,11 +1851,11 @@ function readGappedScale(tonic, key) {
1816
1851
  if (tones.length > MAX_JOINT_TONE_COUNT) {
1817
1852
  return void 0;
1818
1853
  }
1819
- const tonicPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, tonic.letter) + tonic.alter);
1820
- const tonicNote = { letter: _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, tonic.letter), alter: tonic.alter };
1854
+ const tonicPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, tonic.letter) + tonic.alter);
1855
+ const tonicNote = { letter: _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, tonic.letter), alter: tonic.alter };
1821
1856
  const preferFlat = leansFlat(tonic, key);
1822
- const rest = tones.filter((pc) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - tonicPc) !== 0);
1823
- const candidates = rest.map((pc) => gappedCandidates(tonic, _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - tonicPc), pc, preferFlat));
1857
+ const rest = tones.filter((pc) => _chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc - tonicPc) !== 0);
1858
+ const candidates = rest.map((pc) => gappedCandidates(tonic, _chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc - tonicPc), pc, preferFlat));
1824
1859
  const chosen = _nullishCoalesce(_nullishCoalesce(spellByParentMode(tonicNote, rest, preferFlat), () => ( // A scale that can hold a letter per tone does; only one that cannot writes
1825
1860
  // a letter twice, and then where the doubling falls is what is chosen.
1826
1861
  assignDistinctLetters(candidates, tonicNote, 0))), () => ( assignDistinctLetters(candidates, tonicNote, 1)));
@@ -1831,22 +1866,22 @@ function readGappedScale(tonic, key) {
1831
1866
  for (const [index, pc] of rest.entries()) {
1832
1867
  const note = chosen[index];
1833
1868
  if (note !== void 0) {
1834
- spellings.set(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc), note);
1869
+ spellings.set(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc), note);
1835
1870
  }
1836
1871
  }
1837
1872
  return spellings;
1838
1873
  }
1839
1874
  function spellByKey(pc, tonic, key) {
1840
- const tonicPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, tonic.letter) + tonic.alter);
1841
- const offset = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - tonicPc);
1875
+ const tonicPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, tonic.letter) + tonic.alter);
1876
+ const offset = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc - tonicPc);
1842
1877
  if (offset === 0) {
1843
- return { letter: _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, tonic.letter), alter: tonic.alter };
1878
+ return { letter: _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, tonic.letter), alter: tonic.alter };
1844
1879
  }
1845
1880
  const heptatonic = isHeptatonic(key);
1846
1881
  if (heptatonic) {
1847
- const degree = scaleTonesInDegreeOrder(key).indexOf(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc));
1882
+ const degree = scaleTonesInDegreeOrder(key).indexOf(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc));
1848
1883
  if (degree >= 0) {
1849
- const letter = _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, tonic.letter + degree);
1884
+ const letter = _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, tonic.letter + degree);
1850
1885
  return { letter, alter: alterFor(letter, pc) };
1851
1886
  }
1852
1887
  const degreeOffset = CHROMATIC_SPELLING[offset];
@@ -1859,7 +1894,7 @@ function spellByKey(pc, tonic, key) {
1859
1894
  }
1860
1895
  } else {
1861
1896
  if (isScaleTone(pc, key)) {
1862
- const assigned = _optionalChain([spellGappedScale, 'call', _9 => _9(tonic, key), 'optionalAccess', _10 => _10.get, 'call', _11 => _11(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc))]);
1897
+ const assigned = _optionalChain([spellGappedScale, 'call', _9 => _9(tonic, key), 'optionalAccess', _10 => _10.get, 'call', _11 => _11(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc))]);
1863
1898
  if (assigned !== void 0) {
1864
1899
  return { letter: assigned.letter, alter: assigned.alter };
1865
1900
  }
@@ -1869,9 +1904,10 @@ function spellByKey(pc, tonic, key) {
1869
1904
  return preferred;
1870
1905
  }
1871
1906
  }
1872
- const belowLetter = _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, _nullishCoalesce([0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6][_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc)], () => ( 0)));
1907
+ const belowLetter = _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, _nullishCoalesce(LETTER_BELOW_PITCH_CLASS[_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc)], () => ( 0)));
1873
1908
  return { letter: belowLetter, alter: alterFor(belowLetter, pc) };
1874
1909
  }
1910
+ var LETTER_BELOW_PITCH_CLASS = [0, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6];
1875
1911
  var CHORD_TONE_LETTER_STEPS = {
1876
1912
  0: 0,
1877
1913
  // root
@@ -1898,7 +1934,7 @@ function chordToneLetterStep(pc, rootPc, chord) {
1898
1934
  if (chord !== void 0) {
1899
1935
  const offsets = chordToneLetterOffsets(chord);
1900
1936
  const index = chord.intervals.findIndex(
1901
- (interval) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval) === _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc)
1937
+ (interval) => _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval) === _chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc)
1902
1938
  );
1903
1939
  const offset = _optionalChain([offsets, 'optionalAccess', _12 => _12[index]]);
1904
1940
  if (offset !== void 0) {
@@ -1909,7 +1945,7 @@ function chordToneLetterStep(pc, rootPc, chord) {
1909
1945
  return LETTER_STEP_BY_ROLE[role];
1910
1946
  }
1911
1947
  }
1912
- return CHORD_TONE_LETTER_STEPS[_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - rootPc)];
1948
+ return CHORD_TONE_LETTER_STEPS[_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc - rootPc)];
1913
1949
  }
1914
1950
  function spellChordTone(pc, context, tonic, key) {
1915
1951
  const { chord } = context;
@@ -1917,19 +1953,19 @@ function spellChordTone(pc, context, tonic, key) {
1917
1953
  if (chordRoot === void 0) {
1918
1954
  return void 0;
1919
1955
  }
1920
- const root = chord === void 0 ? spellByKey(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chordRoot), tonic, key) : chordRootSpelling(chord, tonic, key);
1956
+ const root = chord === void 0 ? spellByKey(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, chordRoot), tonic, key) : chordRootSpelling(chord, tonic, key);
1921
1957
  return letterFor(root, chordToneLetterStep(pc, chordRoot, chord), pc);
1922
1958
  }
1923
1959
  function neighbourSpelling(neighbour, gap, letterStep, pc, tonic, key) {
1924
- if (neighbour === void 0 || _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, neighbour - pc) !== _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, gap)) {
1960
+ if (neighbour === void 0 || _chunkS3QELJUEcjs.pitchClassOf.call(void 0, neighbour - pc) !== _chunkS3QELJUEcjs.pitchClassOf.call(void 0, gap)) {
1925
1961
  return void 0;
1926
1962
  }
1927
- return letterFor(spellByKey(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, neighbour), tonic, key), letterStep, pc);
1963
+ return letterFor(spellByKey(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, neighbour), tonic, key), letterStep, pc);
1928
1964
  }
1929
- function refineByContext(pc, tonic, key, context, keySpelling) {
1930
- const tonicPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, tonic.letter) + tonic.alter);
1931
- if (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc) === tonicPc || isScaleTone(pc, key)) {
1932
- return keySpelling;
1965
+ function refineByContext(pc, tonic, key, context, keySpelling2) {
1966
+ const tonicPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, tonic.letter) + tonic.alter);
1967
+ if (_chunkS3QELJUEcjs.pitchClassOf.call(void 0, pc) === tonicPc || isScaleTone(pc, key)) {
1968
+ return keySpelling2;
1933
1969
  }
1934
1970
  const { previous, next } = context;
1935
1971
  const candidates = [
@@ -1952,34 +1988,35 @@ function refineByContext(pc, tonic, key, context, keySpelling) {
1952
1988
  return candidate;
1953
1989
  }
1954
1990
  }
1955
- return keySpelling;
1991
+ return keySpelling2;
1956
1992
  }
1957
1993
  function spellPitchClass(pc, tonic, key, context) {
1958
- const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
1994
+ const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
1959
1995
  const scale = toKeyScale(key);
1960
1996
  assertTonicOf(note, scale, "spellPitchClass");
1961
- _chunkS5BKZZGMcjs.assertOptions.call(void 0, context, "context");
1997
+ _chunkS3QELJUEcjs.assertOptions.call(void 0, context, "context");
1962
1998
  return spelledPitchClass(pc, note, scale, context);
1963
1999
  }
1964
2000
  function spelledPitchClass(pc, tonic, key, context) {
1965
- const keySpelling = spellByKey(pc, tonic, key);
1966
- return context === void 0 ? keySpelling : refineByContext(pc, tonic, key, context, keySpelling);
2001
+ const keySpelling2 = spellByKey(pc, tonic, key);
2002
+ return context === void 0 ? keySpelling2 : refineByContext(pc, tonic, key, context, keySpelling2);
1967
2003
  }
1968
2004
  function spellScale(tonic, key) {
1969
- const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
2005
+ const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
1970
2006
  const scale = toKeyScale(key);
1971
2007
  assertTonicOf(note, scale, "spellScale");
1972
2008
  return scaleTonesInDegreeOrder(scale).map((pc) => spelledPitchClass(pc, note, scale));
1973
2009
  }
1974
2010
  function spellPitchClasses(pcs, tonic, key) {
1975
- const classes = _chunkS5BKZZGMcjs.assertArray.call(void 0, pcs, "pcs");
1976
- const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
2011
+ const classes = _chunkS3QELJUEcjs.assertArray.call(void 0, pcs, "pcs");
2012
+ const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
1977
2013
  const scale = toKeyScale(key);
1978
2014
  assertTonicOf(note, scale, "spellPitchClasses");
1979
2015
  return classes.map(
1980
- (pc, index) => spelledPitchClass(_chunkS5BKZZGMcjs.assertPitchClass.call(void 0, pc, `pcs[${index}]`), note, scale)
2016
+ (pc, index) => spelledPitchClass(_chunkS3QELJUEcjs.assertPitchClass.call(void 0, pc, `pcs[${index}]`), note, scale)
1981
2017
  );
1982
2018
  }
2019
+ var SIMPLE_LETTER_OFFSETS = [0, 1, 1, 2, 2, 3, 4, 4, 4, 5, 6, 6];
1983
2020
  function chordLetterOffset(interval, chord) {
1984
2021
  switch (interval) {
1985
2022
  case 0:
@@ -1994,7 +2031,7 @@ function chordLetterOffset(interval, chord) {
1994
2031
  case 4:
1995
2032
  return 2;
1996
2033
  case 15:
1997
- return chord.intervals.some((i) => i === 3 || i === 4) ? 1 : 2;
2034
+ return 1;
1998
2035
  case 5:
1999
2036
  case 16:
2000
2037
  case 17:
@@ -2017,74 +2054,74 @@ function chordLetterOffset(interval, chord) {
2017
2054
  return 6;
2018
2055
  default: {
2019
2056
  const octaves = Math.floor(Math.max(0, interval) / 12);
2020
- const simple = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, interval);
2021
- const simpleOffset = _nullishCoalesce([0, 1, 1, 2, 2, 3, 4, 4, 4, 5, 6, 6][simple], () => ( 0));
2057
+ const simple = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, interval);
2058
+ const simpleOffset = _nullishCoalesce(SIMPLE_LETTER_OFFSETS[simple], () => ( 0));
2022
2059
  return octaves * 7 + simpleOffset;
2023
2060
  }
2024
2061
  }
2025
2062
  }
2026
2063
  function spellChordFromRoot(chord, root) {
2027
- return chordTonesFromRoot(assertChord(chord), _chunkS5BKZZGMcjs.toNoteData.call(void 0, root));
2064
+ return chordTonesFromRoot(assertChord(chord), _chunkS3QELJUEcjs.toNoteData.call(void 0, root));
2028
2065
  }
2029
2066
  function chordTonesFromRoot(chord, root) {
2030
- if (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, root.letter) + root.alter) !== _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc)) {
2031
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)("chord root spelling must match chord.rootPc");
2067
+ if (_chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, root.letter) + root.alter) !== _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc)) {
2068
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)("chord root spelling must match chord.rootPc");
2032
2069
  }
2033
2070
  const hinted = chordToneLetterOffsets(chord);
2034
2071
  return chord.intervals.map((interval, index) => {
2035
- const letter = _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, root.letter + (_nullishCoalesce(_optionalChain([hinted, 'optionalAccess', _14 => _14[index]]), () => ( chordLetterOffset(interval, chord)))));
2036
- const pc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
2072
+ const letter = _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, root.letter + (_nullishCoalesce(_optionalChain([hinted, 'optionalAccess', _14 => _14[index]]), () => ( chordLetterOffset(interval, chord)))));
2073
+ const pc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
2037
2074
  return { letter, alter: alterFor(letter, pc) };
2038
2075
  });
2039
2076
  }
2040
2077
  function spellChord(chord, tonic, key) {
2041
2078
  assertChord(chord);
2042
- const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
2079
+ const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
2043
2080
  const scale = toKeyScale(key);
2044
2081
  assertTonicOf(note, scale, "spellChord");
2045
2082
  return chordTonesFromRoot(chord, chordRootSpelling(chord, note, scale));
2046
2083
  }
2047
2084
  function chordRootSpelling(chord, tonic, key) {
2048
2085
  const hint = chord.rootSpelling;
2049
- if (hint !== void 0 && _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, hint.letter) + hint.alter) === _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc)) {
2050
- return { letter: _chunkS5BKZZGMcjs.diatonicLetterOf.call(void 0, hint.letter), alter: hint.alter };
2086
+ if (hint !== void 0 && _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, hint.letter) + hint.alter) === _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc)) {
2087
+ return { letter: _chunkS3QELJUEcjs.diatonicLetterOf.call(void 0, hint.letter), alter: hint.alter };
2051
2088
  }
2052
2089
  return spelledPitchClass(chord.rootPc, tonic, key);
2053
2090
  }
2054
2091
  function spellPitch(pitch, tonic, key, context) {
2055
- const note = _chunkS5BKZZGMcjs.toNoteData.call(void 0, tonic);
2092
+ const note = _chunkS3QELJUEcjs.toNoteData.call(void 0, tonic);
2056
2093
  const scale = toKeyScale(key);
2057
2094
  assertTonicOf(note, scale, "spellPitch");
2058
- _chunkS5BKZZGMcjs.assertOptions.call(void 0, context, "context");
2059
- const rounded = Math.round(_chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, pitch, "pitch"));
2060
- const spelled2 = spelledPitchClass(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, rounded), note, scale, context);
2061
- const octave = (rounded - _chunkS5BKZZGMcjs.naturalPitchClassOf.call(void 0, spelled2.letter) - spelled2.alter) / 12 - 1;
2095
+ _chunkS3QELJUEcjs.assertOptions.call(void 0, context, "context");
2096
+ const rounded = Math.round(_chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, pitch, "pitch"));
2097
+ const spelled2 = spelledPitchClass(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, rounded), note, scale, context);
2098
+ const octave = (rounded - _chunkS3QELJUEcjs.naturalPitchClassOf.call(void 0, spelled2.letter) - spelled2.alter) / 12 - 1;
2062
2099
  return { letter: spelled2.letter, alter: spelled2.alter, octave };
2063
2100
  }
2064
2101
  function noteNames(notes) {
2065
- _chunkS5BKZZGMcjs.assertArray.call(void 0, notes, "notes");
2066
- return notes.map((note) => _chunkS5BKZZGMcjs.formatNote.call(void 0, _chunkS5BKZZGMcjs.toNoteData.call(void 0, note)));
2102
+ _chunkS3QELJUEcjs.assertArray.call(void 0, notes, "notes");
2103
+ return notes.map((note) => _chunkS3QELJUEcjs.formatNote.call(void 0, _chunkS3QELJUEcjs.toNoteData.call(void 0, note)));
2067
2104
  }
2068
2105
 
2069
2106
  // src/theory/counterpoint/internal.ts
2070
2107
  function assertQualityLabel(quality) {
2071
2108
  if (typeof quality !== "string" || !/^(P|M|m|A+|d+)$/.test(quality)) {
2072
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
2073
- `interval.quality must be an interval quality; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, quality)}`
2109
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
2110
+ `interval.quality must be an interval quality; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, quality)}`
2074
2111
  );
2075
2112
  }
2076
2113
  return quality;
2077
2114
  }
2078
2115
  function pitchOf(value) {
2079
- return typeof value === "number" ? value : _chunkS5BKZZGMcjs.noteToMidi.call(void 0, value);
2116
+ return typeof value === "number" ? value : _chunkS3QELJUEcjs.noteToMidi.call(void 0, value);
2080
2117
  }
2081
2118
  function simpleIntervalNumber(numberValue) {
2082
2119
  return (Math.abs(numberValue) - 1) % 7 + 1;
2083
2120
  }
2084
2121
  function classifySpelledInterval(interval, twoVoice = true) {
2085
- _chunkS5BKZZGMcjs.assertFlag.call(void 0, twoVoice, "twoVoice");
2086
- const read = _chunkS5BKZZGMcjs.assertRecord.call(void 0, interval, "interval");
2087
- const simple = simpleIntervalNumber(_chunkS5BKZZGMcjs.assertDegree.call(void 0, read.number, "interval.number"));
2122
+ _chunkS3QELJUEcjs.assertFlag.call(void 0, twoVoice, "twoVoice");
2123
+ const read = _chunkS3QELJUEcjs.assertRecord.call(void 0, interval, "interval");
2124
+ const simple = simpleIntervalNumber(_chunkS3QELJUEcjs.assertDegree.call(void 0, read.number, "interval.number"));
2088
2125
  const quality = assertQualityLabel(read.quality);
2089
2126
  if (quality === "P") {
2090
2127
  if (simple === 1 || simple === 5) {
@@ -2131,16 +2168,16 @@ function motionBetween(from, to) {
2131
2168
  if (leadMove > 0 !== counterMove > 0) {
2132
2169
  return "contrary";
2133
2170
  }
2134
- const before = simpleIntervalNumber(_chunkS5BKZZGMcjs.spelledInterval.call(void 0, from.counter, from.lead).number);
2135
- const after = simpleIntervalNumber(_chunkS5BKZZGMcjs.spelledInterval.call(void 0, to.counter, to.lead).number);
2171
+ const before = simpleIntervalNumber(_chunkS3QELJUEcjs.spelledInterval.call(void 0, from.counter, from.lead).number);
2172
+ const after = simpleIntervalNumber(_chunkS3QELJUEcjs.spelledInterval.call(void 0, to.counter, to.lead).number);
2136
2173
  return before === after ? "parallel" : "similar";
2137
2174
  }
2138
2175
  function voiceIndependence(lead, counter, opts) {
2139
- _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
2140
- const upper = _chunkS5BKZZGMcjs.assertArray.call(void 0, lead, "lead");
2141
- const lower = _chunkS5BKZZGMcjs.assertArray.call(void 0, counter, "counter");
2176
+ _chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "opts");
2177
+ const upper = _chunkS3QELJUEcjs.assertArray.call(void 0, lead, "lead");
2178
+ const lower = _chunkS3QELJUEcjs.assertArray.call(void 0, counter, "counter");
2142
2179
  if (upper.length !== lower.length) {
2143
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
2180
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
2144
2181
  `voiceIndependence needs the two lines aligned slot for slot; received ${upper.length} and ${lower.length}`
2145
2182
  );
2146
2183
  }
@@ -2149,7 +2186,7 @@ function voiceIndependence(lead, counter, opts) {
2149
2186
  ["counterAttacks", _optionalChain([opts, 'optionalAccess', _16 => _16.counterAttacks])]
2150
2187
  ]) {
2151
2188
  if (flags !== void 0 && flags.length !== upper.length) {
2152
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
2189
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
2153
2190
  `voiceIndependence needs ${name} aligned slot for slot with the lines; received ${flags.length} and ${upper.length}`
2154
2191
  );
2155
2192
  }
@@ -2206,7 +2243,7 @@ function voiceIndependence(lead, counter, opts) {
2206
2243
  totalGap += Math.abs(gap);
2207
2244
  minGap = Math.min(minGap, Math.abs(gap));
2208
2245
  orderSum += Math.sign(gap);
2209
- const interval = _chunkS5BKZZGMcjs.spelledInterval.call(void 0, slot.counter, slot.lead);
2246
+ const interval = _chunkS3QELJUEcjs.spelledInterval.call(void 0, slot.counter, slot.lead);
2210
2247
  const perfect = classifySpelledInterval(interval) === 0 /* PerfectConsonance */ || (_nullishCoalesce(_optionalChain([opts, 'optionalAccess', _19 => _19.countFourths]), () => ( false))) && interval.quality === "P" && simpleIntervalNumber(interval.number) === 4;
2211
2248
  perfectRun = perfect ? perfectRun + 1 : 0;
2212
2249
  longestPerfectRun = Math.max(longestPerfectRun, perfectRun);
@@ -2247,13 +2284,13 @@ function createsVoiceCrossing(upper, lower) {
2247
2284
  }
2248
2285
  function createsVerticalDissonance(a, b, twoVoice) {
2249
2286
  if (typeof a !== "number" && typeof b !== "number") {
2250
- return classifySpelledInterval(_chunkS5BKZZGMcjs.spelledInterval.call(void 0, a, b), twoVoice) === 2 /* Dissonance */;
2287
+ return classifySpelledInterval(_chunkS3QELJUEcjs.spelledInterval.call(void 0, a, b), twoVoice) === 2 /* Dissonance */;
2251
2288
  }
2252
- return !_chunkS5BKZZGMcjs.isConsonantInterval.call(void 0, pitchOf(a) - pitchOf(b), twoVoice);
2289
+ return !_chunkS3QELJUEcjs.isConsonantInterval.call(void 0, pitchOf(a) - pitchOf(b), twoVoice);
2253
2290
  }
2254
2291
  function isForbiddenMelodicLeap(prev, cur) {
2255
2292
  if (typeof prev !== "number" && typeof cur !== "number") {
2256
- const interval = _chunkS5BKZZGMcjs.spelledInterval.call(void 0, prev, cur);
2293
+ const interval = _chunkS3QELJUEcjs.spelledInterval.call(void 0, prev, cur);
2257
2294
  if (Math.abs(interval.semitones) > 12 || interval.number > 8) {
2258
2295
  return true;
2259
2296
  }
@@ -2272,11 +2309,11 @@ function isAugmentedMelodicInterval(prev, cur) {
2272
2309
  if (typeof prev === "number" || typeof cur === "number") {
2273
2310
  return false;
2274
2311
  }
2275
- const interval = _chunkS5BKZZGMcjs.spelledInterval.call(void 0, prev, cur);
2312
+ const interval = _chunkS3QELJUEcjs.spelledInterval.call(void 0, prev, cur);
2276
2313
  return interval.number >= 2 && interval.quality.startsWith("A");
2277
2314
  }
2278
2315
  function simpleClass(semitones) {
2279
- return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, Math.abs(semitones));
2316
+ return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, Math.abs(semitones));
2280
2317
  }
2281
2318
  function isPerfectClass(cls) {
2282
2319
  return cls === 0 || cls === 7;
@@ -2320,7 +2357,7 @@ function createsParallelUnison(aPrev, aCur, bPrev, bCur) {
2320
2357
  return a1 === b1 && a0 === b0;
2321
2358
  }
2322
2359
  function createsHiddenParallelPerfect(aPrev, aCur, bPrev, bCur, strictness = "fourPart") {
2323
- _chunkS5BKZZGMcjs.assertOneOf.call(void 0, strictness, HIDDEN_PARALLEL_READINGS, "strictness");
2360
+ _chunkS3QELJUEcjs.assertOneOf.call(void 0, strictness, HIDDEN_PARALLEL_READINGS, "strictness");
2324
2361
  const a0 = pitchOf(aPrev);
2325
2362
  const a1 = pitchOf(aCur);
2326
2363
  const b0 = pitchOf(bPrev);
@@ -2370,15 +2407,15 @@ function createsVoiceOverlap(upperPrev, upperCur, lowerPrev, lowerCur) {
2370
2407
  return u1 < l0 || l1 > u0;
2371
2408
  }
2372
2409
  function exceedsSpacing(upper, lower, maxSemitones = 12) {
2373
- _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, maxSemitones, "maxSemitones");
2410
+ _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, maxSemitones, "maxSemitones");
2374
2411
  return Math.abs(pitchOf(upper) - pitchOf(lower)) > maxSemitones;
2375
2412
  }
2376
2413
  function isLeadingToneResolution(prev, cur, key) {
2377
2414
  const prevPitch = pitchOf(prev);
2378
2415
  const curPitch = pitchOf(cur);
2379
- const tonic = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, toKeyScale(key).rootPc);
2416
+ const tonic = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, toKeyScale(key).rootPc);
2380
2417
  const leading = (tonic + 11) % 12;
2381
- if (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, prevPitch) !== leading || _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, curPitch) !== tonic) {
2418
+ if (_chunkS3QELJUEcjs.pitchClassOf.call(void 0, prevPitch) !== leading || _chunkS3QELJUEcjs.pitchClassOf.call(void 0, curPitch) !== tonic) {
2382
2419
  return false;
2383
2420
  }
2384
2421
  return curPitch > prevPitch && curPitch - prevPitch <= 2;
@@ -2417,17 +2454,17 @@ var PROFILE_WEIGHTS = Object.freeze({
2417
2454
  });
2418
2455
  var SAFETY_PROFILES = Object.keys(PROFILE_WEIGHTS);
2419
2456
  function profileWeights(profile, overrides) {
2420
- const base = PROFILE_WEIGHTS[_chunkS5BKZZGMcjs.assertOneOf.call(void 0, profile, SAFETY_PROFILES, "safety profile")];
2457
+ const base = PROFILE_WEIGHTS[_chunkS3QELJUEcjs.assertOneOf.call(void 0, profile, SAFETY_PROFILES, "safety profile")];
2421
2458
  if (overrides === void 0) {
2422
2459
  return { ...base };
2423
2460
  }
2424
- _chunkS5BKZZGMcjs.assertRecord.call(void 0, overrides, "overrides");
2461
+ _chunkS3QELJUEcjs.assertRecord.call(void 0, overrides, "overrides");
2425
2462
  const weights = { ...base };
2426
2463
  for (const [field, value] of Object.entries(overrides)) {
2427
2464
  if (value === void 0) {
2428
2465
  continue;
2429
2466
  }
2430
- weights[field] = _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, value, `weight ${field}`);
2467
+ weights[field] = _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, value, `weight ${field}`);
2431
2468
  }
2432
2469
  return weights;
2433
2470
  }
@@ -2494,7 +2531,7 @@ function avoidsMajorSeventh(chord) {
2494
2531
  return chord.intervals.includes(4) && chord.intervals.includes(10);
2495
2532
  }
2496
2533
  function isStructuralChordDissonance(a, b, chord) {
2497
- const rawClass = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, Math.abs(a - b));
2534
+ const rawClass = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, Math.abs(a - b));
2498
2535
  const aOffset = intervalAboveRoot(a, chord);
2499
2536
  const bOffset = intervalAboveRoot(b, chord);
2500
2537
  const rootSeventh = aOffset === 0 && (bOffset === 10 || bOffset === 11) || bOffset === 0 && (aOffset === 10 || aOffset === 11);
@@ -2513,31 +2550,35 @@ function stepResolution(pitch, chord) {
2513
2550
  }
2514
2551
  function evaluateSafety(q, opts = {}) {
2515
2552
  assertSafetyContext(q);
2516
- _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, q.candidatePitch, "candidatePitch");
2517
- const options = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
2553
+ _chunkS3QELJUEcjs.assertMidiPitch.call(void 0, q.candidatePitch, "candidatePitch");
2554
+ const options = _chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "opts");
2518
2555
  return evaluateInternal(q, _nullishCoalesce(options.suggestions, () => ( true)), _nullishCoalesce(options.partners, () => ( false)));
2519
2556
  }
2520
2557
  function assertSafetyContext(q) {
2521
- _chunkS5BKZZGMcjs.assertRecord.call(void 0, q, "safety query");
2522
- _chunkS5BKZZGMcjs.assertOneOf.call(void 0, q.profile, SAFETY_PROFILES, "safety profile");
2523
- if (q.prevPitch !== void 0) _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, q.prevPitch, "prevPitch");
2524
- if (q.vocalLow !== void 0) _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, q.vocalLow, "vocalLow");
2525
- if (q.vocalHigh !== void 0) _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, q.vocalHigh, "vocalHigh");
2558
+ _chunkS3QELJUEcjs.assertRecord.call(void 0, q, "safety query");
2559
+ _chunkS3QELJUEcjs.assertOneOf.call(void 0, q.profile, SAFETY_PROFILES, "safety profile");
2560
+ if (q.prevPitch !== void 0) _chunkS3QELJUEcjs.assertMidiPitch.call(void 0, q.prevPitch, "prevPitch");
2561
+ if (q.vocalLow !== void 0) _chunkS3QELJUEcjs.assertMidiPitch.call(void 0, q.vocalLow, "vocalLow");
2562
+ if (q.vocalHigh !== void 0) _chunkS3QELJUEcjs.assertMidiPitch.call(void 0, q.vocalHigh, "vocalHigh");
2526
2563
  if (q.vocalLow !== void 0 && q.vocalHigh !== void 0 && q.vocalLow > q.vocalHigh) {
2527
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)("vocalLow must not exceed vocalHigh");
2564
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)("vocalLow must not exceed vocalHigh");
2528
2565
  }
2529
2566
  if (!Array.isArray(q.otherVoices)) {
2530
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`otherVoices must be an array; received ${typeof q.otherVoices}`);
2567
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
2568
+ `otherVoices must be an array; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, q.otherVoices)}`
2569
+ );
2531
2570
  }
2532
- _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, q.otherVoices.length, "other voices");
2571
+ _chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, q.otherVoices.length, "other voices");
2533
2572
  for (let index = 0; index < q.otherVoices.length; index += 1) {
2534
- const voice = q.otherVoices[index];
2535
- if (!voice) continue;
2536
- _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, voice.pitch, `otherVoices[${index}].pitch`);
2573
+ const voice = _chunkS3QELJUEcjs.assertRecord.call(void 0, q.otherVoices[index], `otherVoices[${index}]`);
2574
+ _chunkS3QELJUEcjs.assertMidiPitch.call(void 0, voice.pitch, `otherVoices[${index}].pitch`);
2537
2575
  if (voice.prevPitch !== void 0) {
2538
- _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, voice.prevPitch, `otherVoices[${index}].prevPitch`);
2576
+ _chunkS3QELJUEcjs.assertMidiPitch.call(void 0, voice.prevPitch, `otherVoices[${index}].prevPitch`);
2539
2577
  }
2540
2578
  }
2579
+ if (q.chord !== null) {
2580
+ _chunkS3QELJUEcjs.assertRecord.call(void 0, q.chord, "chord");
2581
+ }
2541
2582
  }
2542
2583
  function evaluateInternal(q, collectSuggestions, collectPartners) {
2543
2584
  let reasons = 0;
@@ -2633,7 +2674,7 @@ function evaluateInternal(q, collectSuggestions, collectPartners) {
2633
2674
  if (chord && isStructuralChordDissonance(pitch, ov.pitch, chord)) {
2634
2675
  continue;
2635
2676
  }
2636
- if (chord && q.profile === "pop" && _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, Math.abs(pitch - ov.pitch)) === 5 && isChordMember(pitch, chord) && isChordMember(ov.pitch, chord)) {
2677
+ if (chord && q.profile === "pop" && _chunkS3QELJUEcjs.pitchClassOf.call(void 0, Math.abs(pitch - ov.pitch)) === 5 && isChordMember(pitch, chord) && isChordMember(ov.pitch, chord)) {
2637
2678
  continue;
2638
2679
  }
2639
2680
  flagPair(index, 1024 /* VerticalDissonance */);
@@ -2755,14 +2796,14 @@ function enumerateSafePitches(q, pitchLow, pitchHigh) {
2755
2796
  assertSafetyContext(q);
2756
2797
  const chordTones = [];
2757
2798
  const others = [];
2758
- _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, pitchLow, "pitchLow");
2759
- _chunkS5BKZZGMcjs.assertMidiPitch.call(void 0, pitchHigh, "pitchHigh");
2799
+ _chunkS3QELJUEcjs.assertMidiPitch.call(void 0, pitchLow, "pitchLow");
2800
+ _chunkS3QELJUEcjs.assertMidiPitch.call(void 0, pitchHigh, "pitchHigh");
2760
2801
  if (pitchLow > pitchHigh) {
2761
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
2802
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
2762
2803
  `pitchLow must not exceed pitchHigh; received ${pitchLow} > ${pitchHigh}`
2763
2804
  );
2764
2805
  }
2765
- _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, pitchHigh - pitchLow + 1, "safe pitch candidates");
2806
+ _chunkS3QELJUEcjs.assertGenerationBudget.call(void 0, pitchHigh - pitchLow + 1, "safe pitch candidates");
2766
2807
  const low = Math.max(pitchLow, _nullishCoalesce(q.vocalLow, () => ( pitchLow)));
2767
2808
  const high = Math.min(pitchHigh, _nullishCoalesce(q.vocalHigh, () => ( pitchHigh)));
2768
2809
  for (let pitch = high; pitch >= low; pitch -= 1) {
@@ -2925,6 +2966,19 @@ var ADDED_DEGREES = {
2925
2966
  };
2926
2967
  var ALTERABLE = { "5": 5, "9": 9, "11": 11, "13": 13 };
2927
2968
  var OMITTABLE = { "1": 1, "3": 3, "5": 5 };
2969
+ var SUSPENSION_TOKENS = [
2970
+ ["sus2", "sus2"],
2971
+ ["sus4", "sus4"],
2972
+ ["sus", "sus4"]
2973
+ ];
2974
+ var OMISSION_TOKENS = [
2975
+ ["omit", 4],
2976
+ ["no", 2]
2977
+ ];
2978
+ var ACCIDENTAL_TOKENS = [
2979
+ ["b", -1],
2980
+ ["#", 1]
2981
+ ];
2928
2982
  function alterationKey(degree, alter) {
2929
2983
  return `${degree}:${alter}`;
2930
2984
  }
@@ -2984,11 +3038,7 @@ function stackTo(draft, top) {
2984
3038
  }
2985
3039
  }
2986
3040
  function applyFigure(draft, text, at) {
2987
- const base = matchToken(text, at, [
2988
- ["sus2", "sus2"],
2989
- ["sus4", "sus4"],
2990
- ["sus", "sus4"]
2991
- ]);
3041
+ const base = matchToken(text, at, SUSPENSION_TOKENS);
2992
3042
  if (base !== void 0) {
2993
3043
  draft.base = base.value;
2994
3044
  return base.next;
@@ -3007,10 +3057,7 @@ function applyFigure(draft, text, at) {
3007
3057
  draft.additions.add(degree2.value);
3008
3058
  return degree2.next;
3009
3059
  }
3010
- const omitted = matchToken(text, at, [
3011
- ["omit", 4],
3012
- ["no", 2]
3013
- ]);
3060
+ const omitted = matchToken(text, at, OMISSION_TOKENS);
3014
3061
  if (omitted !== void 0) {
3015
3062
  const degree2 = matchNumberToken(text, omitted.next, OMITTABLE);
3016
3063
  if (degree2 === void 0) {
@@ -3019,10 +3066,7 @@ function applyFigure(draft, text, at) {
3019
3066
  draft.omissions.add(degree2.value);
3020
3067
  return degree2.next;
3021
3068
  }
3022
- const accidental = matchToken(text, at, [
3023
- ["b", -1],
3024
- ["#", 1]
3025
- ]);
3069
+ const accidental = matchToken(text, at, ACCIDENTAL_TOKENS);
3026
3070
  const from = _nullishCoalesce(_optionalChain([accidental, 'optionalAccess', _20 => _20.next]), () => ( at));
3027
3071
  const degree = matchNumberToken(text, from, ALTERABLE);
3028
3072
  if (degree === void 0) {
@@ -3171,10 +3215,10 @@ function suffixSpec(suffix) {
3171
3215
  return quality === void 0 ? structuralSpec(suffix) : chordSpecForQuality(quality, 0);
3172
3216
  }
3173
3217
  function assertNamingSystem(system) {
3174
- _chunkS5BKZZGMcjs.formatNote.call(void 0, SYSTEM_PROBE, { system });
3218
+ _chunkS3QELJUEcjs.formatNote.call(void 0, SYSTEM_PROBE, { system });
3175
3219
  }
3176
3220
  function bareNote(text, system) {
3177
- const read = _chunkS5BKZZGMcjs.tryParseNote.call(void 0, text, { system });
3221
+ const read = _chunkS3QELJUEcjs.tryParseNote.call(void 0, text, { system });
3178
3222
  if (!read.ok) {
3179
3223
  return void 0;
3180
3224
  }
@@ -3184,11 +3228,11 @@ function rootSplits(text, system) {
3184
3228
  if (system === "english") {
3185
3229
  const match = text.match(ROOT_RE);
3186
3230
  const token = _optionalChain([match, 'optionalAccess', _22 => _22[0]]);
3187
- return token === void 0 ? [] : [{ root: _chunkS5BKZZGMcjs.parseNote.call(void 0, token, { system }), rest: text.slice(token.length) }];
3231
+ return token === void 0 ? [] : [{ root: _chunkS3QELJUEcjs.parseNote.call(void 0, token, { system }), rest: text.slice(token.length) }];
3188
3232
  }
3189
3233
  assertNamingSystem(system);
3190
3234
  const splits = [];
3191
- const longest = Math.min(text.length, _chunkS5BKZZGMcjs.maxNoteNameLength.call(void 0, system));
3235
+ const longest = Math.min(text.length, _chunkS3QELJUEcjs.maxNoteNameLength.call(void 0, system));
3192
3236
  for (let end = longest; end > 0; end -= 1) {
3193
3237
  const root = bareNote(text.slice(0, end), system);
3194
3238
  if (root !== void 0) {
@@ -3199,14 +3243,14 @@ function rootSplits(text, system) {
3199
3243
  }
3200
3244
  function bassNote(text, system) {
3201
3245
  if (system === "english") {
3202
- return BASS_RE.test(text) ? _chunkS5BKZZGMcjs.parseNote.call(void 0, text, { system }) : void 0;
3246
+ return BASS_RE.test(text) ? _chunkS3QELJUEcjs.parseNote.call(void 0, text, { system }) : void 0;
3203
3247
  }
3204
3248
  return bareNote(text, system);
3205
3249
  }
3206
- function makeSpelledChord(root, spec, bass) {
3207
- const rooted = { ...spec, rootPc: _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, root) };
3250
+ function chordFromSymbolParts(root, spec, bass) {
3251
+ const rooted = { ...spec, rootPc: _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, root) };
3208
3252
  if (bass !== void 0) {
3209
- rooted.bassPc = _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, bass);
3253
+ rooted.bassPc = _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, bass);
3210
3254
  }
3211
3255
  const chord = chordFromSpec(rooted);
3212
3256
  chord.rootSpelling = { letter: root.letter, alter: root.alter };
@@ -3221,11 +3265,11 @@ function chordAfterRoot(root, rest, system) {
3221
3265
  const slashSpec = suffixSpec(rest.slice(0, slashIndex));
3222
3266
  const bass = slashSpec === void 0 ? void 0 : bassNote(rest.slice(slashIndex + 1), system);
3223
3267
  if (slashSpec !== void 0 && bass !== void 0) {
3224
- return makeSpelledChord(root, slashSpec, bass);
3268
+ return chordFromSymbolParts(root, slashSpec, bass);
3225
3269
  }
3226
3270
  }
3227
3271
  const spec = suffixSpec(rest);
3228
- return spec === void 0 ? void 0 : makeSpelledChord(root, spec);
3272
+ return spec === void 0 ? void 0 : chordFromSymbolParts(root, spec);
3229
3273
  }
3230
3274
 
3231
3275
  // src/theory/symbol/suffix.ts
@@ -3302,7 +3346,11 @@ var BASE_SUFFIX = {
3302
3346
  sus4: "sus4",
3303
3347
  power: "5"
3304
3348
  };
3305
- var SEVENTH_SUFFIX = { maj7: "maj7", min7: "7", dim7: "dim7" };
3349
+ var SEVENTH_SUFFIX = {
3350
+ maj7: "maj7",
3351
+ min7: "7",
3352
+ dim7: "dim7"
3353
+ };
3306
3354
  var MAJOR_SEVENTH_AFTER_BASE = "Maj7";
3307
3355
  function builtCoreSuffix(spec) {
3308
3356
  const base = BASE_SUFFIX[spec.base];
@@ -3351,21 +3399,21 @@ function bareSpelling(note) {
3351
3399
  return { letter: note.letter, alter: note.alter };
3352
3400
  }
3353
3401
  function plainSpelling(pc, asFlat) {
3354
- return bareSpelling(_chunkS5BKZZGMcjs.midiToNote.call(void 0, 60 + pc, asFlat ? "flat" : "sharp"));
3402
+ return bareSpelling(_chunkS3QELJUEcjs.midiToNote.call(void 0, 60 + pc, asFlat ? "flat" : "sharp"));
3355
3403
  }
3356
3404
  function symbolName(note, system) {
3357
- const name = _chunkS5BKZZGMcjs.formatNote.call(void 0, note, { system });
3405
+ const name = _chunkS3QELJUEcjs.formatNote.call(void 0, note, { system });
3358
3406
  return system === "german" ? `${name.slice(0, 1).toUpperCase()}${name.slice(1)}` : name;
3359
3407
  }
3360
3408
  function isWrittenSpelling(spelling) {
3361
- const written = _chunkS5BKZZGMcjs.midiToNote.call(void 0,
3362
- 60 + _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, spelling),
3409
+ const written = _chunkS3QELJUEcjs.midiToNote.call(void 0,
3410
+ 60 + _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, spelling),
3363
3411
  spelling.alter < 0 ? "flat" : "sharp"
3364
3412
  );
3365
3413
  return written.letter === spelling.letter && written.alter === spelling.alter;
3366
3414
  }
3367
3415
  function pitchClassName(pc, hint, system, flats, inheritFlats) {
3368
- if (flats === void 0 && hint !== void 0 && _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, hint) === pc) {
3416
+ if (flats === void 0 && hint !== void 0 && _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, hint) === pc) {
3369
3417
  return symbolName(hint, system);
3370
3418
  }
3371
3419
  return symbolName(plainSpelling(pc, _nullishCoalesce(_nullishCoalesce(flats, () => ( inheritFlats)), () => ( false))), system);
@@ -3374,19 +3422,19 @@ function onAccidentalSide(spelling, flats) {
3374
3422
  return flats === void 0 || spelling.alter === 0 || spelling.alter < 0 === flats;
3375
3423
  }
3376
3424
  function bySameStep(spelling, from, to) {
3377
- return bareSpelling(_chunkS5BKZZGMcjs.transposeByInterval.call(void 0, spelling, _chunkS5BKZZGMcjs.spelledInterval.call(void 0, from, to)));
3425
+ return bareSpelling(_chunkS3QELJUEcjs.transposeByInterval.call(void 0, spelling, _chunkS3QELJUEcjs.spelledInterval.call(void 0, from, to)));
3378
3426
  }
3379
3427
  function spellingAbove(root, letters, pc) {
3380
3428
  const letter = ((root.letter + letters) % 7 + 7) % 7;
3381
- const natural = _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, { letter, alter: 0 });
3429
+ const natural = _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, { letter, alter: 0 });
3382
3430
  return { letter, alter: ((pc - natural) % 12 + 18) % 12 - 6 };
3383
3431
  }
3384
3432
  function carriedBass(spelling, from, to, asFlat, isOwnSpelling) {
3385
3433
  const carried = bySameStep(spelling, from, to);
3386
- return isOwnSpelling(carried) || isWrittenSpelling(carried) ? carried : plainSpelling(_chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, carried), asFlat);
3434
+ return isOwnSpelling(carried) || isWrittenSpelling(carried) ? carried : plainSpelling(_chunkS3QELJUEcjs.noteToPitchClass.call(void 0, carried), asFlat);
3387
3435
  }
3388
3436
  function hintFor(hint, pc) {
3389
- return hint !== void 0 && _chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, hint) === pc ? hint : void 0;
3437
+ return hint !== void 0 && _chunkS3QELJUEcjs.noteToPitchClass.call(void 0, hint) === pc ? hint : void 0;
3390
3438
  }
3391
3439
  function rootSpellingFor(pc, hint, flats) {
3392
3440
  return hint !== void 0 && onAccidentalSide(hint, flats) ? hint : plainSpelling(pc, _nullishCoalesce(flats, () => ( false)));
@@ -3394,19 +3442,19 @@ function rootSpellingFor(pc, hint, flats) {
3394
3442
 
3395
3443
  // src/theory/symbol/index.ts
3396
3444
  function parseChordSymbol(text, opts) {
3397
- return _chunkS5BKZZGMcjs.unwrapParse.call(void 0, tryParseChordSymbol(text, opts));
3445
+ return _chunkS3QELJUEcjs.unwrapParse.call(void 0, tryParseChordSymbol(text, opts));
3398
3446
  }
3399
3447
  function tryParseChordSymbol(text, opts) {
3400
- const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
3448
+ const asked = _chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "opts");
3401
3449
  try {
3402
3450
  if (typeof text !== "string") {
3403
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`chord symbol must be a string; received ${typeof text}`);
3451
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`chord symbol must be a string; received ${typeof text}`);
3404
3452
  }
3405
3453
  const system = _nullishCoalesce(asked.system, () => ( DEFAULT_SYSTEM));
3406
3454
  const trimmed = text.trim().replaceAll("\u266F", "#").replaceAll("\u266D", "b").replaceAll("\u{1D12A}", "x").replaceAll("\u{1D12B}", "bb").replaceAll("\u2206", "\u0394");
3407
3455
  const splits = rootSplits(trimmed, system);
3408
3456
  if (splits.length === 0) {
3409
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Invalid chord symbol: ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, text)}`);
3457
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`Invalid chord symbol: ${_chunkS3QELJUEcjs.describeRejected.call(void 0, text)}`);
3410
3458
  }
3411
3459
  for (const { root, rest } of splits) {
3412
3460
  const chord = chordAfterRoot(root, rest, system);
@@ -3414,34 +3462,34 @@ function tryParseChordSymbol(text, opts) {
3414
3462
  return { ok: true, value: chord };
3415
3463
  }
3416
3464
  }
3417
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Unrecognized chord quality: ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, text)}`);
3465
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`Unrecognized chord quality: ${_chunkS3QELJUEcjs.describeRejected.call(void 0, text)}`);
3418
3466
  } catch (error) {
3419
- return _chunkS5BKZZGMcjs.parseFailure.call(void 0, error);
3467
+ return _chunkS3QELJUEcjs.parseFailure.call(void 0, error);
3420
3468
  }
3421
3469
  }
3422
3470
  function formatChordSymbol(chord, opts) {
3423
3471
  const data = toChordData(chord);
3424
- if (!Object.hasOwn(CANONICAL_SUFFIX, data.quality)) {
3425
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`Unknown chord quality: ${String(data.quality)}`);
3472
+ if (typeof data.quality !== "string" || !Object.hasOwn(CANONICAL_SUFFIX, data.quality)) {
3473
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(`Unknown chord quality: ${String(data.quality)}`);
3426
3474
  }
3427
- const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
3475
+ const asked = _chunkS3QELJUEcjs.assertOptions.call(void 0, opts, "opts");
3428
3476
  const system = _nullishCoalesce(asked.system, () => ( DEFAULT_SYSTEM));
3429
- const flats = asked.flats;
3430
- const rootPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, data.rootPc);
3477
+ const flats = symbolFlats(asked.flats);
3478
+ const rootPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, data.rootPc);
3431
3479
  const rootHint = hintFor(data.rootSpelling, rootPc);
3432
3480
  const rootSpelling = rootSpellingFor(rootPc, rootHint, flats);
3433
3481
  const suffix = specSuffix(chordSpecOf(data));
3434
3482
  let symbol = `${symbolName(rootSpelling, system)}${suffix}`;
3435
- if (data.bassPc !== void 0 && _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, data.bassPc) !== rootPc) {
3436
- const bassPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, data.bassPc);
3483
+ if (data.bassPc !== void 0 && _chunkS3QELJUEcjs.pitchClassOf.call(void 0, data.bassPc) !== rootPc) {
3484
+ const bassPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, data.bassPc);
3437
3485
  const bassHint = hintFor(data.bassSpelling, bassPc);
3438
3486
  const tonePcs = new Set(chordPitchClasses(data, { includeBass: false }));
3439
3487
  const ownSpelling = tonePcs.has(bassPc) ? spellingAbove(
3440
3488
  rootSpelling,
3441
- (_nullishCoalesce(degreeOfInterval(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, bassPc - rootPc), data), () => ( 1))) - 1,
3489
+ (_nullishCoalesce(degreeOfInterval(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, bassPc - rootPc), data), () => ( 1))) - 1,
3442
3490
  bassPc
3443
3491
  ) : void 0;
3444
- const bassName = rootHint !== void 0 && bassHint !== void 0 ? symbolName(
3492
+ const bassName = flats !== void 0 && rootHint !== void 0 && bassHint !== void 0 ? symbolName(
3445
3493
  carriedBass(
3446
3494
  bassHint,
3447
3495
  rootHint,
@@ -3455,16 +3503,19 @@ function formatChordSymbol(chord, opts) {
3455
3503
  }
3456
3504
  return symbol;
3457
3505
  }
3506
+ function symbolFlats(flats) {
3507
+ return flats === void 0 ? void 0 : _chunkS3QELJUEcjs.assertFlag.call(void 0, flats, "flats");
3508
+ }
3458
3509
  function transposeChordSpellings(spellings, semitones, flats) {
3459
- const byLetter = (spelling) => spelling === void 0 ? void 0 : bareSpelling(_chunkS5BKZZGMcjs.transposeNote.call(void 0, spelling, semitones));
3510
+ const byLetter = (spelling) => spelling === void 0 ? void 0 : bareSpelling(_chunkS3QELJUEcjs.transposeNote.call(void 0, spelling, semitones));
3460
3511
  const movedRoot = byLetter(spellings.rootSpelling);
3461
3512
  const movedBass = byLetter(spellings.bassSpelling);
3462
3513
  const side = [movedRoot, spellings.rootSpelling, movedBass, spellings.bassSpelling].find(
3463
3514
  (spelling) => spelling !== void 0 && spelling.alter !== 0
3464
3515
  );
3465
3516
  const preferFlats = _nullishCoalesce(flats, () => ( (side !== void 0 && side.alter < 0)));
3466
- const octaveOnly = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, semitones) === 0;
3467
- const plainName = (spelling, asFlat) => plainSpelling(_chunkS5BKZZGMcjs.noteToPitchClass.call(void 0, spelling), asFlat);
3517
+ const octaveOnly = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, semitones) === 0;
3518
+ const plainName = (spelling, asFlat) => plainSpelling(_chunkS3QELJUEcjs.noteToPitchClass.call(void 0, spelling), asFlat);
3468
3519
  const writable = (spelling) => octaveOnly || isWrittenSpelling(spelling) ? spelling : plainName(spelling, preferFlats);
3469
3520
  const root = spellings.rootSpelling;
3470
3521
  const bass = spellings.bassSpelling;
@@ -3486,9 +3537,9 @@ function transposeChordSpellings(spellings, semitones, flats) {
3486
3537
  ];
3487
3538
  moved.rootSpelling = _nullishCoalesce(candidates.find(carriesBass), () => ( plainName(movedRoot, preferFlats)));
3488
3539
  }
3489
- const step = root !== void 0 && moved.rootSpelling !== void 0 ? _chunkS5BKZZGMcjs.spelledInterval.call(void 0, root, moved.rootSpelling) : void 0;
3540
+ const step = root !== void 0 && moved.rootSpelling !== void 0 ? _chunkS3QELJUEcjs.spelledInterval.call(void 0, root, moved.rootSpelling) : void 0;
3490
3541
  const byStep = (spelling) => bareSpelling(
3491
- step === void 0 ? _chunkS5BKZZGMcjs.transposeNote.call(void 0, spelling, semitones) : _chunkS5BKZZGMcjs.transposeByInterval.call(void 0, spelling, step)
3542
+ step === void 0 ? _chunkS3QELJUEcjs.transposeNote.call(void 0, spelling, semitones) : _chunkS3QELJUEcjs.transposeByInterval.call(void 0, spelling, step)
3492
3543
  );
3493
3544
  if (bass !== void 0) {
3494
3545
  moved.bassSpelling = writable(byStep(bass));
@@ -3499,13 +3550,13 @@ function transposeChordSpellings(spellings, semitones, flats) {
3499
3550
  return moved;
3500
3551
  }
3501
3552
  function transposeChordSymbol(text, semitones, opts) {
3502
- _chunkS5BKZZGMcjs.assertFiniteSemitones.call(void 0, semitones);
3553
+ _chunkS3QELJUEcjs.assertFiniteSemitones.call(void 0, semitones);
3503
3554
  const chord = parseChordSymbol(text, opts);
3504
- const transposed = { ...chord, rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + semitones) };
3555
+ const transposed = { ...chord, rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + semitones) };
3505
3556
  if (chord.bassPc !== void 0) {
3506
- transposed.bassPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.bassPc + semitones);
3557
+ transposed.bassPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.bassPc + semitones);
3507
3558
  }
3508
- const spellings = transposeChordSpellings(chord, semitones, _optionalChain([opts, 'optionalAccess', _26 => _26.flats]));
3559
+ const spellings = transposeChordSpellings(chord, semitones, symbolFlats(_optionalChain([opts, 'optionalAccess', _26 => _26.flats])));
3509
3560
  if (spellings.rootSpelling !== void 0) {
3510
3561
  transposed.rootSpelling = spellings.rootSpelling;
3511
3562
  }
@@ -3521,20 +3572,20 @@ function transposeChordSymbol(text, semitones, opts) {
3521
3572
  // src/theory/symbol/coerce.ts
3522
3573
  function normalizedChord(data) {
3523
3574
  if (!Array.isArray(data.intervals)) {
3524
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)("chord.intervals must be an array of semitone offsets");
3575
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)("chord.intervals must be an array of semitone offsets");
3525
3576
  }
3526
3577
  const copy = {
3527
- rootPc: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, data.rootPc, "chord.rootPc")),
3578
+ rootPc: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, data.rootPc, "chord.rootPc")),
3528
3579
  quality: data.quality,
3529
3580
  // Each offset is checked rather than copied blind: a chord holding a NaN
3530
3581
  // interval voices, spells and formats as a chord that looks real, and the
3531
3582
  // failure surfaces wherever the number is finally used.
3532
3583
  intervals: data.intervals.map(
3533
- (interval, index) => _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, interval, `chord.intervals[${index}]`)
3584
+ (interval, index) => _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, interval, `chord.intervals[${index}]`)
3534
3585
  )
3535
3586
  };
3536
3587
  if (data.bassPc !== void 0) {
3537
- copy.bassPc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, data.bassPc, "chord.bassPc"));
3588
+ copy.bassPc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, _chunkS3QELJUEcjs.assertFiniteNumber.call(void 0, data.bassPc, "chord.bassPc"));
3538
3589
  }
3539
3590
  if (data.rootSpelling !== void 0) {
3540
3591
  copy.rootSpelling = data.rootSpelling;
@@ -3552,21 +3603,24 @@ function toChordData(value) {
3552
3603
  return parseChordSymbol(value);
3553
3604
  }
3554
3605
  if (typeof value === "object" && value !== null) {
3555
- const data = "toJSON" in value && typeof value.toJSON === "function" ? value.toJSON() : value;
3606
+ const data = "toJSON" in value && typeof value.toJSON === "function" ? "data" in value && typeof value.data === "object" && value.data !== null ? value.data : value.toJSON() : value;
3556
3607
  return normalizedChord(data);
3557
3608
  }
3558
- throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
3559
- `chord must be a chord symbol or chord data; received ${typeof value}`
3609
+ throw new (0, _chunkS3QELJUEcjs.InvalidInputError)(
3610
+ `chord must be a chord symbol or chord data; received ${_chunkS3QELJUEcjs.describeRejected.call(void 0, value)}`
3560
3611
  );
3561
3612
  }
3562
3613
 
3563
3614
  // src/theory/tendency/index.ts
3564
3615
  function hasInterval(chord, semitones) {
3565
- return chord.intervals.some((interval) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, interval) === semitones);
3616
+ return chord.intervals.some((interval) => _chunkS3QELJUEcjs.pitchClassOf.call(void 0, interval) === semitones);
3566
3617
  }
3567
3618
  function isDiatonicChord(chord, key) {
3568
3619
  return chordPitchClasses(chord).every((pc) => isScaleTone(pc, key));
3569
3620
  }
3621
+ function isNativeDominantSeventh(rootPc, key) {
3622
+ return isDiatonicChord(makeChord(rootPc, "dom7"), key);
3623
+ }
3570
3624
  function hasMajorThird(chord) {
3571
3625
  return hasInterval(chord, 4);
3572
3626
  }
@@ -3580,7 +3634,7 @@ function hasDominantSonority(chord) {
3580
3634
  return soundsMajorTriad(chord) || soundsDominantSeventh(chord);
3581
3635
  }
3582
3636
  function isDominantChordOf(chord, key) {
3583
- if (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc - key.rootPc) !== 7) {
3637
+ if (_chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc - key.rootPc) !== 7) {
3584
3638
  return false;
3585
3639
  }
3586
3640
  if (hasMajorThird(chord)) {
@@ -3590,17 +3644,17 @@ function isDominantChordOf(chord, key) {
3590
3644
  return suspended && hasInterval(chord, 10);
3591
3645
  }
3592
3646
  function isNeapolitanChordOf(chord, key) {
3593
- return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc - key.rootPc) === 1 && soundsMajorTriad(chord) && !isDiatonicChord(chord, key);
3647
+ return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc - key.rootPc) === 1 && soundsMajorTriad(chord) && !isDiatonicChord(chord, key);
3594
3648
  }
3595
3649
  var DOMINANT_DEGREE = 5;
3596
3650
  function heptatonicFrameOf(key) {
3597
- return scaleTonesInDegreeOrder(key).length === 7 ? key : majorKey(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc));
3651
+ return scaleTonesInDegreeOrder(key).length === 7 ? key : majorKey(_chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc));
3598
3652
  }
3599
3653
  function degreeTriad(tones, index) {
3600
3654
  const root = _nullishCoalesce(tones[index], () => ( 0));
3601
3655
  return {
3602
- third: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, (_nullishCoalesce(tones[(index + 2) % tones.length], () => ( 0))) - root),
3603
- fifth: _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, (_nullishCoalesce(tones[(index + 4) % tones.length], () => ( 0))) - root)
3656
+ third: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, (_nullishCoalesce(tones[(index + 2) % tones.length], () => ( 0))) - root),
3657
+ fifth: _chunkS3QELJUEcjs.pitchClassOf.call(void 0, (_nullishCoalesce(tones[(index + 4) % tones.length], () => ( 0))) - root)
3604
3658
  };
3605
3659
  }
3606
3660
  function tonicizableDegrees(key) {
@@ -3622,25 +3676,38 @@ function tonicizableDegrees(key) {
3622
3676
  return out;
3623
3677
  }
3624
3678
  function appliedDominantTarget(rootPc, key) {
3625
- const target = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, rootPc);
3679
+ const target = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, rootPc);
3626
3680
  return _nullishCoalesce(tonicizableDegrees(key).find(
3627
3681
  (degree) => degree.degreeNumber !== 1 && degree.rootPc === target
3628
3682
  ), () => ( null));
3629
3683
  }
3684
+ function cadencesThroughRaisedSeventh(key) {
3685
+ return isMinorMask(key.modeMask12) && scaleSystemOf(key) === "common-practice";
3686
+ }
3630
3687
  function leadingTonePcOf(key) {
3631
- return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc - 1);
3688
+ return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc - 1);
3689
+ }
3690
+ var LEADING_TONE_QUALITY_NAMES = ["dim", "dim7", "m7b5"];
3691
+ var LEADING_TONE_QUALITIES = new Set(
3692
+ LEADING_TONE_QUALITY_NAMES
3693
+ );
3694
+ function appliedChordTarget(chord, key) {
3695
+ const dominant = hasDominantSonority(chord);
3696
+ if (!dominant && !LEADING_TONE_QUALITIES.has(chord.quality)) {
3697
+ return null;
3698
+ }
3699
+ return appliedDominantTarget(chord.rootPc + (dominant ? 5 : 1), key);
3632
3700
  }
3633
- var LEADING_TONE_QUALITIES = /* @__PURE__ */ new Set(["dim", "dim7", "m7b5"]);
3634
3701
  function soundsDiminishedTriad(chord) {
3635
3702
  return hasInterval(chord, 3) && hasInterval(chord, 6) && !hasInterval(chord, 7);
3636
3703
  }
3637
3704
  function isLeadingToneChordOf(chord, key) {
3638
- return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc) === leadingTonePcOf(key) && soundsDiminishedTriad(chord);
3705
+ return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc) === leadingTonePcOf(key) && soundsDiminishedTriad(chord);
3639
3706
  }
3640
3707
  function isFunctioningLeadingTone(chord, key) {
3641
3708
  const role = chordToneRole(leadingTonePcOf(key), chord);
3642
3709
  if (role === "third") {
3643
- return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc) === _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc + 7);
3710
+ return _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc) === _chunkS3QELJUEcjs.pitchClassOf.call(void 0, key.rootPc + 7);
3644
3711
  }
3645
3712
  if (role === "root") {
3646
3713
  return soundsDiminishedTriad(chord);
@@ -3649,7 +3716,7 @@ function isFunctioningLeadingTone(chord, key) {
3649
3716
  }
3650
3717
  function seventhPcOf(chord) {
3651
3718
  for (const interval of chord.intervals) {
3652
- const pc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
3719
+ const pc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
3653
3720
  if (chordToneRole(pc, chord) === "seventh") {
3654
3721
  return pc;
3655
3722
  }
@@ -3658,7 +3725,7 @@ function seventhPcOf(chord) {
3658
3725
  }
3659
3726
  function fifthPcOf(chord) {
3660
3727
  for (const interval of chord.intervals) {
3661
- const pc = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
3728
+ const pc = _chunkS3QELJUEcjs.pitchClassOf.call(void 0, chord.rootPc + interval);
3662
3729
  if (chordToneRole(pc, chord) === "fifth") {
3663
3730
  return pc;
3664
3731
  }
@@ -3674,7 +3741,7 @@ function isFrustratedLeadingTone(fromPitch, toPitch, nextChord) {
3674
3741
  return false;
3675
3742
  }
3676
3743
  const fifthPc = fifthPcOf(nextChord);
3677
- return fifthPc !== void 0 && _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, toPitch) === fifthPc;
3744
+ return fifthPc !== void 0 && _chunkS3QELJUEcjs.pitchClassOf.call(void 0, toPitch) === fifthPc;
3678
3745
  }
3679
3746
 
3680
3747
 
@@ -3822,5 +3889,11 @@ function isFrustratedLeadingTone(fromPitch, toPitch, nextChord) {
3822
3889
 
3823
3890
 
3824
3891
 
3825
- exports.maskFromOffsets = maskFromOffsets; exports.MAJOR_MASK = MAJOR_MASK; exports.NATURAL_MINOR_MASK = NATURAL_MINOR_MASK; exports.HARMONIC_MINOR_MASK = HARMONIC_MINOR_MASK; exports.MELODIC_MINOR_MASK = MELODIC_MINOR_MASK; exports.DORIAN_MASK = DORIAN_MASK; exports.PHRYGIAN_MASK = PHRYGIAN_MASK; exports.LYDIAN_MASK = LYDIAN_MASK; exports.MIXOLYDIAN_MASK = MIXOLYDIAN_MASK; exports.LOCRIAN_MASK = LOCRIAN_MASK; exports.MAJOR_PENTATONIC_MASK = MAJOR_PENTATONIC_MASK; exports.MINOR_PENTATONIC_MASK = MINOR_PENTATONIC_MASK; exports.BLUES_MASK = BLUES_MASK; exports.WHOLE_TONE_MASK = WHOLE_TONE_MASK; exports.OCTATONIC_HALF_WHOLE_MASK = OCTATONIC_HALF_WHOLE_MASK; exports.OCTATONIC_WHOLE_HALF_MASK = OCTATONIC_WHOLE_HALF_MASK; exports.CHROMATIC_MASK = CHROMATIC_MASK; exports.assertModeMask = assertModeMask; exports.LYDIAN_DOMINANT_MASK = LYDIAN_DOMINANT_MASK; exports.MIXOLYDIAN_B13_MASK = MIXOLYDIAN_B13_MASK; exports.LOCRIAN_NATURAL2_MASK = LOCRIAN_NATURAL2_MASK; exports.ALTERED_MASK = ALTERED_MASK; exports.PHRYGIAN_DOMINANT_MASK = PHRYGIAN_DOMINANT_MASK; exports.MIYAKO_BUSHI_MASK = MIYAKO_BUSHI_MASK; exports.RITSU_MASK = RITSU_MASK; exports.RYUKYU_MASK = RYUKYU_MASK; exports.DOUBLE_HARMONIC_MASK = DOUBLE_HARMONIC_MASK; exports.TODI_MASK = TODI_MASK; exports.MARWA_MASK = MARWA_MASK; exports.PURVI_MASK = PURVI_MASK; exports.NAMED_SCALES = NAMED_SCALES; exports.WORLD_SCALES = WORLD_SCALES; exports.SCALE_ALIASES = SCALE_ALIASES; exports.resolveScaleName = resolveScaleName; exports.namedScaleMask = namedScaleMask; exports.requireScaleMask = requireScaleMask; exports.isMinorMask = isMinorMask; exports.variantOfMask = variantOfMask; exports.assertKeyVariant = assertKeyVariant; exports.scaleNameOfMask = scaleNameOfMask; exports.tryResolveKeyName = tryResolveKeyName; exports.toKeyScale = toKeyScale; exports.isScaleTone = isScaleTone; exports.nearestScaleTone = nearestScaleTone; exports.scaleLadderPosition = scaleLadderPosition; exports.scaleLadderPitch = scaleLadderPitch; exports.shiftByScaleDegrees = shiftByScaleDegrees; exports.pitchToScaleDegree = pitchToScaleDegree; exports.diatonicPitchClasses = diatonicPitchClasses; exports.scaleTonesInDegreeOrder = scaleTonesInDegreeOrder; exports.assertTonicOf = assertTonicOf; exports.spellPitchClass = spellPitchClass; exports.spellScale = spellScale; exports.spellPitchClasses = spellPitchClasses; exports.spellChordFromRoot = spellChordFromRoot; exports.spellChord = spellChord; exports.spellPitch = spellPitch; exports.noteNames = noteNames; exports.isSignatureKey = isSignatureKey; exports.keySignatureFifths = keySignatureFifths; exports.keyFromFifths = keyFromFifths; exports.spelledKeyOf = spelledKeyOf; exports.relativeKeyOf = relativeKeyOf; exports.parallelKeyOf = parallelKeyOf; exports.isWrittenTonic = isWrittenTonic; exports.dominantKeyOf = dominantKeyOf; exports.subdominantKeyOf = subdominantKeyOf; exports.enharmonicKeyOf = enharmonicKeyOf; exports.relatedKeysOf = relatedKeysOf; exports.keyRelationBetween = keyRelationBetween; exports.resolveKey = resolveKey; exports.scaleOf = scaleOf; exports.majorKey = majorKey; exports.minorKey = minorKey; exports.scaleByName = scaleByName; exports.SCALE_SYSTEMS = SCALE_SYSTEMS; exports.scaleSystemOf = scaleSystemOf; exports.supportsFunctionalHarmony = supportsFunctionalHarmony; exports.chordSpecIntervals = chordSpecIntervals; exports.chordSpecQuality = chordSpecQuality; exports.chordQualities = chordQualities; exports.assertChordQuality = assertChordQuality; exports.assertChord = assertChord; exports.chordFromDegree = chordFromDegree; exports.makeChord = makeChord; exports.chordFromSpec = chordFromSpec; exports.chordSpecOf = chordSpecOf; exports.chordFromSpan = chordFromSpan; exports.spanFromChord = spanFromChord; exports.transposeChord = transposeChord; exports.chordToneSpellings = chordToneSpellings; exports.chordPitchClasses = chordPitchClasses; exports.intervalAboveRoot = intervalAboveRoot; exports.isChordMember = isChordMember; exports.chordToneRole = chordToneRole; exports.degreeOfInterval = degreeOfInterval; exports.thirdSlotOf = thirdSlotOf; exports.displacedThirds = displacedThirds; exports.diatonicTriad = diatonicTriad; exports.diatonicSeventh = diatonicSeventh; exports.simpleIntervalNumber = simpleIntervalNumber; exports.classifySpelledInterval = classifySpelledInterval; exports.voiceIndependence = voiceIndependence; exports.createsVoiceCrossing = createsVoiceCrossing; exports.createsVerticalDissonance = createsVerticalDissonance; exports.isForbiddenMelodicLeap = isForbiddenMelodicLeap; exports.isAugmentedMelodicInterval = isAugmentedMelodicInterval; exports.createsParallelPerfect = createsParallelPerfect; exports.createsParallelOctave = createsParallelOctave; exports.createsParallelUnison = createsParallelUnison; exports.createsHiddenParallelPerfect = createsHiddenParallelPerfect; exports.createsBattuta = createsBattuta; exports.createsVoiceOverlap = createsVoiceOverlap; exports.exceedsSpacing = exceedsSpacing; exports.isLeadingToneResolution = isLeadingToneResolution; exports.PROFILE_WEIGHTS = PROFILE_WEIGHTS; exports.profileWeights = profileWeights; exports.NoteSafety = NoteSafety; exports.ReasonFlag = ReasonFlag; exports.evaluateSafety = evaluateSafety; exports.enumerateSafePitches = enumerateSafePitches; exports.toChordData = toChordData; exports.parseChordSymbol = parseChordSymbol; exports.tryParseChordSymbol = tryParseChordSymbol; exports.formatChordSymbol = formatChordSymbol; exports.transposeChordSpellings = transposeChordSpellings; exports.transposeChordSymbol = transposeChordSymbol; exports.isDiatonicChord = isDiatonicChord; exports.hasMajorThird = hasMajorThird; exports.soundsDominantSeventh = soundsDominantSeventh; exports.hasDominantSonority = hasDominantSonority; exports.isDominantChordOf = isDominantChordOf; exports.isNeapolitanChordOf = isNeapolitanChordOf; exports.heptatonicFrameOf = heptatonicFrameOf; exports.tonicizableDegrees = tonicizableDegrees; exports.appliedDominantTarget = appliedDominantTarget; exports.leadingTonePcOf = leadingTonePcOf; exports.LEADING_TONE_QUALITIES = LEADING_TONE_QUALITIES; exports.isLeadingToneChordOf = isLeadingToneChordOf; exports.isFunctioningLeadingTone = isFunctioningLeadingTone; exports.seventhPcOf = seventhPcOf; exports.fifthPcOf = fifthPcOf; exports.isDescendingStep = isDescendingStep; exports.isFrustratedLeadingTone = isFrustratedLeadingTone;
3826
- //# sourceMappingURL=chunk-3R3QVKY5.cjs.map
3892
+
3893
+
3894
+
3895
+
3896
+
3897
+
3898
+ exports.maskFromOffsets = maskFromOffsets; exports.MAJOR_MASK = MAJOR_MASK; exports.NATURAL_MINOR_MASK = NATURAL_MINOR_MASK; exports.HARMONIC_MINOR_MASK = HARMONIC_MINOR_MASK; exports.MELODIC_MINOR_MASK = MELODIC_MINOR_MASK; exports.DORIAN_MASK = DORIAN_MASK; exports.PHRYGIAN_MASK = PHRYGIAN_MASK; exports.LYDIAN_MASK = LYDIAN_MASK; exports.MIXOLYDIAN_MASK = MIXOLYDIAN_MASK; exports.LOCRIAN_MASK = LOCRIAN_MASK; exports.MAJOR_PENTATONIC_MASK = MAJOR_PENTATONIC_MASK; exports.MINOR_PENTATONIC_MASK = MINOR_PENTATONIC_MASK; exports.BLUES_MASK = BLUES_MASK; exports.WHOLE_TONE_MASK = WHOLE_TONE_MASK; exports.OCTATONIC_HALF_WHOLE_MASK = OCTATONIC_HALF_WHOLE_MASK; exports.OCTATONIC_WHOLE_HALF_MASK = OCTATONIC_WHOLE_HALF_MASK; exports.CHROMATIC_MASK = CHROMATIC_MASK; exports.assertModeMask = assertModeMask; exports.LYDIAN_DOMINANT_MASK = LYDIAN_DOMINANT_MASK; exports.MIXOLYDIAN_B13_MASK = MIXOLYDIAN_B13_MASK; exports.LOCRIAN_NATURAL2_MASK = LOCRIAN_NATURAL2_MASK; exports.ALTERED_MASK = ALTERED_MASK; exports.PHRYGIAN_DOMINANT_MASK = PHRYGIAN_DOMINANT_MASK; exports.MIYAKO_BUSHI_MASK = MIYAKO_BUSHI_MASK; exports.RITSU_MASK = RITSU_MASK; exports.RYUKYU_MASK = RYUKYU_MASK; exports.DOUBLE_HARMONIC_MASK = DOUBLE_HARMONIC_MASK; exports.TODI_MASK = TODI_MASK; exports.MARWA_MASK = MARWA_MASK; exports.PURVI_MASK = PURVI_MASK; exports.NAMED_SCALES = NAMED_SCALES; exports.WORLD_SCALES = WORLD_SCALES; exports.SCALE_ALIASES = SCALE_ALIASES; exports.resolveScaleName = resolveScaleName; exports.namedScaleMask = namedScaleMask; exports.requireScaleMask = requireScaleMask; exports.isMinorMask = isMinorMask; exports.variantOfMask = variantOfMask; exports.assertKeyVariant = assertKeyVariant; exports.scaleNameOfMask = scaleNameOfMask; exports.tryResolveKeyName = tryResolveKeyName; exports.toKeyScale = toKeyScale; exports.isScaleTone = isScaleTone; exports.nearestScaleTone = nearestScaleTone; exports.scaleLadderPosition = scaleLadderPosition; exports.scaleLadderPitch = scaleLadderPitch; exports.shiftByScaleDegrees = shiftByScaleDegrees; exports.pitchToScaleDegree = pitchToScaleDegree; exports.diatonicPitchClasses = diatonicPitchClasses; exports.scaleTonesInDegreeOrder = scaleTonesInDegreeOrder; exports.assertTonicOf = assertTonicOf; exports.spellPitchClass = spellPitchClass; exports.spellScale = spellScale; exports.spellPitchClasses = spellPitchClasses; exports.spellChordFromRoot = spellChordFromRoot; exports.spellChord = spellChord; exports.spellPitch = spellPitch; exports.noteNames = noteNames; exports.isSignatureKey = isSignatureKey; exports.keySignatureFifths = keySignatureFifths; exports.keyFromFifths = keyFromFifths; exports.spelledKeyOf = spelledKeyOf; exports.relativeKeyOf = relativeKeyOf; exports.parallelKeyOf = parallelKeyOf; exports.isWrittenTonic = isWrittenTonic; exports.dominantKeyOf = dominantKeyOf; exports.subdominantKeyOf = subdominantKeyOf; exports.enharmonicKeyOf = enharmonicKeyOf; exports.relatedKeysOf = relatedKeysOf; exports.keyRelationBetween = keyRelationBetween; exports.resolveKey = resolveKey; exports.scaleOf = scaleOf; exports.majorKey = majorKey; exports.minorKey = minorKey; exports.scaleByName = scaleByName; exports.SCALE_SYSTEMS = SCALE_SYSTEMS; exports.scaleSystemOf = scaleSystemOf; exports.supportsFunctionalHarmony = supportsFunctionalHarmony; exports.chordSpecIntervals = chordSpecIntervals; exports.QUALITY_INTERVALS = QUALITY_INTERVALS; exports.chordSpecForQuality = chordSpecForQuality; exports.chordSpecQuality = chordSpecQuality; exports.chordQualities = chordQualities; exports.assertChordQuality = assertChordQuality; exports.assertChord = assertChord; exports.chordFromDegree = chordFromDegree; exports.makeChord = makeChord; exports.makeSpelledChord = makeSpelledChord; exports.keySpelling = keySpelling; exports.chordFromSpec = chordFromSpec; exports.chordSpecOf = chordSpecOf; exports.chordFromSpan = chordFromSpan; exports.spanFromChord = spanFromChord; exports.transposeChord = transposeChord; exports.chordToneSpellings = chordToneSpellings; exports.chordPitchClasses = chordPitchClasses; exports.intervalAboveRoot = intervalAboveRoot; exports.isChordMember = isChordMember; exports.chordToneRole = chordToneRole; exports.degreeOfInterval = degreeOfInterval; exports.thirdSlotOf = thirdSlotOf; exports.displacedThirds = displacedThirds; exports.diatonicTriad = diatonicTriad; exports.diatonicSeventh = diatonicSeventh; exports.simpleIntervalNumber = simpleIntervalNumber; exports.classifySpelledInterval = classifySpelledInterval; exports.voiceIndependence = voiceIndependence; exports.createsVoiceCrossing = createsVoiceCrossing; exports.createsVerticalDissonance = createsVerticalDissonance; exports.isForbiddenMelodicLeap = isForbiddenMelodicLeap; exports.isAugmentedMelodicInterval = isAugmentedMelodicInterval; exports.createsParallelPerfect = createsParallelPerfect; exports.createsParallelOctave = createsParallelOctave; exports.createsParallelUnison = createsParallelUnison; exports.createsHiddenParallelPerfect = createsHiddenParallelPerfect; exports.createsBattuta = createsBattuta; exports.createsVoiceOverlap = createsVoiceOverlap; exports.exceedsSpacing = exceedsSpacing; exports.isLeadingToneResolution = isLeadingToneResolution; exports.PROFILE_WEIGHTS = PROFILE_WEIGHTS; exports.profileWeights = profileWeights; exports.NoteSafety = NoteSafety; exports.ReasonFlag = ReasonFlag; exports.evaluateSafety = evaluateSafety; exports.enumerateSafePitches = enumerateSafePitches; exports.toChordData = toChordData; exports.spellingAbove = spellingAbove; exports.parseChordSymbol = parseChordSymbol; exports.tryParseChordSymbol = tryParseChordSymbol; exports.formatChordSymbol = formatChordSymbol; exports.transposeChordSpellings = transposeChordSpellings; exports.transposeChordSymbol = transposeChordSymbol; exports.isDiatonicChord = isDiatonicChord; exports.isNativeDominantSeventh = isNativeDominantSeventh; exports.hasMajorThird = hasMajorThird; exports.soundsDominantSeventh = soundsDominantSeventh; exports.isDominantChordOf = isDominantChordOf; exports.isNeapolitanChordOf = isNeapolitanChordOf; exports.heptatonicFrameOf = heptatonicFrameOf; exports.tonicizableDegrees = tonicizableDegrees; exports.cadencesThroughRaisedSeventh = cadencesThroughRaisedSeventh; exports.leadingTonePcOf = leadingTonePcOf; exports.LEADING_TONE_QUALITIES = LEADING_TONE_QUALITIES; exports.appliedChordTarget = appliedChordTarget; exports.isLeadingToneChordOf = isLeadingToneChordOf; exports.isFunctioningLeadingTone = isFunctioningLeadingTone; exports.seventhPcOf = seventhPcOf; exports.fifthPcOf = fifthPcOf; exports.isDescendingStep = isDescendingStep; exports.isFrustratedLeadingTone = isFrustratedLeadingTone;
3899
+ //# sourceMappingURL=chunk-YDGMWH43.cjs.map