@pepperhorn/chordl-core 0.3.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 (104) hide show
  1. package/LICENSE +21 -0
  2. package/dist/audio/midi-export.d.ts +23 -0
  3. package/dist/audio/midi-export.js +155 -0
  4. package/dist/audio/midi-export.js.map +1 -0
  5. package/dist/chord-sheet/codec.d.ts +14 -0
  6. package/dist/chord-sheet/codec.js +119 -0
  7. package/dist/chord-sheet/codec.js.map +1 -0
  8. package/dist/chord-sheet/defaults.d.ts +13 -0
  9. package/dist/chord-sheet/defaults.js +48 -0
  10. package/dist/chord-sheet/defaults.js.map +1 -0
  11. package/dist/chord-sheet/index.d.ts +3 -0
  12. package/dist/chord-sheet/index.js +4 -0
  13. package/dist/chord-sheet/index.js.map +1 -0
  14. package/dist/chord-sheet/schema.d.ts +6 -0
  15. package/dist/chord-sheet/schema.js +17 -0
  16. package/dist/chord-sheet/schema.js.map +1 -0
  17. package/dist/config.d.ts +2 -0
  18. package/dist/config.js +15 -0
  19. package/dist/config.js.map +1 -0
  20. package/dist/engine/auto-fingering.d.ts +36 -0
  21. package/dist/engine/auto-fingering.js +344 -0
  22. package/dist/engine/auto-fingering.js.map +1 -0
  23. package/dist/engine/highlight-mapper.d.ts +3 -0
  24. package/dist/engine/highlight-mapper.js +46 -0
  25. package/dist/engine/highlight-mapper.js.map +1 -0
  26. package/dist/engine/keyboard-layout.d.ts +6 -0
  27. package/dist/engine/keyboard-layout.js +65 -0
  28. package/dist/engine/keyboard-layout.js.map +1 -0
  29. package/dist/engine/note-spelling.d.ts +54 -0
  30. package/dist/engine/note-spelling.js +103 -0
  31. package/dist/engine/note-spelling.js.map +1 -0
  32. package/dist/engine/scale-fingering.d.ts +21 -0
  33. package/dist/engine/scale-fingering.js +130 -0
  34. package/dist/engine/scale-fingering.js.map +1 -0
  35. package/dist/engine/staff-constants.d.ts +16 -0
  36. package/dist/engine/staff-constants.js +20 -0
  37. package/dist/engine/staff-constants.js.map +1 -0
  38. package/dist/engine/staff-glyphs.d.ts +17 -0
  39. package/dist/engine/staff-glyphs.js +59 -0
  40. package/dist/engine/staff-glyphs.js.map +1 -0
  41. package/dist/engine/staff-layout.d.ts +28 -0
  42. package/dist/engine/staff-layout.js +238 -0
  43. package/dist/engine/staff-layout.js.map +1 -0
  44. package/dist/engine/svg-constants.d.ts +19 -0
  45. package/dist/engine/svg-constants.js +40 -0
  46. package/dist/engine/svg-constants.js.map +1 -0
  47. package/dist/index.d.ts +42 -0
  48. package/dist/index.js +37 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/logging.d.ts +70 -0
  51. package/dist/logging.js +24 -0
  52. package/dist/logging.js.map +1 -0
  53. package/dist/parser/natural-language.d.ts +9 -0
  54. package/dist/parser/natural-language.js +406 -0
  55. package/dist/parser/natural-language.js.map +1 -0
  56. package/dist/parser/progression-parser.d.ts +16 -0
  57. package/dist/parser/progression-parser.js +97 -0
  58. package/dist/parser/progression-parser.js.map +1 -0
  59. package/dist/pipeline.d.ts +33 -0
  60. package/dist/pipeline.js +203 -0
  61. package/dist/pipeline.js.map +1 -0
  62. package/dist/progression/form-templates.d.ts +11 -0
  63. package/dist/progression/form-templates.js +105 -0
  64. package/dist/progression/form-templates.js.map +1 -0
  65. package/dist/progression/index.d.ts +5 -0
  66. package/dist/progression/index.js +4 -0
  67. package/dist/progression/index.js.map +1 -0
  68. package/dist/progression/progression-resolver.d.ts +29 -0
  69. package/dist/progression/progression-resolver.js +135 -0
  70. package/dist/progression/progression-resolver.js.map +1 -0
  71. package/dist/progression/roman-numeral.d.ts +14 -0
  72. package/dist/progression/roman-numeral.js +78 -0
  73. package/dist/progression/roman-numeral.js.map +1 -0
  74. package/dist/resolver/auto-layout.d.ts +20 -0
  75. package/dist/resolver/auto-layout.js +195 -0
  76. package/dist/resolver/auto-layout.js.map +1 -0
  77. package/dist/resolver/chord-resolver.d.ts +8 -0
  78. package/dist/resolver/chord-resolver.js +172 -0
  79. package/dist/resolver/chord-resolver.js.map +1 -0
  80. package/dist/resolver/scale-resolver.d.ts +9 -0
  81. package/dist/resolver/scale-resolver.js +45 -0
  82. package/dist/resolver/scale-resolver.js.map +1 -0
  83. package/dist/themes/boomwhacker.d.ts +2 -0
  84. package/dist/themes/boomwhacker.js +35 -0
  85. package/dist/themes/boomwhacker.js.map +1 -0
  86. package/dist/themes/crf.d.ts +19 -0
  87. package/dist/themes/crf.js +34 -0
  88. package/dist/themes/crf.js.map +1 -0
  89. package/dist/themes/index.d.ts +3 -0
  90. package/dist/themes/index.js +25 -0
  91. package/dist/themes/index.js.map +1 -0
  92. package/dist/themes/simple.d.ts +2 -0
  93. package/dist/themes/simple.js +13 -0
  94. package/dist/themes/simple.js.map +1 -0
  95. package/dist/theory/chord-tones.d.ts +56 -0
  96. package/dist/theory/chord-tones.js +215 -0
  97. package/dist/theory/chord-tones.js.map +1 -0
  98. package/dist/theory/degree-labels.d.ts +31 -0
  99. package/dist/theory/degree-labels.js +74 -0
  100. package/dist/theory/degree-labels.js.map +1 -0
  101. package/dist/types.d.ts +123 -0
  102. package/dist/types.js +2 -0
  103. package/dist/types.js.map +1 -0
  104. package/package.json +37 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svg-constants.js","sourceRoot":"","sources":["../../src/engine/svg-constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAC1C,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAC3C,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAC1C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAE9B,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAC1C,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAC3C,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AACzC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC;AAE9B,MAAM,CAAC,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAC5C,MAAM,CAAC,MAAM,kBAAkB,GAAG,SAAS,CAAC;AAC5C,MAAM,CAAC,MAAM,cAAc,GAAG,SAAS,CAAC;AACxC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAEtC,wEAAwE;AACxE,MAAM,CAAC,MAAM,iBAAiB,GAA2B;IACvD,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,KAAK;CACT,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAA2B;IAC7D,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,KAAK;IACR,CAAC,EAAE,KAAK;CACT,CAAC;AAEF,oDAAoD;AACpD,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAE1E,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,EAAE,EAAE,IAAI;IACR,EAAE,EAAE,IAAI;IACR,EAAE,EAAE,IAAI;IACR,EAAE,EAAE,IAAI;IACR,EAAE,EAAE,IAAI;CACT,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAC"}
