@libraz/libcantus 0.9.4 → 0.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/README.md +27 -18
  2. package/README_ja.md +268 -0
  3. package/dist/analyze/index.cjs +7 -7
  4. package/dist/analyze/index.d.cts +9 -99
  5. package/dist/analyze/index.d.ts +9 -99
  6. package/dist/analyze/index.js +6 -6
  7. package/dist/{chunk-36N73KZ3.cjs → chunk-2A2QMA74.cjs} +80 -65
  8. package/dist/chunk-2A2QMA74.cjs.map +1 -0
  9. package/dist/{chunk-YLEMGEFH.js → chunk-2PTFGVD7.js} +50 -35
  10. package/dist/chunk-2PTFGVD7.js.map +1 -0
  11. package/dist/{chunk-ZEJR4TKL.cjs → chunk-357ZDPVU.cjs} +36 -47
  12. package/dist/chunk-357ZDPVU.cjs.map +1 -0
  13. package/dist/{chunk-EHVEBWM5.js → chunk-3KX76RLG.js} +136 -37
  14. package/dist/chunk-3KX76RLG.js.map +1 -0
  15. package/dist/{chunk-RC6GBMCD.cjs → chunk-4VZ5MZAM.cjs} +155 -111
  16. package/dist/chunk-4VZ5MZAM.cjs.map +1 -0
  17. package/dist/{chunk-RK35RIN7.js → chunk-7EONYVI5.js} +115 -28
  18. package/dist/chunk-7EONYVI5.js.map +1 -0
  19. package/dist/{chunk-GQSGS2N4.js → chunk-7JEP3MFY.js} +5 -16
  20. package/dist/chunk-7JEP3MFY.js.map +1 -0
  21. package/dist/{chunk-7NKDPF74.js → chunk-AID75RN3.js} +203 -104
  22. package/dist/chunk-AID75RN3.js.map +1 -0
  23. package/dist/{chunk-FNDWXRRI.cjs → chunk-BSLTLGM3.cjs} +55 -37
  24. package/dist/chunk-BSLTLGM3.cjs.map +1 -0
  25. package/dist/{chunk-NP4NA2FB.cjs → chunk-CU6VG2YM.cjs} +39 -36
  26. package/dist/chunk-CU6VG2YM.cjs.map +1 -0
  27. package/dist/{chunk-NYYWMV2C.js → chunk-DZMHIGI4.js} +27 -17
  28. package/dist/chunk-DZMHIGI4.js.map +1 -0
  29. package/dist/{chunk-I24MV65U.js → chunk-EDOTEABK.js} +18 -15
  30. package/dist/{chunk-I24MV65U.js.map → chunk-EDOTEABK.js.map} +1 -1
  31. package/dist/{chunk-NKIBQ6PT.js → chunk-HN2OEUN2.js} +7 -4
  32. package/dist/chunk-HN2OEUN2.js.map +1 -0
  33. package/dist/{chunk-D2FAJBYL.js → chunk-KBTTEX7Q.js} +30 -12
  34. package/dist/chunk-KBTTEX7Q.js.map +1 -0
  35. package/dist/{chunk-CAN76NCU.cjs → chunk-KQN2ZYND.cjs} +147 -102
  36. package/dist/chunk-KQN2ZYND.cjs.map +1 -0
  37. package/dist/{chunk-4HLLZPXT.cjs → chunk-MPTVJIVG.cjs} +350 -251
  38. package/dist/chunk-MPTVJIVG.cjs.map +1 -0
  39. package/dist/{chunk-RUMU3UA6.cjs → chunk-MTMZTMWM.cjs} +12 -12
  40. package/dist/{chunk-RUMU3UA6.cjs.map → chunk-MTMZTMWM.cjs.map} +1 -1
  41. package/dist/{chunk-KMHOICIY.js → chunk-NNB67XA2.js} +90 -45
  42. package/dist/chunk-NNB67XA2.js.map +1 -0
  43. package/dist/{chunk-LW53AHQU.cjs → chunk-OL3IHHSJ.cjs} +228 -141
  44. package/dist/chunk-OL3IHHSJ.cjs.map +1 -0
  45. package/dist/{chunk-7MGZ7D62.cjs → chunk-PI3UXRWK.cjs} +43 -13
  46. package/dist/chunk-PI3UXRWK.cjs.map +1 -0
  47. package/dist/{chunk-XEBG3G53.js → chunk-R2VVFAIN.js} +42 -12
  48. package/dist/chunk-R2VVFAIN.js.map +1 -0
  49. package/dist/{chunk-Q6OP4U43.cjs → chunk-WFDXOLUB.cjs} +50 -40
  50. package/dist/chunk-WFDXOLUB.cjs.map +1 -0
  51. package/dist/{chunk-NVE34YGZ.cjs → chunk-WTAN4ACG.cjs} +212 -113
  52. package/dist/chunk-WTAN4ACG.cjs.map +1 -0
  53. package/dist/{chunk-FCANXBAT.cjs → chunk-YFJXS3AU.cjs} +8 -5
  54. package/dist/chunk-YFJXS3AU.cjs.map +1 -0
  55. package/dist/{chunk-Q2XUP227.js → chunk-YUE6TJ4M.js} +89 -45
  56. package/dist/chunk-YUE6TJ4M.js.map +1 -0
  57. package/dist/{chunk-HKGYCQ34.js → chunk-ZGLJM4A4.js} +2 -2
  58. package/dist/core/index.cjs +15 -5
  59. package/dist/core/index.cjs.map +1 -1
  60. package/dist/core/index.d.cts +14 -4
  61. package/dist/core/index.d.ts +14 -4
  62. package/dist/core/index.js +14 -4
  63. package/dist/{function-DNugAOrt.d.cts → function-CxixTB02.d.cts} +98 -7
  64. package/dist/{function-BtiZb9i9.d.ts → function-DTCt675z.d.ts} +98 -7
  65. package/dist/generate/index.cjs +10 -10
  66. package/dist/generate/index.d.cts +21 -21
  67. package/dist/generate/index.d.ts +21 -21
  68. package/dist/generate/index.js +9 -9
  69. package/dist/{index-tJhkmQgE.d.cts → index-B2Ulxxpo.d.cts} +3 -2
  70. package/dist/{index-Be74mcon.d.cts → index-BkYJ0xMq.d.cts} +2 -2
  71. package/dist/{index-6VR8-kit.d.ts → index-BuaB-ypt.d.ts} +3 -2
  72. package/dist/{index-70p168VM.d.ts → index-CAN7v-kw.d.ts} +9 -2
  73. package/dist/{index-C83mZI1P.d.ts → index-COw1Ky9g.d.ts} +1 -1
  74. package/dist/{index-tSQh-xwY.d.ts → index-Cfx8xgH0.d.ts} +1 -1
  75. package/dist/{index-C5UBbQ4G.d.ts → index-DRtIhlJj.d.ts} +2 -2
  76. package/dist/{index-BtXT6UQ0.d.cts → index-alrRninU.d.cts} +9 -2
  77. package/dist/{index-y_ak9_Hi.d.cts → index-oTQbYYIs.d.cts} +1 -1
  78. package/dist/{index-OG65ocOr.d.ts → index-tR9jTn26.d.cts} +4 -1
  79. package/dist/{index-OG65ocOr.d.cts → index-tR9jTn26.d.ts} +4 -1
  80. package/dist/{index-D6b6na69.d.cts → index-x2vcsduE.d.cts} +1 -1
  81. package/dist/index.cjs +24 -14
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.d.cts +11 -11
  84. package/dist/index.d.ts +11 -11
  85. package/dist/index.js +23 -13
  86. package/dist/model/index.cjs +7 -7
  87. package/dist/model/index.d.cts +48 -16
  88. package/dist/model/index.d.ts +48 -16
  89. package/dist/model/index.js +6 -6
  90. package/dist/{styled-DIRkk9Uz.d.ts → styled-Bl0ZK28h.d.ts} +40 -3
  91. package/dist/{styled-DJbkJQfj.d.cts → styled-Crv6SA4S.d.cts} +40 -3
  92. package/dist/theory/index.cjs +6 -6
  93. package/dist/theory/index.d.cts +9 -9
  94. package/dist/theory/index.d.ts +9 -9
  95. package/dist/theory/index.js +5 -5
  96. package/package.json +12 -9
  97. package/dist/chunk-36N73KZ3.cjs.map +0 -1
  98. package/dist/chunk-4HLLZPXT.cjs.map +0 -1
  99. package/dist/chunk-7MGZ7D62.cjs.map +0 -1
  100. package/dist/chunk-7NKDPF74.js.map +0 -1
  101. package/dist/chunk-CAN76NCU.cjs.map +0 -1
  102. package/dist/chunk-D2FAJBYL.js.map +0 -1
  103. package/dist/chunk-EHVEBWM5.js.map +0 -1
  104. package/dist/chunk-FCANXBAT.cjs.map +0 -1
  105. package/dist/chunk-FNDWXRRI.cjs.map +0 -1
  106. package/dist/chunk-GQSGS2N4.js.map +0 -1
  107. package/dist/chunk-KMHOICIY.js.map +0 -1
  108. package/dist/chunk-LW53AHQU.cjs.map +0 -1
  109. package/dist/chunk-NKIBQ6PT.js.map +0 -1
  110. package/dist/chunk-NP4NA2FB.cjs.map +0 -1
  111. package/dist/chunk-NVE34YGZ.cjs.map +0 -1
  112. package/dist/chunk-NYYWMV2C.js.map +0 -1
  113. package/dist/chunk-Q2XUP227.js.map +0 -1
  114. package/dist/chunk-Q6OP4U43.cjs.map +0 -1
  115. package/dist/chunk-RC6GBMCD.cjs.map +0 -1
  116. package/dist/chunk-RK35RIN7.js.map +0 -1
  117. package/dist/chunk-XEBG3G53.js.map +0 -1
  118. package/dist/chunk-YLEMGEFH.js.map +0 -1
  119. package/dist/chunk-ZEJR4TKL.cjs.map +0 -1
  120. /package/dist/{chunk-HKGYCQ34.js.map → chunk-ZGLJM4A4.js.map} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { K as KeyScale } from './types-BN6_Q9Kl.cjs';
