@tspro/web-music-score 3.1.1 → 4.0.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 (38) hide show
  1. package/CHANGELOG.md +35 -7
  2. package/README.md +189 -331
  3. package/dist/audio/index.d.ts +1 -1
  4. package/dist/audio/index.js +1 -1
  5. package/dist/audio/index.mjs +2 -2
  6. package/dist/audio-cg/index.js +1 -1
  7. package/dist/audio-cg/index.mjs +2 -2
  8. package/dist/{chunk-PU4J7K4Z.mjs → chunk-D643HZHM.mjs} +2 -2
  9. package/dist/core/index.js +2 -2
  10. package/dist/core/index.mjs +3 -3
  11. package/dist/{guitar-C2Cp71NZ.d.ts → guitar-cNmE-EvH.d.ts} +1 -1
  12. package/dist/iife/index.global.js +11 -11
  13. package/dist/{interface-Fn8ufBQx.d.ts → interface-7k8qGG44.d.ts} +131 -83
  14. package/dist/{interface-Bz_525zj.d.mts → interface-XoKiryoV.d.mts} +130 -82
  15. package/dist/{note-BFa43I86.d.ts → note-CcVdUFqS.d.ts} +1 -1
  16. package/dist/pieces/index.d.mts +2 -2
  17. package/dist/pieces/index.d.ts +3 -3
  18. package/dist/pieces/index.js +4 -7
  19. package/dist/pieces/index.mjs +8 -11
  20. package/dist/react-ui/index.d.mts +3 -3
  21. package/dist/react-ui/index.d.ts +5 -5
  22. package/dist/react-ui/index.js +1 -1
  23. package/dist/react-ui/index.mjs +2 -2
  24. package/dist/{scale-DRR-t4Kr.d.mts → scale-C2pCNxdE.d.mts} +4 -3
  25. package/dist/{scale-ebJm37q1.d.ts → scale-CvPbJvfN.d.ts} +5 -4
  26. package/dist/score/index.d.mts +98 -31
  27. package/dist/score/index.d.ts +99 -32
  28. package/dist/score/index.js +922 -599
  29. package/dist/score/index.mjs +929 -606
  30. package/dist/tempo-BAYoZ_Li.d.mts +187 -0
  31. package/dist/tempo-r2sb6Ku2.d.ts +187 -0
  32. package/dist/theory/index.d.mts +3 -3
  33. package/dist/theory/index.d.ts +6 -6
  34. package/dist/theory/index.js +221 -78
  35. package/dist/theory/index.mjs +218 -76
  36. package/package.json +2 -2
  37. package/dist/tempo-B4h5Ktob.d.mts +0 -104
  38. package/dist/tempo-DgqDEsn0.d.ts +0 -104