@@ -0,0 +1,42 @@
1
+ export type { Format, TextSize, NoteNameMode, WhiteNote, NoteName, ColorTheme, ParsedChordRequest, KeyDescriptor, HandBracket, DisplayMode, DisplayDefaults, ChordData, SectionData, ChordSheetData, } from "./types";
2
+ export { computeKeyboard, computeSvgDimensions } from "./engine/keyboard-layout";
3
+ export { mapHighlights, normalizeNote } from "./engine/highlight-mapper";
4
+ export { FLAT_TO_SHARP, SHARP_TO_FLAT, FLAT_KEYS, normalizeToSharps, spellForKey, spellWithPreference, PC_SEMITONES, MIDI_A3, assignAscendingOctaves, } from "./engine/note-spelling";
5
+ export { autoFingering, assignFingering } from "./engine/auto-fingering";
6
+ export { scaleAutoFingering } from "./engine/scale-fingering";
7
+ export type { HandAssignment } from "./engine/auto-fingering";
8
+ export { computeStaffLayout } from "./engine/staff-layout";
9
+ export type { StaffNote, StaffLayoutResult, StaffLayoutOptions } from "./engine/staff-layout";
10
+ export { getDefaultGlyphs, setDefaultGlyphs, BRAVURA_GLYPHS, PETALUMA_GLYPHS } from "./engine/staff-glyphs";
11
+ export type { StaffGlyphSet } from "./engine/staff-glyphs";
12
+ export { STAFF_LINE_SPACING, HALF_STAFF_SPACING, STAFF_WIDTH, CLEF_AREA_WIDTH, NOTE_COLUMN_X, NOTE_HEAD_RX, ACCIDENTAL_OFFSET, LEDGER_LINE_EXTEND, LEDGER_LINE_STROKE, STAFF_GAP, STAFF_TOP_MARGIN, STAFF_BOTTOM_MARGIN, STAFF_LINE_STROKE, BRACE_WIDTH, SECOND_OFFSET, ACCIDENTAL_COL_WIDTH, } from "./engine/staff-constants";
13
+ export { WHITE_KEY_WIDTH, WHITE_KEY_WIDTH_EXACT, WHITE_KEY_HEIGHT_COMPACT, WHITE_KEY_HEIGHT_EXACT, WHITE_KEY_RY, BLACK_KEY_WIDTH, BLACK_KEY_WIDTH_EXACT, BLACK_KEY_HEIGHT_COMPACT, BLACK_KEY_HEIGHT_EXACT, BLACK_KEY_RY, BLACK_KEY_OFFSETS, BLACK_KEY_OFFSETS_EXACT, WHITE_NOTES_WITH_SHARPS, WHITE_NOTE_ORDER, DEFAULT_WHITE_FILL, DEFAULT_BLACK_FILL, DEFAULT_STROKE, DEFAULT_STROKE_WIDTH, } from "./engine/svg-constants";
14
+ export { parseChordDescription } from "./parser/natural-language";
15
+ export { isProgressionRequest, parseProgressionRequest } from "./parser/progression-parser";
16
+ export type { ParsedProgressionRequest } from "./parser/progression-parser";
17
+ export { resolveChord } from "./resolver/chord-resolver";
18
+ export type { ResolvedChord } from "./resolver/chord-resolver";
19
+ export { calculateLayout, whiteIdxHasSharp } from "./resolver/auto-layout";
20
+ export type { LayoutOptions, LayoutResult } from "./resolver/auto-layout";
21
+ export { MAX_EXAMPLES, ENABLE_CHORD_LOGGING } from "./config";
22
+ export { resolveProgression, tokenizeProgression } from "./progression/roman-numeral";
23
+ export { FORM_TEMPLATES, findTemplate } from "./progression/form-templates";
24
+ export type { FormTemplate } from "./progression/form-templates";
25
+ export { resolveProgressionRequest } from "./progression/progression-resolver";
26
+ export type { ProgressionRequest, ProgressionResult, ProgressionExample, ProgressionChord } from "./progression/progression-resolver";
27
+ export { generateMidiFile, downloadMidi } from "./audio/midi-export";
28
+ export { logChordRequest, LOG_SCHEMA_VERSION } from "./logging";
29
+ export type { ChordLogEntry, LogConfig } from "./logging";
30
+ export { classifyTones, parseInterval, minimalVoicing, dropOrder } from "./theory/chord-tones";
31
+ export type { ChordTone, ChordToneRole, ChordToneAnalysis } from "./theory/chord-tones";
32
+ export { intervalToDegreeLabel, degreesForIntervals } from "./theory/degree-labels";
33
+ export { resolveScale } from "./resolver/scale-resolver";
34
+ export type { ResolvedScale } from "./resolver/scale-resolver";
35
+ export { getTheme, resolveTheme } from "./themes";
36
+ export { CRF_PITCH_PALETTE, formatCmyk } from "./themes/crf";
37
+ export type { CrfPitchEntry } from "./themes/crf";
38
+ export { processChordRequest } from "./pipeline";
39
+ export type { ChordRequest, ChordResult } from "./pipeline";
40
+ export { resolveDefaults, chordRef, SYSTEM_DEFAULTS } from "./chord-sheet/defaults";
41
+ export { CHORD_SHEET_SCHEMA_VERSION, validateVersion } from "./chord-sheet/schema";
42
+ export { encodeChordSheet, decodeChordSheet } from "./chord-sheet/codec";
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ export { computeKeyboard, computeSvgDimensions } from "./engine/keyboard-layout";
2
+ export { mapHighlights, normalizeNote } from "./engine/highlight-mapper";
3
+ export { FLAT_TO_SHARP, SHARP_TO_FLAT, FLAT_KEYS, normalizeToSharps, spellForKey, spellWithPreference, PC_SEMITONES, MIDI_A3, assignAscendingOctaves, } from "./engine/note-spelling";
4
+ export { autoFingering, assignFingering } from "./engine/auto-fingering";
5
+ export { scaleAutoFingering } from "./engine/scale-fingering";
6
+ export { computeStaffLayout } from "./engine/staff-layout";
7
+ export { getDefaultGlyphs, setDefaultGlyphs, BRAVURA_GLYPHS, PETALUMA_GLYPHS } from "./engine/staff-glyphs";
8
+ export { STAFF_LINE_SPACING, HALF_STAFF_SPACING, STAFF_WIDTH, CLEF_AREA_WIDTH, NOTE_COLUMN_X, NOTE_HEAD_RX, ACCIDENTAL_OFFSET, LEDGER_LINE_EXTEND, LEDGER_LINE_STROKE, STAFF_GAP, STAFF_TOP_MARGIN, STAFF_BOTTOM_MARGIN, STAFF_LINE_STROKE, BRACE_WIDTH, SECOND_OFFSET, ACCIDENTAL_COL_WIDTH, } from "./engine/staff-constants";
9
+ export { WHITE_KEY_WIDTH, WHITE_KEY_WIDTH_EXACT, WHITE_KEY_HEIGHT_COMPACT, WHITE_KEY_HEIGHT_EXACT, WHITE_KEY_RY, BLACK_KEY_WIDTH, BLACK_KEY_WIDTH_EXACT, BLACK_KEY_HEIGHT_COMPACT, BLACK_KEY_HEIGHT_EXACT, BLACK_KEY_RY, BLACK_KEY_OFFSETS, BLACK_KEY_OFFSETS_EXACT, WHITE_NOTES_WITH_SHARPS, WHITE_NOTE_ORDER, DEFAULT_WHITE_FILL, DEFAULT_BLACK_FILL, DEFAULT_STROKE, DEFAULT_STROKE_WIDTH, } from "./engine/svg-constants";
10
+ export { parseChordDescription } from "./parser/natural-language";
11
+ export { isProgressionRequest, parseProgressionRequest } from "./parser/progression-parser";
12
+ export { resolveChord } from "./resolver/chord-resolver";
13
+ export { calculateLayout, whiteIdxHasSharp } from "./resolver/auto-layout";
14
+ export { MAX_EXAMPLES, ENABLE_CHORD_LOGGING } from "./config";
15
+ // Progression
16
+ export { resolveProgression, tokenizeProgression } from "./progression/roman-numeral";
17
+ export { FORM_TEMPLATES, findTemplate } from "./progression/form-templates";
18
+ export { resolveProgressionRequest } from "./progression/progression-resolver";
19
+ // Audio
20
+ export { generateMidiFile, downloadMidi } from "./audio/midi-export";
21
+ // Logging
22
+ export { logChordRequest, LOG_SCHEMA_VERSION } from "./logging";
23
+ // Theory
24
+ export { classifyTones, parseInterval, minimalVoicing, dropOrder } from "./theory/chord-tones";
25
+ export { intervalToDegreeLabel, degreesForIntervals } from "./theory/degree-labels";
26
+ // Scale resolver
27
+ export { resolveScale } from "./resolver/scale-resolver";
28
+ // Themes
29
+ export { getTheme, resolveTheme } from "./themes";
30
+ export { CRF_PITCH_PALETTE, formatCmyk } from "./themes/crf";
31
+ // Pipeline
32
+ export { processChordRequest } from "./pipeline";
33
+ // ChordSheet
34
+ export { resolveDefaults, chordRef, SYSTEM_DEFAULTS } from "./chord-sheet/defaults";
35
+ export { CHORD_SHEET_SCHEMA_VERSION, validateVersion } from "./chord-sheet/schema";
36
+ export { encodeChordSheet, decodeChordSheet } from "./chord-sheet/codec";
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ export declare const LOG_SCHEMA_VERSION = "1.1.0";
2
+ export interface ChordLogEntry {
3
+ input: string;
4
+ /** Optional: where this chord came from. */
5
+ source?: {
6
+ type: "chord-sheet" | "standalone";
7
+ /** Chord reference ID within a sheet (e.g. "A3", "B1"). */
8
+ sheetRef?: string;
9
+ };
10
+ pipeline: {
11
+ parser: "chord" | "progression";
12
+ parsed: {
13
+ chordName: string;
14
+ inversion?: number;
15
+ allInversions?: boolean;
16
+ startingNote?: string;
17
+ startingDegree?: number;
18
+ bassNote?: string;
19
+ bassDegree?: number;
20
+ spanFrom?: string;
21
+ spanTo?: string;
22
+ padding?: number;
23
+ chordOctaveShift?: number;
24
+ bassOctaveShift?: number;
25
+ styleHint?: string;
26
+ format?: string;
27
+ showNoteNames?: boolean;
28
+ fingering?: (number | string)[];
29
+ autoFingering?: boolean;
30
+ };
31
+ resolver: {
32
+ method: "tonal" | "special-builder" | "fallback";
33
+ type: string;
34
+ root: string;
35
+ pitchClasses: string[];
36
+ };
37
+ voicing: {
38
+ attempted: boolean;
39
+ style?: string;
40
+ quality?: string;
41
+ found: boolean;
42
+ };
43
+ layout: {
44
+ startFrom: string;
45
+ size: number;
46
+ chordOctave: number;
47
+ };
48
+ output: {
49
+ notes: string[];
50
+ lhNotes?: string[];
51
+ rhNotes?: string[];
52
+ highlightKeys: string[];
53
+ format?: string;
54
+ display?: string;
55
+ };
56
+ };
57
+ success: boolean;
58
+ errorMessage?: string;
59
+ durationMs: number;
60
+ }
61
+ export interface LogConfig {
62
+ enabled: boolean;
63
+ endpoint?: string;
64
+ versions?: {
65
+ core?: string;
66
+ voicings?: string;
67
+ react?: string;
68
+ };
69
+ }
70
+ export declare function logChordRequest(entry: ChordLogEntry, config: LogConfig): void;
@@ -0,0 +1,24 @@
1
+ export const LOG_SCHEMA_VERSION = "1.1.0";
2
+ export function logChordRequest(entry, config) {
3
+ if (!config.enabled || !config.endpoint)
4
+ return;
5
+ const payload = {
6
+ logSchema: LOG_SCHEMA_VERSION,
7
+ ...entry,
8
+ versions: config.versions ?? {},
9
+ timestamp: new Date().toISOString(),
10
+ };
11
+ try {
12
+ fetch(config.endpoint, {
13
+ method: "POST",
14
+ headers: { "Content-Type": "application/json" },
15
+ body: JSON.stringify(payload),
16
+ }).catch(() => {
17
+ // silently swallow — logging must never affect functionality
18
+ });
19
+ }
20
+ catch {
21
+ // silently swallow
22
+ }
23
+ }
24
+ //# sourceMappingURL=logging.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAwE1C,MAAM,UAAU,eAAe,CAAC,KAAoB,EAAE,MAAiB;IACrE,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ;QAAE,OAAO;IAEhD,MAAM,OAAO,GAAG;QACd,SAAS,EAAE,kBAAkB;QAC7B,GAAG,KAAK;QACR,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;QAC/B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,IAAI,CAAC;QACH,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE;YACrB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;SAC9B,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;YACZ,6DAA6D;QAC/D,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,mBAAmB;IACrB,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ParsedChordRequest } from "../types";
2
+ /**
3
+ * Extract modifiers first (format, inversion, bass, style, etc.) using
4
+ * dedicated regexes, then strip ALL matched patterns plus filler words
5
+ * from the input. Whatever remains is treated as the chord symbol.
6
+ * This "strip everything known, keep the residual" approach avoids needing
7
+ * a single monolithic chord regex that accounts for all possible contexts.
8
+ */
9
+ export declare function parseChordDescription(input: string): ParsedChordRequest;
@@ -0,0 +1,406 @@
1
+ const FILLER_WORDS = /\b(show\s+me|draw|display|render|please|a|an|the|with|that|this|me|of)\b/gi;
2
+ const FORMAT_RE = /\b(compact|exact|full)\b/i;
3
+ const FORMAT_FULL_RE = /\bfull\s+(?:layout|height|size|keys?)\b/i;
4
+ // "size 80" / "size 80%" / "size 0.8" / "size xl" / "keys xl"
5
+ const SIZE_NUM_RE = /\b(?:size|keys?)\s+([\d.]+)\s*%?\b/i;
6
+ const SIZE_NAME_RE = /\b(?:size|keys?)\s+(sm|base|lg|xl|2xl)\b/i;
7
+ const SIZE_SCALE = {
8
+ sm: 0.5,
9
+ base: 0.7,
10
+ lg: 0.85,
11
+ xl: 1.0,
12
+ "2xl": 1.2,
13
+ };
14
+ const INVERSION_WORD = {
15
+ first: 1,
16
+ second: 2,
17
+ third: 3,
18
+ fourth: 4,
19
+ root: 0,
20
+ };
21
+ const ALL_INVERSIONS_RE = /(?:(?:with\s+|show\s+)?all|every)\s+inversions?/i;
22
+ const INVERSION_NUM_RE = /(\d+)(?:st|nd|rd|th)\s+inversion/i;
23
+ const INVERSION_WORD_RE = /(first|second|third|fourth)\s+inversion/i;
24
+ const ROOT_POSITION_RE = /root\s+position/i;
25
+ const SPAN_RE = /spanning\s+([A-Ga-g][#b]?)\s+to\s+([A-Ga-g][#b]?)/i;
26
+ const STARTING_NOTE_RE = /start(?:s|ing)?\s+(?:on|from|at|around)\s+(?:the\s+)?([A-Ga-g][#b]?)/i;
27
+ // "starting on the 5th" or "starting on the 3rd"
28
+ const STARTING_DEGREE_RE = /start(?:s|ing)?\s+(?:on|from|at|around)\s+(?:the\s+)?(\d+)(?:st|nd|rd|th)/i;
29
+ // "with the 5th in the bottom/bass" or "with G in the bass"
30
+ const BASS_DEGREE_RE = /(?:with\s+)?(?:the\s+)?(\d+)(?:st|nd|rd|th)\s+(?:in\s+)?(?:the\s+)?(?:bottom|bass|lowest)/i;
31
+ const BASS_NOTE_RE = /(?:with\s+)?([A-Ga-g][#b]?)\s+(?:in\s+)?(?:the\s+)?(?:bottom|bass|lowest)/i;
32
+ // "C6/9 over D" or "Cmaj7 over E"
33
+ const OVER_BASS_NOTE_RE = /\bover\s+([A-Ga-g][#b]?)(?:\s|$)/i;
34
+ // "in the style of Bill Evans" / "like McCoy Tyner" / "bebop style"
35
+ const STYLE_RE = /(?:(?:in\s+)?(?:the\s+)?style\s+of\s+|like\s+|a\s+la\s+)([\w\s]+?)(?:\s*$|\s*,|\s+(?:starting|spanning|with|compact|exact))/i;
36
+ const STYLE_KEYWORD_RE = /\b(bebop|basie|nestico|ellington|modal|comping|rootless|quartal|block\s*chords?|locked\s*hands|drop\s*2\s*\+?\s*4|drop\s*2|upper\s*structure|shell|stride|spread|4[- ]?note\s*closed)\b/i;
37
+ // "with 2 notes on either side" / "with 3 keys on each side"
38
+ const PADDING_RE = /(?:with\s+)?(\d+)\s+(?:notes?|keys?)\s+(?:on\s+)?(?:either|each|both)\s+side/i;
39
+ // "chord down an octave" / "chord up 2 octaves" / "with the chord an octave lower"
40
+ const CHORD_OCTAVE_RE = /(?:with\s+)?(?:the\s+)?chord\s+(?:(?:(down|up|lower|higher)\s+)?(?:(\d+)\s+)?(?:an?\s+)?octaves?(?:\s+(down|up|lower|higher))?)/i;
41
+ // "bass note up an octave" / "with the bass up 2 octaves" / "bass down an octave"
42
+ const BASS_OCTAVE_RE = /(?:with\s+)?(?:the\s+)?bass(?:\s+note)?\s+(?:(?:(down|up|lower|higher)\s+)?(?:(\d+)\s+)?(?:an?\s+)?octaves?(?:\s+(down|up|lower|higher))?)/i;
43
+ // "with note names" / "note names in xl" / "name the notes" / "xl note names"
44
+ const NOTE_NAMES_RE = /(?:(?:with\s+)?(?:show\s+)?(?:(base|lg|xl|2xl)\s+)?note\s*names?(?:\s+(?:in\s+)?(base|lg|xl|2xl))?|name\s+the\s+notes(?:\s+(?:in\s+)?(base|lg|xl|2xl))?)/i;
45
+ // "midi note names" / "with midi names" / "show midi note names in xl"
46
+ const MIDI_NAMES_RE = /(?:(?:with\s+)?(?:show\s+)?midi\s+(?:(base|lg|xl|2xl)\s+)?(?:note\s*)?names?(?:\s+(?:in\s+)?(base|lg|xl|2xl))?)/i;
47
+ // "fingering 1 2 3 5" / "with fingering 1-3-5 in lg" / "fingering 1 x 3 5"
48
+ // Negative lookahead prevents matching "2xl" as a finger number
49
+ const FINGERING_RE = /(?:with\s+)?finger(?:ing|s)?\s+([\dxX\-](?:[,\s\-]*[\dxX\-])+)(?!\s*xl)(?:\s+(?:in\s+)?(base|lg|xl|2xl))?/i;
50
+ /** Valid fingering values: digits 0–5 plus extra symbols. Anything else → "?" */
51
+ const VALID_FINGERING = new Set(["0", "1", "2", "3", "4", "5", "-", "x"]);
52
+ // "custom fingering "A0,A1,A2"" / "fingering "G3-G0-E1"" / "fingering xl "1-2-3"" / "fingering "1-2-3" 2xl"
53
+ // Quoted strings after "fingering" or "custom fingering" are treated as free-form labels.
54
+ const CUSTOM_FINGERING_RE = /(?:with\s+)?(?:custom\s+)?finger(?:ing|s)?\s+(?:(?:in\s+)?(base|lg|xl|2xl)\s+)?[""]([^""]+)[""](?:\s+(?:in\s+)?(base|lg|xl|2xl))?/i;
55
+ // "with fingerings" / "show fingering" / "with fingering in xl" / "fingering 2xl" (no explicit numbers → auto)
56
+ // Negative lookahead: don't match when followed by digits (explicit fingering like "1 2 3 5")
57
+ const AUTO_FINGERING_RE = /(?:with\s+)?(?:show\s+)?finger(?:ings?|s)?(?:\s+(?:in\s+)?(base|lg|xl|2xl)|\s+(base|lg|xl|2xl))?(?!\s+\d)(?:\s|$)/i;
58
+ const VALID_TEXT_SIZES = new Set(["base", "lg", "xl", "2xl"]);
59
+ function toTextSize(s) {
60
+ if (!s)
61
+ return undefined;
62
+ const lower = s.toLowerCase();
63
+ return VALID_TEXT_SIZES.has(lower) ? lower : undefined;
64
+ }
65
+ // Scale types that are unambiguous (never collide with chord names)
66
+ const UNAMBIGUOUS_SCALE_TYPES = [
67
+ "dorian", "mixolydian", "phrygian", "lydian", "locrian",
68
+ "harmonic\\s+minor", "minor\\s+harmonic", "melodic\\s+minor", "minor\\s+melodic", "natural\\s+minor",
69
+ "major\\s+pentatonic", "minor\\s+pentatonic", "pentatonic",
70
+ "blues", "whole\\s+tone", "bebop", "diminished",
71
+ ];
72
+ // Scale patterns: "D major scale", "C blues", "A dorian", etc.
73
+ // For "major"/"minor" alone, require the trailing word "scale" to avoid chord collision.
74
+ const SCALE_UNAMBIGUOUS_RE = new RegExp(`([A-Ga-g][#b]?)\\s+(${UNAMBIGUOUS_SCALE_TYPES.join("|")})(?:\\s+scale)?`, "i");
75
+ const SCALE_EXPLICIT_RE = /([A-Ga-g][#b]?)\s+(major|minor)\s+scale/i;
76
+ // "ascending" / "descending" for melodic minor
77
+ const DIRECTION_RE = /\b(ascending|descending)\b/i;
78
+ // "in N octaves" / "N octaves" — works for both scales and arpeggios
79
+ const OCTAVES_RE = /\b(?:in\s+)?(\d+)\s+octaves?\b/i;
80
+ // "with degrees" / "with degrees in xl" / "with note names and degrees in lg"
81
+ const DEGREE_DISPLAY_RE = /\bwith\s+(?:note\s+names?\s+and\s+)?degrees?(?:\s+(?:in\s+)?(base|lg|xl|2xl))?\b/i;
82
+ const DEGREE_ONLY_RE = /\bwith\s+degrees?(?:\s+(?:in\s+)?(base|lg|xl|2xl))?\b/i;
83
+ const NAMES_AND_DEGREES_RE = /\bwith\s+note\s+names?\s+and\s+degrees?(?:\s+(?:in\s+)?(base|lg|xl|2xl))?\b/i;
84
+ // "with heading" / "with a heading" / "show heading"
85
+ const HEADING_RE = /\b(?:with\s+)?(?:a\s+)?(?:show\s+)?heading\b/i;
86
+ // "boomwhacker" / "with boomwhacker theme" / "crf theme" / "rainbow"
87
+ const THEME_RE = /\b(?:(?:with\s+)?(?:the\s+)?)?(?:(boomwhacker|boomwhackers|crf|rainbow)\s*(?:theme|colors?|colours?)?)\b/i;
88
+ const THEME_MAP = {
89
+ boomwhacker: "boomwhacker",
90
+ boomwhackers: "boomwhacker",
91
+ crf: "crf",
92
+ rainbow: "crf",
93
+ };
94
+ // Quality word mapping for descriptive chord names
95
+ const QUALITY_WORDS = {
96
+ major: "",
97
+ minor: "m",
98
+ diminished: "dim",
99
+ augmented: "aug",
100
+ dominant: "dom",
101
+ suspended: "sus",
102
+ triad: "",
103
+ seventh: "7",
104
+ ninth: "9",
105
+ eleventh: "11",
106
+ thirteenth: "13",
107
+ };
108
+ const CHORD_RE = /([A-Ga-g][#b]?)\s*(maj|min|m|aug|dim|sus|add|dom|M|°|ø|[0-9#b/]+)*/i;
109
+ function capitalizeNote(note) {
110
+ return note.charAt(0).toUpperCase() + note.slice(1);
111
+ }
112
+ /**
113
+ * Extract modifiers first (format, inversion, bass, style, etc.) using
114
+ * dedicated regexes, then strip ALL matched patterns plus filler words
115
+ * from the input. Whatever remains is treated as the chord symbol.
116
+ * This "strip everything known, keep the residual" approach avoids needing
117
+ * a single monolithic chord regex that accounts for all possible contexts.
118
+ */
119
+ export function parseChordDescription(input) {
120
+ const result = { chordName: "" };
121
+ // Extract format ("compact", "exact", "full", "full layout", "full height")
122
+ const formatFullMatch = input.match(FORMAT_FULL_RE);
123
+ const formatMatch = input.match(FORMAT_RE);
124
+ if (formatFullMatch) {
125
+ result.format = "exact";
126
+ }
127
+ else if (formatMatch) {
128
+ const f = formatMatch[1].toLowerCase();
129
+ result.format = (f === "full" ? "exact" : f);
130
+ }
131
+ // Extract display scale ("size 80", "size 80%", "size 0.8", "size xl", "keys lg")
132
+ const sizeNameMatch = input.match(SIZE_NAME_RE);
133
+ const sizeNumMatch = input.match(SIZE_NUM_RE);
134
+ if (sizeNameMatch) {
135
+ result.scale = SIZE_SCALE[sizeNameMatch[1].toLowerCase()];
136
+ }
137
+ else if (sizeNumMatch) {
138
+ const v = parseFloat(sizeNumMatch[1]);
139
+ result.scale = v > 10 ? v / 100 : v; // "80" → 0.8, "0.8" → 0.8
140
+ }
141
+ // Extract inversion
142
+ const allInvMatch = input.match(ALL_INVERSIONS_RE);
143
+ const numInvMatch = input.match(INVERSION_NUM_RE);
144
+ const wordInvMatch = input.match(INVERSION_WORD_RE);
145
+ const rootMatch = input.match(ROOT_POSITION_RE);
146
+ if (allInvMatch) {
147
+ result.allInversions = true;
148
+ }
149
+ else if (numInvMatch) {
150
+ result.inversion = parseInt(numInvMatch[1], 10);
151
+ }
152
+ else if (wordInvMatch) {
153
+ result.inversion = INVERSION_WORD[wordInvMatch[1].toLowerCase()];
154
+ }
155
+ else if (rootMatch) {
156
+ result.inversion = 0;
157
+ }
158
+ // Extract span
159
+ const spanMatch = input.match(SPAN_RE);
160
+ if (spanMatch) {
161
+ result.spanFrom = capitalizeNote(spanMatch[1]);
162
+ result.spanTo = capitalizeNote(spanMatch[2]);
163
+ }
164
+ // Extract padding ("with 2 notes on either side")
165
+ const paddingMatch = input.match(PADDING_RE);
166
+ if (paddingMatch) {
167
+ result.padding = parseInt(paddingMatch[1], 10);
168
+ }
169
+ // Extract chord octave shift ("chord down an octave" / "chord up 2 octaves")
170
+ const chordOctaveMatch = input.match(CHORD_OCTAVE_RE);
171
+ if (chordOctaveMatch) {
172
+ const direction = (chordOctaveMatch[1] || chordOctaveMatch[3] || "").toLowerCase();
173
+ const count = chordOctaveMatch[2] ? parseInt(chordOctaveMatch[2], 10) : 1;
174
+ const isDown = direction === "down" || direction === "lower";
175
+ result.chordOctaveShift = isDown ? -count : count;
176
+ }
177
+ // Extract bass octave shift ("bass note up an octave" / "bass down 2 octaves")
178
+ const bassOctaveMatch = input.match(BASS_OCTAVE_RE);
179
+ if (bassOctaveMatch) {
180
+ const direction = (bassOctaveMatch[1] || bassOctaveMatch[3] || "").toLowerCase();
181
+ const count = bassOctaveMatch[2] ? parseInt(bassOctaveMatch[2], 10) : 1;
182
+ const isDown = direction === "down" || direction === "lower";
183
+ result.bassOctaveShift = isDown ? -count : count;
184
+ }
185
+ // Extract "midi note names" / "with midi names" (check before regular note names)
186
+ const midiNamesMatch = input.match(MIDI_NAMES_RE);
187
+ if (midiNamesMatch) {
188
+ result.showNoteNames = true;
189
+ result.noteNameMode = "midi";
190
+ result.noteNameSize = toTextSize(midiNamesMatch[1]) ?? toTextSize(midiNamesMatch[2]);
191
+ }
192
+ // Extract "with note names" / "note names in xl" / "xl note names"
193
+ if (!midiNamesMatch) {
194
+ const noteNamesMatch = input.match(NOTE_NAMES_RE);
195
+ if (noteNamesMatch) {
196
+ result.showNoteNames = true;
197
+ // Size can be in group 1 (before "note names"), 2 (after), or 3 ("name the notes in xl")
198
+ result.noteNameSize = toTextSize(noteNamesMatch[1]) ?? toTextSize(noteNamesMatch[2]) ?? toTextSize(noteNamesMatch[3]);
199
+ }
200
+ }
201
+ // Fallback: bare "midi" in the input implies MIDI note names
202
+ if (!result.showNoteNames && /\bmidi\b/i.test(input)) {
203
+ result.showNoteNames = true;
204
+ result.noteNameMode = "midi";
205
+ }
206
+ // Check custom fingering FIRST ("custom fingering A0,A1,A2")
207
+ const customFingerMatch = input.match(CUSTOM_FINGERING_RE);
208
+ if (customFingerMatch) {
209
+ result.customFingering = customFingerMatch[2].split(/[,\-\s]+/).filter(Boolean);
210
+ result.fingeringSize = toTextSize(customFingerMatch[1]) ?? toTextSize(customFingerMatch[3]);
211
+ }
212
+ // Check auto fingering ("with fingering", "fingering 2xl", "fingering in xl")
213
+ // so that size keywords like "2xl" aren't grabbed as explicit finger numbers.
214
+ if (!result.customFingering) {
215
+ const autoFingerMatch = input.match(AUTO_FINGERING_RE);
216
+ if (autoFingerMatch) {
217
+ result.autoFingering = true;
218
+ result.fingeringSize = toTextSize(autoFingerMatch[1]) ?? toTextSize(autoFingerMatch[2]);
219
+ }
220
+ // Then check for explicit fingering numbers ("fingering 1 2 3 5 in lg")
221
+ // only if auto-fingering didn't match
222
+ if (!result.autoFingering) {
223
+ const fingeringMatch = input.match(FINGERING_RE);
224
+ if (fingeringMatch) {
225
+ const tokens = [];
226
+ for (const part of fingeringMatch[1].split(/[\s,]+/)) {
227
+ if (part === "-" || part === "x" || part === "X") {
228
+ tokens.push(part);
229
+ }
230
+ else if (part.includes("-")) {
231
+ tokens.push(...part.split("-").filter((s) => s.length > 0));
232
+ }
233
+ else {
234
+ tokens.push(part);
235
+ }
236
+ }
237
+ result.fingering = tokens.map((s) => {
238
+ const lower = s.toLowerCase();
239
+ if (!VALID_FINGERING.has(lower))
240
+ return "?";
241
+ const num = parseInt(lower, 10);
242
+ return isNaN(num) ? lower : num;
243
+ });
244
+ result.fingeringSize = toTextSize(fingeringMatch[2]);
245
+ }
246
+ }
247
+ } // end if (!result.customFingering)
248
+ // Extract bass note or degree ("with the 5th in the bottom" / "over D")
249
+ const bassDegreeMatch = input.match(BASS_DEGREE_RE);
250
+ const bassNoteMatch = input.match(BASS_NOTE_RE);
251
+ const overBassMatch = input.match(OVER_BASS_NOTE_RE);
252
+ if (bassDegreeMatch) {
253
+ result.bassDegree = parseInt(bassDegreeMatch[1], 10);
254
+ }
255
+ else if (bassNoteMatch) {
256
+ result.bassNote = capitalizeNote(bassNoteMatch[1]);
257
+ }
258
+ else if (overBassMatch) {
259
+ result.bassNote = capitalizeNote(overBassMatch[1]);
260
+ }
261
+ // Extract style hint
262
+ const styleMatch = input.match(STYLE_RE);
263
+ const styleKeywordMatch = input.match(STYLE_KEYWORD_RE);
264
+ if (styleMatch) {
265
+ result.styleHint = styleMatch[1].trim();
266
+ }
267
+ else if (styleKeywordMatch) {
268
+ result.styleHint = styleKeywordMatch[1].trim();
269
+ }
270
+ // Extract heading flag
271
+ if (HEADING_RE.test(input)) {
272
+ result.showHeading = true;
273
+ }
274
+ // Extract color theme
275
+ const themeMatch = input.match(THEME_RE);
276
+ if (themeMatch) {
277
+ result.colorTheme = THEME_MAP[themeMatch[1].toLowerCase()] ?? themeMatch[1].toLowerCase();
278
+ }
279
+ // Extract degree display mode (before scale detection, since it applies to both)
280
+ const namesDegMatch = input.match(NAMES_AND_DEGREES_RE);
281
+ const degOnlyMatch = input.match(DEGREE_ONLY_RE);
282
+ if (namesDegMatch) {
283
+ result.showNoteNames = true;
284
+ result.noteNameMode = "pitch-class+degree";
285
+ const sz = toTextSize(namesDegMatch[1]);
286
+ if (sz)
287
+ result.noteNameSize = sz;
288
+ }
289
+ else if (degOnlyMatch) {
290
+ result.showNoteNames = true;
291
+ result.noteNameMode = "degree";
292
+ const sz = toTextSize(degOnlyMatch[1]);
293
+ if (sz)
294
+ result.noteNameSize = sz;
295
+ }
296
+ // Extract scale direction
297
+ const dirMatch = input.match(DIRECTION_RE);
298
+ if (dirMatch) {
299
+ result.scaleDirection = dirMatch[1].toLowerCase();
300
+ }
301
+ // Extract octave count (used by both scales and arpeggios)
302
+ const octavesMatch = input.match(OCTAVES_RE);
303
+ const octaveCount = octavesMatch ? parseInt(octavesMatch[1], 10) : undefined;
304
+ // Detect scales — check BEFORE chord extraction
305
+ const scaleUnambig = input.match(SCALE_UNAMBIGUOUS_RE);
306
+ const scaleExplicit = input.match(SCALE_EXPLICIT_RE);
307
+ const scaleMatch = scaleUnambig || scaleExplicit;
308
+ if (scaleMatch) {
309
+ const scaleRoot = capitalizeNote(scaleMatch[1]);
310
+ const scaleType = scaleMatch[2].toLowerCase().replace(/\s+/g, " ").trim();
311
+ result.isScale = true;
312
+ result.scaleName = `${scaleRoot} ${scaleType}`;
313
+ result.scaleOctaves = octaveCount ?? 1;
314
+ }
315
+ else if (octaveCount) {
316
+ // Not a scale but has "N octaves" → arpeggio mode for chord
317
+ result.chordOctaves = octaveCount;
318
+ }
319
+ // Extract starting note or degree
320
+ const startDegreeMatch = input.match(STARTING_DEGREE_RE);
321
+ const startMatch = input.match(STARTING_NOTE_RE);
322
+ if (startDegreeMatch) {
323
+ result.startingDegree = parseInt(startDegreeMatch[1], 10);
324
+ }
325
+ else if (startMatch) {
326
+ result.startingNote = capitalizeNote(startMatch[1]);
327
+ }
328
+ // Strip extracted patterns and filler for chord name extraction
329
+ let cleaned = input
330
+ .replace(FORMAT_FULL_RE, "")
331
+ .replace(FORMAT_RE, "")
332
+ .replace(SIZE_NAME_RE, "")
333
+ .replace(SIZE_NUM_RE, "")
334
+ .replace(ALL_INVERSIONS_RE, "")
335
+ .replace(INVERSION_NUM_RE, "")
336
+ .replace(INVERSION_WORD_RE, "")
337
+ .replace(ROOT_POSITION_RE, "")
338
+ .replace(SPAN_RE, "")
339
+ .replace(PADDING_RE, "")
340
+ .replace(CHORD_OCTAVE_RE, "")
341
+ .replace(BASS_OCTAVE_RE, "")
342
+ .replace(NOTE_NAMES_RE, "")
343
+ .replace(CUSTOM_FINGERING_RE, "")
344
+ .replace(FINGERING_RE, "")
345
+ .replace(AUTO_FINGERING_RE, "")
346
+ .replace(STYLE_RE, "")
347
+ .replace(STYLE_KEYWORD_RE, "")
348
+ .replace(BASS_DEGREE_RE, "")
349
+ .replace(BASS_NOTE_RE, "")
350
+ .replace(OVER_BASS_NOTE_RE, "")
351
+ .replace(STARTING_DEGREE_RE, "")
352
+ .replace(STARTING_NOTE_RE, "")
353
+ .replace(NAMES_AND_DEGREES_RE, "")
354
+ .replace(DEGREE_DISPLAY_RE, "")
355
+ .replace(DIRECTION_RE, "")
356
+ .replace(OCTAVES_RE, "")
357
+ .replace(SCALE_UNAMBIGUOUS_RE, "")
358
+ .replace(SCALE_EXPLICIT_RE, "")
359
+ .replace(/\bscale\b/gi, "")
360
+ .replace(HEADING_RE, "")
361
+ .replace(THEME_RE, "")
362
+ .replace(/\btheme\b/gi, "")
363
+ .replace(/\bcolou?rs?\b/gi, "")
364
+ .replace(/\bcustom\b/gi, "")
365
+ .replace(/\band\b/gi, "")
366
+ .replace(FILLER_WORDS, "")
367
+ .replace(/,/g, "")
368
+ .replace(/\blayout\b/gi, "")
369
+ .replace(/\bfull\b/gi, "")
370
+ .replace(/\bheight\b/gi, "")
371
+ .replace(/\bsize\b/gi, "")
372
+ .replace(/\bkeys?\b/gi, "")
373
+ .replace(/\bin\b/gi, "")
374
+ .replace(/\s+/g, " ")
375
+ .trim();
376
+ // Replace word-based accidentals before chord extraction
377
+ cleaned = cleaned
378
+ .replace(/\bsharp\b/gi, "#")
379
+ .replace(/\bflat\b/gi, "b");
380
+ // Collapse spaces around accidentals: "G #" → "G#"
381
+ cleaned = cleaned.replace(/([A-Ga-g])\s+([#b])/g, "$1$2");
382
+ cleaned = cleaned.replace(/\s+/g, " ").trim();
383
+ // Try to extract chord from descriptive words: "C minor seventh" → "Cm7"
384
+ const descriptiveRe = /([A-Ga-g][#b]?)\s+((?:major|minor|diminished|augmented|dominant|suspended)\s*(?:triad|seventh|ninth|eleventh|thirteenth)?)/i;
385
+ const descMatch = cleaned.match(descriptiveRe);
386
+ if (descMatch) {
387
+ const root = capitalizeNote(descMatch[1]);
388
+ const words = descMatch[2].toLowerCase().trim().split(/\s+/);
389
+ let suffix = "";
390
+ for (const word of words) {
391
+ suffix += QUALITY_WORDS[word] ?? "";
392
+ }
393
+ result.chordName = root + suffix;
394
+ }
395
+ else {
396
+ const chordMatch = cleaned.match(CHORD_RE);
397
+ if (chordMatch) {
398
+ const root = capitalizeNote(chordMatch[1]);
399
+ const fullMatch = chordMatch[0];
400
+ const afterRoot = fullMatch.slice(chordMatch[1].length);
401
+ result.chordName = root + afterRoot.trim();
402
+ }
403
+ }
404
+ return result;
405
+ }
406
+ //# sourceMappingURL=natural-language.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"natural-language.js","sourceRoot":"","sources":["../../src/parser/natural-language.ts"],"names":[],"mappings":"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"}