2
- import { C as Chord } from './index-y_ak9_Hi.cjs';
2
+ import { C as Chord } from './index-oTQbYYIs.cjs';
3
3
 
4
4
  /**
5
5
  * Borrowed chords (modal interchange) and the Neapolitan.
@@ -22,7 +22,7 @@ type BorrowedSource = 'parallelMinor' | 'parallelMajor' | 'neapolitan' | null;
22
22
  * {@link parallelKey} — e.g. iv, bVI, or bVII in a major key, or the Picardy
23
23
  * tonic and major IV in a minor key. Two non-diatonic families are excluded:
24
24
  * chords diatonic to neither mode (they are chromatic, not borrowed), and, in
25
- * a minor key, chords explained by the harmonic minor scale (the major
25
+ * a minor key, chords explained by the altered minor forms (the major
26
26
  * dominant and raised-leading-tone chords), which are in-key alterations
27
27
  * rather than interchange even though they happen to fit the parallel major.
28
28
  *
@@ -37,7 +37,7 @@ declare function isBorrowedChord(chord: Chord, key: KeyScale): boolean;
37
37
  *
38
38
  * The Neapolitan (major triad on b2) is recognized first, since it sits
39
39
  * outside both parallel modes; parallel-mode borrowing follows the
40
- * {@link isBorrowedChord} rules. Diatonic chords, harmonic-minor alterations,
40
+ * {@link isBorrowedChord} rules. Diatonic chords and altered-minor chords,
41
41
  * and unrecognized chromatic chords all yield null.
42
42
  *
43
43
  * @param chord The chord to classify.
@@ -85,6 +85,96 @@ type Cadence = 'authentic' | 'plagal' | 'half' | 'deceptive' | null;
85
85
  */
86
86
  declare function detectCadence(from: Chord, to: Chord, key: KeyScale): Cadence;
87
87
 