@@ -1,7 +1,7 @@
1
- /* WebMusicScore v3.1.1 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v4.0.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
2
  import {
3
3
  __publicField
4
- } from "../chunk-PU4J7K4Z.mjs";
4
+ } from "../chunk-D643HZHM.mjs";
5
5
 
6
6
  // src/score/pub/div-rect.ts
7
7
  import { Utils } from "@tspro/ts-utils-lib";
@@ -277,22 +277,22 @@ var DivRect = class _DivRect {
277
277
  };
278
278
 
279
279
  // src/score/pub/document-builder.ts
280
- import { Utils as Utils11 } from "@tspro/ts-utils-lib";
280
+ import { Utils as Utils13 } from "@tspro/ts-utils-lib";
281
281
 
282
282
  // src/score/pub/types.ts
283
- var StaffPreset = /* @__PURE__ */ ((StaffPreset4) => {
284
- StaffPreset4[StaffPreset4["Treble"] = 1] = "Treble";
285
- StaffPreset4[StaffPreset4["Bass"] = 2] = "Bass";
286
- StaffPreset4[StaffPreset4["Grand"] = 3] = "Grand";
287
- StaffPreset4[StaffPreset4["GuitarTreble"] = 4] = "GuitarTreble";
288
- StaffPreset4[StaffPreset4["GuitarTab"] = 8] = "GuitarTab";
289
- StaffPreset4[StaffPreset4["GuitarCombined"] = 12] = "GuitarCombined";
290
- return StaffPreset4;
283
+ var StaffPreset = /* @__PURE__ */ ((StaffPreset3) => {
284
+ StaffPreset3["Treble"] = "treble";
285
+ StaffPreset3["Bass"] = "bass";
286
+ StaffPreset3["Grand"] = "grand";
287
+ StaffPreset3["GuitarTreble"] = "guitarTreble";
288
+ StaffPreset3["GuitarTab"] = "guitarTab";
289
+ StaffPreset3["GuitarCombined"] = "guitarCombined";
290
+ return StaffPreset3;
291
291
  })(StaffPreset || {});
292
- var Clef = /* @__PURE__ */ ((Clef3) => {
293
- Clef3["G"] = "G";
294
- Clef3["F"] = "F";
295
- return Clef3;
292
+ var Clef = /* @__PURE__ */ ((Clef2) => {
293
+ Clef2["G"] = "G";
294
+ Clef2["F"] = "F";
295
+ return Clef2;
296
296
  })(Clef || {});
297
297
  function getVoiceIds() {
298
298
  return [0, 1, 2, 3];
@@ -300,78 +300,78 @@ function getVoiceIds() {
300
300
  function getStringNumbers() {
301
301
  return [1, 2, 3, 4, 5, 6];
302
302
  }
303
- var Stem = /* @__PURE__ */ ((Stem3) => {
304
- Stem3[Stem3["Auto"] = 0] = "Auto";
305
- Stem3[Stem3["Up"] = 1] = "Up";
306
- Stem3[Stem3["Down"] = 2] = "Down";
307
- return Stem3;
303
+ var Stem = /* @__PURE__ */ ((Stem2) => {
304
+ Stem2["Auto"] = "auto";
305
+ Stem2["Up"] = "up";
306
+ Stem2["Down"] = "down";
307
+ return Stem2;
308
308
  })(Stem || {});
309
309
  var Arpeggio = /* @__PURE__ */ ((Arpeggio2) => {
310
- Arpeggio2[Arpeggio2["Up"] = 0] = "Up";
311
- Arpeggio2[Arpeggio2["Down"] = 1] = "Down";
310
+ Arpeggio2["Up"] = "up";
311
+ Arpeggio2["Down"] = "down";
312
312
  return Arpeggio2;
313
313
  })(Arpeggio || {});
314
- var TieType = /* @__PURE__ */ ((TieType3) => {
315
- TieType3[TieType3["Stub"] = -1] = "Stub";
316
- TieType3[TieType3["ToMeasureEnd"] = -2] = "ToMeasureEnd";
317
- return TieType3;
314
+ var TieType = /* @__PURE__ */ ((TieType2) => {
315
+ TieType2["Stub"] = "stub";
316
+ TieType2["ToMeasureEnd"] = "toMeasureEnd";
317
+ return TieType2;
318
318
  })(TieType || {});
319
319
  var NoteAnchor = /* @__PURE__ */ ((NoteAnchor2) => {
320
- NoteAnchor2[NoteAnchor2["Auto"] = 0] = "Auto";
321
- NoteAnchor2[NoteAnchor2["Above"] = 1] = "Above";
322
- NoteAnchor2[NoteAnchor2["Center"] = 2] = "Center";
323
- NoteAnchor2[NoteAnchor2["Below"] = 3] = "Below";
324
- NoteAnchor2[NoteAnchor2["StemTip"] = 4] = "StemTip";
320
+ NoteAnchor2["Auto"] = "auto";
321
+ NoteAnchor2["Above"] = "above";
322
+ NoteAnchor2["Center"] = "center";
323
+ NoteAnchor2["Below"] = "below";
324
+ NoteAnchor2["StemTip"] = "stemTip";
325
325
  return NoteAnchor2;
326
326
  })(NoteAnchor || {});
327
- var Connective = /* @__PURE__ */ ((Connective3) => {
328
- Connective3[Connective3["Tie"] = 0] = "Tie";
329
- Connective3[Connective3["Slur"] = 1] = "Slur";
330
- Connective3[Connective3["Slide"] = 2] = "Slide";
331
- return Connective3;
327
+ var Connective = /* @__PURE__ */ ((Connective2) => {
328
+ Connective2["Tie"] = "tie";
329
+ Connective2["Slur"] = "slur";
330
+ Connective2["Slide"] = "slide";
331
+ return Connective2;
332
332
  })(Connective || {});
333
333
  var VerticalPosition = /* @__PURE__ */ ((VerticalPosition4) => {
334
- VerticalPosition4[VerticalPosition4["Above"] = 0] = "Above";
335
- VerticalPosition4[VerticalPosition4["Below"] = 1] = "Below";
336
- VerticalPosition4[VerticalPosition4["Both"] = 2] = "Both";
337
- VerticalPosition4[VerticalPosition4["Auto"] = 3] = "Auto";
334
+ VerticalPosition4["Auto"] = "auto";
335
+ VerticalPosition4["Above"] = "above";
336
+ VerticalPosition4["Below"] = "below";
337
+ VerticalPosition4["Both"] = "both";
338
338
  return VerticalPosition4;
339
339
  })(VerticalPosition || {});
340
+ var Fermata = /* @__PURE__ */ ((Fermata2) => {
341
+ Fermata2["AtNote"] = "atNote";
342
+ Fermata2["AtMeasureEnd"] = "atMeasureEnd";
343
+ return Fermata2;
344
+ })(Fermata || {});
345
+ var Navigation = /* @__PURE__ */ ((Navigation2) => {
346
+ Navigation2["DC_al_Fine"] = "D.C. al Fine";
347
+ Navigation2["DC_al_Coda"] = "D.C. al Coda";
348
+ Navigation2["DS_al_Fine"] = "D.S. al Fine";
349
+ Navigation2["DS_al_Coda"] = "D.S. al Coda";
350
+ Navigation2["Coda"] = "Coda";
351
+ Navigation2["toCoda"] = "toCoda";
352
+ Navigation2["Segno"] = "Segno";
353
+ Navigation2["Fine"] = "Fine";
354
+ Navigation2["StartRepeat"] = "startRepeat";
355
+ Navigation2["EndRepeat"] = "endRepeat";
356
+ Navigation2["Ending"] = "ending";
357
+ return Navigation2;
358
+ })(Navigation || {});
359
+ var Annotation = /* @__PURE__ */ ((Annotation2) => {
360
+ Annotation2["Dynamics"] = "dynamics";
361
+ Annotation2["Tempo"] = "tempo";
362
+ return Annotation2;
363
+ })(Annotation || {});
364
+ var Label = /* @__PURE__ */ ((Label2) => {
365
+ Label2["Note"] = "note";
366
+ Label2["Chord"] = "chord";
367
+ return Label2;
368
+ })(Label || {});
340
369
  var PlayState = /* @__PURE__ */ ((PlayState2) => {
341
370
  PlayState2[PlayState2["Playing"] = 0] = "Playing";
342
371
  PlayState2[PlayState2["Paused"] = 1] = "Paused";
343
372
  PlayState2[PlayState2["Stopped"] = 2] = "Stopped";
344
373
  return PlayState2;
345
374
  })(PlayState || {});
346
- var Fermata = /* @__PURE__ */ ((Fermata3) => {
347
- Fermata3[Fermata3["AtNote"] = 0] = "AtNote";
348
- Fermata3[Fermata3["AtMeasureEnd"] = 1] = "AtMeasureEnd";
349
- return Fermata3;
350
- })(Fermata || {});
351
- var Navigation = /* @__PURE__ */ ((Navigation3) => {
352
- Navigation3[Navigation3["DC_al_Fine"] = 0] = "DC_al_Fine";
353
- Navigation3[Navigation3["DC_al_Coda"] = 1] = "DC_al_Coda";
354
- Navigation3[Navigation3["DS_al_Fine"] = 2] = "DS_al_Fine";
355
- Navigation3[Navigation3["DS_al_Coda"] = 3] = "DS_al_Coda";
356
- Navigation3[Navigation3["Coda"] = 4] = "Coda";
357
- Navigation3[Navigation3["toCoda"] = 5] = "toCoda";
358
- Navigation3[Navigation3["Segno"] = 6] = "Segno";
359
- Navigation3[Navigation3["Fine"] = 7] = "Fine";
360
- Navigation3[Navigation3["StartRepeat"] = 8] = "StartRepeat";
361
- Navigation3[Navigation3["EndRepeat"] = 9] = "EndRepeat";
362
- Navigation3[Navigation3["Ending"] = 10] = "Ending";
363
- return Navigation3;
364
- })(Navigation || {});
365
- var Annotation = /* @__PURE__ */ ((Annotation3) => {
366
- Annotation3[Annotation3["Dynamics"] = 0] = "Dynamics";
367
- Annotation3[Annotation3["Tempo"] = 1] = "Tempo";
368
- return Annotation3;
369
- })(Annotation || {});
370
- var Label = /* @__PURE__ */ ((Label3) => {
371
- Label3[Label3["Note"] = 0] = "Note";
372
- Label3[Label3["Chord"] = 1] = "Chord";
373
- return Label3;
374
- })(Label || {});
375
375
 
376
376
  // src/score/engine/music-object.ts
377
377
  var MusicObjectLink = class {
@@ -870,11 +870,11 @@ var Renderer = class {
870
870
 
871
871
  // src/score/engine/obj-staff-and-tab.ts
872
872
  import { MusicError as MusicError15, MusicErrorType as MusicErrorType15 } from "@tspro/web-music-score/core";
873
- import { Utils as Utils9 } from "@tspro/ts-utils-lib";
873
+ import { Utils as Utils11 } from "@tspro/ts-utils-lib";
874
874
 
875
875
  // src/score/engine/obj-measure.ts
876
- import { Utils as Utils8 } from "@tspro/ts-utils-lib";
877
- import { getScale, Scale, validateScaleType, Note as Note7, NoteLength as NoteLength6, RhythmProps as RhythmProps4, KeySignature as KeySignature2, getDefaultKeySignature, PitchNotation, SymbolSet } from "@tspro/web-music-score/theory";
876
+ import { Utils as Utils10 } from "@tspro/ts-utils-lib";
877
+ import { getScale, Scale, validateScaleType, Note as Note7, RhythmProps as RhythmProps4, KeySignature as KeySignature2, getDefaultKeySignature, PitchNotation, SymbolSet, validateNoteLength, NoteLengthProps as NoteLengthProps4 } from "@tspro/web-music-score/theory";
878
878
  import { getDefaultTempo, TimeSignature, getDefaultTimeSignature } from "@tspro/web-music-score/theory";
879
879
 
880
880
  // src/score/engine/acc-state.ts
@@ -1462,12 +1462,12 @@ var ObjSignature = class extends MusicObject {
1462
1462
  };
1463
1463
 
1464
1464
  // src/score/engine/player.ts
1465
- import { Utils as Utils5 } from "@tspro/ts-utils-lib";
1465
+ import { Utils as Utils6 } from "@tspro/ts-utils-lib";
1466
1466
  import { NoteLength as NoteLength5, RhythmProps as RhythmProps3, alterTempoSpeed } from "@tspro/web-music-score/theory";
1467
1467
  import * as Audio from "@tspro/web-music-score/audio";
1468
1468
 
1469
1469
  // src/score/engine/obj-rhythm-column.ts
1470
- import { Note as Note5, NoteLength as NoteLength4 } from "@tspro/web-music-score/theory";
1470
+ import { Note as Note5 } from "@tspro/web-music-score/theory";
1471
1471
 
1472
1472
  // src/score/engine/obj-arpeggio.ts
1473
1473
  var ObjArpeggio = class extends MusicObject {
@@ -1492,8 +1492,8 @@ var ObjArpeggio = class extends MusicObject {
1492
1492
  }
1493
1493
  layout(renderer) {
1494
1494
  let { unitSize } = renderer;
1495
- this.topArrowHeight = this.arpeggioDir === 0 /* Up */ ? unitSize : 0;
1496
- this.bottomArrowHeight = this.arpeggioDir === 1 /* Down */ ? unitSize : 0;
1495
+ this.topArrowHeight = this.arpeggioDir === "up" /* Up */ ? unitSize : 0;
1496
+ this.bottomArrowHeight = this.arpeggioDir === "down" /* Down */ ? unitSize : 0;
1497
1497
  let top = this.line.getTopLineY();
1498
1498
  let bottom = this.line.getBottomLineY();
1499
1499
  this.cycleHeight = unitSize * 2;
@@ -1540,7 +1540,7 @@ var ObjArpeggio = class extends MusicObject {
1540
1540
  };
1541
1541
 
1542
1542
  // src/score/engine/obj-rest.ts
1543
- import { Note as Note3, NoteLength, RhythmProps } from "@tspro/web-music-score/theory";
1543
+ import { Note as Note3, NoteLength, NoteLengthProps, RhythmProps, Tuplet } from "@tspro/web-music-score/theory";
1544
1544
  import { MusicError as MusicError5, MusicErrorType as MusicErrorType5 } from "@tspro/web-music-score/core";
1545
1545
  function getDiatonicIdFromStaffPos(staffPos) {
1546
1546
  if (typeof staffPos === "number") {
@@ -1559,7 +1559,7 @@ var ObjStaffRest = class extends MusicObject {
1559
1559
  this.staff = staff;
1560
1560
  this.rest = rest;
1561
1561
  __publicField(this, "restRect", new DivRect());
1562
- __publicField(this, "dotRect");
1562
+ __publicField(this, "dotRects", []);
1563
1563
  __publicField(this, "mi");
1564
1564
  staff.addObject(this);
1565
1565
  this.mi = new MStaffRest(this);
@@ -1571,21 +1571,18 @@ var ObjStaffRest = class extends MusicObject {
1571
1571
  return this.getRect().contains(x, y) ? [this] : [];
1572
1572
  }
1573
1573
  offset(dx, dy) {
1574
- var _a;
1575
1574
  this.restRect.offsetInPlace(dx, dy);
1576
- (_a = this.dotRect) == null ? void 0 : _a.offsetInPlace(dx, dy);
1575
+ this.dotRects.forEach((r) => r.offsetInPlace(dx, dy));
1577
1576
  this.requestRectUpdate();
1578
1577
  this.rest.requestRectUpdate();
1579
1578
  }
1580
1579
  updateRect() {
1581
1580
  this.rect = this.restRect.copy();
1582
- if (this.dotRect) {
1583
- this.rect.expandInPlace(this.dotRect);
1584
- }
1581
+ this.dotRects.forEach((r) => this.rect.expandInPlace(r));
1585
1582
  }
1586
1583
  };
1587
1584
  var ObjRest = class extends MusicObject {
1588
- constructor(col, voiceId, noteLength, options) {
1585
+ constructor(col, voiceId, noteLength, options, tupletRatio) {
1589
1586
  var _a, _b;
1590
1587
  super(col);
1591
1588
  this.col = col;
@@ -1594,6 +1591,7 @@ var ObjRest = class extends MusicObject {
1594
1591
  __publicField(this, "ownDiatonicId");
1595
1592
  __publicField(this, "color");
1596
1593
  __publicField(this, "hide");
1594
+ __publicField(this, "oldStyleTriplet");
1597
1595
  __publicField(this, "rhythmProps");
1598
1596
  __publicField(this, "beamGroup");
1599
1597
  __publicField(this, "staffObjects", []);
@@ -1617,7 +1615,9 @@ var ObjRest = class extends MusicObject {
1617
1615
  }
1618
1616
  this.color = (_a = options == null ? void 0 : options.color) != null ? _a : "black";
1619
1617
  this.hide = (_b = options == null ? void 0 : options.hide) != null ? _b : false;
1620
- this.rhythmProps = new RhythmProps(noteLength, options == null ? void 0 : options.dotted, options == null ? void 0 : options.triplet);
1618
+ this.oldStyleTriplet = tupletRatio === void 0 && ((options == null ? void 0 : options.triplet) === true || NoteLengthProps.get(noteLength).isTriplet);
1619
+ let dotCount = typeof (options == null ? void 0 : options.dotted) === "number" ? options.dotted > 0 ? options.dotted : void 0 : (options == null ? void 0 : options.dotted) === true ? 1 : void 0;
1620
+ this.rhythmProps = RhythmProps.get(noteLength, dotCount, (tupletRatio != null ? tupletRatio : this.oldStyleTriplet) ? Tuplet.Triplet : void 0);
1621
1621
  this.mi = new MRest(this);
1622
1622
  }
1623
1623
  getMusicInterface() {
@@ -1635,15 +1635,9 @@ var ObjRest = class extends MusicObject {
1635
1635
  get noteLength() {
1636
1636
  return this.rhythmProps.noteLength;
1637
1637
  }
1638
- get dotted() {
1639
- return this.rhythmProps.dotted;
1640
- }
1641
1638
  get stemDir() {
1642
1639
  return this.beamGroup ? this.beamGroup.stemDir : this.ownStemDir;
1643
1640
  }
1644
- get triplet() {
1645
- return this.rhythmProps.triplet;
1646
- }
1647
1641
  getStaticObjects(line) {
1648
1642
  let staticObjects = [];
1649
1643
  this.staffObjects.forEach((obj) => {
@@ -1663,13 +1657,13 @@ var ObjRest = class extends MusicObject {
1663
1657
  return [this, ...arr];
1664
1658
  }
1665
1659
  }
1666
- return [this];
1660
+ return [];
1667
1661
  }
1668
1662
  getBeamGroup() {
1669
1663
  return this.beamGroup;
1670
1664
  }
1671
- setBeamGroup(beam) {
1672
- this.beamGroup = beam;
1665
+ setBeamGroup(beamGroup) {
1666
+ this.beamGroup = beamGroup;
1673
1667
  }
1674
1668
  resetBeamGroup() {
1675
1669
  this.beamGroup = void 0;
@@ -1678,7 +1672,7 @@ var ObjRest = class extends MusicObject {
1678
1672
  return this.staffObjects.map((obj) => {
1679
1673
  let staff = obj.staff;
1680
1674
  let x = obj.getRect().centerX;
1681
- let y = this.stemDir === 1 /* Up */ ? obj.getRect().top : obj.getRect().bottom;
1675
+ let y = this.stemDir === "up" /* Up */ ? obj.getRect().top : obj.getRect().bottom;
1682
1676
  let stemHeight = Math.abs(obj.getRect().centerY - y);
1683
1677
  return { staff, x, y, stemHeight };
1684
1678
  });
@@ -1719,7 +1713,7 @@ var ObjRest = class extends MusicObject {
1719
1713
  }
1720
1714
  let { unitSize } = renderer;
1721
1715
  let { ownDiatonicId } = this;
1722
- let { noteLength, dotted, flagCount } = this.rhythmProps;
1716
+ let { noteLength, dotCount, flagCount } = this.rhythmProps;
1723
1717
  let leftw = 0;
1724
1718
  let rightw = 0;
1725
1719
  let toph = 0;
@@ -1752,11 +1746,11 @@ var ObjRest = class extends MusicObject {
1752
1746
  }
1753
1747
  let obj = new ObjStaffRest(staff, this);
1754
1748
  obj.restRect = new DivRect(-leftw, 0, rightw, -toph, 0, bottomh);
1755
- if (dotted) {
1749
+ for (let i = 0; i < dotCount; i++) {
1756
1750
  let dotWidth = DocumentSettings.DotSize * unitSize;
1757
- let dotX = rightw + (DocumentSettings.RestDotSpace + DocumentSettings.DotSize / 2) * unitSize;
1751
+ let dotX = rightw + (DocumentSettings.RestDotSpace + DocumentSettings.DotSize * unitSize) + i * DocumentSettings.DotSize * unitSize * 1.5;
1758
1752
  let dotY = this.getRestDotVerticalDisplacement(noteLength) * unitSize;
1759
- obj.dotRect = DivRect.createCentered(dotX, dotY, dotWidth, dotWidth);
1753
+ obj.dotRects.push(DivRect.createCentered(dotX, dotY, dotWidth, dotWidth));
1760
1754
  }
1761
1755
  obj.offset(0, staff.getDiatonicIdY(ownDiatonicId));
1762
1756
  this.staffObjects.push(obj);
@@ -1790,7 +1784,7 @@ var ObjRest = class extends MusicObject {
1790
1784
  ctx.strokeStyle = ctx.fillStyle = color;
1791
1785
  ctx.lineWidth = lineWidth;
1792
1786
  this.staffObjects.forEach((obj) => {
1793
- let { dotRect, restRect } = obj;
1787
+ let { dotRects, restRect } = obj;
1794
1788
  let x = restRect.centerX;
1795
1789
  let y = restRect.centerY;
1796
1790
  if (noteLength === NoteLength.Whole) {
@@ -1855,20 +1849,20 @@ var ObjRest = class extends MusicObject {
1855
1849
  ctx.fill();
1856
1850
  }
1857
1851
  }
1858
- if (dotRect) {
1859
- renderer.fillCircle(dotRect.centerX, dotRect.centerY, dotRect.width / 2);
1860
- }
1852
+ dotRects.forEach((r) => {
1853
+ renderer.fillCircle(r.centerX, r.centerY, r.width / 2);
1854
+ });
1861
1855
  });
1862
1856
  }
1863
1857
  };
1864
1858
 
1865
1859
  // src/score/engine/obj-note-group.ts
1866
1860
  import { Utils as Utils4 } from "@tspro/ts-utils-lib";
1867
- import { Note as Note4, NoteLength as NoteLength3, RhythmProps as RhythmProps2 } from "@tspro/web-music-score/theory";
1861
+ import { Note as Note4, NoteLengthProps as NoteLengthProps3, RhythmProps as RhythmProps2, Tuplet as Tuplet3 } from "@tspro/web-music-score/theory";
1868
1862
 
1869
1863
  // src/score/engine/obj-beam-group.ts
1870
1864
  import { Utils as Utils3 } from "@tspro/ts-utils-lib";
1871
- import { MinNoteLength, NoteLength as NoteLength2 } from "@tspro/web-music-score/theory";
1865
+ import { NoteLength as NoteLength2, Tuplet as Tuplet2, NoteLengthProps as NoteLengthProps2 } from "@tspro/web-music-score/theory";
1872
1866
  import { MusicError as MusicError6, MusicErrorType as MusicErrorType6 } from "@tspro/web-music-score/core";
1873
1867
  var adjustBeamAngle = (dx, dy) => {
1874
1868
  let T = DocumentSettings.BeamAngleFactor;
@@ -1905,8 +1899,8 @@ var ObjStaffBeamGroup = class extends MusicObject {
1905
1899
  super(staff);
1906
1900
  this.staff = staff;
1907
1901
  this.beamGroup = beamGroup;
1908
- __publicField(this, "tripletNumber");
1909
- __publicField(this, "tripletNumberOffsetY", 0);
1902
+ __publicField(this, "tupletNumber");
1903
+ __publicField(this, "tupletNumberOffsetY", 0);
1910
1904
  __publicField(this, "points", []);
1911
1905
  __publicField(this, "mi");
1912
1906
  staff.addObject(this);
@@ -1921,48 +1915,47 @@ var ObjStaffBeamGroup = class extends MusicObject {
1921
1915
  offset(dx, dy) {
1922
1916
  var _a;
1923
1917
  this.points.forEach((p) => p.offset(dx, 0));
1924
- (_a = this.tripletNumber) == null ? void 0 : _a.offset(dx, dy);
1918
+ (_a = this.tupletNumber) == null ? void 0 : _a.offset(dx, dy);
1925
1919
  this.requestRectUpdate();
1926
1920
  this.beamGroup.requestRectUpdate();
1927
1921
  }
1928
1922
  updateRect() {
1929
1923
  if (this.points.length > 0) {
1930
1924
  this.rect = this.points[0].getRect().copy();
1931
- } else if (this.tripletNumber) {
1932
- this.rect = this.tripletNumber.getRect().copy();
1925
+ } else if (this.tupletNumber) {
1926
+ this.rect = this.tupletNumber.getRect().copy();
1933
1927
  }
1934
1928
  this.points.forEach((pt) => this.rect.expandInPlace(pt.getRect()));
1935
- if (this.tripletNumber) {
1936
- this.rect.expandInPlace(this.tripletNumber.getRect());
1929
+ if (this.tupletNumber) {
1930
+ this.rect.expandInPlace(this.tupletNumber.getRect());
1937
1931
  }
1938
1932
  }
1939
1933
  };
1940
1934
  var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
1941
- constructor(symbols, triplet) {
1935
+ constructor(symbols, tupletRatio) {
1942
1936
  super(symbols[0].measure);
1943
1937
  this.symbols = symbols;
1938
+ this.tupletRatio = tupletRatio;
1944
1939
  __publicField(this, "mi");
1945
1940
  __publicField(this, "type");
1946
1941
  __publicField(this, "staffObjects", []);
1947
1942
  this.mi = new MBeamGroup(this);
1943
+ let beamGroupName = tupletRatio ? "Tuplet" : "BeamGroup";
1948
1944
  if (!symbols.every((s) => s.measure === symbols[0].measure)) {
1949
- throw new MusicError6(MusicErrorType6.Score, "All beam group symbols are not in same measure.");
1945
+ throw new MusicError6(MusicErrorType6.Score, `All ${beamGroupName} symbols are not in same measure.`);
1950
1946
  } else if (symbols.length < 2) {
1951
- throw new MusicError6(MusicErrorType6.Score, "Beam group need minimum 2 symbols, but " + symbols.length + " given.");
1947
+ throw new MusicError6(MusicErrorType6.Score, `${beamGroupName} needs minimum 2 symbols, but ${symbols.length} given.`);
1952
1948
  }
1953
- if (triplet) {
1954
- if (!symbols.every((s) => s.triplet)) {
1955
- throw new MusicError6(MusicErrorType6.Score, "Not every symbol's triplet property is true.");
1956
- }
1949
+ if (tupletRatio !== void 0) {
1957
1950
  let isGroup = symbols.length < 3 || symbols.some((s) => !(s instanceof ObjNoteGroup)) || symbols.some((s) => s.rhythmProps.flagCount !== symbols[0].rhythmProps.flagCount);
1958
- if (symbols.length === 3 && symbols[0] instanceof ObjNoteGroup && symbols[symbols.length - 1] instanceof ObjNoteGroup && symbols[0].rhythmProps.flagCount === symbols[symbols.length - 1].rhythmProps.flagCount) {
1951
+ if (symbols.length >= 3 && symbols[0] instanceof ObjNoteGroup && symbols[symbols.length - 1] instanceof ObjNoteGroup && symbols[0].rhythmProps.flagCount === symbols[symbols.length - 1].rhythmProps.flagCount) {
1959
1952
  isGroup = false;
1960
1953
  }
1961
- if (symbols.some((s) => s.rhythmProps.noteLength >= NoteLength2.Quarter)) {
1954
+ if (symbols.some((s) => NoteLengthProps2.cmp(s.rhythmProps.noteLength, NoteLength2.Quarter) >= 0)) {
1962
1955
  isGroup = true;
1963
1956
  }
1964
- this.type = isGroup ? 2 /* TripletGroup */ : 1 /* TripletBeam */;
1965
- ObjNoteGroup.setTripletBeamCounts(this);
1957
+ this.type = isGroup ? 2 /* TupletGroup */ : 1 /* TupletBeam */;
1958
+ ObjNoteGroup.setTupletBeamCounts(this);
1966
1959
  } else {
1967
1960
  this.type = 0 /* RegularBeam */;
1968
1961
  }
@@ -1970,32 +1963,35 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
1970
1963
  symbols.forEach((s) => s.setBeamGroup(this));
1971
1964
  symbols[0].measure.addBeamGroup(this);
1972
1965
  } else {
1973
- throw new MusicError6(MusicErrorType6.Score, "Cannot add beam group because some symbol already has one.");
1966
+ throw new MusicError6(MusicErrorType6.Score, `Cannot add ${beamGroupName} because some symbol already has one.`);
1974
1967
  }
1975
1968
  }
1969
+ get showTupletRatio() {
1970
+ var _a;
1971
+ return ((_a = this.tupletRatio) == null ? void 0 : _a.showRatio) === true;
1972
+ }
1976
1973
  static createBeam(noteGroups) {
1977
1974
  if (noteGroups.length > 1) {
1978
- new _ObjBeamGroup(noteGroups, false);
1975
+ new _ObjBeamGroup(noteGroups, void 0);
1979
1976
  }
1980
1977
  }
1981
- static createTriplet(symbols) {
1982
- if (!symbols.every((s) => s.triplet)) {
1983
- return false;
1978
+ static createOldStyleTriplet(symbols) {
1979
+ let s2 = symbols.slice(0, 2);
1980
+ let n2 = s2.map((s) => s.rhythmProps.noteSize);
1981
+ if (s2.length === 2 && s2.every((s) => s.oldStyleTriplet && s.getBeamGroup() === void 0) && (n2[0] * 2 === n2[1] || n2[1] * 2 === n2[0])) {
1982
+ new _ObjBeamGroup(s2, Tuplet2.Triplet);
1983
+ return 2;
1984
1984
  }
1985
- let MaxTripletNoteLenght = NoteLength2.Half;
1986
- let len = symbols.map((s) => s.rhythmProps.noteLength);
1987
- if (symbols.length == 2) {
1988
- if (len[0] <= MaxTripletNoteLenght && len[1] === len[0] / 2 && len[0] / 2 >= MinNoteLength || len[1] <= MaxTripletNoteLenght && len[0] === len[1] / 2 && len[1] / 2 >= MinNoteLength) {
1989
- new _ObjBeamGroup(symbols, true);
1990
- return true;
1991
- }
1992
- } else if (symbols.length === 3) {
1993
- if (len[0] <= MaxTripletNoteLenght && len.every((l) => l === len[0])) {
1994
- new _ObjBeamGroup(symbols, true);
1995
- return true;
1996
- }
1985
+ let s3 = symbols.slice(0, 3);
1986
+ let n3 = s3.map((s) => s.rhythmProps.noteSize);
1987
+ if (s3.length === 3 && s3.every((s) => s.oldStyleTriplet && s.getBeamGroup() === void 0) && n3.every((n) => n === n3[0])) {
1988
+ new _ObjBeamGroup(s3, Tuplet2.Triplet);
1989
+ return 3;
1997
1990
  }
1998
- return false;
1991
+ return 0;
1992
+ }
1993
+ static createTuplet(symbols, tupletRatio) {
1994
+ new _ObjBeamGroup(symbols, tupletRatio);
1999
1995
  }
2000
1996
  getMusicInterface() {
2001
1997
  return this.mi;
@@ -2021,8 +2017,8 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
2021
2017
  getType() {
2022
2018
  return this.type;
2023
2019
  }
2024
- isTriplet() {
2025
- return this.type === 1 /* TripletBeam */ || this.type === 2 /* TripletGroup */;
2020
+ isTuplet() {
2021
+ return this.type === 1 /* TupletBeam */ || this.type === 2 /* TupletGroup */;
2026
2022
  }
2027
2023
  getSymbols() {
2028
2024
  return this.symbols;
@@ -2084,10 +2080,10 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
2084
2080
  }
2085
2081
  let leftStemHeight = (_a = symbolStemHeight[0]) != null ? _a : 0;
2086
2082
  let rightStemHeight = (_b = symbolStemHeight[symbolStemHeight.length - 1]) != null ? _b : 0;
2087
- if (this.type !== 2 /* TripletGroup */) {
2083
+ if (this.type !== 2 /* TupletGroup */) {
2088
2084
  let leftDy = leftStemHeight < rightStemHeight ? Math.sqrt(rightStemHeight - leftStemHeight) : 0;
2089
2085
  let rightDy = rightStemHeight < leftStemHeight ? Math.sqrt(leftStemHeight - rightStemHeight) : 0;
2090
- if (stemDir === 1 /* Up */) {
2086
+ if (stemDir === "up" /* Up */) {
2091
2087
  leftDy *= -1;
2092
2088
  rightDy *= -1;
2093
2089
  }
@@ -2100,7 +2096,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
2100
2096
  symbolY[symbolY.length - 1] += rightDy;
2101
2097
  }
2102
2098
  }
2103
- let groupLineDy = unitSize * 2 * (stemDir === 1 /* Up */ ? -1 : 1);
2099
+ let groupLineDy = unitSize * 2 * (stemDir === "up" /* Up */ ? -1 : 1);
2104
2100
  let centerY = (rightY + leftY) / 2;
2105
2101
  let halfDy = adjustBeamAngle(rightX - leftX, rightY - leftY) / 2;
2106
2102
  leftY = centerY - halfDy;
@@ -2111,9 +2107,9 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
2111
2107
  if (symX !== void 0 && symY !== void 0) {
2112
2108
  let beamY = Utils3.Math.interpolateY(leftX, leftY, rightX, rightY, symX);
2113
2109
  let raiseY = symY - beamY;
2114
- if (stemDir === 1 /* Up */ && raiseY < 0) {
2110
+ if (stemDir === "up" /* Up */ && raiseY < 0) {
2115
2111
  raiseBeamY = Math.min(raiseBeamY, raiseY);
2116
- } else if (stemDir === 2 /* Down */ && raiseY > 0) {
2112
+ } else if (stemDir === "down" /* Down */ && raiseY > 0) {
2117
2113
  raiseBeamY = Math.max(raiseBeamY, raiseY);
2118
2114
  }
2119
2115
  }
@@ -2122,21 +2118,21 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
2122
2118
  rightY += raiseBeamY;
2123
2119
  symbolY = symbolY.map((y) => y === void 0 ? void 0 : y + raiseBeamY);
2124
2120
  let obj = new ObjStaffBeamGroup(mainStaff, this);
2125
- if (this.type === 2 /* TripletGroup */) {
2121
+ if (this.type === 2 /* TupletGroup */) {
2126
2122
  let ef = unitSize / (rightX - leftX);
2127
2123
  let l = Utils3.Math.interpolateCoord(leftX, leftY + groupLineDy, rightX, rightY + groupLineDy, -ef);
2128
2124
  let r = Utils3.Math.interpolateCoord(leftX, leftY + groupLineDy, rightX, rightY + groupLineDy, 1 + ef);
2129
2125
  obj.points.push(new BeamPoint(leftStaff, this, leftSymbol, l.x, l.y));
2130
2126
  obj.points.push(new BeamPoint(rightStaff, this, rightSymbol, r.x, r.y));
2131
- obj.tripletNumberOffsetY = 0;
2132
- } else if (this.type === 0 /* RegularBeam */ || this.type === 1 /* TripletBeam */) {
2127
+ obj.tupletNumberOffsetY = 0;
2128
+ } else if (this.type === 0 /* RegularBeam */ || this.type === 1 /* TupletBeam */) {
2133
2129
  raiseBeamY *= 0.5;
2134
2130
  let { beamThickness } = renderer;
2135
2131
  const beamHeight = (i) => {
2136
2132
  let sym = symbols[i];
2137
2133
  if (sym instanceof ObjNoteGroup) {
2138
2134
  let beamCount = sym instanceof ObjNoteGroup ? Math.max(sym.getLeftBeamCount(), sym.getRightBeamCount()) : 0;
2139
- return DocumentSettings.BeamSeparation * unitSize * (this.stemDir === 1 /* Up */ ? beamCount - 1 : 0);
2135
+ return DocumentSettings.BeamSeparation * unitSize * (this.stemDir === "up" /* Up */ ? beamCount - 1 : 0);
2140
2136
  } else {
2141
2137
  return 0;
2142
2138
  }
@@ -2147,17 +2143,18 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
2147
2143
  let symY = symbolY[i];
2148
2144
  if (symStaff && symX !== void 0 && symY !== void 0) {
2149
2145
  let pt = new BeamPoint(symStaff, this, sym, symX, symY);
2150
- pt.topBeamsHeight = beamThickness / 2 + (stemDir === 2 /* Down */ ? beamHeight(i) : 0);
2151
- pt.bottomBeamsHeight = beamThickness / 2 + (stemDir === 1 /* Up */ ? beamHeight(i) : 0);
2146
+ pt.topBeamsHeight = beamThickness / 2 + (stemDir === "down" /* Down */ ? beamHeight(i) : 0);
2147
+ pt.bottomBeamsHeight = beamThickness / 2 + (stemDir === "up" /* Up */ ? beamHeight(i) : 0);
2152
2148
  obj.points.push(pt);
2153
2149
  }
2154
2150
  });
2155
- obj.tripletNumberOffsetY = groupLineDy;
2151
+ obj.tupletNumberOffsetY = groupLineDy;
2156
2152
  }
2157
- if (this.isTriplet()) {
2158
- obj.tripletNumber = new ObjText(this, "3", 0.5, 0.5);
2159
- obj.tripletNumber.layout(renderer);
2160
- obj.tripletNumber.offset((leftX + rightX) / 2, (leftY + rightY) / 2 + obj.tripletNumberOffsetY);
2153
+ if (this.isTuplet() && this.tupletRatio) {
2154
+ let txt = this.showTupletRatio ? String(this.tupletRatio.parts) + ":" + String(this.tupletRatio.inTimeOf) : String(this.tupletRatio.parts);
2155
+ obj.tupletNumber = new ObjText(this, txt, 0.5, 0.5);
2156
+ obj.tupletNumber.layout(renderer);
2157
+ obj.tupletNumber.offset((leftX + rightX) / 2, (leftY + rightY) / 2 + obj.tupletNumberOffsetY);
2161
2158
  }
2162
2159
  if (obj.points.length >= 2) {
2163
2160
  this.staffObjects.push(obj);
@@ -2179,7 +2176,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
2179
2176
  this.staffObjects.forEach((obj) => {
2180
2177
  let left = obj.points[0];
2181
2178
  let right = obj.points[obj.points.length - 1];
2182
- if (this.type !== 2 /* TripletGroup */) {
2179
+ if (this.type !== 2 /* TupletGroup */) {
2183
2180
  obj.points.forEach((pt) => {
2184
2181
  if (pt.symbol instanceof ObjNoteGroup) {
2185
2182
  if (pt !== left && pt !== right) {
@@ -2189,9 +2186,9 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
2189
2186
  }
2190
2187
  });
2191
2188
  }
2192
- if (obj.tripletNumber) {
2193
- let y = (left.y + right.y) / 2 + obj.tripletNumberOffsetY;
2194
- obj.tripletNumber.offset(0, -obj.tripletNumber.getRect().centerY + y);
2189
+ if (obj.tupletNumber) {
2190
+ let y = (left.y + right.y) / 2 + obj.tupletNumberOffsetY;
2191
+ obj.tupletNumber.offset(0, -obj.tupletNumber.getRect().centerY + y);
2195
2192
  }
2196
2193
  });
2197
2194
  }
@@ -2203,21 +2200,21 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
2203
2200
  let { unitSize, beamThickness, lineWidth } = renderer;
2204
2201
  let color = "black";
2205
2202
  this.staffObjects.forEach((obj) => {
2206
- if (this.type === 2 /* TripletGroup */) {
2203
+ if (this.type === 2 /* TupletGroup */) {
2207
2204
  let l = obj.points[0];
2208
2205
  let r = obj.points[obj.points.length - 1];
2209
2206
  if (l && r) {
2210
- let tf = obj.tripletNumber ? obj.tripletNumber.getRect().width / (r.x - l.x) * 1.2 : 0;
2207
+ let tf = obj.tupletNumber ? obj.tupletNumber.getRect().width / (r.x - l.x) * 1.2 : 0;
2211
2208
  let lc = Utils3.Math.interpolateCoord(l.x, l.y, r.x, r.y, 0.5 - tf / 2);
2212
2209
  let rc = Utils3.Math.interpolateCoord(l.x, l.y, r.x, r.y, 0.5 + tf / 2);
2213
- let tipH = this.stemDir === 1 /* Up */ ? unitSize : -unitSize;
2210
+ let tipH = this.stemDir === "up" /* Up */ ? unitSize : -unitSize;
2214
2211
  renderer.drawLine(l.x, l.y, lc.x, lc.y, color, lineWidth);
2215
2212
  renderer.drawLine(rc.x, rc.y, r.x, r.y, color, lineWidth);
2216
2213
  renderer.drawLine(l.x, l.y, l.x, l.y + tipH, color, lineWidth);
2217
2214
  renderer.drawLine(r.x, r.y, r.x, r.y + tipH, color, lineWidth);
2218
2215
  }
2219
- } else if (this.type === 0 /* RegularBeam */ || this.type === 1 /* TripletBeam */) {
2220
- let beamSeparation = DocumentSettings.BeamSeparation * unitSize * (this.stemDir === 1 /* Up */ ? 1 : -1);
2216
+ } else if (this.type === 0 /* RegularBeam */ || this.type === 1 /* TupletBeam */) {
2217
+ let beamSeparation = DocumentSettings.BeamSeparation * unitSize * (this.stemDir === "up" /* Up */ ? 1 : -1);
2221
2218
  let noteGroupPoints = obj.points.filter((p) => p.symbol instanceof ObjNoteGroup);
2222
2219
  for (let i = 0; i < noteGroupPoints.length - 1; i++) {
2223
2220
  let left = noteGroupPoints[i];
@@ -2244,8 +2241,8 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
2244
2241
  }
2245
2242
  }
2246
2243
  }
2247
- if (obj.tripletNumber) {
2248
- obj.tripletNumber.draw(renderer);
2244
+ if (obj.tupletNumber) {
2245
+ obj.tupletNumber.draw(renderer);
2249
2246
  }
2250
2247
  });
2251
2248
  }
@@ -2253,6 +2250,12 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
2253
2250
 
2254
2251
  // src/score/engine/obj-note-group.ts
2255
2252
  import { MusicError as MusicError7, MusicErrorType as MusicErrorType7 } from "@tspro/web-music-score/core";
2253
+ function getStem(stem) {
2254
+ return Utils4.Is.isEnumValue(stem, Stem) ? stem : void 0;
2255
+ }
2256
+ function getArpeggio(a) {
2257
+ return Utils4.Is.isEnumValue(a, Arpeggio) ? a : a === true ? "up" /* Up */ : void 0;
2258
+ }
2256
2259
  function sortNoteStringData(notes, strings) {
2257
2260
  let stringArr = Utils4.Arr.isArray(strings) ? strings : strings !== void 0 ? [strings] : [];
2258
2261
  let noteStringData = notes.map((note, i) => {
@@ -2264,9 +2267,6 @@ function sortNoteStringData(notes, strings) {
2264
2267
  strings: noteStringData.every((e) => e.string === void 0) ? void 0 : noteStringData.map((e) => e.string)
2265
2268
  };
2266
2269
  }
2267
- function solveArpeggio(a) {
2268
- return a === true || a === 0 /* Up */ ? 0 /* Up */ : a === 1 /* Down */ ? 1 /* Down */ : void 0;
2269
- }
2270
2270
  var ObjStaffNoteGroup = class extends MusicObject {
2271
2271
  constructor(staff, noteGroup) {
2272
2272
  super(staff);
@@ -2287,7 +2287,16 @@ var ObjStaffNoteGroup = class extends MusicObject {
2287
2287
  return this.mi;
2288
2288
  }
2289
2289
  pick(x, y) {
2290
- return this.getRect().contains(x, y) ? [this] : [];
2290
+ if (!this.getRect().contains(x, y)) {
2291
+ return [];
2292
+ }
2293
+ for (let i = 0; i < this.accidentals.length; i++) {
2294
+ let arr = this.accidentals[i].pick(x, y);
2295
+ if (arr.length > 0) {
2296
+ return [this, ...arr];
2297
+ }
2298
+ }
2299
+ return [this];
2291
2300
  }
2292
2301
  updateRect() {
2293
2302
  this.rect = this.noteHeadRects[0].copy();
@@ -2347,7 +2356,7 @@ var ObjTabNoteGroup = class extends MusicObject {
2347
2356
  }
2348
2357
  };
2349
2358
  var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2350
- constructor(col, voiceId, notes, noteLength, options) {
2359
+ constructor(col, voiceId, notes, noteLength, options, tupletRatio) {
2351
2360
  var _a, _b, _c;
2352
2361
  super(col);
2353
2362
  this.col = col;
@@ -2363,6 +2372,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2363
2372
  __publicField(this, "staccato");
2364
2373
  __publicField(this, "diamond");
2365
2374
  __publicField(this, "arpeggio");
2375
+ __publicField(this, "oldStyleTriplet");
2366
2376
  __publicField(this, "rhythmProps");
2367
2377
  __publicField(this, "startConnnectives", []);
2368
2378
  __publicField(this, "runningConnectives", []);
@@ -2380,13 +2390,15 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2380
2390
  this.minDiatonicId = this.notes[0].diatonicId;
2381
2391
  this.maxDiatonicId = this.notes[this.notes.length - 1].diatonicId;
2382
2392
  this.ownDiatonicId = this.measure.updateOwnDiatonicId(voiceId, Math.round((this.minDiatonicId + this.maxDiatonicId) / 2));
2383
- this.ownStemDir = this.measure.updateOwnStemDir(this, options == null ? void 0 : options.stem);
2393
+ this.ownStemDir = this.measure.updateOwnStemDir(this, getStem(options == null ? void 0 : options.stem));
2384
2394
  this.ownString = this.measure.updateOwnString(this, noteStringData.strings);
2385
2395
  this.color = (_a = options == null ? void 0 : options.color) != null ? _a : "black";
2386
2396
  this.staccato = (_b = options == null ? void 0 : options.staccato) != null ? _b : false;
2387
2397
  this.diamond = (_c = options == null ? void 0 : options.diamond) != null ? _c : false;
2388
- this.arpeggio = solveArpeggio(options == null ? void 0 : options.arpeggio);
2389
- this.rhythmProps = new RhythmProps2(noteLength, options == null ? void 0 : options.dotted, options == null ? void 0 : options.triplet);
2398
+ this.arpeggio = getArpeggio(options == null ? void 0 : options.arpeggio);
2399
+ this.oldStyleTriplet = tupletRatio === void 0 && ((options == null ? void 0 : options.triplet) === true || NoteLengthProps3.get(noteLength).isTriplet);
2400
+ let dotCount = typeof (options == null ? void 0 : options.dotted) === "number" ? options.dotted > 0 ? options.dotted : void 0 : (options == null ? void 0 : options.dotted) === true ? 1 : void 0;
2401
+ this.rhythmProps = RhythmProps2.get(noteLength, dotCount, (tupletRatio != null ? tupletRatio : this.oldStyleTriplet) ? Tuplet3.Triplet : void 0);
2390
2402
  this.mi = new MNoteGroup(this);
2391
2403
  }
2392
2404
  getMusicInterface() {
@@ -2404,16 +2416,13 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2404
2416
  get stemDir() {
2405
2417
  return this.beamGroup ? this.beamGroup.stemDir : this.ownStemDir;
2406
2418
  }
2407
- get triplet() {
2408
- return this.rhythmProps.triplet;
2409
- }
2410
2419
  enableConnective(line) {
2411
2420
  return line.containsVoiceId(this.voiceId) && (line instanceof ObjTab || line.containsDiatonicId(this.ownDiatonicId));
2412
2421
  }
2413
2422
  startConnective(connectiveProps) {
2414
- if (!this.row.hasStaff && connectiveProps.connective === 0 /* Tie */) {
2423
+ if (!this.row.hasStaff && connectiveProps.connective === "tie" /* Tie */) {
2415
2424
  throw new MusicError7(MusicErrorType7.Score, "Ties not implemented for guitar tabs alone, staff is required!");
2416
- } else if (!this.row.hasStaff && connectiveProps.connective === 1 /* Slur */) {
2425
+ } else if (!this.row.hasStaff && connectiveProps.connective === "slur" /* Slur */) {
2417
2426
  throw new MusicError7(MusicErrorType7.Score, "Slurs not implemented for guitar tabs alone, staff is required!");
2418
2427
  }
2419
2428
  this.startConnnectives.push(connectiveProps);
@@ -2449,7 +2458,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2449
2458
  return [this, ...arr];
2450
2459
  }
2451
2460
  }
2452
- return [this];
2461
+ return [];
2453
2462
  }
2454
2463
  getTopNote() {
2455
2464
  return this.notes[this.notes.length - 1];
@@ -2472,7 +2481,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2472
2481
  let stemTip = obj.stemTip;
2473
2482
  let stemDir = this.stemDir;
2474
2483
  let hasStem = stemTip !== void 0;
2475
- let stemSide = !hasStem ? void 0 : stemDir === 1 /* Up */ ? "right" : "left";
2484
+ let stemSide = !hasStem ? void 0 : stemDir === "up" /* Up */ ? "right" : "left";
2476
2485
  let padding = noteHeadRect.height / 2;
2477
2486
  let centerX = noteHeadRect.centerX;
2478
2487
  let centerY = noteHeadRect.centerY;
@@ -2480,16 +2489,16 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2480
2489
  let rightX = noteHeadRect.right + padding;
2481
2490
  let aboveY = noteHeadRect.top - padding;
2482
2491
  let belowY = noteHeadRect.bottom + padding;
2483
- if (noteAnchor === 0 /* Auto */) {
2484
- noteAnchor = 3 /* Below */;
2485
- } else if (noteAnchor === 4 /* StemTip */ && !hasStem) {
2486
- noteAnchor = stemDir === 1 /* Up */ ? 1 /* Above */ : 3 /* Below */;
2492
+ if (noteAnchor === "auto" /* Auto */) {
2493
+ noteAnchor = "below" /* Below */;
2494
+ } else if (noteAnchor === "stemTip" /* StemTip */ && !hasStem) {
2495
+ noteAnchor = stemDir === "up" /* Up */ ? "above" /* Above */ : "below" /* Below */;
2487
2496
  }
2488
2497
  switch (noteAnchor) {
2489
- case 2 /* Center */:
2498
+ case "center" /* Center */:
2490
2499
  return side === "left" ? { x: rightX, y: centerY } : { x: leftX, y: centerY };
2491
- case 1 /* Above */:
2492
- if (!hasStem || stemDir === 2 /* Down */) {
2500
+ case "above" /* Above */:
2501
+ if (!hasStem || stemDir === "down" /* Down */) {
2493
2502
  return { x: centerX, y: aboveY };
2494
2503
  } else {
2495
2504
  return {
@@ -2497,8 +2506,8 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2497
2506
  y: aboveY
2498
2507
  };
2499
2508
  }
2500
- case 3 /* Below */:
2501
- if (!hasStem || stemDir === 1 /* Up */) {
2509
+ case "below" /* Below */:
2510
+ if (!hasStem || stemDir === "up" /* Up */) {
2502
2511
  return { x: centerX, y: belowY };
2503
2512
  } else {
2504
2513
  return {
@@ -2506,8 +2515,8 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2506
2515
  y: belowY
2507
2516
  };
2508
2517
  }
2509
- case 4 /* StemTip */:
2510
- return { x: centerX, y: stemTip.centerY + (stemDir === 1 /* Up */ ? -padding : padding) };
2518
+ case "stemTip" /* StemTip */:
2519
+ return { x: centerX, y: stemTip.centerY + (stemDir === "up" /* Up */ ? -padding : padding) };
2511
2520
  default:
2512
2521
  throw new MusicError7(MusicErrorType7.Score, "Invalid noteAnchor: " + noteAnchor);
2513
2522
  }
@@ -2522,7 +2531,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2522
2531
  let x = side === "right" ? r.left : r.right;
2523
2532
  let y;
2524
2533
  let s = 0.9;
2525
- if (connectiveProps.connective === 2 /* Slide */) {
2534
+ if (connectiveProps.connective === "slide" /* Slide */) {
2526
2535
  let leftFretNumber = connectiveProps.noteGroups[0].getFretNumber(obj, 0);
2527
2536
  let rightFretNumber = connectiveProps.noteGroups[1].getFretNumber(obj, 0);
2528
2537
  let slideUp = leftFretNumber === void 0 || rightFretNumber === void 0 || leftFretNumber <= rightFretNumber;
@@ -2576,7 +2585,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2576
2585
  this.runningConnectives = [];
2577
2586
  }
2578
2587
  getPlaySlur() {
2579
- let slurs = this.runningConnectives.filter((c) => c.connective === 1 /* Slur */).map((c) => c.startsWith(this) ? "first" : "slurred");
2588
+ let slurs = this.runningConnectives.filter((c) => c.connective === "slur" /* Slur */).map((c) => c.startsWith(this) ? "first" : "slurred");
2580
2589
  if (slurs.indexOf("first") >= 0) {
2581
2590
  return "first";
2582
2591
  } else if (slurs.indexOf("slurred") >= 0) {
@@ -2588,8 +2597,8 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2588
2597
  getBeamGroup() {
2589
2598
  return this.beamGroup;
2590
2599
  }
2591
- setBeamGroup(beam) {
2592
- this.beamGroup = beam;
2600
+ setBeamGroup(beamGroup) {
2601
+ this.beamGroup = beamGroup;
2593
2602
  }
2594
2603
  resetBeamGroup() {
2595
2604
  this.leftBeamCount = this.rightBeamCount = 0;
@@ -2600,19 +2609,19 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2600
2609
  var _a, _b, _c, _d;
2601
2610
  let staff = obj.staff;
2602
2611
  let x = (_b = (_a = obj.stemTip) == null ? void 0 : _a.centerX) != null ? _b : obj.noteHeadRects[0].centerX;
2603
- let y = (_d = (_c = obj.stemTip) == null ? void 0 : _c.centerY) != null ? _d : this.stemDir === 1 /* Up */ ? obj.getRect().top : obj.getRect().bottom;
2604
- let stemHeight = this.stemDir === 1 /* Up */ ? Math.abs(obj.noteHeadRects[0].centerY - y) : Math.abs(obj.noteHeadRects[obj.noteHeadRects.length - 1].centerY - y);
2612
+ let y = (_d = (_c = obj.stemTip) == null ? void 0 : _c.centerY) != null ? _d : this.stemDir === "up" /* Up */ ? obj.getRect().top : obj.getRect().bottom;
2613
+ let stemHeight = this.stemDir === "up" /* Up */ ? Math.abs(obj.noteHeadRects[0].centerY - y) : Math.abs(obj.noteHeadRects[obj.noteHeadRects.length - 1].centerY - y);
2605
2614
  return { staff, x, y, stemHeight };
2606
2615
  });
2607
2616
  }
2608
2617
  getStemHeight(renderer) {
2609
2618
  let { unitSize } = renderer;
2610
- let { noteLength, flagCount } = this.rhythmProps;
2611
- if (noteLength >= NoteLength3.Whole) {
2612
- return 0;
2613
- } else {
2619
+ let { flagCount, hasStem } = this.rhythmProps;
2620
+ if (hasStem) {
2614
2621
  let addY = this.hasBeamCount() ? DocumentSettings.BeamSeparation : DocumentSettings.FlagSeparation;
2615
2622
  return (DocumentSettings.StemHeight + Math.max(0, flagCount - 1) * addY) * unitSize;
2623
+ } else {
2624
+ return 0;
2616
2625
  }
2617
2626
  }
2618
2627
  hasBeamCount() {
@@ -2631,13 +2640,13 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2631
2640
  return staff.containsVoiceId(this.voiceId) && this.staffObjects.some((obj) => obj instanceof ObjStaffNoteGroup && obj.staff === staff);
2632
2641
  }
2633
2642
  getPlayTicks(note) {
2634
- let tiedTicks = this.runningConnectives.filter((c) => c.connective === 0 /* Tie */).map((tie) => {
2643
+ let tiedTicks = this.runningConnectives.filter((c) => c.connective === "tie" /* Tie */).map((tie) => {
2635
2644
  let tieNoteGroups = tie.noteGroups;
2636
2645
  let j = tieNoteGroups.indexOf(this);
2637
2646
  if (j < 0) {
2638
2647
  return 0;
2639
2648
  }
2640
- if (tie.span === -1 /* Stub */ || tie.span === -2 /* ToMeasureEnd */) {
2649
+ if (tie.span === "stub" /* Stub */ || tie.span === "toMeasureEnd" /* ToMeasureEnd */) {
2641
2650
  return Math.max(this.rhythmProps.ticks, this.measure.getMeasureTicks() - this.col.positionTicks);
2642
2651
  }
2643
2652
  let prev = tieNoteGroups[j - 1];
@@ -2664,7 +2673,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2664
2673
  this.requestRectUpdate();
2665
2674
  let { unitSize } = renderer;
2666
2675
  let { row, stemDir } = this;
2667
- let { dotted, flagCount } = this.rhythmProps;
2676
+ let { dotCount, flagCount, hasStem } = this.rhythmProps;
2668
2677
  let dotWidth = DocumentSettings.DotSize * unitSize;
2669
2678
  let noteHeadWidth = (this.diamond ? DocumentSettings.DiamondNoteHeadSize : DocumentSettings.NoteHeadWidth) * unitSize;
2670
2679
  let noteHeadHeight = (this.diamond ? DocumentSettings.DiamondNoteHeadSize : DocumentSettings.NoteHeadHeight) * unitSize;
@@ -2684,10 +2693,10 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2684
2693
  let noteX = this.col.getNoteHeadDisplacement(this, note) * noteHeadWidth;
2685
2694
  let noteY = noteStaff.getDiatonicIdY(note.diatonicId);
2686
2695
  let isNoteOnLine = noteStaff.isLine(note.diatonicId);
2687
- if (isBottomNote && stemDir === 1 /* Up */) stemBaseStaff = noteStaff;
2688
- if (isTopNote && stemDir === 1 /* Up */) stemTipStaff = noteStaff;
2689
- if (isBottomNote && stemDir === 2 /* Down */) stemTipStaff = noteStaff;
2690
- if (isTopNote && stemDir === 2 /* Down */) stemBaseStaff = noteStaff;
2696
+ if (isBottomNote && stemDir === "up" /* Up */) stemBaseStaff = noteStaff;
2697
+ if (isTopNote && stemDir === "up" /* Up */) stemTipStaff = noteStaff;
2698
+ if (isBottomNote && stemDir === "down" /* Down */) stemTipStaff = noteStaff;
2699
+ if (isTopNote && stemDir === "down" /* Down */) stemBaseStaff = noteStaff;
2691
2700
  let noteHeadRect = obj.noteHeadRects[noteIndex] = DivRect.createCentered(noteX, noteY, noteHeadWidth, noteHeadHeight);
2692
2701
  noteStaff.addObject(noteHeadRect);
2693
2702
  if (accState.needAccidental(note)) {
@@ -2698,21 +2707,21 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2698
2707
  }
2699
2708
  noteStaff.addObject(acc);
2700
2709
  }
2701
- if (dotted) {
2702
- let dotX = noteHeadRect.right + DocumentSettings.NoteDotSpace * unitSize + dotWidth / 2;
2710
+ for (let i = 0; i < dotCount; i++) {
2711
+ let dotX = noteHeadRect.right + DocumentSettings.NoteDotSpace * unitSize + dotWidth / 2 + i * dotWidth * 1.5;
2703
2712
  let dotY = noteY + this.getDotVerticalDisplacement(staff, note.diatonicId, stemDir) * unitSize;
2704
2713
  let r = DivRect.createCentered(dotX, dotY, dotWidth, dotWidth);
2705
2714
  obj.dotRects.push(r);
2706
2715
  noteStaff.addObject(r);
2707
2716
  }
2708
2717
  if (this.staccato) {
2709
- if (stemDir === 1 /* Up */ && isBottomNote) {
2718
+ if (stemDir === "up" /* Up */ && isBottomNote) {
2710
2719
  let dotX = noteX;
2711
2720
  let dotY = noteY + unitSize * (isNoteOnLine ? 3 : 2);
2712
2721
  let r = DivRect.createCentered(dotX, dotY, dotWidth, dotWidth);
2713
2722
  obj.dotRects.push(r);
2714
2723
  stemBaseStaff.addObject(r);
2715
- } else if (stemDir === 2 /* Down */ && isTopNote) {
2724
+ } else if (stemDir === "down" /* Down */ && isTopNote) {
2716
2725
  let dotX = noteX;
2717
2726
  let dotY = noteY - unitSize * (isNoteOnLine ? 3 : 2);
2718
2727
  let r = DivRect.createCentered(dotX, dotY, dotWidth, dotWidth);
@@ -2723,11 +2732,11 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2723
2732
  });
2724
2733
  let bottomNoteY = obj.noteHeadRects[0].centerY;
2725
2734
  let topNoteY = obj.noteHeadRects[obj.noteHeadRects.length - 1].centerY;
2726
- let stemX = stemDir === 1 /* Up */ ? noteHeadWidth / 2 : -noteHeadWidth / 2;
2735
+ let stemX = stemDir === "up" /* Up */ ? noteHeadWidth / 2 : -noteHeadWidth / 2;
2727
2736
  let stemHeight = this.getStemHeight(renderer);
2728
- let stemTipY = stemDir === 1 /* Up */ ? topNoteY - stemHeight : bottomNoteY + stemHeight;
2729
- let stemBaseY = stemDir === 1 /* Up */ ? bottomNoteY : topNoteY;
2730
- if (this.rhythmProps.hasStem()) {
2737
+ let stemTipY = stemDir === "up" /* Up */ ? topNoteY - stemHeight : bottomNoteY + stemHeight;
2738
+ let stemBaseY = stemDir === "up" /* Up */ ? bottomNoteY : topNoteY;
2739
+ if (hasStem) {
2731
2740
  obj.stemTip = new DivRect(stemX, stemX, stemTipY, stemTipY);
2732
2741
  obj.stemBase = new DivRect(stemX, stemX, stemBaseY, stemBaseY);
2733
2742
  stemTipStaff.addObject(obj.stemTip);
@@ -2738,7 +2747,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2738
2747
  let flagHeight = flagCount === 0 ? 0 : DocumentSettings.FlagHeight * unitSize;
2739
2748
  for (let i = 0; i < flagCount; i++) {
2740
2749
  let flagAddY = i * unitSize * DocumentSettings.FlagSeparation;
2741
- let r = obj.flagRects[i] = stemDir === 1 /* Up */ ? new DivRect(stemX, stemX + flagWidth, stemTipY + flagAddY, stemTipY + flagHeight + flagAddY) : new DivRect(stemX, stemX + flagWidth, stemTipY - flagHeight - flagAddY, stemTipY - flagAddY);
2750
+ let r = obj.flagRects[i] = stemDir === "up" /* Up */ ? new DivRect(stemX, stemX + flagWidth, stemTipY + flagAddY, stemTipY + flagHeight + flagAddY) : new DivRect(stemX, stemX + flagWidth, stemTipY - flagHeight - flagAddY, stemTipY - flagAddY);
2742
2751
  stemTipStaff.addObject(r);
2743
2752
  }
2744
2753
  }
@@ -2751,7 +2760,6 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2751
2760
  }
2752
2761
  let obj = new ObjTabNoteGroup(tab, this);
2753
2762
  this.notes.forEach((note, noteIndex) => {
2754
- var _a, _b;
2755
2763
  if (this.ownString[noteIndex] !== void 0) {
2756
2764
  let stringId = this.ownString[noteIndex] - 1;
2757
2765
  let fretId = note.chromaticId - tab.getTuningStrings()[stringId].chromaticId;
@@ -2759,9 +2767,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2759
2767
  let fretNumber = new ObjText(this, { text: String(fretId), color, bgcolor: "white" }, 0.5, 0.5);
2760
2768
  obj.fretNumbers.push(fretNumber);
2761
2769
  fretNumber.layout(renderer);
2762
- let noteX = this.col.getNoteHeadDisplacement(this, note) * noteHeadWidth;
2763
- let stemX = (_b = (_a = this.staffObjects[0]) == null ? void 0 : _a.stemBase) == null ? void 0 : _b.centerX;
2764
- let x = stemX != null ? stemX : noteX;
2770
+ let x = this.col.getRect().centerX;
2765
2771
  let y = tab.getStringY(stringId);
2766
2772
  fretNumber.offset(x, y);
2767
2773
  }
@@ -2804,15 +2810,22 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2804
2810
  renderer.drawDebugRect(this.getRect());
2805
2811
  let { lineWidth } = renderer;
2806
2812
  let { color, stemDir } = this;
2807
- let { noteLength } = this.rhythmProps;
2813
+ let { isSolidNoteHead } = this.rhythmProps;
2808
2814
  this.staffObjects.forEach((obj) => {
2809
2815
  obj.accidentals.forEach((d) => d.draw(renderer));
2810
2816
  ctx.strokeStyle = ctx.fillStyle = color;
2811
2817
  ctx.lineWidth = lineWidth;
2812
2818
  obj.noteHeadRects.forEach((r) => {
2813
- let outlinedNoteHead = noteLength >= NoteLength3.Half;
2814
2819
  if (this.diamond) {
2815
- if (outlinedNoteHead) {
2820
+ if (isSolidNoteHead) {
2821
+ ctx.beginPath();
2822
+ ctx.moveTo(r.centerX, r.top);
2823
+ ctx.lineTo(r.right, r.centerY);
2824
+ ctx.lineTo(r.centerX, r.bottom);
2825
+ ctx.lineTo(r.left, r.centerY);
2826
+ ctx.lineTo(r.centerX, r.top);
2827
+ ctx.fill();
2828
+ } else {
2816
2829
  ctx.beginPath();
2817
2830
  ctx.lineWidth = lineWidth * 2.5;
2818
2831
  ctx.moveTo(r.centerX, r.top);
@@ -2827,22 +2840,14 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2827
2840
  ctx.moveTo(r.centerX, r.top);
2828
2841
  ctx.lineTo(r.left, r.centerY);
2829
2842
  ctx.stroke();
2830
- } else {
2831
- ctx.beginPath();
2832
- ctx.moveTo(r.centerX, r.top);
2833
- ctx.lineTo(r.right, r.centerY);
2834
- ctx.lineTo(r.centerX, r.bottom);
2835
- ctx.lineTo(r.left, r.centerY);
2836
- ctx.lineTo(r.centerX, r.top);
2837
- ctx.fill();
2838
2843
  }
2839
2844
  } else {
2840
2845
  ctx.beginPath();
2841
2846
  ctx.ellipse(r.centerX, r.centerY, r.leftw, r.toph, -0.3, 0, Math.PI * 2);
2842
- if (outlinedNoteHead) {
2843
- ctx.stroke();
2844
- } else {
2847
+ if (isSolidNoteHead) {
2845
2848
  ctx.fill();
2849
+ } else {
2850
+ ctx.stroke();
2846
2851
  }
2847
2852
  }
2848
2853
  });
@@ -2857,8 +2862,8 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2857
2862
  let left = rect.left;
2858
2863
  let right = rect.right;
2859
2864
  let width = right - left;
2860
- let top = stemDir === 1 /* Up */ ? rect.top : rect.bottom;
2861
- let bottom = stemDir === 1 /* Up */ ? rect.bottom : rect.top;
2865
+ let top = stemDir === "up" /* Up */ ? rect.top : rect.bottom;
2866
+ let bottom = stemDir === "up" /* Up */ ? rect.bottom : rect.top;
2862
2867
  ctx.beginPath();
2863
2868
  ctx.moveTo(left, top);
2864
2869
  ctx.bezierCurveTo(
@@ -2872,13 +2877,13 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2872
2877
  ctx.stroke();
2873
2878
  });
2874
2879
  });
2875
- this.tabObjects.forEach((obj) => {
2876
- obj.fretNumbers.forEach((fn) => fn.draw(renderer));
2877
- });
2880
+ this.tabObjects.forEach((obj) => obj.fretNumbers.forEach((fn) => fn.draw(renderer)));
2878
2881
  }
2879
2882
  static setBeamCounts(groupNotes) {
2880
2883
  const isADottedBHalf = (a, b) => {
2881
- return a.rhythmProps.noteLength === b.rhythmProps.noteLength * 2 && a.rhythmProps.dotted && !b.rhythmProps.dotted && a.rhythmProps.flagCount > 0 && b.rhythmProps.flagCount > 0;
2884
+ let { flagCount: aFlagCount, noteSize: aNoteSize, dotCount: aDotCount } = a.rhythmProps;
2885
+ let { flagCount: bFlagCount, noteSize: bNoteSize, dotCount: bDotCount } = b.rhythmProps;
2886
+ return aFlagCount > 0 && bFlagCount > 0 && aDotCount > 0 && bDotCount === 0 && aNoteSize * Math.pow(2, aDotCount) === bNoteSize;
2882
2887
  };
2883
2888
  for (let i = 0; i < groupNotes.length; i++) {
2884
2889
  let center = groupNotes[i];
@@ -2924,29 +2929,27 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2924
2929
  }
2925
2930
  } while (fixAgain);
2926
2931
  }
2927
- static setTripletBeamCounts(triplet) {
2928
- let type = triplet.getType();
2929
- let symbols = triplet.getSymbols();
2930
- if (type === 1 /* TripletBeam */) {
2932
+ static setTupletBeamCounts(tuplet) {
2933
+ let type = tuplet.getType();
2934
+ let symbols = tuplet.getSymbols();
2935
+ if (type === 1 /* TupletBeam */) {
2931
2936
  symbols.forEach((s, i) => {
2932
2937
  if (s instanceof _ObjNoteGroup) {
2933
2938
  s.leftBeamCount = i === 0 ? 0 : s.rhythmProps.flagCount;
2934
2939
  s.rightBeamCount = i === symbols.length - 1 ? 0 : s.rhythmProps.flagCount;
2935
2940
  }
2936
2941
  });
2937
- } else if (type === 2 /* TripletGroup */) {
2942
+ } else if (type === 2 /* TupletGroup */) {
2938
2943
  symbols.forEach((s) => {
2939
2944
  if (s instanceof _ObjNoteGroup) {
2940
2945
  s.leftBeamCount = s.rightBeamCount = 0;
2941
2946
  }
2942
2947
  });
2943
- } else {
2944
- throw new MusicError7(MusicErrorType7.Score, "Cannot set triplet beam count because triplet beam group type is invalid.");
2945
2948
  }
2946
2949
  }
2947
2950
  getDotVerticalDisplacement(staff, diatonicId, stemDir) {
2948
2951
  if (staff.isLine(diatonicId)) {
2949
- return stemDir === 1 /* Up */ ? -1 : 1;
2952
+ return stemDir === "up" /* Up */ ? -1 : 1;
2950
2953
  } else {
2951
2954
  return 0;
2952
2955
  }
@@ -2971,7 +2974,7 @@ import { MusicError as MusicError8, MusicErrorType as MusicErrorType8 } from "@t
2971
2974
  var noteHeadDataCompareFunc = (a, b) => {
2972
2975
  let cmp = Note5.compareFunc(a.note, b.note);
2973
2976
  if (cmp === 0) {
2974
- cmp = a.noteGroup.stemDir === b.noteGroup.stemDir ? 0 : a.noteGroup.stemDir === 1 /* Up */ ? 1 : -1;
2977
+ cmp = a.noteGroup.stemDir === b.noteGroup.stemDir ? 0 : a.noteGroup.stemDir === "up" /* Up */ ? 1 : -1;
2975
2978
  }
2976
2979
  return cmp;
2977
2980
  };
@@ -3077,23 +3080,21 @@ var ObjRhythmColumn = class extends MusicObject {
3077
3080
  return [this, ...arr];
3078
3081
  }
3079
3082
  }
3080
- return [this];
3083
+ return [];
3081
3084
  }
3082
3085
  hasArpeggio() {
3083
3086
  return this.arpeggioDir !== void 0;
3084
3087
  }
3085
3088
  getArpeggioDir() {
3086
3089
  var _a;
3087
- return (_a = this.arpeggioDir) != null ? _a : 0 /* Up */;
3090
+ return (_a = this.arpeggioDir) != null ? _a : "up" /* Up */;
3088
3091
  }
3089
3092
  setVoiceSymbol(voiceId, symbol) {
3090
3093
  validateVoiceId(voiceId);
3091
3094
  this.voiceSymbol[voiceId] = symbol;
3092
- if (symbol instanceof ObjRest) {
3093
- if (!symbol.hide && symbol.noteLength >= NoteLength4.Half) {
3094
- this.minDiatonicId = this.minDiatonicId === void 0 ? symbol.ownDiatonicId : Math.min(this.minDiatonicId, symbol.ownDiatonicId);
3095
- this.maxDiatonicId = this.maxDiatonicId === void 0 ? symbol.ownDiatonicId : Math.max(this.maxDiatonicId, symbol.ownDiatonicId);
3096
- }
3095
+ if (symbol instanceof ObjRest && !symbol.hide) {
3096
+ this.minDiatonicId = this.minDiatonicId === void 0 ? symbol.ownDiatonicId : Math.min(this.minDiatonicId, symbol.ownDiatonicId);
3097
+ this.maxDiatonicId = this.maxDiatonicId === void 0 ? symbol.ownDiatonicId : Math.max(this.maxDiatonicId, symbol.ownDiatonicId);
3097
3098
  } else if (symbol instanceof ObjNoteGroup) {
3098
3099
  this.minDiatonicId = this.minDiatonicId === void 0 ? symbol.notes[0].diatonicId : Math.min(this.minDiatonicId, symbol.notes[0].diatonicId);
3099
3100
  this.maxDiatonicId = this.maxDiatonicId === void 0 ? symbol.notes[symbol.notes.length - 1].diatonicId : Math.max(this.maxDiatonicId, symbol.notes[symbol.notes.length - 1].diatonicId);
@@ -3109,15 +3110,18 @@ var ObjRhythmColumn = class extends MusicObject {
3109
3110
  return this.voiceSymbol[voiceId];
3110
3111
  }
3111
3112
  getMinWidth() {
3112
- let maxNoteLength = Math.max(...this.voiceSymbol.map((s) => s.rhythmProps.noteLength));
3113
+ let maxNoteSize = Math.max(...this.voiceSymbol.map((s) => s.rhythmProps.noteSize));
3113
3114
  let w = DocumentSettings.NoteHeadWidth;
3114
- switch (maxNoteLength) {
3115
- case NoteLength4.Whole:
3115
+ switch (maxNoteSize) {
3116
+ case 1:
3116
3117
  return w * 5;
3117
- case NoteLength4.Half:
3118
+ // whole note
3119
+ case 2:
3118
3120
  return w * 3;
3119
- case NoteLength4.Quarter:
3121
+ // half note
3122
+ case 4:
3120
3123
  return w * 2;
3124
+ // quarter note
3121
3125
  default:
3122
3126
  return w;
3123
3127
  }
@@ -3149,7 +3153,7 @@ var ObjRhythmColumn = class extends MusicObject {
3149
3153
  if (cur.displacement !== void 0) {
3150
3154
  continue;
3151
3155
  }
3152
- let d = cur.noteGroup.stemDir === 2 /* Down */ ? -1 : 1;
3156
+ let d = cur.noteGroup.stemDir === "down" /* Down */ ? -1 : 1;
3153
3157
  if (prev && cur.note.diatonicId - prev.note.diatonicId <= 1) {
3154
3158
  cur.displacement = prev.displacement === 0 ? d : 0;
3155
3159
  } else if (next && next.note.diatonicId - cur.note.diatonicId <= 1) {
@@ -3203,7 +3207,7 @@ var ObjRhythmColumn = class extends MusicObject {
3203
3207
  }
3204
3208
  });
3205
3209
  playerNotes.sort((a, b) => Note5.compareFunc(a.note, b.note));
3206
- if (this.hasArpeggio() && this.getArpeggioDir() === 1 /* Down */) {
3210
+ if (this.hasArpeggio() && this.getArpeggioDir() === "down" /* Down */) {
3207
3211
  playerNotes.reverse();
3208
3212
  }
3209
3213
  return playerNotes;
@@ -3320,6 +3324,9 @@ var ObjRhythmColumn = class extends MusicObject {
3320
3324
  }
3321
3325
  };
3322
3326
 
3327
+ // src/score/engine/element-data.ts
3328
+ import { Utils as Utils5 } from "@tspro/ts-utils-lib";
3329
+
3323
3330
  // src/score/engine/obj-special-text.ts
3324
3331
  var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3325
3332
  constructor(parent, text) {
@@ -3417,36 +3424,71 @@ __publicField(_ObjSpecialText, "Segno", "\u{1D10B}");
3417
3424
  var ObjSpecialText = _ObjSpecialText;
3418
3425
 
3419
3426
  // src/score/engine/element-data.ts
3420
- function getNavigationString(n) {
3421
- switch (n) {
3422
- case 1 /* DC_al_Coda */:
3427
+ function getNavigationString(navigation) {
3428
+ switch (navigation) {
3429
+ case "D.C. al Coda" /* DC_al_Coda */:
3423
3430
  return "D.C. al Coda";
3424
- case 0 /* DC_al_Fine */:
3431
+ case "D.C. al Fine" /* DC_al_Fine */:
3425
3432
  return "D.C. al Fine";
3426
- case 3 /* DS_al_Coda */:
3433
+ case "D.S. al Coda" /* DS_al_Coda */:
3427
3434
  return "D.S. al Coda";
3428
- case 2 /* DS_al_Fine */:
3435
+ case "D.S. al Fine" /* DS_al_Fine */:
3429
3436
  return "D.S. al Fine";
3430
- case 7 /* Fine */:
3437
+ case "Fine" /* Fine */:
3431
3438
  return "Fine";
3432
- case 6 /* Segno */:
3439
+ case "Segno" /* Segno */:
3433
3440
  return ObjSpecialText.Segno;
3434
- case 4 /* Coda */:
3441
+ case "Coda" /* Coda */:
3435
3442
  return ObjSpecialText.Coda;
3436
- case 5 /* toCoda */:
3443
+ case "toCoda" /* toCoda */:
3437
3444
  return ObjSpecialText.toCoda;
3438
3445
  default:
3439
- return Navigation[n];
3446
+ return navigation[0].toUpperCase() + navigation.substring(1);
3440
3447
  }
3441
3448
  }
3449
+ var DynamicsAnnotations = /* @__PURE__ */ ((DynamicsAnnotations2) => {
3450
+ DynamicsAnnotations2["cresc"] = "cresc.";
3451
+ DynamicsAnnotations2["decresc"] = "decresc.";
3452
+ DynamicsAnnotations2["dim"] = "dim.";
3453
+ DynamicsAnnotations2["ppp"] = "ppp";
3454
+ DynamicsAnnotations2["pp"] = "pp";
3455
+ DynamicsAnnotations2["p"] = "p";
3456
+ DynamicsAnnotations2["mp"] = "mp";
3457
+ DynamicsAnnotations2["m"] = "m";
3458
+ DynamicsAnnotations2["mf"] = "mf";
3459
+ DynamicsAnnotations2["f"] = "f";
3460
+ DynamicsAnnotations2["ff"] = "ff";
3461
+ DynamicsAnnotations2["fff"] = "fff";
3462
+ return DynamicsAnnotations2;
3463
+ })(DynamicsAnnotations || {});
3464
+ var TempoAnnotations = /* @__PURE__ */ ((TempoAnnotations2) => {
3465
+ TempoAnnotations2["accel"] = "accel.";
3466
+ TempoAnnotations2["rit"] = "rit.";
3467
+ TempoAnnotations2["a_tempo"] = "a tempo";
3468
+ return TempoAnnotations2;
3469
+ })(TempoAnnotations || {});
3442
3470
  function isDynamicsText(text) {
3443
- return ["ppp", "pp", "p", "mp", "m", "mf", "f", "ff", "fff", "cresc.", "decresc.", "dim."].indexOf(text) >= 0;
3471
+ return Utils5.Is.isEnumValue(text, DynamicsAnnotations);
3444
3472
  }
3445
- function isDynamicsLevelText(text) {
3446
- return ["ppp", "pp", "p", "mp", "m", "mf", "f", "ff", "fff"].indexOf(text) >= 0;
3473
+ function getDynamicsVolume(text) {
3474
+ if (/^(p+|f+|m|mp|mf)$/.test(text)) {
3475
+ let volume = 0.5 - Utils5.Str.charCount(text, "p") * 0.1 + Utils5.Str.charCount(text, "f") * 0.1;
3476
+ return Utils5.Math.clamp(volume, 0, 1);
3477
+ } else {
3478
+ return void 0;
3479
+ }
3447
3480
  }
3448
3481
  function isTempoText(text) {
3449
- return ["accel.", "rit.", "a tempo"].indexOf(text) >= 0;
3482
+ return Utils5.Is.isEnumValue(text, TempoAnnotations);
3483
+ }
3484
+ function getAnnotation(text) {
3485
+ if (Utils5.Is.isEnumValue(text, DynamicsAnnotations)) {
3486
+ return "dynamics" /* Dynamics */;
3487
+ } else if (Utils5.Is.isEnumValue(text, TempoAnnotations)) {
3488
+ return "tempo" /* Tempo */;
3489
+ } else {
3490
+ return void 0;
3491
+ }
3450
3492
  }
3451
3493
 
3452
3494
  // src/score/engine/extension.ts
@@ -3505,7 +3547,7 @@ var Extension = class extends MusicObjectLink {
3505
3547
  if (prevMeasure.hasEndSection() || prevMeasure.hasEndSong()) {
3506
3548
  return "section-break";
3507
3549
  }
3508
- let elemArr = [9 /* EndRepeat */, 10 /* Ending */];
3550
+ let elemArr = ["endRepeat" /* EndRepeat */, "ending" /* Ending */];
3509
3551
  for (let i = 0; i < elemArr.length; i++) {
3510
3552
  if (prevMeasure.hasNavigation(elemArr[i])) {
3511
3553
  return "section-break";
@@ -3566,35 +3608,12 @@ var RitardandoSpeedDiv = 2;
3566
3608
  var CrescendoVolumeAdd = 0.5;
3567
3609
  var DiminuendoVolumeSub = 0.5;
3568
3610
  function calcTicksDuration(ticks, tempo) {
3569
- let beatTicks = new RhythmProps3(tempo.options.beatLength, tempo.options.dotted).ticks;
3611
+ let beatTicks = RhythmProps3.get(tempo.options.beatLength, tempo.options.dotCount).ticks;
3570
3612
  let ticksPerMinute = tempo.beatsPerMinute * beatTicks;
3571
3613
  return 60 * ticks / ticksPerMinute;
3572
3614
  }
3573
- function getVolume(dynamicsLevelText) {
3574
- switch (dynamicsLevelText) {
3575
- case "fff":
3576
- return 0.9;
3577
- case "ff":
3578
- return 0.8;
3579
- case "f":
3580
- return 0.7;
3581
- case "mf":
3582
- return 0.6;
3583
- default:
3584
- case "m":
3585
- return 0.5;
3586
- case "mp":
3587
- return 0.4;
3588
- case "p":
3589
- return 0.3;
3590
- case "pp":
3591
- return 0.2;
3592
- case "ppp":
3593
- return 0.1;
3594
- }
3595
- }
3596
3615
  function getDefaultVolume() {
3597
- return getVolume("m");
3616
+ return getDynamicsVolume("m");
3598
3617
  }
3599
3618
  function adjustVolume(linearVolume) {
3600
3619
  return linearVolume * 1.25;
@@ -3622,7 +3641,7 @@ var PlayerColumnProps = class {
3622
3641
  return this.speed;
3623
3642
  }
3624
3643
  getTempo() {
3625
- let speed = Utils5.Math.clamp(this.getSpeed(), 0.1, 10);
3644
+ let speed = Utils6.Math.clamp(this.getSpeed(), 0.1, 10);
3626
3645
  return alterTempoSpeed(this.measure.getTempo(), speed);
3627
3646
  }
3628
3647
  setVolume(volume) {
@@ -3647,7 +3666,7 @@ var PlayerColumnProps = class {
3647
3666
  if (symbolsTicks.length === 0) {
3648
3667
  return 0;
3649
3668
  } else {
3650
- return Utils5.Math.sum(symbolsTicks) / symbolsTicks.length;
3669
+ return Utils6.Math.sum(symbolsTicks) / symbolsTicks.length;
3651
3670
  }
3652
3671
  }
3653
3672
  }
@@ -3710,34 +3729,34 @@ var Player = class _Player {
3710
3729
  continue;
3711
3730
  }
3712
3731
  measureSequence.push(curMeasure);
3713
- if (curMeasure.hasNavigation(8 /* StartRepeat */)) {
3732
+ if (curMeasure.hasNavigation("startRepeat" /* StartRepeat */)) {
3714
3733
  startRepeatMeasure = curMeasure;
3715
3734
  }
3716
- if (curMeasure.hasNavigation(6 /* Segno */)) {
3735
+ if (curMeasure.hasNavigation("Segno" /* Segno */)) {
3717
3736
  segnoMeasure = curMeasure;
3718
3737
  }
3719
- if (alCoda && curMeasure.hasNavigation(5 /* toCoda */)) {
3720
- while (curMeasure && !curMeasure.hasNavigation(4 /* Coda */)) {
3738
+ if (alCoda && curMeasure.hasNavigation("toCoda" /* toCoda */)) {
3739
+ while (curMeasure && !curMeasure.hasNavigation("Coda" /* Coda */)) {
3721
3740
  curMeasure = curMeasure.getNextMeasure();
3722
3741
  }
3723
- } else if (alFine && curMeasure.hasNavigation(7 /* Fine */)) {
3742
+ } else if (alFine && curMeasure.hasNavigation("Fine" /* Fine */)) {
3724
3743
  curMeasure = void 0;
3725
- } else if (curMeasure.hasNavigation(1 /* DC_al_Coda */)) {
3744
+ } else if (curMeasure.hasNavigation("D.C. al Coda" /* DC_al_Coda */)) {
3726
3745
  alCoda = true;
3727
3746
  curMeasure = this.doc.getFirstMeasure();
3728
- } else if (curMeasure.hasNavigation(0 /* DC_al_Fine */)) {
3747
+ } else if (curMeasure.hasNavigation("D.C. al Fine" /* DC_al_Fine */)) {
3729
3748
  alFine = true;
3730
3749
  curMeasure = this.doc.getFirstMeasure();
3731
- } else if (curMeasure.hasNavigation(3 /* DS_al_Coda */)) {
3750
+ } else if (curMeasure.hasNavigation("D.S. al Coda" /* DS_al_Coda */)) {
3732
3751
  alCoda = true;
3733
3752
  curMeasure = segnoMeasure;
3734
- } else if (curMeasure.hasNavigation(2 /* DS_al_Fine */)) {
3753
+ } else if (curMeasure.hasNavigation("D.S. al Fine" /* DS_al_Fine */)) {
3735
3754
  alFine = true;
3736
3755
  curMeasure = segnoMeasure;
3737
- } else if (curMeasure.hasNavigation(9 /* EndRepeat */)) {
3756
+ } else if (curMeasure.hasNavigation("endRepeat" /* EndRepeat */)) {
3738
3757
  let passage = curMeasure.getPassCount();
3739
3758
  let repeatCount = curMeasure.getEndRepeatPlayCount() - 1;
3740
- let cannotPassThrough = ((_a = curMeasure.getNextMeasure()) == null ? void 0 : _a.hasNavigation(10 /* Ending */)) === true;
3759
+ let cannotPassThrough = ((_a = curMeasure.getNextMeasure()) == null ? void 0 : _a.hasNavigation("ending" /* Ending */)) === true;
3741
3760
  if (passage <= repeatCount || cannotPassThrough) {
3742
3761
  curMeasure = startRepeatMeasure;
3743
3762
  } else {
@@ -3788,14 +3807,15 @@ var Player = class _Player {
3788
3807
  col.getAnchoredLayoutObjects().forEach((layoutObj) => {
3789
3808
  var _a2;
3790
3809
  let text = (_a2 = layoutObj.getTextContent()) != null ? _a2 : "";
3791
- if (text === "a tempo") {
3810
+ let vol;
3811
+ if (text === "a tempo" /* a_tempo */) {
3792
3812
  curSpeed = 1;
3793
- } else if (isDynamicsLevelText(text)) {
3794
- curVolume = getVolume(text);
3813
+ } else if ((vol = getDynamicsVolume(text)) !== void 0) {
3814
+ curVolume = vol;
3795
3815
  } else if (layoutObj.musicObj.getLink() instanceof Extension) {
3796
3816
  let extension = layoutObj.musicObj.getLink();
3797
3817
  let { columnRange, extensionBreakText } = extension.getExtensionRangeInfo();
3798
- let totalTicks = Utils5.Math.sum(columnRange.map((c) => c.getTicksToNextColumn()));
3818
+ let totalTicks = Utils6.Math.sum(columnRange.map((c) => c.getTicksToNextColumn()));
3799
3819
  switch (text) {
3800
3820
  case "accel." /* accel */: {
3801
3821
  let startSpeed = curSpeed;
@@ -3820,8 +3840,8 @@ var Player = class _Player {
3820
3840
  case "cresc." /* cresc */: {
3821
3841
  let startVol = curVolume;
3822
3842
  let endVol = startVol + CrescendoVolumeAdd;
3823
- if (extensionBreakText && isDynamicsLevelText(extensionBreakText) && getVolume(extensionBreakText) > startVol) {
3824
- endVol = getVolume(extensionBreakText);
3843
+ if (extensionBreakText && (vol = getDynamicsVolume(extensionBreakText)) !== void 0 && vol > startVol) {
3844
+ endVol = vol;
3825
3845
  }
3826
3846
  let accuTicks = 0;
3827
3847
  columnRange.forEach((c) => {
@@ -3834,8 +3854,8 @@ var Player = class _Player {
3834
3854
  case "dim." /* dim */: {
3835
3855
  let startVol = curVolume;
3836
3856
  let endVol = startVol - DiminuendoVolumeSub;
3837
- if (extensionBreakText && isDynamicsLevelText(extensionBreakText) && getVolume(extensionBreakText) < startVol) {
3838
- endVol = getVolume(extensionBreakText);
3857
+ if (extensionBreakText && (vol = getDynamicsVolume(extensionBreakText)) !== void 0 && vol < startVol) {
3858
+ endVol = vol;
3839
3859
  }
3840
3860
  let accuTicks = 0;
3841
3861
  columnRange.forEach((c) => {
@@ -3849,11 +3869,11 @@ var Player = class _Player {
3849
3869
  });
3850
3870
  let speedArr = (_a = speedMap.get(col)) != null ? _a : [];
3851
3871
  if (speedArr.length > 0) {
3852
- curSpeed = Utils5.Math.sum(speedArr) / speedArr.length;
3872
+ curSpeed = Utils6.Math.sum(speedArr) / speedArr.length;
3853
3873
  }
3854
3874
  let volumeArr = (_b = volumeMap.get(col)) != null ? _b : [];
3855
3875
  if (volumeArr.length > 0) {
3856
- curVolume = Utils5.Math.sum(volumeArr) / volumeArr.length;
3876
+ curVolume = Utils6.Math.sum(volumeArr) / volumeArr.length;
3857
3877
  }
3858
3878
  col.getPlayerProps().setSpeed(curSpeed);
3859
3879
  col.getPlayerProps().setVolume(curVolume);
@@ -3866,7 +3886,7 @@ var Player = class _Player {
3866
3886
  return m;
3867
3887
  }
3868
3888
  let next = m == null ? void 0 : m.getNextMeasure();
3869
- if (!m || m.hasEndSong() || m.hasEndSection() || !next || next.hasNavigation(8 /* StartRepeat */)) {
3889
+ if (!m || m.hasEndSong() || m.hasEndSection() || !next || next.hasNavigation("startRepeat" /* StartRepeat */)) {
3870
3890
  return void 0;
3871
3891
  }
3872
3892
  }
@@ -3891,11 +3911,11 @@ var Player = class _Player {
3891
3911
  } else {
3892
3912
  let playerNotes = col.getPlayerNotes();
3893
3913
  playerNotes.forEach((note, i) => {
3894
- let arpeggioDelayTicks = col.hasArpeggio() ? NoteLength5.ThirtySecond * i : 0;
3914
+ let arpeggioDelayTicks = col.hasArpeggio() ? RhythmProps3.get(NoteLength5.ThirtySecond).ticks * i : 0;
3895
3915
  let noteSeconds = getDuration(note.ticks + fermataHoldTicks - arpeggioDelayTicks, tempo);
3896
3916
  if (noteSeconds > 0) {
3897
3917
  if (note.staccato) {
3898
- noteSeconds = Math.min(getDuration(NoteLength5.Eighth, tempo) / 2, noteSeconds / 2);
3918
+ noteSeconds = Math.min(getDuration(RhythmProps3.get(NoteLength5.Eighth).ticks, tempo) / 2, noteSeconds / 2);
3899
3919
  }
3900
3920
  let volume = adjustVolume(col.getPlayerProps().getVolume());
3901
3921
  if (note.slur === "slurred") {
@@ -3973,8 +3993,9 @@ var Player = class _Player {
3973
3993
 
3974
3994
  // src/score/engine/obj-bar-line.ts
3975
3995
  var ObjStaffTabBarLine = class extends MusicObject {
3976
- constructor(line) {
3996
+ constructor(barLine, line) {
3977
3997
  super(line);
3998
+ this.barLine = barLine;
3978
3999
  this.line = line;
3979
4000
  __publicField(this, "lineRects", []);
3980
4001
  __publicField(this, "dotRects", []);
@@ -4029,7 +4050,7 @@ var ObjBarLine = class extends MusicObject {
4029
4050
  let dotW = DocumentSettings.DotSize * unitSize;
4030
4051
  let dotRadius = dotW / 2;
4031
4052
  row.getNotationLines().forEach((line) => {
4032
- let obj = new ObjStaffTabBarLine(line);
4053
+ let obj = new ObjStaffTabBarLine(this, line);
4033
4054
  let lineCenterY;
4034
4055
  let lineDotOff;
4035
4056
  let top, bottom;
@@ -4132,8 +4153,8 @@ var ObjBarLineLeft = class extends ObjBarLine {
4132
4153
  solveBarLineType() {
4133
4154
  let m = this.measure;
4134
4155
  let prev = m.getPrevMeasure();
4135
- if (m.hasNavigation(8 /* StartRepeat */)) {
4136
- if (prev && prev.row === m.row && prev.hasNavigation(9 /* EndRepeat */)) {
4156
+ if (m.hasNavigation("startRepeat" /* StartRepeat */)) {
4157
+ if (prev && prev.row === m.row && prev.hasNavigation("endRepeat" /* EndRepeat */)) {
4137
4158
  return 0 /* None */;
4138
4159
  } else {
4139
4160
  return 4 /* StartRepeat */;
@@ -4160,8 +4181,8 @@ var ObjBarLineRight = class extends ObjBarLine {
4160
4181
  solveBarLineType() {
4161
4182
  let m = this.measure;
4162
4183
  let next = m.getNextMeasure();
4163
- if (m.hasNavigation(9 /* EndRepeat */)) {
4164
- if (next && next.row === m.row && next.hasNavigation(8 /* StartRepeat */)) {
4184
+ if (m.hasNavigation("endRepeat" /* EndRepeat */)) {
4185
+ if (next && next.row === m.row && next.hasNavigation("startRepeat" /* StartRepeat */)) {
4165
4186
  return 6 /* EndStartRepeat */;
4166
4187
  } else {
4167
4188
  return 5 /* EndRepeat */;
@@ -4171,10 +4192,10 @@ var ObjBarLineRight = class extends ObjBarLine {
4171
4192
  } else if (m.hasEndSection()) {
4172
4193
  return 2 /* Double */;
4173
4194
  }
4174
- if (m === m.row.getLastMeasure() && next && next.row === m.row.getNextRow() && next.hasNavigation(8 /* StartRepeat */)) {
4195
+ if (m === m.row.getLastMeasure() && next && next.row === m.row.getNextRow() && next.hasNavigation("startRepeat" /* StartRepeat */)) {
4175
4196
  return 2 /* Double */;
4176
4197
  }
4177
- if (next && next.hasNavigation(8 /* StartRepeat */)) {
4198
+ if (next && next.hasNavigation("startRepeat" /* StartRepeat */)) {
4178
4199
  return 0 /* None */;
4179
4200
  }
4180
4201
  return 1 /* Single */;
@@ -4182,7 +4203,7 @@ var ObjBarLineRight = class extends ObjBarLine {
4182
4203
  };
4183
4204
 
4184
4205
  // src/score/engine/obj-ending.ts
4185
- import { Utils as Utils6 } from "@tspro/ts-utils-lib";
4206
+ import { Utils as Utils7 } from "@tspro/ts-utils-lib";
4186
4207
  import { MusicError as MusicError10, MusicErrorType as MusicErrorType10 } from "@tspro/web-music-score/core";
4187
4208
  var ObjEnding = class extends MusicObject {
4188
4209
  constructor(measure, passages) {
@@ -4193,9 +4214,9 @@ var ObjEnding = class extends MusicObject {
4193
4214
  __publicField(this, "shapeRects", []);
4194
4215
  __publicField(this, "mi");
4195
4216
  this.mi = new MEnding(this);
4196
- if (!Utils6.Is.isIntegerGte(passages.length, 1)) {
4217
+ if (!Utils7.Is.isIntegerGte(passages.length, 1)) {
4197
4218
  throw new MusicError10(MusicErrorType10.Score, "Passages is empty.");
4198
- } else if (!this.passages.every((p) => Utils6.Is.isIntegerGte(p, 1))) {
4219
+ } else if (!this.passages.every((p) => Utils7.Is.isIntegerGte(p, 1))) {
4199
4220
  throw new MusicError10(MusicErrorType10.Score, "Invalid passages: " + this.passages);
4200
4221
  }
4201
4222
  this.passages.sort((a, b) => a - b);
@@ -4211,7 +4232,7 @@ var ObjEnding = class extends MusicObject {
4211
4232
  isSingleMeasureEnding() {
4212
4233
  let { measure } = this;
4213
4234
  let next = measure.getNextMeasure();
4214
- return (next == null ? void 0 : next.hasNavigation(10 /* Ending */)) === true || measure.hasNavigation(9 /* EndRepeat */) || measure.isLastMeasure();
4235
+ return (next == null ? void 0 : next.hasNavigation("ending" /* Ending */)) === true || measure.hasNavigation("endRepeat" /* EndRepeat */) || measure.isLastMeasure();
4215
4236
  }
4216
4237
  hasPassage(pass) {
4217
4238
  return this.passages.some((p) => p === pass);
@@ -4331,9 +4352,10 @@ var ObjFermata = class extends MusicObject {
4331
4352
 
4332
4353
  // src/score/engine/obj-extension-line.ts
4333
4354
  var ObjExtensionLine = class extends MusicObject {
4334
- constructor(measure, extension, leftObj, rightObj) {
4355
+ constructor(measure, line, extension, leftObj, rightObj) {
4335
4356
  super(measure);
4336
4357
  this.measure = measure;
4358
+ this.line = line;
4337
4359
  this.extension = extension;
4338
4360
  this.leftObj = leftObj;
4339
4361
  this.rightObj = rightObj;
@@ -4396,7 +4418,7 @@ var ObjExtensionLine = class extends MusicObject {
4396
4418
  ctx.setLineDash([]);
4397
4419
  let tails = this.extension.getTails();
4398
4420
  if (tails.length > 0 && this === tails[tails.length - 1]) {
4399
- let tipH = rect.centerY > this.measure.row.getRect().centerY ? -renderer.unitSize : renderer.unitSize;
4421
+ let tipH = rect.centerY > this.line.getRect().centerY ? -renderer.unitSize : renderer.unitSize;
4400
4422
  renderer.drawLine(rect.right, rect.centerY, rect.right, rect.centerY + tipH, "black", renderer.lineWidth);
4401
4423
  }
4402
4424
  }
@@ -4409,7 +4431,7 @@ import { MusicError as MusicError13, MusicErrorType as MusicErrorType13 } from "
4409
4431
  import { Note as Note6 } from "@tspro/web-music-score/theory";
4410
4432
 
4411
4433
  // src/score/engine/obj-connective.ts
4412
- import { Utils as Utils7 } from "@tspro/ts-utils-lib";
4434
+ import { Utils as Utils8 } from "@tspro/ts-utils-lib";
4413
4435
  import { MusicError as MusicError11, MusicErrorType as MusicErrorType11 } from "@tspro/web-music-score/core";
4414
4436
  var ObjConnective = class extends MusicObject {
4415
4437
  constructor(connectiveProps, line, measure, leftNoteGroup, leftNoteId, ...args) {
@@ -4438,7 +4460,7 @@ var ObjConnective = class extends MusicObject {
4438
4460
  this.rightNoteGroup = args[0];
4439
4461
  this.rightNoteId = args[1];
4440
4462
  this.tieType = void 0;
4441
- } else if (Utils7.Is.isEnumValue(args[0], TieType)) {
4463
+ } else if (Utils8.Is.isEnumValue(args[0], TieType)) {
4442
4464
  this.rightNoteGroup = void 0;
4443
4465
  this.rightNoteId = void 0;
4444
4466
  this.tieType = args[0];
@@ -4469,7 +4491,7 @@ var ObjConnective = class extends MusicObject {
4469
4491
  if (rightNoteGroup !== void 0 && rightNoteId !== void 0) {
4470
4492
  rightPos = rightNoteGroup.getConnectiveAnchorPoint(connectiveProps, line, rightNoteId, noteAnchor, "right");
4471
4493
  } else {
4472
- rightPos = this.tieType === -2 /* ToMeasureEnd */ ? { x: measure.getColumnsContentRect().right, y: leftPos.y } : { x: leftPos.x + unitSize * DocumentSettings.StubTieLength, y: leftPos.y };
4494
+ rightPos = this.tieType === "toMeasureEnd" /* ToMeasureEnd */ ? { x: measure.getColumnsContentRect().right, y: leftPos.y } : { x: leftPos.x + unitSize * DocumentSettings.StubTieLength, y: leftPos.y };
4473
4495
  }
4474
4496
  let lx, ly, rx, ry;
4475
4497
  if (rightNoteGroup === void 0) {
@@ -4507,8 +4529,8 @@ var ObjConnective = class extends MusicObject {
4507
4529
  this.ly = ly;
4508
4530
  this.rx = rx;
4509
4531
  this.ry = ry;
4510
- this.arcHeight = this.connectiveProps.connective === 2 /* Slide */ ? 0 : arcHeight;
4511
- let { nx, ny } = Utils7.Math.calcNormal(lx, ly, rx, ry);
4532
+ this.arcHeight = this.connectiveProps.connective === "slide" /* Slide */ ? 0 : arcHeight;
4533
+ let { nx, ny } = Utils8.Math.calcNormal(lx, ly, rx, ry);
4512
4534
  this.cp1x = lx * 0.7 + rx * 0.3 + nx * this.arcHeight;
4513
4535
  this.cp1y = ly * 0.7 + ry * 0.3 + ny * this.arcHeight;
4514
4536
  this.cp2x = lx * 0.3 + rx * 0.7 + nx * this.arcHeight;
@@ -4569,6 +4591,7 @@ var ObjConnective = class extends MusicObject {
4569
4591
 
4570
4592
  // src/score/engine/connective-props.ts
4571
4593
  import { MusicError as MusicError12, MusicErrorType as MusicErrorType12 } from "@tspro/web-music-score/core";
4594
+ import { Utils as Utils9 } from "@tspro/ts-utils-lib";
4572
4595
  var ConnectiveProps = class {
4573
4596
  constructor(connective, span, noteAnchor, startNoteGroup) {
4574
4597
  this.connective = connective;
@@ -4590,7 +4613,7 @@ var ConnectiveProps = class {
4590
4613
  * @returns true if noteGroup was added, false if not.
4591
4614
  */
4592
4615
  addNoteGroup(noteGroup) {
4593
- if (this.span === -1 /* Stub */ || this.span === -2 /* ToMeasureEnd */) {
4616
+ if (this.span === "stub" /* Stub */ || this.span === "toMeasureEnd" /* ToMeasureEnd */) {
4594
4617
  return false;
4595
4618
  } else if (this.span > this.noteGroups.length) {
4596
4619
  this.noteGroups.push(noteGroup);
@@ -4600,29 +4623,29 @@ var ConnectiveProps = class {
4600
4623
  }
4601
4624
  }
4602
4625
  computeParams() {
4603
- let stemDir = this.noteGroups[0].stemDir;
4604
- let hasStem = this.noteGroups[0].rhythmProps.hasStem;
4605
- if (this.noteAnchor === 4 /* StemTip */) {
4606
- this.arcDir = stemDir === 1 /* Up */ ? "up" : "down";
4607
- } else if (this.noteAnchor === 0 /* Auto */) {
4608
- this.arcDir = stemDir === 1 /* Up */ || !hasStem ? "down" : "up";
4626
+ let { stemDir } = this.noteGroups[0];
4627
+ let { hasStem } = this.noteGroups[0].rhythmProps;
4628
+ if (this.noteAnchor === "stemTip" /* StemTip */) {
4629
+ this.arcDir = stemDir === "up" /* Up */ ? "up" : "down";
4630
+ } else if (this.noteAnchor === "auto" /* Auto */) {
4631
+ this.arcDir = stemDir === "up" /* Up */ || !hasStem ? "down" : "up";
4609
4632
  if (this.noteGroups[0].notes.length > 1) {
4610
- this.noteAnchor = 2 /* Center */;
4611
- } else if (this.connective === 2 /* Slide */) {
4612
- this.noteAnchor = 2 /* Center */;
4633
+ this.noteAnchor = "center" /* Center */;
4634
+ } else if (this.connective === "slide" /* Slide */) {
4635
+ this.noteAnchor = "center" /* Center */;
4613
4636
  } else if (this.arcDir === "up") {
4614
- this.noteAnchor = 1 /* Above */;
4637
+ this.noteAnchor = "above" /* Above */;
4615
4638
  } else {
4616
- this.noteAnchor = 3 /* Below */;
4639
+ this.noteAnchor = "below" /* Below */;
4617
4640
  }
4618
- } else if (this.noteAnchor === 2 /* Center */) {
4641
+ } else if (this.noteAnchor === "center" /* Center */) {
4619
4642
  let { row } = this.noteGroups[0].measure;
4620
4643
  let diatonicId = this.noteGroups[0].ownDiatonicId;
4621
4644
  let staff = row.getStaff(diatonicId);
4622
4645
  this.arcDir = !staff || diatonicId < staff.middleLineDiatonicId ? "down" : "up";
4623
- } else if (this.noteAnchor === 1 /* Above */) {
4646
+ } else if (this.noteAnchor === "above" /* Above */) {
4624
4647
  this.arcDir = "up";
4625
- } else if (this.noteAnchor === 3 /* Below */) {
4648
+ } else if (this.noteAnchor === "below" /* Below */) {
4626
4649
  this.arcDir = "down";
4627
4650
  }
4628
4651
  }
@@ -4637,8 +4660,8 @@ var ConnectiveProps = class {
4637
4660
  this.getStartNoteGroup().collectConnectiveProps();
4638
4661
  this.computeParams();
4639
4662
  let { connective, span } = this;
4640
- if (connective === 0 /* Tie */) {
4641
- if (span === -1 /* Stub */ || span === -2 /* ToMeasureEnd */) {
4663
+ if (connective === "tie" /* Tie */) {
4664
+ if (Utils9.Is.isEnumValue(span, TieType)) {
4642
4665
  let leftNoteGroup = this.noteGroups[0];
4643
4666
  for (let noteId = 0; noteId < leftNoteGroup.notes.length; noteId++) {
4644
4667
  this.createObjConnectiveWithTieType(leftNoteGroup, noteId, span);
@@ -4655,13 +4678,13 @@ var ConnectiveProps = class {
4655
4678
  });
4656
4679
  }
4657
4680
  }
4658
- } else if (connective === 1 /* Slur */) {
4681
+ } else if (connective === "slur" /* Slur */) {
4659
4682
  if (typeof span === "number" && span >= 2 && this.noteGroups.length === span) {
4660
4683
  let leftNoteGroup = this.noteGroups[0];
4661
4684
  let rightNoteGroup = this.noteGroups[this.noteGroups.length - 1];
4662
4685
  this.createObjConnective(leftNoteGroup, 0, rightNoteGroup, 0);
4663
4686
  }
4664
- } else if (connective === 2 /* Slide */) {
4687
+ } else if (connective === "slide" /* Slide */) {
4665
4688
  if (this.noteGroups.length >= 2) {
4666
4689
  for (let i = 0; i < this.noteGroups.length - 1; i++) {
4667
4690
  let leftNoteGroup = this.noteGroups[i];
@@ -4691,7 +4714,7 @@ var ConnectiveProps = class {
4691
4714
  } else {
4692
4715
  let leftString = leftNoteGroup2.getFretNumberString(leftNoteId2);
4693
4716
  let rightString = rightNoteGroup2.getFretNumberString(rightNoteId2);
4694
- if (leftString !== void 0 && rightString !== void 0 && (leftString === rightString || this.connective === 1 /* Slur */)) {
4717
+ if (leftString !== void 0 && rightString !== void 0 && (leftString === rightString || this.connective === "slur" /* Slur */)) {
4695
4718
  new ObjConnective(this, line, measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2);
4696
4719
  }
4697
4720
  }
@@ -4716,6 +4739,32 @@ function validateVoiceId(voiceId) {
4716
4739
  return voiceId;
4717
4740
  }
4718
4741
  }
4742
+ function getExtensionTicks(extensionLength) {
4743
+ if (typeof extensionLength === "string") {
4744
+ extensionLength = [extensionLength];
4745
+ }
4746
+ if (Utils10.Is.isArray(extensionLength)) {
4747
+ let totalTicks = 0;
4748
+ for (let i = 0; i < extensionLength.length; ) {
4749
+ let str = extensionLength[i];
4750
+ let num = extensionLength[i + 1];
4751
+ if (typeof str === "string") {
4752
+ i++;
4753
+ let ticks = RhythmProps4.get(str).ticks;
4754
+ if (typeof num === "number") {
4755
+ i++;
4756
+ ticks *= num;
4757
+ }
4758
+ totalTicks += ticks;
4759
+ } else {
4760
+ i++;
4761
+ }
4762
+ }
4763
+ return totalTicks;
4764
+ } else {
4765
+ return extensionLength;
4766
+ }
4767
+ }
4719
4768
  var _ObjMeasure = class _ObjMeasure extends MusicObject {
4720
4769
  constructor(row) {
4721
4770
  super(row);
@@ -4819,15 +4868,15 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
4819
4868
  if (setStemDir !== void 0) {
4820
4869
  this.useStemDir[voiceId] = setStemDir;
4821
4870
  } else if (this.useStemDir[voiceId] === void 0) {
4822
- this.useStemDir[voiceId] = (_b = (_a = this.getPrevMeasure()) == null ? void 0 : _a.useStemDir[voiceId]) != null ? _b : 0 /* Auto */;
4871
+ this.useStemDir[voiceId] = (_b = (_a = this.getPrevMeasure()) == null ? void 0 : _a.useStemDir[voiceId]) != null ? _b : "auto" /* Auto */;
4823
4872
  }
4824
4873
  let stemDir = this.useStemDir[voiceId];
4825
- if (stemDir === 0 /* Auto */ || stemDir === void 0) {
4874
+ if (stemDir === "auto" /* Auto */ || stemDir === void 0) {
4826
4875
  let staff = this.row.getStaff(symbol.ownDiatonicId);
4827
4876
  if (staff) {
4828
- return symbol.ownDiatonicId > staff.middleLineDiatonicId ? 2 /* Down */ : 1 /* Up */;
4877
+ return symbol.ownDiatonicId > staff.middleLineDiatonicId ? "down" /* Down */ : "up" /* Up */;
4829
4878
  } else {
4830
- return 1 /* Up */;
4879
+ return "up" /* Up */;
4831
4880
  }
4832
4881
  } else {
4833
4882
  return stemDir;
@@ -4934,6 +4983,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
4934
4983
  // See MMeasure interface
4935
4984
  //setKeySignature(tonic: string, scaleType: ScaleType): void;
4936
4985
  //setKeySignature(keySignature: KeySignature): void;
4986
+ //setKeySignature(keySignature: string): void;
4937
4987
  //setKeySignature(scale: Scale): void;
4938
4988
  setKeySignature(...args) {
4939
4989
  var _a;
@@ -4942,13 +4992,17 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
4942
4992
  this.alterKeySignature = args[0];
4943
4993
  } else if (args[0] instanceof Scale) {
4944
4994
  this.alterKeySignature = args[0];
4945
- } else {
4946
- try {
4947
- let tonic = "" + args[0];
4948
- let scaleType = validateScaleType("" + args[1]);
4949
- this.alterKeySignature = getScale(tonic, scaleType);
4950
- } catch (e) {
4951
- throw new MusicError13(MusicErrorType13.Score, "Cannot set key signature because invalid args: " + args);
4995
+ } else if (Utils10.Is.isNonEmptyString(args[0])) {
4996
+ if (args.length === 1) {
4997
+ this.alterKeySignature = getScale(args[0]);
4998
+ } else if (args.length === 2) {
4999
+ try {
5000
+ let tonic = "" + args[0];
5001
+ let scaleType = validateScaleType("" + args[1]);
5002
+ this.alterKeySignature = getScale(tonic, scaleType);
5003
+ } catch (e) {
5004
+ throw new MusicError13(MusicErrorType13.Score, "Cannot set key signature because invalid args: " + args);
5005
+ }
4952
5006
  }
4953
5007
  }
4954
5008
  this.updateKeySignature();
@@ -4988,8 +5042,16 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
4988
5042
  setTempo(beatsPerMinute, beatLength, dotted) {
4989
5043
  var _a;
4990
5044
  (_a = this.getPrevMeasure()) == null ? void 0 : _a.endSection();
4991
- let options = beatLength !== void 0 ? { beatLength, dotted } : void 0;
4992
- this.alterTempo = { beatsPerMinute, options };
5045
+ if (beatLength === void 0) {
5046
+ this.alterTempo = { beatsPerMinute };
5047
+ } else {
5048
+ let dotCount = typeof dotted === "number" && dotted > 0 ? dotted : dotted === true ? 1 : NoteLengthProps4.get(beatLength).dotCount;
5049
+ let options = {
5050
+ beatLength: validateNoteLength(beatLength),
5051
+ dotCount: dotCount > 0 ? dotCount : void 0
5052
+ };
5053
+ this.alterTempo = { beatsPerMinute, options };
5054
+ }
4993
5055
  this.updateTempo();
4994
5056
  }
4995
5057
  updateTempo() {
@@ -4998,18 +5060,18 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
4998
5060
  if (this.alterTempo) {
4999
5061
  let beatsPerMinute = this.alterTempo.beatsPerMinute;
5000
5062
  let beatLength;
5001
- let dotted;
5063
+ let dotCount;
5002
5064
  if (this.alterTempo.options) {
5003
5065
  beatLength = this.alterTempo.options.beatLength;
5004
- dotted = (_a = this.alterTempo.options.dotted) != null ? _a : false;
5066
+ dotCount = (_a = this.alterTempo.options.dotCount) != null ? _a : 0;
5005
5067
  } else if (this.alterTimeSignature) {
5006
5068
  beatLength = this.alterTimeSignature.beatLength;
5007
- dotted = false;
5069
+ dotCount = 0;
5008
5070
  } else {
5009
5071
  beatLength = this.tempo.options.beatLength;
5010
- dotted = this.tempo.options.dotted;
5072
+ dotCount = this.tempo.options.dotCount;
5011
5073
  }
5012
- this.tempo = { beatsPerMinute, options: { beatLength, dotted } };
5074
+ this.tempo = { beatsPerMinute, options: { beatLength, dotCount } };
5013
5075
  }
5014
5076
  if (this.nextMeasure) {
5015
5077
  this.nextMeasure.updateTempo();
@@ -5041,19 +5103,19 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5041
5103
  let grp = this.doc.getStaffGroup(staffTabOrGroup);
5042
5104
  if (grp && !prevGroups.includes(staffTabOrGroup)) {
5043
5105
  let curGroups = [...prevGroups, staffTabOrGroup];
5044
- (Utils8.Is.isArray(grp.staffsTabsAndGroups) ? grp.staffsTabsAndGroups : [grp.staffsTabsAndGroups]).forEach((staffTabOrGroup2) => {
5106
+ (Utils10.Is.isArray(grp.staffsTabsAndGroups) ? grp.staffsTabsAndGroups : [grp.staffsTabsAndGroups]).forEach((staffTabOrGroup2) => {
5045
5107
  switch (grp.verticalPosition) {
5046
- case 0 /* Above */:
5108
+ case "above" /* Above */:
5047
5109
  addToStaffTabOrGroup(staffTabOrGroup2, 0 /* Above */, curGroups);
5048
5110
  break;
5049
- case 1 /* Below */:
5111
+ case "below" /* Below */:
5050
5112
  addToStaffTabOrGroup(staffTabOrGroup2, 1 /* Below */, curGroups);
5051
5113
  break;
5052
- case 2 /* Both */:
5114
+ case "both" /* Both */:
5053
5115
  addToStaffTabOrGroup(staffTabOrGroup2, 0 /* Above */, curGroups);
5054
5116
  addToStaffTabOrGroup(staffTabOrGroup2, 1 /* Below */, curGroups);
5055
5117
  break;
5056
- case 3 /* Auto */:
5118
+ case "auto" /* Auto */:
5057
5119
  addToStaffTabOrGroup(staffTabOrGroup2, defaultVerticalPos, curGroups);
5058
5120
  break;
5059
5121
  }
@@ -5068,14 +5130,14 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5068
5130
  } else {
5069
5131
  addToStaffTabOrGroup(0, defaultVerticalPos);
5070
5132
  }
5071
- } else if (Utils8.Is.isArray(staffTabOrGroups)) {
5133
+ } else if (Utils10.Is.isArray(staffTabOrGroups)) {
5072
5134
  staffTabOrGroups.forEach((staffTabOrGroup) => addToStaffTabOrGroup(staffTabOrGroup, defaultVerticalPos));
5073
5135
  } else {
5074
5136
  addToStaffTabOrGroup(staffTabOrGroups, defaultVerticalPos);
5075
5137
  }
5076
5138
  }
5077
5139
  addFermata(staffTabOrGroups, fermata) {
5078
- let anchor = fermata === 1 /* AtMeasureEnd */ ? this.barLineRight : this.lastAddedRhythmColumn;
5140
+ let anchor = fermata === "atMeasureEnd" /* AtMeasureEnd */ ? this.barLineRight : this.lastAddedRhythmColumn;
5079
5141
  if (!anchor) {
5080
5142
  throw new MusicError13(MusicErrorType13.Score, "Cannot add Fermata because anchor is undefined.");
5081
5143
  }
@@ -5091,7 +5153,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5091
5153
  addNavigation(staffTabOrGroups, navigation, ...args) {
5092
5154
  let addLayoutObjectProps = void 0;
5093
5155
  switch (navigation) {
5094
- case 10 /* Ending */:
5156
+ case "ending" /* Ending */:
5095
5157
  if (this.navigationSet.has(navigation)) {
5096
5158
  throw new MusicError13(MusicErrorType13.Score, "Cannot add ending beasure measure already has one.");
5097
5159
  }
@@ -5103,10 +5165,10 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5103
5165
  defaultVerticalPos: 0 /* Above */
5104
5166
  };
5105
5167
  break;
5106
- case 1 /* DC_al_Coda */:
5107
- case 0 /* DC_al_Fine */:
5108
- case 3 /* DS_al_Coda */:
5109
- case 2 /* DS_al_Fine */: {
5168
+ case "D.C. al Coda" /* DC_al_Coda */:
5169
+ case "D.C. al Fine" /* DC_al_Fine */:
5170
+ case "D.S. al Coda" /* DS_al_Coda */:
5171
+ case "D.S. al Fine" /* DS_al_Fine */: {
5110
5172
  let anchor2 = this.barLineRight;
5111
5173
  let text = getNavigationString(navigation);
5112
5174
  addLayoutObjectProps = {
@@ -5114,11 +5176,11 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5114
5176
  layoutGroupId: 2 /* Navigation */,
5115
5177
  defaultVerticalPos: 0 /* Above */
5116
5178
  };
5117
- this.addNavigation(staffTabOrGroups, 9 /* EndRepeat */);
5179
+ this.addNavigation(staffTabOrGroups, "endRepeat" /* EndRepeat */);
5118
5180
  this.endSong();
5119
5181
  break;
5120
5182
  }
5121
- case 7 /* Fine */: {
5183
+ case "Fine" /* Fine */: {
5122
5184
  let anchor2 = this.barLineRight;
5123
5185
  let text = getNavigationString(navigation);
5124
5186
  addLayoutObjectProps = {
@@ -5128,8 +5190,8 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5128
5190
  };
5129
5191
  break;
5130
5192
  }
5131
- case 6 /* Segno */:
5132
- case 4 /* Coda */: {
5193
+ case "Segno" /* Segno */:
5194
+ case "Coda" /* Coda */: {
5133
5195
  let anchor2 = this.barLineLeft;
5134
5196
  let text = getNavigationString(navigation);
5135
5197
  addLayoutObjectProps = {
@@ -5139,7 +5201,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5139
5201
  };
5140
5202
  break;
5141
5203
  }
5142
- case 5 /* toCoda */: {
5204
+ case "toCoda" /* toCoda */: {
5143
5205
  let anchor2 = this.barLineRight;
5144
5206
  let text = getNavigationString(navigation);
5145
5207
  addLayoutObjectProps = {
@@ -5149,10 +5211,10 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5149
5211
  };
5150
5212
  break;
5151
5213
  }
5152
- case 9 /* EndRepeat */:
5214
+ case "endRepeat" /* EndRepeat */:
5153
5215
  if (args.length === 0) {
5154
5216
  this.endRepeatPlayCount = 2;
5155
- } else if (Utils8.Is.isIntegerGte(args[0], 2)) {
5217
+ } else if (Utils10.Is.isIntegerGte(args[0], 2)) {
5156
5218
  this.endRepeatPlayCount = args[0];
5157
5219
  } else {
5158
5220
  throw new MusicError13(MusicErrorType13.Score, "Invalid end repeat play count (should be 2 or greater integer): " + args[0]);
@@ -5188,17 +5250,18 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5188
5250
  let layoutGroupId;
5189
5251
  let defaultVerticalPos;
5190
5252
  switch (annotation) {
5191
- case 0 /* Dynamics */:
5253
+ case "dynamics" /* Dynamics */:
5192
5254
  layoutGroupId = 5 /* DynamicsAnnotation */;
5193
5255
  defaultVerticalPos = 0 /* Above */;
5194
5256
  textProps.italic = true;
5195
5257
  break;
5196
- case 1 /* Tempo */:
5258
+ case "tempo" /* Tempo */:
5197
5259
  layoutGroupId = 4 /* TempoAnnotation */;
5198
5260
  defaultVerticalPos = 0 /* Above */;
5199
5261
  textProps.italic = true;
5200
5262
  break;
5201
5263
  }
5264
+ this.disableExtension();
5202
5265
  this.forEachStaffGroup(staffTabOrGroups, defaultVerticalPos, (line, vpos) => {
5203
5266
  let textObj = new ObjText(anchor, textProps, 0.5, 1);
5204
5267
  this.addLayoutObject(textObj, line, layoutGroupId, vpos);
@@ -5216,15 +5279,16 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5216
5279
  let layoutGroupId;
5217
5280
  let defaultVerticalPos;
5218
5281
  switch (label) {
5219
- case 0 /* Note */:
5282
+ case "note" /* Note */:
5220
5283
  layoutGroupId = 1 /* NoteLabel */;
5221
5284
  defaultVerticalPos = 1 /* Below */;
5222
5285
  break;
5223
- case 1 /* Chord */:
5286
+ case "chord" /* Chord */:
5224
5287
  layoutGroupId = 6 /* ChordLabel */;
5225
5288
  defaultVerticalPos = 0 /* Above */;
5226
5289
  break;
5227
5290
  }
5291
+ this.disableExtension();
5228
5292
  this.forEachStaffGroup(staffTabOrGroups, defaultVerticalPos, (line, vpos) => {
5229
5293
  let textObj = new ObjText(anchor, textProps, 0.5, 1);
5230
5294
  this.addLayoutObject(textObj, line, layoutGroupId, vpos);
@@ -5236,17 +5300,17 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5236
5300
  if (!(anchor instanceof ObjNoteGroup)) {
5237
5301
  throw new MusicError13(MusicErrorType13.Score, "Connective can be added to note group only.");
5238
5302
  }
5239
- if (connective === 0 /* Tie */) {
5240
- let tieSpan = Utils8.Is.isInteger(args[0]) || Utils8.Is.isEnumValue(args[0], TieType) ? args[0] : 2;
5241
- let noteAnchor = Utils8.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : 0 /* Auto */;
5242
- anchor.startConnective(new ConnectiveProps(0 /* Tie */, tieSpan, noteAnchor, anchor));
5243
- } else if (connective === 1 /* Slur */) {
5244
- let slurSpan = Utils8.Is.isInteger(args[0]) ? args[0] : 2;
5245
- let noteAnchor = Utils8.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : 0 /* Auto */;
5246
- anchor.startConnective(new ConnectiveProps(1 /* Slur */, slurSpan, noteAnchor, anchor));
5247
- } else if (connective === 2 /* Slide */) {
5248
- let noteAnchor = Utils8.Is.isEnumValue(args[0], NoteAnchor) ? args[0] : 0 /* Auto */;
5249
- anchor.startConnective(new ConnectiveProps(2 /* Slide */, 2, noteAnchor, anchor));
5303
+ if (connective === "tie" /* Tie */) {
5304
+ let tieSpan = Utils10.Is.isInteger(args[0]) || Utils10.Is.isEnumValue(args[0], TieType) ? args[0] : 2;
5305
+ let noteAnchor = Utils10.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : "auto" /* Auto */;
5306
+ anchor.startConnective(new ConnectiveProps("tie" /* Tie */, tieSpan, noteAnchor, anchor));
5307
+ } else if (connective === "slur" /* Slur */) {
5308
+ let slurSpan = Utils10.Is.isInteger(args[0]) ? args[0] : 2;
5309
+ let noteAnchor = Utils10.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : "auto" /* Auto */;
5310
+ anchor.startConnective(new ConnectiveProps("slur" /* Slur */, slurSpan, noteAnchor, anchor));
5311
+ } else if (connective === "slide" /* Slide */) {
5312
+ let noteAnchor = Utils10.Is.isEnumValue(args[0], NoteAnchor) ? args[0] : "auto" /* Auto */;
5313
+ anchor.startConnective(new ConnectiveProps("slide" /* Slide */, 2, noteAnchor, anchor));
5250
5314
  }
5251
5315
  }
5252
5316
  addExtension(extensionLength, extensionVisible) {
@@ -5255,7 +5319,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5255
5319
  if (musicObj instanceof ObjText && anchor instanceof ObjRhythmColumn) {
5256
5320
  let lineStyle = "dashed";
5257
5321
  let linePos = "bottom";
5258
- let extension = new Extension(musicObj, anchor, extensionLength, extensionVisible, lineStyle, linePos);
5322
+ let extension = new Extension(musicObj, anchor, getExtensionTicks(extensionLength), extensionVisible, lineStyle, linePos);
5259
5323
  musicObj.setLink(extension);
5260
5324
  } else {
5261
5325
  throw new MusicError13(MusicErrorType13.Score, "Cannot add extension becaue no compatible music object to attach it to.");
@@ -5304,18 +5368,25 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5304
5368
  col.setVoiceSymbol(voiceId, symbol);
5305
5369
  this.getVoiceSymbols(voiceId);
5306
5370
  this.voiceSymbols[voiceId].push(symbol);
5371
+ if (symbol.oldStyleTriplet) {
5372
+ this.createOldStyleTriplets(voiceId);
5373
+ }
5307
5374
  this.requestBeamsUpdate();
5308
5375
  this.lastAddedRhythmColumn = col;
5309
5376
  this.lastAddedRhythmSymbol = symbol;
5310
5377
  }
5311
- addNoteGroup(voiceId, notes, noteLength, options) {
5312
- let notes2 = notes.map((note) => typeof note === "string" ? Note7.getNote(note) : note);
5378
+ addNoteGroup(voiceId, notes, noteLength, options, tupletRatio) {
5379
+ let realNotes = notes.map((note) => typeof note === "string" ? Note7.getNote(note) : note);
5313
5380
  let col = this.getRhythmColumn(voiceId);
5314
- this.addRhythmSymbol(voiceId, new ObjNoteGroup(col, voiceId, notes2, noteLength, options));
5381
+ let noteGroup = new ObjNoteGroup(col, voiceId, realNotes, noteLength, options, tupletRatio);
5382
+ this.addRhythmSymbol(voiceId, noteGroup);
5383
+ return noteGroup;
5315
5384
  }
5316
- addRest(voiceId, restLength, options) {
5385
+ addRest(voiceId, restLength, options, tupletRatio) {
5317
5386
  let col = this.getRhythmColumn(voiceId);
5318
- this.addRhythmSymbol(voiceId, new ObjRest(col, voiceId, restLength, options));
5387
+ let rest = new ObjRest(col, voiceId, restLength, options, tupletRatio);
5388
+ this.addRhythmSymbol(voiceId, rest);
5389
+ return rest;
5319
5390
  }
5320
5391
  /**
5321
5392
  *
@@ -5443,7 +5514,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5443
5514
  const lines = m.row.getNotationLines();
5444
5515
  let line2 = (_a = lines.find((l) => l.name !== "" && l.name === line.name)) != null ? _a : lines[line.id];
5445
5516
  if (line2) {
5446
- m.addLayoutObject(new ObjExtensionLine(m, extension, leftObj, rightObj), line2, layoutGroupId, verticalPos);
5517
+ m.addLayoutObject(new ObjExtensionLine(m, line2, extension, leftObj, rightObj), line2, layoutGroupId, verticalPos);
5447
5518
  }
5448
5519
  }
5449
5520
  }
@@ -5457,28 +5528,36 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5457
5528
  requestBeamsUpdate() {
5458
5529
  this.needBeamsUpdate = true;
5459
5530
  }
5531
+ // Create triplets by triplet property of NoteOptions/RestOptions.
5532
+ createOldStyleTriplets(voiceId) {
5533
+ let symbols = this.getVoiceSymbols(voiceId);
5534
+ for (let i = 0; i < symbols.length; ) {
5535
+ if (symbols[i].oldStyleTriplet) {
5536
+ let n = ObjBeamGroup.createOldStyleTriplet(symbols.slice(i, i + 3));
5537
+ i += n === 0 ? 1 : n;
5538
+ } else {
5539
+ i++;
5540
+ }
5541
+ }
5542
+ this.requestLayout();
5543
+ }
5460
5544
  createBeams() {
5461
- if (!this.needBeamsUpdate || !this.row.hasStaff) {
5545
+ if (!this.needBeamsUpdate) {
5462
5546
  return;
5463
5547
  }
5464
- this.beamGroups.forEach((beamGroup) => beamGroup.detach());
5465
- this.beamGroups.length = 0;
5548
+ this.beamGroups = this.beamGroups.filter((beamGroup) => {
5549
+ if (beamGroup.isTuplet()) {
5550
+ return true;
5551
+ } else {
5552
+ beamGroup.detach();
5553
+ return false;
5554
+ }
5555
+ });
5466
5556
  getVoiceIds().forEach((voiceId) => {
5467
5557
  let symbols = this.getVoiceSymbols(voiceId);
5468
5558
  if (symbols.length <= 2) {
5469
5559
  return;
5470
5560
  }
5471
- for (let i = 0; i < symbols.length; ) {
5472
- let s2 = symbols.slice(i, i + 2);
5473
- let s3 = symbols.slice(i, i + 3);
5474
- if (s2.length === 2 && ObjBeamGroup.createTriplet(s2)) {
5475
- i += 2;
5476
- } else if (s3.length === 3 && ObjBeamGroup.createTriplet(s3)) {
5477
- i += 3;
5478
- } else {
5479
- i++;
5480
- }
5481
- }
5482
5561
  if (!DebugSettings.DisableBeams) {
5483
5562
  let groupSymbols = [];
5484
5563
  let groupStartTicks = 0;
@@ -5507,7 +5586,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5507
5586
  static setupBeamGroup(groupSymbols) {
5508
5587
  let groupNotes = groupSymbols.map((s) => {
5509
5588
  var _a;
5510
- return s instanceof ObjNoteGroup && ((_a = s.getBeamGroup()) == null ? void 0 : _a.isTriplet()) !== true ? s : void 0;
5589
+ return s instanceof ObjNoteGroup && ((_a = s.getBeamGroup()) == null ? void 0 : _a.isTuplet()) !== true ? s : void 0;
5511
5590
  });
5512
5591
  ObjNoteGroup.setBeamCounts(groupNotes);
5513
5592
  let beamNotes = [];
@@ -5539,36 +5618,32 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5539
5618
  if (this.getConsumedTicks() === 0) {
5540
5619
  this.completeRests(0);
5541
5620
  } else {
5542
- getVoiceIds().forEach((voiceId2) => {
5543
- if (this.getConsumedTicks(voiceId2) > 0) {
5544
- this.completeRests(voiceId2);
5545
- }
5546
- });
5621
+ this.completeRests(getVoiceIds().filter((id) => this.getConsumedTicks(id) > 0));
5547
5622
  }
5548
5623
  return;
5549
- }
5550
- let measureTicks = this.getMeasureTicks();
5551
- let consumedTicks = this.getConsumedTicks(voiceId);
5552
- let remainingTicks = measureTicks - consumedTicks;
5553
- let rests = [];
5554
- let noteLengthValues = Utils8.Enum.getEnumValues(NoteLength6);
5555
- while (remainingTicks > 0) {
5556
- noteLengthValues.forEach((restLength) => {
5557
- let restValue = new RhythmProps4(restLength, false);
5558
- if (restValue.canDot()) {
5559
- let dottedRestValue = new RhythmProps4(restLength, true);
5560
- while (dottedRestValue.ticks <= remainingTicks) {
5561
- rests.push(dottedRestValue);
5562
- remainingTicks -= dottedRestValue.ticks;
5624
+ } else if (Utils10.Is.isArray(voiceId)) {
5625
+ voiceId.forEach((id) => this.completeRests(id));
5626
+ return;
5627
+ } else {
5628
+ validateVoiceId(voiceId);
5629
+ let measureTicks = this.getMeasureTicks();
5630
+ let consumedTicks = this.getConsumedTicks(voiceId);
5631
+ let remainingTicks = measureTicks - consumedTicks;
5632
+ let rests = [];
5633
+ while (remainingTicks > 0) {
5634
+ for (let noteSize = NoteLengthProps4.LongestNoteSize; noteSize <= NoteLengthProps4.ShortestNoteSize; noteSize *= 2) {
5635
+ let restLength = NoteLengthProps4.create(noteSize).noteLength;
5636
+ for (let dotCount = NoteLengthProps4.get(restLength).maxDotCount; dotCount >= 0; dotCount--) {
5637
+ let restProps = RhythmProps4.get(restLength, dotCount);
5638
+ while (restProps.ticks <= remainingTicks) {
5639
+ rests.push(restProps);
5640
+ remainingTicks -= restProps.ticks;
5641
+ }
5563
5642
  }
5564
5643
  }
5565
- while (restValue.ticks <= remainingTicks) {
5566
- rests.push(restValue);
5567
- remainingTicks -= restValue.ticks;
5568
- }
5569
- });
5644
+ }
5645
+ rests.reverse().forEach((rest) => this.addRest(voiceId, rest.noteLength, { dotted: rest.dotCount }));
5570
5646
  }
5571
- rests.reverse().forEach((rest) => this.addRest(voiceId, rest.noteLength, { dotted: rest.dotted }));
5572
5647
  }
5573
5648
  requestLayout() {
5574
5649
  if (!this.needLayout) {
@@ -5661,7 +5736,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5661
5736
  let columnsAreaLeft = this.rect.left + this.leftSolidAreaWidth;
5662
5737
  let columnsAreaRight = this.rect.right - this.rightSolidAreaWidth;
5663
5738
  let columnsAreaWidth = columnsAreaRight - columnsAreaLeft;
5664
- let columnsWidth = Utils8.Math.sum(this.columns.map((col) => col.getRect().width));
5739
+ let columnsWidth = Utils10.Math.sum(this.columns.map((col) => col.getRect().width));
5665
5740
  let columnScale = columnsAreaWidth / columnsWidth;
5666
5741
  let columnLeft = columnsAreaLeft;
5667
5742
  this.columns.forEach((col) => {
@@ -6001,10 +6076,12 @@ var ObjStaff = class extends ObjNotationLine4 {
6001
6076
  this.clefImageAsset = 0 /* TrebleClefPng */;
6002
6077
  this.clefLineDiatonicId = getDiatonicId("G4", staffConfig.isOctaveDown === true);
6003
6078
  this.middleLineDiatonicId = this.clefLineDiatonicId + 2;
6004
- } else {
6079
+ } else if (staffConfig.clef === "F" /* F */) {
6005
6080
  this.clefImageAsset = 1 /* BassClefPng */;
6006
6081
  this.clefLineDiatonicId = getDiatonicId("F3", staffConfig.isOctaveDown === true);
6007
6082
  this.middleLineDiatonicId = this.clefLineDiatonicId - 2;
6083
+ } else {
6084
+ throw new MusicError15(MusicErrorType15.Score, `Invalid staffConfig.clef ${staffConfig.clef}.`);
6008
6085
  }
6009
6086
  this.topLineDiatonicId = this.middleLineDiatonicId + 4;
6010
6087
  this.bottomLineDiatonicId = this.middleLineDiatonicId - 4;
@@ -6140,7 +6217,7 @@ var ObjTab = class extends ObjNotationLine4 {
6140
6217
  __publicField(this, "tuningName");
6141
6218
  __publicField(this, "tuningStrings");
6142
6219
  __publicField(this, "mi");
6143
- if (Utils9.Is.isArray(tabConfig.tuning)) {
6220
+ if (Utils11.Is.isArray(tabConfig.tuning)) {
6144
6221
  this.tuningName = void 0;
6145
6222
  this.tuningStrings = tabConfig.tuning.map((noteName) => Note8.getNote(noteName)).reverse();
6146
6223
  } else if (typeof tabConfig.tuning === "string") {
@@ -6431,8 +6508,8 @@ var ObjScoreRow = class extends MusicObject {
6431
6508
  updateRect() {
6432
6509
  let left = this.measures.length > 0 ? this.measures[0].getRect().left : 0;
6433
6510
  let right = this.measures.length > 0 ? this.measures[this.measures.length - 1].getRect().right : 0;
6434
- let top = Math.min(0, ...this.measures.map((m) => m.getRect().top));
6435
- let bottom = Math.max(0, ...this.measures.map((m) => m.getRect().bottom));
6511
+ let top = this.measures.length > 0 ? Math.min(...this.measures.map((m) => m.getRect().top)) : 0;
6512
+ let bottom = this.measures.length > 0 ? Math.max(...this.measures.map((m) => m.getRect().bottom)) : 0;
6436
6513
  this.rect = new DivRect(left, right, top, bottom);
6437
6514
  }
6438
6515
  alignStemsToBeams() {
@@ -6595,7 +6672,7 @@ var ObjHeader = class extends MusicObject {
6595
6672
  };
6596
6673
 
6597
6674
  // src/score/engine/obj-document.ts
6598
- import { Utils as Utils10 } from "@tspro/ts-utils-lib";
6675
+ import { Utils as Utils12 } from "@tspro/ts-utils-lib";
6599
6676
  var ObjDocument = class extends MusicObject {
6600
6677
  constructor() {
6601
6678
  super(void 0);
@@ -6616,35 +6693,35 @@ var ObjDocument = class extends MusicObject {
6616
6693
  return this.mi;
6617
6694
  }
6618
6695
  setScoreConfiguration(config) {
6619
- if (Utils10.Is.isEnumValue(config, StaffPreset)) {
6696
+ if (Utils12.Is.isEnumValue(config, StaffPreset)) {
6620
6697
  switch (config) {
6621
6698
  default:
6622
- case 1 /* Treble */:
6699
+ case "treble" /* Treble */:
6623
6700
  this.curScoreConfig = [{ type: "staff", clef: "G" /* G */ }];
6624
6701
  break;
6625
- case 2 /* Bass */:
6702
+ case "bass" /* Bass */:
6626
6703
  this.curScoreConfig = [{ type: "staff", clef: "F" /* F */ }];
6627
6704
  break;
6628
- case 3 /* Grand */:
6705
+ case "grand" /* Grand */:
6629
6706
  this.curScoreConfig = [
6630
6707
  { type: "staff", clef: "G" /* G */, isGrand: true },
6631
6708
  { type: "staff", clef: "F" /* F */, isGrand: true }
6632
6709
  ];
6633
6710
  break;
6634
- case 4 /* GuitarTreble */:
6711
+ case "guitarTreble" /* GuitarTreble */:
6635
6712
  this.curScoreConfig = [{ type: "staff", clef: "G" /* G */, isOctaveDown: true }];
6636
6713
  break;
6637
- case 8 /* GuitarTab */:
6714
+ case "guitarTab" /* GuitarTab */:
6638
6715
  this.curScoreConfig = [{ type: "tab", tuning: "Standard" }];
6639
6716
  break;
6640
- case 12 /* GuitarCombined */:
6717
+ case "guitarCombined" /* GuitarCombined */:
6641
6718
  this.curScoreConfig = [
6642
6719
  { type: "staff", clef: "G" /* G */, isOctaveDown: true },
6643
6720
  { type: "tab", tuning: "Standard" }
6644
6721
  ];
6645
6722
  break;
6646
6723
  }
6647
- } else if (Utils10.Is.isArray(config)) {
6724
+ } else if (Utils12.Is.isArray(config)) {
6648
6725
  this.curScoreConfig = config;
6649
6726
  } else {
6650
6727
  this.curScoreConfig = [config];
@@ -6724,6 +6801,12 @@ var ObjDocument = class extends MusicObject {
6724
6801
  getLastRow() {
6725
6802
  return this.rows.length === 0 ? this.addNewRow(void 0) : this.rows[this.rows.length - 1];
6726
6803
  }
6804
+ getRows() {
6805
+ return this.rows;
6806
+ }
6807
+ getMeasures() {
6808
+ return this.measures;
6809
+ }
6727
6810
  requestNewRow() {
6728
6811
  this.newRowRequested = true;
6729
6812
  }
@@ -6864,7 +6947,7 @@ var ObjDocument = class extends MusicObject {
6864
6947
  };
6865
6948
 
6866
6949
  // src/score/pub/document-builder.ts
6867
- import { KeySignature as KeySignature3, Note as Note10, NoteLength as NoteLength7, Scale as Scale2, ScaleType, SymbolSet as SymbolSet2, TimeSignature as TimeSignature2, TuningNameList } from "@tspro/web-music-score/theory";
6950
+ import { KeySignature as KeySignature3, Note as Note10, NoteLength as NoteLength7, RhythmProps as RhythmProps5, Scale as Scale2, ScaleType, SymbolSet as SymbolSet2, TimeSignature as TimeSignature2, TuningNameList, validateNoteLength as validateNoteLength2, validateTupletRatio } from "@tspro/web-music-score/theory";
6868
6951
  import { MusicError as MusicError17, MusicErrorType as MusicErrorType17 } from "@tspro/web-music-score/core";
6869
6952
  function assertArg(condition, argName, argValue) {
6870
6953
  if (!condition) {
@@ -6880,85 +6963,105 @@ function isNote(note) {
6880
6963
  }
6881
6964
  }
6882
6965
  function isVoiceId(value) {
6883
- return Utils11.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
6966
+ return Utils13.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
6884
6967
  }
6885
6968
  function isStringNumber(value) {
6886
- return Utils11.Is.isNumber(value) && getStringNumbers().indexOf(value) >= 0;
6969
+ return Utils13.Is.isNumber(value) && getStringNumbers().indexOf(value) >= 0;
6887
6970
  }
6888
6971
  function assertStaffConfig(staffConfig) {
6889
- assertArg(Utils11.Is.isObject(staffConfig), "staffConfig", staffConfig);
6972
+ assertArg(Utils13.Is.isObject(staffConfig), "staffConfig", staffConfig);
6890
6973
  assertArg(staffConfig.type === "staff", "staffConfig.type", staffConfig.type);
6891
- assertArg(Utils11.Is.isEnumValue(staffConfig.clef, Clef), "staffConfig.clef", staffConfig.clef);
6892
- assertArg(Utils11.Is.isBooleanOrUndefined(staffConfig.isOctaveDown), "staffConfig.isOctaveDown", staffConfig.isOctaveDown);
6893
- assertArg(Utils11.Is.isUndefined(staffConfig.minNote) || isNote(staffConfig.minNote), "staffConfig.minNote", staffConfig.minNote);
6894
- assertArg(Utils11.Is.isUndefined(staffConfig.maxNote) || isNote(staffConfig.maxNote), "staffConfig.maxNote", staffConfig.maxNote);
6895
- assertArg(Utils11.Is.isUndefined(staffConfig.voiceIds) || Utils11.Is.isArray(staffConfig.voiceIds) && staffConfig.voiceIds.every((voiceId) => Utils11.Is.isNumber(voiceId)), "staffConfig.voiceIds", staffConfig.voiceIds);
6896
- assertArg(Utils11.Is.isBooleanOrUndefined(staffConfig.isGrand), "staffConfig.isGrand", staffConfig.isGrand);
6974
+ assertArg(Utils13.Is.isEnumValue(staffConfig.clef, Clef), "staffConfig.clef", staffConfig.clef);
6975
+ assertArg(Utils13.Is.isBooleanOrUndefined(staffConfig.isOctaveDown), "staffConfig.isOctaveDown", staffConfig.isOctaveDown);
6976
+ assertArg(Utils13.Is.isUndefined(staffConfig.minNote) || isNote(staffConfig.minNote), "staffConfig.minNote", staffConfig.minNote);
6977
+ assertArg(Utils13.Is.isUndefined(staffConfig.maxNote) || isNote(staffConfig.maxNote), "staffConfig.maxNote", staffConfig.maxNote);
6978
+ assertArg(Utils13.Is.isUndefined(staffConfig.voiceIds) || Utils13.Is.isArray(staffConfig.voiceIds) && staffConfig.voiceIds.every((voiceId) => Utils13.Is.isNumber(voiceId)), "staffConfig.voiceIds", staffConfig.voiceIds);
6979
+ assertArg(Utils13.Is.isBooleanOrUndefined(staffConfig.isGrand), "staffConfig.isGrand", staffConfig.isGrand);
6897
6980
  }
6898
6981
  function assertTabConfig(tabConfig) {
6899
- assertArg(Utils11.Is.isObject(tabConfig), "tabConfig", tabConfig);
6982
+ assertArg(Utils13.Is.isObject(tabConfig), "tabConfig", tabConfig);
6900
6983
  assertArg(tabConfig.type === "tab", "tabConfig.type", tabConfig.type);
6901
6984
  if (typeof tabConfig.tuning === "string") {
6902
6985
  assertArg(TuningNameList.includes(tabConfig.tuning), "tabConfig.tuning", tabConfig.tuning);
6903
- } else if (Utils11.Is.isArray(tabConfig.tuning)) {
6904
- assertArg(tabConfig.tuning.length === 6 && tabConfig.tuning.every((s) => isNote(s)), "tabConfig.tuning", tabConfig.tuning);
6986
+ } else if (Utils13.Is.isArray(tabConfig.tuning)) {
6987
+ assertArg(tabConfig.tuning.length === getStringNumbers().length && tabConfig.tuning.every((s) => isNote(s)), "tabConfig.tuning", tabConfig.tuning);
6905
6988
  }
6906
- assertArg(Utils11.Is.isUndefined(tabConfig.voiceIds) || Utils11.Is.isArray(tabConfig.voiceIds) && tabConfig.voiceIds.every((voiceId) => Utils11.Is.isNumber(voiceId)), "tabConfig.voiceIds", tabConfig.voiceIds);
6989
+ assertArg(Utils13.Is.isUndefined(tabConfig.voiceIds) || Utils13.Is.isArray(tabConfig.voiceIds) && tabConfig.voiceIds.every((voiceId) => Utils13.Is.isNumber(voiceId)), "tabConfig.voiceIds", tabConfig.voiceIds);
6907
6990
  }
6908
6991
  function assertNoteOptions(options) {
6909
- assertArg(Utils11.Is.isObject(options), "noteOptions", options);
6910
- assertArg(Utils11.Is.isBooleanOrUndefined(options.dotted), "noteOptions.dotted", options.dotted);
6911
- assertArg(Utils11.Is.isEnumValueOrUndefined(options.stem, Stem), "noteOptions.stem", options.stem);
6912
- assertArg(Utils11.Is.isStringOrUndefined(options.color), "noteOptions.color", options.color);
6913
- assertArg(Utils11.Is.isBooleanOrUndefined(options.arpeggio) || Utils11.Is.isEnumValue(options.arpeggio, Arpeggio), "noteOptions.arpeggio", options.arpeggio);
6914
- assertArg(Utils11.Is.isBooleanOrUndefined(options.staccato), "noteOptions.staccato", options.staccato);
6915
- assertArg(Utils11.Is.isBooleanOrUndefined(options.diamond), "noteOptions.diamond", options.diamond);
6916
- assertArg(Utils11.Is.isBooleanOrUndefined(options.triplet), "noteOptions.triplet", options.triplet);
6917
- assertArg(Utils11.Is.isUndefined(options.string) || isStringNumber(options.string) || Utils11.Is.isArray(options.string) && options.string.length > 0 && options.string.every((string) => isStringNumber(string)), "noteOptions.string", options.string);
6992
+ assertArg(Utils13.Is.isObject(options), "noteOptions", options);
6993
+ assertArg(Utils13.Is.isBooleanOrUndefined(options.dotted) || Utils13.Is.isIntegerGte(options.dotted, 0), "noteOptions.dotted", options.dotted);
6994
+ assertArg(Utils13.Is.isEnumValueOrUndefined(options.stem, Stem), "noteOptions.stem", options.stem);
6995
+ assertArg(Utils13.Is.isStringOrUndefined(options.color), "noteOptions.color", options.color);
6996
+ assertArg(Utils13.Is.isBooleanOrUndefined(options.arpeggio) || Utils13.Is.isEnumValue(options.arpeggio, Arpeggio), "noteOptions.arpeggio", options.arpeggio);
6997
+ assertArg(Utils13.Is.isBooleanOrUndefined(options.staccato), "noteOptions.staccato", options.staccato);
6998
+ assertArg(Utils13.Is.isBooleanOrUndefined(options.diamond), "noteOptions.diamond", options.diamond);
6999
+ assertArg(Utils13.Is.isBooleanOrUndefined(options.triplet), "noteOptions.triplet", options.triplet);
7000
+ assertArg(Utils13.Is.isUndefined(options.string) || isStringNumber(options.string) || Utils13.Is.isNonEmptyArray(options.string) && options.string.every((string) => isStringNumber(string)), "noteOptions.string", options.string);
7001
+ assertArg(Utils13.Is.isUndefined(options.tieSpan), 'NoteOptions.tieSpan was removed. Use addConnective("tie", tieSpan)', "");
7002
+ assertArg(Utils13.Is.isUndefined(options.slurSpan), 'NoteOptions.slurSpan was removed. Use addConnective("slur", slurSpan)', "");
6918
7003
  }
6919
7004
  function assertRestOptions(options) {
6920
- assertArg(Utils11.Is.isObject(options), "restOptions", options);
6921
- assertArg(Utils11.Is.isBooleanOrUndefined(options.dotted), "restOptions.dotted", options.dotted);
6922
- assertArg(Utils11.Is.isStringOrUndefined(options.staffPos) || Utils11.Is.isInteger(options.staffPos) || options.staffPos instanceof Note10, "restOptions.staffPos", options.staffPos);
6923
- assertArg(Utils11.Is.isStringOrUndefined(options.color), "restOptions.color", options.color);
6924
- assertArg(Utils11.Is.isBooleanOrUndefined(options.hide), "restOptions.hide", options.hide);
6925
- assertArg(Utils11.Is.isBooleanOrUndefined(options.triplet), "restOptions.triplet", options.triplet);
7005
+ assertArg(Utils13.Is.isObject(options), "restOptions", options);
7006
+ assertArg(Utils13.Is.isBooleanOrUndefined(options.dotted) || Utils13.Is.isIntegerGte(options.dotted, 0), "restOptions.dotted", options.dotted);
7007
+ assertArg(Utils13.Is.isStringOrUndefined(options.staffPos) || Utils13.Is.isInteger(options.staffPos) || options.staffPos instanceof Note10, "restOptions.staffPos", options.staffPos);
7008
+ assertArg(Utils13.Is.isStringOrUndefined(options.color), "restOptions.color", options.color);
7009
+ assertArg(Utils13.Is.isBooleanOrUndefined(options.hide), "restOptions.hide", options.hide);
7010
+ assertArg(Utils13.Is.isBooleanOrUndefined(options.triplet), "restOptions.triplet", options.triplet);
6926
7011
  }
6927
7012
  function assertStaffTabOrGRoups(staffTabOrGroups) {
6928
7013
  assertArg(
6929
- Utils11.Is.isStringOrUndefined(staffTabOrGroups) || Utils11.Is.isIntegerGte(staffTabOrGroups, 0) || Utils11.Is.isArray(staffTabOrGroups) && staffTabOrGroups.every(
6930
- (staffTabOrGroup) => Utils11.Is.isString(staffTabOrGroup) || Utils11.Is.isIntegerGte(staffTabOrGroup, 0)
7014
+ Utils13.Is.isStringOrUndefined(staffTabOrGroups) || Utils13.Is.isIntegerGte(staffTabOrGroups, 0) || Utils13.Is.isNonEmptyArray(staffTabOrGroups) && staffTabOrGroups.every(
7015
+ (staffTabOrGroup) => Utils13.Is.isString(staffTabOrGroup) || Utils13.Is.isIntegerGte(staffTabOrGroup, 0)
6931
7016
  ),
6932
7017
  "staffTabOrGroup",
6933
7018
  staffTabOrGroups
6934
7019
  );
6935
7020
  }
7021
+ function isNoteLength(noteLen) {
7022
+ try {
7023
+ validateNoteLength2(noteLen);
7024
+ return true;
7025
+ } catch (e) {
7026
+ return false;
7027
+ }
7028
+ }
7029
+ function isTupletRatio(tupletRatio) {
7030
+ try {
7031
+ validateTupletRatio(tupletRatio);
7032
+ return true;
7033
+ } catch (e) {
7034
+ return false;
7035
+ }
7036
+ }
6936
7037
  var DocumentBuilder = class {
6937
7038
  constructor() {
6938
7039
  __publicField(this, "doc");
6939
7040
  this.doc = new ObjDocument();
6940
7041
  }
6941
7042
  setScoreConfiguration(config) {
6942
- if (Utils11.Is.isEnumValue(config, StaffPreset)) {
6943
- } else if (Utils11.Is.isObject(config) && config.type === "staff") {
7043
+ if (Utils13.Is.isEnumValue(config, StaffPreset)) {
7044
+ this.doc.setScoreConfiguration(config);
7045
+ } else if (Utils13.Is.isObject(config) && config.type === "staff") {
6944
7046
  assertStaffConfig(config);
6945
- } else if (Utils11.Is.isObject(config) && config.type === "tab") {
7047
+ this.doc.setScoreConfiguration(config);
7048
+ } else if (Utils13.Is.isObject(config) && config.type === "tab") {
6946
7049
  assertTabConfig(config);
6947
- } else if (Utils11.Is.isArray(config)) {
6948
- assertArg(config.length > 0, "config", config);
7050
+ this.doc.setScoreConfiguration(config);
7051
+ } else if (Utils13.Is.isNonEmptyArray(config)) {
6949
7052
  config.forEach((c) => {
6950
- if (Utils11.Is.isObject(c) && c.type === "staff") {
7053
+ if (Utils13.Is.isObject(c) && c.type === "staff") {
6951
7054
  assertStaffConfig(c);
6952
- } else if (Utils11.Is.isObject(c) && c.type === "tab") {
7055
+ } else if (Utils13.Is.isObject(c) && c.type === "tab") {
6953
7056
  assertTabConfig(c);
6954
7057
  } else {
6955
7058
  assertArg(false, "config", config);
6956
7059
  }
6957
7060
  });
7061
+ this.doc.setScoreConfiguration(config);
6958
7062
  } else {
6959
7063
  assertArg(false, "config", config);
6960
7064
  }
6961
- this.doc.setScoreConfiguration(config);
6962
7065
  return this;
6963
7066
  }
6964
7067
  getMeasure() {
@@ -6969,14 +7072,14 @@ var DocumentBuilder = class {
6969
7072
  return this.doc.getMusicInterface();
6970
7073
  }
6971
7074
  setHeader(title, composer, arranger) {
6972
- assertArg(Utils11.Is.isStringOrUndefined(title), "title", title);
6973
- assertArg(Utils11.Is.isStringOrUndefined(composer), "composer", composer);
6974
- assertArg(Utils11.Is.isStringOrUndefined(arranger), "arranger", arranger);
7075
+ assertArg(Utils13.Is.isStringOrUndefined(title), "title", title);
7076
+ assertArg(Utils13.Is.isStringOrUndefined(composer), "composer", composer);
7077
+ assertArg(Utils13.Is.isStringOrUndefined(arranger), "arranger", arranger);
6975
7078
  this.doc.setHeader(title, composer, arranger);
6976
7079
  return this;
6977
7080
  }
6978
7081
  setMeasuresPerRow(measuresPerRow) {
6979
- assertArg(Utils11.Is.isIntegerGte(measuresPerRow, 1) || measuresPerRow === Infinity, "measuresPerRow", measuresPerRow);
7082
+ assertArg(Utils13.Is.isIntegerGte(measuresPerRow, 1) || Utils13.Is.isPosInfinity(measuresPerRow), "measuresPerRow", measuresPerRow);
6980
7083
  this.doc.setMeasuresPerRow(measuresPerRow);
6981
7084
  return this;
6982
7085
  }
@@ -6985,30 +7088,30 @@ var DocumentBuilder = class {
6985
7088
  return this;
6986
7089
  }
6987
7090
  setKeySignature(...args) {
6988
- assertArg(args[0] instanceof Scale2 || args[0] instanceof KeySignature3 || Utils11.Is.isString(args[0]) && Utils11.Is.isEnumValue(args[1], ScaleType), "keySignature", args);
7091
+ assertArg(args[0] instanceof Scale2 || args[0] instanceof KeySignature3 || Utils13.Is.isNonEmptyString(args[0]) && (args.length === 1 || Utils13.Is.isEnumValue(args[1], ScaleType)), "keySignature", args);
6989
7092
  this.getMeasure().setKeySignature(...args);
6990
7093
  return this;
6991
7094
  }
6992
7095
  setTimeSignature(timeSignature) {
6993
- assertArg(timeSignature instanceof TimeSignature2 || Utils11.Is.isString(timeSignature), "timeSignature", timeSignature);
7096
+ assertArg(timeSignature instanceof TimeSignature2 || Utils13.Is.isNonEmptyString(timeSignature), "timeSignature", timeSignature);
6994
7097
  this.getMeasure().setTimeSignature(timeSignature);
6995
7098
  return this;
6996
7099
  }
6997
7100
  setTempo(beatsPerMinute, beatLength, dotted) {
6998
- assertArg(Utils11.Is.isIntegerGte(beatsPerMinute, 1), "beatsPerMinute", beatsPerMinute);
7101
+ assertArg(Utils13.Is.isIntegerGte(beatsPerMinute, 1), "beatsPerMinute", beatsPerMinute);
6999
7102
  if (beatLength === void 0) {
7000
- assertArg(Utils11.Is.isUndefined(dotted), "dotted", dotted);
7103
+ assertArg(Utils13.Is.isUndefined(dotted), "dotted", dotted);
7001
7104
  } else {
7002
- assertArg(Utils11.Is.isEnumValue(beatLength, NoteLength7), "beatLength", beatLength);
7003
- assertArg(Utils11.Is.isBooleanOrUndefined(dotted), "dotted", dotted);
7105
+ assertArg(Utils13.Is.isEnumValue(beatLength, NoteLength7) || isNoteLength(beatLength), "beatLength", beatLength);
7106
+ assertArg(Utils13.Is.isBooleanOrUndefined(dotted) || Utils13.Is.isIntegerGte(dotted, 0), "dotted", dotted);
7004
7107
  }
7005
7108
  this.getMeasure().setTempo(beatsPerMinute, beatLength, dotted);
7006
7109
  return this;
7007
7110
  }
7008
7111
  addNote(voiceId, note, noteLength, options) {
7009
7112
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7010
- assertArg(note instanceof Note10 || Utils11.Is.isString(note), "note", note);
7011
- assertArg(Utils11.Is.isEnumValue(noteLength, NoteLength7), "noteLength", noteLength);
7113
+ assertArg(note instanceof Note10 || Utils13.Is.isNonEmptyString(note), "note", note);
7114
+ assertArg(Utils13.Is.isEnumValue(noteLength, NoteLength7) || isNoteLength(noteLength), "noteLength", noteLength);
7012
7115
  if (options !== void 0) {
7013
7116
  assertNoteOptions(options);
7014
7117
  }
@@ -7017,8 +7120,8 @@ var DocumentBuilder = class {
7017
7120
  }
7018
7121
  addChord(voiceId, notes, noteLength, options) {
7019
7122
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7020
- assertArg(Utils11.Is.isArray(notes) && notes.length >= 1 && notes.every((note) => note instanceof Note10 || Utils11.Is.isString(note)), "notes", notes);
7021
- assertArg(Utils11.Is.isEnumValue(noteLength, NoteLength7), "noteLength", noteLength);
7123
+ assertArg(Utils13.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof Note10 || Utils13.Is.isNonEmptyString(note)), "notes", notes);
7124
+ assertArg(Utils13.Is.isEnumValue(noteLength, NoteLength7) || isNoteLength(noteLength), "noteLength", noteLength);
7022
7125
  if (options !== void 0) {
7023
7126
  assertNoteOptions(options);
7024
7127
  }
@@ -7027,33 +7130,91 @@ var DocumentBuilder = class {
7027
7130
  }
7028
7131
  addRest(voiceId, restLength, options) {
7029
7132
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7030
- assertArg(Utils11.Is.isEnumValue(restLength, NoteLength7), "restLength", restLength);
7133
+ assertArg(Utils13.Is.isEnumValue(restLength, NoteLength7) || isNoteLength(restLength), "restLength", restLength);
7031
7134
  if (options !== void 0) {
7032
7135
  assertRestOptions(options);
7033
7136
  }
7034
7137
  this.getMeasure().addRest(voiceId, restLength, options);
7035
7138
  return this;
7036
7139
  }
7140
+ /**
7141
+ * Usage:
7142
+ * <pre>
7143
+ * addTuplet(0, Theory.Tuplet.Triplet, notes => {
7144
+ * notes.addNote("G3", Theory.NoteLength.Eighth);
7145
+ * notes.addNote("B3", Theory.NoteLength.Eighth);
7146
+ * notes.addNote("D4", Theory.NoteLength.Eighth);
7147
+ * });
7148
+ * </pre>
7149
+ *
7150
+ * @param voiceId
7151
+ * @param tupletRatio - You can also use Theory.Tuplet presets (e.g. Theory.Tuplet.Triplet).
7152
+ * @param tupletBuilder
7153
+ * @returns
7154
+ */
7155
+ addTuplet(voiceId, tupletRatio, tupletBuilder) {
7156
+ assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7157
+ assertArg(Utils13.Is.isFunction(tupletBuilder), "tupletBuilder", tupletBuilder);
7158
+ assertArg(isTupletRatio(tupletRatio) && Utils13.Is.isBooleanOrUndefined(tupletRatio.showRatio), "tupletRatio", tupletRatio);
7159
+ let tupletSymbols = [];
7160
+ const helper = {
7161
+ addNote: (note, noteLength, options) => {
7162
+ assertArg(note instanceof Note10 || Utils13.Is.isNonEmptyString(note), "note", note);
7163
+ assertArg(Utils13.Is.isEnumValue(noteLength, NoteLength7) || isNoteLength(noteLength), "noteLength", noteLength);
7164
+ if (options !== void 0) {
7165
+ delete options.triplet;
7166
+ assertNoteOptions(options);
7167
+ }
7168
+ let s = this.getMeasure().addNoteGroup(voiceId, [note], noteLength, options, tupletRatio);
7169
+ tupletSymbols.push(s);
7170
+ return helper;
7171
+ },
7172
+ addChord: (notes, noteLength, options) => {
7173
+ assertArg(Utils13.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof Note10 || Utils13.Is.isNonEmptyString(note)), "notes", notes);
7174
+ assertArg(Utils13.Is.isEnumValue(noteLength, NoteLength7) || isNoteLength(noteLength), "noteLength", noteLength);
7175
+ if (options !== void 0) {
7176
+ delete options.triplet;
7177
+ assertNoteOptions(options);
7178
+ }
7179
+ let s = this.getMeasure().addNoteGroup(voiceId, notes, noteLength, options, tupletRatio);
7180
+ tupletSymbols.push(s);
7181
+ return helper;
7182
+ },
7183
+ addRest: (restLength, options) => {
7184
+ assertArg(Utils13.Is.isEnumValue(restLength, NoteLength7) || isNoteLength(restLength), "restLength", restLength);
7185
+ if (options !== void 0) {
7186
+ delete options.triplet;
7187
+ assertRestOptions(options);
7188
+ }
7189
+ let s = this.getMeasure().addRest(voiceId, restLength, options, tupletRatio);
7190
+ tupletSymbols.push(s);
7191
+ return helper;
7192
+ }
7193
+ };
7194
+ tupletBuilder(helper);
7195
+ ObjBeamGroup.createTuplet(tupletSymbols, tupletRatio);
7196
+ return this;
7197
+ }
7037
7198
  addFermataInternal(staffTabOrGroups, fermata) {
7038
7199
  assertStaffTabOrGRoups(staffTabOrGroups);
7039
- assertArg(Utils11.Is.isEnumValue(fermata, Fermata), "fermata", fermata);
7200
+ assertArg(Utils13.Is.isEnumValue(fermata, Fermata), "fermata", fermata);
7040
7201
  this.getMeasure().addFermata(staffTabOrGroups, fermata);
7041
7202
  return this;
7042
7203
  }
7043
- addFermata(fermata = 0 /* AtNote */) {
7204
+ addFermata(fermata = "atNote" /* AtNote */) {
7044
7205
  return this.addFermataInternal(void 0, fermata);
7045
7206
  }
7046
7207
  /** @param staffTabOrGroups - staff/tab index (0=top), staff/tab name, or staff group name. */
7047
- addFermataTo(staffTabOrGroups, fermata = 0 /* AtNote */) {
7208
+ addFermataTo(staffTabOrGroups, fermata = "atNote" /* AtNote */) {
7048
7209
  return this.addFermataInternal(staffTabOrGroups, fermata);
7049
7210
  }
7050
7211
  addNavigationInternal(staffTabOrGroups, navigation, ...args) {
7051
7212
  assertStaffTabOrGRoups(staffTabOrGroups);
7052
- assertArg(Utils11.Is.isEnumValue(navigation, Navigation), "navigation", navigation);
7053
- if (navigation === 9 /* EndRepeat */ && args.length > 0) {
7054
- assertArg(Utils11.Is.isIntegerGte(args[0], 1), "playCount", args[0]);
7055
- } else if (navigation === 10 /* Ending */ && args.length > 0) {
7056
- assertArg(args.every((passage) => Utils11.Is.isIntegerGte(passage, 1)), "passages", args);
7213
+ assertArg(Utils13.Is.isEnumValue(navigation, Navigation), "navigation", navigation);
7214
+ if (navigation === "endRepeat" /* EndRepeat */ && args.length > 0) {
7215
+ assertArg(Utils13.Is.isIntegerGte(args[0], 1), "playCount", args[0]);
7216
+ } else if (navigation === "ending" /* Ending */ && args.length > 0) {
7217
+ assertArg(args.every((passage) => Utils13.Is.isIntegerGte(passage, 1)), "passages", args);
7057
7218
  }
7058
7219
  this.getMeasure().addNavigation(staffTabOrGroups, navigation, ...args);
7059
7220
  return this;
@@ -7064,10 +7225,35 @@ var DocumentBuilder = class {
7064
7225
  addNavigationTo(staffTabOrGroups, navigation, ...args) {
7065
7226
  return this.addNavigationInternal(staffTabOrGroups, navigation, ...args);
7066
7227
  }
7228
+ addAnnotationInternal(staffTabOrGroups, annotation, text) {
7229
+ annotation != null ? annotation : annotation = getAnnotation(text);
7230
+ if (annotation === void 0) {
7231
+ throw new MusicError17(MusicErrorType17.Score, `Annotation text "${text}" is not known annotation.`);
7232
+ }
7233
+ assertStaffTabOrGRoups(staffTabOrGroups);
7234
+ assertArg(Utils13.Is.isEnumValue(annotation, Annotation), "annotation", annotation);
7235
+ assertArg(Utils13.Is.isNonEmptyString(text), "text", text);
7236
+ this.getMeasure().addAnnotation(staffTabOrGroups, annotation, text);
7237
+ return this;
7238
+ }
7239
+ addAnnotation(...args) {
7240
+ if (args.length === 1) {
7241
+ return this.addAnnotationInternal(void 0, void 0, args[0]);
7242
+ } else {
7243
+ return this.addAnnotationInternal(void 0, args[0], args[1]);
7244
+ }
7245
+ }
7246
+ addAnnotationTo(staffTabOrGroups, ...args) {
7247
+ if (args.length === 1) {
7248
+ return this.addAnnotationInternal(staffTabOrGroups, void 0, args[0]);
7249
+ } else {
7250
+ return this.addAnnotationInternal(staffTabOrGroups, args[0], args[1]);
7251
+ }
7252
+ }
7067
7253
  addLabelInternal(staffTabOrGroups, label, text) {
7068
7254
  assertStaffTabOrGRoups(staffTabOrGroups);
7069
- assertArg(Utils11.Is.isEnumValue(label, Label), "label", label);
7070
- assertArg(Utils11.Is.isString(text), "text", text);
7255
+ assertArg(Utils13.Is.isEnumValue(label, Label), "label", label);
7256
+ assertArg(Utils13.Is.isNonEmptyString(text), "text", text);
7071
7257
  this.getMeasure().addLabel(staffTabOrGroups, label, text);
7072
7258
  return this;
7073
7259
  }
@@ -7078,45 +7264,70 @@ var DocumentBuilder = class {
7078
7264
  addLabelTo(staffTabOrGroups, label, text) {
7079
7265
  return this.addLabelInternal(staffTabOrGroups, label, text);
7080
7266
  }
7081
- addAnnotationInternal(staffTabOrGroups, annotation, text) {
7082
- assertStaffTabOrGRoups(staffTabOrGroups);
7083
- assertArg(Utils11.Is.isEnumValue(annotation, Annotation), "annotation", annotation);
7084
- assertArg(Utils11.Is.isString(text), "text", text);
7085
- this.getMeasure().addAnnotation(staffTabOrGroups, annotation, text);
7086
- return this;
7087
- }
7088
- addAnnotation(annotation, text) {
7089
- return this.addAnnotationInternal(void 0, annotation, text);
7090
- }
7091
- /** @param staffTabOrGroups - staff/tab index (0=top), staff/tab name, or staff group name. */
7092
- addAnnotationTo(staffTabOrGroups, annotation, text) {
7093
- return this.addAnnotationInternal(staffTabOrGroups, annotation, text);
7094
- }
7095
7267
  addConnective(connective, ...args) {
7096
- assertArg(Utils11.Is.isEnumValue(connective, Connective), "connective", connective);
7097
- if (connective === 0 /* Tie */) {
7098
- assertArg(Utils11.Is.isUndefined(args[0]) || Utils11.Is.isInteger(args[0]) || Utils11.Is.isEnumValue(args[0], TieType), "tieSpan", args[0]);
7099
- assertArg(Utils11.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
7268
+ assertArg(Utils13.Is.isEnumValue(connective, Connective), "connective", connective);
7269
+ if (connective === "tie" /* Tie */) {
7270
+ assertArg(Utils13.Is.isIntegerOrUndefined(args[0]) || Utils13.Is.isEnumValue(args[0], TieType), "tieSpan", args[0]);
7271
+ assertArg(Utils13.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
7100
7272
  let tieSpan = args[0];
7101
7273
  let noteAnchor = args[1];
7102
7274
  this.getMeasure().addConnective(connective, tieSpan, noteAnchor);
7103
- } else if (connective === 1 /* Slur */) {
7104
- assertArg(Utils11.Is.isUndefined(args[0]) || Utils11.Is.isInteger(args[0]), "slurSpan", args[0]);
7105
- assertArg(Utils11.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
7275
+ } else if (connective === "slur" /* Slur */) {
7276
+ assertArg(Utils13.Is.isIntegerOrUndefined(args[0]), "slurSpan", args[0]);
7277
+ assertArg(Utils13.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
7106
7278
  let slurSpan = args[0];
7107
7279
  let noteAnchor = args[1];
7108
7280
  this.getMeasure().addConnective(connective, slurSpan, noteAnchor);
7109
- } else if (connective === 2 /* Slide */) {
7110
- assertArg(Utils11.Is.isEnumValueOrUndefined(args[0], NoteAnchor), "noteAnchor", args[0]);
7281
+ } else if (connective === "slide" /* Slide */) {
7282
+ assertArg(Utils13.Is.isEnumValueOrUndefined(args[0], NoteAnchor), "noteAnchor", args[0]);
7111
7283
  let noteAnchor = args[0];
7112
7284
  this.getMeasure().addConnective(connective, noteAnchor);
7113
7285
  }
7114
7286
  return this;
7115
7287
  }
7116
- addExtension(extensionLength, extensionVisible) {
7117
- assertArg(Utils11.Is.isIntegerGte(extensionLength, 0) || extensionLength === Infinity || Utils11.Is.isEnumValue(extensionLength, NoteLength7), "extendionLength", extensionLength);
7118
- assertArg(Utils11.Is.isBooleanOrUndefined(extensionVisible), "extensionVisible", extensionVisible);
7119
- this.getMeasure().addExtension(extensionLength, extensionVisible != null ? extensionVisible : true);
7288
+ /**
7289
+ * Extension length example:
7290
+ * <pre>
7291
+ * addExtension(ext => ext.notes("1n", 2)) // length is 2 whole notes
7292
+ * addExtension(ext => ext.measures(3).hide()) // length is 3 measures, hidden
7293
+ * addExtension(ext => ext.measures(1).notes("8n")) // length is 1 measure + 1 eigth note
7294
+ * addExtension(ext => ext.infinity()) // length is as long as possible
7295
+ * </pre>
7296
+ * @param extensionLength
7297
+ * @param extensionVisible
7298
+ * @returns
7299
+ */
7300
+ addExtension(extensionBuilder) {
7301
+ assertArg(Utils13.Is.isFunctionOrUndefined(extensionBuilder), "addExtension() has new usage, for e.g. addExtension(ext => ext.measures(2)). Please refer to README or API Reference.", extensionBuilder);
7302
+ let ticks = 0;
7303
+ let visible = true;
7304
+ const helper = {
7305
+ notes: (noteLength, noteCount) => {
7306
+ assertArg(Utils13.Is.isEnumValue(noteLength, NoteLength7) || isNoteLength(noteLength), "noteLength", noteLength);
7307
+ assertArg(Utils13.Is.isUndefined(noteCount) || Utils13.Is.isNumber(noteCount) && noteCount >= 0, "noteCount", noteCount);
7308
+ ticks += RhythmProps5.get(noteLength).ticks * (noteCount != null ? noteCount : 1);
7309
+ return helper;
7310
+ },
7311
+ measures: (measureCount) => {
7312
+ assertArg(Utils13.Is.isNumber(measureCount) && measureCount >= 1, "measureCount", measureCount);
7313
+ ticks += this.getMeasure().getMeasureTicks() * measureCount;
7314
+ return helper;
7315
+ },
7316
+ infinity: () => {
7317
+ ticks = Infinity;
7318
+ return helper;
7319
+ },
7320
+ hide: () => {
7321
+ visible = false;
7322
+ return helper;
7323
+ }
7324
+ };
7325
+ if (extensionBuilder) {
7326
+ extensionBuilder(helper);
7327
+ } else {
7328
+ ticks = Infinity;
7329
+ }
7330
+ this.getMeasure().addExtension(ticks, visible);
7120
7331
  return this;
7121
7332
  }
7122
7333
  /**
@@ -7126,14 +7337,14 @@ var DocumentBuilder = class {
7126
7337
  * @param verticalPosition - Vertical position, are elements added above, below or both.
7127
7338
  * @returns
7128
7339
  */
7129
- addStaffGroup(groupName, staffsTabsAndGroups, verticalPosition = 3 /* Auto */) {
7130
- assertArg(Utils11.Is.isString(groupName) && groupName.length > 0, "groupName", groupName);
7340
+ addStaffGroup(groupName, staffsTabsAndGroups, verticalPosition = "auto" /* Auto */) {
7341
+ assertArg(Utils13.Is.isNonEmptyString(groupName), "groupName", groupName);
7131
7342
  assertArg(
7132
- Utils11.Is.isString(staffsTabsAndGroups) && staffsTabsAndGroups.length > 0 || Utils11.Is.isIntegerGte(staffsTabsAndGroups, 0) || Utils11.Is.isArray(staffsTabsAndGroups) && staffsTabsAndGroups.every((line) => Utils11.Is.isString(line) && line.length > 0 || Utils11.Is.isIntegerGte(line, 0)),
7343
+ Utils13.Is.isNonEmptyString(staffsTabsAndGroups) || Utils13.Is.isIntegerGte(staffsTabsAndGroups, 0) || Utils13.Is.isNonEmptyArray(staffsTabsAndGroups) && staffsTabsAndGroups.every((line) => Utils13.Is.isNonEmptyString(line) || Utils13.Is.isIntegerGte(line, 0)),
7133
7344
  "staffsTabsAndGroups",
7134
7345
  staffsTabsAndGroups
7135
7346
  );
7136
- assertArg(Utils11.Is.isEnumValue(verticalPosition, VerticalPosition), "verticalPosition", verticalPosition);
7347
+ assertArg(Utils13.Is.isEnumValue(verticalPosition, VerticalPosition), "verticalPosition", verticalPosition);
7137
7348
  this.doc.addStaffGroup(groupName, staffsTabsAndGroups, verticalPosition);
7138
7349
  return this;
7139
7350
  }
@@ -7151,13 +7362,13 @@ var DocumentBuilder = class {
7151
7362
  return this;
7152
7363
  }
7153
7364
  completeRests(voiceId) {
7154
- assertArg(Utils11.Is.isUndefined(voiceId) || isVoiceId(voiceId), "voiceId", voiceId);
7365
+ assertArg(Utils13.Is.isUndefined(voiceId) || isVoiceId(voiceId) || Utils13.Is.isArray(voiceId) && voiceId.every((id) => isVoiceId(id)), "voiceId", voiceId);
7155
7366
  this.getMeasure().completeRests(voiceId);
7156
7367
  return this;
7157
7368
  }
7158
7369
  addScaleArpeggio(scale, bottomNote, numOctaves) {
7159
- assertArg(Utils11.Is.isString(bottomNote), "bottomNote", bottomNote);
7160
- assertArg(Utils11.Is.isIntegerGte(numOctaves, 1), "numOctaves", numOctaves);
7370
+ assertArg(Utils13.Is.isNonEmptyString(bottomNote), "bottomNote", bottomNote);
7371
+ assertArg(Utils13.Is.isIntegerGte(numOctaves, 1), "numOctaves", numOctaves);
7161
7372
  let ts = this.getMeasure().getTimeSignature();
7162
7373
  let notes = scale.getScaleNotes(bottomNote, numOctaves);
7163
7374
  for (let i = 0; i < notes.length; i++) {
@@ -7166,7 +7377,7 @@ var DocumentBuilder = class {
7166
7377
  }
7167
7378
  let note = notes[i];
7168
7379
  this.addNote(0, note, ts.beatLength);
7169
- this.addLabel(0 /* Note */, note.formatOmitOctave(SymbolSet2.Unicode));
7380
+ this.addLabel("note" /* Note */, note.formatOmitOctave(SymbolSet2.Unicode));
7170
7381
  }
7171
7382
  return this;
7172
7383
  }
@@ -7206,7 +7417,7 @@ var ScoreObjectEvent = class extends ScoreEvent {
7206
7417
 
7207
7418
  // src/score/pub/interface.ts
7208
7419
  import * as Audio2 from "@tspro/web-music-score/audio";
7209
- import { Utils as Utils12 } from "@tspro/ts-utils-lib";
7420
+ import { Utils as Utils14 } from "@tspro/ts-utils-lib";
7210
7421
  import { MusicError as MusicError19, MusicErrorType as MusicErrorType19 } from "@tspro/web-music-score/core";
7211
7422
  function assertArg2(condition, argName, argValue) {
7212
7423
  if (!condition) {
@@ -7221,7 +7432,14 @@ function require_t(t, message) {
7221
7432
  }
7222
7433
  }
7223
7434
  function isVoiceId2(value) {
7224
- return Utils12.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
7435
+ return Utils14.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
7436
+ }
7437
+ function getNotationLine(line) {
7438
+ if (line instanceof ObjStaff || line instanceof ObjTab) {
7439
+ return line.getMusicInterface();
7440
+ } else {
7441
+ throw new MusicError19(MusicErrorType19.Score, `Notation line not staff nor tab.`);
7442
+ }
7225
7443
  }
7226
7444
  var MusicInterface6 = class {
7227
7445
  constructor(name) {
@@ -7271,6 +7489,12 @@ var _MArpeggio = class _MArpeggio extends MusicInterface6 {
7271
7489
  getMusicObject() {
7272
7490
  return this.obj;
7273
7491
  }
7492
+ getRhythmColumn() {
7493
+ return this.obj.col.getMusicInterface();
7494
+ }
7495
+ getNotationLine() {
7496
+ return getNotationLine(this.obj.line);
7497
+ }
7274
7498
  };
7275
7499
  __publicField(_MArpeggio, "Name", "Arpeggio");
7276
7500
  var MArpeggio = _MArpeggio;
@@ -7297,6 +7521,9 @@ var _MStaffBeamGroup = class _MStaffBeamGroup extends MusicInterface6 {
7297
7521
  getMusicObject() {
7298
7522
  return this.obj;
7299
7523
  }
7524
+ getStaff() {
7525
+ return this.obj.staff.getMusicInterface();
7526
+ }
7300
7527
  };
7301
7528
  __publicField(_MStaffBeamGroup, "Name", "StaffBeamGroup");
7302
7529
  var MStaffBeamGroup = _MStaffBeamGroup;
@@ -7320,8 +7547,14 @@ var _MDocument = class _MDocument extends MusicInterface6 {
7320
7547
  getArranger() {
7321
7548
  return this.obj.getArranger();
7322
7549
  }
7550
+ getRows() {
7551
+ return this.obj.getRows().map((r) => r.getMusicInterface());
7552
+ }
7553
+ getMeasures() {
7554
+ return this.obj.getMeasures().map((m) => m.getMusicInterface());
7555
+ }
7323
7556
  play(fn) {
7324
- assertArg2(Utils12.Is.isFunctionOrUndefined(fn), "playStateChangeListener", fn);
7557
+ assertArg2(Utils14.Is.isFunctionOrUndefined(fn), "playStateChangeListener", fn);
7325
7558
  return new MPlayer(this, fn).play();
7326
7559
  }
7327
7560
  };
@@ -7341,7 +7574,7 @@ var _MEnding = class _MEnding extends MusicInterface6 {
7341
7574
  return this.obj.passages;
7342
7575
  }
7343
7576
  hasPassage(passage) {
7344
- assertArg2(Utils12.Is.isIntegerGte(passage, 1), "passage", passage);
7577
+ assertArg2(Utils14.Is.isIntegerGte(passage, 1), "passage", passage);
7345
7578
  return this.obj.hasPassage(passage);
7346
7579
  }
7347
7580
  };
@@ -7411,6 +7644,9 @@ var _MMeasure = class _MMeasure extends MusicInterface6 {
7411
7644
  getRhythmColumns() {
7412
7645
  return this.obj.getColumns().map((col) => col.getMusicInterface());
7413
7646
  }
7647
+ getRow() {
7648
+ return this.obj.row.getMusicInterface();
7649
+ }
7414
7650
  };
7415
7651
  __publicField(_MMeasure, "Name", "Measure");
7416
7652
  var MMeasure = _MMeasure;
@@ -7450,6 +7686,17 @@ var _MStaffTabBarLine = class _MStaffTabBarLine extends MusicInterface6 {
7450
7686
  getMusicObject() {
7451
7687
  return this.obj;
7452
7688
  }
7689
+ getBarLine() {
7690
+ let barLine = this.obj.barLine;
7691
+ if (barLine instanceof ObjBarLineLeft || barLine instanceof ObjBarLineRight) {
7692
+ return barLine.getMusicInterface();
7693
+ } else {
7694
+ throw new MusicError19(MusicErrorType19.Score, `Bar line not let nor right.`);
7695
+ }
7696
+ }
7697
+ getNotationLine() {
7698
+ return getNotationLine(this.obj.line);
7699
+ }
7453
7700
  };
7454
7701
  __publicField(_MStaffTabBarLine, "Name", "StaffTabBarLine");
7455
7702
  var MStaffTabBarLine = _MStaffTabBarLine;
@@ -7469,6 +7716,12 @@ var _MNoteGroup = class _MNoteGroup extends MusicInterface6 {
7469
7716
  getRhythmProps() {
7470
7717
  return this.obj.rhythmProps;
7471
7718
  }
7719
+ getRhythmColumn() {
7720
+ return this.obj.col.getMusicInterface();
7721
+ }
7722
+ getMeasure() {
7723
+ return this.obj.measure.getMusicInterface();
7724
+ }
7472
7725
  };
7473
7726
  __publicField(_MNoteGroup, "Name", "NoteGroup");
7474
7727
  var MNoteGroup = _MNoteGroup;
@@ -7485,6 +7738,15 @@ var _MStaffNoteGroup = class _MStaffNoteGroup extends MusicInterface6 {
7485
7738
  getNoteGroup() {
7486
7739
  return this.obj.noteGroup.getMusicInterface();
7487
7740
  }
7741
+ getRhythmColumn() {
7742
+ return this.getNoteGroup().getRhythmColumn();
7743
+ }
7744
+ getMeasure() {
7745
+ return this.getNoteGroup().getMeasure();
7746
+ }
7747
+ getStaff() {
7748
+ return this.obj.staff.getMusicInterface();
7749
+ }
7488
7750
  };
7489
7751
  __publicField(_MStaffNoteGroup, "Name", "StaffNoteGroup");
7490
7752
  var MStaffNoteGroup = _MStaffNoteGroup;
@@ -7501,6 +7763,15 @@ var _MTabNoteGroup = class _MTabNoteGroup extends MusicInterface6 {
7501
7763
  getNoteGroup() {
7502
7764
  return this.obj.noteGroup.getMusicInterface();
7503
7765
  }
7766
+ getRhythmColumn() {
7767
+ return this.getNoteGroup().getRhythmColumn();
7768
+ }
7769
+ getMeasure() {
7770
+ return this.getNoteGroup().getMeasure();
7771
+ }
7772
+ getTab() {
7773
+ return this.obj.tab.getMusicInterface();
7774
+ }
7504
7775
  };
7505
7776
  __publicField(_MTabNoteGroup, "Name", "TabNoteGroup");
7506
7777
  var MTabNoteGroup = _MTabNoteGroup;
@@ -7517,6 +7788,12 @@ var _MRest = class _MRest extends MusicInterface6 {
7517
7788
  getRhythmProps() {
7518
7789
  return this.obj.rhythmProps;
7519
7790
  }
7791
+ getRhythmColumn() {
7792
+ return this.obj.col.getMusicInterface();
7793
+ }
7794
+ getMeasure() {
7795
+ return this.obj.measure.getMusicInterface();
7796
+ }
7520
7797
  };
7521
7798
  __publicField(_MRest, "Name", "Rest");
7522
7799
  var MRest = _MRest;
@@ -7533,6 +7810,15 @@ var _MStaffRest = class _MStaffRest extends MusicInterface6 {
7533
7810
  getRest() {
7534
7811
  return this.obj.rest.getMusicInterface();
7535
7812
  }
7813
+ getRhythmColumn() {
7814
+ return this.getRest().getRhythmColumn();
7815
+ }
7816
+ getMeasure() {
7817
+ return this.getRest().getMeasure();
7818
+ }
7819
+ getStaff() {
7820
+ return this.obj.staff.getMusicInterface();
7821
+ }
7536
7822
  };
7537
7823
  __publicField(_MStaffRest, "Name", "StaffRest");
7538
7824
  var MStaffRest = _MStaffRest;
@@ -7551,6 +7837,13 @@ var _MRhythmColumn = class _MRhythmColumn extends MusicInterface6 {
7551
7837
  assertArg2(isVoiceId2(voiceId), "voiceId", voiceId);
7552
7838
  return (_a = this.obj.getVoiceSymbol(voiceId)) == null ? void 0 : _a.getMusicInterface();
7553
7839
  }
7840
+ getMeasure() {
7841
+ return this.obj.measure.getMusicInterface();
7842
+ }
7843
+ getVoiceSymbol(voiceId) {
7844
+ let s = this.obj.getVoiceSymbol(voiceId);
7845
+ return s instanceof ObjNoteGroup || s instanceof ObjRest ? s.getMusicInterface() : void 0;
7846
+ }
7554
7847
  };
7555
7848
  __publicField(_MRhythmColumn, "Name", "RhythmColumn");
7556
7849
  var MRhythmColumn = _MRhythmColumn;
@@ -7564,9 +7857,15 @@ var _MScoreRow = class _MScoreRow extends MusicInterface6 {
7564
7857
  getMusicObject() {
7565
7858
  return this.obj;
7566
7859
  }
7860
+ getDocument() {
7861
+ return this.obj.doc.getMusicInterface();
7862
+ }
7567
7863
  getMeasures() {
7568
7864
  return this.obj.getMeasures().map((m) => m.getMusicInterface());
7569
7865
  }
7866
+ getNotationLines() {
7867
+ return this.obj.getNotationLines().map((line) => getNotationLine(line));
7868
+ }
7570
7869
  };
7571
7870
  __publicField(_MScoreRow, "Name", "ScoreRow");
7572
7871
  var MScoreRow = _MScoreRow;
@@ -7580,6 +7879,15 @@ var _MStaff = class _MStaff extends MusicInterface6 {
7580
7879
  getMusicObject() {
7581
7880
  return this.obj;
7582
7881
  }
7882
+ getId() {
7883
+ return this.obj.id;
7884
+ }
7885
+ getName() {
7886
+ return this.obj.name.length > 0 ? this.obj.name : void 0;
7887
+ }
7888
+ getRow() {
7889
+ return this.obj.row.getMusicInterface();
7890
+ }
7583
7891
  };
7584
7892
  __publicField(_MStaff, "Name", "Staff");
7585
7893
  var MStaff = _MStaff;
@@ -7593,6 +7901,15 @@ var _MTab = class _MTab extends MusicInterface6 {
7593
7901
  getMusicObject() {
7594
7902
  return this.obj;
7595
7903
  }
7904
+ getId() {
7905
+ return this.obj.id;
7906
+ }
7907
+ getName() {
7908
+ return this.obj.name.length > 0 ? this.obj.name : void 0;
7909
+ }
7910
+ getRow() {
7911
+ return this.obj.row.getMusicInterface();
7912
+ }
7596
7913
  };
7597
7914
  __publicField(_MTab, "Name", "Tab");
7598
7915
  var MTab = _MTab;
@@ -7606,6 +7923,9 @@ var _MSignature = class _MSignature extends MusicInterface6 {
7606
7923
  getMusicObject() {
7607
7924
  return this.obj;
7608
7925
  }
7926
+ getStaff() {
7927
+ return this.obj.staff.getMusicInterface();
7928
+ }
7609
7929
  };
7610
7930
  __publicField(_MSignature, "Name", "Signature");
7611
7931
  var MSignature = _MSignature;
@@ -7619,6 +7939,9 @@ var _MSpecialText = class _MSpecialText extends MusicInterface6 {
7619
7939
  getMusicObject() {
7620
7940
  return this.obj;
7621
7941
  }
7942
+ getText() {
7943
+ return this.obj.getText();
7944
+ }
7622
7945
  };
7623
7946
  __publicField(_MSpecialText, "Name", "SpecialText");
7624
7947
  var MSpecialText = _MSpecialText;
@@ -7655,7 +7978,7 @@ var _MPlayer = class _MPlayer {
7655
7978
  constructor(doc, fn) {
7656
7979
  __publicField(this, "player");
7657
7980
  assertArg2(doc instanceof MDocument2, "doc", doc);
7658
- assertArg2(Utils12.Is.isFunctionOrUndefined(fn), "playStateChangeListener", fn);
7981
+ assertArg2(Utils14.Is.isFunctionOrUndefined(fn), "playStateChangeListener", fn);
7659
7982
  this.player = new Player();
7660
7983
  this.player.setDocument(doc.getMusicObject());
7661
7984
  this.player.setCursorPositionChangeListener((cursorRect) => doc.getMusicObject().updateCursorRect(cursorRect));
@@ -7690,17 +8013,17 @@ var MRenderer2 = class {
7690
8013
  this.renderer = new Renderer(this);
7691
8014
  }
7692
8015
  setDocument(doc) {
7693
- assertArg2(Utils12.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
8016
+ assertArg2(Utils14.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
7694
8017
  this.renderer.setDocument(doc);
7695
8018
  return this;
7696
8019
  }
7697
8020
  setCanvas(canvas) {
7698
- canvas = require_t(Utils12.Dom.getCanvas(canvas), typeof canvas === "string" ? "Cannot set renderer canvas because invalid canvas id: " + canvas : "Cannot set renderer canvas because given canvas is undefined.");
8021
+ canvas = require_t(Utils14.Dom.getCanvas(canvas), typeof canvas === "string" ? "Cannot set renderer canvas because invalid canvas id: " + canvas : "Cannot set renderer canvas because given canvas is undefined.");
7699
8022
  this.renderer.setCanvas(canvas);
7700
8023
  return this;
7701
8024
  }
7702
8025
  setScoreEventListener(fn) {
7703
- assertArg2(Utils12.Is.isFunctionOrUndefined(fn), "scoreEventListener", fn);
8026
+ assertArg2(Utils14.Is.isFunctionOrUndefined(fn), "scoreEventListener", fn);
7704
8027
  this.renderer.setScoreEventListener(fn);
7705
8028
  }
7706
8029
  hilightObject(obj) {
@@ -7755,7 +8078,7 @@ var _MPlaybackButtons = class _MPlaybackButtons {
7755
8078
  this.updateButtons();
7756
8079
  }
7757
8080
  setDocument(doc) {
7758
- assertArg2(Utils12.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
8081
+ assertArg2(Utils14.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
7759
8082
  this.onStop();
7760
8083
  if (doc) {
7761
8084
  this.player = new MPlayer(doc, (playState) => {
@@ -7790,9 +8113,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
7790
8113
  }
7791
8114
  }
7792
8115
  setPlayButton(btn, btnLabel) {
7793
- assertArg2(Utils12.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
8116
+ assertArg2(Utils14.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
7794
8117
  _MPlaybackButtons.removeOnClickListeners(this.playButton, this.onPlay);
7795
- this.playButton = require_t(Utils12.Dom.getButton(btn), "Play button required!");
8118
+ this.playButton = require_t(Utils14.Dom.getButton(btn), "Play button required!");
7796
8119
  this.playLabel = btnLabel != null ? btnLabel : "Play";
7797
8120
  _MPlaybackButtons.removeOnClickListeners(this.playButton, "all");
7798
8121
  _MPlaybackButtons.addOnClickListener(this.playButton, this.onPlay);
@@ -7800,9 +8123,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
7800
8123
  return this;
7801
8124
  }
7802
8125
  setStopButton(btn, btnLabel) {
7803
- assertArg2(Utils12.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
8126
+ assertArg2(Utils14.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
7804
8127
  _MPlaybackButtons.removeOnClickListeners(this.stopButton, this.onStop);
7805
- this.stopButton = require_t(Utils12.Dom.getButton(btn), "Stop button required!");
8128
+ this.stopButton = require_t(Utils14.Dom.getButton(btn), "Stop button required!");
7806
8129
  this.stopLabel = btnLabel != null ? btnLabel : "Stop";
7807
8130
  _MPlaybackButtons.removeOnClickListeners(this.stopButton, "all");
7808
8131
  _MPlaybackButtons.addOnClickListener(this.stopButton, this.onStop);
@@ -7810,10 +8133,10 @@ var _MPlaybackButtons = class _MPlaybackButtons {
7810
8133
  return this;
7811
8134
  }
7812
8135
  setPlayStopButton(btn, playLabel, stopLabel) {
7813
- assertArg2(Utils12.Is.isStringOrUndefined(playLabel), "playLabel", playLabel);
7814
- assertArg2(Utils12.Is.isStringOrUndefined(stopLabel), "stopLabel", stopLabel);
8136
+ assertArg2(Utils14.Is.isStringOrUndefined(playLabel), "playLabel", playLabel);
8137
+ assertArg2(Utils14.Is.isStringOrUndefined(stopLabel), "stopLabel", stopLabel);
7815
8138
  _MPlaybackButtons.removeOnClickListeners(this.playStopButton, this.onPlayStop);
7816
- this.playStopButton = require_t(Utils12.Dom.getButton(btn), "Play/stop button required!");
8139
+ this.playStopButton = require_t(Utils14.Dom.getButton(btn), "Play/stop button required!");
7817
8140
  this.playLabel = playLabel != null ? playLabel : "Play";
7818
8141
  this.stopLabel = stopLabel != null ? stopLabel : "Stop";
7819
8142
  _MPlaybackButtons.removeOnClickListeners(this.playStopButton, "all");
@@ -7822,9 +8145,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
7822
8145
  return this;
7823
8146
  }
7824
8147
  setPauseButton(btn, btnLabel) {
7825
- assertArg2(Utils12.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
8148
+ assertArg2(Utils14.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
7826
8149
  _MPlaybackButtons.removeOnClickListeners(this.pauseButton, this.onPause);
7827
- this.pauseButton = require_t(Utils12.Dom.getButton(btn), "Pause button required!");
8150
+ this.pauseButton = require_t(Utils14.Dom.getButton(btn), "Pause button required!");
7828
8151
  this.pauseLabel = btnLabel != null ? btnLabel : "Pause";
7829
8152
  _MPlaybackButtons.removeOnClickListeners(this.pauseButton, "all");
7830
8153
  _MPlaybackButtons.addOnClickListener(this.pauseButton, this.onPause);
@@ -7846,7 +8169,7 @@ var _MPlaybackButtons = class _MPlaybackButtons {
7846
8169
  }
7847
8170
  }
7848
8171
  static addOnClickListener(btn, onClick) {
7849
- assertArg2(Utils12.Is.isFunction(onClick), "onClick", onClick);
8172
+ assertArg2(Utils14.Is.isFunction(onClick), "onClick", onClick);
7850
8173
  btn.addEventListener("click", onClick);
7851
8174
  let clickListeners = this.savedOnClickListeners.get(btn) || [];
7852
8175
  this.savedOnClickListeners.set(btn, [...clickListeners, onClick]);