@libraz/libcantus 1.1.0 → 1.2.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 (93) hide show
  1. package/dist/analyze/index.cjs +7 -7
  2. package/dist/analyze/index.d.cts +8 -8
  3. package/dist/analyze/index.d.ts +8 -8
  4. package/dist/analyze/index.js +6 -6
  5. package/dist/{chunk-TT6PKMPR.cjs → chunk-35NBV2FT.cjs} +16 -16
  6. package/dist/{chunk-TT6PKMPR.cjs.map → chunk-35NBV2FT.cjs.map} +1 -1
  7. package/dist/{chunk-YPB3A3EY.cjs → chunk-3R3QVKY5.cjs} +314 -285
  8. package/dist/chunk-3R3QVKY5.cjs.map +1 -0
  9. package/dist/{chunk-RVS4G4MR.cjs → chunk-76ZBTRG2.cjs} +198 -198
  10. package/dist/{chunk-RVS4G4MR.cjs.map → chunk-76ZBTRG2.cjs.map} +1 -1
  11. package/dist/{chunk-X6RJAHII.js → chunk-7KG3RTYS.js} +2 -2
  12. package/dist/{chunk-PQL7E5F6.js → chunk-AGOVW7U6.js} +1 -1
  13. package/dist/{chunk-PQL7E5F6.js.map → chunk-AGOVW7U6.js.map} +1 -1
  14. package/dist/{chunk-J772DL3B.cjs → chunk-CGBADIO5.cjs} +53 -53
  15. package/dist/{chunk-J772DL3B.cjs.map → chunk-CGBADIO5.cjs.map} +1 -1
  16. package/dist/{chunk-GDKE6RQW.cjs → chunk-DSMJRXCZ.cjs} +402 -401
  17. package/dist/chunk-DSMJRXCZ.cjs.map +1 -0
  18. package/dist/{chunk-DKICR7AN.js → chunk-FBH75DAY.js} +13 -12
  19. package/dist/{chunk-DKICR7AN.js.map → chunk-FBH75DAY.js.map} +1 -1
  20. package/dist/{chunk-VLE5R7PF.js → chunk-H2KJHBW4.js} +4 -4
  21. package/dist/{chunk-XVMJO3QF.cjs → chunk-HPVSH7SF.cjs} +237 -215
  22. package/dist/chunk-HPVSH7SF.cjs.map +1 -0
  23. package/dist/{chunk-QCXYKSZS.cjs → chunk-HWHGOVO6.cjs} +19 -19
  24. package/dist/{chunk-QCXYKSZS.cjs.map → chunk-HWHGOVO6.cjs.map} +1 -1
  25. package/dist/{chunk-HSY2VQXZ.js → chunk-HYJJ2V2I.js} +32 -10
  26. package/dist/chunk-HYJJ2V2I.js.map +1 -0
  27. package/dist/{chunk-5KW7DNCJ.cjs → chunk-J7FHVZII.cjs} +445 -445
  28. package/dist/{chunk-5KW7DNCJ.cjs.map → chunk-J7FHVZII.cjs.map} +1 -1
  29. package/dist/{chunk-AWEMD747.js → chunk-M5RYMAFI.js} +3 -3
  30. package/dist/{chunk-H66ARFU5.js → chunk-NB25P3EH.js} +3 -3
  31. package/dist/{chunk-57WB2EDF.js → chunk-NFJ4P6ZZ.js} +3 -3
  32. package/dist/{chunk-5JJ6EHEZ.cjs → chunk-NM7UAMC3.cjs} +62 -62
  33. package/dist/{chunk-5JJ6EHEZ.cjs.map → chunk-NM7UAMC3.cjs.map} +1 -1
  34. package/dist/{chunk-R7B5N2JK.cjs → chunk-PM4XJE2Y.cjs} +47 -47
  35. package/dist/{chunk-R7B5N2JK.cjs.map → chunk-PM4XJE2Y.cjs.map} +1 -1
  36. package/dist/{chunk-7GOKQJTQ.js → chunk-PUKJP2Z5.js} +2 -2
  37. package/dist/{chunk-R5VUXQMP.js → chunk-Q6LFSAKV.js} +7 -7
  38. package/dist/{chunk-FPBZFNCD.js → chunk-RFIBF2RR.js} +47 -18
  39. package/dist/{chunk-FPBZFNCD.js.map → chunk-RFIBF2RR.js.map} +1 -1
  40. package/dist/{chunk-XKSO2V5I.cjs → chunk-S5BKZZGM.cjs} +1 -1
  41. package/dist/{chunk-XKSO2V5I.cjs.map → chunk-S5BKZZGM.cjs.map} +1 -1
  42. package/dist/{chunk-Q6R3QAZD.cjs → chunk-SGLEQVJH.cjs} +332 -332
  43. package/dist/{chunk-Q6R3QAZD.cjs.map → chunk-SGLEQVJH.cjs.map} +1 -1
  44. package/dist/{chunk-HOHFYGKW.js → chunk-UMWZ4ZET.js} +2 -2
  45. package/dist/{coerce-wwdELNYS.d.ts → coerce-DP0vYu-x.d.ts} +77 -1
  46. package/dist/{coerce-CJlgULrQ.d.cts → coerce-DRERzdve.d.cts} +77 -1
  47. package/dist/core/index.cjs +5 -5
  48. package/dist/core/index.d.cts +2 -2
  49. package/dist/core/index.d.ts +2 -2
  50. package/dist/core/index.js +4 -4
  51. package/dist/generate/index.cjs +8 -8
  52. package/dist/generate/index.d.cts +8 -8
  53. package/dist/generate/index.d.ts +8 -8
  54. package/dist/generate/index.js +7 -7
  55. package/dist/{index-BaoKVVhE.d.cts → index-B9QLziDe.d.cts} +2 -2
  56. package/dist/{index-B3WCj_Hm.d.cts → index-BBWNZS0f.d.cts} +2 -2
  57. package/dist/{index-CnHQgqNh.d.ts → index-BHIUyjhZ.d.ts} +2 -2
  58. package/dist/{index-DpC-mDlV.d.ts → index-BJgP97N1.d.ts} +4 -4
  59. package/dist/{index-CBCP84rv.d.cts → index-BL5N2Oyz.d.cts} +1 -1
  60. package/dist/{index-D_hzxD8w.d.cts → index-BMweUlm5.d.cts} +3 -0
  61. package/dist/{index-BzLNkmA7.d.cts → index-BNSM-DSk.d.cts} +4 -4
  62. package/dist/{index-BUtIf2go.d.ts → index-BRMbPkHE.d.ts} +25 -5
  63. package/dist/{index-BpWOhkkE.d.ts → index-CJBBiAmU.d.ts} +2 -2
  64. package/dist/{index-Ci3xyows.d.ts → index-CL4b4gUQ.d.ts} +3 -0
  65. package/dist/{index-DTsKaPaC.d.cts → index-DGCNKAUr.d.cts} +25 -5
  66. package/dist/{index-CnIdP4EZ.d.ts → index-Dw2DP7vm.d.ts} +1 -1
  67. package/dist/index.cjs +13 -13
  68. package/dist/index.d.cts +8 -8
  69. package/dist/index.d.ts +8 -8
  70. package/dist/index.js +12 -12
  71. package/dist/{masks-O73Rhj5d.d.ts → masks-Cc7-MzzY.d.ts} +1 -1
  72. package/dist/{masks-C8TWLFIi.d.cts → masks-pADfTOiD.d.cts} +1 -1
  73. package/dist/model/index.cjs +12 -12
  74. package/dist/model/index.d.cts +16 -15
  75. package/dist/model/index.d.ts +16 -15
  76. package/dist/model/index.js +11 -11
  77. package/dist/theory/index.cjs +5 -5
  78. package/dist/theory/index.d.cts +7 -7
  79. package/dist/theory/index.d.ts +7 -7
  80. package/dist/theory/index.js +4 -4
  81. package/package.json +6 -5
  82. package/dist/chunk-GDKE6RQW.cjs.map +0 -1
  83. package/dist/chunk-HSY2VQXZ.js.map +0 -1
  84. package/dist/chunk-XVMJO3QF.cjs.map +0 -1
  85. package/dist/chunk-YPB3A3EY.cjs.map +0 -1
  86. /package/dist/{chunk-X6RJAHII.js.map → chunk-7KG3RTYS.js.map} +0 -0
  87. /package/dist/{chunk-VLE5R7PF.js.map → chunk-H2KJHBW4.js.map} +0 -0
  88. /package/dist/{chunk-AWEMD747.js.map → chunk-M5RYMAFI.js.map} +0 -0
  89. /package/dist/{chunk-H66ARFU5.js.map → chunk-NB25P3EH.js.map} +0 -0
  90. /package/dist/{chunk-57WB2EDF.js.map → chunk-NFJ4P6ZZ.js.map} +0 -0
  91. /package/dist/{chunk-7GOKQJTQ.js.map → chunk-PUKJP2Z5.js.map} +0 -0
  92. /package/dist/{chunk-R5VUXQMP.js.map → chunk-Q6LFSAKV.js.map} +0 -0
  93. /package/dist/{chunk-HOHFYGKW.js.map → chunk-UMWZ4ZET.js.map} +0 -0
@@ -30,7 +30,7 @@
30
30
 
31
31
 
32
32
 
33
- var _chunkQ6R3QAZDcjs = require('./chunk-Q6R3QAZD.cjs');
33
+ var _chunkSGLEQVJHcjs = require('./chunk-SGLEQVJH.cjs');
34
34
 
35
35
 
36
36
 
@@ -41,7 +41,7 @@ var _chunkQ6R3QAZDcjs = require('./chunk-Q6R3QAZD.cjs');
41
41
 
42
42
 
43
43
 
44
- var _chunkYPB3A3EYcjs = require('./chunk-YPB3A3EY.cjs');
44
+ var _chunk3R3QVKY5cjs = require('./chunk-3R3QVKY5.cjs');
45
45
 
46
46
 
47
47
 
@@ -65,12 +65,12 @@ var _chunkYPB3A3EYcjs = require('./chunk-YPB3A3EY.cjs');
65
65
 
66
66
 
67
67
 
68
- var _chunkXKSO2V5Icjs = require('./chunk-XKSO2V5I.cjs');
68
+ var _chunkS5BKZZGMcjs = require('./chunk-S5BKZZGM.cjs');
69
69
 
70
70
  // src/analyze/arrange/internal.ts
71
71
  var MAX_LANE_LEAP = 24;
72
72
  function covers(note, beat) {
73
- return beat >= note.startBeat - _chunkXKSO2V5Icjs.BEAT_EPS && beat < note.endBeat - _chunkXKSO2V5Icjs.BEAT_EPS;
73
+ return beat >= note.startBeat - _chunkS5BKZZGMcjs.BEAT_EPS && beat < note.endBeat - _chunkS5BKZZGMcjs.BEAT_EPS;
74
74
  }
75
75
  function isPercussion(role) {
76
76
  return role === "drums";
@@ -84,31 +84,31 @@ var TRACK_ROLE_TABLE = {
84
84
  };
85
85
  var TRACK_ROLES = Object.keys(TRACK_ROLE_TABLE);
86
86
  function trackRoleOf(role, name) {
87
- return role === void 0 ? "other" : _chunkXKSO2V5Icjs.assertOneOf.call(void 0, role, TRACK_ROLES, name);
87
+ return role === void 0 ? "other" : _chunkS5BKZZGMcjs.assertOneOf.call(void 0, role, TRACK_ROLES, name);
88
88
  }
89
89
  var DEFAULT_PROFILE = "pop";
90
- var SAFETY_PROFILES = Object.keys(_chunkYPB3A3EYcjs.PROFILE_WEIGHTS);
90
+ var SAFETY_PROFILES = Object.keys(_chunk3R3QVKY5cjs.PROFILE_WEIGHTS);
91
91
  function arrangementProfile(profile) {
92
- return _chunkXKSO2V5Icjs.assertOneOf.call(void 0, _nullishCoalesce(profile, () => ( DEFAULT_PROFILE)), SAFETY_PROFILES, "arrangement profile");
92
+ return _chunkS5BKZZGMcjs.assertOneOf.call(void 0, _nullishCoalesce(profile, () => ( DEFAULT_PROFILE)), SAFETY_PROFILES, "arrangement profile");
93
93
  }
94
94
  function assertTrackNotes(tracks, options) {
95
- _chunkXKSO2V5Icjs.assertArray.call(void 0, tracks, "arrangement tracks");
95
+ _chunkS5BKZZGMcjs.assertArray.call(void 0, tracks, "arrangement tracks");
96
96
  let noteCount = 0;
97
97
  for (let index = 0; index < tracks.length; index += 1) {
98
98
  const notes = _optionalChain([tracks, 'access', _2 => _2[index], 'optionalAccess', _3 => _3.notes]);
99
99
  if (!Array.isArray(notes)) {
100
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
100
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
101
101
  `tracks[${index}].notes must be an array; received ${typeof notes}`
102
102
  );
103
103
  }
104
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, notes, `tracks[${index}].notes`, options);
104
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, notes, `tracks[${index}].notes`, options);
105
105
  noteCount += notes.length;
106
106
  }
107
107
  return noteCount;
108
108
  }
109
109
  function assertGivenTimeline(timeline, name) {
110
110
  if (timeline !== void 0) {
111
- _chunkQ6R3QAZDcjs.assertChordTimeline.call(void 0, timeline, name);
111
+ _chunkSGLEQVJHcjs.assertChordTimeline.call(void 0, timeline, name);
112
112
  }
113
113
  }
114
114
  function assertGivenKeys(keys, name) {
@@ -116,25 +116,25 @@ function assertGivenKeys(keys, name) {
116
116
  return;
117
117
  }
118
118
  if (!Array.isArray(keys)) {
119
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
120
- `${name} must be an array of key regions; received ${_chunkXKSO2V5Icjs.describeRejected.call(void 0, keys)}`
119
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
120
+ `${name} must be an array of key regions; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, keys)}`
121
121
  );
122
122
  }