88
+ /**
89
+ * Roman-numeral parsing and formatting.
90
+ *
91
+ * The {@link ROMAN_STYLE} table is the single source of truth for both
92
+ * directions, so {@link chordToRoman} and {@link romanToChord} stay mutual
93
+ * inverses by construction.
94
+ */
95
+
96
+ /**
97
+ * Build the chord denoted by a Roman numeral in a key.
98
+ *
99
+ * Supports accidentals (`bVII`, `#iv`), case-based triad quality, the `o`/`ø`/`+`
100
+ * suffixes, sevenths (`V7`, `viio7`, `Imaj7`), figured-bass inversions
101
+ * (`V6`, `V64`, `V65`, `V43`, `V42`), and applied/secondary chords via a slash
102
+ * (`V7/V`, `viio/ii`). The target after the slash is read as a scale degree
103
+ * whose root becomes a local major tonic for the applied chord. Inverted chords
104
+ * carry a `bassPc`.
105
+ *
106
+ * The `ø` glyph always denotes the half-diminished seventh (`iiø` == `iiø7` ==
107
+ * `m7b5`), since no half-diminished triad exists. Extension and added-tone
108
+ * suffixes are the canonical case-sensitive forms emitted by
109
+ * {@link chordToRoman} and honor the numeral case: `V9` -> `dom9`, `ii9` ->
110
+ * `min9`, `Imaj9` -> `maj9`, `V11` -> `11`, `V13` -> `13`, `Iadd6`/`iadd6` ->
111
+ * `6`/`min6`, `I69` -> `6/9`, `Isus2`/`Isus4`, `Iadd9`/`Iadd11`, `Ib5` ->
112
+ * `majb5`, `I5` -> `5`, and the altered dominants `V7b9`/`V7#9`/`V7#11`/`V7b13`.
113
+ * A figure string that is neither a recognized inversion nor a supported
114
+ * quality suffix throws rather than silently degrading to a triad.
115
+ *
116
+ * @param text The Roman numeral.
117
+ * @param key The prevailing key.
118
+ * @returns The chord.
119
+ * @example
120
+ * ```ts
121
+ * import { romanToChord, majorKey } from '@libraz/libcantus';
122
+ * romanToChord('V7', majorKey(0)); // G7 in C major: { rootPc: 7, quality: 'dom7', ... }
123
+ * ```
124
+ * @category Functional Harmony
125
+ */
126
+ declare function romanToChord(text: string, key: KeyScale): Chord;
127
+ /**
128
+ * Options for {@link chordToRoman}.
129
+ *
130
+ * @category Functional Harmony
131
+ */
132
+ type ChordToRomanOptions = {
133
+ /**
134
+ * Render a tonicizing chord as an applied numeral (`V7/V`, `viio7/ii`)
135
+ * instead of naming its root against the home key (`II7`, `#ivo7`).
136
+ *
137
+ * Off by default: naming the root is always a correct spelling, whereas
138
+ * whether a chromatic dominant is genuinely applied is a reading only the
139
+ * caller can make. Turning it on makes {@link chordToRoman} the exact inverse
140
+ * of {@link romanToChord} for the chords {@link secondaryDominant} builds.
141
+ */
142
+ applied?: boolean;
143
+ };
144
+ /**
145
+ * Render a chord as a Roman numeral relative to a key.
146
+ *
147
+ * Diatonic roots take their scale-degree numeral directly, so numerals are
148
+ * correct in both major and minor keys (and any custom scale). The quality
149
+ * selects the case and suffix; chromatic roots receive a flat/sharp spelling by
150
+ * convention. A key that is not heptatonic has no numeral of its own for every
151
+ * degree, so its roots are named against its parallel major.
152
+ *
153
+ * When the chord carries a `bassPc` on a chord tone, a figured-bass inversion
154
+ * (`6`, `64`, `65`, `43`, `42`) is emitted for plain triads and true seventh
155
+ * chords; added-tone and extended qualities have no lossless figure and render
156
+ * in root position instead (the bass is dropped, pitch classes are preserved).
157
+ *
158
+ * A `bassPc` that is *not* a chord tone — a pedal or passing bass such as
159
+ * `C/D` — is likewise dropped, and the numeral names the upper chord alone.
160
+ * Roman-numeral notation spends its slash on applied chords (`V7/V`), so there
161
+ * is no unambiguous way to write such a bass; a caller that must keep it should
162
+ * read `chord.bassPc` alongside the numeral.
163
+ *
164
+ * @param chord The chord to name.
165
+ * @param key The prevailing key.
166
+ * @param opts `applied` renders tonicizing chords as `V7/V`-style numerals.
167
+ * @returns The Roman numeral string.
168
+ * @example
169
+ * ```ts
170
+ * import { chordToRoman, makeChord, majorKey } from '@libraz/libcantus';
171
+ * chordToRoman(makeChord(7, 'dom7'), majorKey(0)); // => 'V7' (G7 in C major)
172
+ * chordToRoman(makeChord(2, 'dom7'), majorKey(0), { applied: true }); // => 'V7/V'
173
+ * ```
174
+ * @category Functional Harmony
175
+ */
176
+ declare function chordToRoman(chord: Chord, key: KeyScale, opts?: ChordToRomanOptions): string;
177
+
88
178
  /**
89
179
  * Harmonic function (tonic / subdominant / dominant), diatonicity, parallel-key
90
180
  * mirroring, and full chord analysis.
@@ -184,6 +274,7 @@ declare function parallelKey(key: KeyScale): KeyScale;
184
274
  *
185
275
  * @param chord The chord to analyze.
186
276
  * @param key The prevailing key.
277
+ * @param opts Options used when rendering the Roman numeral.
187
278
  * @returns The chord analysis.
188
279
  * @example
189
280
  * ```ts
@@ -193,16 +284,16 @@ declare function parallelKey(key: KeyScale): KeyScale;
193
284
  * ```
194
285
  * @category Functional Harmony
195
286
  */
196
- declare function analyzeChord(chord: Chord, key: KeyScale): ChordAnalysis;
287
+ declare function analyzeChord(chord: Chord, key: KeyScale, opts?: ChordToRomanOptions): ChordAnalysis;
197
288
  /**
198
289
  * The secondary dominant (V7) that tonicizes a scale degree.
199
290
  *
200
- * @param targetDegree 0-based scale degree to tonicize, in 0..6.
291
+ * @param targetDegree 0-based scale degree to tonicize.
201
292
  * @param key The prevailing key.
202
293
  * @returns A dominant-seventh chord a fifth above the target's root.
203
- * @throws If `targetDegree` is not an integer in 0..6.
294
+ * @throws If `targetDegree` is not an integer naming a degree in `key`.
204
295
  * @category Functional Harmony
205
296
  */
206
297
  declare function secondaryDominant(targetDegree: number, key: KeyScale): Chord;
207
298
 
208
- export { type BorrowedSource as B, type Cadence as C, type HarmonicFunction as H, type ChordAnalysis as a, analyzeChord as b, borrowedSource as c, detectCadence as d, isDiatonic as e, functionOf as f, isMinorKey as g, isBorrowedChord as i, parallelKey as p, secondaryDominant as s };
299
+ export { type BorrowedSource as B, type Cadence as C, type HarmonicFunction as H, type ChordAnalysis as a, type ChordToRomanOptions as b, analyzeChord as c, borrowedSource as d, chordToRoman as e, detectCadence as f, functionOf as g, isDiatonic as h, isBorrowedChord as i, isMinorKey as j, parallelKey as p, romanToChord as r, secondaryDominant as s };
@@ -1,5 +1,5 @@
1
1
  import { K as KeyScale } from './types-BN6_Q9Kl.js';
