@tspro/web-music-score 4.0.1 → 4.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 (34) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +70 -28
  3. package/dist/audio/index.js +1 -1
  4. package/dist/audio/index.mjs +2 -2
  5. package/dist/audio-cg/index.js +1 -1
  6. package/dist/audio-cg/index.mjs +2 -2
  7. package/dist/{chunk-YFPLOHP2.mjs → chunk-5NWLGWHS.mjs} +2 -2
  8. package/dist/chunk-7MNV5JN6.mjs +264 -0
  9. package/dist/core/index.js +2 -2
  10. package/dist/core/index.mjs +3 -3
  11. package/dist/iife/index.global.js +11 -11
  12. package/dist/{music-objects-DJQ4d2OA.d.mts → music-objects-3Hxlkxy6.d.mts} +172 -80
  13. package/dist/{music-objects-Dc3kR-XF.d.ts → music-objects-CI7IjsjE.d.ts} +172 -80
  14. package/dist/pieces/index.d.mts +2 -2
  15. package/dist/pieces/index.d.ts +2 -2
  16. package/dist/pieces/index.js +3 -3
  17. package/dist/pieces/index.mjs +4 -4
  18. package/dist/react-ui/index.d.mts +3 -3
  19. package/dist/react-ui/index.d.ts +3 -3
  20. package/dist/react-ui/index.js +1 -1
  21. package/dist/react-ui/index.mjs +2 -2
  22. package/dist/{scale-B2Icbetz.d.ts → scale-DGx3tJH4.d.ts} +1 -1
  23. package/dist/{scale-BbDJTbrG.d.mts → scale-DQP3b9Zx.d.mts} +1 -1
  24. package/dist/score/index.d.mts +60 -23
  25. package/dist/score/index.d.ts +60 -23
  26. package/dist/score/index.js +910 -349
  27. package/dist/score/index.mjs +630 -320
  28. package/dist/{tempo-Dt8aHpol.d.ts → tempo-GrstpD9G.d.ts} +42 -10
  29. package/dist/{tempo-CtUhvJbr.d.mts → tempo-dkctPkCS.d.mts} +42 -10
  30. package/dist/theory/index.d.mts +3 -3
  31. package/dist/theory/index.d.ts +3 -3
  32. package/dist/theory/index.js +70 -20
  33. package/dist/theory/index.mjs +84 -280
  34. package/package.json +8 -3
@@ -1,4 +1,4 @@
1
- /* WebMusicScore v4.0.1 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v4.2.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
2
  "use strict";
3
3
  var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
@@ -42,6 +42,8 @@ __export(score_exports, {
42
42
  DynamicsAnnotation: () => DynamicsAnnotation,
43
43
  Fermata: () => Fermata,
44
44
  Label: () => Label,
45
+ LyricsAlign: () => LyricsAlign,
46
+ LyricsHyphen: () => LyricsHyphen,
45
47
  MAccidental: () => MAccidental,
46
48
  MArpeggio: () => MArpeggio,
47
49
  MBarLineLeft: () => MBarLineLeft,
@@ -54,6 +56,7 @@ __export(score_exports, {
54
56
  MFermata: () => MFermata,
55
57
  MHeader: () => MHeader,
56
58
  MImage: () => MImage,
59
+ MLyrics: () => MLyrics,
57
60
  MMeasure: () => MMeasure,
58
61
  MNoteGroup: () => MNoteGroup,
59
62
  MPlaybackButtons: () => MPlaybackButtons,
@@ -85,6 +88,7 @@ __export(score_exports, {
85
88
  TieType: () => TieType,
86
89
  VerticalPosition: () => VerticalPosition,
87
90
  getStringNumbers: () => getStringNumbers,
91
+ getVerseNumbers: () => getVerseNumbers,
88
92
  getVoiceIds: () => getVoiceIds
89
93
  });
90
94
  module.exports = __toCommonJS(score_exports);
@@ -124,11 +128,11 @@ var DivRect = class _DivRect {
124
128
  /**
125
129
  * Create rect from basic left, top, width and height arguments.
126
130
  *
127
- * @param left -
128
- * @param top -
129
- * @param width -
130
- * @param height -
131
- * @returns
131
+ * @param left - Left coordinate.
132
+ * @param top - Top coordinate.
133
+ * @param width - With.
134
+ * @param height - Height.
135
+ * @returns - DivRect.
132
136
  */