123
123
  for (let index = 0; index < keys.length; index += 1) {
124
124
  const region = keys[index];
125
125
  if (typeof region !== "object" || region === null) {
126
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
127
- `${name}[${index}] must be a key region; received ${_chunkXKSO2V5Icjs.describeRejected.call(void 0, region)}`
126
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
127
+ `${name}[${index}] must be a key region; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, region)}`
128
128
  );
129
129
  }
130
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, region.startBeat, `${name}[${index}].startBeat`);
131
- _chunkXKSO2V5Icjs.assertFiniteNumber.call(void 0, region.endBeat, `${name}[${index}].endBeat`);
130
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, region.startBeat, `${name}[${index}].startBeat`);
131
+ _chunkS5BKZZGMcjs.assertFiniteNumber.call(void 0, region.endBeat, `${name}[${index}].endBeat`);
132
132
  if (region.key === void 0 || region.key === null || typeof region.key !== "string" && typeof region.key !== "object") {
133
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
134
- `${name}[${index}].key must name a key; received ${_chunkXKSO2V5Icjs.describeRejected.call(void 0, region.key)}`
133
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
134
+ `${name}[${index}].key must name a key; received ${_chunkS5BKZZGMcjs.describeRejected.call(void 0, region.key)}`
135
135
  );
136
136
  }
137
- _chunkYPB3A3EYcjs.resolveKey.call(void 0, region.key);
137
+ _chunk3R3QVKY5cjs.resolveKey.call(void 0, region.key);
138
138
  }
139
139
  }