2
- import { C as Chord } from './index-C83mZI1P.js';
2
+ import { C as Chord } from './index-COw1Ky9g.js';
3
3
 
4
4
  /**
5
5
  * Borrowed chords (modal interchange) and the Neapolitan.
@@ -22,7 +22,7 @@ type BorrowedSource = 'parallelMinor' | 'parallelMajor' | 'neapolitan' | null;
22
22
  * {@link parallelKey} — e.g. iv, bVI, or bVII in a major key, or the Picardy
23
23
  * tonic and major IV in a minor key. Two non-diatonic families are excluded:
24
24
  * chords diatonic to neither mode (they are chromatic, not borrowed), and, in
25
- * a minor key, chords explained by the harmonic minor scale (the major
25
+ * a minor key, chords explained by the altered minor forms (the major
26
26
  * dominant and raised-leading-tone chords), which are in-key alterations
27
27
  * rather than interchange even though they happen to fit the parallel major.
28
28
  *
@@ -37,7 +37,7 @@ declare function isBorrowedChord(chord: Chord, key: KeyScale): boolean;
37
37
  *
38
38
  * The Neapolitan (major triad on b2) is recognized first, since it sits
39
39
  * outside both parallel modes; parallel-mode borrowing follows the
40
- * {@link isBorrowedChord} rules. Diatonic chords, harmonic-minor alterations,
40
+ * {@link isBorrowedChord} rules. Diatonic chords and altered-minor chords,
41
41
  * and unrecognized chromatic chords all yield null.
42
42
  *
43
43
  * @param chord The chord to classify.
@@ -85,6 +85,96 @@ type Cadence = 'authentic' | 'plagal' | 'half' | 'deceptive' | null;
85
85
  */
86
86
  declare function detectCadence(from: Chord, to: Chord, key: KeyScale): Cadence;
87
87
 
88
+ /**
89
+ * Roman-numeral parsing and formatting.
90
+ *
91
+ * The {@link ROMAN_STYLE} table is the single source of truth for both
92
+ * directions, so {@link chordToRoman} and {@link romanToChord} stay mutual
93
+ * inverses by construction.
94
+ */
95
+
96
+ /**
97
+ * Build the chord denoted by a Roman numeral in a key.
98
+ *
99
+ * Supports accidentals (`bVII`, `#iv`), case-based triad quality, the `o`/`ø`/`+`
100
+ * suffixes, sevenths (`V7`, `viio7`, `Imaj7`), figured-bass inversions
101
+ * (`V6`, `V64`, `V65`, `V43`, `V42`), and applied/secondary chords via a slash
102
+ * (`V7/V`, `viio/ii`). The target after the slash is read as a scale degree
103
+ * whose root becomes a local major tonic for the applied chord. Inverted chords
104
+ * carry a `bassPc`.
105
+ *
106
+ * The `ø` glyph always denotes the half-diminished seventh (`iiø` == `iiø7` ==
107
+ * `m7b5`), since no half-diminished triad exists. Extension and added-tone
108
+ * suffixes are the canonical case-sensitive forms emitted by
109
+ * {@link chordToRoman} and honor the numeral case: `V9` -> `dom9`, `ii9` ->
110
+ * `min9`, `Imaj9` -> `maj9`, `V11` -> `11`, `V13` -> `13`, `Iadd6`/`iadd6` ->
111
+ * `6`/`min6`, `I69` -> `6/9`, `Isus2`/`Isus4`, `Iadd9`/`Iadd11`, `Ib5` ->
112
+ * `majb5`, `I5` -> `5`, and the altered dominants `V7b9`/`V7#9`/`V7#11`/`V7b13`.
113
+ * A figure string that is neither a recognized inversion nor a supported
114
+ * quality suffix throws rather than silently degrading to a triad.
115
+ *
116
+ * @param text The Roman numeral.
117
+ * @param key The prevailing key.
118
+ * @returns The chord.
119
+ * @example
120
+ * ```ts
121
+ * import { romanToChord, majorKey } from '@libraz/libcantus';
122
+ * romanToChord('V7', majorKey(0)); // G7 in C major: { rootPc: 7, quality: 'dom7', ... }
123
+ * ```
124
+ * @category Functional Harmony
125
+ */
126
+ declare function romanToChord(text: string, key: KeyScale): Chord;
127
+ /**
128
+ * Options for {@link chordToRoman}.
129
+ *
130
+ * @category Functional Harmony
131
+ */
132
+ type ChordToRomanOptions = {
133
+ /**
134
+ * Render a tonicizing chord as an applied numeral (`V7/V`, `viio7/ii`)
135
+ * instead of naming its root against the home key (`II7`, `#ivo7`).
136
+ *
137
+ * Off by default: naming the root is always a correct spelling, whereas
138
+ * whether a chromatic dominant is genuinely applied is a reading only the
139
+ * caller can make. Turning it on makes {@link chordToRoman} the exact inverse
140
+ * of {@link romanToChord} for the chords {@link secondaryDominant} builds.
141
+ */
142
+ applied?: boolean;
143
+ };
144
+ /**
145
+ * Render a chord as a Roman numeral relative to a key.
146
+ *
147
+ * Diatonic roots take their scale-degree numeral directly, so numerals are
148
+ * correct in both major and minor keys (and any custom scale). The quality
149
+ * selects the case and suffix; chromatic roots receive a flat/sharp spelling by
150
+ * convention. A key that is not heptatonic has no numeral of its own for every
151
+ * degree, so its roots are named against its parallel major.
152
+ *
153
+ * When the chord carries a `bassPc` on a chord tone, a figured-bass inversion
154
+ * (`6`, `64`, `65`, `43`, `42`) is emitted for plain triads and true seventh
155
+ * chords; added-tone and extended qualities have no lossless figure and render
156
+ * in root position instead (the bass is dropped, pitch classes are preserved).
157
+ *
158
+ * A `bassPc` that is *not* a chord tone — a pedal or passing bass such as
159
+ * `C/D` — is likewise dropped, and the numeral names the upper chord alone.
160
+ * Roman-numeral notation spends its slash on applied chords (`V7/V`), so there
161
+ * is no unambiguous way to write such a bass; a caller that must keep it should
162
+ * read `chord.bassPc` alongside the numeral.
163
+ *
164
+ * @param chord The chord to name.
165
+ * @param key The prevailing key.
166
+ * @param opts `applied` renders tonicizing chords as `V7/V`-style numerals.
167
+ * @returns The Roman numeral string.
168
+ * @example
169
+ * ```ts
170
+ * import { chordToRoman, makeChord, majorKey } from '@libraz/libcantus';
171
+ * chordToRoman(makeChord(7, 'dom7'), majorKey(0)); // => 'V7' (G7 in C major)
172
+ * chordToRoman(makeChord(2, 'dom7'), majorKey(0), { applied: true }); // => 'V7/V'
173
+ * ```
174
+ * @category Functional Harmony
175
+ */
176
+ declare function chordToRoman(chord: Chord, key: KeyScale, opts?: ChordToRomanOptions): string;
177
+
88
178
  /**
89
179
  * Harmonic function (tonic / subdominant / dominant), diatonicity, parallel-key
90
180
  * mirroring, and full chord analysis.
@@ -184,6 +274,7 @@ declare function parallelKey(key: KeyScale): KeyScale;
184
274
  *
185
275
  * @param chord The chord to analyze.
186
276
  * @param key The prevailing key.
277
+ * @param opts Options used when rendering the Roman numeral.
187
278
  * @returns The chord analysis.
188
279
  * @example
189
280
  * ```ts
@@ -193,16 +284,16 @@ declare function parallelKey(key: KeyScale): KeyScale;
193
284
  * ```
194
285
  * @category Functional Harmony
195
286
  */