133
137
  static create(left, top, width, height) {
134
138
  return new _DivRect(left, left + width, top, top + height);
@@ -138,9 +142,9 @@ var DivRect = class _DivRect {
138
142
  *
139
143
  * @param centerX - Center x-coordinate.
140
144
  * @param centerY - Center y-coordinate.
141
- * @param width -
142
- * @param height -
143
- * @returns
145
+ * @param width - Width.
146
+ * @param height - Height.
147
+ * @returns - DivRect.
144
148
  */
145
149
  static createCentered(centerX, centerY, width, height) {
146
150
  return new _DivRect(centerX - width / 2, centerX + width / 2, centerY - height / 2, centerY + height / 2);
@@ -152,43 +156,43 @@ var DivRect = class _DivRect {
152
156
  * @param rightw - Right section width.
153
157
  * @param toph - Top section height.
154
158
  * @param bottomh - Bottomsection height.
155
- * @returns
159
+ * @returns - DivRect.
156
160
  */
157
161
  static createSections(leftw, rightw, toph, bottomh) {
158
162
  return new _DivRect(-leftw, 0, rightw, -toph, 0, bottomh);
159
163
  }
160
164
  /**
161
- * Width.
165
+ * Width getter.
162
166
  */
163
167
  get width() {
164
168
  return this.right - this.left;
165
169
  }
166
170
  /**
167
- * Height.
171
+ * Height getter.
168
172
  */
169
173
  get height() {
170
174
  return this.bottom - this.top;
171
175
  }
172
176
  /**
173
- * Left section width.
177
+ * Left section width getter.
174
178
  */
175
179
  get leftw() {
176
180
  return this.centerX - this.left;
177
181
  }
178
182
  /**
179
- * Right section width.
183
+ * Right section width getter.
180
184
  */
181
185
  get rightw() {
182
186
  return this.right - this.centerX;
183
187
  }
184
188
  /**
185
- * Top section height.
189
+ * Top section height getter.
186
190
  */
187
191
  get toph() {
188
192
  return this.centerY - this.top;
189
193
  }
190
194
  /**
191
- * Bottom section height.
195
+ * Bottom section height getter.
192
196
  */
193
197
  get bottomh() {
194
198
  return this.bottom - this.centerY;
@@ -196,9 +200,9 @@ var DivRect = class _DivRect {
196
200
  /**
197
201
  * Does this Rect contain given (x, y)-point?
198
202
  *
199
- * @param x -
200
- * @param y -
201
- * @returns
203
+ * @param x - X-coordinate.
204
+ * @param y - Y-coordinate.
205
+ * @returns - True/false.
202
206
  */
203
207
  contains(x, y) {
204
208
  return x >= this.left && x <= this.right && y >= this.top && y <= this.bottom;
@@ -206,9 +210,9 @@ var DivRect = class _DivRect {
206
210
  /**
207
211
  * Do a and b rects overlap?
208
212
  *
209
- * @param a -
210
- * @param b -
211
- * @returns
213
+ * @param a - DivRect a.
214
+ * @param b - DivRect b.
215
+ * @returns - True/false.
212
216
  */
213
217
  static overlap(a, b) {
214
218
  return a.right > b.left && a.left < b.right && a.bottom > b.top && a.top < b.bottom;
@@ -216,17 +220,18 @@ var DivRect = class _DivRect {
216
220
  /**
217
221
  * Do horizontal measures of a and b rects overlap?
218
222
  *
219
- * @param a -
220
- * @param b -
221
- * @returns
223
+ * @param a - DivRect a.
224
+ * @param b - DivRect b.
225
+ * @returns - True/false.
222
226
  */
223
227
  static overlapX(a, b) {
224
228
  return a.right > b.left && a.left < b.right;
225
229
  }
226
230
  /**
227
231
  * Check if this Rect equals with given Rect.
228
- * @param b -
229
- * @returns
232
+ * @param a - DivRect a.
233
+ * @param b - DivRect b.
234
+ * @returns - True/false.
230
235
  */
231
236
  static equals(a, b) {
232
237
  if (a == null && b == null) {
@@ -238,10 +243,11 @@ var DivRect = class _DivRect {
238
243
  }
239
244
  }
240
245
  /**
241
- * Check if frame (ignoring centerX/Y) of this Rect equals with given Rect, ignoring centerX and centerY.
246
+ * Check if frame of this Rect equals with given Rect, ignoring center x- and center y-coordinates.
242
247
  *
243
- * @param b -
244
- * @returns
248
+ * @param a - DivRect a.
249
+ * @param b - DivRect b.
250
+ * @returns - True/false.
245
251
  */
246
252
  static equalsFrame(a, b) {
247
253
  if (a == null && b == null) {
@@ -255,7 +261,7 @@ var DivRect = class _DivRect {
255
261
  /**
256
262
  * Created duplicate of this Rect.
257
263
  *
258
- * @returns
264
+ * @returns - Duplicate.
259
265
  */
260
266
  copy() {
261
267
  return new _DivRect(this.left, this.centerX, this.right, this.top, this.centerY, this.bottom);
@@ -263,9 +269,9 @@ var DivRect = class _DivRect {
263
269
  /**
264
270
  * Move this rect by (dx, dy). Modifies this Rect.
265
271
  *
266
- * @param dx -
267
- * @param dy -
268
- * @returns
272
+ * @param dx - Offset amount in x-direction.
273
+ * @param dy - Offset amount in y-direction.
274
+ * @returns - This DivRect instance.
269
275
  */
270
276
  offsetInPlace(dx, dy) {
271
277
  this.left += dx;
@@ -279,9 +285,9 @@ var DivRect = class _DivRect {
279
285
  /**
280
286
  * Move this rect by (dx, dy). Immutable, returns modified copy.
281
287
  *
282
- * @param dx -
283
- * @param dy -
284
- * @returns
288
+ * @param dx - Offset amount in x-direction.
289
+ * @param dy - Offset amount in y-direction.
290
+ * @returns - DivRect copy with applied offset.
285
291
  */
286
292
  offsetCopy(dx, dy) {
287
293
  return this.copy().offsetInPlace(dx, dy);
@@ -289,8 +295,8 @@ var DivRect = class _DivRect {
289
295
  /**
290
296
  * Expand this Rect by given Rect. Modifies this Rect.
291
297
  *
292
- * @param rect -
293
- * @returns
298
+ * @param rect - DivRect to expand this instance with.
299
+ * @returns - This DivRect instance.
294
300
  */
295
301
  expandInPlace(rect) {
296
302
  this.left = Math.min(this.left, rect.left);
@@ -302,8 +308,8 @@ var DivRect = class _DivRect {
302
308
  /**
303
309
  * Expand this Rect by given Rect. Immutable, returns modified copy.
304
310
  *
305
- * @param rect -
306
- * @returns
311
+ * @param rect - DivRect to expand this instance with.
312
+ * @returns - Expanded copy of this DivRect.
307
313
  */
308
314
  expandCopy(rect) {
309
315
  return this.copy().expandInPlace(rect);
@@ -311,8 +317,8 @@ var DivRect = class _DivRect {
311
317
  /**
312
318
  * Clip this Rect by given Rect. Mmodifies this Rect.
313
319
  *
314
- * @param clipRect -
315
- * @returns
320
+ * @param clipRect - DivRect to clip this instance with.
321
+ * @returns - This DivRect instance.
316
322
  */
317
323
  clipInPlace(clipRect) {
318
324
  this.left = Math.max(this.left, clipRect.left);
@@ -326,8 +332,8 @@ var DivRect = class _DivRect {
326
332
  /**
327
333
  * Clip this Rect by given Rect. Immutable, return modified copy.
328
334
  *
329
- * @param clipRect -
330
- * @returns
335
+ * @param clipRect - DivRecto to clip this instance with.
336
+ * @returns - Clipped DivRect copy.
331
337
  */
332
338
  clipCopy(clipRect) {
333
339
  return this.copy().clipInPlace(clipRect);
@@ -335,9 +341,9 @@ var DivRect = class _DivRect {
335
341
  /**
336
342
  * Scale Rect. Anchor pos is (centerX, centerY). Modifies this Rect.
337
343
  *
338
- * @param scaleX -
339
- * @param scaleY -
340
- * @returns Copy of scaled Rect.
344
+ * @param scaleX - Scale x-amount.
345
+ * @param scaleY - Scale y-amount. If undefined then scale x-amount is used.
346
+ * @returns This DivRect instance.
341
347
  */
342
348
  scaleInPlace(scaleX, scaleY) {
343
349
  scaleY = scaleY != null ? scaleY : scaleX;
@@ -350,20 +356,24 @@ var DivRect = class _DivRect {
350
356
  /**
351
357
  * Scale Rect. Anchor pos is (centerX, centerY). Immutable, returns modified copy.
352
358
  *
353
- * @param scaleX -
354
- * @param scaleY -
355
- * @returns Copy of scaled Rect.
359
+ * @param scaleX - Scale x-amount.
360
+ * @param scaleY - Scale y-amount. If undefined then scale x-amount is used.
361
+ * @returns Scaled copy of this DivRect.
356
362
  */
357
363
  scaleCopy(scaleX, scaleY) {
358
364
  return this.copy().scaleInPlace(scaleX, scaleY);
359
365
  }
366
+ /**
367
+ * Get this DivRect instance.
368
+ * @returns - This DivRect instance.
369
+ */
360
370
  getRect() {
361
371
  return this;
362
372
  }
363
373
  };
364
374
 
365
375
  // src/score/pub/document-builder.ts
366
- var import_ts_utils_lib13 = require("@tspro/ts-utils-lib");
376
+ var import_ts_utils_lib15 = require("@tspro/ts-utils-lib");
367
377
 
368
378
  // src/score/pub/types.ts
369
379
  var StaffPreset = /* @__PURE__ */ ((StaffPreset3) => {
@@ -386,6 +396,9 @@ function getVoiceIds() {
386
396
  function getStringNumbers() {
387
397
  return [1, 2, 3, 4, 5, 6];
388
398
  }
399
+ function getVerseNumbers() {
400
+ return [1, 2, 3];
401
+ }
389
402
  var Stem = /* @__PURE__ */ ((Stem2) => {
390
403
  Stem2["Auto"] = "auto";
391
404
  Stem2["Up"] = "up";
@@ -423,6 +436,17 @@ var VerticalPosition = /* @__PURE__ */ ((VerticalPosition4) => {
423
436
  VerticalPosition4["Both"] = "both";
424
437
  return VerticalPosition4;
425
438
  })(VerticalPosition || {});
439
+ var LyricsAlign = /* @__PURE__ */ ((LyricsAlign2) => {
440
+ LyricsAlign2["Left"] = "left";
441
+ LyricsAlign2["Center"] = "center";
442
+ LyricsAlign2["Right"] = "right";
443
+ return LyricsAlign2;
444
+ })(LyricsAlign || {});
445
+ var LyricsHyphen = /* @__PURE__ */ ((LyricsHyphen2) => {
446
+ LyricsHyphen2["Hyphen"] = "-";
447
+ LyricsHyphen2["Extender"] = "---";
448
+ return LyricsHyphen2;
449
+ })(LyricsHyphen || {});
426
450
  var Fermata = /* @__PURE__ */ ((Fermata2) => {
427
451
  Fermata2["AtNote"] = "atNote";
428
452
  Fermata2["AtMeasureEnd"] = "atMeasureEnd";
@@ -976,11 +1000,11 @@ var Renderer = class {
976
1000
  };
977
1001
 
978
1002
  // src/score/engine/obj-staff-and-tab.ts
979
- var import_core15 = require("@tspro/web-music-score/core");
980
- var import_ts_utils_lib11 = require("@tspro/ts-utils-lib");
1003
+ var import_core16 = require("@tspro/web-music-score/core");
1004
+ var import_ts_utils_lib13 = require("@tspro/ts-utils-lib");
981
1005
 
982
1006
  // src/score/engine/obj-measure.ts
983
- var import_ts_utils_lib10 = require("@tspro/ts-utils-lib");
1007
+ var import_ts_utils_lib12 = require("@tspro/ts-utils-lib");
984
1008
  var import_theory9 = require("@tspro/web-music-score/theory");
985
1009
  var import_theory10 = require("@tspro/web-music-score/theory");
986
1010
 
@@ -1365,9 +1389,9 @@ var ObjSignature = class extends MusicObject {
1365
1389
  if (showTimeSignature) {
1366
1390
  let timeSignature = this.measure.getTimeSignature();
1367
1391
  let beatCount = timeSignature.beatCount.toString();
1368
- this.beatCountText = new ObjText(this, { text: beatCount, scale: 1.4 }, 0, 0.5);
1392
+ this.beatCountText = new ObjText(this, { text: beatCount, scale: 1.4 }, 0.5, 0.5);
1369
1393
  let beatSize = timeSignature.beatSize.toString();
1370
- this.beatSizeText = new ObjText(this, { text: beatSize, scale: 1.4 }, 0, 0.5);
1394
+ this.beatSizeText = new ObjText(this, { text: beatSize, scale: 1.4 }, 0.5, 0.5);
1371
1395
  } else {
1372
1396
  this.beatCountText = this.beatSizeText = void 0;
1373
1397
  }
@@ -1457,6 +1481,7 @@ var ObjSignature = class extends MusicObject {
1457
1481
  return [this];
1458
1482
  }
1459
1483
  layout(renderer) {
1484
+ var _a, _b, _c, _d, _e, _f;
1460
1485
  let { unitSize } = renderer;
1461
1486
  let { staff } = this;
1462
1487
  let paddingX = unitSize;
@@ -1501,15 +1526,16 @@ var ObjSignature = class extends MusicObject {
1501
1526
  });
1502
1527
  }
1503
1528
  let right = x;
1529
+ (_a = this.beatCountText) == null ? void 0 : _a.layout(renderer);
1530
+ (_b = this.beatSizeText) == null ? void 0 : _b.layout(renderer);
1531
+ let tsWidth = Math.max((_d = (_c = this.beatCountText) == null ? void 0 : _c.getRect().width) != null ? _d : 0, (_f = (_e = this.beatSizeText) == null ? void 0 : _e.getRect().width) != null ? _f : 0);
1504
1532
  if (this.beatCountText) {
1505
- this.beatCountText.layout(renderer);
1506
- this.beatCountText.offset(x + paddingX, staff.getDiatonicIdY(staff.middleLineDiatonicId + 2));
1533
+ this.beatCountText.offset(x + tsWidth / 2 + paddingX, staff.getDiatonicIdY(staff.middleLineDiatonicId + 2));
1507
1534
  this.rect.expandInPlace(this.beatCountText.getRect());
1508
1535
  right = Math.max(right, this.rect.right);
1509
1536
  }
1510
1537
  if (this.beatSizeText) {
1511
- this.beatSizeText.layout(renderer);
1512
- this.beatSizeText.offset(x + paddingX, staff.getDiatonicIdY(staff.bottomLineDiatonicId + 2));
1538
+ this.beatSizeText.offset(x + tsWidth / 2 + paddingX, staff.getDiatonicIdY(staff.bottomLineDiatonicId + 2));
1513
1539
  this.rect.expandInPlace(this.beatSizeText.getRect());
1514
1540
  right = Math.max(right, this.rect.right);
1515
1541
  }
@@ -1569,7 +1595,7 @@ var ObjSignature = class extends MusicObject {
1569
1595
  };
1570
1596
 
1571
1597
  // src/score/engine/player.ts
1572
- var import_ts_utils_lib6 = require("@tspro/ts-utils-lib");
1598
+ var import_ts_utils_lib8 = require("@tspro/ts-utils-lib");
1573
1599
  var import_theory7 = require("@tspro/web-music-score/theory");
1574
1600
  var Audio = __toESM(require("@tspro/web-music-score/audio"));
1575
1601
 
@@ -2898,11 +2924,10 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2898
2924
  }
2899
2925
  setStemTipY(staff, stemTipY) {
2900
2926
  let obj = this.staffObjects.find((obj2) => obj2.staff === staff);
2901
- if (!(obj == null ? void 0 : obj.stemTip) || stemTipY === obj.stemTip.centerY) {
2902
- return;
2927
+ if (this.hasBeamCount() && (obj == null ? void 0 : obj.stemTip) && stemTipY !== obj.stemTip.centerY) {
2928
+ obj.stemTip.top = obj.stemTip.centerY = obj.stemTip.bottom = stemTipY;
2929
+ this.requestRectUpdate();
2903
2930
  }
2904
- obj.stemTip.top = obj.stemTip.centerY = obj.stemTip.bottom = stemTipY;
2905
- this.requestRectUpdate();
2906
2931
  }
2907
2932
  offset(dx, dy) {
2908
2933
  this.staffObjects.forEach((obj) => obj.offset(dx, 0));
@@ -3077,13 +3102,344 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
3077
3102
  };
3078
3103
 
3079
3104
  // src/score/engine/obj-rhythm-column.ts
3105
+ var import_core9 = require("@tspro/web-music-score/core");
3106
+
3107
+ // src/theory/rhythm.ts
3108
+ var import_ts_utils_lib5 = require("@tspro/ts-utils-lib");
3080
3109
  var import_core8 = require("@tspro/web-music-score/core");
3110
+ var cmp = (a, b) => a === b ? 0 : a < b ? -1 : 1;
3111
+ var MaxTupletRatioValue = 12;
3112
+ var TicksMultiplier = 12 * 11 * 9 * 7 * 5;
3113
+ var NoteLength4 = /* @__PURE__ */ ((NoteLength10) => {
3114
+ NoteLength10["Whole"] = "1n";
3115
+ NoteLength10["WholeTriplet"] = "1t";
3116
+ NoteLength10["WholeDot"] = "1.";
3117
+ NoteLength10["Whole2Dots"] = "1..";
3118
+ NoteLength10["Whole12Dots"] = "1..";
3119
+ NoteLength10["Whole3Dots"] = "1...";
3120
+ NoteLength10["Whole4Dots"] = "1....";
3121
+ NoteLength10["Whole5Dots"] = "1.....";
3122
+ NoteLength10["Whole6Dots"] = "1......";
3123
+ NoteLength10["Half"] = "2n";
3124
+ NoteLength10["HalfTriplet"] = "2t";
3125
+ NoteLength10["HalfDot"] = "2.";
3126
+ NoteLength10["Half2Dots"] = "2..";
3127
+ NoteLength10["Half3Dots"] = "2...";
3128
+ NoteLength10["Half4Dots"] = "2....";
3129
+ NoteLength10["Half5Dots"] = "2.....";
3130
+ NoteLength10["Quarter"] = "4n";
3131
+ NoteLength10["QuarterTriplet"] = "4t";
3132
+ NoteLength10["QuarterDot"] = "4.";
3133
+ NoteLength10["Quarter2Dots"] = "4..";
3134
+ NoteLength10["Quarter3Dots"] = "4...";
3135
+ NoteLength10["Quarter4Dots"] = "4....";
3136
+ NoteLength10["Eighth"] = "8n";
3137
+ NoteLength10["EighthTriplet"] = "8t";
3138
+ NoteLength10["EighthDot"] = "8.";
3139
+ NoteLength10["Eighth2Dots"] = "8..";
3140
+ NoteLength10["Eighth3Dots"] = "8...";
3141
+ NoteLength10["Sixteenth"] = "16n";
3142
+ NoteLength10["SixteenthTriplet"] = "16t";
3143
+ NoteLength10["SixteenthDot"] = "16.";
3144
+ NoteLength10["Sixteenth2Dots"] = "16..";
3145
+ NoteLength10["ThirtySecond"] = "32n";
3146
+ NoteLength10["ThirtySecondTriplet"] = "32t";
3147
+ NoteLength10["ThirtySecondDot"] = "32.";
3148
+ NoteLength10["SixtyFourth"] = "64n";
3149
+ NoteLength10["SixtyFourthTriplet"] = "64t";
3150
+ return NoteLength10;
3151
+ })(NoteLength4 || {});
3152
+ function validateNoteLength(noteLength) {
3153
+ if (import_ts_utils_lib5.Utils.Is.isEnumValue(noteLength, NoteLength4)) {
3154
+ return noteLength;
3155
+ } else {
3156
+ throw new import_core8.MusicError(import_core8.MusicErrorType.InvalidArg, `Invalid noteLength: ${noteLength}`);
3157
+ }
3158
+ }
3159
+ var _NoteLengthProps = class _NoteLengthProps {
3160
+ constructor(noteLength) {
3161
+ /** Note length. */
3162
+ __publicField(this, "noteLength");
3163
+ /** Note size (whole=1, half=2, quarter=4, ...). */
3164
+ __publicField(this, "noteSize");
3165
+ /** Number of ticks (not altered by isTriplet). */
3166
+ __publicField(this, "ticks");
3167
+ /** Flag count. */
3168
+ __publicField(this, "flagCount");
3169
+ /** Dot count. */
3170
+ __publicField(this, "dotCount");
3171
+ /** Max dot count. */
3172
+ __publicField(this, "maxDotCount");
3173
+ /** Is triplet? */
3174
+ __publicField(this, "isTriplet");
3175
+ /** Has note stem. */
3176
+ __publicField(this, "hasStem");
3177
+ /** Is note head solid (black)? */
3178
+ __publicField(this, "isSolid");
3179
+ this.noteLength = validateNoteLength(noteLength);
3180
+ this.noteSize = parseInt(noteLength);
3181
+ this.isTriplet = noteLength.endsWith("t");
3182
+ this.maxDotCount = this.isTriplet ? 0 : Math.floor(Math.log2(_NoteLengthProps.ShortestNoteSize / this.noteSize));
3183
+ this.dotCount = import_ts_utils_lib5.Utils.Str.charCount(noteLength, ".");
3184
+ this.flagCount = this.noteSize > 4 ? Math.floor(Math.log2(this.noteSize / 4)) : 0;
3185
+ this.ticks = TicksMultiplier * _NoteLengthProps.ShortestNoteSize / this.noteSize;
3186
+ this.hasStem = this.noteSize > 1;
3187
+ this.isSolid = this.noteSize > 2;
3188
+ if (this.dotCount > this.maxDotCount) {
3189
+ throw new import_core8.MusicError(import_core8.MusicErrorType.Note, `dotCount ${this.dotCount} > maxDotCount ${this.maxDotCount}, for noteLength "${this.noteLength}".`);
3190
+ } else if (this.isTriplet && this.dotCount > 0) {
3191
+ throw new import_core8.MusicError(import_core8.MusicErrorType.Note, `noteLength "${this.noteLength}" is both triplet and dotted!`);
3192
+ }
3193
+ }
3194
+ /**
3195
+ * Get note length props.
3196
+ * @param noteLength - Note length.
3197
+ * @returns - Note length props.
3198
+ */
3199
+ static get(noteLength) {
3200
+ let p = this.cache.get(noteLength);
3201
+ if (!p) {
3202
+ this.cache.set(noteLength, p = new _NoteLengthProps(noteLength));
3203
+ }
3204
+ return p;
3205
+ }
3206
+ /**
3207
+ * Create note length props.
3208
+ * @param noteLength - Note length or note size.
3209
+ * @param dotCount - Dot count.
3210
+ * @returns - Note length props.
3211
+ */
3212
+ static create(noteLength, dotCount = 0) {
3213
+ let noteSize = typeof noteLength === "number" ? noteLength : this.get(noteLength).noteSize;
3214
+ return this.get(noteSize + (import_ts_utils_lib5.Utils.Is.isIntegerGte(dotCount, 1) ? ".".repeat(dotCount) : "n"));
3215
+ }
3216
+ /**
3217
+ * Compare note lengths/sizes. Whole (1) > half (2) > quarter (4), etc.
3218
+ * Ignores possible triplet property of note length.
3219
+ * @param a - NoteLengthProps, NoteLength/Str or noteSize
3220
+ * @param b - NoteLengthProps, NoteLength/Str or noteSize
3221
+ * @returns - -1: a < b, 0: a === b, +1: a > b (note length/size comparisons)
3222
+ */
3223
+ static cmp(a, b) {
3224
+ let aNoteSize = a instanceof _NoteLengthProps ? a.noteSize : typeof a === "number" ? a : _NoteLengthProps.get(a).noteSize;
3225
+ let bNoteSize = b instanceof _NoteLengthProps ? b.noteSize : typeof b === "number" ? b : _NoteLengthProps.get(b).noteSize;
3226
+ return cmp(bNoteSize, aNoteSize);
3227
+ }
3228
+ /**
3229
+ * Compare note lengths/sizes for equality.
3230
+ * Ignores possible triplet property of note length.
3231
+ * @param a - NoteLengthProps, NoteLength/Str or noteSize
3232
+ * @param b - NoteLengthProps, NoteLength/Str or noteSize
3233
+ * @returns - true: a === b, false: a !== b (note length/size comparisons)
3234
+ */
3235
+ static equals(a, b) {
3236
+ let aNoteSize = a instanceof _NoteLengthProps ? a.noteSize : typeof a === "number" ? a : _NoteLengthProps.get(a).noteSize;
3237
+ let bNoteSize = b instanceof _NoteLengthProps ? b.noteSize : typeof b === "number" ? b : _NoteLengthProps.get(b).noteSize;
3238
+ return aNoteSize === bNoteSize;
3239
+ }
3240
+ };
3241
+ /** Longest note size (e.g. 1 = whole note). */
3242
+ __publicField(_NoteLengthProps, "LongestNoteSize", Math.min(...import_ts_utils_lib5.Utils.Enum.getEnumValues(NoteLength4).map((noteLength) => parseInt(noteLength))));
3243
+ /** Shortest note size (e.g. 64 = sixtyfourth note). */
3244
+ __publicField(_NoteLengthProps, "ShortestNoteSize", Math.max(...import_ts_utils_lib5.Utils.Enum.getEnumValues(NoteLength4).map((noteLength) => parseInt(noteLength))));
3245
+ __publicField(_NoteLengthProps, "cache", /* @__PURE__ */ new Map());
3246
+ var NoteLengthProps4 = _NoteLengthProps;
3247
+ function validateTupletRatio(tupletRatio) {
3248
+ if (import_ts_utils_lib5.Utils.Is.isObject(tupletRatio) && import_ts_utils_lib5.Utils.Is.isIntegerBetween(tupletRatio.parts, 2, MaxTupletRatioValue) && import_ts_utils_lib5.Utils.Is.isIntegerBetween(tupletRatio.inTimeOf, 2, MaxTupletRatioValue)) {
3249
+ return tupletRatio;
3250
+ } else {
3251
+ throw new import_core8.MusicError(import_core8.MusicErrorType.Note, `Invalid tupletRatio ${JSON.stringify(tupletRatio)}`);
3252
+ }
3253
+ }
3254
+ var Tuplet4 = {
3255
+ /** Duplet: 2 in the time of 3 */
3256
+ Duplet: { parts: 2, inTimeOf: 3 },
3257
+ /** Triplet: 3 in the time of 2 */
3258
+ Triplet: { parts: 3, inTimeOf: 2 },
3259
+ /** Quadruplet: 4 in the time of 3 */
3260
+ Quadruplet: { parts: 4, inTimeOf: 3 }
3261
+ };
3262
+ var _RhythmProps = class _RhythmProps {
3263
+ constructor(noteLength, dotCount, tupletRatio) {
3264
+ /** Note length. */
3265
+ __publicField(this, "noteLength");
3266
+ /** Note size (whole=1, half=2, quarter=4, ...). */
3267
+ __publicField(this, "noteSize");
3268
+ /** Dot count. */
3269
+ __publicField(this, "dotCount");
3270
+ /** Tuplet ratio. */
3271
+ __publicField(this, "tupletRatio");
3272
+ /** Number of ticks. */
3273
+ __publicField(this, "ticks");
3274
+ /** Flag count. */
3275
+ __publicField(this, "flagCount");
3276
+ /** Has note stem. */
3277
+ __publicField(this, "hasStem");
3278
+ /** Is note head solid (black)? */
3279
+ __publicField(this, "isSolidNoteHead");
3280
+ this.noteLength = validateNoteLength(noteLength);
3281
+ let p = NoteLengthProps4.get(noteLength);
3282
+ this.noteSize = p.noteSize;
3283
+ this.ticks = p.ticks;
3284
+ this.flagCount = p.flagCount;
3285
+ this.dotCount = dotCount != null ? dotCount : p.dotCount;
3286
+ this.hasStem = p.hasStem;
3287
+ this.isSolidNoteHead = p.isSolid;
3288
+ if (import_ts_utils_lib5.Utils.Is.isObject(tupletRatio)) {
3289
+ this.tupletRatio = validateTupletRatio(tupletRatio);
3290
+ } else if (p.isTriplet) {
3291
+ this.tupletRatio = Tuplet4.Triplet;
3292
+ } else {
3293
+ this.tupletRatio = void 0;
3294
+ }
3295
+ if (this.dotCount > 0 && this.tupletRatio !== void 0) {
3296
+ throw new import_core8.MusicError(import_core8.MusicErrorType.Note, `Note cannot be both dotted and tuplet!`);
3297
+ } else if (this.dotCount > p.maxDotCount) {
3298
+ throw new import_core8.MusicError(import_core8.MusicErrorType.Note, `Too big dot count ${this.dotCount} for note length ${this.noteLength}.`);
3299
+ }
3300
+ for (let add = this.ticks / 2, i = 1; i <= this.dotCount; i++, add /= 2) {
3301
+ this.ticks += add;
3302
+ }
3303
+ if (this.tupletRatio) {
3304
+ this.ticks *= this.tupletRatio.inTimeOf / this.tupletRatio.parts;
3305
+ }
3306
+ }
3307
+ /**
3308
+ * Get string presentation of rhythm props.
3309
+ * @returns - String presentation.
3310
+ */
3311
+ toString() {
3312
+ let sym = _RhythmProps.NoteSymbolMap.get(this.noteSize);
3313
+ let dots = ".".repeat(this.dotCount);
3314
+ return sym ? sym + dots : "" + this.noteSize + (dots.length > 0 ? dots : "n");
3315
+ }
3316
+ /**
3317
+ * Get rhythm props with given arguments.
3318
+ * @param noteLength - Note length.
3319
+ * @param dotCount - Dot count.
3320
+ * @param tupletRatio - Tuplet ratio.
3321
+ * @returns - Rhythm props.
3322
+ */
3323
+ static get(noteLength, dotCount, tupletRatio) {
3324
+ if (dotCount !== void 0 || tupletRatio !== void 0) {
3325
+ return new _RhythmProps(noteLength, dotCount, tupletRatio);
3326
+ } else {
3327
+ let rhythmProps = this.cache.get(noteLength);
3328
+ if (!rhythmProps) {
3329
+ this.cache.set(noteLength, rhythmProps = new _RhythmProps(noteLength));
3330
+ }
3331
+ return rhythmProps;
3332
+ }
3333
+ }
3334
+ /**
3335
+ * Compare duration of rhythm props.
3336
+ * @param a - RhythmProps
3337
+ * @param b - RhythmProps
3338
+ * @returns - -1: a < b, 0: a === b, +1: a > b (duration comparisons)
3339
+ */
3340
+ static cmp(a, b) {
3341
+ return cmp(a.ticks, b.ticks);
3342
+ }
3343
+ /**
3344
+ * Compare duration equality of rhythm props.
3345
+ * @param a - RhythmProps
3346
+ * @param b - RhythmProps
3347
+ * @returns - true: a === b, false: a !== b (duration comparisons)
3348
+ */
3349
+ static equals(a, b) {
3350
+ return a.ticks === b.ticks;
3351
+ }
3352
+ };
3353
+ __publicField(_RhythmProps, "NoteSymbolMap", /* @__PURE__ */ new Map([[1, "\u{1D15D}"], [2, "\u{1D15E}"], [4, "\u{1D15F}"], [8, "\u{1D160}"], [16, "\u{1D161}"], [32, "\u{1D162}"], [64, "\u{1D163}"], [128, "\u{1D164}"]]));
3354
+ __publicField(_RhythmProps, "cache", /* @__PURE__ */ new Map());
3355
+ var RhythmProps3 = _RhythmProps;
3356
+
3357
+ // src/score/engine/obj-lyrics.ts
3358
+ var import_ts_utils_lib6 = require("@tspro/ts-utils-lib");
3359
+ var LyricsContainer = class {
3360
+ constructor(col, lyricsLength) {
3361
+ this.col = col;
3362
+ __publicField(this, "lyricsObjects", []);
3363
+ __publicField(this, "rhythmProps");
3364
+ this.rhythmProps = RhythmProps3.get(lyricsLength);
3365
+ }
3366
+ addLyricsObject(lyricsObj) {
3367
+ var _a;
3368
+ this.lyricsObjects.push(lyricsObj);
3369
+ (_a = lyricsObj.measure.getPrevLyricsObject(lyricsObj)) == null ? void 0 : _a.setNextLyricsObject(lyricsObj);
3370
+ }
3371
+ };
3372
+ var ObjLyrics = class extends MusicObject {
3373
+ constructor(col, verse, line, vpos, lyricsText, lyricsOptions) {
3374
+ super(col);
3375
+ this.col = col;
3376
+ this.verse = verse;
3377
+ this.line = line;
3378
+ this.vpos = vpos;
3379
+ __publicField(this, "nextLyricsObject");
3380
+ __publicField(this, "color", "black");
3381
+ __publicField(this, "hyphen");
3382
+ __publicField(this, "text");
3383
+ __publicField(this, "mi");
3384
+ let halign = (lyricsOptions == null ? void 0 : lyricsOptions.align) === "left" /* Left */ ? 0 : (lyricsOptions == null ? void 0 : lyricsOptions.align) === "right" /* Right */ ? 1 : 0.5;
3385
+ this.hyphen = import_ts_utils_lib6.Utils.Is.isEnumValue(lyricsOptions == null ? void 0 : lyricsOptions.hyphen, LyricsHyphen) ? lyricsOptions == null ? void 0 : lyricsOptions.hyphen : void 0;
3386
+ this.text = new ObjText(this, { text: lyricsText, color: this.color, scale: 0.8 }, halign, 0);
3387
+ this.rect = new DivRect();
3388
+ this.mi = new MLyrics(this);
3389
+ }
3390
+ getMusicInterface() {
3391
+ return this.mi;
3392
+ }
3393
+ get measure() {
3394
+ return this.col.measure;
3395
+ }
3396
+ getText() {
3397
+ return this.text.getText();
3398
+ }
3399
+ setNextLyricsObject(lyricsObj) {
3400
+ this.nextLyricsObject = lyricsObj;
3401
+ }
3402
+ pick(x, y) {
3403
+ return this.rect.contains(x, y) ? [this] : [];
3404
+ }
3405
+ layout(renderer) {
3406
+ this.text.layout(renderer);
3407
+ this.rect = this.text.getRect().copy();
3408
+ }
3409
+ offset(dx, dy) {
3410
+ this.text.offset(dx, dy);
3411
+ this.rect.offsetInPlace(dx, dy);
3412
+ }
3413
+ draw(renderer) {
3414
+ var _a;
3415
+ this.text.draw(renderer);
3416
+ const ctx = renderer.getCanvasContext();
3417
+ if (ctx && this.hyphen !== void 0) {
3418
+ let l = this.getRect();
3419
+ let r = (_a = this.nextLyricsObject) == null ? void 0 : _a.getRect();
3420
+ let hyphenw = renderer.unitSize * 1.5;
3421
+ let maxw = r ? (r.left - l.right) * 0.85 : hyphenw;
3422
+ let w = this.hyphen === "-" /* Hyphen */ ? Math.min(hyphenw, maxw) : maxw;
3423
+ if (w > 0) {
3424
+ ctx.lineWidth = renderer.lineWidth;
3425
+ ctx.strokeStyle = ctx.fillStyle = this.color;
3426
+ let cx = r ? (r.left + l.right) / 2 : l.right + w / 0.85;
3427
+ let cy = (l.top + l.bottom) / 2;
3428
+ ctx.moveTo(cx - w / 2, cy);
3429
+ ctx.lineTo(cx + w / 2, cy);
3430
+ ctx.stroke();
3431
+ }
3432
+ }
3433
+ }
3434
+ };
3435
+
3436
+ // src/score/engine/obj-rhythm-column.ts
3081
3437
  var noteHeadDataCompareFunc = (a, b) => {
3082
- let cmp = import_theory6.Note.compareFunc(a.note, b.note);
3083
- if (cmp === 0) {
3084
- cmp = a.noteGroup.stemDir === b.noteGroup.stemDir ? 0 : a.noteGroup.stemDir === "up" /* Up */ ? 1 : -1;
3438
+ let cmp3 = import_theory6.Note.compareFunc(a.note, b.note);
3439
+ if (cmp3 === 0) {
3440
+ cmp3 = a.noteGroup.stemDir === b.noteGroup.stemDir ? 0 : a.noteGroup.stemDir === "up" /* Up */ ? 1 : -1;
3085
3441
  }
3086
- return cmp;
3442
+ return cmp3;
3087
3443
  };
3088
3444
  var ObjRhythmColumn = class extends MusicObject {
3089
3445
  constructor(measure, positionTicks) {
@@ -3091,6 +3447,7 @@ var ObjRhythmColumn = class extends MusicObject {
3091
3447
  this.measure = measure;
3092
3448
  this.positionTicks = positionTicks;
3093
3449
  __publicField(this, "voiceSymbol", []);
3450
+ __publicField(this, "lyricsContainers", []);
3094
3451
  __publicField(this, "minDiatonicId");
3095
3452
  __publicField(this, "maxDiatonicId");
3096
3453
  __publicField(this, "staffMinDiatonicId", /* @__PURE__ */ new Map());
@@ -3120,7 +3477,7 @@ var ObjRhythmColumn = class extends MusicObject {
3120
3477
  if (colId >= 0 && colId < this.measure.getColumnCount()) {
3121
3478
  return this.measure.getColumn(colId + 1);
3122
3479
  } else {
3123
- throw new import_core8.MusicError(import_core8.MusicErrorType.Score, "Cannot get next column in measure because current column's id in mesure is invalid.");
3480
+ throw new import_core9.MusicError(import_core9.MusicErrorType.Score, "Cannot get next column in measure because current column's id in mesure is invalid.");
3124
3481
  }
3125
3482
  }
3126
3483
  /**
@@ -3216,6 +3573,19 @@ var ObjRhythmColumn = class extends MusicObject {
3216
3573
  getVoiceSymbol(voiceId) {
3217
3574
  return this.voiceSymbol[voiceId];
3218
3575
  }
3576
+ getLyricsContainerDatas() {
3577
+ return this.lyricsContainers;
3578
+ }
3579
+ getLyricsContainer(verse, line, vpos, lyricsLength) {
3580
+ let data = this.lyricsContainers.find((data2) => data2.verse === verse && data2.line === line && data2.vpos === vpos);
3581
+ if (data === void 0 && lyricsLength !== void 0) {
3582
+ data = { lyricsContainer: new LyricsContainer(this, (0, import_theory6.validateNoteLength)(lyricsLength)), verse, line, vpos };
3583
+ this.lyricsContainers.push(data);
3584
+ this.requestLayout();
3585
+ this.requestRectUpdate();
3586
+ }
3587
+ return data == null ? void 0 : data.lyricsContainer;
3588
+ }
3219
3589
  getMinWidth() {
3220
3590
  let maxNoteSize = Math.max(...this.voiceSymbol.map((s) => s.rhythmProps.noteSize));
3221
3591
  let w = DocumentSettings.NoteHeadWidth;
@@ -3432,10 +3802,10 @@ var ObjRhythmColumn = class extends MusicObject {
3432
3802
  };
3433
3803
 
3434
3804
  // src/score/engine/extension.ts
3435
- var import_core9 = require("@tspro/web-music-score/core");
3805
+ var import_core10 = require("@tspro/web-music-score/core");
3436
3806
 
3437
3807
  // src/score/engine/element-data.ts
3438
- var import_ts_utils_lib5 = require("@tspro/ts-utils-lib");
3808
+ var import_ts_utils_lib7 = require("@tspro/ts-utils-lib");
3439
3809
 
3440
3810
  // src/score/engine/obj-special-text.ts
3441
3811
  var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
@@ -3557,23 +3927,23 @@ function getNavigationString(navigation) {
3557
3927
  }
3558
3928
  }
3559
3929
  function isDynamicsText(text) {
3560
- return import_ts_utils_lib5.Utils.Is.isEnumValue(text, DynamicsAnnotation);
3930
+ return import_ts_utils_lib7.Utils.Is.isEnumValue(text, DynamicsAnnotation);
3561
3931
  }
3562
3932
  function getDynamicsVolume(text) {
3563
3933
  if (/^(p+|f+|m|mp|mf)$/.test(text)) {
3564
- let volume = 0.5 - import_ts_utils_lib5.Utils.Str.charCount(text, "p") * 0.1 + import_ts_utils_lib5.Utils.Str.charCount(text, "f") * 0.1;
3565
- return import_ts_utils_lib5.Utils.Math.clamp(volume, 0, 1);
3934
+ let volume = 0.5 - import_ts_utils_lib7.Utils.Str.charCount(text, "p") * 0.1 + import_ts_utils_lib7.Utils.Str.charCount(text, "f") * 0.1;
3935
+ return import_ts_utils_lib7.Utils.Math.clamp(volume, 0, 1);
3566
3936
  } else {
3567
3937
  return void 0;
3568
3938
  }
3569
3939
  }
3570
3940
  function isTempoText(text) {
3571
- return import_ts_utils_lib5.Utils.Is.isEnumValue(text, TempoAnnotation);
3941
+ return import_ts_utils_lib7.Utils.Is.isEnumValue(text, TempoAnnotation);
3572
3942
  }
3573
3943
  function getAnnotation(text) {
3574
- if (import_ts_utils_lib5.Utils.Is.isEnumValue(text, DynamicsAnnotation)) {
3944
+ if (import_ts_utils_lib7.Utils.Is.isEnumValue(text, DynamicsAnnotation)) {
3575
3945
  return "dynamics" /* Dynamics */;
3576
- } else if (import_ts_utils_lib5.Utils.Is.isEnumValue(text, TempoAnnotation)) {
3946
+ } else if (import_ts_utils_lib7.Utils.Is.isEnumValue(text, TempoAnnotation)) {
3577
3947
  return "tempo" /* Tempo */;
3578
3948
  } else {
3579
3949
  return void 0;
@@ -3616,7 +3986,7 @@ var Extension = class extends MusicObjectLink {
3616
3986
  if (head instanceof ObjText) {
3617
3987
  head.updateAnchorY(getTextAnchorY(linePos));
3618
3988
  } else {
3619
- throw new import_core9.MusicError(import_core9.MusicErrorType.Score, "Update anchor's y-coordinate is only implemented for text objects.");
3989
+ throw new import_core10.MusicError(import_core10.MusicErrorType.Score, "Update anchor's y-coordinate is only implemented for text objects.");
3620
3990
  }
3621
3991
  }
3622
3992
  isVisible() {
@@ -3729,7 +4099,7 @@ var PlayerColumnProps = class {
3729
4099
  return this.speed;
3730
4100
  }
3731
4101
  getTempo() {
3732
- let speed = import_ts_utils_lib6.Utils.Math.clamp(this.getSpeed(), 0.1, 10);
4102
+ let speed = import_ts_utils_lib8.Utils.Math.clamp(this.getSpeed(), 0.1, 10);
3733
4103
  return (0, import_theory7.alterTempoSpeed)(this.measure.getTempo(), speed);
3734
4104
  }
3735
4105
  setVolume(volume) {
@@ -3754,7 +4124,7 @@ var PlayerColumnProps = class {
3754
4124
  if (symbolsTicks.length === 0) {
3755
4125
  return 0;
3756
4126
  } else {
3757
- return import_ts_utils_lib6.Utils.Math.sum(symbolsTicks) / symbolsTicks.length;
4127
+ return import_ts_utils_lib8.Utils.Math.sum(symbolsTicks) / symbolsTicks.length;
3758
4128
  }
3759
4129
  }
3760
4130
  }
@@ -3903,7 +4273,7 @@ var Player = class _Player {
3903
4273
  } else if (layoutObj.musicObj.getLink() instanceof Extension) {
3904
4274
  let extension = layoutObj.musicObj.getLink();
3905
4275
  let { columnRange, extensionBreakText } = extension.getExtensionRangeInfo();
3906
- let totalTicks = import_ts_utils_lib6.Utils.Math.sum(columnRange.map((c) => c.getTicksToNextColumn()));
4276
+ let totalTicks = import_ts_utils_lib8.Utils.Math.sum(columnRange.map((c) => c.getTicksToNextColumn()));
3907
4277
  switch (text) {
3908
4278
  case "accel." /* accel */: {
3909
4279
  let startSpeed = curSpeed;
@@ -3957,11 +4327,11 @@ var Player = class _Player {
3957
4327
  });
3958
4328
  let speedArr = (_a = speedMap.get(col)) != null ? _a : [];
3959
4329
  if (speedArr.length > 0) {
3960
- curSpeed = import_ts_utils_lib6.Utils.Math.sum(speedArr) / speedArr.length;
4330
+ curSpeed = import_ts_utils_lib8.Utils.Math.sum(speedArr) / speedArr.length;
3961
4331
  }
3962
4332
  let volumeArr = (_b = volumeMap.get(col)) != null ? _b : [];
3963
4333
  if (volumeArr.length > 0) {
3964
- curVolume = import_ts_utils_lib6.Utils.Math.sum(volumeArr) / volumeArr.length;
4334
+ curVolume = import_ts_utils_lib8.Utils.Math.sum(volumeArr) / volumeArr.length;
3965
4335
  }
3966
4336
  col.getPlayerProps().setSpeed(curSpeed);
3967
4337
  col.getPlayerProps().setVolume(curVolume);
@@ -4291,8 +4661,8 @@ var ObjBarLineRight = class extends ObjBarLine {
4291
4661
  };
4292
4662
 
4293
4663
  // src/score/engine/obj-ending.ts
4294
- var import_ts_utils_lib7 = require("@tspro/ts-utils-lib");
4295
- var import_core10 = require("@tspro/web-music-score/core");
4664
+ var import_ts_utils_lib9 = require("@tspro/ts-utils-lib");
4665
+ var import_core11 = require("@tspro/web-music-score/core");
4296
4666
  var ObjEnding = class extends MusicObject {
4297
4667
  constructor(measure, passages) {
4298
4668
  super(measure);
@@ -4302,10 +4672,10 @@ var ObjEnding = class extends MusicObject {
4302
4672
  __publicField(this, "shapeRects", []);
4303
4673
  __publicField(this, "mi");
4304
4674
  this.mi = new MEnding(this);
4305
- if (!import_ts_utils_lib7.Utils.Is.isIntegerGte(passages.length, 1)) {
4306
- throw new import_core10.MusicError(import_core10.MusicErrorType.Score, "Passages is empty.");
4307
- } else if (!this.passages.every((p) => import_ts_utils_lib7.Utils.Is.isIntegerGte(p, 1))) {
4308
- throw new import_core10.MusicError(import_core10.MusicErrorType.Score, "Invalid passages: " + this.passages);
4675
+ if (!import_ts_utils_lib9.Utils.Is.isIntegerGte(passages.length, 1)) {
4676
+ throw new import_core11.MusicError(import_core11.MusicErrorType.Score, "Passages is empty.");
4677
+ } else if (!this.passages.every((p) => import_ts_utils_lib9.Utils.Is.isIntegerGte(p, 1))) {
4678
+ throw new import_core11.MusicError(import_core11.MusicErrorType.Score, "Invalid passages: " + this.passages);
4309
4679
  }
4310
4680
  this.passages.sort((a, b) => a - b);
4311
4681
  let text = this.passages.map((p) => p + ".").join("");
@@ -4513,14 +4883,14 @@ var ObjExtensionLine = class extends MusicObject {
4513
4883
  };
4514
4884
 
4515
4885
  // src/score/engine/obj-measure.ts
4516
- var import_core13 = require("@tspro/web-music-score/core");
4886
+ var import_core14 = require("@tspro/web-music-score/core");
4517
4887
 
4518
4888
  // src/score/engine/connective-props.ts
4519
4889
  var import_theory8 = require("@tspro/web-music-score/theory");
4520
4890
 
4521
4891
  // src/score/engine/obj-connective.ts
4522
- var import_ts_utils_lib8 = require("@tspro/ts-utils-lib");
4523
- var import_core11 = require("@tspro/web-music-score/core");
4892
+ var import_ts_utils_lib10 = require("@tspro/ts-utils-lib");
4893
+ var import_core12 = require("@tspro/web-music-score/core");
4524
4894
  var ObjConnective = class extends MusicObject {
4525
4895
  constructor(connectiveProps, line, measure, leftNoteGroup, leftNoteId, ...args) {
4526
4896
  super(measure);
@@ -4548,7 +4918,7 @@ var ObjConnective = class extends MusicObject {
4548
4918
  this.rightNoteGroup = args[0];
4549
4919
  this.rightNoteId = args[1];
4550
4920
  this.tieType = void 0;
4551
- } else if (import_ts_utils_lib8.Utils.Is.isEnumValue(args[0], TieType)) {
4921
+ } else if (import_ts_utils_lib10.Utils.Is.isEnumValue(args[0], TieType)) {
4552
4922
  this.rightNoteGroup = void 0;
4553
4923
  this.rightNoteId = void 0;
4554
4924
  this.tieType = args[0];
@@ -4609,7 +4979,7 @@ var ObjConnective = class extends MusicObject {
4609
4979
  rx = contentRect.right;
4610
4980
  ry = leftPos.y + (rightPos.y - leftPos.y) * tLeft / (tLeft + tRight);
4611
4981
  } else {
4612
- throw new import_core11.MusicError(import_core11.MusicErrorType.Score, "Cannot layout connective object because no valid left and right note groups.");
4982
+ throw new import_core12.MusicError(import_core12.MusicErrorType.Score, "Cannot layout connective object because no valid left and right note groups.");
4613
4983
  }
4614
4984
  let spanDy = arcDir === "up" ? -1 : 1;
4615
4985
  let arcHeight = spanDy * unitSize * Math.log2(rx - lx) / 3;
@@ -4618,7 +4988,7 @@ var ObjConnective = class extends MusicObject {
4618
4988
  this.rx = rx;
4619
4989
  this.ry = ry;
4620
4990
  this.arcHeight = this.connectiveProps.connective === "slide" /* Slide */ ? 0 : arcHeight;
4621
- let { nx, ny } = import_ts_utils_lib8.Utils.Math.calcNormal(lx, ly, rx, ry);
4991
+ let { nx, ny } = import_ts_utils_lib10.Utils.Math.calcNormal(lx, ly, rx, ry);
4622
4992
  this.cp1x = lx * 0.7 + rx * 0.3 + nx * this.arcHeight;
4623
4993
  this.cp1y = ly * 0.7 + ry * 0.3 + ny * this.arcHeight;
4624
4994
  this.cp2x = lx * 0.3 + rx * 0.7 + nx * this.arcHeight;
@@ -4678,8 +5048,8 @@ var ObjConnective = class extends MusicObject {
4678
5048
  };
4679
5049
 
4680
5050
  // src/score/engine/connective-props.ts
4681
- var import_core12 = require("@tspro/web-music-score/core");
4682
- var import_ts_utils_lib9 = require("@tspro/ts-utils-lib");
5051
+ var import_core13 = require("@tspro/web-music-score/core");
5052
+ var import_ts_utils_lib11 = require("@tspro/ts-utils-lib");
4683
5053
  var ConnectiveProps = class {
4684
5054
  constructor(connective, span, noteAnchor, startNoteGroup) {
4685
5055
  this.connective = connective;
@@ -4749,7 +5119,7 @@ var ConnectiveProps = class {
4749
5119
  this.computeParams();
4750
5120
  let { connective, span } = this;
4751
5121
  if (connective === "tie" /* Tie */) {
4752
- if (import_ts_utils_lib9.Utils.Is.isEnumValue(span, TieType)) {
5122
+ if (import_ts_utils_lib11.Utils.Is.isEnumValue(span, TieType)) {
4753
5123
  let leftNoteGroup = this.noteGroups[0];
4754
5124
  for (let noteId = 0; noteId < leftNoteGroup.notes.length; noteId++) {
4755
5125
  this.createObjConnectiveWithTieType(leftNoteGroup, noteId, span);
@@ -4814,15 +5184,16 @@ var ConnectiveProps = class {
4814
5184
  addConnective(leftNoteGroup.measure, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId);
4815
5185
  addConnective(rightNoteGroup.measure, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId);
4816
5186
  } else {
4817
- throw new import_core12.MusicError(import_core12.MusicErrorType.Score, "Cannot create connective because it is jumping measures.");
5187
+ throw new import_core13.MusicError(import_core13.MusicErrorType.Score, "Cannot create connective because it is jumping measures.");
4818
5188
  }
4819
5189
  }
4820
5190
  };
4821
5191
 
4822
5192
  // src/score/engine/obj-measure.ts
5193
+ var cmp2 = (a, b) => a === b ? 0 : a < b ? -1 : 1;
4823
5194
  function validateVoiceId(voiceId) {
4824
- if (getVoiceIds().indexOf(voiceId) < 0) {
4825
- throw new import_core13.MusicError(import_core13.MusicErrorType.Score, "Invalid voiceId: " + voiceId);
5195
+ if (typeof voiceId === "number" && getVoiceIds().indexOf(voiceId) < 0) {
5196
+ throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Invalid voiceId: " + voiceId);
4826
5197
  } else {
4827
5198
  return voiceId;
4828
5199
  }
@@ -4831,7 +5202,7 @@ function getExtensionTicks(extensionLength) {
4831
5202
  if (typeof extensionLength === "string") {
4832
5203
  extensionLength = [extensionLength];
4833
5204
  }
4834
- if (import_ts_utils_lib10.Utils.Is.isArray(extensionLength)) {
5205
+ if (import_ts_utils_lib12.Utils.Is.isArray(extensionLength)) {
4835
5206
  let totalTicks = 0;
4836
5207
  for (let i = 0; i < extensionLength.length; ) {
4837
5208
  let str = extensionLength[i];
@@ -4853,6 +5224,18 @@ function getExtensionTicks(extensionLength) {
4853
5224
  return extensionLength;
4854
5225
  }
4855
5226
  }
5227
+ function getVerseLayoutGroupId(verse) {
5228
+ switch (verse) {
5229
+ case 1:
5230
+ return 7 /* LyricsVerse1 */;
5231
+ case 2:
5232
+ return 8 /* LyricsVerse2 */;
5233
+ case 3:
5234
+ return 9 /* LyricsVerse3 */;
5235
+ default:
5236
+ throw new import_core14.MusicError(import_core14.MusicErrorType.Unknown, "VerseNumber is not 1, 2 or 3.");
5237
+ }
5238
+ }
4856
5239
  var _ObjMeasure = class _ObjMeasure extends MusicObject {
4857
5240
  constructor(row) {
4858
5241
  super(row);
@@ -4897,6 +5280,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
4897
5280
  // play twice.
4898
5281
  __publicField(this, "endRepeatPlayCountText");
4899
5282
  __publicField(this, "staticObjectsCache", /* @__PURE__ */ new Map());
5283
+ __publicField(this, "lyricsObjectsCache", /* @__PURE__ */ new Map());
4900
5284
  __publicField(this, "mi");
4901
5285
  this.mi = new MMeasure(this);
4902
5286
  this.prevMeasure = row.doc.getLastMeasure();
@@ -5080,7 +5464,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5080
5464
  this.alterKeySignature = args[0];
5081
5465
  } else if (args[0] instanceof import_theory9.Scale) {
5082
5466
  this.alterKeySignature = args[0];
5083
- } else if (import_ts_utils_lib10.Utils.Is.isNonEmptyString(args[0])) {
5467
+ } else if (import_ts_utils_lib12.Utils.Is.isNonEmptyString(args[0])) {
5084
5468
  if (args.length === 1) {
5085
5469
  this.alterKeySignature = (0, import_theory9.getScale)(args[0]);
5086
5470
  } else if (args.length === 2) {
@@ -5089,7 +5473,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5089
5473
  let scaleType = (0, import_theory9.validateScaleType)("" + args[1]);
5090
5474
  this.alterKeySignature = (0, import_theory9.getScale)(tonic, scaleType);
5091
5475
  } catch (e) {
5092
- throw new import_core13.MusicError(import_core13.MusicErrorType.Score, "Cannot set key signature because invalid args: " + args);
5476
+ throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Cannot set key signature because invalid args: " + args);
5093
5477
  }
5094
5478
  }
5095
5479
  }
@@ -5111,7 +5495,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5111
5495
  setTimeSignature(timeSignature) {
5112
5496
  var _a;
5113
5497
  (_a = this.getPrevMeasure()) == null ? void 0 : _a.endSection();
5114
- this.alterTimeSignature = timeSignature instanceof import_theory10.TimeSignature ? timeSignature : new import_theory10.TimeSignature(timeSignature);
5498
+ this.alterTimeSignature = timeSignature;
5115
5499
  this.updateTimeSignature();
5116
5500
  }
5117
5501
  updateTimeSignature() {
@@ -5191,7 +5575,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5191
5575
  let grp = this.doc.getStaffGroup(staffTabOrGroup);
5192
5576
  if (grp && !prevGroups.includes(staffTabOrGroup)) {
5193
5577
  let curGroups = [...prevGroups, staffTabOrGroup];
5194
- (import_ts_utils_lib10.Utils.Is.isArray(grp.staffsTabsAndGroups) ? grp.staffsTabsAndGroups : [grp.staffsTabsAndGroups]).forEach((staffTabOrGroup2) => {
5578
+ (import_ts_utils_lib12.Utils.Is.isArray(grp.staffsTabsAndGroups) ? grp.staffsTabsAndGroups : [grp.staffsTabsAndGroups]).forEach((staffTabOrGroup2) => {
5195
5579
  switch (grp.verticalPosition) {
5196
5580
  case "above" /* Above */:
5197
5581
  addToStaffTabOrGroup(staffTabOrGroup2, 0 /* Above */, curGroups);
@@ -5218,7 +5602,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5218
5602
  } else {
5219
5603
  addToStaffTabOrGroup(0, defaultVerticalPos);
5220
5604
  }
5221
- } else if (import_ts_utils_lib10.Utils.Is.isArray(staffTabOrGroups)) {
5605
+ } else if (import_ts_utils_lib12.Utils.Is.isArray(staffTabOrGroups)) {
5222
5606
  staffTabOrGroups.forEach((staffTabOrGroup) => addToStaffTabOrGroup(staffTabOrGroup, defaultVerticalPos));
5223
5607
  } else {
5224
5608
  addToStaffTabOrGroup(staffTabOrGroups, defaultVerticalPos);
@@ -5227,7 +5611,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5227
5611
  addFermata(staffTabOrGroups, fermata) {
5228
5612
  let anchor = fermata === "atMeasureEnd" /* AtMeasureEnd */ ? this.barLineRight : this.lastAddedRhythmColumn;
5229
5613
  if (!anchor) {
5230
- throw new import_core13.MusicError(import_core13.MusicErrorType.Score, "Cannot add Fermata because anchor is undefined.");
5614
+ throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Cannot add Fermata because anchor is undefined.");
5231
5615
  }
5232
5616
  this.forEachStaffGroup(staffTabOrGroups, 0 /* Above */, (line, vpos) => {
5233
5617
  this.addLayoutObject(new ObjFermata(anchor, vpos), line, 0 /* Fermata */, vpos);
@@ -5243,7 +5627,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5243
5627
  switch (navigation) {
5244
5628
  case "ending" /* Ending */:
5245
5629
  if (this.navigationSet.has(navigation)) {
5246
- throw new import_core13.MusicError(import_core13.MusicErrorType.Score, "Cannot add ending beasure measure already has one.");
5630
+ throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Cannot add ending beasure measure already has one.");
5247
5631
  }
5248
5632
  let anchor = this;
5249
5633
  let passages = args;
@@ -5302,10 +5686,10 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5302
5686
  case "endRepeat" /* EndRepeat */:
5303
5687
  if (args.length === 0) {
5304
5688
  this.endRepeatPlayCount = 2;
5305
- } else if (import_ts_utils_lib10.Utils.Is.isIntegerGte(args[0], 2)) {
5689
+ } else if (import_ts_utils_lib12.Utils.Is.isIntegerGte(args[0], 2)) {
5306
5690
  this.endRepeatPlayCount = args[0];
5307
5691
  } else {
5308
- throw new import_core13.MusicError(import_core13.MusicErrorType.Score, "Invalid end repeat play count (should be 2 or greater integer): " + args[0]);
5692
+ throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Invalid end repeat play count (should be 2 or greater integer): " + args[0]);
5309
5693
  }
5310
5694
  if (this.endRepeatPlayCount !== 2) {
5311
5695
  let textProps = {
@@ -5330,9 +5714,9 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5330
5714
  addAnnotation(staffTabOrGroups, annotation, text) {
5331
5715
  let anchor = this.lastAddedRhythmColumn;
5332
5716
  if (!anchor) {
5333
- throw new import_core13.MusicError(import_core13.MusicErrorType.Score, "Cannot add annotation because anchor is undefined.");
5717
+ throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Cannot add annotation because anchor is undefined.");
5334
5718
  } else if (text.length === 0) {
5335
- throw new import_core13.MusicError(import_core13.MusicErrorType.Score, "Cannot add annotation because annotation text is empty.");
5719
+ throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Cannot add annotation because annotation text is empty.");
5336
5720
  }
5337
5721
  let textProps = { text };
5338
5722
  let layoutGroupId;
@@ -5359,9 +5743,9 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5359
5743
  addLabel(staffTabOrGroups, label, text) {
5360
5744
  let anchor = this.lastAddedRhythmColumn;
5361
5745
  if (!anchor) {
5362
- throw new import_core13.MusicError(import_core13.MusicErrorType.Score, "Cannot add label because anchor is undefined.");
5746
+ throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Cannot add label because anchor is undefined.");
5363
5747
  } else if (text.length === 0) {
5364
- throw new import_core13.MusicError(import_core13.MusicErrorType.Score, "Cannot add label because label text is empty.");
5748
+ throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Cannot add label because label text is empty.");
5365
5749
  }
5366
5750
  let textProps = { text };
5367
5751
  let layoutGroupId;
@@ -5386,18 +5770,18 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5386
5770
  addConnective(connective, ...args) {
5387
5771
  let anchor = this.lastAddedRhythmSymbol;
5388
5772
  if (!(anchor instanceof ObjNoteGroup)) {
5389
- throw new import_core13.MusicError(import_core13.MusicErrorType.Score, "Connective can be added to note group only.");
5773
+ throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Connective can be added to note group only.");
5390
5774
  }
5391
5775
  if (connective === "tie" /* Tie */) {
5392
- let tieSpan = import_ts_utils_lib10.Utils.Is.isInteger(args[0]) || import_ts_utils_lib10.Utils.Is.isEnumValue(args[0], TieType) ? args[0] : 2;
5393
- let noteAnchor = import_ts_utils_lib10.Utils.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : "auto" /* Auto */;
5776
+ let tieSpan = import_ts_utils_lib12.Utils.Is.isInteger(args[0]) || import_ts_utils_lib12.Utils.Is.isEnumValue(args[0], TieType) ? args[0] : 2;
5777
+ let noteAnchor = import_ts_utils_lib12.Utils.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : "auto" /* Auto */;
5394
5778
  anchor.startConnective(new ConnectiveProps("tie" /* Tie */, tieSpan, noteAnchor, anchor));
5395
5779
  } else if (connective === "slur" /* Slur */) {
5396
- let slurSpan = import_ts_utils_lib10.Utils.Is.isInteger(args[0]) ? args[0] : 2;
5397
- let noteAnchor = import_ts_utils_lib10.Utils.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : "auto" /* Auto */;
5780
+ let slurSpan = import_ts_utils_lib12.Utils.Is.isInteger(args[0]) ? args[0] : 2;
5781
+ let noteAnchor = import_ts_utils_lib12.Utils.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : "auto" /* Auto */;
5398
5782
  anchor.startConnective(new ConnectiveProps("slur" /* Slur */, slurSpan, noteAnchor, anchor));
5399
5783
  } else if (connective === "slide" /* Slide */) {
5400
- let noteAnchor = import_ts_utils_lib10.Utils.Is.isEnumValue(args[0], NoteAnchor) ? args[0] : "auto" /* Auto */;
5784
+ let noteAnchor = import_ts_utils_lib12.Utils.Is.isEnumValue(args[0], NoteAnchor) ? args[0] : "auto" /* Auto */;
5401
5785
  anchor.startConnective(new ConnectiveProps("slide" /* Slide */, 2, noteAnchor, anchor));
5402
5786
  }
5403
5787
  }
@@ -5410,11 +5794,11 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5410
5794
  let extension = new Extension(musicObj, anchor, getExtensionTicks(extensionLength), extensionVisible, lineStyle, linePos);
5411
5795
  musicObj.setLink(extension);
5412
5796
  } else {
5413
- throw new import_core13.MusicError(import_core13.MusicErrorType.Score, "Cannot add extension becaue no compatible music object to attach it to.");
5797
+ throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Cannot add extension becaue no compatible music object to attach it to.");
5414
5798
  }
5415
5799
  });
5416
5800
  if (this.addExtensionToMusicObjects.length === 0) {
5417
- throw new import_core13.MusicError(import_core13.MusicErrorType.Score, "Cannot add extension because music object to attach it to is undefined.");
5801
+ throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Cannot add extension because music object to attach it to is undefined.");
5418
5802
  }
5419
5803
  this.disableExtension();
5420
5804
  this.requestLayout();
@@ -5451,10 +5835,11 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5451
5835
  this.doc.requestNewRow();
5452
5836
  this.disableExtension();
5453
5837
  }
5454
- addRhythmSymbol(voiceId, symbol) {
5455
- let { col } = symbol;
5838
+ addRhythmSymbol(symbol) {
5839
+ var _a, _b;
5840
+ let { col, voiceId } = symbol;
5456
5841
  col.setVoiceSymbol(voiceId, symbol);
5457
- this.getVoiceSymbols(voiceId);
5842
+ (_b = (_a = this.voiceSymbols)[voiceId]) != null ? _b : _a[voiceId] = [];
5458
5843
  this.voiceSymbols[voiceId].push(symbol);
5459
5844
  if (symbol.oldStyleTriplet) {
5460
5845
  this.createOldStyleTriplets(voiceId);
@@ -5467,25 +5852,40 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5467
5852
  let realNotes = notes.map((note) => typeof note === "string" ? import_theory9.Note.getNote(note) : note);
5468
5853
  let col = this.getRhythmColumn(voiceId);
5469
5854
  let noteGroup = new ObjNoteGroup(col, voiceId, realNotes, noteLength, options, tupletRatio);
5470
- this.addRhythmSymbol(voiceId, noteGroup);
5855
+ this.addRhythmSymbol(noteGroup);
5471
5856
  return noteGroup;
5472
5857
  }
5473
5858
  addRest(voiceId, restLength, options, tupletRatio) {
5474
5859
  let col = this.getRhythmColumn(voiceId);
5475
5860
  let rest = new ObjRest(col, voiceId, restLength, options, tupletRatio);
5476
- this.addRhythmSymbol(voiceId, rest);
5861
+ this.addRhythmSymbol(rest);
5477
5862
  return rest;
5478
5863
  }
5864
+ addLyrics(staffTabOrGroups, verse, lyricsLength, lyricsText, lyricsOptions) {
5865
+ this.forEachStaffGroup(staffTabOrGroups, 1 /* Below */, (line, vpos) => {
5866
+ let col = this.getRhythmColumn({ verse, line, vpos });
5867
+ let lyricsContainer = col.getLyricsContainer(verse, line, vpos, (0, import_theory9.validateNoteLength)(lyricsLength));
5868
+ if (lyricsContainer) {
5869
+ let lyricsObj = new ObjLyrics(col, verse, line, vpos, lyricsText, lyricsOptions);
5870
+ let lyricsArr = this.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
5871
+ lyricsArr.push(lyricsObj);
5872
+ lyricsArr.sort((a, b) => cmp2(a.col.positionTicks, b.col.positionTicks));
5873
+ lyricsContainer.addLyricsObject(lyricsObj);
5874
+ this.addLayoutObject(lyricsObj, line, getVerseLayoutGroupId(verse), vpos);
5875
+ }
5876
+ this.lastAddedRhythmColumn = col;
5877
+ });
5878
+ }
5479
5879
  /**
5480
5880
  *
5481
5881
  * @param positionTicks - get ObjRhythmColumn with positionTicks. Insert new if necessary.
5482
5882
  * @returns
5483
5883
  */
5484
- getRhythmColumn(voiceId) {
5884
+ getRhythmColumn(arg) {
5485
5885
  let positionTicks = 0;
5486
5886
  for (let i = this.columns.length - 1; i >= 0 && positionTicks === 0; i--) {
5487
5887
  let col = this.columns[i];
5488
- let symbol = col.getVoiceSymbol(voiceId);
5888
+ let symbol = typeof arg === "number" ? col.getVoiceSymbol(arg) : col.getLyricsContainer(arg.verse, arg.line, arg.vpos);
5489
5889
  if (symbol) {
5490
5890
  positionTicks = col.positionTicks + symbol.rhythmProps.ticks;
5491
5891
  }
@@ -5500,7 +5900,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5500
5900
  return col2;
5501
5901
  }
5502
5902
  }
5503
- throw new import_core13.MusicError(import_core13.MusicErrorType.Score, "Error in rhythm column. Should never get here.");
5903
+ throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Error in rhythm column. Should never get here.");
5504
5904
  }
5505
5905
  getMeasureTicks() {
5506
5906
  return this.getTimeSignature().measureTicks;
@@ -5552,6 +5952,38 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5552
5952
  getStaffLineRight() {
5553
5953
  return this.barLineRight.getRect().centerX;
5554
5954
  }
5955
+ getLyricsObjects(line, vpos, verse) {
5956
+ let vposMap = this.lyricsObjectsCache.get(line);
5957
+ if (vposMap === void 0) {
5958
+ vposMap = /* @__PURE__ */ new Map();
5959
+ this.lyricsObjectsCache.set(line, vposMap);
5960
+ }
5961
+ let verseMap = vposMap.get(vpos);
5962
+ if (verseMap === void 0) {
5963
+ verseMap = /* @__PURE__ */ new Map();
5964
+ vposMap.set(vpos, verseMap);
5965
+ }
5966
+ let lyricsArr = verseMap.get(verse);
5967
+ if (lyricsArr === void 0) {
5968
+ lyricsArr = [];
5969
+ verseMap.set(verse, lyricsArr);
5970
+ }
5971
+ return lyricsArr;
5972
+ }
5973
+ getPrevLyricsObject(lyricsObj) {
5974
+ var _a;
5975
+ let lyricsArr = this.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
5976
+ let i = lyricsArr.indexOf(lyricsObj);
5977
+ if (i > 0) {
5978
+ return lyricsArr[i - 1];
5979
+ } else if (i === 0) {
5980
+ let lyricsArr2 = (_a = lyricsObj.measure.getPrevMeasure()) == null ? void 0 : _a.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
5981
+ if (lyricsArr2 && lyricsArr2.length > 0) {
5982
+ return lyricsArr2[lyricsArr2.length - 1];
5983
+ }
5984
+ }
5985
+ return void 0;
5986
+ }
5555
5987
  getStaticObjects(line) {
5556
5988
  let staticObjects = this.staticObjectsCache.get(line);
5557
5989
  if (!staticObjects) {
@@ -5641,52 +6073,77 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5641
6073
  return false;
5642
6074
  }
5643
6075
  });
6076
+ let ts = this.getTimeSignature();
6077
+ if (!this.needBeamsUpdate || ts.beamGroupSizes.length === 0) {
6078
+ return;
6079
+ }
5644
6080
  getVoiceIds().forEach((voiceId) => {
5645
- let symbols = this.getVoiceSymbols(voiceId);
5646
- if (symbols.length <= 2) {
5647
- return;
5648
- }
5649
- if (!DebugSettings.DisableBeams) {
5650
- let groupSymbols = [];
6081
+ let symbols = this.getVoiceSymbols(voiceId).slice();
6082
+ if (symbols.length >= 2) {
6083
+ let symbolsStartTicks = this.isUpBeat() ? Math.max(0, this.getMeasureTicks() - this.getConsumedTicks()) : 0;
5651
6084
  let groupStartTicks = 0;
5652
- let groupEndTicks = 0;
5653
- if (this.isUpBeat()) {
5654
- let startTicks = Math.max(0, this.getMeasureTicks() - this.getConsumedTicks());
5655
- groupStartTicks = groupEndTicks = startTicks;
5656
- }
5657
- let ts = this.getTimeSignature();
5658
- symbols.forEach((symbol) => {
5659
- groupSymbols.push(symbol);
5660
- groupEndTicks += symbol.rhythmProps.ticks;
5661
- if (groupStartTicks === 0 && groupEndTicks === ts.beamGroupLength) {
5662
- _ObjMeasure.setupBeamGroup(groupSymbols);
5663
- }
5664
- while (groupEndTicks >= ts.beamGroupLength) {
5665
- groupSymbols = [];
5666
- groupStartTicks = groupEndTicks = groupEndTicks - ts.beamGroupLength;
6085
+ for (let groupId = 0; groupId < ts.beamGroupSizes.length; groupId++) {
6086
+ let beamGroupSize = ts.beamGroupSizes[groupId];
6087
+ let groupSizeSum = 0;
6088
+ beamGroupSize.forEach((s) => groupSizeSum += s);
6089
+ let groupLength = groupSizeSum * import_theory9.NoteLengthProps.get("8n").ticks;
6090
+ let groupSymbols = [];
6091
+ let groupSymbolsLength = 0;
6092
+ while (symbols.length > 0 && groupSymbolsLength < groupLength) {
6093
+ let symbol = symbols[0];
6094
+ if (symbol.col.positionTicks >= groupStartTicks) {
6095
+ groupSymbols.push(symbol);
6096
+ groupSymbolsLength += symbol.rhythmProps.ticks;
6097
+ symbols.shift();
6098
+ } else {
6099
+ break;
6100
+ }
5667
6101
  }
5668
- });
6102
+ _ObjMeasure.setupBeamGroup(groupSymbols, beamGroupSize);
6103
+ symbolsStartTicks += groupSymbolsLength;
6104
+ groupStartTicks += groupLength;
6105
+ }
5669
6106
  }
5670
6107
  });
5671
6108
  this.needBeamsUpdate = false;
5672
6109
  this.requestLayout();
5673
6110
  }
5674
- static setupBeamGroup(groupSymbols) {
6111
+ static setupBeamGroup(groupSymbols, mainBeamGroupSizeArr) {
6112
+ if (mainBeamGroupSizeArr.length === 0) {
6113
+ return false;
6114
+ }
5675
6115
  let groupNotes = groupSymbols.map((s) => {
5676
6116
  var _a;
5677
6117
  return s instanceof ObjNoteGroup && ((_a = s.getBeamGroup()) == null ? void 0 : _a.isTuplet()) !== true ? s : void 0;
5678
6118
  });
5679
6119
  ObjNoteGroup.setBeamCounts(groupNotes);
5680
- let beamNotes = [];
5681
- groupNotes.forEach((noteGroup) => {
5682
- if (noteGroup && noteGroup.hasBeamCount()) {
5683
- beamNotes.push(noteGroup);
5684
- } else {
5685
- ObjBeamGroup.createBeam(beamNotes);
5686
- beamNotes = [];
5687
- }
5688
- });
5689
- ObjBeamGroup.createBeam(beamNotes);
6120
+ let beamGroupSizeArrList = [mainBeamGroupSizeArr];
6121
+ if (mainBeamGroupSizeArr.length > 1) {
6122
+ let sum = 0;
6123
+ mainBeamGroupSizeArr.forEach((s) => sum += s);
6124
+ beamGroupSizeArrList.unshift([sum]);
6125
+ }
6126
+ let beamsCreated = false;
6127
+ while (beamGroupSizeArrList.length > 0 && !beamsCreated) {
6128
+ let beamGroupSizeArr = beamGroupSizeArrList.shift();
6129
+ let groupSymbolsCopy = groupSymbols.slice();
6130
+ beamGroupSizeArr.forEach((beamGroupSize) => {
6131
+ var _a;
6132
+ let beamGroupLength = beamGroupSize * import_theory9.NoteLengthProps.get("8n").ticks;
6133
+ let beamNotesLength = 0;
6134
+ let beamNotes = [];
6135
+ while (beamNotesLength < beamGroupLength && groupSymbolsCopy.length > 0) {
6136
+ let symbol = groupSymbolsCopy.shift();
6137
+ beamNotesLength += symbol.rhythmProps.ticks;
6138
+ beamNotes.push(symbol instanceof ObjNoteGroup && ((_a = symbol.getBeamGroup()) == null ? void 0 : _a.isTuplet()) !== true ? symbol : void 0);
6139
+ }
6140
+ if (beamNotesLength === beamGroupLength && beamNotes.every((n) => n !== void 0) && (beamNotes.every((n) => n.rhythmProps.flagCount === 1) || beamGroupSizeArrList.length === 0)) {
6141
+ ObjBeamGroup.createBeam(beamNotes);
6142
+ beamsCreated = true;
6143
+ }
6144
+ });
6145
+ }
6146
+ return beamsCreated;
5690
6147
  }
5691
6148
  getBarLineLeft() {
5692
6149
  return this.barLineLeft;
@@ -5695,10 +6152,9 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5695
6152
  return this.barLineRight;
5696
6153
  }
5697
6154
  getVoiceSymbols(voiceId) {
6155
+ var _a, _b;
5698
6156
  validateVoiceId(voiceId);
5699
- if (this.voiceSymbols[voiceId] === void 0) {
5700
- this.voiceSymbols[voiceId] = [];
5701
- }
6157
+ (_b = (_a = this.voiceSymbols)[voiceId]) != null ? _b : _a[voiceId] = [];
5702
6158
  return this.voiceSymbols[voiceId];
5703
6159
  }
5704
6160
  completeRests(voiceId) {
@@ -5709,7 +6165,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5709
6165
  this.completeRests(getVoiceIds().filter((id) => this.getConsumedTicks(id) > 0));
5710
6166
  }
5711
6167
  return;
5712
- } else if (import_ts_utils_lib10.Utils.Is.isArray(voiceId)) {
6168
+ } else if (import_ts_utils_lib12.Utils.Is.isArray(voiceId)) {
5713
6169
  voiceId.forEach((id) => this.completeRests(id));
5714
6170
  return;
5715
6171
  } else {
@@ -5824,7 +6280,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5824
6280
  let columnsAreaLeft = this.rect.left + this.leftSolidAreaWidth;
5825
6281
  let columnsAreaRight = this.rect.right - this.rightSolidAreaWidth;
5826
6282
  let columnsAreaWidth = columnsAreaRight - columnsAreaLeft;
5827
- let columnsWidth = import_ts_utils_lib10.Utils.Math.sum(this.columns.map((col) => col.getRect().width));
6283
+ let columnsWidth = import_ts_utils_lib12.Utils.Math.sum(this.columns.map((col) => col.getRect().width));
5828
6284
  let columnScale = columnsAreaWidth / columnsWidth;
5829
6285
  let columnLeft = columnsAreaLeft;
5830
6286
  this.columns.forEach((col) => {
@@ -5943,9 +6399,21 @@ __publicField(_ObjMeasure, "MinFlexContentWidth", 10);
5943
6399
  var ObjMeasure2 = _ObjMeasure;
5944
6400
 
5945
6401
  // src/score/engine/layout-object.ts
5946
- var import_core14 = require("@tspro/web-music-score/core");
5947
- var WidenColumnList = [1 /* NoteLabel */, 6 /* ChordLabel */];
5948
- var RowAlignList = [2 /* Navigation */, 3 /* Ending */, 4 /* TempoAnnotation */, 5 /* DynamicsAnnotation */, 6 /* ChordLabel */];
6402
+ var import_core15 = require("@tspro/web-music-score/core");
6403
+ var WidenColumnList = [
6404
+ 1 /* NoteLabel */,
6405
+ 6 /* ChordLabel */
6406
+ ];
6407
+ var RowAlignList = [
6408
+ 2 /* Navigation */,
6409
+ 3 /* Ending */,
6410
+ 4 /* TempoAnnotation */,
6411
+ 5 /* DynamicsAnnotation */,
6412
+ 6 /* ChordLabel */,
6413
+ 7 /* LyricsVerse1 */,
6414
+ 8 /* LyricsVerse2 */,
6415
+ 9 /* LyricsVerse3 */
6416
+ ];
5949
6417
  function requireParentMeasure(p) {
5950
6418
  while (p) {
5951
6419
  if (p instanceof ObjMeasure2) {
@@ -5953,7 +6421,7 @@ function requireParentMeasure(p) {
5953
6421
  }
5954
6422
  p = p.getParent();
5955
6423
  }
5956
- throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Parent measure is required but not found!");
6424
+ throw new import_core15.MusicError(import_core15.MusicErrorType.Score, "Parent measure is required but not found!");
5957
6425
  }
5958
6426
  var StaffGroup = class {
5959
6427
  constructor(groupName, staffsTabsAndGroups, verticalPosition) {
@@ -5977,7 +6445,7 @@ var LayoutObjectWrapper = class {
5977
6445
  this.row = this.measure.row;
5978
6446
  let anchor = this.musicObj.getParent();
5979
6447
  if (!anchor) {
5980
- throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Parent music object is required as an anchor.");
6448
+ throw new import_core15.MusicError(import_core15.MusicErrorType.Score, "Parent music object is required as an anchor.");
5981
6449
  }
5982
6450
  this.anchor = anchor;
5983
6451
  this.anchor.addAnchoredLayoutObject(this);
@@ -6169,7 +6637,7 @@ var ObjStaff = class extends ObjNotationLine4 {
6169
6637
  this.clefLineDiatonicId = getDiatonicId("F3", staffConfig.isOctaveDown === true);
6170
6638
  this.middleLineDiatonicId = this.clefLineDiatonicId - 2;
6171
6639
  } else {
6172
- throw new import_core15.MusicError(import_core15.MusicErrorType.Score, `Invalid staffConfig.clef ${staffConfig.clef}.`);
6640
+ throw new import_core16.MusicError(import_core16.MusicErrorType.Score, `Invalid staffConfig.clef ${staffConfig.clef}.`);
6173
6641
  }
6174
6642
  this.topLineDiatonicId = this.middleLineDiatonicId + 4;
6175
6643
  this.bottomLineDiatonicId = this.middleLineDiatonicId - 4;
@@ -6217,7 +6685,7 @@ var ObjStaff = class extends ObjNotationLine4 {
6217
6685
  } else if (this.joinedGrandStaff && this.joinedGrandStaff.containsDiatonicId(diatonicId)) {
6218
6686
  return this.joinedGrandStaff.getDiatonicIdY(diatonicId);
6219
6687
  } else {
6220
- throw new import_core15.MusicError(import_core15.MusicErrorType.Score, "Staff does not contain diatonicId " + diatonicId);
6688
+ throw new import_core16.MusicError(import_core16.MusicErrorType.Score, "Staff does not contain diatonicId " + diatonicId);
6221
6689
  }
6222
6690
  }
6223
6691
  getActualStaff(diatonicId) {
@@ -6226,7 +6694,7 @@ var ObjStaff = class extends ObjNotationLine4 {
6226
6694
  } else if (this.joinedGrandStaff && this.joinedGrandStaff.containsDiatonicId(diatonicId)) {
6227
6695
  return this.joinedGrandStaff;
6228
6696
  } else {
6229
- throw new import_core15.MusicError(import_core15.MusicErrorType.Score, "Staff does not contain diatonicId " + diatonicId);
6697
+ throw new import_core16.MusicError(import_core16.MusicErrorType.Score, "Staff does not contain diatonicId " + diatonicId);
6230
6698
  }
6231
6699
  }
6232
6700
  getDiatonicIdAt(y) {
@@ -6305,7 +6773,7 @@ var ObjTab = class extends ObjNotationLine4 {
6305
6773
  __publicField(this, "tuningName");
6306
6774
  __publicField(this, "tuningStrings");
6307
6775
  __publicField(this, "mi");
6308
- if (import_ts_utils_lib11.Utils.Is.isArray(tabConfig.tuning)) {
6776
+ if (import_ts_utils_lib13.Utils.Is.isArray(tabConfig.tuning)) {
6309
6777
  this.tuningName = void 0;
6310
6778
  this.tuningStrings = tabConfig.tuning.map((noteName) => import_theory11.Note.getNote(noteName)).reverse();
6311
6779
  } else if (typeof tabConfig.tuning === "string") {
@@ -6395,7 +6863,7 @@ var ObjTab = class extends ObjNotationLine4 {
6395
6863
  };
6396
6864
 
6397
6865
  // src/score/engine/obj-score-row.ts
6398
- var import_core16 = require("@tspro/web-music-score/core");
6866
+ var import_core17 = require("@tspro/web-music-score/core");
6399
6867
  var ObjScoreRow = class extends MusicObject {
6400
6868
  constructor(doc, prevRow, scoreConfig) {
6401
6869
  super(doc);
@@ -6453,7 +6921,7 @@ var ObjScoreRow = class extends MusicObject {
6453
6921
  if (topStaff) {
6454
6922
  return topStaff;
6455
6923
  } else {
6456
- throw new import_core16.MusicError(import_core16.MusicErrorType.Score, "Top staff is required!");
6924
+ throw new import_core17.MusicError(import_core17.MusicErrorType.Score, "Top staff is required!");
6457
6925
  }
6458
6926
  }
6459
6927
  getBottomStaff() {
@@ -6461,7 +6929,7 @@ var ObjScoreRow = class extends MusicObject {
6461
6929
  if (bottomStaff) {
6462
6930
  return bottomStaff;
6463
6931
  } else {
6464
- throw new import_core16.MusicError(import_core16.MusicErrorType.Score, "Bottom staff is required!");
6932
+ throw new import_core17.MusicError(import_core17.MusicErrorType.Score, "Bottom staff is required!");
6465
6933
  }
6466
6934
  }
6467
6935
  getStaff(diatonicId) {
@@ -6760,7 +7228,7 @@ var ObjHeader = class extends MusicObject {
6760
7228
  };
6761
7229
 
6762
7230
  // src/score/engine/obj-document.ts
6763
- var import_ts_utils_lib12 = require("@tspro/ts-utils-lib");
7231
+ var import_ts_utils_lib14 = require("@tspro/ts-utils-lib");
6764
7232
  var ObjDocument = class extends MusicObject {
6765
7233
  constructor() {
6766
7234
  super(void 0);
@@ -6781,7 +7249,7 @@ var ObjDocument = class extends MusicObject {
6781
7249
  return this.mi;
6782
7250
  }
6783
7251
  setScoreConfiguration(config) {
6784
- if (import_ts_utils_lib12.Utils.Is.isEnumValue(config, StaffPreset)) {
7252
+ if (import_ts_utils_lib14.Utils.Is.isEnumValue(config, StaffPreset)) {
6785
7253
  switch (config) {
6786
7254
  default:
6787
7255
  case "treble" /* Treble */:
@@ -6809,7 +7277,7 @@ var ObjDocument = class extends MusicObject {
6809
7277
  ];
6810
7278
  break;
6811
7279
  }
6812
- } else if (import_ts_utils_lib12.Utils.Is.isArray(config)) {
7280
+ } else if (import_ts_utils_lib14.Utils.Is.isArray(config)) {
6813
7281
  this.curScoreConfig = config;
6814
7282
  } else {
6815
7283
  this.curScoreConfig = [config];
@@ -7036,10 +7504,10 @@ var ObjDocument = class extends MusicObject {
7036
7504
 
7037
7505
  // src/score/pub/document-builder.ts
7038
7506
  var import_theory13 = require("@tspro/web-music-score/theory");
7039
- var import_core17 = require("@tspro/web-music-score/core");
7507
+ var import_core18 = require("@tspro/web-music-score/core");
7040
7508
  function assertArg(condition, argName, argValue) {
7041
7509
  if (!condition) {
7042
- throw new import_core17.MusicError(import_core17.MusicErrorType.Score, `Invalid arg: ${argName} = ${argValue}`);
7510
+ throw new import_core18.MusicError(import_core18.MusicErrorType.Score, `Invalid arg: ${argName} = ${argValue}`);
7043
7511
  }
7044
7512
  }
7045
7513
  function isNote(note) {
@@ -7051,56 +7519,64 @@ function isNote(note) {
7051
7519
  }
7052
7520
  }
7053
7521
  function isVoiceId(value) {
7054
- return import_ts_utils_lib13.Utils.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
7522
+ return import_ts_utils_lib15.Utils.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
7055
7523
  }
7056
7524
  function isStringNumber(value) {
7057
- return import_ts_utils_lib13.Utils.Is.isNumber(value) && getStringNumbers().indexOf(value) >= 0;
7525
+ return import_ts_utils_lib15.Utils.Is.isNumber(value) && getStringNumbers().indexOf(value) >= 0;
7526
+ }
7527
+ function isVerseNumber(value) {
7528
+ return import_ts_utils_lib15.Utils.Is.isNumber(value) && getVerseNumbers().indexOf(value) >= 0;
7058
7529
  }
7059
7530
  function assertStaffConfig(staffConfig) {
7060
- assertArg(import_ts_utils_lib13.Utils.Is.isObject(staffConfig), "staffConfig", staffConfig);
7531
+ assertArg(import_ts_utils_lib15.Utils.Is.isObject(staffConfig), "staffConfig", staffConfig);
7061
7532
  assertArg(staffConfig.type === "staff", "staffConfig.type", staffConfig.type);
7062
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(staffConfig.clef, Clef), "staffConfig.clef", staffConfig.clef);
7063
- assertArg(import_ts_utils_lib13.Utils.Is.isBooleanOrUndefined(staffConfig.isOctaveDown), "staffConfig.isOctaveDown", staffConfig.isOctaveDown);
7064
- assertArg(import_ts_utils_lib13.Utils.Is.isUndefined(staffConfig.minNote) || isNote(staffConfig.minNote), "staffConfig.minNote", staffConfig.minNote);
7065
- assertArg(import_ts_utils_lib13.Utils.Is.isUndefined(staffConfig.maxNote) || isNote(staffConfig.maxNote), "staffConfig.maxNote", staffConfig.maxNote);
7066
- assertArg(import_ts_utils_lib13.Utils.Is.isUndefined(staffConfig.voiceIds) || import_ts_utils_lib13.Utils.Is.isArray(staffConfig.voiceIds) && staffConfig.voiceIds.every((voiceId) => import_ts_utils_lib13.Utils.Is.isNumber(voiceId)), "staffConfig.voiceIds", staffConfig.voiceIds);
7067
- assertArg(import_ts_utils_lib13.Utils.Is.isBooleanOrUndefined(staffConfig.isGrand), "staffConfig.isGrand", staffConfig.isGrand);
7533
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(staffConfig.clef, Clef), "staffConfig.clef", staffConfig.clef);
7534
+ assertArg(import_ts_utils_lib15.Utils.Is.isBooleanOrUndefined(staffConfig.isOctaveDown), "staffConfig.isOctaveDown", staffConfig.isOctaveDown);
7535
+ assertArg(import_ts_utils_lib15.Utils.Is.isUndefined(staffConfig.minNote) || isNote(staffConfig.minNote), "staffConfig.minNote", staffConfig.minNote);
7536
+ assertArg(import_ts_utils_lib15.Utils.Is.isUndefined(staffConfig.maxNote) || isNote(staffConfig.maxNote), "staffConfig.maxNote", staffConfig.maxNote);
7537
+ assertArg(import_ts_utils_lib15.Utils.Is.isUndefined(staffConfig.voiceIds) || import_ts_utils_lib15.Utils.Is.isArray(staffConfig.voiceIds) && staffConfig.voiceIds.every((voiceId) => import_ts_utils_lib15.Utils.Is.isNumber(voiceId)), "staffConfig.voiceIds", staffConfig.voiceIds);
7538
+ assertArg(import_ts_utils_lib15.Utils.Is.isBooleanOrUndefined(staffConfig.isGrand), "staffConfig.isGrand", staffConfig.isGrand);
7068
7539
  }
7069
7540
  function assertTabConfig(tabConfig) {
7070
- assertArg(import_ts_utils_lib13.Utils.Is.isObject(tabConfig), "tabConfig", tabConfig);
7541
+ assertArg(import_ts_utils_lib15.Utils.Is.isObject(tabConfig), "tabConfig", tabConfig);
7071
7542
  assertArg(tabConfig.type === "tab", "tabConfig.type", tabConfig.type);
7072
7543
  if (typeof tabConfig.tuning === "string") {
7073
7544
  assertArg(import_theory13.TuningNameList.includes(tabConfig.tuning), "tabConfig.tuning", tabConfig.tuning);
7074
- } else if (import_ts_utils_lib13.Utils.Is.isArray(tabConfig.tuning)) {
7545
+ } else if (import_ts_utils_lib15.Utils.Is.isArray(tabConfig.tuning)) {
7075
7546
  assertArg(tabConfig.tuning.length === getStringNumbers().length && tabConfig.tuning.every((s) => isNote(s)), "tabConfig.tuning", tabConfig.tuning);
7076
7547
  }
7077
- assertArg(import_ts_utils_lib13.Utils.Is.isUndefined(tabConfig.voiceIds) || import_ts_utils_lib13.Utils.Is.isArray(tabConfig.voiceIds) && tabConfig.voiceIds.every((voiceId) => import_ts_utils_lib13.Utils.Is.isNumber(voiceId)), "tabConfig.voiceIds", tabConfig.voiceIds);
7548
+ assertArg(import_ts_utils_lib15.Utils.Is.isUndefined(tabConfig.voiceIds) || import_ts_utils_lib15.Utils.Is.isArray(tabConfig.voiceIds) && tabConfig.voiceIds.every((voiceId) => import_ts_utils_lib15.Utils.Is.isNumber(voiceId)), "tabConfig.voiceIds", tabConfig.voiceIds);
7549
+ }
7550
+ function assertNoteOptions(noteOptions) {
7551
+ assertArg(import_ts_utils_lib15.Utils.Is.isObject(noteOptions), "noteOptions", noteOptions);
7552
+ assertArg(import_ts_utils_lib15.Utils.Is.isBooleanOrUndefined(noteOptions.dotted) || import_ts_utils_lib15.Utils.Is.isIntegerGte(noteOptions.dotted, 0), "noteOptions.dotted", noteOptions.dotted);
7553
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValueOrUndefined(noteOptions.stem, Stem), "noteOptions.stem", noteOptions.stem);
7554
+ assertArg(import_ts_utils_lib15.Utils.Is.isStringOrUndefined(noteOptions.color), "noteOptions.color", noteOptions.color);
7555
+ assertArg(import_ts_utils_lib15.Utils.Is.isBooleanOrUndefined(noteOptions.arpeggio) || import_ts_utils_lib15.Utils.Is.isEnumValue(noteOptions.arpeggio, Arpeggio), "noteOptions.arpeggio", noteOptions.arpeggio);
7556
+ assertArg(import_ts_utils_lib15.Utils.Is.isBooleanOrUndefined(noteOptions.staccato), "noteOptions.staccato", noteOptions.staccato);
7557
+ assertArg(import_ts_utils_lib15.Utils.Is.isBooleanOrUndefined(noteOptions.diamond), "noteOptions.diamond", noteOptions.diamond);
7558
+ assertArg(import_ts_utils_lib15.Utils.Is.isBooleanOrUndefined(noteOptions.triplet), "noteOptions.triplet", noteOptions.triplet);
7559
+ assertArg(import_ts_utils_lib15.Utils.Is.isUndefined(noteOptions.string) || isStringNumber(noteOptions.string) || import_ts_utils_lib15.Utils.Is.isNonEmptyArray(noteOptions.string) && noteOptions.string.every((string) => isStringNumber(string)), "noteOptions.string", noteOptions.string);
7560
+ assertArg(import_ts_utils_lib15.Utils.Is.isUndefined(noteOptions.tieSpan), 'NoteOptions.tieSpan was removed. Use addConnective("tie", tieSpan)', "");
7561
+ assertArg(import_ts_utils_lib15.Utils.Is.isUndefined(noteOptions.slurSpan), 'NoteOptions.slurSpan was removed. Use addConnective("slur", slurSpan)', "");
7078
7562
  }
7079
- function assertNoteOptions(options) {
7080
- assertArg(import_ts_utils_lib13.Utils.Is.isObject(options), "noteOptions", options);
7081
- assertArg(import_ts_utils_lib13.Utils.Is.isBooleanOrUndefined(options.dotted) || import_ts_utils_lib13.Utils.Is.isIntegerGte(options.dotted, 0), "noteOptions.dotted", options.dotted);
7082
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValueOrUndefined(options.stem, Stem), "noteOptions.stem", options.stem);
7083
- assertArg(import_ts_utils_lib13.Utils.Is.isStringOrUndefined(options.color), "noteOptions.color", options.color);
7084
- assertArg(import_ts_utils_lib13.Utils.Is.isBooleanOrUndefined(options.arpeggio) || import_ts_utils_lib13.Utils.Is.isEnumValue(options.arpeggio, Arpeggio), "noteOptions.arpeggio", options.arpeggio);
7085
- assertArg(import_ts_utils_lib13.Utils.Is.isBooleanOrUndefined(options.staccato), "noteOptions.staccato", options.staccato);
7086
- assertArg(import_ts_utils_lib13.Utils.Is.isBooleanOrUndefined(options.diamond), "noteOptions.diamond", options.diamond);
7087
- assertArg(import_ts_utils_lib13.Utils.Is.isBooleanOrUndefined(options.triplet), "noteOptions.triplet", options.triplet);
7088
- assertArg(import_ts_utils_lib13.Utils.Is.isUndefined(options.string) || isStringNumber(options.string) || import_ts_utils_lib13.Utils.Is.isNonEmptyArray(options.string) && options.string.every((string) => isStringNumber(string)), "noteOptions.string", options.string);
7089
- assertArg(import_ts_utils_lib13.Utils.Is.isUndefined(options.tieSpan), 'NoteOptions.tieSpan was removed. Use addConnective("tie", tieSpan)', "");
7090
- assertArg(import_ts_utils_lib13.Utils.Is.isUndefined(options.slurSpan), 'NoteOptions.slurSpan was removed. Use addConnective("slur", slurSpan)', "");
7563
+ function assertRestOptions(restOptions) {
7564
+ assertArg(import_ts_utils_lib15.Utils.Is.isObject(restOptions), "restOptions", restOptions);
7565
+ assertArg(import_ts_utils_lib15.Utils.Is.isBooleanOrUndefined(restOptions.dotted) || import_ts_utils_lib15.Utils.Is.isIntegerGte(restOptions.dotted, 0), "restOptions.dotted", restOptions.dotted);
7566
+ assertArg(import_ts_utils_lib15.Utils.Is.isStringOrUndefined(restOptions.staffPos) || import_ts_utils_lib15.Utils.Is.isInteger(restOptions.staffPos) || restOptions.staffPos instanceof import_theory13.Note, "restOptions.staffPos", restOptions.staffPos);
7567
+ assertArg(import_ts_utils_lib15.Utils.Is.isStringOrUndefined(restOptions.color), "restOptions.color", restOptions.color);
7568
+ assertArg(import_ts_utils_lib15.Utils.Is.isBooleanOrUndefined(restOptions.hide), "restOptions.hide", restOptions.hide);
7569
+ assertArg(import_ts_utils_lib15.Utils.Is.isBooleanOrUndefined(restOptions.triplet), "restOptions.triplet", restOptions.triplet);
7091
7570
  }
7092
- function assertRestOptions(options) {
7093
- assertArg(import_ts_utils_lib13.Utils.Is.isObject(options), "restOptions", options);
7094
- assertArg(import_ts_utils_lib13.Utils.Is.isBooleanOrUndefined(options.dotted) || import_ts_utils_lib13.Utils.Is.isIntegerGte(options.dotted, 0), "restOptions.dotted", options.dotted);
7095
- assertArg(import_ts_utils_lib13.Utils.Is.isStringOrUndefined(options.staffPos) || import_ts_utils_lib13.Utils.Is.isInteger(options.staffPos) || options.staffPos instanceof import_theory13.Note, "restOptions.staffPos", options.staffPos);
7096
- assertArg(import_ts_utils_lib13.Utils.Is.isStringOrUndefined(options.color), "restOptions.color", options.color);
7097
- assertArg(import_ts_utils_lib13.Utils.Is.isBooleanOrUndefined(options.hide), "restOptions.hide", options.hide);
7098
- assertArg(import_ts_utils_lib13.Utils.Is.isBooleanOrUndefined(options.triplet), "restOptions.triplet", options.triplet);
7571
+ function assertLyricsOptions(lyricsOptions) {
7572
+ assertArg(import_ts_utils_lib15.Utils.Is.isObject(lyricsOptions), "lyricsOptions", lyricsOptions);
7573
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValueOrUndefined(lyricsOptions.align, LyricsAlign), "lyricsOptions.align", lyricsOptions.align);
7574
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValueOrUndefined(lyricsOptions.hyphen, LyricsHyphen), "lyricsOptions.hyphen", lyricsOptions.hyphen);
7099
7575
  }
7100
7576
  function assertStaffTabOrGRoups(staffTabOrGroups) {
7101
7577
  assertArg(
7102
- import_ts_utils_lib13.Utils.Is.isStringOrUndefined(staffTabOrGroups) || import_ts_utils_lib13.Utils.Is.isIntegerGte(staffTabOrGroups, 0) || import_ts_utils_lib13.Utils.Is.isNonEmptyArray(staffTabOrGroups) && staffTabOrGroups.every(
7103
- (staffTabOrGroup) => import_ts_utils_lib13.Utils.Is.isString(staffTabOrGroup) || import_ts_utils_lib13.Utils.Is.isIntegerGte(staffTabOrGroup, 0)
7578
+ import_ts_utils_lib15.Utils.Is.isStringOrUndefined(staffTabOrGroups) || import_ts_utils_lib15.Utils.Is.isIntegerGte(staffTabOrGroups, 0) || import_ts_utils_lib15.Utils.Is.isNonEmptyArray(staffTabOrGroups) && staffTabOrGroups.every(
7579
+ (staffTabOrGroup) => import_ts_utils_lib15.Utils.Is.isString(staffTabOrGroup) || import_ts_utils_lib15.Utils.Is.isIntegerGte(staffTabOrGroup, 0)
7104
7580
  ),
7105
7581
  "staffTabOrGroup",
7106
7582
  staffTabOrGroups
@@ -7128,22 +7604,23 @@ var DocumentBuilder = class {
7128
7604
  */
7129
7605
  constructor() {
7130
7606
  __publicField(this, "doc");
7607
+ __publicField(this, "currentLyricsAlign", "center" /* Center */);
7131
7608
  this.doc = new ObjDocument();
7132
7609
  }
7133
7610
  setScoreConfiguration(config) {
7134
- if (import_ts_utils_lib13.Utils.Is.isEnumValue(config, StaffPreset)) {
7611
+ if (import_ts_utils_lib15.Utils.Is.isEnumValue(config, StaffPreset)) {
7135
7612
  this.doc.setScoreConfiguration(config);
7136
- } else if (import_ts_utils_lib13.Utils.Is.isObject(config) && config.type === "staff") {
7613
+ } else if (import_ts_utils_lib15.Utils.Is.isObject(config) && config.type === "staff") {
7137
7614
  assertStaffConfig(config);
7138
7615
  this.doc.setScoreConfiguration(config);
7139
- } else if (import_ts_utils_lib13.Utils.Is.isObject(config) && config.type === "tab") {
7616
+ } else if (import_ts_utils_lib15.Utils.Is.isObject(config) && config.type === "tab") {
7140
7617
  assertTabConfig(config);
7141
7618
  this.doc.setScoreConfiguration(config);
7142
- } else if (import_ts_utils_lib13.Utils.Is.isNonEmptyArray(config)) {
7619
+ } else if (import_ts_utils_lib15.Utils.Is.isNonEmptyArray(config)) {
7143
7620
  config.forEach((c) => {
7144
- if (import_ts_utils_lib13.Utils.Is.isObject(c) && c.type === "staff") {
7621
+ if (import_ts_utils_lib15.Utils.Is.isObject(c) && c.type === "staff") {
7145
7622
  assertStaffConfig(c);
7146
- } else if (import_ts_utils_lib13.Utils.Is.isObject(c) && c.type === "tab") {
7623
+ } else if (import_ts_utils_lib15.Utils.Is.isObject(c) && c.type === "tab") {
7147
7624
  assertTabConfig(c);
7148
7625
  } else {
7149
7626
  assertArg(false, "config", config);
@@ -7174,9 +7651,9 @@ var DocumentBuilder = class {
7174
7651
  * @returns - This document builder instance.
7175
7652
  */
7176
7653
  setHeader(title, composer, arranger) {
7177
- assertArg(import_ts_utils_lib13.Utils.Is.isStringOrUndefined(title), "title", title);
7178
- assertArg(import_ts_utils_lib13.Utils.Is.isStringOrUndefined(composer), "composer", composer);
7179
- assertArg(import_ts_utils_lib13.Utils.Is.isStringOrUndefined(arranger), "arranger", arranger);
7654
+ assertArg(import_ts_utils_lib15.Utils.Is.isStringOrUndefined(title), "title", title);
7655
+ assertArg(import_ts_utils_lib15.Utils.Is.isStringOrUndefined(composer), "composer", composer);
7656
+ assertArg(import_ts_utils_lib15.Utils.Is.isStringOrUndefined(arranger), "arranger", arranger);
7180
7657
  this.doc.setHeader(title, composer, arranger);
7181
7658
  return this;
7182
7659
  }
@@ -7186,7 +7663,7 @@ var DocumentBuilder = class {
7186
7663
  * @returns - This document builder instance.
7187
7664
  */
7188
7665
  setMeasuresPerRow(measuresPerRow) {
7189
- assertArg(import_ts_utils_lib13.Utils.Is.isIntegerGte(measuresPerRow, 1) || import_ts_utils_lib13.Utils.Is.isPosInfinity(measuresPerRow), "measuresPerRow", measuresPerRow);
7666
+ assertArg(import_ts_utils_lib15.Utils.Is.isIntegerGte(measuresPerRow, 1) || import_ts_utils_lib15.Utils.Is.isPosInfinity(measuresPerRow), "measuresPerRow", measuresPerRow);
7190
7667
  this.doc.setMeasuresPerRow(measuresPerRow);
7191
7668
  return this;
7192
7669
  }
@@ -7199,80 +7676,88 @@ var DocumentBuilder = class {
7199
7676
  return this;
7200
7677
  }
7201
7678
  setKeySignature(...args) {
7202
- assertArg(args[0] instanceof import_theory13.Scale || args[0] instanceof import_theory13.KeySignature || import_ts_utils_lib13.Utils.Is.isNonEmptyString(args[0]) && (args.length === 1 || import_ts_utils_lib13.Utils.Is.isEnumValue(args[1], import_theory13.ScaleType)), "keySignature", args);
7679
+ assertArg(args[0] instanceof import_theory13.Scale || args[0] instanceof import_theory13.KeySignature || import_ts_utils_lib15.Utils.Is.isNonEmptyString(args[0]) && (args.length === 1 || import_ts_utils_lib15.Utils.Is.isEnumValue(args[1], import_theory13.ScaleType)), "keySignature", args);
7203
7680
  this.getMeasure().setKeySignature(...args);
7204
7681
  return this;
7205
7682
  }
7206
- /**
7207
- * Set time signature for current measure and forward.
7208
- * @param timeSignature - TimeSignature object instance or string (e.g. "3/4").
7209
- * @returns - This document builder instance.
7210
- */
7211
- setTimeSignature(timeSignature) {
7212
- assertArg(timeSignature instanceof import_theory13.TimeSignature || import_ts_utils_lib13.Utils.Is.isNonEmptyString(timeSignature), "timeSignature", timeSignature);
7213
- this.getMeasure().setTimeSignature(timeSignature);
7683
+ setTimeSignature(...args) {
7684
+ if (args[0] instanceof import_theory13.TimeSignature) {
7685
+ this.getMeasure().setTimeSignature(args[0]);
7686
+ } else if (import_ts_utils_lib15.Utils.Is.isEnumValue(args[0], import_theory13.TimeSignatures) && import_ts_utils_lib15.Utils.Is.isEnumValueOrUndefined(args[1], import_theory13.BeamGrouping)) {
7687
+ this.getMeasure().setTimeSignature(new import_theory13.TimeSignature(args[0], args[1]));
7688
+ } else if (import_ts_utils_lib15.Utils.Is.isIntegerGte(args[0], 1) && import_ts_utils_lib15.Utils.Is.isIntegerGte(args[1], 1) && import_ts_utils_lib15.Utils.Is.isEnumValueOrUndefined(args[2], import_theory13.BeamGrouping)) {
7689
+ this.getMeasure().setTimeSignature(new import_theory13.TimeSignature(args[0], args[1], args[2]));
7690
+ } else {
7691
+ assertArg(false, "timeSignature args", args);
7692
+ }
7214
7693
  return this;
7215
7694
  }
7216
7695
  setTempo(beatsPerMinute, beatLength, dotted) {
7217
- assertArg(import_ts_utils_lib13.Utils.Is.isIntegerGte(beatsPerMinute, 1), "beatsPerMinute", beatsPerMinute);
7696
+ assertArg(import_ts_utils_lib15.Utils.Is.isIntegerGte(beatsPerMinute, 1), "beatsPerMinute", beatsPerMinute);
7218
7697
  if (beatLength === void 0) {
7219
- assertArg(import_ts_utils_lib13.Utils.Is.isUndefined(dotted), "dotted", dotted);
7698
+ assertArg(import_ts_utils_lib15.Utils.Is.isUndefined(dotted), "dotted", dotted);
7220
7699
  } else {
7221
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(beatLength, import_theory13.NoteLength) || isNoteLength(beatLength), "beatLength", beatLength);
7222
- assertArg(import_ts_utils_lib13.Utils.Is.isBooleanOrUndefined(dotted) || import_ts_utils_lib13.Utils.Is.isIntegerGte(dotted, 0), "dotted", dotted);
7700
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(beatLength, import_theory13.NoteLength) || isNoteLength(beatLength), "beatLength", beatLength);
7701
+ assertArg(import_ts_utils_lib15.Utils.Is.isBooleanOrUndefined(dotted) || import_ts_utils_lib15.Utils.Is.isIntegerGte(dotted, 0), "dotted", dotted);
7223
7702
  }
7224
7703
  this.getMeasure().setTempo(beatsPerMinute, beatLength, dotted);
7225
7704
  return this;
7226
7705
  }
7227
7706
  /**
7228
- * Add note o current measure.
7707
+ * Add note to current measure.
7229
7708
  * @param voiceId - Voice id to add note to.
7230
- * @param note - Note instance of Note or string (e.g. "D4").
7709
+ * @param note - Instance of Note or string, single value (e.g. "C4") or array (e.g. ["C4", "E4", "G4"]).
7231
7710
  * @param noteLength - Note length (e.g. "4n").
7232
- * @param options - Note options.
7711
+ * @param noteOptions - Note options.
7233
7712
  * @returns - This document builder instance.
7234
7713
  */
7235
- addNote(voiceId, note, noteLength, options) {
7714
+ addNote(voiceId, note, noteLength, noteOptions) {
7236
7715
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7237
- assertArg(note instanceof import_theory13.Note || import_ts_utils_lib13.Utils.Is.isNonEmptyString(note), "note", note);
7238
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
7239
- if (options !== void 0) {
7240
- assertNoteOptions(options);
7716
+ assertArg(
7717
+ note instanceof import_theory13.Note || import_ts_utils_lib15.Utils.Is.isNonEmptyString(note) || import_ts_utils_lib15.Utils.Is.isArray(note) && note.every((note2) => note2 instanceof import_theory13.Note || import_ts_utils_lib15.Utils.Is.isNonEmptyString(note2)),
7718
+ "note",
7719
+ note
7720
+ );
7721
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
7722
+ noteOptions != null ? noteOptions : noteOptions = {};
7723
+ assertNoteOptions(noteOptions);
7724
+ if (import_ts_utils_lib15.Utils.Is.isArray(note)) {
7725
+ note.forEach((note2) => this.getMeasure().addNoteGroup(voiceId, [note2], noteLength, noteOptions));
7726
+ } else {
7727
+ this.getMeasure().addNoteGroup(voiceId, [note], noteLength, noteOptions);
7241
7728
  }
7242
- this.getMeasure().addNoteGroup(voiceId, [note], noteLength, options);
7243
7729
  return this;
7244
7730
  }
7245
7731
  /**
7732
+ * Add chord to current measure.
7246
7733
  * @param voiceId - Voice id to add chord to.
7247
7734
  * @param notes - Array of notes, each instance of Note or string (e.g. "D4").
7248
7735
  * @param noteLength - Note length (e.g. "4n").
7249
- * @param options - Note options.
7736
+ * @param noteOptions - Note options.
7250
7737
  * @returns - This document builder instance.
7251
7738
  */
7252
- addChord(voiceId, notes, noteLength, options) {
7739
+ addChord(voiceId, notes, noteLength, noteOptions) {
7253
7740
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7254
- assertArg(import_ts_utils_lib13.Utils.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof import_theory13.Note || import_ts_utils_lib13.Utils.Is.isNonEmptyString(note)), "notes", notes);
7255
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
7256
- if (options !== void 0) {
7257
- assertNoteOptions(options);
7258
- }
7259
- this.getMeasure().addNoteGroup(voiceId, notes, noteLength, options);
7741
+ assertArg(import_ts_utils_lib15.Utils.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof import_theory13.Note || import_ts_utils_lib15.Utils.Is.isNonEmptyString(note)), "notes", notes);
7742
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
7743
+ noteOptions != null ? noteOptions : noteOptions = {};
7744
+ assertNoteOptions(noteOptions);
7745
+ this.getMeasure().addNoteGroup(voiceId, notes, noteLength, noteOptions);
7260
7746
  return this;
7261
7747
  }
7262
7748
  /**
7263
- *
7749
+ * Add rest to current measure.
7264
7750
  * @param voiceId - Voice id to add rest to.
7265
7751
  * @param restLength - Rest length (e.g. "4n").
7266
- * @param options - Rest options.
7752
+ * @param restOptions - Rest options.
7267
7753
  * @returns - This document builder instance.
7268
7754
  */
7269
- addRest(voiceId, restLength, options) {
7755
+ addRest(voiceId, restLength, restOptions) {
7270
7756
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7271
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(restLength, import_theory13.NoteLength) || isNoteLength(restLength), "restLength", restLength);
7272
- if (options !== void 0) {
7273
- assertRestOptions(options);
7274
- }
7275
- this.getMeasure().addRest(voiceId, restLength, options);
7757
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(restLength, import_theory13.NoteLength) || isNoteLength(restLength), "restLength", restLength);
7758
+ restOptions != null ? restOptions : restOptions = {};
7759
+ assertRestOptions(restOptions);
7760
+ this.getMeasure().addRest(voiceId, restLength, restOptions);
7276
7761
  return this;
7277
7762
  }
7278
7763
  /**
@@ -7292,39 +7777,47 @@ var DocumentBuilder = class {
7292
7777
  */
7293
7778
  addTuplet(voiceId, tupletRatio, tupletBuilder) {
7294
7779
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7295
- assertArg(import_ts_utils_lib13.Utils.Is.isFunction(tupletBuilder), "tupletBuilder", tupletBuilder);
7296
- assertArg(isTupletRatio(tupletRatio) && import_ts_utils_lib13.Utils.Is.isBooleanOrUndefined(tupletRatio.showRatio), "tupletRatio", tupletRatio);
7780
+ assertArg(import_ts_utils_lib15.Utils.Is.isFunction(tupletBuilder), "tupletBuilder", tupletBuilder);
7781
+ assertArg(isTupletRatio(tupletRatio) && import_ts_utils_lib15.Utils.Is.isBooleanOrUndefined(tupletRatio.showRatio), "tupletRatio", tupletRatio);
7297
7782
  let tupletSymbols = [];
7298
7783
  const helper = {
7299
- addNote: (note, noteLength, options) => {
7300
- assertArg(note instanceof import_theory13.Note || import_ts_utils_lib13.Utils.Is.isNonEmptyString(note), "note", note);
7301
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
7302
- if (options !== void 0) {
7303
- delete options.triplet;
7304
- assertNoteOptions(options);
7784
+ addNote: (note, noteLength, noteOptions) => {
7785
+ assertArg(
7786
+ note instanceof import_theory13.Note || import_ts_utils_lib15.Utils.Is.isNonEmptyString(note) || import_ts_utils_lib15.Utils.Is.isArray(note) && note.every((note2) => note2 instanceof import_theory13.Note || import_ts_utils_lib15.Utils.Is.isNonEmptyString(note2)),
7787
+ "note",
7788
+ note
7789
+ );
7790
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
7791
+ noteOptions != null ? noteOptions : noteOptions = {};
7792
+ delete noteOptions.triplet;
7793
+ assertNoteOptions(noteOptions);
7794
+ if (import_ts_utils_lib15.Utils.Is.isArray(note)) {
7795
+ note.forEach((note2) => {
7796
+ let s = this.getMeasure().addNoteGroup(voiceId, [note2], noteLength, noteOptions, tupletRatio);
7797
+ tupletSymbols.push(s);
7798
+ });
7799
+ } else {
7800
+ let s = this.getMeasure().addNoteGroup(voiceId, [note], noteLength, noteOptions, tupletRatio);
7801
+ tupletSymbols.push(s);
7305
7802
  }
7306
- let s = this.getMeasure().addNoteGroup(voiceId, [note], noteLength, options, tupletRatio);
7307
- tupletSymbols.push(s);
7308
7803
  return helper;
7309
7804
  },
7310
- addChord: (notes, noteLength, options) => {
7311
- assertArg(import_ts_utils_lib13.Utils.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof import_theory13.Note || import_ts_utils_lib13.Utils.Is.isNonEmptyString(note)), "notes", notes);
7312
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
7313
- if (options !== void 0) {
7314
- delete options.triplet;
7315
- assertNoteOptions(options);
7316
- }
7317
- let s = this.getMeasure().addNoteGroup(voiceId, notes, noteLength, options, tupletRatio);
7805
+ addChord: (notes, noteLength, noteOptions) => {
7806
+ assertArg(import_ts_utils_lib15.Utils.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof import_theory13.Note || import_ts_utils_lib15.Utils.Is.isNonEmptyString(note)), "notes", notes);
7807
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
7808
+ noteOptions != null ? noteOptions : noteOptions = {};
7809
+ delete noteOptions.triplet;
7810
+ assertNoteOptions(noteOptions);
7811
+ let s = this.getMeasure().addNoteGroup(voiceId, notes, noteLength, noteOptions, tupletRatio);
7318
7812
  tupletSymbols.push(s);
7319
7813
  return helper;
7320
7814
  },
7321
- addRest: (restLength, options) => {
7322
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(restLength, import_theory13.NoteLength) || isNoteLength(restLength), "restLength", restLength);
7323
- if (options !== void 0) {
7324
- delete options.triplet;
7325
- assertRestOptions(options);
7326
- }
7327
- let s = this.getMeasure().addRest(voiceId, restLength, options, tupletRatio);
7815
+ addRest: (restLength, restOptions) => {
7816
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(restLength, import_theory13.NoteLength) || isNoteLength(restLength), "restLength", restLength);
7817
+ restOptions != null ? restOptions : restOptions = {};
7818
+ delete restOptions.triplet;
7819
+ assertRestOptions(restOptions);
7820
+ let s = this.getMeasure().addRest(voiceId, restLength, restOptions, tupletRatio);
7328
7821
  tupletSymbols.push(s);
7329
7822
  return helper;
7330
7823
  }
@@ -7333,9 +7826,52 @@ var DocumentBuilder = class {
7333
7826
  ObjBeamGroup.createTuplet(tupletSymbols, tupletRatio);
7334
7827
  return this;
7335
7828
  }
7829
+ addLyricsInternal(staffTabOrGroups, verse, lyricsLength, lyricsText, lyricsOptions) {
7830
+ var _a;
7831
+ assertStaffTabOrGRoups(staffTabOrGroups);
7832
+ assertArg(isVerseNumber(verse), "verse", verse);
7833
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(lyricsLength, import_theory13.NoteLength), "lyricsLength", lyricsLength);
7834
+ assertArg(import_ts_utils_lib15.Utils.Is.isString(lyricsText) || import_ts_utils_lib15.Utils.Is.isArray(lyricsText) && lyricsText.every((text) => import_ts_utils_lib15.Utils.Is.isString(text)), "lyricsText", lyricsText);
7835
+ lyricsOptions != null ? lyricsOptions : lyricsOptions = {};
7836
+ assertLyricsOptions(lyricsOptions);
7837
+ if (lyricsOptions.align !== void 0) {
7838
+ this.currentLyricsAlign = lyricsOptions.align;
7839
+ } else {
7840
+ (_a = lyricsOptions.align) != null ? _a : lyricsOptions.align = this.currentLyricsAlign;
7841
+ }
7842
+ if (import_ts_utils_lib15.Utils.Is.isArray(lyricsText)) {
7843
+ lyricsText.forEach((text) => this.getMeasure().addLyrics(staffTabOrGroups, verse, lyricsLength, text, lyricsOptions));
7844
+ } else {
7845
+ this.getMeasure().addLyrics(staffTabOrGroups, verse, lyricsLength, lyricsText, lyricsOptions);
7846
+ }
7847
+ return this;
7848
+ }
7849
+ /**
7850
+ * Add lyrics to current measure.
7851
+ * @param verse - Verse number (e.g. 1).
7852
+ * @param lyricsLength - Lyrics text length (e.g. "2n").
7853
+ * @param lyricsText - Lyrics text (empty space if omitted), single value or array.
7854
+ * @param lyricsOptions - Lyrics options.
7855
+ * @returns - This document builder instance.
7856
+ */
7857
+ addLyrics(verse, lyricsLength, lyricsText, lyricsOptions) {
7858
+ return this.addLyricsInternal(void 0, verse, lyricsLength, lyricsText != null ? lyricsText : "", lyricsOptions);
7859
+ }
7860
+ /**
7861
+ * Add lyrics to current measure to given staff/tab/group.
7862
+ * @param staffTabOrGroups - staff/tab index (0=top), staff/tab name, or staff group name.
7863
+ * @param verse - Verse number (e.g. 1).
7864
+ * @param lyricsLength - Lyrics text length (e.g. "2n").
7865
+ * @param lyricsText - Lyrics text (empty space if omitted), single value or array.
7866
+ * @param lyricsOptions - Lyrics options.
7867
+ * @returns - This document builder instance.
7868
+ */
7869
+ addLyricsTo(staffTabOrGroups, verse, lyricsLength, lyricsText, lyricsOptions) {
7870
+ return this.addLyricsInternal(staffTabOrGroups, verse, lyricsLength, lyricsText != null ? lyricsText : "", lyricsOptions);
7871
+ }
7336
7872
  addFermataInternal(staffTabOrGroups, fermata) {
7337
7873
  assertStaffTabOrGRoups(staffTabOrGroups);
7338
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(fermata, Fermata), "fermata", fermata);
7874
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(fermata, Fermata), "fermata", fermata);
7339
7875
  this.getMeasure().addFermata(staffTabOrGroups, fermata);
7340
7876
  return this;
7341
7877
  }
@@ -7358,11 +7894,11 @@ var DocumentBuilder = class {
7358
7894
  }
7359
7895
  addNavigationInternal(staffTabOrGroups, navigation, ...args) {
7360
7896
  assertStaffTabOrGRoups(staffTabOrGroups);
7361
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(navigation, Navigation), "navigation", navigation);
7897
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(navigation, Navigation), "navigation", navigation);
7362
7898
  if (navigation === "endRepeat" /* EndRepeat */ && args.length > 0) {
7363
- assertArg(import_ts_utils_lib13.Utils.Is.isIntegerGte(args[0], 1), "playCount", args[0]);
7899
+ assertArg(import_ts_utils_lib15.Utils.Is.isIntegerGte(args[0], 1), "playCount", args[0]);
7364
7900
  } else if (navigation === "ending" /* Ending */ && args.length > 0) {
7365
- assertArg(args.every((passage) => import_ts_utils_lib13.Utils.Is.isIntegerGte(passage, 1)), "passages", args);
7901
+ assertArg(args.every((passage) => import_ts_utils_lib15.Utils.Is.isIntegerGte(passage, 1)), "passages", args);
7366
7902
  }
7367
7903
  this.getMeasure().addNavigation(staffTabOrGroups, navigation, ...args);
7368
7904
  return this;
@@ -7376,11 +7912,11 @@ var DocumentBuilder = class {
7376
7912
  addAnnotationInternal(staffTabOrGroups, annotation, text) {
7377
7913
  annotation != null ? annotation : annotation = getAnnotation(text);
7378
7914
  if (annotation === void 0) {
7379
- throw new import_core17.MusicError(import_core17.MusicErrorType.Score, `Annotation text "${text}" is not known annotation.`);
7915
+ throw new import_core18.MusicError(import_core18.MusicErrorType.Score, `Annotation text "${text}" is not known annotation.`);
7380
7916
  }
7381
7917
  assertStaffTabOrGRoups(staffTabOrGroups);
7382
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(annotation, Annotation), "annotation", annotation);
7383
- assertArg(import_ts_utils_lib13.Utils.Is.isNonEmptyString(text), "text", text);
7918
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(annotation, Annotation), "annotation", annotation);
7919
+ assertArg(import_ts_utils_lib15.Utils.Is.isNonEmptyString(text), "text", text);
7384
7920
  this.getMeasure().addAnnotation(staffTabOrGroups, annotation, text);
7385
7921
  return this;
7386
7922
  }
@@ -7400,8 +7936,8 @@ var DocumentBuilder = class {
7400
7936
  }
7401
7937
  addLabelInternal(staffTabOrGroups, label, text) {
7402
7938
  assertStaffTabOrGRoups(staffTabOrGroups);
7403
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(label, Label), "label", label);
7404
- assertArg(import_ts_utils_lib13.Utils.Is.isNonEmptyString(text), "text", text);
7939
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(label, Label), "label", label);
7940
+ assertArg(import_ts_utils_lib15.Utils.Is.isNonEmptyString(text), "text", text);
7405
7941
  this.getMeasure().addLabel(staffTabOrGroups, label, text);
7406
7942
  return this;
7407
7943
  }
@@ -7425,21 +7961,21 @@ var DocumentBuilder = class {
7425
7961
  return this.addLabelInternal(staffTabOrGroups, label, text);
7426
7962
  }
7427
7963
  addConnective(connective, ...args) {
7428
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(connective, Connective), "connective", connective);
7964
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(connective, Connective), "connective", connective);
7429
7965
  if (connective === "tie" /* Tie */) {
7430
- assertArg(import_ts_utils_lib13.Utils.Is.isIntegerOrUndefined(args[0]) || import_ts_utils_lib13.Utils.Is.isEnumValue(args[0], TieType), "tieSpan", args[0]);
7431
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
7966
+ assertArg(import_ts_utils_lib15.Utils.Is.isIntegerOrUndefined(args[0]) || import_ts_utils_lib15.Utils.Is.isEnumValue(args[0], TieType), "tieSpan", args[0]);
7967
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
7432
7968
  let tieSpan = args[0];
7433
7969
  let noteAnchor = args[1];
7434
7970
  this.getMeasure().addConnective(connective, tieSpan, noteAnchor);
7435
7971
  } else if (connective === "slur" /* Slur */) {
7436
- assertArg(import_ts_utils_lib13.Utils.Is.isIntegerOrUndefined(args[0]), "slurSpan", args[0]);
7437
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
7972
+ assertArg(import_ts_utils_lib15.Utils.Is.isIntegerOrUndefined(args[0]), "slurSpan", args[0]);
7973
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
7438
7974
  let slurSpan = args[0];
7439
7975
  let noteAnchor = args[1];
7440
7976
  this.getMeasure().addConnective(connective, slurSpan, noteAnchor);
7441
7977
  } else if (connective === "slide" /* Slide */) {
7442
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValueOrUndefined(args[0], NoteAnchor), "noteAnchor", args[0]);
7978
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValueOrUndefined(args[0], NoteAnchor), "noteAnchor", args[0]);
7443
7979
  let noteAnchor = args[0];
7444
7980
  this.getMeasure().addConnective(connective, noteAnchor);
7445
7981
  }
@@ -7458,18 +7994,18 @@ var DocumentBuilder = class {
7458
7994
  * @returns - This document builder instance.
7459
7995
  */
7460
7996
  addExtension(extensionBuilder) {
7461
- assertArg(import_ts_utils_lib13.Utils.Is.isFunctionOrUndefined(extensionBuilder), "addExtension() has new usage, for e.g. addExtension(ext => ext.measures(2)). Please refer to README or API Reference.", extensionBuilder);
7997
+ assertArg(import_ts_utils_lib15.Utils.Is.isFunctionOrUndefined(extensionBuilder), "addExtension() has new usage, for e.g. addExtension(ext => ext.measures(2)). Please refer to README or API Reference.", extensionBuilder);
7462
7998
  let ticks = 0;
7463
7999
  let visible = true;
7464
8000
  const helper = {
7465
8001
  notes: (noteLength, noteCount) => {
7466
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
7467
- assertArg(import_ts_utils_lib13.Utils.Is.isUndefined(noteCount) || import_ts_utils_lib13.Utils.Is.isNumber(noteCount) && noteCount >= 0, "noteCount", noteCount);
8002
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8003
+ assertArg(import_ts_utils_lib15.Utils.Is.isUndefined(noteCount) || import_ts_utils_lib15.Utils.Is.isNumber(noteCount) && noteCount >= 0, "noteCount", noteCount);
7468
8004
  ticks += import_theory13.RhythmProps.get(noteLength).ticks * (noteCount != null ? noteCount : 1);
7469
8005
  return helper;
7470
8006
  },
7471
8007
  measures: (measureCount) => {
7472
- assertArg(import_ts_utils_lib13.Utils.Is.isNumber(measureCount) && measureCount >= 1, "measureCount", measureCount);
8008
+ assertArg(import_ts_utils_lib15.Utils.Is.isNumber(measureCount) && measureCount >= 1, "measureCount", measureCount);
7473
8009
  ticks += this.getMeasure().getMeasureTicks() * measureCount;
7474
8010
  return helper;
7475
8011
  },
@@ -7498,13 +8034,13 @@ var DocumentBuilder = class {
7498
8034
  * @returns - This document builder instance.
7499
8035
  */
7500
8036
  addStaffGroup(groupName, staffsTabsAndGroups, verticalPosition = "auto" /* Auto */) {
7501
- assertArg(import_ts_utils_lib13.Utils.Is.isNonEmptyString(groupName), "groupName", groupName);
8037
+ assertArg(import_ts_utils_lib15.Utils.Is.isNonEmptyString(groupName), "groupName", groupName);
7502
8038
  assertArg(
7503
- import_ts_utils_lib13.Utils.Is.isNonEmptyString(staffsTabsAndGroups) || import_ts_utils_lib13.Utils.Is.isIntegerGte(staffsTabsAndGroups, 0) || import_ts_utils_lib13.Utils.Is.isNonEmptyArray(staffsTabsAndGroups) && staffsTabsAndGroups.every((line) => import_ts_utils_lib13.Utils.Is.isNonEmptyString(line) || import_ts_utils_lib13.Utils.Is.isIntegerGte(line, 0)),
8039
+ import_ts_utils_lib15.Utils.Is.isNonEmptyString(staffsTabsAndGroups) || import_ts_utils_lib15.Utils.Is.isIntegerGte(staffsTabsAndGroups, 0) || import_ts_utils_lib15.Utils.Is.isNonEmptyArray(staffsTabsAndGroups) && staffsTabsAndGroups.every((line) => import_ts_utils_lib15.Utils.Is.isNonEmptyString(line) || import_ts_utils_lib15.Utils.Is.isIntegerGte(line, 0)),
7504
8040
  "staffsTabsAndGroups",
7505
8041
  staffsTabsAndGroups
7506
8042
  );
7507
- assertArg(import_ts_utils_lib13.Utils.Is.isEnumValue(verticalPosition, VerticalPosition), "verticalPosition", verticalPosition);
8043
+ assertArg(import_ts_utils_lib15.Utils.Is.isEnumValue(verticalPosition, VerticalPosition), "verticalPosition", verticalPosition);
7508
8044
  this.doc.addStaffGroup(groupName, staffsTabsAndGroups, verticalPosition);
7509
8045
  return this;
7510
8046
  }
@@ -7539,7 +8075,7 @@ var DocumentBuilder = class {
7539
8075
  * @returns - This document builder instance.
7540
8076
  */
7541
8077
  completeRests(voiceId) {
7542
- assertArg(import_ts_utils_lib13.Utils.Is.isUndefined(voiceId) || isVoiceId(voiceId) || import_ts_utils_lib13.Utils.Is.isArray(voiceId) && voiceId.every((id) => isVoiceId(id)), "voiceId", voiceId);
8078
+ assertArg(import_ts_utils_lib15.Utils.Is.isUndefined(voiceId) || isVoiceId(voiceId) || import_ts_utils_lib15.Utils.Is.isArray(voiceId) && voiceId.every((id) => isVoiceId(id)), "voiceId", voiceId);
7543
8079
  this.getMeasure().completeRests(voiceId);
7544
8080
  return this;
7545
8081
  }
@@ -7551,8 +8087,8 @@ var DocumentBuilder = class {
7551
8087
  * @returns - This document builder instance.
7552
8088
  */
7553
8089
  addScaleArpeggio(scale, bottomNote, numOctaves) {
7554
- assertArg(import_ts_utils_lib13.Utils.Is.isNonEmptyString(bottomNote), "bottomNote", bottomNote);
7555
- assertArg(import_ts_utils_lib13.Utils.Is.isIntegerGte(numOctaves, 1), "numOctaves", numOctaves);
8090
+ assertArg(import_ts_utils_lib15.Utils.Is.isNonEmptyString(bottomNote), "bottomNote", bottomNote);
8091
+ assertArg(import_ts_utils_lib15.Utils.Is.isIntegerGte(numOctaves, 1), "numOctaves", numOctaves);
7556
8092
  let ts = this.getMeasure().getTimeSignature();
7557
8093
  let notes = scale.getScaleNotes(bottomNote, numOctaves);
7558
8094
  for (let i = 0; i < notes.length; i++) {
@@ -7568,7 +8104,7 @@ var DocumentBuilder = class {
7568
8104
  };
7569
8105
 
7570
8106
  // src/score/pub/event.ts
7571
- var import_core18 = require("@tspro/web-music-score/core");
8107
+ var import_core19 = require("@tspro/web-music-score/core");
7572
8108
  var ScoreEvent = class {
7573
8109
  /**
7574
8110
  * Create new score event instance.
@@ -7605,7 +8141,7 @@ var ScoreObjectEvent = class extends ScoreEvent {
7605
8141
  this.renderer = renderer;
7606
8142
  this.objects = objects;
7607
8143
  if (arguments.length === 0) {
7608
- throw new import_core18.MusicError(import_core18.MusicErrorType.Score, "Empty array in score object event!");
8144
+ throw new import_core19.MusicError(import_core19.MusicErrorType.Score, "Empty array in score object event!");
7609
8145
  }
7610
8146
  }
7611
8147
  /** Top object getter. */
@@ -7624,24 +8160,24 @@ var ScoreObjectEvent = class extends ScoreEvent {
7624
8160
 
7625
8161
  // src/score/pub/music-interface.ts
7626
8162
  var Audio2 = __toESM(require("@tspro/web-music-score/audio"));
7627
- var import_ts_utils_lib15 = require("@tspro/ts-utils-lib");
8163
+ var import_ts_utils_lib17 = require("@tspro/ts-utils-lib");
7628
8164
 
7629
8165
  // src/score/pub/music-objects.ts
7630
- var import_ts_utils_lib14 = require("@tspro/ts-utils-lib");
7631
- var import_core19 = require("@tspro/web-music-score/core");
8166
+ var import_ts_utils_lib16 = require("@tspro/ts-utils-lib");
8167
+ var import_core20 = require("@tspro/web-music-score/core");
7632
8168
  function assertArg2(condition, argName, argValue) {
7633
8169
  if (!condition) {
7634
- throw new import_core19.MusicError(import_core19.MusicErrorType.Score, `Invalid arg: ${argName} = ${argValue}`);
8170
+ throw new import_core20.MusicError(import_core20.MusicErrorType.Score, `Invalid arg: ${argName} = ${argValue}`);
7635
8171
  }
7636
8172
  }
7637
8173
  function isVoiceId2(value) {
7638
- return import_ts_utils_lib14.Utils.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
8174
+ return import_ts_utils_lib16.Utils.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
7639
8175
  }
7640
8176
  function getNotationLine(line) {
7641
8177
  if (line instanceof ObjStaff || line instanceof ObjTab) {
7642
8178
  return line.getMusicInterface();
7643
8179
  } else {
7644
- throw new import_core19.MusicError(import_core19.MusicErrorType.Score, `Notation line not staff nor tab.`);
8180
+ throw new import_core20.MusicError(import_core20.MusicErrorType.Score, `Notation line not staff nor tab.`);
7645
8181
  }
7646
8182
  }
7647
8183
  var MusicInterface6 = class {
@@ -7811,7 +8347,7 @@ var _MDocument = class _MDocument extends MusicInterface6 {
7811
8347
  * @returns - Player instance.
7812
8348
  */
7813
8349
  play(playStateChangeListener) {
7814
- assertArg2(import_ts_utils_lib14.Utils.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
8350
+ assertArg2(import_ts_utils_lib16.Utils.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
7815
8351
  return new MPlayer(this, playStateChangeListener).play();
7816
8352
  }
7817
8353
  };
@@ -7841,7 +8377,7 @@ var _MEnding = class _MEnding extends MusicInterface6 {
7841
8377
  * @returns - Boolean whether this ending has asked passage number.
7842
8378
  */
7843
8379
  hasPassage(passage) {
7844
- assertArg2(import_ts_utils_lib14.Utils.Is.isIntegerGte(passage, 1), "passage", passage);
8380
+ assertArg2(import_ts_utils_lib16.Utils.Is.isIntegerGte(passage, 1), "passage", passage);
7845
8381
  return this.obj.hasPassage(passage);
7846
8382
  }
7847
8383
  };
@@ -7993,7 +8529,7 @@ var _MStaffTabBarLine = class _MStaffTabBarLine extends MusicInterface6 {
7993
8529
  if (barLine instanceof ObjBarLineLeft || barLine instanceof ObjBarLineRight) {
7994
8530
  return barLine.getMusicInterface();
7995
8531
  } else {
7996
- throw new import_core19.MusicError(import_core19.MusicErrorType.Score, `Bar line not let nor right.`);
8532
+ throw new import_core20.MusicError(import_core20.MusicErrorType.Score, `Bar line not let nor right.`);
7997
8533
  }
7998
8534
  }
7999
8535
  /**
@@ -8420,6 +8956,27 @@ var _MText = class _MText extends MusicInterface6 {
8420
8956
  /** Object name. */
8421
8957
  __publicField(_MText, "Name", "Text");
8422
8958
  var MText = _MText;
8959
+ var _MLyrics = class _MLyrics extends MusicInterface6 {
8960
+ /** @internal */
8961
+ constructor(obj) {
8962
+ super(_MLyrics.Name);
8963
+ this.obj = obj;
8964
+ }
8965
+ /** @internal */
8966
+ getMusicObject() {
8967
+ return this.obj;
8968
+ }
8969
+ /**
8970
+ * Get lyrics text.
8971
+ * @returns - Lyrics text.
8972
+ */
8973
+ getText() {
8974
+ return this.obj.getText();
8975
+ }
8976
+ };
8977
+ /** Object name. */
8978
+ __publicField(_MLyrics, "Name", "Lyrics");
8979
+ var MLyrics = _MLyrics;
8423
8980
  var _MExtensionLine = class _MExtensionLine extends MusicInterface6 {
8424
8981
  /** @internal */
8425
8982
  constructor(obj) {
@@ -8436,10 +8993,10 @@ __publicField(_MExtensionLine, "Name", "ExtensionLine");
8436
8993
  var MExtensionLine = _MExtensionLine;
8437
8994
 
8438
8995
  // src/score/pub/music-interface.ts
8439
- var import_core20 = require("@tspro/web-music-score/core");
8996
+ var import_core21 = require("@tspro/web-music-score/core");
8440
8997
  function assertArg3(condition, argName, argValue) {
8441
8998
  if (!condition) {
8442
- throw new import_core20.MusicError(import_core20.MusicErrorType.Score, `Invalid arg: ${argName} = ${argValue}`);
8999
+ throw new import_core21.MusicError(import_core21.MusicErrorType.Score, `Invalid arg: ${argName} = ${argValue}`);
8443
9000
  }
8444
9001
  }
8445
9002
  function require_t(t, message) {
@@ -8458,7 +9015,7 @@ var _MPlayer = class _MPlayer {
8458
9015
  constructor(doc, playStateChangeListener) {
8459
9016
  __publicField(this, "player");
8460
9017
  assertArg3(doc instanceof MDocument2, "doc", doc);
8461
- assertArg3(import_ts_utils_lib15.Utils.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
9018
+ assertArg3(import_ts_utils_lib17.Utils.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
8462
9019
  this.player = new Player();
8463
9020
  this.player.setDocument(doc.getMusicObject());
8464
9021
  this.player.setCursorPositionChangeListener((cursorRect) => doc.getMusicObject().updateCursorRect(cursorRect));
@@ -8516,7 +9073,7 @@ var MRenderer2 = class {
8516
9073
  * @returns - This renderer instance.
8517
9074
  */
8518
9075
  setDocument(doc) {
8519
- assertArg3(import_ts_utils_lib15.Utils.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9076
+ assertArg3(import_ts_utils_lib17.Utils.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
8520
9077
  this.renderer.setDocument(doc);
8521
9078
  return this;
8522
9079
  }
@@ -8526,7 +9083,7 @@ var MRenderer2 = class {
8526
9083
  * @returns - This renderer instance.
8527
9084
  */
8528
9085
  setCanvas(canvas) {
8529
- canvas = require_t(import_ts_utils_lib15.Utils.Dom.getCanvas(canvas), typeof canvas === "string" ? "Cannot set renderer canvas because invalid canvas id: " + canvas : "Cannot set renderer canvas because given canvas is undefined.");
9086
+ canvas = require_t(import_ts_utils_lib17.Utils.Dom.getCanvas(canvas), typeof canvas === "string" ? "Cannot set renderer canvas because invalid canvas id: " + canvas : "Cannot set renderer canvas because given canvas is undefined.");
8530
9087
  this.renderer.setCanvas(canvas);
8531
9088
  return this;
8532
9089
  }
@@ -8535,7 +9092,7 @@ var MRenderer2 = class {
8535
9092
  * @param scoreEventListener - Score event listener.
8536
9093
  */
8537
9094
  setScoreEventListener(scoreEventListener) {
8538
- assertArg3(import_ts_utils_lib15.Utils.Is.isFunctionOrUndefined(scoreEventListener), "scoreEventListener", scoreEventListener);
9095
+ assertArg3(import_ts_utils_lib17.Utils.Is.isFunctionOrUndefined(scoreEventListener), "scoreEventListener", scoreEventListener);
8539
9096
  this.renderer.setScoreEventListener(scoreEventListener);
8540
9097
  }
8541
9098
  /**
@@ -8609,7 +9166,7 @@ var _MPlaybackButtons = class _MPlaybackButtons {
8609
9166
  * @returns
8610
9167
  */
8611
9168
  setDocument(doc) {
8612
- assertArg3(import_ts_utils_lib15.Utils.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9169
+ assertArg3(import_ts_utils_lib17.Utils.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
8613
9170
  this.onStop();
8614
9171
  if (doc) {
8615
9172
  this.player = new MPlayer(doc, (playState) => {
@@ -8653,9 +9210,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
8653
9210
  * @returns - This playback buttons class instance.
8654
9211
  */
8655
9212
  setPlayButton(btn, btnLabel) {
8656
- assertArg3(import_ts_utils_lib15.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9213
+ assertArg3(import_ts_utils_lib17.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
8657
9214
  _MPlaybackButtons.removeOnClickListeners(this.playButton, this.onPlay);
8658
- this.playButton = require_t(import_ts_utils_lib15.Utils.Dom.getButton(btn), "Play button required!");
9215
+ this.playButton = require_t(import_ts_utils_lib17.Utils.Dom.getButton(btn), "Play button required!");
8659
9216
  this.playLabel = btnLabel != null ? btnLabel : "Play";
8660
9217
  _MPlaybackButtons.removeOnClickListeners(this.playButton, "all");
8661
9218
  _MPlaybackButtons.addOnClickListener(this.playButton, this.onPlay);
@@ -8669,9 +9226,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
8669
9226
  * @returns - This playback buttons class instance.
8670
9227
  */
8671
9228
  setStopButton(btn, btnLabel) {
8672
- assertArg3(import_ts_utils_lib15.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9229
+ assertArg3(import_ts_utils_lib17.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
8673
9230
  _MPlaybackButtons.removeOnClickListeners(this.stopButton, this.onStop);
8674
- this.stopButton = require_t(import_ts_utils_lib15.Utils.Dom.getButton(btn), "Stop button required!");
9231
+ this.stopButton = require_t(import_ts_utils_lib17.Utils.Dom.getButton(btn), "Stop button required!");
8675
9232
  this.stopLabel = btnLabel != null ? btnLabel : "Stop";
8676
9233
  _MPlaybackButtons.removeOnClickListeners(this.stopButton, "all");
8677
9234
  _MPlaybackButtons.addOnClickListener(this.stopButton, this.onStop);
@@ -8686,10 +9243,10 @@ var _MPlaybackButtons = class _MPlaybackButtons {
8686
9243
  * @returns - This playback buttons class instance.
8687
9244
  */
8688
9245
  setPlayStopButton(btn, playLabel, stopLabel) {
8689
- assertArg3(import_ts_utils_lib15.Utils.Is.isStringOrUndefined(playLabel), "playLabel", playLabel);
8690
- assertArg3(import_ts_utils_lib15.Utils.Is.isStringOrUndefined(stopLabel), "stopLabel", stopLabel);
9246
+ assertArg3(import_ts_utils_lib17.Utils.Is.isStringOrUndefined(playLabel), "playLabel", playLabel);
9247
+ assertArg3(import_ts_utils_lib17.Utils.Is.isStringOrUndefined(stopLabel), "stopLabel", stopLabel);
8691
9248
  _MPlaybackButtons.removeOnClickListeners(this.playStopButton, this.onPlayStop);
8692
- this.playStopButton = require_t(import_ts_utils_lib15.Utils.Dom.getButton(btn), "Play/stop button required!");
9249
+ this.playStopButton = require_t(import_ts_utils_lib17.Utils.Dom.getButton(btn), "Play/stop button required!");
8693
9250
  this.playLabel = playLabel != null ? playLabel : "Play";
8694
9251
  this.stopLabel = stopLabel != null ? stopLabel : "Stop";
8695
9252
  _MPlaybackButtons.removeOnClickListeners(this.playStopButton, "all");
@@ -8704,9 +9261,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
8704
9261
  * @returns - This playback buttons class instance.
8705
9262
  */
8706
9263
  setPauseButton(btn, btnLabel) {
8707
- assertArg3(import_ts_utils_lib15.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9264
+ assertArg3(import_ts_utils_lib17.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
8708
9265
  _MPlaybackButtons.removeOnClickListeners(this.pauseButton, this.onPause);
8709
- this.pauseButton = require_t(import_ts_utils_lib15.Utils.Dom.getButton(btn), "Pause button required!");
9266
+ this.pauseButton = require_t(import_ts_utils_lib17.Utils.Dom.getButton(btn), "Pause button required!");
8710
9267
  this.pauseLabel = btnLabel != null ? btnLabel : "Pause";
8711
9268
  _MPlaybackButtons.removeOnClickListeners(this.pauseButton, "all");
8712
9269
  _MPlaybackButtons.addOnClickListener(this.pauseButton, this.onPause);
@@ -8728,7 +9285,7 @@ var _MPlaybackButtons = class _MPlaybackButtons {
8728
9285
  }
8729
9286
  }
8730
9287
  static addOnClickListener(btn, onClick) {
8731
- assertArg3(import_ts_utils_lib15.Utils.Is.isFunction(onClick), "onClick", onClick);
9288
+ assertArg3(import_ts_utils_lib17.Utils.Is.isFunction(onClick), "onClick", onClick);
8732
9289
  btn.addEventListener("click", onClick);
8733
9290
  let clickListeners = this.savedOnClickListeners.get(btn) || [];
8734
9291
  this.savedOnClickListeners.set(btn, [...clickListeners, onClick]);
@@ -8738,8 +9295,8 @@ __publicField(_MPlaybackButtons, "savedOnClickListeners", /* @__PURE__ */ new Ma
8738
9295
  var MPlaybackButtons = _MPlaybackButtons;
8739
9296
 
8740
9297
  // src/score/index.ts
8741
- var import_core21 = require("@tspro/web-music-score/core");
8742
- (0, import_core21.init)();
9298
+ var import_core22 = require("@tspro/web-music-score/core");
9299
+ (0, import_core22.init)();
8743
9300
  // Annotate the CommonJS export names for ESM import in node:
8744
9301
  0 && (module.exports = {
8745
9302
  Annotation,
@@ -8751,6 +9308,8 @@ var import_core21 = require("@tspro/web-music-score/core");
8751
9308
  DynamicsAnnotation,
8752
9309
  Fermata,
8753
9310
  Label,
9311
+ LyricsAlign,
9312
+ LyricsHyphen,
8754
9313
  MAccidental,
8755
9314
  MArpeggio,
8756
9315
  MBarLineLeft,
@@ -8763,6 +9322,7 @@ var import_core21 = require("@tspro/web-music-score/core");
8763
9322
  MFermata,
8764
9323
  MHeader,
8765
9324
  MImage,
9325
+ MLyrics,
8766
9326
  MMeasure,
8767
9327
  MNoteGroup,
8768
9328
  MPlaybackButtons,
@@ -8794,6 +9354,7 @@ var import_core21 = require("@tspro/web-music-score/core");
8794
9354
  TieType,
8795
9355
  VerticalPosition,
8796
9356
  getStringNumbers,
9357
+ getVerseNumbers,
8797
9358
  getVoiceIds
8798
9359
  });
8799
9360
  //# sourceMappingURL=index.js.map