140
140
  function harmonyTrackSet(harmonyTracks, tracks, name = "harmonyTracks") {
@@ -145,16 +145,16 @@ function harmonyTrackSet(harmonyTracks, tracks, name = "harmonyTracks") {
145
145
  for (let index = 0; index < harmonyTracks.length; index += 1) {
146
146
  const value = harmonyTracks[index];
147
147
  if (value === void 0 || !Number.isFinite(value)) {
148
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(`${name}[${index}] must be a track index; received ${value}`);
148
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(`${name}[${index}] must be a track index; received ${value}`);
149
149
  }
150
150
  const track = Math.trunc(value);
151
151
  if (track < 0 || track >= tracks.length) {
152
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
152
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
153
153
  `${name}[${index}] ${track} is outside the arrangement's ${tracks.length} tracks`
154
154
  );
155
155
  }
156
156
  if (isPercussion(_optionalChain([tracks, 'access', _4 => _4[track], 'optionalAccess', _5 => _5.role]))) {
157
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
157
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
158
158
  `${name}[${index}] ${track} names a percussion track, whose pitches state no harmony`
159
159
  );
160
160
  }
@@ -195,7 +195,7 @@ function splitIntoSubVoices(ordered) {
195
195
  continue;
196
196
  }
197
197
  const end = last.startBeat + last.durationBeat;
198
- if (!_chunkQ6R3QAZDcjs.hasEnded.call(void 0, end, note.startBeat)) {
198
+ if (!_chunkSGLEQVJHcjs.hasEnded.call(void 0, end, note.startBeat)) {
199
199
  continue;
200
200
  }
201
201
  const distance = Math.abs(last.pitch - note.pitch);
@@ -216,13 +216,13 @@ function splitIntoSubVoices(ordered) {
216
216
  for (let start = 0; start < ordered.length; ) {
217
217
  const onset = _nullishCoalesce(_optionalChain([ordered, 'access', _13 => _13[start], 'optionalAccess', _14 => _14.startBeat]), () => ( 0));
218
218
  let end = start + 1;
219
- while (end < ordered.length && _chunkQ6R3QAZDcjs.sameInstant.call(void 0, _nullishCoalesce(_optionalChain([ordered, 'access', _15 => _15[end], 'optionalAccess', _16 => _16.startBeat]), () => ( 0)), onset)) {
219
+ while (end < ordered.length && _chunkSGLEQVJHcjs.sameInstant.call(void 0, _nullishCoalesce(_optionalChain([ordered, 'access', _15 => _15[end], 'optionalAccess', _16 => _16.startBeat]), () => ( 0)), onset)) {
220
220
  end += 1;
221
221
  }
222
222
  const block = ordered.slice(start, end);
223
223
  if (block.length > 1) {
224
224
  const freeLanes = lanes.map((lane, index) => ({ index, last: lane[lane.length - 1] })).filter(
225
- (entry) => entry.last !== void 0 && _chunkQ6R3QAZDcjs.hasEnded.call(void 0, entry.last.startBeat + entry.last.durationBeat, onset)
225
+ (entry) => entry.last !== void 0 && _chunkSGLEQVJHcjs.hasEnded.call(void 0, entry.last.startBeat + entry.last.durationBeat, onset)
226
226
  ).sort((a, b) => a.last.pitch - b.last.pitch);
227
227
  const assignment = pairWithFreeLanes(block, freeLanes);
228
228
  const taken = new Set(
@@ -310,7 +310,7 @@ function lastStartingAtOrBefore(sounding, beat) {
310
310
  let high = sounding.length;
311
311
  while (low < high) {
312
312
  const middle = Math.floor((low + high) / 2);
313
- if ((_nullishCoalesce(_optionalChain([sounding, 'access', _22 => _22[middle], 'optionalAccess', _23 => _23.startBeat]), () => ( Number.POSITIVE_INFINITY))) <= beat + _chunkXKSO2V5Icjs.BEAT_EPS) {
313
+ if ((_nullishCoalesce(_optionalChain([sounding, 'access', _22 => _22[middle], 'optionalAccess', _23 => _23.startBeat]), () => ( Number.POSITIVE_INFINITY))) <= beat + _chunkS5BKZZGMcjs.BEAT_EPS) {
314
314
  low = middle + 1;
315
315
  } else {
316
316
  high = middle;
@@ -326,8 +326,10 @@ function prepareTracks(tracks) {
326
326
  const sounding = voice.map((note, i) => {
327
327
  const prev = i > 0 ? voice[i - 1] : void 0;
328
328
  const prevEnd = prev === void 0 ? void 0 : prev.startBeat + prev.durationBeat;
329
- const contiguous = prevEnd !== void 0 && _chunkQ6R3QAZDcjs.adjacent.call(void 0, prevEnd, note.startBeat);
329
+ const contiguous = prevEnd !== void 0 && _chunkSGLEQVJHcjs.adjacent.call(void 0, prevEnd, note.startBeat);
330
330
  return {
331
+ id: note.id,
332
+ originalIndex: note.originalIndex,
331
333
  pitch: note.pitch,
332
334
  prevPitch: contiguous ? _optionalChain([prev, 'optionalAccess', _24 => _24.pitch]) : void 0,
333
335
  startBeat: note.startBeat,
@@ -357,7 +359,7 @@ function withGivenKeys(result, given) {
357
359
  if (given === void 0) {
358
360
  return result;
359
361
  }
360
- return { ...result, keys: given, prevailingKey: _nullishCoalesce(_chunkQ6R3QAZDcjs.prevailingKeyOf.call(void 0, given), () => ( result.prevailingKey)) };
362
+ return { ...result, keys: given, prevailingKey: _nullishCoalesce(_chunkSGLEQVJHcjs.prevailingKeyOf.call(void 0, given), () => ( result.prevailingKey)) };
361
363
  }
362
364
  function callerTimeline(timeline, key, given, pooled, meters, budget) {
363
365
  const chartEnd = timeline.segments.reduce((end, segment) => Math.max(end, segment.endBeat), 0);
@@ -366,15 +368,15 @@ function callerTimeline(timeline, key, given, pooled, meters, budget) {
366
368
  0
367
369
  );
368
370
  const totalBeats = Math.max(chartEnd, soundingEnd);
369
- const { startBeat: musicStart } = _chunkQ6R3QAZDcjs.gridForNotes.call(void 0, pooled, _chunkXKSO2V5Icjs.beatsPerBarAt.call(void 0, 0, meters));
370
- const keys = _nullishCoalesce(given, () => ( _chunkQ6R3QAZDcjs.attachPivots.call(void 0,
371
- key !== void 0 ? [{ startBeat: musicStart, endBeat: totalBeats, key: _chunkYPB3A3EYcjs.resolveKey.call(void 0, key), confidence: 1 }] : _chunkQ6R3QAZDcjs.keyTimelineFromNotes.call(void 0, pooled, { meters, totalBeats, budget }),
371
+ const { startBeat: musicStart } = _chunkSGLEQVJHcjs.gridForNotes.call(void 0, pooled, _chunkS5BKZZGMcjs.beatsPerBarAt.call(void 0, 0, meters));
372
+ const keys = _nullishCoalesce(given, () => ( _chunkSGLEQVJHcjs.attachPivots.call(void 0,
373
+ key !== void 0 ? [{ startBeat: musicStart, endBeat: totalBeats, key: _chunk3R3QVKY5cjs.resolveKey.call(void 0, key), confidence: 1 }] : _chunkSGLEQVJHcjs.keyTimelineFromNotes.call(void 0, pooled, { meters, totalBeats, budget }),
372
374
  timeline.segments
373
375
  )));
374
376
  return {
375
377
  timeline,
376
378
  keys,
377
- prevailingKey: _nullishCoalesce(_chunkQ6R3QAZDcjs.prevailingKeyOf.call(void 0, keys), () => ( _chunkYPB3A3EYcjs.resolveKey.call(void 0, _chunkYPB3A3EYcjs.majorKey.call(void 0, 0)))),
379
+ prevailingKey: _nullishCoalesce(_chunkSGLEQVJHcjs.prevailingKeyOf.call(void 0, keys), () => ( _chunk3R3QVKY5cjs.resolveKey.call(void 0, _chunk3R3QVKY5cjs.majorKey.call(void 0, 0)))),
378
380
  segmentConfidence: timeline.segments.map(() => 0)
379
381
  };
380
382
  }
@@ -391,11 +393,11 @@ function soundingVoicesAt(prepared, beat) {
391
393
  continue;
392
394
  }
393
395
  const snap = { pitch: note.pitch };
394
- const previous = _chunkQ6R3QAZDcjs.sameInstant.call(void 0, note.startBeat, beat) ? note.prevPitch : note.pitch;
396
+ const previous = _chunkSGLEQVJHcjs.sameInstant.call(void 0, note.startBeat, beat) ? note.prevPitch : note.pitch;
395
397
  if (previous !== void 0) {
396
398
  snap.prevPitch = previous;
397
399
  }
398
- out.push({ track: t, voice: v, snapshot: snap });
400
+ out.push({ track: t, voice: v, trackIndex: track.trackIndex, note, snapshot: snap });
399
401
  }
400
402
  }
401
403
  return out;
@@ -403,14 +405,28 @@ function soundingVoicesAt(prepared, beat) {
403
405
  function otherVoicesSounding(prepared, excludeTrack, excludeVoice, beat, cache) {
404
406
  const sounding = _nullishCoalesce(cache.get(beat), () => ( soundingVoicesAt(prepared, beat)));
405
407
  cache.set(beat, sounding);
406
- return sounding.filter(({ track, voice }) => track !== excludeTrack || voice !== excludeVoice).map(({ snapshot }) => snapshot);
408
+ return sounding.filter(({ track, voice }) => track !== excludeTrack || voice !== excludeVoice);
409
+ }
410
+ function conflictPartner(sounding, reasons) {
411
+ const partner = {
412
+ trackIndex: sounding.trackIndex,
413
+ noteId: sounding.note.id,
414
+ reasons
415
+ };
416
+ if (sounding.note.originalIndex !== void 0) {
417
+ partner.originalIndex = sounding.note.originalIndex;
418
+ }
419
+ return partner;
420
+ }
421
+ function snapshotsOf(voices) {
422
+ return voices.map(({ snapshot }) => snapshot);
407
423
  }
408
424
  function analyzePolyphony(notes, chordAtBeat, key) {
409
- const passage = _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, notes, "notes", { allowNonPositiveDuration: true });
410
- _chunkXKSO2V5Icjs.assertFunction.call(void 0, chordAtBeat, "chordAtBeat");
425
+ const passage = _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, notes, "notes", { allowNonPositiveDuration: true });
426
+ _chunkS5BKZZGMcjs.assertFunction.call(void 0, chordAtBeat, "chordAtBeat");
411
427
  const prepared = prepareTracks([{ notes: [...passage] }]);
412
428
  const track = prepared[0];
413
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0,
429
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0,
414
430
  passage.length * (_nullishCoalesce(_optionalChain([track, 'optionalAccess', _29 => _29.voices, 'access', _30 => _30.length]), () => ( 0))),
415
431
  "polyphony note-voice comparisons"
416
432
  );
@@ -421,11 +437,11 @@ function analyzePolyphony(notes, chordAtBeat, key) {
421
437
  if (subVoice === void 0) {
422
438
  continue;
423
439
  }
424
- const analyzed = _chunkQ6R3QAZDcjs.analyzeVoice.call(void 0,
440
+ const analyzed = _chunkSGLEQVJHcjs.analyzeVoice.call(void 0,
425
441
  subVoice.voice,
426
442
  chordAtBeat,
427
443
  key,
428
- (beat) => otherVoicesSounding(prepared, 0, v, beat, soundingCache)
444
+ (beat) => snapshotsOf(otherVoicesSounding(prepared, 0, v, beat, soundingCache))
429
445
  );
430
446
  for (const note of analyzed) {
431
447
  if (note.originalIndex !== void 0) {
@@ -439,7 +455,7 @@ function analyzePolyphony(notes, chordAtBeat, key) {
439
455
  if (analyzed !== void 0) {
440
456
  return analyzed;
441
457
  }
442
- const [only] = _chunkQ6R3QAZDcjs.analyzeVoice.call(void 0, [{ ...note, id: index }], chordAtBeat, key);
458
+ const [only] = _chunkSGLEQVJHcjs.analyzeVoice.call(void 0, [{ ...note, id: index }], chordAtBeat, key);
443
459
  return _nullishCoalesce(only, () => ( {
444
460
  noteId: index,
445
461
  pitch: note.pitch,
@@ -454,7 +470,7 @@ function firstSegmentAfter(timeline, beat) {
454
470
  let high = timeline.segments.length;
455
471
  while (low < high) {
456
472
  const middle = Math.floor((low + high) / 2);
457
- if ((_nullishCoalesce(_optionalChain([timeline, 'access', _35 => _35.segments, 'access', _36 => _36[middle], 'optionalAccess', _37 => _37.startBeat]), () => ( Number.POSITIVE_INFINITY))) <= beat + _chunkXKSO2V5Icjs.BEAT_EPS) {
473
+ if ((_nullishCoalesce(_optionalChain([timeline, 'access', _35 => _35.segments, 'access', _36 => _36[middle], 'optionalAccess', _37 => _37.startBeat]), () => ( Number.POSITIVE_INFINITY))) <= beat + _chunkS5BKZZGMcjs.BEAT_EPS) {
458
474
  low = middle + 1;
459
475
  } else {
460
476
  high = middle;
@@ -467,7 +483,7 @@ function evaluationBeats(note, timeline) {
467
483
  const beats = [note.startBeat];
468
484
  for (let i = firstSegmentAfter(timeline, note.startBeat); i < timeline.segments.length; i += 1) {
469
485
  const start = _optionalChain([timeline, 'access', _38 => _38.segments, 'access', _39 => _39[i], 'optionalAccess', _40 => _40.startBeat]);
470
- if (start === void 0 || start >= noteEnd - _chunkXKSO2V5Icjs.BEAT_EPS) {
486
+ if (start === void 0 || start >= noteEnd - _chunkS5BKZZGMcjs.BEAT_EPS) {
471
487
  break;
472
488
  }
473
489
  beats.push(start);
@@ -478,19 +494,19 @@ function analyzeArrangement(tracks, opts = {}) {
478
494
  return analyzeArrangementWith(tracks, opts).analysis;
479
495
  }
480
496
  function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
481
- const meters = _chunkXKSO2V5Icjs.resolveMeters.call(void 0, opts, "arrangement meters");
497
+ const meters = _chunkS5BKZZGMcjs.resolveMeters.call(void 0, opts, "arrangement meters");
482
498
  const budget = opts.budget;
483
499
  const noteOptions = { allowNonPositiveDuration: true, budget };
484
500
  if (opts.pickupBeats !== void 0) {
485
- _chunkXKSO2V5Icjs.assertRange.call(void 0, opts.pickupBeats, 0, Number.MAX_SAFE_INTEGER, "arrangement pickupBeats");
501
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, opts.pickupBeats, 0, Number.MAX_SAFE_INTEGER, "arrangement pickupBeats");
486
502
  noteOptions.minStartBeat = -opts.pickupBeats;
487
503
  }
488
- _chunkXKSO2V5Icjs.assertArray.call(void 0, tracks, "arrangement tracks");
489
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, tracks.length, "arrangement tracks", budget);
504
+ _chunkS5BKZZGMcjs.assertArray.call(void 0, tracks, "arrangement tracks");
505
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, tracks.length, "arrangement tracks", budget);
490
506
  const noteCount = assertTrackNotes(tracks, noteOptions);
491
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, noteCount, "arrangement notes", budget);
507
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, noteCount, "arrangement notes", budget);
492
508
  const profile = arrangementProfile(opts.profile);
493
- const minSeverity = opts.minSeverity === void 0 ? 1 /* Warning */ : _chunkXKSO2V5Icjs.assertInteger.call(void 0,
509
+ const minSeverity = opts.minSeverity === void 0 ? 1 /* Warning */ : _chunkS5BKZZGMcjs.assertInteger.call(void 0,
494
510
  opts.minSeverity,
495
511
  "arrangement minSeverity",
496
512
  0 /* Safe */,
@@ -501,12 +517,12 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
501
517
  const harmonyTracks = harmonyTrackSet(opts.harmonyTracks, tracks);
502
518
  const prepared = prepareTracks(tracks);
503
519
  const voiceCount = prepared.reduce((sum, track) => sum + track.voices.length, 0);
504
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, noteCount * voiceCount, "arrangement note-voice comparisons", budget);
520
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, noteCount * voiceCount, "arrangement note-voice comparisons", budget);
505
521
  const pooled = poolNotes(tracks, harmonyTracks);
506
522
  let evidence;
507
523
  let inferred;
508
524
  if (opts.timeline === void 0) {
509
- const run = _chunkQ6R3QAZDcjs.analyzeTimeline.call(void 0,
525
+ const run = _chunkSGLEQVJHcjs.analyzeTimeline.call(void 0,
510
526
  pooled,
511
527
  {
512
528
  key: opts.key,
@@ -524,9 +540,9 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
524
540
  inferred = callerTimeline(opts.timeline, opts.key, opts.keys, pooled, meters, budget);
525
541
  }
526
542
  const { timeline, keys, prevailingKey, segmentConfidence } = inferred;
527
- const keyAt = _chunkQ6R3QAZDcjs.keyLookup.call(void 0, keys, prevailingKey);
528
- const scaleAt = (beat) => _chunkYPB3A3EYcjs.scaleOf.call(void 0, keyAt(beat));
529
- const cadences = _chunkQ6R3QAZDcjs.detectCadences.call(void 0, timeline, scaleAt);
543
+ const keyAt = _chunkSGLEQVJHcjs.keyLookup.call(void 0, keys, prevailingKey);
544
+ const scaleAt = (beat) => _chunk3R3QVKY5cjs.scaleOf.call(void 0, keyAt(beat));
545
+ const cadences = _chunkSGLEQVJHcjs.detectCadences.call(void 0, timeline, scaleAt);
530
546
  const soundingCache = /* @__PURE__ */ new Map();
531
547
  const trackAnalyses = [];
532
548
  const conflicts = [];
@@ -545,11 +561,11 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
545
561
  if (!subVoice) {
546
562
  continue;
547
563
  }
548
- const analyzed = _chunkQ6R3QAZDcjs.analyzeVoice.call(void 0,
564
+ const analyzed = _chunkSGLEQVJHcjs.analyzeVoice.call(void 0,
549
565
  subVoice.voice,
550
566
  timeline.at,
551
567
  scaleAt,
552
- (beat) => otherVoicesSounding(prepared, t, v, beat, soundingCache)
568
+ (beat) => snapshotsOf(otherVoicesSounding(prepared, t, v, beat, soundingCache))
553
569
  );
554
570
  for (const note of analyzed) {
555
571
  notes.push({ ...note, trackIndex: track.trackIndex });
@@ -562,19 +578,20 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
562
578
  continue;
563
579
  }
564
580
  for (const beat of evaluationBeats(note, timeline)) {
565
- const atOnset = _chunkQ6R3QAZDcjs.sameInstant.call(void 0, beat, note.startBeat);
581
+ const atOnset = _chunkSGLEQVJHcjs.sameInstant.call(void 0, beat, note.startBeat);
582
+ const others = otherVoicesSounding(prepared, t, v, beat, soundingCache);
566
583
  const safetyQuery = {
567
584
  profile,
568
585
  candidatePitch: note.pitch,
569
586
  prevPitch: atOnset ? preparedNote.prevPitch : note.pitch,
570
587
  chord: timeline.at(beat),
571
588
  key: scaleAt(beat),
572
- otherVoices: otherVoicesSounding(prepared, t, v, beat, soundingCache),
573
- strongBeat: _chunkXKSO2V5Icjs.isStrongBeat.call(void 0, beat, meters)
589
+ otherVoices: snapshotsOf(others),
590
+ strongBeat: _chunkS5BKZZGMcjs.isStrongBeat.call(void 0, beat, meters)
574
591
  };
575
- let result = _chunkYPB3A3EYcjs.evaluateSafety.call(void 0, safetyQuery, { suggestions: false });
592
+ let result = _chunk3R3QVKY5cjs.evaluateSafety.call(void 0, safetyQuery, { suggestions: false });
576
593
  if (result.safety !== 0 /* Safe */ && result.safety >= minSeverity) {
577
- result = _chunkYPB3A3EYcjs.evaluateSafety.call(void 0, safetyQuery);
594
+ result = _chunk3R3QVKY5cjs.evaluateSafety.call(void 0, safetyQuery, { partners: true });
578
595
  const conflict = {
579
596
  beat,
580
597
  trackName: track.name,
@@ -597,6 +614,11 @@ function analyzeArrangementWith(tracks, opts = {}, previous, dirty) {
597
614
  if (result.suggestions !== void 0) {
598
615
  conflict.suggestions = [...result.suggestions];
599
616
  }
617
+ if (result.partners !== void 0) {
618
+ conflict.partners = result.partners.map(
619
+ ({ index, reasons }) => conflictPartner(others[index], reasons)
620
+ );
621
+ }
600
622
  conflicts.push(conflict);
601
623
  }
602
624
  }
@@ -682,7 +704,7 @@ function sessionOf(tracks, opts, analysis, evidence) {
682
704
  tracks,
683
705
  analysis,
684
706
  update(edits) {
685
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, edits.length, "arrangement edits", opts.budget);
707
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, edits.length, "arrangement edits", opts.budget);
686
708
  const next = [...tracks];
687
709
  let edited = null;
688
710
  let reordered = false;
@@ -693,16 +715,16 @@ function sessionOf(tracks, opts, analysis, evidence) {
693
715
  }
694
716
  const target = next[edit.trackIndex];
695
717
  if (target === void 0) {
696
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
718
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
697
719
  `edits[${index}].trackIndex ${edit.trackIndex} is outside the session's ${tracks.length} tracks`
698
720
  );
699
721
  }
700
722
  if (!Array.isArray(edit.notes)) {
701
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
723
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
702
724
  `edits[${index}].notes must be an array; received ${typeof edit.notes}`
703
725
  );
704
726
  }
705
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, edit.notes, `edits[${index}].notes`, {
727
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, edit.notes, `edits[${index}].notes`, {
706
728
  allowNonPositiveDuration: true,
707
729
  budget: opts.budget
708
730
  });
@@ -713,7 +735,7 @@ function sessionOf(tracks, opts, analysis, evidence) {
713
735
  if (edited === null && !reordered) {
714
736
  return sessionOf(next, opts, analysis, evidence);
715
737
  }
716
- const dirty = evidence === void 0 ? void 0 : edited === null ? { from: 0, to: 0 } : _chunkQ6R3QAZDcjs.dirtySlotsFor.call(void 0, evidence, edited.startBeat, edited.endBeat);
738
+ const dirty = evidence === void 0 ? void 0 : edited === null ? { from: 0, to: 0 } : _chunkSGLEQVJHcjs.dirtySlotsFor.call(void 0, evidence, edited.startBeat, edited.endBeat);
717
739
  const run = analyzeArrangementWith(next, opts, evidence, dirty);
718
740
  return sessionOf(next, opts, run.analysis, run.evidence);
719
741
  }
@@ -738,22 +760,22 @@ function clamp012(value) {
738
760
  return Math.min(1, Math.max(0, value));
739
761
  }
740
762
  function tensionCurve(tracks, opts = {}) {
741
- const meters = _chunkXKSO2V5Icjs.resolveMeters.call(void 0, opts, "arrangement meters");
763
+ const meters = _chunkS5BKZZGMcjs.resolveMeters.call(void 0, opts, "arrangement meters");
742
764
  const budget = opts.budget;
743
765
  const noteOptions = { allowNonPositiveDuration: true, budget };
744
766
  if (opts.pickupBeats !== void 0) {
745
- _chunkXKSO2V5Icjs.assertRange.call(void 0, opts.pickupBeats, 0, Number.MAX_SAFE_INTEGER, "arrangement pickupBeats");
767
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, opts.pickupBeats, 0, Number.MAX_SAFE_INTEGER, "arrangement pickupBeats");
746
768
  noteOptions.minStartBeat = -opts.pickupBeats;
747
769
  }
748
- _chunkXKSO2V5Icjs.assertArray.call(void 0, tracks, "arrangement tracks");
749
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, tracks.length, "arrangement tracks", budget);
770
+ _chunkS5BKZZGMcjs.assertArray.call(void 0, tracks, "arrangement tracks");
771
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, tracks.length, "arrangement tracks", budget);
750
772
  const noteCount = assertTrackNotes(tracks, noteOptions);
751
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, noteCount, "arrangement notes", budget);
773
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, noteCount, "arrangement notes", budget);
752
774
  const profile = arrangementProfile(opts.profile);
753
775
  const step = _nullishCoalesce(opts.step, () => ( 1));
754
- _chunkXKSO2V5Icjs.assertRange.call(void 0, step, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "tension sampling step");
776
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, step, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "tension sampling step");
755
777
  if (opts.minSeverity !== void 0) {
756
- _chunkXKSO2V5Icjs.assertInteger.call(void 0,
778
+ _chunkS5BKZZGMcjs.assertInteger.call(void 0,
757
779
  opts.minSeverity,
758
780
  "arrangement minSeverity",
759
781
  0 /* Safe */,
@@ -766,7 +788,7 @@ function tensionCurve(tracks, opts = {}) {
766
788
  const pooled = poolNotes(tracks, harmonyTracks);
767
789
  const all = poolNotes(tracks);
768
790
  const totalBeats = all.reduce((end, n) => Math.max(end, n.startBeat + n.durationBeat), 0);
769
- const { origin: sampleStart, startBeat: musicStart } = _chunkQ6R3QAZDcjs.gridForNotes.call(void 0, all, step);
791
+ const { origin: sampleStart, startBeat: musicStart } = _chunkSGLEQVJHcjs.gridForNotes.call(void 0, all, step);
770
792
  const suppliedKeys = opts.timeline === void 0 ? void 0 : _nullishCoalesce(opts.keys, () => ( (opts.key !== void 0 ? [
771
793
  {
772
794
  // The one region a named key holds starts where the music does,
@@ -774,11 +796,11 @@ function tensionCurve(tracks, opts = {}) {
774
796
  // a key cannot be in force over beats nothing sounds in.
775
797
  startBeat: musicStart,
776
798
  endBeat: totalBeats,
777
- key: _chunkYPB3A3EYcjs.resolveKey.call(void 0, opts.key),
799
+ key: _chunk3R3QVKY5cjs.resolveKey.call(void 0, opts.key),
778
800
  confidence: 1
779
801
  }
780
- ] : _chunkQ6R3QAZDcjs.keyTimelineFromNotes.call(void 0, pooled, { meters, totalBeats, budget }))));
781
- const { timeline, keys, prevailingKey } = opts.timeline === void 0 || suppliedKeys === void 0 ? _chunkQ6R3QAZDcjs.chordTimelineFromNotes.call(void 0, pooled, {
802
+ ] : _chunkSGLEQVJHcjs.keyTimelineFromNotes.call(void 0, pooled, { meters, totalBeats, budget }))));
803
+ const { timeline, keys, prevailingKey } = opts.timeline === void 0 || suppliedKeys === void 0 ? _chunkSGLEQVJHcjs.chordTimelineFromNotes.call(void 0, pooled, {
782
804
  key: opts.key,
783
805
  meters,
784
806
  pickupBeats: opts.pickupBeats,
@@ -787,16 +809,16 @@ function tensionCurve(tracks, opts = {}) {
787
809
  }) : {
788
810
  timeline: opts.timeline,
789
811
  keys: suppliedKeys,
790
- prevailingKey: _nullishCoalesce(_chunkQ6R3QAZDcjs.prevailingKeyOf.call(void 0, suppliedKeys), () => ( _chunkYPB3A3EYcjs.resolveKey.call(void 0, _chunkYPB3A3EYcjs.majorKey.call(void 0, 0))))
812
+ prevailingKey: _nullishCoalesce(_chunkSGLEQVJHcjs.prevailingKeyOf.call(void 0, suppliedKeys), () => ( _chunk3R3QVKY5cjs.resolveKey.call(void 0, _chunk3R3QVKY5cjs.majorKey.call(void 0, 0))))
791
813
  };
792
814
  const regions = _nullishCoalesce(opts.keys, () => ( keys));
793
- const keyAt = _chunkQ6R3QAZDcjs.keyLookup.call(void 0, regions, _nullishCoalesce(_chunkQ6R3QAZDcjs.prevailingKeyOf.call(void 0, regions), () => ( prevailingKey)));
815
+ const keyAt = _chunkSGLEQVJHcjs.keyLookup.call(void 0, regions, _nullishCoalesce(_chunkSGLEQVJHcjs.prevailingKeyOf.call(void 0, regions), () => ( prevailingKey)));
794
816
  const prepared = prepareTracks(tracks);
795
817
  const points = [];
796
- const sampleCount = Math.max(0, Math.ceil((totalBeats - sampleStart) / step - _chunkXKSO2V5Icjs.BEAT_EPS));
797
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, sampleCount, "tension samples", budget);
818
+ const sampleCount = Math.max(0, Math.ceil((totalBeats - sampleStart) / step - _chunkS5BKZZGMcjs.BEAT_EPS));
819
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, sampleCount, "tension samples", budget);
798
820
  const voiceCount = prepared.reduce((sum, track) => sum + track.voices.length, 0);
799
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0,
821
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0,
800
822
  sampleCount * Math.min(128, voiceCount) * voiceCount,
801
823
  "tension sample-voice comparisons",
802
824
  budget
@@ -807,14 +829,14 @@ function tensionCurve(tracks, opts = {}) {
807
829
  beat,
808
830
  // The pitch classes alone: tension is scored from what sounds against
809
831
  // the tonic, and no reading below here asks how the key is written.
810
- tension: sampleTension(prepared, timeline, _chunkYPB3A3EYcjs.scaleOf.call(void 0, keyAt(beat)), meters, profile, beat)
832
+ tension: sampleTension(prepared, timeline, _chunk3R3QVKY5cjs.scaleOf.call(void 0, keyAt(beat)), meters, profile, beat)
811
833
  });
812
834
  }
813
835
  return points;
814
836
  }
815
837
  function tensionCurveFrom(tracks, analysis, opts = {}) {
816
- const asked = _chunkXKSO2V5Icjs.assertRecord.call(void 0, opts, "opts");
817
- const carried = carriedHarmony(_chunkXKSO2V5Icjs.assertRecord.call(void 0, analysis, "analysis"), asked);
838
+ const asked = _chunkS5BKZZGMcjs.assertRecord.call(void 0, opts, "opts");
839
+ const carried = carriedHarmony(_chunkS5BKZZGMcjs.assertRecord.call(void 0, analysis, "analysis"), asked);
818
840
  return tensionCurve(tracks, { ...carried, ...asked });
819
841
  }
820
842
  function carriedHarmony(analysis, opts) {
@@ -848,9 +870,9 @@ function sampleTension(prepared, timeline, key, meters, profile, beat) {
848
870
  return 0;
849
871
  }
850
872
  const chord = timeline.at(beat);
851
- const functionScore = chord ? FUNCTION_TENSION[_chunkQ6R3QAZDcjs.functionOf.call(void 0, chord, key)] : 0;
852
- const chordPcs = chord ? new Set(_chunkYPB3A3EYcjs.chordPitchClasses.call(void 0, chord)) : null;
853
- const strongBeat = _chunkXKSO2V5Icjs.isStrongBeat.call(void 0, beat, meters);
873
+ const functionScore = chord ? FUNCTION_TENSION[_chunkSGLEQVJHcjs.functionOf.call(void 0, chord, key)] : 0;
874
+ const chordPcs = chord ? new Set(_chunk3R3QVKY5cjs.chordPitchClasses.call(void 0, chord)) : null;
875
+ const strongBeat = _chunkS5BKZZGMcjs.isStrongBeat.call(void 0, beat, meters);
854
876
  let nonChord = 0;
855
877
  let dissonant = 0;
856
878
  const pitches = /* @__PURE__ */ new Map();
@@ -866,7 +888,7 @@ function sampleTension(prepared, timeline, key, meters, profile, beat) {
866
888
  }
867
889
  }
868
890
  for (const [pitch, count] of pitches) {
869
- if (chordPcs && !chordPcs.has(_chunkXKSO2V5Icjs.pitchClassOf.call(void 0, pitch))) {
891
+ if (chordPcs && !chordPcs.has(_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pitch))) {
870
892
  nonChord += count;
871
893
  }
872
894
  const at = _nullishCoalesce(firstOf.get(pitch), () => ( 0));
@@ -877,7 +899,7 @@ function sampleTension(prepared, timeline, key, meters, profile, beat) {
877
899
  others[at] = tail;
878
900
  others.pop();
879
901
  }
880
- const result = _chunkYPB3A3EYcjs.evaluateSafety.call(void 0,
902
+ const result = _chunk3R3QVKY5cjs.evaluateSafety.call(void 0,
881
903
  { profile, candidatePitch: pitch, chord, key, otherVoices: others, strongBeat },
882
904
  { suggestions: false }
883
905
  );
@@ -928,7 +950,7 @@ function accentContrast(novelty, slices, groupBars, phase) {
928
950
  continue;
929
951
  }
930
952
  const value = _nullishCoalesce(novelty[i], () => ( 0));
931
- if (_chunkQ6R3QAZDcjs.floorMod.call(void 0, slice.index - phase, groupBars) === 0) {
953
+ if (_chunkSGLEQVJHcjs.floorMod.call(void 0, slice.index - phase, groupBars) === 0) {
932
954
  headSum += value;
933
955
  headCount += 1;
934
956
  } else {
@@ -946,7 +968,7 @@ function cadenceFitOf(cadenceBars, slices, groupBars, phase) {
946
968
  let ends = 0;
947
969
  let fit = 0;
948
970
  for (const slice of slices) {
949
- if (slice.index < 0 || _chunkQ6R3QAZDcjs.floorMod.call(void 0, slice.index - phase, groupBars) !== groupBars - 1) {
971
+ if (slice.index < 0 || _chunkSGLEQVJHcjs.floorMod.call(void 0, slice.index - phase, groupBars) !== groupBars - 1) {
950
972
  continue;
951
973
  }
952
974
  ends += 1;
@@ -956,7 +978,7 @@ function cadenceFitOf(cadenceBars, slices, groupBars, phase) {
956
978
  fit += ELIDED_FIT;
957
979
  }
958
980
  }
959
- return ends === 0 ? 0 : _chunkQ6R3QAZDcjs.clamp01.call(void 0, fit / ends);
981
+ return ends === 0 ? 0 : _chunkSGLEQVJHcjs.clamp01.call(void 0, fit / ends);
960
982
  }
961
983
  function undecidedReading(slices) {
962
984
  const fullBars = slices.filter((slice) => slice.index >= 0);
@@ -970,31 +992,31 @@ function undecidedReading(slices) {
970
992
  };
971
993
  }
972
994
  function hypermeter(notes, meter, opts = {}) {
973
- const asked = _chunkXKSO2V5Icjs.assertOptions.call(void 0, opts, "opts");
974
- const meters = _chunkXKSO2V5Icjs.resolveMeters.call(void 0, { meters: meter }, "meter");
975
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, notes, "hypermeter notes", {
995
+ const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
996
+ const meters = _chunkS5BKZZGMcjs.resolveMeters.call(void 0, { meters: meter }, "meter");
997
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, notes, "hypermeter notes", {
976
998
  allowNonPositiveDuration: true,
977
999
  budget: asked.budget
978
1000
  });
979
1001
  const sounding = notes.filter((note) => note.durationBeat > 0);
980
- const firstOnset = _chunkQ6R3QAZDcjs.firstSoundingBeat.call(void 0, sounding);
1002
+ const firstOnset = _chunkSGLEQVJHcjs.firstSoundingBeat.call(void 0, sounding);
981
1003
  const lastEnd = sounding.reduce((end, n) => Math.max(end, n.startBeat + n.durationBeat), 0);
982
1004
  const spanEnd = _nullishCoalesce(asked.totalBeats, () => ( lastEnd));
983
- _chunkXKSO2V5Icjs.assertRange.call(void 0, spanEnd, 0, Number.MAX_SAFE_INTEGER, "hypermeter totalBeats");
984
- const spanStart = _chunkQ6R3QAZDcjs.barGridStart.call(void 0, firstOnset, meters);
985
- const slices = _chunkQ6R3QAZDcjs.sliceBars.call(void 0, sounding, meters, spanStart, spanEnd, asked.budget);
1005
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, spanEnd, 0, Number.MAX_SAFE_INTEGER, "hypermeter totalBeats");
1006
+ const spanStart = _chunkSGLEQVJHcjs.barGridStart.call(void 0, firstOnset, meters);
1007
+ const slices = _chunkSGLEQVJHcjs.sliceBars.call(void 0, sounding, meters, spanStart, spanEnd, asked.budget);
986
1008
  const fullBars = slices.reduce((count, slice) => slice.index >= 0 ? count + 1 : count, 0);
987
1009
  const candidates = GROUP_CANDIDATES.filter((groupBars) => fullBars >= groupBars * MIN_GROUPS);
988
1010
  if (candidates.length === 0) {
989
1011
  return undecidedReading(slices);
990
1012
  }
991
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0,
1013
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0,
992
1014
  candidates.reduce((sum, groupBars) => sum + groupBars * slices.length, 0),
993
1015
  "hypermeter readings",
994
1016
  asked.budget
995
1017
  );
996
- const novelty = slices.map((_, index) => _chunkQ6R3QAZDcjs.harmonicNovelty.call(void 0, slices, index));
997
- const cadenceBars = new Set((_nullishCoalesce(asked.cadenceBeats, () => ( []))).map((beat) => _chunkXKSO2V5Icjs.barIndexAt.call(void 0, beat, meters)));
1018
+ const novelty = slices.map((_, index) => _chunkSGLEQVJHcjs.harmonicNovelty.call(void 0, slices, index));
1019
+ const cadenceBars = new Set((_nullishCoalesce(asked.cadenceBeats, () => ( []))).map((beat) => _chunkS5BKZZGMcjs.barIndexAt.call(void 0, beat, meters)));
998
1020
  const hasCadences = cadenceBars.size > 0;
999
1021
  const readings = [];
1000
1022
  for (const groupBars of candidates) {
@@ -1005,17 +1027,17 @@ function hypermeter(notes, meter, opts = {}) {
1005
1027
  }));
1006
1028
  const bestFit = phases.reduce((best2, reading) => Math.max(best2, reading.cadenceFit), 0);
1007
1029
  for (const { phase, contrast, cadenceFit } of phases) {
1008
- if (hasCadences && cadenceFit < bestFit - _chunkXKSO2V5Icjs.BEAT_EPS) {
1030
+ if (hasCadences && cadenceFit < bestFit - _chunkS5BKZZGMcjs.BEAT_EPS) {
1009
1031
  continue;
1010
1032
  }
1011
- const evidence = _chunkQ6R3QAZDcjs.clamp01.call(void 0,
1033
+ const evidence = _chunkSGLEQVJHcjs.clamp01.call(void 0,
1012
1034
  hasCadences ? (
1013
1035
  // Floored at zero rather than summed raw: group heads that restate
1014
1036
  // the harmony their group opened with — the commonest way a phrase
1015
1037
  // begins — change less than the bars between them, and a negative
1016
1038
  // contrast subtracted from the cadence term would count that
1017
1039
  // restatement as evidence against the very phase it confirms.
1018
- CONTRAST_SHARE * _chunkQ6R3QAZDcjs.clamp01.call(void 0, contrast) + CADENCE_SHARE * cadenceFit
1040
+ CONTRAST_SHARE * _chunkSGLEQVJHcjs.clamp01.call(void 0, contrast) + CADENCE_SHARE * cadenceFit
1019
1041
  ) : contrast
1020
1042
  );
1021
1043
  readings.push({
@@ -1036,8 +1058,8 @@ function hypermeter(notes, meter, opts = {}) {
1036
1058
  return undecidedReading(slices);
1037
1059
  }
1038
1060
  const runnerUp = readings.find((reading) => reading.groupBars !== best.groupBars);
1039
- const margin = runnerUp === void 0 || best.score <= _chunkXKSO2V5Icjs.BEAT_EPS ? 1 : _chunkQ6R3QAZDcjs.clamp01.call(void 0, (best.score - runnerUp.score) / best.score);
1040
- const downbeats = slices.filter((slice) => slice.index >= 0 && _chunkQ6R3QAZDcjs.floorMod.call(void 0, slice.index - best.phase, best.groupBars) === 0).map((slice) => slice.startBeat);
1061
+ const margin = runnerUp === void 0 || best.score <= _chunkS5BKZZGMcjs.BEAT_EPS ? 1 : _chunkSGLEQVJHcjs.clamp01.call(void 0, (best.score - runnerUp.score) / best.score);
1062
+ const downbeats = slices.filter((slice) => slice.index >= 0 && _chunkSGLEQVJHcjs.floorMod.call(void 0, slice.index - best.phase, best.groupBars) === 0).map((slice) => slice.startBeat);
1041
1063
  const cadencePart = hasCadences ? `${Math.round(best.cadenceFit * 100)}% of group ends closed by a cadence` : "no cadences given";
1042
1064
  return {
1043
1065
  groupBars: best.groupBars,
@@ -1047,7 +1069,7 @@ function hypermeter(notes, meter, opts = {}) {
1047
1069
  // runner-up is nearly always a multiple or a divisor of the winner — four
1048
1070
  // bars nest inside eight — and a reading of the same accents at another
1049
1071
  // level is weaker counter-evidence than an unrelated rival would be.
1050
- confidence: _chunkQ6R3QAZDcjs.clamp01.call(void 0, best.evidence * (MARGIN_FLOOR + (1 - MARGIN_FLOOR) * margin)),
1072
+ confidence: _chunkSGLEQVJHcjs.clamp01.call(void 0, best.evidence * (MARGIN_FLOOR + (1 - MARGIN_FLOOR) * margin)),
1051
1073
  rationale: `${best.groupBars}-bar groups from bar ${best.phase}: harmonic change ${Math.round(best.contrast * 100)}% stronger on group heads, ${cadencePart}`
1052
1074
  };
1053
1075
  }
@@ -1058,15 +1080,15 @@ function phraseNotes(phrase) {
1058
1080
  if (Array.isArray(phrase)) {
1059
1081
  return phrase;
1060
1082
  }
1061
- return _chunkXKSO2V5Icjs.assertRecord.call(void 0, phrase, "melodic phrase").notes;
1083
+ return _chunkS5BKZZGMcjs.assertRecord.call(void 0, phrase, "melodic phrase").notes;
1062
1084
  }
1063
1085
  function orderedNotes(notes, name, budget) {
1064
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, notes, name, { allowNonPositiveDuration: true, budget });
1086
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, notes, name, { allowNonPositiveDuration: true, budget });
1065
1087
  const sounding = notes.filter((note) => note.durationBeat > 0).sort((a, b) => a.startBeat - b.startBeat || a.pitch - b.pitch);
1066
1088
  const line = [];
1067
1089
  for (const note of sounding) {
1068
1090
  const previous = line[line.length - 1];
1069
- if (previous !== void 0 && Math.abs(note.startBeat - previous.startBeat) <= _chunkXKSO2V5Icjs.BEAT_EPS) {
1091
+ if (previous !== void 0 && Math.abs(note.startBeat - previous.startBeat) <= _chunkS5BKZZGMcjs.BEAT_EPS) {
1070
1092
  line[line.length - 1] = note;
1071
1093
  continue;
1072
1094
  }
@@ -1101,7 +1123,7 @@ function retrogradeGaps(notes) {
1101
1123
  }
1102
1124
  function rhythmProfile(gaps) {
1103
1125
  const unit = _nullishCoalesce(gaps[0], () => ( 0));
1104
- if (!(unit > _chunkXKSO2V5Icjs.BEAT_EPS)) {
1126
+ if (!(unit > _chunkS5BKZZGMcjs.BEAT_EPS)) {
1105
1127
  return gaps.length === 0 ? [] : null;
1106
1128
  }
1107
1129
  return gaps.map((gap) => Math.round(gap / unit * RHYTHM_GRID) / RHYTHM_GRID);
@@ -1111,7 +1133,7 @@ function sameNumbers(a, b) {
1111
1133
  return false;
1112
1134
  }
1113
1135
  for (let i = 0; i < a.length; i += 1) {
1114
- if (Math.abs((_nullishCoalesce(a[i], () => ( 0))) - (_nullishCoalesce(b[i], () => ( 0)))) > _chunkXKSO2V5Icjs.BEAT_EPS) {
1136
+ if (Math.abs((_nullishCoalesce(a[i], () => ( 0))) - (_nullishCoalesce(b[i], () => ( 0)))) > _chunkS5BKZZGMcjs.BEAT_EPS) {
1115
1137
  return false;
1116
1138
  }
1117
1139
  }
@@ -1262,12 +1284,12 @@ function motifFromGroup(group, notes) {
1262
1284
  startBeat: _nullishCoalesce(_optionalChain([statement, 'access', _79 => _79[0], 'optionalAccess', _80 => _80.startBeat]), () => ( 0)),
1263
1285
  endBeat: endBeatOf(statement),
1264
1286
  transpose: (_nullishCoalesce(_optionalChain([statement, 'access', _81 => _81[0], 'optionalAccess', _82 => _82.pitch]), () => ( 0))) - primePitch,
1265
- timeRatio: primeSpan > _chunkXKSO2V5Icjs.BEAT_EPS ? span / primeSpan : 1
1287
+ timeRatio: primeSpan > _chunkS5BKZZGMcjs.BEAT_EPS ? span / primeSpan : 1
1266
1288
  };
1267
1289
  });
1268
1290
  const shape = melodicContour(prime).shape;
1269
1291
  const transposed = occurrences.some((occurrence) => occurrence.transpose !== 0);
1270
- const stretched = occurrences.some((occurrence) => Math.abs(occurrence.timeRatio - 1) > _chunkXKSO2V5Icjs.BEAT_EPS);
1292
+ const stretched = occurrences.some((occurrence) => Math.abs(occurrence.timeRatio - 1) > _chunkS5BKZZGMcjs.BEAT_EPS);
1271
1293
  const detail = [
1272
1294
  transposed ? "at more than one pitch level" : "at the same pitch level",
1273
1295
  stretched ? "and in more than one set of note values" : ""
@@ -1281,15 +1303,15 @@ function motifFromGroup(group, notes) {
1281
1303
  };
1282
1304
  }
1283
1305
  function extractMotifs(notes, opts = {}) {
1284
- const asked = _chunkXKSO2V5Icjs.assertOptions.call(void 0, opts, "opts");
1285
- const minNotes = _chunkXKSO2V5Icjs.assertInteger.call(void 0, _nullishCoalesce(asked.minNotes, () => ( MIN_CELL_NOTES)), "motif minNotes", 2, 64);
1286
- const maxNotes = _chunkXKSO2V5Icjs.assertInteger.call(void 0, _nullishCoalesce(asked.maxNotes, () => ( MAX_CELL_NOTES)), "motif maxNotes", 2, 64);
1306
+ const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
1307
+ const minNotes = _chunkS5BKZZGMcjs.assertInteger.call(void 0, _nullishCoalesce(asked.minNotes, () => ( MIN_CELL_NOTES)), "motif minNotes", 2, 64);
1308
+ const maxNotes = _chunkS5BKZZGMcjs.assertInteger.call(void 0, _nullishCoalesce(asked.maxNotes, () => ( MAX_CELL_NOTES)), "motif maxNotes", 2, 64);
1287
1309
  if (maxNotes < minNotes) {
1288
- throw new (0, _chunkXKSO2V5Icjs.InvalidInputError)(
1310
+ throw new (0, _chunkS5BKZZGMcjs.InvalidInputError)(
1289
1311
  `motif maxNotes must be at least minNotes ${minNotes}; received ${maxNotes}`
1290
1312
  );
1291
1313
  }
1292
- const minOccurrences = _chunkXKSO2V5Icjs.assertInteger.call(void 0,
1314
+ const minOccurrences = _chunkS5BKZZGMcjs.assertInteger.call(void 0,
1293
1315
  _nullishCoalesce(asked.minOccurrences, () => ( MIN_OCCURRENCES)),
1294
1316
  "motif minOccurrences",
1295
1317
  2
@@ -1298,7 +1320,7 @@ function extractMotifs(notes, opts = {}) {
1298
1320
  if (sounding.length < minNotes) {
1299
1321
  return [];
1300
1322
  }
1301
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0,
1323
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0,
1302
1324
  sounding.length * (maxNotes - minNotes + 1),
1303
1325
  "motif windows",
1304
1326
  asked.budget
@@ -1345,7 +1367,7 @@ function extractMotifs(notes, opts = {}) {
1345
1367
  }
1346
1368
  }
1347
1369
  }
1348
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, comparisons, "motif subsumption comparisons", asked.budget);
1370
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, comparisons, "motif subsumption comparisons", asked.budget);
1349
1371
  if (!covered) {
1350
1372
  kept.push(candidate);
1351
1373
  let byStart = keptByLength.get(candidate.length);
@@ -1373,18 +1395,18 @@ function spellingOf(key) {
1373
1395
  if (key === void 0) {
1374
1396
  return "sharp";
1375
1397
  }
1376
- return _chunkYPB3A3EYcjs.keySignatureFifths.call(void 0, key.tonic, key.scale) < 0 ? "flat" : "sharp";
1398
+ return _chunk3R3QVKY5cjs.keySignatureFifths.call(void 0, key.tonic, key.scale) < 0 ? "flat" : "sharp";
1377
1399
  }
1378
1400
  function intervalBetween(from, to, key) {
1379
1401
  const spelling = spellingOf(key);
1380
- return _chunkXKSO2V5Icjs.spelledInterval.call(void 0, _chunkXKSO2V5Icjs.midiToNote.call(void 0, from, spelling), _chunkXKSO2V5Icjs.midiToNote.call(void 0, to, spelling));
1402
+ return _chunkS5BKZZGMcjs.spelledInterval.call(void 0, _chunkS5BKZZGMcjs.midiToNote.call(void 0, from, spelling), _chunkS5BKZZGMcjs.midiToNote.call(void 0, to, spelling));
1381
1403
  }
1382
1404
  function intervalName(interval) {
1383
1405
  return `${interval.descending && interval.semitones !== 0 ? "-" : ""}${interval.quality}${interval.number}`;
1384
1406
  }
1385
1407
  function ladderIndices(notes, key) {
1386
- const root = _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, key.rootPc);
1387
- const offsets = _chunkYPB3A3EYcjs.scaleTonesInDegreeOrder.call(void 0, key).map((pc) => _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, pc - root));
1408
+ const root = _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, key.rootPc);
1409
+ const offsets = _chunk3R3QVKY5cjs.scaleTonesInDegreeOrder.call(void 0, key).map((pc) => _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, pc - root));
1388
1410
  if (offsets.length === 0) {
1389
1411
  return null;
1390
1412
  }
@@ -1435,15 +1457,15 @@ function totalGap(gaps) {
1435
1457
  }
1436
1458
  function stretchRatio(modelGaps, answerGaps) {
1437
1459
  const span = totalGap(modelGaps);
1438
- return span > _chunkXKSO2V5Icjs.BEAT_EPS ? totalGap(answerGaps) / span : 1;
1460
+ return span > _chunkS5BKZZGMcjs.BEAT_EPS ? totalGap(answerGaps) / span : 1;
1439
1461
  }
1440
1462
  function stretchPhrase(ratio) {
1441
1463
  return `note values ${roundTo(ratio, 3)}x the model's`;
1442
1464
  }
1443
1465
  function relateMotifs(a, b, keyLike) {
1444
- const key = keyLike === void 0 ? void 0 : _chunkYPB3A3EYcjs.resolveKey.call(void 0, keyLike);
1445
- const model = _chunkXKSO2V5Icjs.assertArray.call(void 0, _chunkXKSO2V5Icjs.assertRecord.call(void 0, a, "a").notes, "a.notes");
1446
- const answer = _chunkXKSO2V5Icjs.assertArray.call(void 0, _chunkXKSO2V5Icjs.assertRecord.call(void 0, b, "b").notes, "b.notes");
1466
+ const key = keyLike === void 0 ? void 0 : _chunk3R3QVKY5cjs.resolveKey.call(void 0, keyLike);
1467
+ const model = _chunkS5BKZZGMcjs.assertArray.call(void 0, _chunkS5BKZZGMcjs.assertRecord.call(void 0, a, "a").notes, "a.notes");
1468
+ const answer = _chunkS5BKZZGMcjs.assertArray.call(void 0, _chunkS5BKZZGMcjs.assertRecord.call(void 0, b, "b").notes, "b.notes");
1447
1469
  if (model.length === 0 || model.length !== answer.length) {
1448
1470
  return null;
1449
1471
  }
@@ -1461,9 +1483,9 @@ function relateMotifs(a, b, keyLike) {
1461
1483
  const semitones = (_nullishCoalesce(_optionalChain([answer, 'access', _83 => _83[0], 'optionalAccess', _84 => _84.pitch]), () => ( 0))) - (_nullishCoalesce(_optionalChain([model, 'access', _85 => _85[0], 'optionalAccess', _86 => _86.pitch]), () => ( 0)));
1462
1484
  const interval = intervalBetween(_nullishCoalesce(_optionalChain([model, 'access', _87 => _87[0], 'optionalAccess', _88 => _88.pitch]), () => ( 0)), _nullishCoalesce(_optionalChain([answer, 'access', _89 => _89[0], 'optionalAccess', _90 => _90.pitch]), () => ( 0)), key);
1463
1485
  const gap = (_nullishCoalesce(_optionalChain([answer, 'access', _91 => _91[0], 'optionalAccess', _92 => _92.startBeat]), () => ( 0))) - endBeatOf(model);
1464
- const sequence = gap >= -_chunkQ6R3QAZDcjs.HUMANIZE_ADJACENCY && gap <= _chunkQ6R3QAZDcjs.HUMANIZE_ADJACENCY;
1486
+ const sequence = gap >= -_chunkSGLEQVJHcjs.HUMANIZE_ADJACENCY && gap <= _chunkSGLEQVJHcjs.HUMANIZE_ADJACENCY;
1465
1487
  const timeRatio = stretchRatio(modelGaps, answerGaps);
1466
- const stretched = Math.abs(timeRatio - 1) > _chunkXKSO2V5Icjs.BEAT_EPS;
1488
+ const stretched = Math.abs(timeRatio - 1) > _chunkS5BKZZGMcjs.BEAT_EPS;
1467
1489
  const shapes = pitchShapes(intervalsOf(model), intervalsOf(answer));
1468
1490
  const base = { sequence, semitones, interval, timeRatio };
1469
1491
  const backwardBase = { ...base, timeRatio: stretchRatio(retroGaps, answerGaps) };
@@ -1561,8 +1583,8 @@ function intervalCost(x, y) {
1561
1583
  return Math.min(1, Math.abs(x - y) / INTERVAL_TOLERANCE);
1562
1584
  }
1563
1585
  function gapCost(x, y) {
1564
- if (!(x > _chunkXKSO2V5Icjs.BEAT_EPS) || !(y > _chunkXKSO2V5Icjs.BEAT_EPS)) {
1565
- return Math.abs(x - y) > _chunkXKSO2V5Icjs.BEAT_EPS ? 1 : 0;
1586
+ if (!(x > _chunkS5BKZZGMcjs.BEAT_EPS) || !(y > _chunkS5BKZZGMcjs.BEAT_EPS)) {
1587
+ return Math.abs(x - y) > _chunkS5BKZZGMcjs.BEAT_EPS ? 1 : 0;
1566
1588
  }
1567
1589
  return Math.min(1, Math.abs(Math.log2(x / y)));
1568
1590
  }
@@ -1632,7 +1654,7 @@ var SIGNAL_ORDER = [
1632
1654
  "hypermeter"
1633
1655
  ];
1634
1656
  function addSignal(boundaries, beat, signal, strength, cadence = null) {
1635
- const key = Math.round(beat / _chunkXKSO2V5Icjs.BEAT_EPS);
1657
+ const key = Math.round(beat / _chunkS5BKZZGMcjs.BEAT_EPS);
1636
1658
  const existing = boundaries.get(key);
1637
1659
  const boundary = _nullishCoalesce(existing, () => ( { beat, strengths: /* @__PURE__ */ new Map(), cadence: null }));
1638
1660
  boundary.strengths.set(signal, Math.max(_nullishCoalesce(boundary.strengths.get(signal), () => ( 0)), strength));
@@ -1646,7 +1668,7 @@ function readBoundary(boundary) {
1646
1668
  (a, b) => b[1] - a[1] || SIGNAL_ORDER.indexOf(a[0]) - SIGNAL_ORDER.indexOf(b[0])
1647
1669
  );
1648
1670
  return {
1649
- strength: _chunkQ6R3QAZDcjs.combineEvidence.call(void 0, signals.map(([, strength]) => strength)),
1671
+ strength: _chunkSGLEQVJHcjs.combineEvidence.call(void 0, signals.map(([, strength]) => strength)),
1650
1672
  signals: signals.map(([signal]) => signal)
1651
1673
  };
1652
1674
  }
@@ -1667,7 +1689,7 @@ function choosePhrasePath(beats, strengths, minPhraseBeats, expected) {
1667
1689
  continue;
1668
1690
  }
1669
1691
  const length = endBeat - (_nullishCoalesce(beats[i], () => ( 0)));
1670
- if (length < minPhraseBeats - _chunkXKSO2V5Icjs.BEAT_EPS) {
1692
+ if (length < minPhraseBeats - _chunkS5BKZZGMcjs.BEAT_EPS) {
1671
1693
  continue;
1672
1694
  }
1673
1695
  const gain = (_nullishCoalesce(value[i], () => ( 0))) + (_nullishCoalesce(strengths[j], () => ( 0))) + lengthFit(length, expected) - PHRASE_CUT_COST;
@@ -1690,14 +1712,14 @@ function choosePhrasePath(beats, strengths, minPhraseBeats, expected) {
1690
1712
  return path;
1691
1713
  }
1692
1714
  function arrivalEnd(timeline, atBeat) {
1693
- return _nullishCoalesce(_optionalChain([_chunkQ6R3QAZDcjs.segmentStartingAt.call(void 0, timeline.segments, atBeat), 'optionalAccess', _93 => _93.endBeat]), () => ( atBeat));
1715
+ return _nullishCoalesce(_optionalChain([_chunkSGLEQVJHcjs.segmentStartingAt.call(void 0, timeline.segments, atBeat), 'optionalAccess', _93 => _93.endBeat]), () => ( atBeat));
1694
1716
  }
1695
1717
  function barSpanOf(startBeat, endBeat, meters) {
1696
- const firstBar = _chunkXKSO2V5Icjs.barIndexAt.call(void 0, startBeat, meters);
1697
- const lastBar = _chunkXKSO2V5Icjs.barIndexAt.call(void 0, endBeat, meters);
1718
+ const firstBar = _chunkS5BKZZGMcjs.barIndexAt.call(void 0, startBeat, meters);
1719
+ const lastBar = _chunkS5BKZZGMcjs.barIndexAt.call(void 0, endBeat, meters);
1698
1720
  const partOf = (beat, bar) => {
1699
- const barStart = _chunkXKSO2V5Icjs.barPositionToBeat.call(void 0, { bar, beat: 0 }, meters);
1700
- const barLength = _chunkXKSO2V5Icjs.beatsPerBarAt.call(void 0, barStart, meters);
1721
+ const barStart = _chunkS5BKZZGMcjs.barPositionToBeat.call(void 0, { bar, beat: 0 }, meters);
1722
+ const barLength = _chunkS5BKZZGMcjs.beatsPerBarAt.call(void 0, barStart, meters);
1701
1723
  return barLength > 0 ? (beat - barStart) / barLength : 0;
1702
1724
  };
1703
1725
  const bars = lastBar - firstBar + partOf(endBeat, lastBar) - partOf(startBeat, firstBar);
@@ -1707,26 +1729,26 @@ function keyContextFor(opts, notes, meters, totalBeats) {
1707
1729
  if (opts.key !== void 0) {
1708
1730
  return opts.key;
1709
1731
  }
1710
- const regions = _chunkQ6R3QAZDcjs.keyTimelineFromNotes.call(void 0, notes, {
1732
+ const regions = _chunkSGLEQVJHcjs.keyTimelineFromNotes.call(void 0, notes, {
1711
1733
  meters,
1712
1734
  totalBeats,
1713
1735
  budget: opts.budget
1714
1736
  });
1715
- const keyAt = _chunkQ6R3QAZDcjs.keyLookup.call(void 0, regions, _nullishCoalesce(_chunkQ6R3QAZDcjs.prevailingKeyOf.call(void 0, regions), () => ( _chunkYPB3A3EYcjs.resolveKey.call(void 0, _chunkYPB3A3EYcjs.majorKey.call(void 0, 0)))));
1716
- return (beat) => _chunkYPB3A3EYcjs.scaleOf.call(void 0, keyAt(beat));
1737
+ const keyAt = _chunkSGLEQVJHcjs.keyLookup.call(void 0, regions, _nullishCoalesce(_chunkSGLEQVJHcjs.prevailingKeyOf.call(void 0, regions), () => ( _chunk3R3QVKY5cjs.resolveKey.call(void 0, _chunk3R3QVKY5cjs.majorKey.call(void 0, 0)))));
1738
+ return (beat) => _chunk3R3QVKY5cjs.scaleOf.call(void 0, keyAt(beat));
1717
1739
  }
1718
1740
  function restBoundaries(boundaries, notes, meters, restBeats) {
1719
1741
  const ordered = [...notes].sort((a, b) => a.startBeat - b.startBeat || a.pitch - b.pitch);
1720
1742
  let covered = Number.NEGATIVE_INFINITY;
1721
1743
  for (const note of ordered) {
1722
1744
  const gap = note.startBeat - covered;
1723
- if (Number.isFinite(covered) && gap >= restBeats - _chunkXKSO2V5Icjs.BEAT_EPS) {
1724
- const bar = _chunkXKSO2V5Icjs.beatsPerBarAt.call(void 0, note.startBeat, meters);
1745
+ if (Number.isFinite(covered) && gap >= restBeats - _chunkS5BKZZGMcjs.BEAT_EPS) {
1746
+ const bar = _chunkS5BKZZGMcjs.beatsPerBarAt.call(void 0, note.startBeat, meters);
1725
1747
  addSignal(
1726
1748
  boundaries,
1727
1749
  note.startBeat,
1728
1750
  "rest",
1729
- REST_STRENGTH * _chunkQ6R3QAZDcjs.clamp01.call(void 0, bar > 0 ? gap / bar : 1)
1751
+ REST_STRENGTH * _chunkSGLEQVJHcjs.clamp01.call(void 0, bar > 0 ? gap / bar : 1)
1730
1752
  );
1731
1753
  }
1732
1754
  covered = Math.max(covered, note.startBeat + note.durationBeat);
@@ -1736,13 +1758,13 @@ function repetitionBoundaries(boundaries, notes, meters, spanStart, spanEnd, win
1736
1758
  if (!(windowBeats > 0)) {
1737
1759
  return;
1738
1760
  }
1739
- const slices = _chunkQ6R3QAZDcjs.sliceBars.call(void 0, notes, meters, spanStart, spanEnd, budget);
1740
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, slices.length * notes.length, "form repetition comparisons", budget);
1741
- const onsetsIn = (from, to) => notes.filter((note) => note.startBeat >= from - _chunkXKSO2V5Icjs.BEAT_EPS && note.startBeat < to - _chunkXKSO2V5Icjs.BEAT_EPS);
1761
+ const slices = _chunkSGLEQVJHcjs.sliceBars.call(void 0, notes, meters, spanStart, spanEnd, budget);
1762
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, slices.length * notes.length, "form repetition comparisons", budget);
1763
+ const onsetsIn = (from, to) => notes.filter((note) => note.startBeat >= from - _chunkS5BKZZGMcjs.BEAT_EPS && note.startBeat < to - _chunkS5BKZZGMcjs.BEAT_EPS);
1742
1764
  let comparisons = 0;
1743
1765
  for (const slice of slices) {
1744
1766
  const beat = slice.startBeat;
1745
- if (beat - windowBeats < spanStart - _chunkXKSO2V5Icjs.BEAT_EPS || beat + windowBeats > spanEnd + _chunkXKSO2V5Icjs.BEAT_EPS) {
1767
+ if (beat - windowBeats < spanStart - _chunkS5BKZZGMcjs.BEAT_EPS || beat + windowBeats > spanEnd + _chunkS5BKZZGMcjs.BEAT_EPS) {
1746
1768
  continue;
1747
1769
  }
1748
1770
  const before = onsetsIn(beat - windowBeats, beat);
@@ -1751,7 +1773,7 @@ function repetitionBoundaries(boundaries, notes, meters, spanStart, spanEnd, win
1751
1773
  continue;
1752
1774
  }
1753
1775
  comparisons += before.length * after.length;
1754
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, comparisons, "form repetition melody comparisons", budget);
1776
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, comparisons, "form repetition melody comparisons", budget);
1755
1777
  const similarity = melodicSimilarity(before, after);
1756
1778
  if (similarity >= REPETITION_THRESHOLD) {
1757
1779
  addSignal(boundaries, beat, "repetition", REPETITION_STRENGTH * similarity);
@@ -1781,7 +1803,7 @@ function structuralWeightOf(cadence, confidence, aligned, isLast) {
1781
1803
  if (aligned) {
1782
1804
  weight += HYPERMETRIC_CLOSE_BONUS;
1783
1805
  }
1784
- return _chunkQ6R3QAZDcjs.clamp01.call(void 0, weight);
1806
+ return _chunkSGLEQVJHcjs.clamp01.call(void 0, weight);
1785
1807
  }
1786
1808
  function describeCadence(cadence) {
1787
1809
  if (cadence === null || cadence.cadence.type === null) {
@@ -1792,15 +1814,15 @@ function describeCadence(cadence) {
1792
1814
  return `a ${graded} cadence at beat ${cadence.atBeat}`;
1793
1815
  }
1794
1816
  function phrasesFromTimeline(timeline, notes, opts = {}) {
1795
- _chunkQ6R3QAZDcjs.assertChordTimeline.call(void 0, timeline);
1796
- const meters = _chunkXKSO2V5Icjs.resolveMeters.call(void 0, opts, "phrase meters");
1797
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, notes, "phrase notes", {
1817
+ _chunkSGLEQVJHcjs.assertChordTimeline.call(void 0, timeline);
1818
+ const meters = _chunkS5BKZZGMcjs.resolveMeters.call(void 0, opts, "phrase meters");
1819
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, notes, "phrase notes", {
1798
1820
  allowNonPositiveDuration: true,
1799
1821
  budget: opts.budget
1800
1822
  });
1801
1823
  if (opts.hypermeter !== void 0) {
1802
- _chunkXKSO2V5Icjs.assertRange.call(void 0, opts.hypermeter.confidence, 0, 1, "phrase hypermeter confidence");
1803
- _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, opts.hypermeter.groupBars, "phrase hypermeter groupBars");
1824
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, opts.hypermeter.confidence, 0, 1, "phrase hypermeter confidence");
1825
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, opts.hypermeter.groupBars, "phrase hypermeter groupBars");
1804
1826
  }
1805
1827
  const sounding = notes.filter((note) => note.durationBeat > 0);
1806
1828
  const segments = timeline.segments;
@@ -1810,37 +1832,37 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
1810
1832
  (first, n) => Math.min(first, n.startBeat),
1811
1833
  _nullishCoalesce(_optionalChain([firstSegment, 'optionalAccess', _94 => _94.startBeat]), () => ( 0))
1812
1834
  );
1813
- const spanStart = _chunkQ6R3QAZDcjs.barGridStart.call(void 0, firstOnset, meters);
1835
+ const spanStart = _chunkSGLEQVJHcjs.barGridStart.call(void 0, firstOnset, meters);
1814
1836
  const notesEnd = sounding.reduce(
1815
1837
  (end, n) => Math.max(end, n.startBeat + n.durationBeat),
1816
1838
  _nullishCoalesce(_optionalChain([lastSegment, 'optionalAccess', _95 => _95.endBeat]), () => ( 0))
1817
1839
  );
1818
1840
  const spanEnd = Math.max(spanStart, _nullishCoalesce(opts.totalBeats, () => ( notesEnd)));
1819
- _chunkXKSO2V5Icjs.assertRange.call(void 0, spanEnd, 0, Number.MAX_SAFE_INTEGER, "phrase totalBeats");
1820
- if (spanEnd <= spanStart + _chunkXKSO2V5Icjs.BEAT_EPS) {
1841
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, spanEnd, 0, Number.MAX_SAFE_INTEGER, "phrase totalBeats");
1842
+ if (spanEnd <= spanStart + _chunkS5BKZZGMcjs.BEAT_EPS) {
1821
1843
  return [];
1822
1844
  }
1823
- const barBeats = _chunkXKSO2V5Icjs.beatsPerBarAt.call(void 0, Math.max(0, spanStart), meters);
1845
+ const barBeats = _chunkS5BKZZGMcjs.beatsPerBarAt.call(void 0, Math.max(0, spanStart), meters);
1824
1846
  const restBeats = _nullishCoalesce(opts.restBeats, () => ( barBeats / 2));
1825
- _chunkXKSO2V5Icjs.assertRange.call(void 0, restBeats, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase restBeats");
1847
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, restBeats, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase restBeats");
1826
1848
  const longNoteBeats = _nullishCoalesce(opts.longNoteBeats, () => ( barBeats));
1827
- _chunkXKSO2V5Icjs.assertRange.call(void 0, longNoteBeats, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase longNoteBeats");
1849
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, longNoteBeats, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase longNoteBeats");
1828
1850
  const minPhraseBeats = _nullishCoalesce(opts.minPhraseBeats, () => ( barBeats));
1829
- _chunkXKSO2V5Icjs.assertRange.call(void 0, minPhraseBeats, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase minPhraseBeats");
1851
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, minPhraseBeats, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase minPhraseBeats");
1830
1852
  const key = keyContextFor(opts, sounding, meters, spanEnd);
1831
- const cadences = _chunkQ6R3QAZDcjs.detectCadences.call(void 0, timeline, key);
1853
+ const cadences = _chunkSGLEQVJHcjs.detectCadences.call(void 0, timeline, key);
1832
1854
  const grouping = _nullishCoalesce(opts.hypermeter, () => ( hypermeter(sounding, meters, {
1833
1855
  totalBeats: spanEnd,
1834
1856
  cadenceBeats: cadences.map((hit) => hit.atBeat),
1835
1857
  budget: opts.budget
1836
1858
  })));
1837
- const firstBar = _chunkXKSO2V5Icjs.barIndexAt.call(void 0, Math.max(0, spanStart), meters);
1859
+ const firstBar = _chunkS5BKZZGMcjs.barIndexAt.call(void 0, Math.max(0, spanStart), meters);
1838
1860
  const hyperBeats = Math.max(
1839
1861
  barBeats,
1840
- _chunkXKSO2V5Icjs.barPositionToBeat.call(void 0, { bar: firstBar + grouping.groupBars, beat: 0 }, meters) - _chunkXKSO2V5Icjs.barPositionToBeat.call(void 0, { bar: firstBar, beat: 0 }, meters)
1862
+ _chunkS5BKZZGMcjs.barPositionToBeat.call(void 0, { bar: firstBar + grouping.groupBars, beat: 0 }, meters) - _chunkS5BKZZGMcjs.barPositionToBeat.call(void 0, { bar: firstBar, beat: 0 }, meters)
1841
1863
  );
1842
1864
  const expected = _nullishCoalesce(opts.expectedPhraseBeats, () => ( hyperBeats));
1843
- _chunkXKSO2V5Icjs.assertRange.call(void 0, expected, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase expectedPhraseBeats");
1865
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, expected, Number.MIN_VALUE, Number.MAX_SAFE_INTEGER, "phrase expectedPhraseBeats");
1844
1866
  const boundaries = /* @__PURE__ */ new Map();
1845
1867
  for (const hit of cadences) {
1846
1868
  const type = hit.cadence.type;
@@ -1850,14 +1872,14 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
1850
1872
  const strength = CADENCE_BOUNDARY_STRENGTH[type];
1851
1873
  const chordEnd = arrivalEnd(timeline, hit.atBeat);
1852
1874
  addSignal(boundaries, chordEnd, "cadence", strength, hit);
1853
- const barEnd = _chunkXKSO2V5Icjs.barPositionToBeat.call(void 0, { bar: _chunkXKSO2V5Icjs.barIndexAt.call(void 0, hit.atBeat, meters) + 1, beat: 0 }, meters);
1854
- if (chordEnd > barEnd + _chunkXKSO2V5Icjs.BEAT_EPS) {
1875
+ const barEnd = _chunkS5BKZZGMcjs.barPositionToBeat.call(void 0, { bar: _chunkS5BKZZGMcjs.barIndexAt.call(void 0, hit.atBeat, meters) + 1, beat: 0 }, meters);
1876
+ if (chordEnd > barEnd + _chunkS5BKZZGMcjs.BEAT_EPS) {
1855
1877
  addSignal(boundaries, barEnd, "cadence", strength, hit);
1856
1878
  }
1857
1879
  }
1858
1880
  restBoundaries(boundaries, sounding, meters, restBeats);
1859
1881
  for (const note of sounding) {
1860
- if (note.durationBeat >= longNoteBeats - _chunkXKSO2V5Icjs.BEAT_EPS) {
1882
+ if (note.durationBeat >= longNoteBeats - _chunkS5BKZZGMcjs.BEAT_EPS) {
1861
1883
  addSignal(boundaries, note.startBeat + note.durationBeat, "longNote", LONG_NOTE_STRENGTH);
1862
1884
  }
1863
1885
  }
@@ -1867,9 +1889,9 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
1867
1889
  }
1868
1890
  addSignal(boundaries, spanEnd, "pieceEnd", PIECE_END_STRENGTH);
1869
1891
  const candidates = [...boundaries.values()].filter(
1870
- (boundary) => boundary.beat > spanStart + _chunkXKSO2V5Icjs.BEAT_EPS && boundary.beat < spanEnd - _chunkXKSO2V5Icjs.BEAT_EPS
1892
+ (boundary) => boundary.beat > spanStart + _chunkS5BKZZGMcjs.BEAT_EPS && boundary.beat < spanEnd - _chunkS5BKZZGMcjs.BEAT_EPS
1871
1893
  ).filter((boundary) => readBoundary(boundary).strength > 0).sort((a, b) => a.beat - b.beat);
1872
- const endBoundary = _nullishCoalesce(boundaries.get(Math.round(spanEnd / _chunkXKSO2V5Icjs.BEAT_EPS)), () => ( {
1894
+ const endBoundary = _nullishCoalesce(boundaries.get(Math.round(spanEnd / _chunkS5BKZZGMcjs.BEAT_EPS)), () => ( {
1873
1895
  beat: spanEnd,
1874
1896
  strengths: /* @__PURE__ */ new Map(),
1875
1897
  cadence: null
@@ -1879,7 +1901,7 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
1879
1901
  ...candidates,
1880
1902
  endBoundary
1881
1903
  ];
1882
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, stops.length * stops.length, "form phrase boundary pairs", opts.budget);
1904
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, stops.length * stops.length, "form phrase boundary pairs", opts.budget);
1883
1905
  const readings = stops.map(readBoundary);
1884
1906
  const path = choosePhrasePath(
1885
1907
  stops.map((stop) => stop.beat),
@@ -1888,7 +1910,7 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
1888
1910
  expected
1889
1911
  );
1890
1912
  const downbeatKeys = new Set(
1891
- grouping.downbeats.map((downbeat) => Math.round(downbeat / _chunkXKSO2V5Icjs.BEAT_EPS))
1913
+ grouping.downbeats.map((downbeat) => Math.round(downbeat / _chunkS5BKZZGMcjs.BEAT_EPS))
1892
1914
  );
1893
1915
  const phrases = [];
1894
1916
  let from = 0;
@@ -1899,16 +1921,16 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
1899
1921
  const endBeat = _nullishCoalesce(_optionalChain([stop, 'optionalAccess', _98 => _98.beat]), () => ( spanEnd));
1900
1922
  const reading = _nullishCoalesce(readings[to], () => ( { strength: 0, signals: [] }));
1901
1923
  const length = endBeat - startBeat;
1902
- const confidence = _chunkQ6R3QAZDcjs.clamp01.call(void 0,
1924
+ const confidence = _chunkSGLEQVJHcjs.clamp01.call(void 0,
1903
1925
  CLOSING_SHARE * reading.strength + (1 - CLOSING_SHARE) * Math.max(0, lengthFit(length, expected))
1904
1926
  );
1905
1927
  const isLast = n === path.length - 1;
1906
1928
  const closing = _nullishCoalesce(_optionalChain([stop, 'optionalAccess', _99 => _99.cadence]), () => ( null));
1907
- const cadence = closing !== null && closing.atBeat >= startBeat - _chunkXKSO2V5Icjs.BEAT_EPS && closing.atBeat < endBeat - _chunkXKSO2V5Icjs.BEAT_EPS ? closing : null;
1929
+ const cadence = closing !== null && closing.atBeat >= startBeat - _chunkS5BKZZGMcjs.BEAT_EPS && closing.atBeat < endBeat - _chunkS5BKZZGMcjs.BEAT_EPS ? closing : null;
1908
1930
  const structuralWeight = structuralWeightOf(
1909
1931
  cadence,
1910
1932
  confidence,
1911
- downbeatKeys.has(Math.round(endBeat / _chunkXKSO2V5Icjs.BEAT_EPS)),
1933
+ downbeatKeys.has(Math.round(endBeat / _chunkS5BKZZGMcjs.BEAT_EPS)),
1912
1934
  isLast
1913
1935
  );
1914
1936
  const signals = cadence === null ? reading.signals.filter((signal) => signal !== "cadence") : reading.signals;
@@ -1927,10 +1949,10 @@ function phrasesFromTimeline(timeline, notes, opts = {}) {
1927
1949
  return phrases;
1928
1950
  }
1929
1951
  function structuralCadences(phrases) {
1930
- _chunkXKSO2V5Icjs.assertArray.call(void 0, phrases, "phrases");
1952
+ _chunkS5BKZZGMcjs.assertArray.call(void 0, phrases, "phrases");
1931
1953
  const ranked = [];
1932
1954
  for (let index = 0; index < phrases.length; index += 1) {
1933
- const phrase = _chunkXKSO2V5Icjs.assertRecord.call(void 0, phrases[index], `phrases[${index}]`);
1955
+ const phrase = _chunkS5BKZZGMcjs.assertRecord.call(void 0, phrases[index], `phrases[${index}]`);
1934
1956
  if (phrase.cadence === null || phrase.cadence === void 0 || phrase.cadence.cadence.type === null) {
1935
1957
  continue;
1936
1958
  }
@@ -1964,16 +1986,16 @@ function isSilent(unit) {
1964
1986
  return unit.notes.length === 0;
1965
1987
  }
1966
1988
  function unitSimilarity(a, b) {
1967
- const harmony = _chunkQ6R3QAZDcjs.weightSimilarity.call(void 0, a.weights, b.weights);
1989
+ const harmony = _chunkSGLEQVJHcjs.weightSimilarity.call(void 0, a.weights, b.weights);
1968
1990
  if (a.notes.length < 2 || b.notes.length < 2) {
1969
1991
  return a.notes.length === b.notes.length ? harmony : 0;
1970
1992
  }
1971
1993
  const melody = melodicSimilarity(a.notes, b.notes);
1972
- return _chunkQ6R3QAZDcjs.clamp01.call(void 0, MELODY_SHARE * melody + HARMONY_SHARE * harmony);
1994
+ return _chunkSGLEQVJHcjs.clamp01.call(void 0, MELODY_SHARE * melody + HARMONY_SHARE * harmony);
1973
1995
  }
1974
1996
  function sectionsFromNotes(notes, opts = {}) {
1975
- const meters = _chunkXKSO2V5Icjs.resolveMeters.call(void 0, opts, "section meters");
1976
- _chunkXKSO2V5Icjs.assertNoteEvents.call(void 0, notes, "section notes", {
1997
+ const meters = _chunkS5BKZZGMcjs.resolveMeters.call(void 0, opts, "section meters");
1998
+ _chunkS5BKZZGMcjs.assertNoteEvents.call(void 0, notes, "section notes", {
1977
1999
  allowNonPositiveDuration: true,
1978
2000
  budget: opts.budget
1979
2001
  });
@@ -1981,33 +2003,33 @@ function sectionsFromNotes(notes, opts = {}) {
1981
2003
  if (sounding.length === 0) {
1982
2004
  return [];
1983
2005
  }
1984
- const firstOnset = _chunkQ6R3QAZDcjs.barGridStart.call(void 0, _chunkQ6R3QAZDcjs.firstSoundingBeat.call(void 0, sounding), meters);
2006
+ const firstOnset = _chunkSGLEQVJHcjs.barGridStart.call(void 0, _chunkSGLEQVJHcjs.firstSoundingBeat.call(void 0, sounding), meters);
1985
2007
  const lastEnd = sounding.reduce((end, n) => Math.max(end, n.startBeat + n.durationBeat), 0);
1986
2008
  const spanEnd = Math.max(firstOnset, _nullishCoalesce(opts.totalBeats, () => ( lastEnd)));
1987
- _chunkXKSO2V5Icjs.assertRange.call(void 0, spanEnd, 0, Number.MAX_SAFE_INTEGER, "section totalBeats");
2009
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, spanEnd, 0, Number.MAX_SAFE_INTEGER, "section totalBeats");
1988
2010
  const threshold = _nullishCoalesce(opts.threshold, () => ( DEFAULT_THRESHOLD));
1989
- _chunkXKSO2V5Icjs.assertRange.call(void 0, threshold, 0, 1, "section threshold");
2011
+ _chunkS5BKZZGMcjs.assertRange.call(void 0, threshold, 0, 1, "section threshold");
1990
2012
  const unitBars = _nullishCoalesce(opts.unitBars, () => ( hypermeter(sounding, meters, { totalBeats: spanEnd, budget: opts.budget }).groupBars));
1991
- _chunkXKSO2V5Icjs.assertPositiveInt.call(void 0, unitBars, "section unitBars");
1992
- const firstBar = _chunkXKSO2V5Icjs.barIndexAt.call(void 0, firstOnset, meters);
1993
- const lastBar = _chunkQ6R3QAZDcjs.lastBarOf.call(void 0, meters, firstOnset, spanEnd);
2013
+ _chunkS5BKZZGMcjs.assertPositiveInt.call(void 0, unitBars, "section unitBars");
2014
+ const firstBar = _chunkS5BKZZGMcjs.barIndexAt.call(void 0, firstOnset, meters);
2015
+ const lastBar = _chunkSGLEQVJHcjs.lastBarOf.call(void 0, meters, firstOnset, spanEnd);
1994
2016
  const startBar = Math.max(0, firstBar);
1995
2017
  const unitCount = Math.max(1, Math.ceil((lastBar - startBar + 1) / unitBars));
1996
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, unitCount * unitCount, "form section comparisons", opts.budget);
1997
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, unitCount * sounding.length, "form section unit notes", opts.budget);
2018
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, unitCount * unitCount, "form section comparisons", opts.budget);
2019
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, unitCount * sounding.length, "form section unit notes", opts.budget);
1998
2020
  const units = [];
1999
2021
  for (let index = 0; index < unitCount; index += 1) {
2000
2022
  const barStart = startBar + index * unitBars;
2001
- const startBeat = index === 0 ? firstOnset : _chunkXKSO2V5Icjs.barPositionToBeat.call(void 0, { bar: barStart, beat: 0 }, meters);
2002
- const endBeat = index === unitCount - 1 ? spanEnd : _chunkXKSO2V5Icjs.barPositionToBeat.call(void 0, { bar: barStart + unitBars, beat: 0 }, meters);
2023
+ const startBeat = index === 0 ? firstOnset : _chunkS5BKZZGMcjs.barPositionToBeat.call(void 0, { bar: barStart, beat: 0 }, meters);
2024
+ const endBeat = index === unitCount - 1 ? spanEnd : _chunkS5BKZZGMcjs.barPositionToBeat.call(void 0, { bar: barStart + unitBars, beat: 0 }, meters);
2003
2025
  const unitNotes = sounding.filter(
2004
- (note) => note.startBeat >= startBeat - _chunkXKSO2V5Icjs.BEAT_EPS && note.startBeat < endBeat - _chunkXKSO2V5Icjs.BEAT_EPS
2026
+ (note) => note.startBeat >= startBeat - _chunkS5BKZZGMcjs.BEAT_EPS && note.startBeat < endBeat - _chunkS5BKZZGMcjs.BEAT_EPS
2005
2027
  ).sort((a, b) => a.startBeat - b.startBeat || a.pitch - b.pitch);
2006
2028
  units.push({
2007
2029
  startBeat,
2008
2030
  endBeat,
2009
2031
  notes: unitNotes,
2010
- weights: _chunkQ6R3QAZDcjs.windowWeights.call(void 0, unitNotes, startBeat, endBeat, meters).weights
2032
+ weights: _chunkSGLEQVJHcjs.windowWeights.call(void 0, unitNotes, startBeat, endBeat, meters).weights
2011
2033
  });
2012
2034
  }
2013
2035
  let comparisons = 0;
@@ -2016,7 +2038,7 @@ function sectionsFromNotes(notes, opts = {}) {
2016
2038
  comparisons += unit.notes.length * earlierNotes;
2017
2039
  earlierNotes += unit.notes.length;
2018
2040
  }
2019
- _chunkXKSO2V5Icjs.assertGenerationBudget.call(void 0, comparisons, "form section melody comparisons", opts.budget);
2041
+ _chunkS5BKZZGMcjs.assertGenerationBudget.call(void 0, comparisons, "form section melody comparisons", opts.budget);
2020
2042
  const labels = [];
2021
2043
  const scores = [];
2022
2044
  let distinct = 0;
@@ -2083,7 +2105,7 @@ function sectionsFromNotes(notes, opts = {}) {
2083
2105
  if (first === void 0) {
2084
2106
  firstByLabel.set(label, sectionIndex);
2085
2107
  }
2086
- const similarity = first === void 0 ? 1 : _chunkQ6R3QAZDcjs.clamp01.call(void 0, scoreSum / Math.max(1, sounded));
2108
+ const similarity = first === void 0 ? 1 : _chunkSGLEQVJHcjs.clamp01.call(void 0, scoreSum / Math.max(1, sounded));
2087
2109
  sections.push({
2088
2110
  label,
2089
2111
  startBeat,
@@ -2101,14 +2123,14 @@ function sectionsFromNotes(notes, opts = {}) {
2101
2123
  // src/analyze/reduction/index.ts
2102
2124
  var TONIC_ARRIVING = /* @__PURE__ */ new Set(["authentic", "plagal", "modal", "deceptive"]);
2103
2125
  function signedStep(fromPc, toPc) {
2104
- return (_chunkXKSO2V5Icjs.pitchClassOf.call(void 0, toPc) - _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, fromPc) + 18) % 12 - 6;
2126
+ return (_chunkS5BKZZGMcjs.pitchClassOf.call(void 0, toPc) - _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, fromPc) + 18) % 12 - 6;
2105
2127
  }
2106
2128
  function isStep(distance) {
2107
2129
  const size = Math.abs(distance);
2108
2130
  return size === 1 || size === 2;
2109
2131
  }
2110
2132
  function touches(before, after) {
2111
- return Math.abs(after.startBeat - before.endBeat) <= _chunkXKSO2V5Icjs.BEAT_EPS;
2133
+ return Math.abs(after.startBeat - before.endBeat) <= _chunkS5BKZZGMcjs.BEAT_EPS;
2112
2134
  }
2113
2135
  function salienceFloors(durations) {
2114
2136
  const order = durations.map((_, index) => index).sort((a, b) => {
@@ -2135,27 +2157,27 @@ function salienceFloors(durations) {
2135
2157
  return floors;
2136
2158
  }
2137
2159
  function isTonicChord(chord, key) {
2138
- return _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, chord.rootPc - key.rootPc) === 0 && !_chunkQ6R3QAZDcjs.isAppliedDominant.call(void 0, chord, key);
2160
+ return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, chord.rootPc - key.rootPc) === 0 && !_chunkSGLEQVJHcjs.isAppliedDominant.call(void 0, chord, key);
2139
2161
  }
2140
2162
  function functionalReason(segment, before, after, keyAt) {
2141
2163
  const key = keyAt(segment.startBeat);
2142
- if (after !== void 0 && _chunkQ6R3QAZDcjs.isCadentialSixFour.call(void 0, segment.chord, after.chord, key)) {
2164
+ if (after !== void 0 && _chunkSGLEQVJHcjs.isCadentialSixFour.call(void 0, segment.chord, after.chord, key)) {
2143
2165
  return { kind: "cadentialSixFour" };
2144
2166
  }
2145
2167
  if (isTonicChord(segment.chord, key)) {
2146
2168
  return { kind: "tonic" };
2147
2169
  }
2148
- if (_chunkYPB3A3EYcjs.isDominantChordOf.call(void 0, segment.chord, key)) {
2170
+ if (_chunk3R3QVKY5cjs.isDominantChordOf.call(void 0, segment.chord, key)) {
2149
2171
  return { kind: "dominant" };
2150
2172
  }
2151
2173
  if (before !== void 0) {
2152
- const arrival = _chunkQ6R3QAZDcjs.detectCadence.call(void 0, before.chord, segment.chord, key).type;
2174
+ const arrival = _chunkSGLEQVJHcjs.detectCadence.call(void 0, before.chord, segment.chord, key).type;
2153
2175
  if (arrival !== null) {
2154
2176
  return { kind: "cadenceArrival", cadence: arrival };
2155
2177
  }
2156
2178
  }
2157
2179
  if (after !== void 0) {
2158
- const agent = _chunkQ6R3QAZDcjs.detectCadence.call(void 0, segment.chord, after.chord, keyAt(after.startBeat)).type;
2180
+ const agent = _chunkSGLEQVJHcjs.detectCadence.call(void 0, segment.chord, after.chord, keyAt(after.startBeat)).type;
2159
2181
  if (agent !== null && TONIC_ARRIVING.has(agent)) {
2160
2182
  return { kind: "cadenceAgent", cadence: agent };
2161
2183
  }
@@ -2174,7 +2196,7 @@ function figureReason(segment, before, after) {
2174
2196
  if (incoming > 0 === outgoing > 0) {
2175
2197
  return { kind: "passing" };
2176
2198
  }
2177
- return _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, before.chord.rootPc) === _chunkXKSO2V5Icjs.pitchClassOf.call(void 0, after.chord.rootPc) ? { kind: "neighbor" } : null;
2199
+ return _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, before.chord.rootPc) === _chunkS5BKZZGMcjs.pitchClassOf.call(void 0, after.chord.rootPc) ? { kind: "neighbor" } : null;
2178
2200
  }
2179
2201
  function describe(reason) {
2180
2202
  switch (reason.kind) {
@@ -2214,10 +2236,10 @@ function levelOf(reason) {
2214
2236
  return reason.kind === "neighbor" ? "neighbor" : "structural";
2215
2237
  }
2216
2238
  function reduceProgression(timeline, key, opts = {}) {
2217
- _chunkQ6R3QAZDcjs.assertChordTimeline.call(void 0, timeline);
2218
- const asked = _chunkXKSO2V5Icjs.assertOptions.call(void 0, opts, "opts");
2219
- const keyAt = _chunkQ6R3QAZDcjs.keyScaleAt.call(void 0, key);
2220
- const basis = _chunkXKSO2V5Icjs.assertOneOf.call(void 0, _nullishCoalesce(asked.basis, () => ( "function")), REDUCTION_BASES, "reduction basis");
2239
+ _chunkSGLEQVJHcjs.assertChordTimeline.call(void 0, timeline);
2240
+ const asked = _chunkS5BKZZGMcjs.assertOptions.call(void 0, opts, "opts");
2241
+ const keyAt = _chunkSGLEQVJHcjs.keyScaleAt.call(void 0, key);
2242
+ const basis = _chunkS5BKZZGMcjs.assertOneOf.call(void 0, _nullishCoalesce(asked.basis, () => ( "function")), REDUCTION_BASES, "reduction basis");
2221
2243
  const reading = BASIS_READINGS[basis];
2222
2244
  const segments = timeline.segments;
2223
2245
  const floors = basis === "duration" ? salienceFloors(segments.map((segment) => segment.endBeat - segment.startBeat)) : [];
@@ -2269,4 +2291,4 @@ function reduceProgression(timeline, key, opts = {}) {
2269
2291
 
2270
2292
 
2271
2293
  exports.trackRoleOf = trackRoleOf; exports.analyzePolyphony = analyzePolyphony; exports.analyzeArrangement = analyzeArrangement; exports.createArrangementSession = createArrangementSession; exports.tensionCurve = tensionCurve; exports.tensionCurveFrom = tensionCurveFrom; exports.hypermeter = hypermeter; exports.melodicContour = melodicContour; exports.extractMotifs = extractMotifs; exports.motifFromNotes = motifFromNotes; exports.relateMotifs = relateMotifs; exports.compareMelodies = compareMelodies; exports.melodicSimilarity = melodicSimilarity; exports.phrasesFromTimeline = phrasesFromTimeline; exports.structuralCadences = structuralCadences; exports.sectionsFromNotes = sectionsFromNotes; exports.reduceProgression = reduceProgression;
2272
- //# sourceMappingURL=chunk-XVMJO3QF.cjs.map
2294
+ //# sourceMappingURL=chunk-HPVSH7SF.cjs.map