196
- declare function analyzeChord(chord: Chord, key: KeyScale): ChordAnalysis;
287
+ declare function analyzeChord(chord: Chord, key: KeyScale, opts?: ChordToRomanOptions): ChordAnalysis;
197
288
  /**
198
289
  * The secondary dominant (V7) that tonicizes a scale degree.
199
290
  *
200
- * @param targetDegree 0-based scale degree to tonicize, in 0..6.
291
+ * @param targetDegree 0-based scale degree to tonicize.
201
292
  * @param key The prevailing key.
202
293
  * @returns A dominant-seventh chord a fifth above the target's root.
203
- * @throws If `targetDegree` is not an integer in 0..6.
294
+ * @throws If `targetDegree` is not an integer naming a degree in `key`.
204
295
  * @category Functional Harmony
205
296
  */
206
297
  declare function secondaryDominant(targetDegree: number, key: KeyScale): Chord;
207
298
 
208
- export { type BorrowedSource as B, type Cadence as C, type HarmonicFunction as H, type ChordAnalysis as a, analyzeChord as b, borrowedSource as c, detectCadence as d, isDiatonic as e, functionOf as f, isMinorKey as g, isBorrowedChord as i, parallelKey as p, secondaryDominant as s };
299
+ export { type BorrowedSource as B, type Cadence as C, type HarmonicFunction as H, type ChordAnalysis as a, type ChordToRomanOptions as b, analyzeChord as c, borrowedSource as d, chordToRoman as e, detectCadence as f, functionOf as g, isDiatonic as h, isBorrowedChord as i, isMinorKey as j, parallelKey as p, romanToChord as r, secondaryDominant as s };
@@ -22,19 +22,19 @@
22
22
 
23
23
 
24
24
 
25
- var _chunk4HLLZPXTcjs = require('../chunk-4HLLZPXT.cjs');
26
- require('../chunk-RUMU3UA6.cjs');
27
- require('../chunk-36N73KZ3.cjs');
25
+ var _chunkMPTVJIVGcjs = require('../chunk-MPTVJIVG.cjs');
26
+ require('../chunk-MTMZTMWM.cjs');
27
+ require('../chunk-2A2QMA74.cjs');
28
28
 
29
29
 
30
30
 
31
31
 
32
- var _chunkZEJR4TKLcjs = require('../chunk-ZEJR4TKL.cjs');
33
- require('../chunk-CAN76NCU.cjs');
34
- require('../chunk-FCANXBAT.cjs');
35
- require('../chunk-Q6OP4U43.cjs');
36
- require('../chunk-FNDWXRRI.cjs');
37
- require('../chunk-7MGZ7D62.cjs');
32
+ var _chunk357ZDPVUcjs = require('../chunk-357ZDPVU.cjs');
33
+ require('../chunk-KQN2ZYND.cjs');
34
+ require('../chunk-YFJXS3AU.cjs');
35
+ require('../chunk-WFDXOLUB.cjs');
36
+ require('../chunk-BSLTLGM3.cjs');
37
+ require('../chunk-PI3UXRWK.cjs');
38
38
 
39
39
 
40
40
 
@@ -62,5 +62,5 @@ require('../chunk-7MGZ7D62.cjs');
62
62
 
63
63
 
64
64
 
65
- exports.BASS_STYLES = _chunk4HLLZPXTcjs.BASS_STYLES; exports.BORROWED_DEGREES = _chunk4HLLZPXTcjs.BORROWED_DEGREES; exports.DRUM_NOTES = _chunk4HLLZPXTcjs.DRUM_NOTES; exports.applyGrooveTemplate = _chunk4HLLZPXTcjs.applyGrooveTemplate; exports.developMotif = _chunk4HLLZPXTcjs.developMotif; exports.drumVoiceOf = _chunk4HLLZPXTcjs.drumVoiceOf; exports.extractGrooveTemplate = _chunk4HLLZPXTcjs.extractGrooveTemplate; exports.generateBassLine = _chunk4HLLZPXTcjs.generateBassLine; exports.generateCounterMelody = _chunk4HLLZPXTcjs.generateCounterMelody; exports.generateDrums = _chunk4HLLZPXTcjs.generateDrums; exports.generateMotif = _chunk4HLLZPXTcjs.generateMotif; exports.generateProgression = _chunk4HLLZPXTcjs.generateProgression; exports.generateRhythm = _chunk4HLLZPXTcjs.generateRhythm; exports.harmonizeMelody = _chunk4HLLZPXTcjs.harmonizeMelody; exports.humanize = _chunk4HLLZPXTcjs.humanize; exports.modalInterchangePalette = _chunkZEJR4TKLcjs.modalInterchangePalette; exports.motifToNoteEvents = _chunk4HLLZPXTcjs.motifToNoteEvents; exports.negativeHarmonyMirror = _chunkZEJR4TKLcjs.negativeHarmonyMirror; exports.onsetWeightCurve = _chunk4HLLZPXTcjs.onsetWeightCurve; exports.pickProgressionPreset = _chunk4HLLZPXTcjs.pickProgressionPreset; exports.progressions = _chunk4HLLZPXTcjs.progressions; exports.progressionsByStyle = _chunk4HLLZPXTcjs.progressionsByStyle; exports.rhythmDensity = _chunk4HLLZPXTcjs.rhythmDensity; exports.rhythmToNoteEvents = _chunk4HLLZPXTcjs.rhythmToNoteEvents; exports.substituteChord = _chunkZEJR4TKLcjs.substituteChord; exports.transformMotif = _chunk4HLLZPXTcjs.transformMotif;
65
+ exports.BASS_STYLES = _chunkMPTVJIVGcjs.BASS_STYLES; exports.BORROWED_DEGREES = _chunkMPTVJIVGcjs.BORROWED_DEGREES; exports.DRUM_NOTES = _chunkMPTVJIVGcjs.DRUM_NOTES; exports.applyGrooveTemplate = _chunkMPTVJIVGcjs.applyGrooveTemplate; exports.developMotif = _chunkMPTVJIVGcjs.developMotif; exports.drumVoiceOf = _chunkMPTVJIVGcjs.drumVoiceOf; exports.extractGrooveTemplate = _chunkMPTVJIVGcjs.extractGrooveTemplate; exports.generateBassLine = _chunkMPTVJIVGcjs.generateBassLine; exports.generateCounterMelody = _chunkMPTVJIVGcjs.generateCounterMelody; exports.generateDrums = _chunkMPTVJIVGcjs.generateDrums; exports.generateMotif = _chunkMPTVJIVGcjs.generateMotif; exports.generateProgression = _chunkMPTVJIVGcjs.generateProgression; exports.generateRhythm = _chunkMPTVJIVGcjs.generateRhythm; exports.harmonizeMelody = _chunkMPTVJIVGcjs.harmonizeMelody; exports.humanize = _chunkMPTVJIVGcjs.humanize; exports.modalInterchangePalette = _chunk357ZDPVUcjs.modalInterchangePalette; exports.motifToNoteEvents = _chunkMPTVJIVGcjs.motifToNoteEvents; exports.negativeHarmonyMirror = _chunk357ZDPVUcjs.negativeHarmonyMirror; exports.onsetWeightCurve = _chunkMPTVJIVGcjs.onsetWeightCurve; exports.pickProgressionPreset = _chunkMPTVJIVGcjs.pickProgressionPreset; exports.progressions = _chunkMPTVJIVGcjs.progressions; exports.progressionsByStyle = _chunkMPTVJIVGcjs.progressionsByStyle; exports.rhythmDensity = _chunkMPTVJIVGcjs.rhythmDensity; exports.rhythmToNoteEvents = _chunkMPTVJIVGcjs.rhythmToNoteEvents; exports.substituteChord = _chunk357ZDPVUcjs.substituteChord; exports.transformMotif = _chunkMPTVJIVGcjs.transformMotif;
66
66
  //# sourceMappingURL=index.cjs.map
@@ -1,10 +1,10 @@
1
- import { B as BorrowedSource, H as HarmonicFunction } from '../function-DNugAOrt.cjs';
1
+ import { B as BorrowedSource, H as HarmonicFunction } from '../function-CxixTB02.cjs';
2
2
  import { K as KeyScale, N as NoteEvent } from '../types-BN6_Q9Kl.cjs';
3
- import { b as ChordSegment, C as Chord, a as ChordQuality, c as ChordSpan } from '../index-y_ak9_Hi.cjs';
4
- export { d as ChordToneRole, P as PitchSpelling } from '../index-y_ak9_Hi.cjs';
5
- import { a as ChordTimeline } from '../index-Be74mcon.cjs';
3
+ import { b as ChordSegment, C as Chord, a as ChordQuality, c as ChordSpan } from '../index-oTQbYYIs.cjs';
4
+ export { d as ChordToneRole, P as PitchSpelling } from '../index-oTQbYYIs.cjs';
5
+ import { a as ChordTimeline } from '../index-BkYJ0xMq.cjs';
6
6
  import { T as TimeSignature } from '../index-DXd9JikN.cjs';
7
- import { H as HarmonyRole } from '../index-D6b6na69.cjs';
7
+ import { H as HarmonyRole } from '../index-x2vcsduE.cjs';
8
8
 
9
9
  /**
10
10
  * Deterministic bass-line generation over a chord placement.
@@ -224,7 +224,7 @@ declare function generateCounterMelody(opts: CounterMelodyOptions): NoteEvent[];
224
224
  * ```
225
225
  * @category Composition
226
226
  */
227
- declare const DRUM_NOTES: {
227
+ declare const DRUM_NOTES: Readonly<{
228
228
  readonly kick: 36;
229
229
  readonly snare: 38;
230
230
  readonly sideStick: 37;
@@ -239,7 +239,7 @@ declare const DRUM_NOTES: {
239
239
  readonly midTom: 47;
240
240
  readonly lowTom: 45;
241
241
  readonly shaker: 82;
242
- };
242
+ }>;
243
243
  /**
244
244
  * A percussion voice name, one key of {@link DRUM_NOTES}.
245
245
  *
@@ -336,16 +336,15 @@ type EuclideanKick = {
336
336
  */
337
337
  type DrumsOptions = {
338
338
  /**
339
- * Number of bars to generate. Bars are four quarter-note beats long: the
340
- * patterns are written for 4/4 and there is no meter option, so a `bars`
341
- * count shared with a meter-aware generator such as
342
- * {@link generateRhythm} only lines up when that generator is also in 4/4.
339
+ * Number of bars to generate.
343
340
  */
344
341
  bars: number;
345
342
  bpm: number;
346
343
  style: GrooveStyle;
347
344
  section: Section;
348
345
  density: number;
346
+ /** Time signature; defaults to 4/4. */
347
+ ts?: TimeSignature;
349
348
  /**
350
349
  * Replace the final bar with a fill.
351
350
  *
@@ -367,8 +366,9 @@ type DrumsOptions = {
367
366
  * - `'fxOnly'`: no kick, snare, ghost notes, timekeeping hi-hat, or fills —
368
367
  * only the fx and auxiliary voices.
369
368
  *
370
- * The ordering holds in every style and section: a busier role never emits
371
- * fewer or quieter voices than a sparser one.
369
+ * Roles express orchestration priority and peak dynamics, not a strict hit
370
+ * count: style-specific ride, foot-hi-hat, and auxiliary patterns may make a
371
+ * sparser role emit more individual onsets in a particular bar.
372
372
  *
373
373
  * @defaultValue `'full'`
374
374
  */
@@ -565,6 +565,8 @@ declare function extractGrooveTemplate(events: readonly NoteEvent[], ts: TimeSig
565
565
  * Velocity is set to the slot's recorded average when it recorded one (a
566
566
  * non-`null` velocity, including a genuine 0); otherwise the event's own
567
567
  * velocity is left untouched.
568
+ * Non-positive-duration input artefacts are omitted, so output positions do
569
+ * not retain a one-to-one correspondence with the input array.
568
570
  *
569
571
  * If the template carries a time signature (see {@link GrooveTemplate.ts}) it
570
572
  * must match `ts`, since a differing bar length would misalign the per-bar
@@ -624,7 +626,8 @@ type ProgressionPreset = {
624
626
  };
625
627
  /**
626
628
  * The borrowed (non-diatonic) chord roots a preset can name, as their semitone
627
- * offset above the tonic.
629
+ * code for a borrowed degree. These are stable identifiers, not semitone
630
+ * offsets: their pitch-class offsets are resolved internally.
628
631
  *
629
632
  * Scale degrees 0..6 address the key's own chords; these codes continue the
630
633
  * numbering for the chromatic chords a pop progression borrows, so a preset is
@@ -642,7 +645,7 @@ type ProgressionPreset = {
642
645
  * ```
643
646
  * @category Composition
644
647
  */
645
- declare const BORROWED_DEGREES: {
648
+ declare const BORROWED_DEGREES: Readonly<{
646
649
  /** Flat submediant: bVI. */
647
650
  readonly bVI: 8;
648
651
  /** Flat subtonic: bVII. */
@@ -655,7 +658,7 @@ declare const BORROWED_DEGREES: {
655
658
  readonly bII: 13;
656
659
  /** Sharp subdominant, the diminished #IV. */
657
660
  readonly sharpIV: 14;
658
- };
661
+ }>;
659
662
  /**
660
663
  * A chord root in a preset: a scale degree 0..6, or one of
661
664
  * {@link BORROWED_DEGREES}.
@@ -1100,8 +1103,6 @@ type SubstituteOptions = {
1100
1103
  * original chord and each other:
1101
1104
  *
1102
1105
  * - `tritone`: for a dominant-type chord, the dominant seventh a tritone away.
1103
- * - `secondaryDominant`: for a stable target, the dominant seventh a fifth
1104
- * above its root (tonicizing it).
1105
1106
  * - `relative`: a diatonic triad a third away that shares two common tones.
1106
1107
  * - `borrowed`: a triad from the parallel mode with the same harmonic function.
1107
1108
  * - `chromaticMediant`: a major/minor triad a third away sharing one common
@@ -1242,8 +1243,7 @@ type RhythmOptions = {
1242
1243
  subdivision?: number;
1243
1244
  /**
1244
1245
  * Overall onset density in [0, 1]. Scales the per-slot onset probability, so
1245
- * higher values fill more grid slots. Values outside [0, 1] are clamped into
1246
- * range.
1246
+ * higher values fill more grid slots. Values outside [0, 1] are rejected.
1247
1247
  *
1248
1248
  * @defaultValue 0.5
1249
1249
  */
@@ -1267,7 +1267,7 @@ declare function onsetWeightCurve(weight: number): number;
1267
1267
  * and sampled from the seeded PRNG. Every bar's downbeat is always an onset, so
1268
1268
  * a pattern of any length has a reliable pulse independent of the seed. Each
1269
1269
  * event's duration extends to the next onset, and the last event extends to the
1270
- * end of the span. `density` is clamped to [0, 1].
1270
+ * end of the span. `density` must be in [0, 1].
1271
1271
  *
1272
1272
  * @param ts The time signature.
1273
1273
  * @param opts Generation options.
@@ -1,10 +1,10 @@
1
- import { B as BorrowedSource, H as HarmonicFunction } from '../function-BtiZb9i9.js';
1
+ import { B as BorrowedSource, H as HarmonicFunction } from '../function-DTCt675z.js';
2
2
  import { K as KeyScale, N as NoteEvent } from '../types-BN6_Q9Kl.js';
3
- import { b as ChordSegment, C as Chord, a as ChordQuality, c as ChordSpan } from '../index-C83mZI1P.js';
4
- export { d as ChordToneRole, P as PitchSpelling } from '../index-C83mZI1P.js';
5
- import { a as ChordTimeline } from '../index-C5UBbQ4G.js';
3
+ import { b as ChordSegment, C as Chord, a as ChordQuality, c as ChordSpan } from '../index-COw1Ky9g.js';
4
+ export { d as ChordToneRole, P as PitchSpelling } from '../index-COw1Ky9g.js';
5
+ import { a as ChordTimeline } from '../index-DRtIhlJj.js';
6
6
  import { T as TimeSignature } from '../index-DXd9JikN.js';
7
- import { H as HarmonyRole } from '../index-tSQh-xwY.js';
7
+ import { H as HarmonyRole } from '../index-Cfx8xgH0.js';
8
8
 
9
9
  /**
10
10
  * Deterministic bass-line generation over a chord placement.
@@ -224,7 +224,7 @@ declare function generateCounterMelody(opts: CounterMelodyOptions): NoteEvent[];
224
224
  * ```
225
225
  * @category Composition
226
226
  */
227
- declare const DRUM_NOTES: {
227
+ declare const DRUM_NOTES: Readonly<{
228
228
  readonly kick: 36;
229
229
  readonly snare: 38;
230
230
  readonly sideStick: 37;
@@ -239,7 +239,7 @@ declare const DRUM_NOTES: {
239
239
  readonly midTom: 47;
240
240
  readonly lowTom: 45;
241
241
  readonly shaker: 82;
242
- };
242
+ }>;
243
243
  /**
244
244
  * A percussion voice name, one key of {@link DRUM_NOTES}.
245
245
  *
@@ -336,16 +336,15 @@ type EuclideanKick = {
336
336
  */
337
337
  type DrumsOptions = {
338
338
  /**
339
- * Number of bars to generate. Bars are four quarter-note beats long: the
340
- * patterns are written for 4/4 and there is no meter option, so a `bars`
341
- * count shared with a meter-aware generator such as
342
- * {@link generateRhythm} only lines up when that generator is also in 4/4.
339
+ * Number of bars to generate.
343
340
  */
344
341
  bars: number;
345
342
  bpm: number;
346
343
  style: GrooveStyle;
347
344
  section: Section;
348
345
  density: number;
346
+ /** Time signature; defaults to 4/4. */
347
+ ts?: TimeSignature;
349
348
  /**
350
349
  * Replace the final bar with a fill.
351
350
  *
@@ -367,8 +366,9 @@ type DrumsOptions = {
367
366
  * - `'fxOnly'`: no kick, snare, ghost notes, timekeeping hi-hat, or fills —
368
367
  * only the fx and auxiliary voices.
369
368
  *
370
- * The ordering holds in every style and section: a busier role never emits
371
- * fewer or quieter voices than a sparser one.
369
+ * Roles express orchestration priority and peak dynamics, not a strict hit
370
+ * count: style-specific ride, foot-hi-hat, and auxiliary patterns may make a
371
+ * sparser role emit more individual onsets in a particular bar.
372
372
  *
373
373
  * @defaultValue `'full'`
374
374
  */
@@ -565,6 +565,8 @@ declare function extractGrooveTemplate(events: readonly NoteEvent[], ts: TimeSig
565
565
  * Velocity is set to the slot's recorded average when it recorded one (a
566
566
  * non-`null` velocity, including a genuine 0); otherwise the event's own
567
567
  * velocity is left untouched.
568
+ * Non-positive-duration input artefacts are omitted, so output positions do
569
+ * not retain a one-to-one correspondence with the input array.
568
570
  *
569
571
  * If the template carries a time signature (see {@link GrooveTemplate.ts}) it
570
572
  * must match `ts`, since a differing bar length would misalign the per-bar
@@ -624,7 +626,8 @@ type ProgressionPreset = {
624
626
  };
625
627
  /**
626
628
  * The borrowed (non-diatonic) chord roots a preset can name, as their semitone
627
- * offset above the tonic.
629
+ * code for a borrowed degree. These are stable identifiers, not semitone
630
+ * offsets: their pitch-class offsets are resolved internally.
628
631
  *
629
632
  * Scale degrees 0..6 address the key's own chords; these codes continue the
630
633
  * numbering for the chromatic chords a pop progression borrows, so a preset is
@@ -642,7 +645,7 @@ type ProgressionPreset = {
642
645
  * ```
643
646
  * @category Composition
644
647
  */
645
- declare const BORROWED_DEGREES: {
648
+ declare const BORROWED_DEGREES: Readonly<{
646
649
  /** Flat submediant: bVI. */
647
650
  readonly bVI: 8;
648
651
  /** Flat subtonic: bVII. */
@@ -655,7 +658,7 @@ declare const BORROWED_DEGREES: {
655
658
  readonly bII: 13;
656
659
  /** Sharp subdominant, the diminished #IV. */
657
660
  readonly sharpIV: 14;
658
- };
661
+ }>;
659
662
  /**
660
663
  * A chord root in a preset: a scale degree 0..6, or one of
661
664
  * {@link BORROWED_DEGREES}.
@@ -1100,8 +1103,6 @@ type SubstituteOptions = {
1100
1103
  * original chord and each other:
1101
1104
  *
1102
1105
  * - `tritone`: for a dominant-type chord, the dominant seventh a tritone away.
1103
- * - `secondaryDominant`: for a stable target, the dominant seventh a fifth
1104
- * above its root (tonicizing it).
1105
1106
  * - `relative`: a diatonic triad a third away that shares two common tones.
1106
1107
  * - `borrowed`: a triad from the parallel mode with the same harmonic function.
1107
1108
  * - `chromaticMediant`: a major/minor triad a third away sharing one common
@@ -1242,8 +1243,7 @@ type RhythmOptions = {
1242
1243
  subdivision?: number;
1243
1244
  /**
1244
1245
  * Overall onset density in [0, 1]. Scales the per-slot onset probability, so
1245
- * higher values fill more grid slots. Values outside [0, 1] are clamped into
1246
- * range.
1246
+ * higher values fill more grid slots. Values outside [0, 1] are rejected.
1247
1247
  *
1248
1248
  * @defaultValue 0.5
1249
1249
  */
@@ -1267,7 +1267,7 @@ declare function onsetWeightCurve(weight: number): number;
1267
1267
  * and sampled from the seeded PRNG. Every bar's downbeat is always an onset, so
1268
1268
  * a pattern of any length has a reliable pulse independent of the seed. Each
1269
1269
  * event's duration extends to the next onset, and the last event extends to the
1270
- * end of the span. `density` is clamped to [0, 1].
1270
+ * end of the span. `density` must be in [0, 1].
1271
1271
  *
1272
1272
  * @param ts The time signature.
1273
1273
  * @param opts Generation options.
@@ -22,19 +22,19 @@ import {
22
22
  rhythmDensity,
23
23
  rhythmToNoteEvents,
24
24
  transformMotif
25
- } from "../chunk-7NKDPF74.js";
26
- import "../chunk-HKGYCQ34.js";
27
- import "../chunk-YLEMGEFH.js";
25
+ } from "../chunk-AID75RN3.js";
26
+ import "../chunk-ZGLJM4A4.js";
27
+ import "../chunk-2PTFGVD7.js";
28
28
  import {
29
29
  modalInterchangePalette,
30
30
  negativeHarmonyMirror,
31
31
  substituteChord
32
- } from "../chunk-GQSGS2N4.js";
33
- import "../chunk-KMHOICIY.js";
34
- import "../chunk-NKIBQ6PT.js";
35
- import "../chunk-NYYWMV2C.js";
36
- import "../chunk-D2FAJBYL.js";
37
- import "../chunk-XEBG3G53.js";
32
+ } from "../chunk-7JEP3MFY.js";
33
+ import "../chunk-NNB67XA2.js";
34
+ import "../chunk-HN2OEUN2.js";
35
+ import "../chunk-DZMHIGI4.js";
36
+ import "../chunk-KBTTEX7Q.js";
37
+ import "../chunk-R2VVFAIN.js";
38
38
  export {
39
39
  BASS_STYLES,
40
40
  BORROWED_DEGREES,
@@ -1,5 +1,5 @@
1
1
  import { K as KeyScale } from './types-BN6_Q9Kl.cjs';
2
- import { C as Chord } from './index-y_ak9_Hi.cjs';
2
+ import { C as Chord } from './index-oTQbYYIs.cjs';
3
3
 
4
4
  /**
5
5
  * Severity policy: `strict` counterpoint vs. lenient `pop` voice-leading.
@@ -38,7 +38,8 @@ declare enum ReasonFlag {
38
38
  HiddenParallel = 4096,
39
39
  VoiceCrossing = 8192,
40
40
  Suspension = 16384,
41
- NeedsResolution = 32768
41
+ NeedsResolution = 32768,
42
+ MelodicTritone = 65536
42
43
  }
43
44
  /**
44
45
  * A neighbouring voice's current and previous pitch.
@@ -1,7 +1,7 @@
1
1
  import { T as TimeSignature } from './index-DXd9JikN.cjs';
2
2
  import { K as KeyScale, N as NoteEvent } from './types-BN6_Q9Kl.cjs';
3
- import { C as Chord, b as ChordSegment, c as ChordSpan } from './index-y_ak9_Hi.cjs';
4
- import { C as Cadence } from './function-DNugAOrt.cjs';
3
+ import { C as Chord, b as ChordSegment, c as ChordSpan } from './index-oTQbYYIs.cjs';
4
+ import { C as Cadence } from './function-CxixTB02.cjs';
5
5
 
6
6
  /**
7
7
  * A beat-indexed sequence of chord segments.