@tspro/web-music-score 5.2.0 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- /* WebMusicScore v5.2.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
1
+ /* WebMusicScore v5.3.0 | (c) 2023 PahkaSoft | MIT License | Includes: Tone.js (MIT License) */
2
2
  "use strict";
3
3
  var __create = Object.create;
4
4
  var __defProp = Object.defineProperty;
@@ -61,7 +61,8 @@ __export(score_exports, {
61
61
  MNoteGroup: () => MNoteGroup,
62
62
  MPlaybackButtons: () => MPlaybackButtons,
63
63
  MPlayer: () => MPlayer,
64
- MRenderer: () => MRenderer2,
64
+ MRenderContext: () => MRenderContext2,
65
+ MRenderer: () => MRenderer,
65
66
  MRest: () => MRest,
66
67
  MRhythmColumn: () => MRhythmColumn,
67
68
  MScoreRow: () => MScoreRow,
@@ -375,7 +376,7 @@ var DivRect = class _DivRect {
375
376
  };
376
377
 
377
378
  // src/score/pub/document-builder.ts
378
- var import_ts_utils_lib16 = require("@tspro/ts-utils-lib");
379
+ var import_ts_utils_lib18 = require("@tspro/ts-utils-lib");
379
380
 
380
381
  // src/score/pub/types.ts
381
382
  var StaffPreset = /* @__PURE__ */ ((StaffPreset3) => {
@@ -387,10 +388,10 @@ var StaffPreset = /* @__PURE__ */ ((StaffPreset3) => {
387
388
  StaffPreset3["GuitarCombined"] = "guitarCombined";
388
389
  return StaffPreset3;
389
390
  })(StaffPreset || {});
390
- var Clef = /* @__PURE__ */ ((Clef4) => {
391
- Clef4["G"] = "G";
392
- Clef4["F"] = "F";
393
- return Clef4;
391
+ var Clef = /* @__PURE__ */ ((Clef2) => {
392
+ Clef2["G"] = "G";
393
+ Clef2["F"] = "F";
394
+ return Clef2;
394
395
  })(Clef || {});
395
396
  function getVoiceIds() {
396
397
  return [0, 1, 2, 3];
@@ -586,7 +587,7 @@ var import_theory12 = require("@tspro/web-music-score/theory");
586
587
  // src/score/engine/obj-staff-and-tab.ts
587
588
  var import_theory11 = require("@tspro/web-music-score/theory");
588
589
 
589
- // src/score/engine/renderer.ts
590
+ // src/score/engine/render-context.ts
590
591
  var import_ts_utils_lib3 = require("@tspro/ts-utils-lib");
591
592
 
592
593
  // src/score/engine/settings.ts
@@ -611,6 +612,7 @@ var DocumentSettings = {
611
612
  FlagSeparation: 2,
612
613
  BeamSeparation: 1.25,
613
614
  BeamAngleFactor: 0.5,
615
+ BeamThickness: 4,
614
616
  RestDotSpace: 0.5,
615
617
  LedgerLineWidth: 3.6,
616
618
  StubTieLength: 5,
@@ -618,58 +620,58 @@ var DocumentSettings = {
618
620
  TabHeight: 20
619
621
  };
620
622
 
621
- // src/score/engine/renderer.ts
623
+ // src/score/engine/render-context.ts
622
624
  var import_core3 = require("@tspro/web-music-score/core");
623
625
 
624
- // src/score/engine/assets/treble-clef.png
625
- var treble_clef_default = "data:image/png;base64,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TTpEb2N1bWVudElEPSJnaW1wOmRvY2lkOmdpbXA6NDA3ODVjMzYtNDAxZC00YTZlLTkxODctMDQ1NTI4MmM0ZGY2IgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjhiZTJkYzc1LTVlYjQtNDk0Yy1iNWRlLWQ2MzZkNzZhNjI2YiIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOmU3YWE0MWNhLTNiYjMtNGU5Yi05NDQxLTllNTNmZTJiZjM5ZiIKICAgZGM6Rm9ybWF0PSJpbWFnZS9wbmciCiAgIEdJTVA6QVBJPSIyLjAiCiAgIEdJTVA6UGxhdGZvcm09IldpbmRvd3MiCiAgIEdJTVA6VGltZVN0YW1wPSIxNjg2NDA4NjA5MzE2NDM4IgogICBHSU1QOlZlcnNpb249IjIuMTAuMzQiCiAgIHRpZmY6T3JpZW50YXRpb249IjEiCiAgIHhtcDpDcmVhdG9yVG9vbD0iR0lNUCAyLjEwIgogICB4bXA6TWV0YWRhdGFEYXRlPSIyMDIzOjA2OjEwVDE3OjUwOjA5KzAzOjAwIgogICB4bXA6TW9kaWZ5RGF0ZT0iMjAyMzowNjoxMFQxNzo1MDowOSswMzowMCI+CiAgIDx4bXBNTTpIaXN0b3J5PgogICAgPHJkZjpTZXE+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjI3MzY2YmY0LWVkZDMtNDE5OC05NjJhLWU5ZTM5MTBlNThiZSIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChXaW5kb3dzKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMi0wOC0yMlQwMjo1NTozNiIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo5NjVlMTM3OS0wZDlmLTQ5ODItYWQ3MC05MzhjOWMzOWE0ZjMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoV2luZG93cykiCiAgICAgIHN0RXZ0OndoZW49IjIwMjItMDktMTFUMTY6MzU6MDAiLz4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MTBmYmEwYTMtOTI5Yi00NTRlLThjNGMtOGVkOGM4YWJhZGRjIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKFdpbmRvd3MpIgogICAgICBzdEV2dDp3aGVuPSIyMDIzLTA2LTEwVDE3OjUwOjA5Ii8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Ppn4NIQAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAALiMAAC4jAXilP3YAAAAHdElNRQfnBgoOMgm5WlWBAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAACHtJREFUeNrtnXuQVmMcxz+77cauTWUpbGSVu2w3BpnUEBq3chkmBjGayG1GBuNWLtUgw5SJkBkjl4QKg1wyQyarK0lRSlstU20bWam9+OM8O3P6vc8553nOe97tnO18Z84f57zP7XvOc/ndnueFfQx5e6neUmAI0B3oDPwD/AJ8Dvzcml5we+Al4D+gyeOaB1S0BrLHAut9iLqv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";
626
+ // src/score/engine/assets/F-clef.png
627
+ var F_clef_default = "data:image/png;base64,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IHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDo0MDc4NWMzNi00MDFkLTRhNmUtOTE4Ny0wNDU1MjgyYzRkZjYiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6Nzg3YjYxN2YtMjg1MS00YzhlLTg2MTYtZWM3NGMwYzYwMWVlIgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6ZTdhYTQxY2EtM2JiMy00ZTliLTk0NDEtOWU1M2ZlMmJmMzlmIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iV2luZG93cyIKICAgR0lNUDpUaW1lU3RhbXA9IjE2ODY2MTM5NDcxOTU2ODAiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4zNCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjM6MDY6MTNUMDI6NTI6MjUrMDM6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIzOjA2OjEzVDAyOjUyOjI1KzAzOjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MjczNjZiZjQtZWRkMy00MTk4LTk2MmEtZTllMzkxMGU1OGJlIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKFdpbmRvd3MpIgogICAgICBzdEV2dDp3aGVuPSIyMDIyLTA4LTIyVDAyOjU1OjM2Ii8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjk2NWUxMzc5LTBkOWYtNDk4Mi1hZDcwLTkzOGM5YzM5YTRmMyIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChXaW5kb3dzKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMi0wOS0xMVQxNjozNTowMCIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoxMGZiYTBhMy05MjliLTQ1NGUtOGM0Yy04ZWQ4YzhhYmFkZGMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoV2luZG93cykiCiAgICAgIHN0RXZ0OndoZW49IjIwMjMtMDYtMTBUMTc6NTA6MDkiLz4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MDBmYjM4YTMtZjZiMi00NjQ1LTliMTYtMjlhNWE0ODZlMjhhIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKFdpbmRvd3MpIgogICAgICBzdEV2dDp3aGVuPSIyMDIzLTA2LTEzVDAyOjUyOjI3Ii8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PsIRrtIAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAALiMAAC4jAXilP3YAAAAHdElNRQfnBgwXNBsqJURsAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAABF9JREFUeNrtmluIF1Ucxz9/E8P1VnnJ9dJWC4Frmq2JJmqolGEILoQvK2gZeXlRCSm1Fx9UEsJQERWsXhRftECs0Gq70EK9ZHlbFyHbds3VVXFX91+7664P81tYhpnfmft//st84TzMzDm/8/vOnPO7nYEMGTJkyJAhQ4YMGSJBLkJZw4FyYAIwDHgU+A9oAxqBv4C7xfyySoBlwKfAFaAb6DG0euAzoAoYXCxEnwH2A60eCGrtFrALGJNWokNEwY6QRO2tFXgPGJAmss8DlyImam/fASPTQHaeGJueBFod8FQhrfSLwM+ynDX8L1/oV+BP4LZY58eBUUAlMB94ycPSvQTMERmJ4jGgwYPh2Qg84VFmGbAP6DTI/aoQS/lzg1JfA2MDyn4ZuGaQvyZJspUGv3oKGBhyjmeBJmWOmxLMJIITiiIXIgwaZgFdylxbDeNHANXAZmAVUBpEiScNe2xRxC/3Y2WuRmUlLRHD1rd/HljvV4F3FAVqYlhNo4B7Pl/wdPEMbmOq/ShwRBH0Vkxb6LAy536fW64HuOpn8vOKoLKYCC9Q5rzs0L/JQxDjyYPkgHYXAW0xGslByrLuFuPUFw0eCI92mmiAQ4LgZoEbYyTcAZxVPsJk271ag7x6cWueCLvhfsyu8LzybKLtersUF9ywxe2BnXBnAZOUJuXZeNv1OSki3LLdzwPrgONuguw+7g7wAHjEoW+vEagAXgeelr1yUSZoCUn4hvJsqMO9byRaWyLGtFkiwOtBJnYzBKcVg/ZuSMIrlHl3RrWMnFK1OqX/q8oXOAisDqFLVxL7xonw9yHk7Q5RoxpuyLdjI3wmhLzBwMqAY0ck4SGcCNeKIQqKOTF84RtxEu4BPgohc2QM467HSRjgqBL5mBDUPU1Rnl1JwqBNUuJqrW0M+OLdYuk8Cdas38Rf4b3FR0HP/nLdZNYaioKbxSVuA6ZGQfoNvNWlO6VvEKxW5O5yGbNc4ml7ZrUtCtLjgGMSdjop9Q+wMIT8GoXwKw79ZxrKUG9r+a8flMoyr5AA4ybwo1QgggYHpZJ6Ou3Ta5IpddvufwEsVWQ2xFisCI1Nypf6RMmsIql4JI0S8bFuSs9UvmCgikeh8b6i8C/KuKOYD+VShzGSwLsprRnByYYYoSqNhE8qCv/kYfxrYjT7jmuPIC+PBWsVsl1YRzBeE45qqWGtwjo1SR0WoZ8a7KAfYa5h7/2OVaPuF1gqtS83srclpi565IAP0c+b7wOz+wPZckOc3Jt0LC52oiXABx7y6VasGnfRYgiwwRAu9raGqPLXQmAGcADvvyN+m9bgXnP4i4E9wN8+KiJ5WQG5QilumnioJP9lwHPANKw/fF7A+fxJw2ms/y9SFdiPBf4Vn9hJNL8T/iFxbyoxgej+m6zBOtnLpXlvhiXcDOyVJV8UCEL4KnBI/OnAtBP0q+ADMTq/SfshrdUFr4TzwJdY9d57WIdYzRIk1GMdeXSQIUOGDBmSwUMtd8u2ArdcUAAAAABJRU5ErkJggg==";
626
628
 
627
- // src/score/engine/assets/bass-clef.png
628
- var bass_clef_default = "data:image/png;base64,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IHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDo0MDc4NWMzNi00MDFkLTRhNmUtOTE4Ny0wNDU1MjgyYzRkZjYiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6Nzg3YjYxN2YtMjg1MS00YzhlLTg2MTYtZWM3NGMwYzYwMWVlIgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6ZTdhYTQxY2EtM2JiMy00ZTliLTk0NDEtOWU1M2ZlMmJmMzlmIgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjIuMCIKICAgR0lNUDpQbGF0Zm9ybT0iV2luZG93cyIKICAgR0lNUDpUaW1lU3RhbXA9IjE2ODY2MTM5NDcxOTU2ODAiCiAgIEdJTVA6VmVyc2lvbj0iMi4xMC4zNCIKICAgdGlmZjpPcmllbnRhdGlvbj0iMSIKICAgeG1wOkNyZWF0b3JUb29sPSJHSU1QIDIuMTAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjM6MDY6MTNUMDI6NTI6MjUrMDM6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDIzOjA2OjEzVDAyOjUyOjI1KzAzOjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MjczNjZiZjQtZWRkMy00MTk4LTk2MmEtZTllMzkxMGU1OGJlIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKFdpbmRvd3MpIgogICAgICBzdEV2dDp3aGVuPSIyMDIyLTA4LTIyVDAyOjU1OjM2Ii8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjk2NWUxMzc5LTBkOWYtNDk4Mi1hZDcwLTkzOGM5YzM5YTRmMyIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChXaW5kb3dzKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMi0wOS0xMVQxNjozNTowMCIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDoxMGZiYTBhMy05MjliLTQ1NGUtOGM0Yy04ZWQ4YzhhYmFkZGMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoV2luZG93cykiCiAgICAgIHN0RXZ0OndoZW49IjIwMjMtMDYtMTBUMTc6NTA6MDkiLz4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MDBmYjM4YTMtZjZiMi00NjQ1LTliMTYtMjlhNWE0ODZlMjhhIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKFdpbmRvd3MpIgogICAgICBzdEV2dDp3aGVuPSIyMDIzLTA2LTEzVDAyOjUyOjI3Ii8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/PsIRrtIAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAALiMAAC4jAXilP3YAAAAHdElNRQfnBgwXNBsqJURsAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAABF9JREFUeNrtmluIF1Ucxz9/E8P1VnnJ9dJWC4Frmq2JJmqolGEILoQvK2gZeXlRCSm1Fx9UEsJQERWsXhRftECs0Gq70EK9ZHlbFyHbds3VVXFX91+7664P81tYhpnfmft//st84TzMzDm/8/vOnPO7nYEMGTJkyJAhQ4YMGSJBLkJZw4FyYAIwDHgU+A9oAxqBv4C7xfyySoBlwKfAFaAb6DG0euAzoAoYXCxEnwH2A60eCGrtFrALGJNWokNEwY6QRO2tFXgPGJAmss8DlyImam/fASPTQHaeGJueBFod8FQhrfSLwM+ynDX8L1/oV+BP4LZY58eBUUAlMB94ycPSvQTMERmJ4jGgwYPh2Qg84VFmGbAP6DTI/aoQS/lzg1JfA2MDyn4ZuGaQvyZJspUGv3oKGBhyjmeBJmWOmxLMJIITiiIXIgwaZgFdylxbDeNHANXAZmAVUBpEiScNe2xRxC/3Y2WuRmUlLRHD1rd/HljvV4F3FAVqYlhNo4B7Pl/wdPEMbmOq/ShwRBH0Vkxb6LAy536fW64HuOpn8vOKoLKYCC9Q5rzs0L/JQxDjyYPkgHYXAW0xGslByrLuFuPUFw0eCI92mmiAQ4LgZoEbYyTcAZxVPsJk271ag7x6cWueCLvhfsyu8LzybKLtersUF9ywxe2BnXBnAZOUJuXZeNv1OSki3LLdzwPrgONuguw+7g7wAHjEoW+vEagAXgeelr1yUSZoCUn4hvJsqMO9byRaWyLGtFkiwOtBJnYzBKcVg/ZuSMIrlHl3RrWMnFK1OqX/q8oXOAisDqFLVxL7xonw9yHk7Q5RoxpuyLdjI3wmhLzBwMqAY0ck4SGcCNeKIQqKOTF84RtxEu4BPgohc2QM467HSRjgqBL5mBDUPU1Rnl1JwqBNUuJqrW0M+OLdYuk8Cdas38Rf4b3FR0HP/nLdZNYaioKbxSVuA6ZGQfoNvNWlO6VvEKxW5O5yGbNc4ml7ZrUtCtLjgGMSdjop9Q+wMIT8GoXwKw79ZxrKUG9r+a8flMoyr5AA4ybwo1QgggYHpZJ6Ou3Ta5IpddvufwEsVWQ2xFisCI1Nypf6RMmsIql4JI0S8bFuSs9UvmCgikeh8b6i8C/KuKOYD+VShzGSwLsprRnByYYYoSqNhE8qCv/kYfxrYjT7jmuPIC+PBWsVsl1YRzBeE45qqWGtwjo1SR0WoZ8a7KAfYa5h7/2OVaPuF1gqtS83srclpi565IAP0c+b7wOz+wPZckOc3Jt0LC52oiXABx7y6VasGnfRYgiwwRAu9raGqPLXQmAGcADvvyN+m9bgXnP4i4E9wN8+KiJ5WQG5QilumnioJP9lwHPANKw/fF7A+fxJw2ms/y9SFdiPBf4Vn9hJNL8T/iFxbyoxgej+m6zBOtnLpXlvhiXcDOyVJV8UCEL4KnBI/OnAtBP0q+ADMTq/SfshrdUFr4TzwJdY9d57WIdYzRIk1GMdeXSQIUOGDBmSwUMtd8u2ArdcUAAAAABJRU5ErkJggg==";
629
+ // src/score/engine/assets/G-clef.png
630
+ var G_clef_default = "data:image/png;base64,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TTpEb2N1bWVudElEPSJnaW1wOmRvY2lkOmdpbXA6NDA3ODVjMzYtNDAxZC00YTZlLTkxODctMDQ1NTI4MmM0ZGY2IgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjhiZTJkYzc1LTVlYjQtNDk0Yy1iNWRlLWQ2MzZkNzZhNjI2YiIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOmU3YWE0MWNhLTNiYjMtNGU5Yi05NDQxLTllNTNmZTJiZjM5ZiIKICAgZGM6Rm9ybWF0PSJpbWFnZS9wbmciCiAgIEdJTVA6QVBJPSIyLjAiCiAgIEdJTVA6UGxhdGZvcm09IldpbmRvd3MiCiAgIEdJTVA6VGltZVN0YW1wPSIxNjg2NDA4NjA5MzE2NDM4IgogICBHSU1QOlZlcnNpb249IjIuMTAuMzQiCiAgIHRpZmY6T3JpZW50YXRpb249IjEiCiAgIHhtcDpDcmVhdG9yVG9vbD0iR0lNUCAyLjEwIgogICB4bXA6TWV0YWRhdGFEYXRlPSIyMDIzOjA2OjEwVDE3OjUwOjA5KzAzOjAwIgogICB4bXA6TW9kaWZ5RGF0ZT0iMjAyMzowNjoxMFQxNzo1MDowOSswMzowMCI+CiAgIDx4bXBNTTpIaXN0b3J5PgogICAgPHJkZjpTZXE+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOjI3MzY2YmY0LWVkZDMtNDE5OC05NjJhLWU5ZTM5MTBlNThiZSIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iR2ltcCAyLjEwIChXaW5kb3dzKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMi0wOC0yMlQwMjo1NTozNiIvPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iLyIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo5NjVlMTM3OS0wZDlmLTQ5ODItYWQ3MC05MzhjOWMzOWE0ZjMiCiAgICAgIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkdpbXAgMi4xMCAoV2luZG93cykiCiAgICAgIHN0RXZ0OndoZW49IjIwMjItMDktMTFUMTY6MzU6MDAiLz4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MTBmYmEwYTMtOTI5Yi00NTRlLThjNGMtOGVkOGM4YWJhZGRjIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHaW1wIDIuMTAgKFdpbmRvd3MpIgogICAgICBzdEV2dDp3aGVuPSIyMDIzLTA2LTEwVDE3OjUwOjA5Ii8+CiAgICA8L3JkZjpTZXE+CiAgIDwveG1wTU06SGlzdG9yeT4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAKPD94cGFja2V0IGVuZD0idyI/Ppn4NIQAAAAGYktHRAD/AP8A/6C9p5MAAAAJcEhZcwAALiMAAC4jAXilP3YAAAAHdElNRQfnBgoOMgm5WlWBAAAAGXRFWHRDb21tZW50AENyZWF0ZWQgd2l0aCBHSU1QV4EOFwAACHtJREFUeNrtnXuQVmMcxz+77cauTWUpbGSVu2w3BpnUEBq3chkmBjGayG1GBuNWLtUgw5SJkBkjl4QKg1wyQyarK0lRSlstU20bWam9+OM8O3P6vc8553nOe97tnO18Z84f57zP7XvOc/ndnueFfQx5e6neUmAI0B3oDPwD/AJ8Dvzcml5we+Al4D+gyeOaB1S0BrLHAut9iLqv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";
629
631
 
630
632
  // src/theory/rhythm.ts
631
633
  var import_ts_utils_lib2 = require("@tspro/ts-utils-lib");
632
634
  var import_core2 = require("@tspro/web-music-score/core");
633
635
  var MaxTupletRatioValue = 12;
634
636
  var TicksMultiplier = 12 * 11 * 9 * 7 * 5;
635
- var NoteLength = /* @__PURE__ */ ((NoteLength10) => {
636
- NoteLength10["Whole"] = "1n";
637
- NoteLength10["WholeTriplet"] = "1t";
638
- NoteLength10["WholeDot"] = "1.";
639
- NoteLength10["Whole2Dots"] = "1..";
640
- NoteLength10["Whole12Dots"] = "1..";
641
- NoteLength10["Whole3Dots"] = "1...";
642
- NoteLength10["Whole4Dots"] = "1....";
643
- NoteLength10["Whole5Dots"] = "1.....";
644
- NoteLength10["Whole6Dots"] = "1......";
645
- NoteLength10["Half"] = "2n";
646
- NoteLength10["HalfTriplet"] = "2t";
647
- NoteLength10["HalfDot"] = "2.";
648
- NoteLength10["Half2Dots"] = "2..";
649
- NoteLength10["Half3Dots"] = "2...";
650
- NoteLength10["Half4Dots"] = "2....";
651
- NoteLength10["Half5Dots"] = "2.....";
652
- NoteLength10["Quarter"] = "4n";
653
- NoteLength10["QuarterTriplet"] = "4t";
654
- NoteLength10["QuarterDot"] = "4.";
655
- NoteLength10["Quarter2Dots"] = "4..";
656
- NoteLength10["Quarter3Dots"] = "4...";
657
- NoteLength10["Quarter4Dots"] = "4....";
658
- NoteLength10["Eighth"] = "8n";
659
- NoteLength10["EighthTriplet"] = "8t";
660
- NoteLength10["EighthDot"] = "8.";
661
- NoteLength10["Eighth2Dots"] = "8..";
662
- NoteLength10["Eighth3Dots"] = "8...";
663
- NoteLength10["Sixteenth"] = "16n";
664
- NoteLength10["SixteenthTriplet"] = "16t";
665
- NoteLength10["SixteenthDot"] = "16.";
666
- NoteLength10["Sixteenth2Dots"] = "16..";
667
- NoteLength10["ThirtySecond"] = "32n";
668
- NoteLength10["ThirtySecondTriplet"] = "32t";
669
- NoteLength10["ThirtySecondDot"] = "32.";
670
- NoteLength10["SixtyFourth"] = "64n";
671
- NoteLength10["SixtyFourthTriplet"] = "64t";
672
- return NoteLength10;
637
+ var NoteLength = /* @__PURE__ */ ((NoteLength9) => {
638
+ NoteLength9["Whole"] = "1n";
639
+ NoteLength9["WholeTriplet"] = "1t";
640
+ NoteLength9["WholeDot"] = "1.";
641
+ NoteLength9["Whole2Dots"] = "1..";
642
+ NoteLength9["Whole12Dots"] = "1..";
643
+ NoteLength9["Whole3Dots"] = "1...";
644
+ NoteLength9["Whole4Dots"] = "1....";
645
+ NoteLength9["Whole5Dots"] = "1.....";
646
+ NoteLength9["Whole6Dots"] = "1......";
647
+ NoteLength9["Half"] = "2n";
648
+ NoteLength9["HalfTriplet"] = "2t";
649
+ NoteLength9["HalfDot"] = "2.";
650
+ NoteLength9["Half2Dots"] = "2..";
651
+ NoteLength9["Half3Dots"] = "2...";
652
+ NoteLength9["Half4Dots"] = "2....";
653
+ NoteLength9["Half5Dots"] = "2.....";
654
+ NoteLength9["Quarter"] = "4n";
655
+ NoteLength9["QuarterTriplet"] = "4t";
656
+ NoteLength9["QuarterDot"] = "4.";
657
+ NoteLength9["Quarter2Dots"] = "4..";
658
+ NoteLength9["Quarter3Dots"] = "4...";
659
+ NoteLength9["Quarter4Dots"] = "4....";
660
+ NoteLength9["Eighth"] = "8n";
661
+ NoteLength9["EighthTriplet"] = "8t";
662
+ NoteLength9["EighthDot"] = "8.";
663
+ NoteLength9["Eighth2Dots"] = "8..";
664
+ NoteLength9["Eighth3Dots"] = "8...";
665
+ NoteLength9["Sixteenth"] = "16n";
666
+ NoteLength9["SixteenthTriplet"] = "16t";
667
+ NoteLength9["SixteenthDot"] = "16.";
668
+ NoteLength9["Sixteenth2Dots"] = "16..";
669
+ NoteLength9["ThirtySecond"] = "32n";
670
+ NoteLength9["ThirtySecondTriplet"] = "32t";
671
+ NoteLength9["ThirtySecondDot"] = "32.";
672
+ NoteLength9["SixtyFourth"] = "64n";
673
+ NoteLength9["SixtyFourthTriplet"] = "64t";
674
+ return NoteLength9;
673
675
  })(NoteLength || {});
674
676
  function validateNoteLength(noteLength) {
675
677
  if (import_ts_utils_lib2.Utils.Is.isEnumValue(noteLength, NoteLength)) {
@@ -876,13 +878,13 @@ __publicField(_RhythmProps, "NoteSymbolMap", /* @__PURE__ */ new Map([[1, "\u{1D
876
878
  __publicField(_RhythmProps, "cache", /* @__PURE__ */ new Map());
877
879
  var RhythmProps = _RhythmProps;
878
880
 
879
- // src/score/engine/renderer.ts
881
+ // src/score/engine/render-context.ts
880
882
  var HilightStaffPosRectColor = "#55cc55";
881
883
  var HilightObjectRectColor = "#55cc55";
882
884
  var PlayPosIndicatorColor = "#44aa44";
883
885
  var ImageAssets = /* @__PURE__ */ new Map([
884
- [0 /* TrebleClefPng */, { src: treble_clef_default }],
885
- [1 /* BassClefPng */, { src: bass_clef_default }]
886
+ [0 /* G_Clef */, { src: G_clef_default }],
887
+ [1 /* F_Clef */, { src: F_clef_default }]
886
888
  ]);
887
889
  function staffPosEquals(a, b) {
888
890
  if (!a && !b) return true;
@@ -894,14 +896,13 @@ function objectsEquals(a, b) {
894
896
  else if (!a || !b) return false;
895
897
  else return a.length === b.length && a.every((a2, i) => a2 === b[i]);
896
898
  }
897
- var Renderer = class {
899
+ var RenderContext = class {
898
900
  constructor(mi) {
899
901
  this.mi = mi;
900
902
  __publicField(this, "devicePixelRatio");
901
903
  __publicField(this, "fontSize");
902
904
  __publicField(this, "unitSize");
903
- __publicField(this, "lineWidth");
904
- __publicField(this, "beamThickness");
905
+ __publicField(this, "_lineWidth");
905
906
  __publicField(this, "scoreEventListener");
906
907
  __publicField(this, "canvas");
907
908
  __publicField(this, "ctx");
@@ -921,8 +922,7 @@ var Renderer = class {
921
922
  this.devicePixelRatio = window.devicePixelRatio;
922
923
  this.fontSize = import_ts_utils_lib3.Device.FontSize * DocumentSettings.DocumentScale * this.devicePixelRatio;
923
924
  this.unitSize = this.fontSize * 0.3;
924
- this.lineWidth = this.unitSize * 0.2;
925
- this.beamThickness = this.unitSize * 0.8;
925
+ this._lineWidth = this.unitSize * 0.2;
926
926
  ImageAssets.forEach((asset) => {
927
927
  if (asset.finished !== true) {
928
928
  const img = new Image();
@@ -968,10 +968,10 @@ var Renderer = class {
968
968
  let prevMDoc = this.mdoc;
969
969
  this.mdoc = mdoc;
970
970
  if (prevMDoc) {
971
- prevMDoc.getMusicObject().setRenderer(void 0);
971
+ prevMDoc.getMusicObject().setRenderContext(void 0);
972
972
  }
973
973
  if (mdoc) {
974
- mdoc.getMusicObject().setRenderer(this);
974
+ mdoc.getMusicObject().setRenderContext(this);
975
975
  }
976
976
  }
977
977
  setCanvas(canvas) {
@@ -1107,22 +1107,24 @@ var Renderer = class {
1107
1107
  }
1108
1108
  }
1109
1109
  draw() {
1110
- let { ctx, doc } = this;
1111
- if (!ctx || !doc) {
1112
- return;
1110
+ try {
1111
+ let { doc } = this;
1112
+ if (doc) {
1113
+ doc.layout();
1114
+ this.updateCanvasSize();
1115
+ this.clearCanvas();
1116
+ this.drawHilightStaffPosRect();
1117
+ this.drawHilightObjectRect();
1118
+ this.drawPlayCursor();
1119
+ doc.drawContent();
1120
+ }
1121
+ } catch (err) {
1122
+ console.error("Render failed!", err);
1113
1123
  }
1114
- doc.layout();
1115
- this.updateCanvasSize();
1116
- this.clearCanvas();
1117
- this.drawHilightStaffPosRect();
1118
- this.drawHilightObjectRect();
1119
- this.drawPlayCursor();
1120
- doc.drawContent();
1121
1124
  }
1122
1125
  drawHilightStaffPosRect() {
1123
- let ctx = this.getCanvasContext();
1124
1126
  let { mousePos, hilightedStaffPos, unitSize } = this;
1125
- if (!ctx || !hilightedStaffPos) {
1127
+ if (!hilightedStaffPos) {
1126
1128
  return;
1127
1129
  }
1128
1130
  let { scoreRow, diatonicId } = hilightedStaffPos;
@@ -1130,26 +1132,25 @@ var Renderer = class {
1130
1132
  if (!staff) {
1131
1133
  return;
1132
1134
  }
1133
- ctx.fillStyle = HilightStaffPosRectColor;
1134
- ctx.fillRect(0, staff.getDiatonicIdY(diatonicId) - unitSize, ctx.canvas.width, 2 * unitSize);
1135
+ this.fillColor(HilightStaffPosRectColor);
1136
+ this.fillRect(staff.row.getRect().left, staff.getDiatonicIdY(diatonicId) - unitSize, staff.row.getRect().width, 2 * unitSize);
1135
1137
  if (mousePos !== void 0) {
1136
1138
  this.drawLedgerLines(staff, diatonicId, mousePos.x);
1137
1139
  }
1138
1140
  }
1139
1141
  drawHilightObjectRect() {
1140
- let ctx = this.getCanvasContext();
1141
1142
  let { hilightedObj } = this;
1142
- if (!ctx || !hilightedObj) {
1143
+ if (!hilightedObj) {
1143
1144
  return;
1144
1145
  }
1145
1146
  let rect = hilightedObj.getRect();
1146
- ctx.strokeStyle = HilightObjectRectColor;
1147
- ctx.strokeRect(rect.left, rect.top, rect.width, rect.height);
1147
+ this.lineColor(HilightObjectRectColor);
1148
+ this.strokeRect(rect.left, rect.top, rect.width, rect.height);
1148
1149
  }
1149
1150
  drawPlayCursor() {
1150
- let { cursorRect: r, lineWidth } = this;
1151
+ let { cursorRect: r } = this;
1151
1152
  if (r) {
1152
- this.drawLine(r.centerX, r.top, r.centerX, r.bottom, PlayPosIndicatorColor, lineWidth * 2);
1153
+ this.color(PlayPosIndicatorColor).lineWidth(2).strokeLine(r.centerX, r.top, r.centerX, r.bottom);
1153
1154
  }
1154
1155
  }
1155
1156
  txFromScreenCoord(screenCoord) {
@@ -1158,75 +1159,13 @@ var Renderer = class {
1158
1159
  txToScreenCoord(coord) {
1159
1160
  return coord.div(this.devicePixelRatio);
1160
1161
  }
1161
- getCanvasContext() {
1162
- return this.ctx;
1163
- }
1164
1162
  clearCanvas() {
1165
- let ctx = this.getCanvasContext();
1166
- if (ctx) {
1167
- ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
1168
- }
1169
- }
1170
- getTextWidth(text, font) {
1171
- let ctx = this.getCanvasContext();
1172
- if (ctx) {
1173
- let savedFont = ctx.font;
1174
- ctx.font = font;
1175
- let metrics = ctx.measureText(text);
1176
- ctx.font = savedFont;
1177
- return metrics.width;
1178
- } else {
1179
- return import_ts_utils_lib3.Utils.Dom.getCanvasTextWidth(text, font);
1180
- }
1163
+ var _a;
1164
+ (_a = this.ctx) == null ? void 0 : _a.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
1181
1165
  }
1182
1166
  drawDebugRect(r) {
1183
- if (!DebugSettings.DrawDebugRects) {
1184
- return;
1185
- }
1186
- let ctx = this.getCanvasContext();
1187
- if (ctx) {
1188
- ctx.lineWidth = 1;
1189
- ctx.strokeStyle = "red";
1190
- ctx.beginPath();
1191
- ctx.rect(r.left, r.top, r.right - r.left, r.bottom - r.top);
1192
- ctx.stroke();
1193
- }
1194
- }
1195
- fillCircle(x, y, radius, color) {
1196
- let ctx = this.getCanvasContext();
1197
- if (ctx) {
1198
- if (color !== void 0) {
1199
- ctx.fillStyle = color;
1200
- }
1201
- ctx.beginPath();
1202
- ctx.arc(x, y, radius, 0, 2 * Math.PI);
1203
- ctx.fill();
1204
- }
1205
- }
1206
- drawLine(startX, startY, endX, endY, color, lineWidth) {
1207
- let ctx = this.getCanvasContext();
1208
- if (ctx) {
1209
- ctx.strokeStyle = color != null ? color : "black";
1210
- ctx.lineWidth = lineWidth != null ? lineWidth : this.lineWidth;
1211
- ctx.beginPath();
1212
- ctx.moveTo(startX, startY);
1213
- ctx.lineTo(endX, endY);
1214
- ctx.stroke();
1215
- }
1216
- }
1217
- drawPartialLine(startX, startY, endX, endY, startT, endT, color, lineWidth) {
1218
- let ctx = this.getCanvasContext();
1219
- if (ctx) {
1220
- let x1 = startX + (endX - startX) * startT;
1221
- let y1 = startY + (endY - startY) * startT;
1222
- let x2 = startX + (endX - startX) * endT;
1223
- let y2 = startY + (endY - startY) * endT;
1224
- ctx.strokeStyle = color != null ? color : "black";
1225
- ctx.lineWidth = lineWidth != null ? lineWidth : this.lineWidth;
1226
- ctx.beginPath();
1227
- ctx.moveTo(x1, y1);
1228
- ctx.lineTo(x2, y2);
1229
- ctx.stroke();
1167
+ if (DebugSettings.DrawDebugRects) {
1168
+ this.color("red").lineWidth(1).strokeRect(r.left, r.top, r.width, r.height);
1230
1169
  }
1231
1170
  }
1232
1171
  drawLedgerLines(staff, diatonicId, x) {
@@ -1236,14 +1175,14 @@ var Renderer = class {
1236
1175
  for (let lineDiatonicId = staff.topLineDiatonicId + 2; lineDiatonicId <= diatonicId; lineDiatonicId += 2) {
1237
1176
  if (staff.containsDiatonicId(lineDiatonicId)) {
1238
1177
  let y = staff.getDiatonicIdY(lineDiatonicId);
1239
- this.drawLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
1178
+ this.strokeLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
1240
1179
  }
1241
1180
  }
1242
1181
  } else if (diatonicId <= staff.bottomLineDiatonicId - 2) {
1243
1182
  for (let lineDiatonicId = staff.bottomLineDiatonicId - 2; lineDiatonicId >= diatonicId; lineDiatonicId -= 2) {
1244
1183
  if (staff.containsDiatonicId(lineDiatonicId)) {
1245
1184
  let y = staff.getDiatonicIdY(lineDiatonicId);
1246
- this.drawLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
1185
+ this.strokeLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
1247
1186
  }
1248
1187
  }
1249
1188
  }
@@ -1279,44 +1218,38 @@ var Renderer = class {
1279
1218
  }
1280
1219
  return new DivRect(-leftw, 0, rightw, -toph, 0, bottomh);
1281
1220
  }
1282
- drawRest(restSize, x, y, color) {
1283
- let ctx = this.getCanvasContext();
1284
- if (!ctx) {
1285
- return;
1286
- }
1287
- let { unitSize, lineWidth } = this;
1221
+ drawRest(restSize, x, y) {
1222
+ let { unitSize } = this;
1288
1223
  let { flagCount } = NoteLengthProps.get(validateNoteLength(restSize + "n"));
1289
- ctx.strokeStyle = ctx.fillStyle = color;
1290
- ctx.lineWidth = lineWidth;
1291
1224
  if (NoteLengthProps.equals(restSize, "1n" /* Whole */)) {
1292
- ctx.fillRect(x - unitSize, y, unitSize * 2, unitSize);
1225
+ this.fillRect(x - unitSize, y, unitSize * 2, unitSize);
1293
1226
  } else if (NoteLengthProps.equals(restSize, "2n" /* Half */)) {
1294
- ctx.fillRect(x - unitSize, y - unitSize, unitSize * 2, unitSize);
1227
+ this.fillRect(x - unitSize, y - unitSize, unitSize * 2, unitSize);
1295
1228
  } else if (NoteLengthProps.equals(restSize, "4n" /* Quarter */)) {
1296
- ctx.beginPath();
1297
- ctx.moveTo(x - unitSize * 0.6, y - unitSize * 3.2);
1298
- ctx.lineTo(x + unitSize * 0.7, y - unitSize * 1.5);
1299
- ctx.quadraticCurveTo(
1229
+ this.beginPath();
1230
+ this.moveTo(x - unitSize * 0.6, y - unitSize * 3.2);
1231
+ this.lineTo(x + unitSize * 0.7, y - unitSize * 1.5);
1232
+ this.quadraticCurveTo(
1300
1233
  x - unitSize * 0.8,
1301
1234
  y - unitSize * 0.5,
1302
1235
  x + unitSize * 1,
1303
1236
  y + unitSize * 1.5
1304
1237
  );
1305
- ctx.lineTo(x - unitSize * 1, y - unitSize * 0.75);
1306
- ctx.quadraticCurveTo(
1238
+ this.lineTo(x - unitSize * 1, y - unitSize * 0.75);
1239
+ this.quadraticCurveTo(
1307
1240
  x + unitSize * 0.2,
1308
1241
  y - unitSize * 1.5,
1309
1242
  x - unitSize * 0.6,
1310
1243
  y - unitSize * 3.2
1311
1244
  );
1312
- ctx.moveTo(x + unitSize * 1, y + unitSize * 1.5);
1313
- ctx.quadraticCurveTo(
1245
+ this.moveTo(x + unitSize * 1, y + unitSize * 1.5);
1246
+ this.quadraticCurveTo(
1314
1247
  x - unitSize * 0.8,
1315
1248
  y + unitSize * 1,
1316
1249
  x - unitSize * 0.2,
1317
1250
  y + unitSize * 2.8
1318
1251
  );
1319
- ctx.bezierCurveTo(
1252
+ this.bezierCurveTo(
1320
1253
  x - unitSize * 1.8,
1321
1254
  y + unitSize * 1.5,
1322
1255
  x - unitSize * 0.6,
@@ -1324,46 +1257,42 @@ var Renderer = class {
1324
1257
  x + unitSize * 0.9,
1325
1258
  y + unitSize * 1.5
1326
1259
  );
1327
- ctx.fill();
1328
- ctx.stroke();
1260
+ this.fill();
1261
+ this.stroke();
1329
1262
  } else if (flagCount > 0) {
1330
1263
  let adj = 1 - flagCount % 2;
1331
1264
  let fx = (p) => x + (-p * 0.25 + 0.5) * unitSize;
1332
1265
  let fy = (p) => y + (p + adj) * unitSize;
1333
- ctx.beginPath();
1334
- ctx.moveTo(fx(1 + flagCount), fy(1 + flagCount));
1335
- ctx.lineTo(fx(-0.5 - flagCount), fy(-0.5 - flagCount));
1336
- ctx.stroke();
1266
+ this.beginPath();
1267
+ this.moveTo(fx(1 + flagCount), fy(1 + flagCount));
1268
+ this.lineTo(fx(-0.5 - flagCount), fy(-0.5 - flagCount));
1269
+ this.stroke();
1337
1270
  for (let i = 0; i < flagCount; i++) {
1338
1271
  let t = flagCount - i * 2;
1339
- ctx.beginPath();
1340
- ctx.moveTo(fx(t - 2.5), fy(t - 2.5));
1341
- ctx.quadraticCurveTo(
1272
+ this.beginPath();
1273
+ this.moveTo(fx(t - 2.5), fy(t - 2.5));
1274
+ this.quadraticCurveTo(
1342
1275
  fx(t - 0.5) + unitSize * 0.25,
1343
1276
  fy(t - 1.5),
1344
1277
  fx(t - 1.5) - unitSize * 1.5,
1345
1278
  fy(t - 1.5)
1346
1279
  );
1347
- ctx.stroke();
1348
- ctx.beginPath();
1349
- ctx.arc(fx(t - 2) - unitSize * 1.5, fy(t - 2), unitSize * 0.5, 0, Math.PI * 2);
1350
- ctx.fill();
1280
+ this.stroke();
1281
+ this.beginPath();
1282
+ this.arc(fx(t - 2) - unitSize * 1.5, fy(t - 2), unitSize * 0.5, 0, Math.PI * 2);
1283
+ this.fill();
1351
1284
  }
1352
1285
  }
1353
1286
  }
1354
1287
  drawFlag(rect, dir) {
1355
- let ctx = this.getCanvasContext();
1356
- if (!ctx) {
1357
- return;
1358
- }
1359
1288
  let left = rect.left;
1360
1289
  let right = rect.right;
1361
1290
  let width = right - left;
1362
1291
  let top = dir === "up" ? rect.top : rect.bottom;
1363
1292
  let bottom = dir === "up" ? rect.bottom : rect.top;
1364
- ctx.beginPath();
1365
- ctx.moveTo(left, top);
1366
- ctx.bezierCurveTo(
1293
+ this.beginPath();
1294
+ this.moveTo(left, top);
1295
+ this.bezierCurveTo(
1367
1296
  left,
1368
1297
  top * 0.75 + bottom * 0.25,
1369
1298
  left + width * 1.5,
@@ -1371,16 +1300,178 @@ var Renderer = class {
1371
1300
  left + width * 0.5,
1372
1301
  bottom
1373
1302
  );
1374
- ctx.stroke();
1303
+ this.stroke();
1304
+ }
1305
+ color(color) {
1306
+ if (this.ctx) this.ctx.strokeStyle = this.ctx.fillStyle = color;
1307
+ return this;
1308
+ }
1309
+ lineColor(color) {
1310
+ if (this.ctx) this.ctx.strokeStyle = color;
1311
+ return this;
1312
+ }
1313
+ fillColor(color) {
1314
+ if (this.ctx) this.ctx.fillStyle = color;
1315
+ return this;
1316
+ }
1317
+ lineWidth(lineWidth) {
1318
+ if (this.ctx) this.ctx.lineWidth = this._lineWidth * (lineWidth != null ? lineWidth : 1);
1319
+ return this;
1320
+ }
1321
+ font(font) {
1322
+ if (this.ctx) this.ctx.font = font;
1323
+ return this;
1324
+ }
1325
+ beginPath() {
1326
+ if (this.ctx) this.ctx.beginPath();
1327
+ return this;
1328
+ }
1329
+ stroke() {
1330
+ if (this.ctx) this.ctx.stroke();
1331
+ return this;
1332
+ }
1333
+ fill() {
1334
+ if (this.ctx) this.ctx.fill();
1335
+ return this;
1336
+ }
1337
+ moveTo(x, y) {
1338
+ if (this.ctx) this.ctx.moveTo(x, y);
1339
+ return this;
1340
+ }
1341
+ lineTo(x, y) {
1342
+ if (this.ctx) this.ctx.lineTo(x, y);
1343
+ return this;
1344
+ }
1345
+ bezierCurveTo(x1, y1, x2, y2, x3, y3) {
1346
+ if (this.ctx) this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
1347
+ return this;
1348
+ }
1349
+ quadraticCurveTo(x1, y1, x2, y2) {
1350
+ if (this.ctx) this.ctx.quadraticCurveTo(x1, y1, x2, y2);
1351
+ return this;
1352
+ }
1353
+ fillRect(x, y, w, h) {
1354
+ if (this.ctx) this.ctx.fillRect(x, y, w, h);
1355
+ return this;
1356
+ }
1357
+ setLineDash(pattern) {
1358
+ if (this.ctx) this.ctx.setLineDash(pattern);
1359
+ return this;
1360
+ }
1361
+ drawImage(img, x, y, w, h) {
1362
+ if (this.ctx) this.ctx.drawImage(img, x, y, w, h);
1363
+ return this;
1364
+ }
1365
+ ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle) {
1366
+ if (this.ctx) this.ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle);
1367
+ return this;
1368
+ }
1369
+ clip() {
1370
+ if (this.ctx) this.ctx.clip();
1371
+ return this;
1372
+ }
1373
+ save() {
1374
+ if (this.ctx) this.ctx.save();
1375
+ return this;
1376
+ }
1377
+ restore() {
1378
+ if (this.ctx) this.ctx.restore();
1379
+ return this;
1380
+ }
1381
+ rect(x, y, w, h) {
1382
+ if (this.ctx) this.ctx.rect(x, y, w, h);
1383
+ return this;
1384
+ }
1385
+ scale(x, y) {
1386
+ if (this.ctx) this.ctx.scale(x, y);
1387
+ return this;
1388
+ }
1389
+ strokeRect(x, y, w, h) {
1390
+ if (this.ctx) this.ctx.strokeRect(x, y, w, h);
1391
+ return this;
1392
+ }
1393
+ fillText(text, x, y) {
1394
+ if (this.ctx) this.ctx.fillText(text, x, y);
1395
+ return this;
1396
+ }
1397
+ getTextWidth(text, font) {
1398
+ if (this.ctx) {
1399
+ let savedFont = this.ctx.font;
1400
+ this.ctx.font = font;
1401
+ let metrics = this.ctx.measureText(text);
1402
+ this.ctx.font = savedFont;
1403
+ return metrics.width;
1404
+ } else {
1405
+ return import_ts_utils_lib3.Utils.Dom.getCanvasTextWidth(text, font);
1406
+ }
1407
+ }
1408
+ arc(x, y, radius, startRadians, endRadians) {
1409
+ var _a;
1410
+ (_a = this.ctx) == null ? void 0 : _a.arc(x, y, radius, startRadians, endRadians);
1411
+ }
1412
+ fillCircle(x, y, radius) {
1413
+ if (this.ctx) {
1414
+ this.ctx.beginPath();
1415
+ this.ctx.arc(x, y, radius, 0, 2 * Math.PI);
1416
+ this.ctx.fill();
1417
+ }
1418
+ }
1419
+ strokeLine(startX, startY, endX, endY) {
1420
+ if (this.ctx) {
1421
+ this.ctx.beginPath();
1422
+ this.ctx.moveTo(startX, startY);
1423
+ this.ctx.lineTo(endX, endY);
1424
+ this.ctx.stroke();
1425
+ }
1426
+ }
1427
+ strokePartialLine(startX, startY, endX, endY, startT, endT) {
1428
+ let x1 = startX + (endX - startX) * startT;
1429
+ let y1 = startY + (endY - startY) * startT;
1430
+ let x2 = startX + (endX - startX) * endT;
1431
+ let y2 = startY + (endY - startY) * endT;
1432
+ if (this.ctx) {
1433
+ this.ctx.beginPath();
1434
+ this.ctx.moveTo(x1, y1);
1435
+ this.ctx.lineTo(x2, y2);
1436
+ this.ctx.stroke();
1437
+ }
1438
+ }
1439
+ drawBrace(rect, side) {
1440
+ if (this.ctx) {
1441
+ let { left, right, width, top, bottom, centerY } = rect;
1442
+ if (side === "right") {
1443
+ [left, right, width] = [right, left, -width];
1444
+ }
1445
+ this.ctx.beginPath();
1446
+ this.ctx.moveTo(right, top);
1447
+ this.ctx.bezierCurveTo(
1448
+ left + width * 0.1,
1449
+ top,
1450
+ left + width * 0.8,
1451
+ centerY,
1452
+ left,
1453
+ centerY
1454
+ );
1455
+ this.ctx.moveTo(right, bottom);
1456
+ this.ctx.bezierCurveTo(
1457
+ left + width * 0.1,
1458
+ bottom,
1459
+ left + width * 0.8,
1460
+ centerY,
1461
+ left,
1462
+ centerY
1463
+ );
1464
+ this.ctx.stroke();
1465
+ }
1375
1466
  }
1376
1467
  };
1377
1468
 
1378
1469
  // src/score/engine/obj-staff-and-tab.ts
1379
1470
  var import_core16 = require("@tspro/web-music-score/core");
1380
- var import_ts_utils_lib14 = require("@tspro/ts-utils-lib");
1471
+ var import_ts_utils_lib15 = require("@tspro/ts-utils-lib");
1381
1472
 
1382
1473
  // src/score/engine/obj-measure.ts
1383
- var import_ts_utils_lib13 = require("@tspro/ts-utils-lib");
1474
+ var import_ts_utils_lib14 = require("@tspro/ts-utils-lib");
1384
1475
  var import_theory9 = require("@tspro/web-music-score/theory");
1385
1476
  var import_theory10 = require("@tspro/web-music-score/theory");
1386
1477
 
@@ -1426,9 +1517,9 @@ var ObjImage = class extends MusicObject {
1426
1517
  pick(x, y) {
1427
1518
  return this.rect.contains(x, y) ? [this] : [];
1428
1519
  }
1429
- layout(renderer) {
1520
+ layout(ctx) {
1430
1521
  let { anchorX, anchorY, image, imageScale } = this;
1431
- let { unitSize } = renderer;
1522
+ let { unitSize } = ctx;
1432
1523
  try {
1433
1524
  let w = image.naturalWidth * imageScale * unitSize;
1434
1525
  let h = image.naturalHeight * imageScale * unitSize;
@@ -1440,17 +1531,10 @@ var ObjImage = class extends MusicObject {
1440
1531
  offset(dx, dy) {
1441
1532
  this.rect.offsetInPlace(dx, dy);
1442
1533
  }
1443
- draw(renderer) {
1444
- let ctx = renderer.getCanvasContext();
1445
- if (!ctx) {
1446
- return;
1447
- }
1534
+ draw(ctx) {
1448
1535
  let r = this.rect;
1449
- renderer.drawDebugRect(r);
1450
- try {
1451
- ctx.drawImage(this.image, r.centerX - r.leftw, r.centerY - r.toph, r.width, r.height);
1452
- } catch (err) {
1453
- }
1536
+ ctx.drawDebugRect(r);
1537
+ ctx.drawImage(this.image, r.centerX - r.leftw, r.centerY - r.toph, r.width, r.height);
1454
1538
  }
1455
1539
  };
1456
1540
 
@@ -1471,8 +1555,8 @@ var ObjAccidental = class extends MusicObject {
1471
1555
  pick(x, y) {
1472
1556
  return this.rect.contains(x, y) ? [this] : [];
1473
1557
  }
1474
- layout(renderer) {
1475
- let { unitSize } = renderer;
1558
+ layout(ctx) {
1559
+ let { unitSize } = ctx;
1476
1560
  switch (this.accidental) {
1477
1561
  case -2:
1478
1562
  this.rect = DivRect.createSections(unitSize * 1.25, unitSize * 1.25, unitSize * 4, unitSize * 1.2);
@@ -1496,34 +1580,23 @@ var ObjAccidental = class extends MusicObject {
1496
1580
  offset(dx, dy) {
1497
1581
  this.rect.offsetInPlace(dx, dy);
1498
1582
  }
1499
- draw(renderer) {
1500
- let ctx = renderer.getCanvasContext();
1501
- if (!ctx) {
1502
- return;
1503
- }
1504
- renderer.drawDebugRect(this.rect);
1505
- let { unitSize, lineWidth } = renderer;
1583
+ draw(ctx) {
1584
+ ctx.drawDebugRect(this.rect);
1585
+ let { unitSize } = ctx;
1506
1586
  let { accidental } = this;
1507
1587
  let x = this.rect.centerX;
1508
1588
  let y = this.rect.centerY;
1509
- ctx.strokeStyle = ctx.fillStyle = this.color;
1510
- function draw_b(x2, y2) {
1511
- if (ctx) {
1512
- ctx.lineWidth = lineWidth;
1513
- ctx.beginPath();
1514
- ctx.moveTo(x2 - unitSize * 0.75, y2 - unitSize * 4);
1515
- ctx.lineTo(x2 - unitSize * 0.75, y2 + unitSize * 1.1);
1516
- ctx.bezierCurveTo(
1517
- x2 + unitSize * 0.75,
1518
- y2 - unitSize * 0,
1519
- x2 + unitSize * 0.75,
1520
- y2 - unitSize * 2.2,
1521
- x2 - unitSize * 0.75,
1522
- y2 - unitSize * 0.5
1523
- );
1524
- ctx.stroke();
1525
- }
1526
- }
1589
+ ctx.color(this.color);
1590
+ const draw_b = (x2, y2) => {
1591
+ ctx.lineWidth(1).beginPath().moveTo(x2 - unitSize * 0.75, y2 - unitSize * 4).lineTo(x2 - unitSize * 0.75, y2 + unitSize * 1.1).bezierCurveTo(
1592
+ x2 + unitSize * 0.75,
1593
+ y2 - unitSize * 0,
1594
+ x2 + unitSize * 0.75,
1595
+ y2 - unitSize * 2.2,
1596
+ x2 - unitSize * 0.75,
1597
+ y2 - unitSize * 0.5
1598
+ ).stroke();
1599
+ };
1527
1600
  if (accidental === -2) {
1528
1601
  draw_b(x - unitSize * 0.5, y);
1529
1602
  draw_b(x + unitSize * 0.5, y);
@@ -1531,47 +1604,11 @@ var ObjAccidental = class extends MusicObject {
1531
1604
  draw_b(x, y);
1532
1605
  }
1533
1606
  if (accidental === 0) {
1534
- ctx.beginPath();
1535
- ctx.lineWidth = lineWidth;
1536
- ctx.moveTo(x - unitSize * 0.5, y - unitSize * 2.2);
1537
- ctx.lineTo(x - unitSize * 0.5, y + unitSize * 1);
1538
- ctx.moveTo(x + unitSize * 0.5, y + unitSize * 2.2);
1539
- ctx.lineTo(x + unitSize * 0.5, y - unitSize * 1);
1540
- ctx.stroke();
1541
- ctx.beginPath();
1542
- ctx.lineWidth = lineWidth * 2;
1543
- ctx.moveTo(x - unitSize * 0.5, y + unitSize * 1);
1544
- ctx.lineTo(x + unitSize * 0.5, y + unitSize * 0.6);
1545
- ctx.moveTo(x + unitSize * 0.5, y - unitSize * 1);
1546
- ctx.lineTo(x - unitSize * 0.5, y - unitSize * 0.6);
1547
- ctx.stroke();
1607
+ ctx.beginPath().lineWidth(1).moveTo(x - unitSize * 0.5, y - unitSize * 2.2).lineTo(x - unitSize * 0.5, y + unitSize * 1).moveTo(x + unitSize * 0.5, y + unitSize * 2.2).lineTo(x + unitSize * 0.5, y - unitSize * 1).stroke().beginPath().lineWidth(2).moveTo(x - unitSize * 0.5, y + unitSize * 1).lineTo(x + unitSize * 0.5, y + unitSize * 0.6).moveTo(x + unitSize * 0.5, y - unitSize * 1).lineTo(x - unitSize * 0.5, y - unitSize * 0.6).stroke();
1548
1608
  } else if (accidental === 1) {
1549
- ctx.lineWidth = lineWidth;
1550
- ctx.beginPath();
1551
- ctx.moveTo(x - unitSize * 0.3, y - unitSize * 1.6);
1552
- ctx.lineTo(x - unitSize * 0.3, y + unitSize * 2);
1553
- ctx.moveTo(x + unitSize * 0.3, y - unitSize * 2);
1554
- ctx.lineTo(x + unitSize * 0.3, y + unitSize * 1.6);
1555
- ctx.stroke();
1556
- ctx.lineWidth = lineWidth * 2;
1557
- ctx.beginPath();
1558
- ctx.moveTo(x - unitSize * 0.75, y - unitSize * 0.5);
1559
- ctx.lineTo(x + unitSize * 0.75, y - unitSize * 0.9);
1560
- ctx.moveTo(x - unitSize * 0.75, y + unitSize * 0.9);
1561
- ctx.lineTo(x + unitSize * 0.75, y + unitSize * 0.5);
1562
- ctx.stroke();
1609
+ ctx.lineWidth(1).beginPath().moveTo(x - unitSize * 0.3, y - unitSize * 1.6).lineTo(x - unitSize * 0.3, y + unitSize * 2).moveTo(x + unitSize * 0.3, y - unitSize * 2).lineTo(x + unitSize * 0.3, y + unitSize * 1.6).stroke().lineWidth(2).beginPath().moveTo(x - unitSize * 0.75, y - unitSize * 0.5).lineTo(x + unitSize * 0.75, y - unitSize * 0.9).moveTo(x - unitSize * 0.75, y + unitSize * 0.9).lineTo(x + unitSize * 0.75, y + unitSize * 0.5).stroke();
1563
1610
  } else if (accidental === 2) {
1564
- ctx.lineWidth = lineWidth;
1565
- ctx.beginPath();
1566
- ctx.moveTo(x - unitSize * 0.75, y - unitSize * 0.75);
1567
- ctx.lineTo(x + unitSize * 0.75, y + unitSize * 0.75);
1568
- ctx.moveTo(x - unitSize * 0.75, y + unitSize * 0.75);
1569
- ctx.lineTo(x + unitSize * 0.75, y - unitSize * 0.75);
1570
- ctx.stroke();
1571
- ctx.fillRect(x - unitSize * 1, y - unitSize * 1, unitSize * 0.7, unitSize * 0.7);
1572
- ctx.fillRect(x + unitSize * 0.3, y - unitSize * 1, unitSize * 0.7, unitSize * 0.7);
1573
- ctx.fillRect(x - unitSize * 1, y + unitSize * 0.3, unitSize * 0.7, unitSize * 0.7);
1574
- ctx.fillRect(x + unitSize * 0.3, y + unitSize * 0.3, unitSize * 0.7, unitSize * 0.7);
1611
+ ctx.lineWidth(1).beginPath().moveTo(x - unitSize * 0.75, y - unitSize * 0.75).lineTo(x + unitSize * 0.75, y + unitSize * 0.75).moveTo(x - unitSize * 0.75, y + unitSize * 0.75).lineTo(x + unitSize * 0.75, y - unitSize * 0.75).stroke().fillRect(x - unitSize * 1, y - unitSize * 1, unitSize * 0.7, unitSize * 0.7).fillRect(x + unitSize * 0.3, y - unitSize * 1, unitSize * 0.7, unitSize * 0.7).fillRect(x - unitSize * 1, y + unitSize * 0.3, unitSize * 0.7, unitSize * 0.7).fillRect(x + unitSize * 0.3, y + unitSize * 0.3, unitSize * 0.7, unitSize * 0.7);
1575
1612
  }
1576
1613
  }
1577
1614
  };
@@ -1637,13 +1674,13 @@ var ObjText = class extends MusicObject {
1637
1674
  pick(x, y) {
1638
1675
  return this.rect.contains(x, y) ? [this] : [];
1639
1676
  }
1640
- layout(renderer) {
1677
+ layout(ctx) {
1641
1678
  let { scale, anchorX, anchorY, bold, italic } = this;
1642
- let fontSize = renderer.fontSize * scale;
1679
+ let fontSize = ctx.fontSize * scale;
1643
1680
  this.font = (italic ? "italic " : "") + (bold ? "bold " : "") + fontSize + "px Times New Roman";
1644
- this.lineWidths = this.textLines.map((text) => renderer.getTextWidth(text, this.font));
1681
+ this.lineWidths = this.textLines.map((text) => ctx.getTextWidth(text, this.font));
1645
1682
  this.lineHeight = fontSize;
1646
- let p = this.padding * renderer.unitSize;
1683
+ let p = this.padding * ctx.unitSize;
1647
1684
  let w = p + Math.max(...this.lineWidths) + p;
1648
1685
  let h = p + this.lineHeight * this.textLines.length + p;
1649
1686
  if (this.boxed === "square" || this.boxed === "circle") {
@@ -1654,19 +1691,14 @@ var ObjText = class extends MusicObject {
1654
1691
  offset(dx, dy) {
1655
1692
  this.rect.offsetInPlace(dx, dy);
1656
1693
  }
1657
- draw(renderer) {
1658
- const ctx = renderer.getCanvasContext();
1659
- if (!ctx) {
1660
- return;
1661
- }
1662
- renderer.drawDebugRect(this.rect);
1663
- ctx.lineWidth = renderer.lineWidth;
1664
- ctx.strokeStyle = ctx.fillStyle = this.color;
1665
- ctx.font = this.font;
1694
+ draw(ctx) {
1695
+ var _a;
1696
+ ctx.drawDebugRect(this.rect);
1697
+ ctx.lineWidth(1).font(this.font);
1666
1698
  let { rect, padding, lineHeight, lineWidths, anchorX, anchorY, italic } = this;
1667
1699
  if (this.bgcolor !== void 0) {
1668
1700
  ctx.save();
1669
- ctx.fillStyle = this.bgcolor;
1701
+ ctx.fillColor((_a = this.bgcolor) != null ? _a : "black");
1670
1702
  ctx.beginPath();
1671
1703
  ctx.fillRect(rect.left, rect.top, rect.width, rect.height);
1672
1704
  ctx.fill();
@@ -1674,10 +1706,11 @@ var ObjText = class extends MusicObject {
1674
1706
  }
1675
1707
  let lineCount = this.textLines.length;
1676
1708
  let textHeight = lineCount * lineHeight;
1677
- let fixY = -lineHeight * (italic ? 0.25 : 0.175);
1678
- let p = padding * renderer.unitSize;
1709
+ let fixY = -lineHeight * (italic ? 0.25 : 0.2);
1710
+ let p = padding * ctx.unitSize;
1679
1711
  let centerX = (rect.left + p) * (1 - anchorX) + (rect.right - p) * anchorX;
1680
1712
  let centerY = (rect.top + p) * (1 - anchorY) + (rect.bottom - p) * anchorY;
1713
+ ctx.color(this.color);
1681
1714
  this.textLines.forEach((textLine, i) => {
1682
1715
  let x = centerX - lineWidths[i] * anchorX;
1683
1716
  let y = centerY - textHeight * anchorY + lineHeight * (i + 1) + fixY;
@@ -1723,9 +1756,9 @@ var ObjStaffSignature = class extends MusicObject {
1723
1756
  getMusicInterface() {
1724
1757
  return this.mi;
1725
1758
  }
1726
- updateClefImage(renderer, showClef) {
1759
+ updateClefImage(ctx, showClef) {
1727
1760
  if (showClef) {
1728
- let img = renderer.getImageAsset(this.staff.clefImageAsset);
1761
+ let img = ctx.getImageAsset(this.staff.clefImageAsset);
1729
1762
  this.clefImage = img ? new ObjImage(this, img, 0, 0.5, 0.1) : void 0;
1730
1763
  this.eightBelowClef = this.clefImage && this.staff.isOctaveDown ? new ObjText(this, "8", 0.5, 0) : void 0;
1731
1764
  } else {
@@ -1856,29 +1889,29 @@ var ObjStaffSignature = class extends MusicObject {
1856
1889
  }
1857
1890
  return [this];
1858
1891
  }
1859
- layout(renderer) {
1892
+ layout(ctx) {
1860
1893
  var _a, _b, _c, _d, _e, _f;
1861
- let { unitSize } = renderer;
1894
+ let { unitSize } = ctx;
1862
1895
  let { staff } = this;
1863
1896
  let paddingX = unitSize;
1864
1897
  let x = 0;
1865
1898
  this.rect = new DivRect();
1866
1899
  if (this.clefImage) {
1867
1900
  x += paddingX;
1868
- this.clefImage.layout(renderer);
1901
+ this.clefImage.layout(ctx);
1869
1902
  this.clefImage.offset(x, staff.getDiatonicIdY(staff.clefLineDiatonicId));
1870
1903
  this.rect.expandInPlace(this.clefImage.getRect());
1871
1904
  x = this.rect.right;
1872
1905
  if (this.eightBelowClef) {
1873
1906
  let r = this.clefImage.getRect();
1874
- this.eightBelowClef.layout(renderer);
1907
+ this.eightBelowClef.layout(ctx);
1875
1908
  this.eightBelowClef.offset(r.left + r.width / 2, Math.max(r.centerY + r.height * 0.3, staff.getBottomLineY()));
1876
1909
  this.rect.expandInPlace(this.eightBelowClef.getRect());
1877
1910
  }
1878
1911
  }
1879
1912
  if (this.measureNumber) {
1880
- this.measureNumber.layout(renderer);
1881
- let y = this.clefImage ? this.clefImage.getRect().top : staff.getTopLineY();
1913
+ this.measureNumber.layout(ctx);
1914
+ let y = Math.min(staff.getTopLineY(), this.clefImage ? this.clefImage.getRect().top : staff.getTopLineY());
1882
1915
  this.measureNumber.offset(0, y);
1883
1916
  this.rect.expandInPlace(this.measureNumber.getRect());
1884
1917
  x = Math.max(x, this.rect.right);
@@ -1886,7 +1919,7 @@ var ObjStaffSignature = class extends MusicObject {
1886
1919
  if (this.ksNeutralizeAccidentals.length > 0) {
1887
1920
  x += paddingX;
1888
1921
  this.ksNeutralizeAccidentals.forEach((objAcc) => {
1889
- objAcc.layout(renderer);
1922
+ objAcc.layout(ctx);
1890
1923
  objAcc.offset(x + objAcc.getRect().leftw, staff.getDiatonicIdY(objAcc.diatonicId));
1891
1924
  this.rect.expandInPlace(objAcc.getRect());
1892
1925
  x = this.rect.right;
@@ -1895,15 +1928,15 @@ var ObjStaffSignature = class extends MusicObject {
1895
1928
  if (this.ksNewAccidentals) {
1896
1929
  x += paddingX;
1897
1930
  this.ksNewAccidentals.forEach((objAcc) => {
1898
- objAcc.layout(renderer);
1931
+ objAcc.layout(ctx);
1899
1932
  objAcc.offset(x + objAcc.getRect().leftw, staff.getDiatonicIdY(objAcc.diatonicId));
1900
1933
  this.rect.expandInPlace(objAcc.getRect());
1901
1934
  x = this.rect.right;
1902
1935
  });
1903
1936
  }
1904
1937
  let right = x;
1905
- (_a = this.beatCountText) == null ? void 0 : _a.layout(renderer);
1906
- (_b = this.beatSizeText) == null ? void 0 : _b.layout(renderer);
1938
+ (_a = this.beatCountText) == null ? void 0 : _a.layout(ctx);
1939
+ (_b = this.beatSizeText) == null ? void 0 : _b.layout(ctx);
1907
1940
  let tsWidth = Math.max((_d = (_c = this.beatCountText) == null ? void 0 : _c.getRect().width) != null ? _d : 0, (_f = (_e = this.beatSizeText) == null ? void 0 : _e.getRect().width) != null ? _f : 0);
1908
1941
  if (this.beatCountText) {
1909
1942
  this.beatCountText.offset(x + tsWidth / 2 + paddingX, staff.getDiatonicIdY(staff.middleLineDiatonicId + 2));
@@ -1922,7 +1955,7 @@ var ObjStaffSignature = class extends MusicObject {
1922
1955
  ...this.ksNeutralizeAccidentals.map((o) => o.getRect().top),
1923
1956
  ...this.ksNewAccidentals.map((o) => o.getRect().top)
1924
1957
  );
1925
- this.tempoText.layout(renderer);
1958
+ this.tempoText.layout(ctx);
1926
1959
  this.tempoText.offset(x, tempoBottom);
1927
1960
  this.rect.expandInPlace(this.tempoText.getRect());
1928
1961
  }
@@ -1940,16 +1973,16 @@ var ObjStaffSignature = class extends MusicObject {
1940
1973
  (_f = this.tempoText) == null ? void 0 : _f.offset(dx, dy);
1941
1974
  this.rect.offsetInPlace(dx, dy);
1942
1975
  }
1943
- draw(renderer) {
1976
+ draw(ctx) {
1944
1977
  var _a, _b, _c, _d, _e, _f;
1945
- (_a = this.clefImage) == null ? void 0 : _a.draw(renderer);
1946
- (_b = this.eightBelowClef) == null ? void 0 : _b.draw(renderer);
1947
- (_c = this.measureNumber) == null ? void 0 : _c.draw(renderer);
1948
- this.ksNeutralizeAccidentals.forEach((acc) => acc.draw(renderer));
1949
- this.ksNewAccidentals.forEach((acc) => acc.draw(renderer));
1950
- (_d = this.beatCountText) == null ? void 0 : _d.draw(renderer);
1951
- (_e = this.beatSizeText) == null ? void 0 : _e.draw(renderer);
1952
- (_f = this.tempoText) == null ? void 0 : _f.draw(renderer);
1978
+ (_a = this.clefImage) == null ? void 0 : _a.draw(ctx);
1979
+ (_b = this.eightBelowClef) == null ? void 0 : _b.draw(ctx);
1980
+ (_c = this.measureNumber) == null ? void 0 : _c.draw(ctx);
1981
+ this.ksNeutralizeAccidentals.forEach((acc) => acc.draw(ctx));
1982
+ this.ksNewAccidentals.forEach((acc) => acc.draw(ctx));
1983
+ (_d = this.beatCountText) == null ? void 0 : _d.draw(ctx);
1984
+ (_e = this.beatSizeText) == null ? void 0 : _e.draw(ctx);
1985
+ (_f = this.tempoText) == null ? void 0 : _f.draw(ctx);
1953
1986
  }
1954
1987
  };
1955
1988
  var ObjTabSignature = class extends MusicObject {
@@ -2024,22 +2057,22 @@ var ObjTabSignature = class extends MusicObject {
2024
2057
  }
2025
2058
  return [this];
2026
2059
  }
2027
- layout(renderer) {
2060
+ layout(ctx) {
2028
2061
  var _a, _b, _c, _d, _e, _f;
2029
- let { unitSize } = renderer;
2062
+ let { unitSize } = ctx;
2030
2063
  let { tab } = this;
2031
2064
  let paddingX = unitSize;
2032
2065
  let x = 0;
2033
2066
  let topLineY = tab.getTopLineY();
2034
2067
  this.rect = new DivRect();
2035
2068
  if (this.measureNumber) {
2036
- this.measureNumber.layout(renderer);
2069
+ this.measureNumber.layout(ctx);
2037
2070
  this.measureNumber.offset(0, topLineY);
2038
2071
  this.rect.expandInPlace(this.measureNumber.getRect());
2039
2072
  x = Math.max(x, this.rect.right);
2040
2073
  }
2041
- (_a = this.beatCountText) == null ? void 0 : _a.layout(renderer);
2042
- (_b = this.beatSizeText) == null ? void 0 : _b.layout(renderer);
2074
+ (_a = this.beatCountText) == null ? void 0 : _a.layout(ctx);
2075
+ (_b = this.beatSizeText) == null ? void 0 : _b.layout(ctx);
2043
2076
  let tsWidth = Math.max((_d = (_c = this.beatCountText) == null ? void 0 : _c.getRect().width) != null ? _d : 0, (_f = (_e = this.beatSizeText) == null ? void 0 : _e.getRect().width) != null ? _f : 0);
2044
2077
  if (this.beatCountText) {
2045
2078
  this.beatCountText.offset(0 + tsWidth / 2 + paddingX, tab.getRect().centerY - this.beatCountText.getRect().bottomh);
@@ -2050,7 +2083,7 @@ var ObjTabSignature = class extends MusicObject {
2050
2083
  this.rect.expandInPlace(this.beatSizeText.getRect());
2051
2084
  }
2052
2085
  if (this.tempoText) {
2053
- this.tempoText.layout(renderer);
2086
+ this.tempoText.layout(ctx);
2054
2087
  this.tempoText.offset(x + unitSize * 2, topLineY);
2055
2088
  this.rect.expandInPlace(this.tempoText.getRect());
2056
2089
  }
@@ -2064,12 +2097,12 @@ var ObjTabSignature = class extends MusicObject {
2064
2097
  (_d = this.tempoText) == null ? void 0 : _d.offset(dx, dy);
2065
2098
  this.rect.offsetInPlace(dx, dy);
2066
2099
  }
2067
- draw(renderer) {
2100
+ draw(ctx) {
2068
2101
  var _a, _b, _c, _d;
2069
- (_a = this.measureNumber) == null ? void 0 : _a.draw(renderer);
2070
- (_b = this.beatCountText) == null ? void 0 : _b.draw(renderer);
2071
- (_c = this.beatSizeText) == null ? void 0 : _c.draw(renderer);
2072
- (_d = this.tempoText) == null ? void 0 : _d.draw(renderer);
2102
+ (_a = this.measureNumber) == null ? void 0 : _a.draw(ctx);
2103
+ (_b = this.beatCountText) == null ? void 0 : _b.draw(ctx);
2104
+ (_c = this.beatSizeText) == null ? void 0 : _c.draw(ctx);
2105
+ (_d = this.tempoText) == null ? void 0 : _d.draw(ctx);
2073
2106
  }
2074
2107
  };
2075
2108
 
@@ -2102,8 +2135,8 @@ var ObjArpeggio = class extends MusicObject {
2102
2135
  pick(x, y) {
2103
2136
  return this.rect.contains(x, y) ? [this] : [];
2104
2137
  }
2105
- layout(renderer) {
2106
- let { unitSize } = renderer;
2138
+ layout(ctx) {
2139
+ let { unitSize } = ctx;
2107
2140
  this.topArrowHeight = this.arpeggioDir === "up" /* Up */ ? unitSize : 0;
2108
2141
  this.bottomArrowHeight = this.arpeggioDir === "down" /* Down */ ? unitSize : 0;
2109
2142
  let top = this.line.getTopLineY();
@@ -2117,16 +2150,11 @@ var ObjArpeggio = class extends MusicObject {
2117
2150
  offset(dx, dy) {
2118
2151
  this.rect.offsetInPlace(dx, dy);
2119
2152
  }
2120
- draw(renderer) {
2121
- let ctx = renderer.getCanvasContext();
2122
- if (!ctx) {
2123
- return;
2124
- }
2125
- let { lineWidth } = renderer;
2153
+ draw(ctx) {
2126
2154
  let { rect, topArrowHeight, bottomArrowHeight } = this;
2127
- renderer.drawDebugRect(this.rect);
2128
- ctx.strokeStyle = ctx.fillStyle = this.color;
2129
- ctx.lineWidth = lineWidth * 2;
2155
+ ctx.drawDebugRect(this.rect);
2156
+ ctx.color(this.color);
2157
+ ctx.lineWidth(2);
2130
2158
  ctx.beginPath();
2131
2159
  for (let i = 0, y = rect.top + topArrowHeight; i < this.numCycles; i++, y += this.cycleHeight) {
2132
2160
  ctx.moveTo(rect.centerX, y);
@@ -2193,40 +2221,33 @@ var ObjStaffRest = class extends MusicObject {
2193
2221
  this.dotRects.forEach((r) => this.rect.expandInPlace(r));
2194
2222
  }
2195
2223
  };
2196
- var ObjRest = class extends MusicObject {
2224
+ var _ObjRest = class _ObjRest extends MusicObject {
2197
2225
  constructor(col, voiceId, noteLength, options, tupletRatio) {
2198
- var _a, _b;
2226
+ var _a, _b, _c, _d;
2199
2227
  super(col);
2200
2228
  this.col = col;
2201
2229
  this.voiceId = voiceId;
2202
- __publicField(this, "ownStemDir");
2203
- __publicField(this, "ownDiatonicId");
2230
+ this.options = options;
2204
2231
  __publicField(this, "color");
2205
2232
  __publicField(this, "hide");
2206
2233
  __publicField(this, "oldStyleTriplet");
2207
2234
  __publicField(this, "rhythmProps");
2235
+ __publicField(this, "setDiatonicId");
2236
+ __publicField(this, "runningDiatonicId");
2237
+ // Staff position of rest.
2238
+ __publicField(this, "runningStemDir");
2208
2239
  __publicField(this, "beamGroup");
2209
2240
  __publicField(this, "staffObjects", []);
2210
2241
  __publicField(this, "mi");
2211
- let diatonicId = getDiatonicIdFromStaffPos(options == null ? void 0 : options.staffPos);
2212
- if (diatonicId !== void 0) {
2213
- let hasStaff = this.row.hasStaff;
2214
- let staff2 = this.row.getStaff(diatonicId);
2215
- if (hasStaff && !staff2) {
2216
- throw new import_core6.MusicError(import_core6.MusicErrorType.Score, "Rest staffPos is out of staff boundaries!");
2217
- }
2218
- }
2219
- this.ownDiatonicId = this.measure.updateOwnDiatonicId(voiceId, diatonicId);
2220
- this.ownStemDir = this.measure.updateOwnStemDir(
2221
- this
2222
- /*, options?.stem*/
2223
- );
2224
- let staff = this.row.getStaff(this.ownDiatonicId);
2225
- if (staff && staff.isSpace(this.ownDiatonicId)) {
2226
- this.ownDiatonicId += this.ownDiatonicId >= staff.middleLineDiatonicId ? 1 : -1;
2227
- }
2228
- this.color = (_a = options == null ? void 0 : options.color) != null ? _a : "black";
2229
- this.hide = (_b = options == null ? void 0 : options.hide) != null ? _b : false;
2242
+ this.setDiatonicId = (_b = getDiatonicIdFromStaffPos((_a = this.options) == null ? void 0 : _a.staffPos)) != null ? _b : _ObjRest.UndefinedDiatonicId;
2243
+ let staves = this.row.getStaves().filter((staff) => staff.containsVoiceId(this.voiceId));
2244
+ if (this.setDiatonicId !== _ObjRest.UndefinedDiatonicId && staves.length > 0 && staves[0].isSpace(this.setDiatonicId)) {
2245
+ this.setDiatonicId += this.setDiatonicId >= staves[0].middleLineDiatonicId ? 1 : -1;
2246
+ }
2247
+ this.runningDiatonicId = this.setDiatonicId;
2248
+ this.runningStemDir = "up" /* Up */;
2249
+ this.color = (_c = options == null ? void 0 : options.color) != null ? _c : "black";
2250
+ this.hide = (_d = options == null ? void 0 : options.hide) != null ? _d : false;
2230
2251
  this.oldStyleTriplet = tupletRatio === void 0 && ((options == null ? void 0 : options.triplet) === true || import_theory3.NoteLengthProps.get(noteLength).isTriplet);
2231
2252
  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;
2232
2253
  this.rhythmProps = import_theory3.RhythmProps.get(noteLength, dotCount, (tupletRatio != null ? tupletRatio : this.oldStyleTriplet) ? import_theory3.Tuplet.Triplet : void 0);
@@ -2247,8 +2268,27 @@ var ObjRest = class extends MusicObject {
2247
2268
  get noteLength() {
2248
2269
  return this.rhythmProps.noteLength;
2249
2270
  }
2271
+ getDiatonicId(staff) {
2272
+ if (this.runningDiatonicId === _ObjRest.UndefinedDiatonicId) {
2273
+ if (staff) {
2274
+ if (import_theory3.NoteLengthProps.equals(this.noteLength, "1n")) {
2275
+ return staff.middleLineDiatonicId + 2;
2276
+ } else {
2277
+ return staff.middleLineDiatonicId;
2278
+ }
2279
+ } else {
2280
+ return import_theory3.Note.getNote("G4").diatonicId;
2281
+ }
2282
+ } else {
2283
+ return this.runningDiatonicId;
2284
+ }
2285
+ }
2250
2286
  get stemDir() {
2251
- return this.beamGroup ? this.beamGroup.stemDir : this.ownStemDir;
2287
+ return this.runningStemDir;
2288
+ }
2289
+ updateRunningArguments(diatonicId, stemDir, stringNumbers) {
2290
+ this.runningDiatonicId = diatonicId;
2291
+ this.runningStemDir = stemDir;
2252
2292
  }
2253
2293
  getStaticObjects(line) {
2254
2294
  let staticObjects = [];
@@ -2320,28 +2360,28 @@ var ObjRest = class extends MusicObject {
2320
2360
  }
2321
2361
  updateAccidentalState(accState) {
2322
2362
  }
2323
- layout(renderer, accState) {
2363
+ layout(ctx, accState) {
2324
2364
  this.requestRectUpdate();
2325
2365
  this.staffObjects.length = 0;
2326
2366
  if (this.hide) {
2327
2367
  return;
2328
2368
  }
2329
- let { unitSize } = renderer;
2330
- let { ownDiatonicId } = this;
2369
+ let { unitSize } = ctx;
2331
2370
  let { noteSize, dotCount } = this.rhythmProps;
2332
2371
  this.row.getStaves().forEach((staff) => {
2333
- if (!staff.containsDiatonicId(ownDiatonicId) || !staff.containsVoiceId(this.voiceId)) {
2372
+ let diatonicId = this.getDiatonicId(staff);
2373
+ if (!staff.containsDiatonicId(diatonicId) || !staff.containsVoiceId(this.voiceId)) {
2334
2374
  return;
2335
2375
  }
2336
2376
  let obj = new ObjStaffRest(staff, this);
2337
- obj.restRect = renderer.getRestRect(noteSize);
2377
+ obj.restRect = ctx.getRestRect(noteSize);
2338
2378
  for (let i = 0; i < dotCount; i++) {
2339
2379
  let dotWidth = DocumentSettings.DotSize * unitSize;
2340
2380
  let dotX = obj.restRect.rightw + (DocumentSettings.RestDotSpace + DocumentSettings.DotSize * unitSize) + i * DocumentSettings.DotSize * unitSize * 1.5;
2341
2381
  let dotY = this.getRestDotVerticalDisplacement(noteSize) * unitSize;
2342
2382
  obj.dotRects.push(DivRect.createCentered(dotX, dotY, dotWidth, dotWidth));
2343
2383
  }
2344
- obj.offset(0, staff.getDiatonicIdY(ownDiatonicId));
2384
+ obj.offset(0, staff.getDiatonicIdY(diatonicId));
2345
2385
  this.staffObjects.push(obj);
2346
2386
  });
2347
2387
  }
@@ -2361,48 +2401,41 @@ var ObjRest = class extends MusicObject {
2361
2401
  this.staffObjects.forEach((s) => s.offset(dx, 0));
2362
2402
  this.requestRectUpdate();
2363
2403
  }
2364
- draw(renderer) {
2365
- let ctx = renderer.getCanvasContext();
2366
- if (!ctx || this.staffObjects.length === 0) {
2404
+ draw(ctx) {
2405
+ if (this.staffObjects.length === 0) {
2367
2406
  return;
2368
2407
  }
2369
- renderer.drawDebugRect(this.getRect());
2370
- let { lineWidth } = renderer;
2371
- let { color } = this;
2408
+ ctx.drawDebugRect(this.getRect());
2372
2409
  let { noteSize } = this.rhythmProps;
2373
- ctx.strokeStyle = ctx.fillStyle = color;
2374
- ctx.lineWidth = lineWidth;
2410
+ ctx.color(this.color).lineWidth(1);
2375
2411
  this.staffObjects.forEach((obj) => {
2376
2412
  let { dotRects, restRect } = obj;
2377
2413
  let x = restRect.centerX;
2378
2414
  let y = restRect.centerY;
2379
- renderer.drawRest(noteSize, x, y, color);
2380
- dotRects.forEach((r) => {
2381
- renderer.fillCircle(r.centerX, r.centerY, r.width / 2);
2382
- });
2415
+ ctx.drawRest(noteSize, x, y);
2416
+ dotRects.forEach((r) => ctx.fillCircle(r.centerX, r.centerY, r.width / 2));
2383
2417
  });
2384
2418
  }
2385
2419
  };
2420
+ __publicField(_ObjRest, "UndefinedDiatonicId", Infinity);
2421
+ var ObjRest = _ObjRest;
2386
2422
 
2387
2423
  // src/score/engine/obj-note-group.ts
2388
2424
  var import_ts_utils_lib4 = require("@tspro/ts-utils-lib");
2389
2425
  var import_theory4 = require("@tspro/web-music-score/theory");
2390
2426
  var import_core7 = require("@tspro/web-music-score/core");
2391
- function getStem(stem) {
2392
- return import_ts_utils_lib4.Utils.Is.isEnumValue(stem, Stem) ? stem : void 0;
2393
- }
2394
2427
  function getArpeggio(a) {
2395
2428
  return import_ts_utils_lib4.Utils.Is.isEnumValue(a, Arpeggio) ? a : a === true ? "up" /* Up */ : void 0;
2396
2429
  }
2397
- function sortNoteStringData(notes, strings) {
2430
+ function sortNotesAndStrings(notes, strings) {
2398
2431
  let stringArr = import_ts_utils_lib4.Utils.Arr.isArray(strings) ? strings : strings !== void 0 ? [strings] : [];
2399
2432
  let noteStringData = notes.map((note, i) => {
2400
2433
  return { note, string: stringArr[i] };
2401
2434
  });
2402
2435
  noteStringData = import_ts_utils_lib4.Utils.Arr.removeDuplicatesCmp(noteStringData, (a, b) => import_theory4.Note.equals(a.note, b.note)).sort((a, b) => import_theory4.Note.compareFunc(a.note, b.note));
2403
2436
  return {
2404
- notes: noteStringData.map((e) => e.note),
2405
- strings: noteStringData.every((e) => e.string === void 0) ? void 0 : noteStringData.map((e) => e.string)
2437
+ sortedNotes: noteStringData.map((e) => e.note),
2438
+ sortedStrings: noteStringData.every((e) => e.string === void 0) ? void 0 : noteStringData.map((e) => e.string)
2406
2439
  };
2407
2440
  }
2408
2441
  var ObjStaffNoteGroup = class extends MusicObject {
@@ -2474,7 +2507,6 @@ var ObjTabNoteGroup = class extends MusicObject {
2474
2507
  this.noteGroup = noteGroup;
2475
2508
  __publicField(this, "fretNumbers", []);
2476
2509
  __publicField(this, "mi");
2477
- tab.addObject(this);
2478
2510
  this.mi = new MTabNoteGroup(this);
2479
2511
  }
2480
2512
  getMusicInterface() {
@@ -2500,12 +2532,13 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2500
2532
  this.col = col;
2501
2533
  this.voiceId = voiceId;
2502
2534
  this.notes = notes;
2503
- __publicField(this, "minDiatonicId");
2504
- __publicField(this, "maxDiatonicId");
2505
- __publicField(this, "ownDiatonicId");
2535
+ this.options = options;
2536
+ __publicField(this, "setDiatonicId");
2537
+ __publicField(this, "setStringsNumbers");
2538
+ __publicField(this, "runningDiatonicId");
2506
2539
  // Average diatonicId of notes.
2507
- __publicField(this, "ownStemDir");
2508
- __publicField(this, "ownString");
2540
+ __publicField(this, "runningStemDir");
2541
+ __publicField(this, "runningStringNumbers");
2509
2542
  __publicField(this, "color");
2510
2543
  __publicField(this, "staccato");
2511
2544
  __publicField(this, "diamond");
@@ -2523,13 +2556,13 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2523
2556
  if (!import_ts_utils_lib4.Utils.Is.isIntegerGte(notes.length, 1)) {
2524
2557
  throw new import_core7.MusicError(import_core7.MusicErrorType.Score, "Cannot create note group object because notes array is empty.");
2525
2558
  }
2526
- let noteStringData = sortNoteStringData(notes, options == null ? void 0 : options.string);
2527
- this.notes = noteStringData.notes;
2528
- this.minDiatonicId = this.notes[0].diatonicId;
2529
- this.maxDiatonicId = this.notes[this.notes.length - 1].diatonicId;
2530
- this.ownDiatonicId = this.measure.updateOwnDiatonicId(voiceId, Math.round((this.minDiatonicId + this.maxDiatonicId) / 2));
2531
- this.ownStemDir = this.measure.updateOwnStemDir(this, getStem(options == null ? void 0 : options.stem));
2532
- this.ownString = this.measure.updateOwnString(this, noteStringData.strings);
2559
+ let { sortedNotes, sortedStrings } = sortNotesAndStrings(notes, options == null ? void 0 : options.string);
2560
+ this.notes = sortedNotes;
2561
+ this.setStringsNumbers = sortedStrings;
2562
+ this.setDiatonicId = Math.round((this.minDiatonicId + this.maxDiatonicId) / 2);
2563
+ this.runningDiatonicId = this.setDiatonicId;
2564
+ this.runningStemDir = "up" /* Up */;
2565
+ this.runningStringNumbers = [];
2533
2566
  this.color = (_a = options == null ? void 0 : options.color) != null ? _a : "black";
2534
2567
  this.staccato = (_b = options == null ? void 0 : options.staccato) != null ? _b : false;
2535
2568
  this.diamond = (_c = options == null ? void 0 : options.diamond) != null ? _c : false;
@@ -2551,11 +2584,20 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2551
2584
  get row() {
2552
2585
  return this.col.row;
2553
2586
  }
2587
+ get minDiatonicId() {
2588
+ return this.notes[0].diatonicId;
2589
+ }
2590
+ get maxDiatonicId() {
2591
+ return this.notes[this.notes.length - 1].diatonicId;
2592
+ }
2593
+ getDiatonicId(staff) {
2594
+ return this.runningDiatonicId;
2595
+ }
2554
2596
  get stemDir() {
2555
- return this.beamGroup ? this.beamGroup.stemDir : this.ownStemDir;
2597
+ return this.runningStemDir;
2556
2598
  }
2557
2599
  enableConnective(line) {
2558
- return line.containsVoiceId(this.voiceId) && (line instanceof ObjTab || line.containsDiatonicId(this.ownDiatonicId));
2600
+ return line.containsVoiceId(this.voiceId) && (line instanceof ObjTab || line.containsDiatonicId(this.runningDiatonicId));
2559
2601
  }
2560
2602
  startConnective(connectiveProps) {
2561
2603
  if (!this.row.hasStaff && connectiveProps.connective === "tie" /* Tie */) {
@@ -2566,6 +2608,11 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2566
2608
  this.startConnnectives.push(connectiveProps);
2567
2609
  this.doc.addConnectiveProps(connectiveProps);
2568
2610
  }
2611
+ updateRunningArguments(diatonicId, stemDir, stringNumbers) {
2612
+ this.runningDiatonicId = diatonicId === ObjRest.UndefinedDiatonicId ? this.setDiatonicId : diatonicId;
2613
+ this.runningStemDir = stemDir;
2614
+ this.runningStringNumbers = stringNumbers;
2615
+ }
2569
2616
  getStaticObjects(line) {
2570
2617
  let staticObjects = [];
2571
2618
  this.staffObjects.forEach((obj) => {
@@ -2605,12 +2652,12 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2605
2652
  return this.notes[0];
2606
2653
  }
2607
2654
  getConnectiveAnchorPoint(connectiveProps, line, noteIndex, noteAnchor, side) {
2655
+ var _a;
2608
2656
  if (line instanceof ObjStaff) {
2609
- let staff = line;
2610
2657
  if (noteIndex < 0 || noteIndex >= this.notes.length) {
2611
2658
  throw new import_core7.MusicError(import_core7.MusicErrorType.Score, "Invalid noteIndex: " + noteIndex);
2612
2659
  }
2613
- let obj = this.staffObjects.find((obj2) => obj2.staff === staff);
2660
+ let obj = this.staffObjects.find((obj2) => obj2.staff === line);
2614
2661
  if (!obj || noteIndex < 0 || noteIndex >= obj.noteHeadRects.length) {
2615
2662
  let r = this.getRect();
2616
2663
  return { x: r.centerX, y: r.bottom };
@@ -2658,11 +2705,9 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2658
2705
  default:
2659
2706
  throw new import_core7.MusicError(import_core7.MusicErrorType.Score, "Invalid noteAnchor: " + noteAnchor);
2660
2707
  }
2661
- } else {
2662
- let tab = line;
2663
- let obj = this.tabObjects.find((obj2) => obj2.tab === tab);
2664
- let fretNumber = obj == null ? void 0 : obj.fretNumbers[noteIndex];
2665
- if (!obj || !fretNumber) {
2708
+ } else if (line instanceof ObjTab) {
2709
+ let fretNumber = (_a = this.tabObjects.find((obj) => obj.tab === line)) == null ? void 0 : _a.fretNumbers[noteIndex];
2710
+ if (!fretNumber) {
2666
2711
  return { x: 0, y: 0 };
2667
2712
  }
2668
2713
  let r = fretNumber.getRect();
@@ -2670,26 +2715,29 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2670
2715
  let y;
2671
2716
  let s = 0.9;
2672
2717
  if (connectiveProps.connective === "slide" /* Slide */) {
2673
- let leftFretNumber = connectiveProps.noteGroups[0].getFretNumber(obj, 0);
2674
- let rightFretNumber = connectiveProps.noteGroups[1].getFretNumber(obj, 0);
2718
+ let leftFretNumber = connectiveProps.noteGroups[0].getFretNumber(line, 0);
2719
+ let rightFretNumber = connectiveProps.noteGroups[1].getFretNumber(line, 0);
2675
2720
  let slideUp = leftFretNumber === void 0 || rightFretNumber === void 0 || leftFretNumber <= rightFretNumber;
2676
2721
  if (side === "left") {
2677
- y = slideUp ? r.centerY + r.bottomh * s : r.centerY - r.toph * s;
2722
+ y = (slideUp ? r.centerY + r.bottomh : r.centerY - r.toph) * s;
2678
2723
  } else {
2679
- y = slideUp ? r.centerY - r.toph * s : r.centerY + r.bottomh * s;
2724
+ y = (slideUp ? r.centerY - r.toph : r.centerY + r.bottomh) * s;
2680
2725
  }
2681
2726
  } else {
2682
2727
  y = r.centerY + r.bottomh * s;
2683
2728
  }
2684
2729
  return { x, y };
2730
+ } else {
2731
+ return { x: 0, y: 0 };
2685
2732
  }
2686
2733
  }
2687
2734
  getFretNumberString(noteIndex) {
2688
- return this.ownString[noteIndex];
2735
+ return this.runningStringNumbers[noteIndex];
2689
2736
  }
2690
- getFretNumber(tabObj, noteIndex) {
2691
- let fretNumber = tabObj.fretNumbers[noteIndex];
2692
- return fretNumber === void 0 ? void 0 : +fretNumber.getText();
2737
+ getFretNumber(tab, noteIndex) {
2738
+ let tabObj = this.tabObjects.find((o) => o.tab === tab);
2739
+ let fretNumber = tabObj == null ? void 0 : tabObj.fretNumbers[noteIndex];
2740
+ return fretNumber ? parseInt(fretNumber.getText()) : void 0;
2693
2741
  }
2694
2742
  getNextNoteGroup() {
2695
2743
  let voiceNoteGroups = this.measure.getVoiceSymbols(this.voiceId).filter((s) => s instanceof _ObjNoteGroup);
@@ -2752,8 +2800,8 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2752
2800
  return { staff, x, y, stemHeight };
2753
2801
  });
2754
2802
  }
2755
- getStemHeight(renderer) {
2756
- let { unitSize } = renderer;
2803
+ getStemHeight(ctx) {
2804
+ let { unitSize } = ctx;
2757
2805
  let { flagCount, hasStem } = this.rhythmProps;
2758
2806
  if (hasStem) {
2759
2807
  let addY = this.hasBeamCount() ? DocumentSettings.BeamSeparation : DocumentSettings.FlagSeparation;
@@ -2816,9 +2864,9 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2816
2864
  }
2817
2865
  });
2818
2866
  }
2819
- layout(renderer, accState) {
2867
+ layout(ctx, accState) {
2820
2868
  this.requestRectUpdate();
2821
- let { unitSize } = renderer;
2869
+ let { unitSize } = ctx;
2822
2870
  let { row, stemDir } = this;
2823
2871
  let { dotCount, flagCount, hasStem } = this.rhythmProps;
2824
2872
  let dotWidth = DocumentSettings.DotSize * unitSize;
@@ -2826,7 +2874,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2826
2874
  let noteHeadHeight = (this.diamond ? DocumentSettings.DiamondNoteHeadSize : DocumentSettings.NoteHeadHeight) * unitSize;
2827
2875
  this.staffObjects.length = 0;
2828
2876
  row.getStaves().forEach((staff) => {
2829
- if (!staff.containsDiatonicId(this.ownDiatonicId) || !staff.containsVoiceId(this.voiceId)) {
2877
+ if (!staff.containsDiatonicId(this.runningDiatonicId) || !staff.containsVoiceId(this.voiceId)) {
2830
2878
  return;
2831
2879
  }
2832
2880
  let obj = new ObjStaffNoteGroup(staff, this);
@@ -2849,7 +2897,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2849
2897
  if (accState.needAccidental(note)) {
2850
2898
  let acc = obj.accidentals[noteIndex] = new ObjAccidental(this, note.diatonicId, note.accidental, this.color);
2851
2899
  if (acc) {
2852
- acc.layout(renderer);
2900
+ acc.layout(ctx);
2853
2901
  acc.offset(-noteHeadRect.leftw - unitSize * DocumentSettings.NoteAccSpace - acc.getRect().rightw, noteY);
2854
2902
  }
2855
2903
  noteStaff.addObject(acc);
@@ -2880,7 +2928,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2880
2928
  let bottomNoteY = obj.noteHeadRects[0].centerY;
2881
2929
  let topNoteY = obj.noteHeadRects[obj.noteHeadRects.length - 1].centerY;
2882
2930
  let stemX = stemDir === "up" /* Up */ ? noteHeadWidth / 2 : -noteHeadWidth / 2;
2883
- let stemHeight = this.getStemHeight(renderer);
2931
+ let stemHeight = this.getStemHeight(ctx);
2884
2932
  let stemTipY = stemDir === "up" /* Up */ ? topNoteY - stemHeight : bottomNoteY + stemHeight;
2885
2933
  let stemBaseY = stemDir === "up" /* Up */ ? bottomNoteY : topNoteY;
2886
2934
  if (hasStem) {
@@ -2907,20 +2955,21 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2907
2955
  }
2908
2956
  let obj = new ObjTabNoteGroup(tab, this);
2909
2957
  this.notes.forEach((note, noteIndex) => {
2910
- if (this.ownString[noteIndex] !== void 0) {
2911
- let stringId = this.ownString[noteIndex] - 1;
2912
- let fretId = note.chromaticId - tab.getTuningStrings()[stringId].chromaticId;
2958
+ let stringNumber = this.runningStringNumbers[noteIndex];
2959
+ if (import_ts_utils_lib4.Utils.Is.isIntegerBetween(stringNumber, 1, 6)) {
2960
+ let fretId = note.chromaticId - tab.getTuningStrings()[stringNumber - 1].chromaticId;
2913
2961
  let color = fretId < 0 ? "red" : "black";
2914
2962
  let fretNumber = new ObjText(this, { text: String(fretId), color, bgcolor: "white" }, 0.5, 0.5);
2915
- obj.fretNumbers.push(fretNumber);
2916
- fretNumber.layout(renderer);
2963
+ fretNumber.layout(ctx);
2917
2964
  let x = this.col.getRect().centerX;
2918
- let y = tab.getStringY(stringId);
2965
+ let y = tab.getStringY(stringNumber - 1);
2919
2966
  fretNumber.offset(x, y);
2967
+ obj.fretNumbers.push(fretNumber);
2920
2968
  }
2921
2969
  });
2922
2970
  if (obj.fretNumbers.length > 0) {
2923
2971
  this.tabObjects.push(obj);
2972
+ tab.addObject(obj);
2924
2973
  }
2925
2974
  });
2926
2975
  }
@@ -2948,19 +2997,14 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2948
2997
  this.tabObjects.forEach((obj) => obj.offset(dx, 0));
2949
2998
  this.requestRectUpdate();
2950
2999
  }
2951
- draw(renderer) {
2952
- const ctx = renderer.getCanvasContext();
2953
- if (!ctx) {
2954
- return;
2955
- }
2956
- renderer.drawDebugRect(this.getRect());
2957
- let { lineWidth } = renderer;
2958
- let { color, stemDir } = this;
3000
+ draw(ctx) {
3001
+ ctx.drawDebugRect(this.getRect());
3002
+ let { stemDir } = this;
2959
3003
  let { isSolidNoteHead } = this.rhythmProps;
2960
3004
  this.staffObjects.forEach((obj) => {
2961
- obj.accidentals.forEach((d) => d.draw(renderer));
2962
- ctx.strokeStyle = ctx.fillStyle = color;
2963
- ctx.lineWidth = lineWidth;
3005
+ obj.accidentals.forEach((d) => d.draw(ctx));
3006
+ ctx.color(this.color);
3007
+ ctx.lineWidth(1);
2964
3008
  obj.noteHeadRects.forEach((r) => {
2965
3009
  if (this.diamond) {
2966
3010
  if (isSolidNoteHead) {
@@ -2973,14 +3017,14 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2973
3017
  ctx.fill();
2974
3018
  } else {
2975
3019
  ctx.beginPath();
2976
- ctx.lineWidth = lineWidth * 2.5;
3020
+ ctx.lineWidth(2.5);
2977
3021
  ctx.moveTo(r.centerX, r.top);
2978
3022
  ctx.lineTo(r.right, r.centerY);
2979
3023
  ctx.moveTo(r.left, r.centerY);
2980
3024
  ctx.lineTo(r.centerX, r.bottom);
2981
3025
  ctx.stroke();
2982
3026
  ctx.beginPath();
2983
- ctx.lineWidth = lineWidth;
3027
+ ctx.lineWidth(1);
2984
3028
  ctx.moveTo(r.right, r.centerY);
2985
3029
  ctx.lineTo(r.centerX, r.bottom);
2986
3030
  ctx.moveTo(r.centerX, r.top);
@@ -2997,16 +3041,16 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2997
3041
  }
2998
3042
  }
2999
3043
  });
3000
- obj.dotRects.forEach((r) => renderer.fillCircle(r.centerX, r.centerY, r.width / 2));
3044
+ obj.dotRects.forEach((r) => ctx.fillCircle(r.centerX, r.centerY, r.width / 2));
3001
3045
  if (obj.stemTip && obj.stemBase) {
3002
3046
  ctx.beginPath();
3003
3047
  ctx.moveTo(obj.stemBase.centerX, obj.stemBase.centerY);
3004
3048
  ctx.lineTo(obj.stemTip.centerX, obj.stemTip.centerY);
3005
3049
  ctx.stroke();
3006
3050
  }
3007
- obj.flagRects.forEach((rect) => renderer.drawFlag(rect, stemDir === "up" /* Up */ ? "up" : "down"));
3051
+ obj.flagRects.forEach((rect) => ctx.drawFlag(rect, stemDir === "up" /* Up */ ? "up" : "down"));
3008
3052
  });
3009
- this.tabObjects.forEach((obj) => obj.fretNumbers.forEach((fn) => fn.draw(renderer)));
3053
+ this.tabObjects.forEach((obj) => obj.fretNumbers.forEach((fn) => fn.draw(ctx)));
3010
3054
  }
3011
3055
  getDotVerticalDisplacement(staff, diatonicId, stemDir) {
3012
3056
  if (staff.isLine(diatonicId)) {
@@ -3032,87 +3076,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
3032
3076
 
3033
3077
  // src/score/engine/obj-rhythm-column.ts
3034
3078
  var import_core8 = require("@tspro/web-music-score/core");
3035
-
3036
- // src/score/engine/obj-lyrics.ts
3037
3079
  var import_ts_utils_lib5 = require("@tspro/ts-utils-lib");
3038
- var LyricsContainer = class {
3039
- constructor(col, lyricsLength) {
3040
- this.col = col;
3041
- __publicField(this, "lyricsObjects", []);
3042
- __publicField(this, "rhythmProps");
3043
- this.rhythmProps = RhythmProps.get(lyricsLength);
3044
- }
3045
- addLyricsObject(lyricsObj) {
3046
- var _a;
3047
- this.lyricsObjects.push(lyricsObj);
3048
- (_a = lyricsObj.measure.getPrevLyricsObject(lyricsObj)) == null ? void 0 : _a.setNextLyricsObject(lyricsObj);
3049
- }
3050
- };
3051
- var ObjLyrics = class extends MusicObject {
3052
- constructor(col, verse, line, vpos, lyricsText, lyricsOptions) {
3053
- super(col);
3054
- this.col = col;
3055
- this.verse = verse;
3056
- this.line = line;
3057
- this.vpos = vpos;
3058
- __publicField(this, "nextLyricsObject");
3059
- __publicField(this, "color", "black");
3060
- __publicField(this, "hyphen");
3061
- __publicField(this, "text");
3062
- __publicField(this, "mi");
3063
- let halign = (lyricsOptions == null ? void 0 : lyricsOptions.align) === "left" /* Left */ ? 0 : (lyricsOptions == null ? void 0 : lyricsOptions.align) === "right" /* Right */ ? 1 : 0.5;
3064
- this.hyphen = import_ts_utils_lib5.Utils.Is.isEnumValue(lyricsOptions == null ? void 0 : lyricsOptions.hyphen, LyricsHyphen) ? lyricsOptions == null ? void 0 : lyricsOptions.hyphen : void 0;
3065
- this.text = new ObjText(this, { text: lyricsText, color: this.color, scale: 0.8 }, halign, 0);
3066
- this.rect = new DivRect();
3067
- this.mi = new MLyrics(this);
3068
- }
3069
- getMusicInterface() {
3070
- return this.mi;
3071
- }
3072
- get measure() {
3073
- return this.col.measure;
3074
- }
3075
- getText() {
3076
- return this.text.getText();
3077
- }
3078
- setNextLyricsObject(lyricsObj) {
3079
- this.nextLyricsObject = lyricsObj;
3080
- }
3081
- pick(x, y) {
3082
- return this.rect.contains(x, y) ? [this] : [];
3083
- }
3084
- layout(renderer) {
3085
- this.text.layout(renderer);
3086
- this.rect = this.text.getRect().copy();
3087
- }
3088
- offset(dx, dy) {
3089
- this.text.offset(dx, dy);
3090
- this.rect.offsetInPlace(dx, dy);
3091
- }
3092
- draw(renderer) {
3093
- var _a;
3094
- this.text.draw(renderer);
3095
- const ctx = renderer.getCanvasContext();
3096
- if (ctx && this.hyphen !== void 0) {
3097
- let l = this.getRect();
3098
- let r = (_a = this.nextLyricsObject) == null ? void 0 : _a.getRect();
3099
- let hyphenw = renderer.unitSize * 1.5;
3100
- let maxw = r ? (r.left - l.right) * 0.85 : hyphenw;
3101
- let w = this.hyphen === "-" /* Hyphen */ ? Math.min(hyphenw, maxw) : maxw;
3102
- if (w > 0) {
3103
- ctx.lineWidth = renderer.lineWidth;
3104
- ctx.strokeStyle = ctx.fillStyle = this.color;
3105
- let cx = r ? (r.left + l.right) / 2 : l.right + w / 0.85;
3106
- let cy = (l.top + l.bottom) / 2;
3107
- ctx.moveTo(cx - w / 2, cy);
3108
- ctx.lineTo(cx + w / 2, cy);
3109
- ctx.stroke();
3110
- }
3111
- }
3112
- }
3113
- };
3114
-
3115
- // src/score/engine/obj-rhythm-column.ts
3116
3080
  var noteHeadDataCompareFunc = (a, b) => {
3117
3081
  let cmp = import_theory5.Note.compareFunc(a.note, b.note);
3118
3082
  if (cmp === 0) {
@@ -3126,7 +3090,7 @@ var ObjRhythmColumn = class extends MusicObject {
3126
3090
  this.measure = measure;
3127
3091
  this.positionTicks = positionTicks;
3128
3092
  __publicField(this, "voiceSymbol", []);
3129
- __publicField(this, "lyricsContainerCache", /* @__PURE__ */ new Map());
3093
+ __publicField(this, "lyricsObject", new import_ts_utils_lib5.Map3());
3130
3094
  __publicField(this, "minDiatonicId");
3131
3095
  __publicField(this, "maxDiatonicId");
3132
3096
  __publicField(this, "staffMinDiatonicId", /* @__PURE__ */ new Map());
@@ -3236,8 +3200,11 @@ var ObjRhythmColumn = class extends MusicObject {
3236
3200
  validateVoiceId(voiceId);
3237
3201
  this.voiceSymbol[voiceId] = symbol;
3238
3202
  if (symbol instanceof ObjRest && !symbol.hide) {
3239
- this.minDiatonicId = this.minDiatonicId === void 0 ? symbol.ownDiatonicId : Math.min(this.minDiatonicId, symbol.ownDiatonicId);
3240
- this.maxDiatonicId = this.maxDiatonicId === void 0 ? symbol.ownDiatonicId : Math.max(this.maxDiatonicId, symbol.ownDiatonicId);
3203
+ this.row.getStaves().forEach((staff) => {
3204
+ let diatonicId = symbol.getDiatonicId(staff);
3205
+ this.minDiatonicId = this.minDiatonicId === void 0 ? diatonicId : Math.min(this.minDiatonicId, diatonicId);
3206
+ this.maxDiatonicId = this.maxDiatonicId === void 0 ? diatonicId : Math.max(this.maxDiatonicId, diatonicId);
3207
+ });
3241
3208
  } else if (symbol instanceof ObjNoteGroup) {
3242
3209
  this.minDiatonicId = this.minDiatonicId === void 0 ? symbol.notes[0].diatonicId : Math.min(this.minDiatonicId, symbol.notes[0].diatonicId);
3243
3210
  this.maxDiatonicId = this.maxDiatonicId === void 0 ? symbol.notes[symbol.notes.length - 1].diatonicId : Math.max(this.maxDiatonicId, symbol.notes[symbol.notes.length - 1].diatonicId);
@@ -3252,20 +3219,11 @@ var ObjRhythmColumn = class extends MusicObject {
3252
3219
  getVoiceSymbol(voiceId) {
3253
3220
  return this.voiceSymbol[voiceId];
3254
3221
  }
3255
- getLyricsContainer(verse, line, vpos, lyricsLength) {
3256
- let vposMap = this.lyricsContainerCache.get(line);
3257
- if (vposMap === void 0) {
3258
- this.lyricsContainerCache.set(line, vposMap = /* @__PURE__ */ new Map());
3259
- }
3260
- let verseMap = vposMap.get(vpos);
3261
- if (verseMap === void 0) {
3262
- vposMap.set(vpos, verseMap = /* @__PURE__ */ new Map());
3263
- }
3264
- let lyricsContainer = verseMap.get(verse);
3265
- if (lyricsContainer === void 0 && lyricsLength !== void 0) {
3266
- verseMap.set(verse, lyricsContainer = new LyricsContainer(this, (0, import_theory5.validateNoteLength)(lyricsLength)));
3267
- }
3268
- return lyricsContainer;
3222
+ getLyricsObject(verse, line, vpos) {
3223
+ return this.lyricsObject.get(verse, line, vpos);
3224
+ }
3225
+ addLyricsObject(lyricsObj) {
3226
+ this.lyricsObject.set(lyricsObj.verse, lyricsObj.line, lyricsObj.vpos, lyricsObj);
3269
3227
  }
3270
3228
  getMinWidth() {
3271
3229
  let maxNoteSize = Math.max(...this.voiceSymbol.map((s) => s.rhythmProps.noteSize));
@@ -3376,19 +3334,19 @@ var ObjRhythmColumn = class extends MusicObject {
3376
3334
  this.measure.requestLayout();
3377
3335
  }
3378
3336
  }
3379
- layout(renderer, accState) {
3337
+ layout(ctx, accState) {
3380
3338
  if (!this.needLayout) {
3381
3339
  return;
3382
3340
  }
3383
3341
  this.requestRectUpdate();
3384
3342
  this.rect = new DivRect();
3385
3343
  let { row } = this;
3386
- let { unitSize } = renderer;
3344
+ let { unitSize } = ctx;
3387
3345
  let halfMinWidth = this.getMinWidth() * unitSize / 2;
3388
3346
  let leftw = halfMinWidth;
3389
3347
  let rightw = halfMinWidth;
3390
3348
  this.voiceSymbol.forEach((symbol) => {
3391
- symbol.layout(renderer, accState);
3349
+ symbol.layout(ctx, accState);
3392
3350
  let r = symbol.getRect();
3393
3351
  leftw = Math.max(leftw, r.leftw);
3394
3352
  rightw = Math.max(rightw, r.rightw);
@@ -3397,7 +3355,7 @@ var ObjRhythmColumn = class extends MusicObject {
3397
3355
  let arpeggioWidth = 0;
3398
3356
  this.arpeggios = row.getNotationLines().map((line) => {
3399
3357
  let arpeggio = new ObjArpeggio(this, line, this.getArpeggioDir());
3400
- arpeggio.layout(renderer);
3358
+ arpeggio.layout(ctx);
3401
3359
  arpeggio.offset(-leftw - arpeggio.getRect().right, line.getRect().centerY - arpeggio.getRect().centerY);
3402
3360
  arpeggioWidth = Math.max(arpeggioWidth, arpeggio.getRect().width);
3403
3361
  line.addObject(arpeggio);
@@ -3427,8 +3385,9 @@ var ObjRhythmColumn = class extends MusicObject {
3427
3385
  minDiatonicId = minDiatonicId === void 0 ? symbol.minDiatonicId : Math.min(minDiatonicId, symbol.minDiatonicId);
3428
3386
  maxDiatonicId = maxDiatonicId === void 0 ? symbol.maxDiatonicId : Math.max(maxDiatonicId, symbol.maxDiatonicId);
3429
3387
  } else if (symbol instanceof ObjRest) {
3430
- minDiatonicId = minDiatonicId === void 0 ? symbol.ownDiatonicId : Math.min(minDiatonicId, symbol.ownDiatonicId);
3431
- maxDiatonicId = maxDiatonicId === void 0 ? symbol.ownDiatonicId : Math.max(maxDiatonicId, symbol.ownDiatonicId);
3388
+ let diatonicId = symbol.getDiatonicId(staff);
3389
+ minDiatonicId = minDiatonicId === void 0 ? diatonicId : Math.min(minDiatonicId, diatonicId);
3390
+ maxDiatonicId = maxDiatonicId === void 0 ? diatonicId : Math.max(maxDiatonicId, diatonicId);
3432
3391
  }
3433
3392
  }
3434
3393
  });
@@ -3462,23 +3421,23 @@ var ObjRhythmColumn = class extends MusicObject {
3462
3421
  this.shapeRects.forEach((r) => r.offsetInPlace(dx, dy));
3463
3422
  this.rect.offsetInPlace(dx, dy);
3464
3423
  }
3465
- draw(renderer) {
3424
+ draw(ctx) {
3466
3425
  this.row.getStaves().forEach((staff) => {
3467
3426
  let minDiatonicId = this.staffMinDiatonicId.get(staff);
3468
3427
  let maxDiatonicId = this.staffMaxDiatonicId.get(staff);
3469
3428
  if (minDiatonicId !== void 0) {
3470
- renderer.drawLedgerLines(staff, minDiatonicId, this.getRect().centerX);
3429
+ ctx.drawLedgerLines(staff, minDiatonicId, this.getRect().centerX);
3471
3430
  }
3472
3431
  if (maxDiatonicId !== void 0) {
3473
- renderer.drawLedgerLines(staff, maxDiatonicId, this.getRect().centerX);
3432
+ ctx.drawLedgerLines(staff, maxDiatonicId, this.getRect().centerX);
3474
3433
  }
3475
3434
  });
3476
3435
  this.voiceSymbol.forEach((symbol) => {
3477
3436
  if (symbol) {
3478
- symbol.draw(renderer);
3437
+ symbol.draw(ctx);
3479
3438
  }
3480
3439
  });
3481
- this.arpeggios.forEach((arpeggio) => arpeggio.draw(renderer));
3440
+ this.arpeggios.forEach((arpeggio) => arpeggio.draw(ctx));
3482
3441
  }
3483
3442
  };
3484
3443
 
@@ -3526,13 +3485,13 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3526
3485
  pick(x, y) {
3527
3486
  return this.rect.contains(x, y) ? [this] : [];
3528
3487
  }
3529
- layout(renderer) {
3488
+ layout(ctx) {
3530
3489
  switch (this.text) {
3531
3490
  case _ObjSpecialText.Coda: {
3532
3491
  let codaSym = this.components[0];
3533
3492
  let codaText = this.components[1];
3534
- codaSym.layout(renderer);
3535
- codaText.layout(renderer);
3493
+ codaSym.layout(ctx);
3494
+ codaText.layout(ctx);
3536
3495
  codaSym.offset(0, (codaText.getRect().top + codaText.getRect().bottom) / 2);
3537
3496
  codaText.offset(codaSym.getRect().right, 0);
3538
3497
  this.rect = new DivRect(
@@ -3548,8 +3507,8 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3548
3507
  case _ObjSpecialText.toCoda: {
3549
3508
  let toCodaText = this.components[0];
3550
3509
  let codaSym = this.components[1];
3551
- toCodaText.layout(renderer);
3552
- codaSym.layout(renderer);
3510
+ toCodaText.layout(ctx);
3511
+ codaSym.layout(ctx);
3553
3512
  codaSym.offset(0, (toCodaText.getRect().top + toCodaText.getRect().bottom) / 2);
3554
3513
  toCodaText.offset(codaSym.getRect().left, 0);
3555
3514
  this.rect = new DivRect(
@@ -3564,7 +3523,7 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3564
3523
  }
3565
3524
  default: {
3566
3525
  let text = this.components[0];
3567
- text.layout(renderer);
3526
+ text.layout(ctx);
3568
3527
  this.rect = text.getRect().copy();
3569
3528
  break;
3570
3529
  }
@@ -3574,9 +3533,9 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3574
3533
  this.components.forEach((c) => c.offset(dx, dy));
3575
3534
  this.rect.offsetInPlace(dx, dy);
3576
3535
  }
3577
- draw(renderer) {
3578
- renderer.drawDebugRect(this.rect);
3579
- this.components.forEach((c) => c.draw(renderer));
3536
+ draw(ctx) {
3537
+ ctx.drawDebugRect(this.rect);
3538
+ this.components.forEach((c) => c.draw(ctx));
3580
3539
  }
3581
3540
  };
3582
3541
  __publicField(_ObjSpecialText, "toCoda", "\u{1D10C} toCoda");
@@ -4143,8 +4102,8 @@ var ObjStaffTabBarLine = class extends MusicObject {
4143
4102
  super(line);
4144
4103
  this.barLine = barLine;
4145
4104
  this.line = line;
4146
- __publicField(this, "lineRects", []);
4147
- __publicField(this, "dotRects", []);
4105
+ __publicField(this, "verticalLines", []);
4106
+ __publicField(this, "dots", []);
4148
4107
  __publicField(this, "mi");
4149
4108
  line.addObject(this);
4150
4109
  this.mi = new MStaffTabBarLine(this);
@@ -4159,8 +4118,11 @@ var ObjStaffTabBarLine = class extends MusicObject {
4159
4118
  this.rect = r;
4160
4119
  }
4161
4120
  offset(dx, dy) {
4162
- this.lineRects.forEach((r) => r.offsetInPlace(dx, dy));
4163
- this.dotRects.forEach((r) => r.offsetInPlace(dx, dy));
4121
+ this.verticalLines.forEach((l) => l.left += dx);
4122
+ this.dots.forEach((d) => {
4123
+ d.x += dx;
4124
+ d.y += dy;
4125
+ });
4164
4126
  this.rect.offsetInPlace(dx, dy);
4165
4127
  }
4166
4128
  };
@@ -4169,6 +4131,7 @@ var ObjBarLine = class extends MusicObject {
4169
4131
  super(measure);
4170
4132
  this.measure = measure;
4171
4133
  __publicField(this, "staffTabObjects", []);
4134
+ __publicField(this, "staffTabObjectGroups", []);
4172
4135
  __publicField(this, "barLineType", 0 /* None */);
4173
4136
  }
4174
4137
  pick(x, y) {
@@ -4183,14 +4146,14 @@ var ObjBarLine = class extends MusicObject {
4183
4146
  }
4184
4147
  return [this];
4185
4148
  }
4186
- layout(renderer) {
4149
+ layout(ctx) {
4187
4150
  this.requestRectUpdate();
4188
4151
  this.staffTabObjects.length = 0;
4189
4152
  this.barLineType = this.solveBarLineType();
4190
- let { unitSize, lineWidth } = renderer;
4153
+ let { unitSize, _lineWidth } = ctx;
4191
4154
  let { measure, barLineType } = this;
4192
4155
  let { row } = measure;
4193
- let thinW = lineWidth;
4156
+ let thinW = _lineWidth;
4194
4157
  let thicW = 0.7 * unitSize;
4195
4158
  let spaceW = 0.7 * unitSize;
4196
4159
  let dotW = DocumentSettings.DotSize * unitSize;
@@ -4200,13 +4163,13 @@ var ObjBarLine = class extends MusicObject {
4200
4163
  let lineCenterY;
4201
4164
  let lineDotOff;
4202
4165
  let top, bottom;
4203
- const addRect = (left, width) => {
4204
- obj.lineRects.push(new DivRect(left, left + width / 2, left + width, top, 0, bottom));
4166
+ const addVerticalLine = (left, width) => {
4167
+ obj.verticalLines.push({ left, width });
4205
4168
  };
4206
- const addDots = (cx) => {
4169
+ const addDotPair = (cx) => {
4207
4170
  for (let i = -1; i <= 1; i += 2) {
4208
4171
  let y = lineCenterY + i * lineDotOff;
4209
- obj.dotRects.push(new DivRect(cx - dotRadius, cx, cx + dotRadius, y - dotRadius, y, y + dotRadius));
4172
+ obj.dots.push({ x: cx, y, r: dotRadius });
4210
4173
  }
4211
4174
  };
4212
4175
  if (line instanceof ObjStaff) {
@@ -4224,41 +4187,44 @@ var ObjBarLine = class extends MusicObject {
4224
4187
  break;
4225
4188
  case 1 /* Single */:
4226
4189
  obj.setRect(new DivRect(-thinW, 0, 0, top, 0, bottom));
4227
- addRect(-thinW, thinW);
4190
+ addVerticalLine(-thinW, thinW);
4228
4191
  break;
4229
4192
  case 2 /* Double */:
4230
4193
  obj.setRect(new DivRect(-thinW - spaceW - thinW, 0, 0, top, 0, bottom));
4231
- addRect(-thinW - spaceW - thinW, thinW);
4232
- addRect(-thinW, thinW);
4194
+ addVerticalLine(-thinW - spaceW - thinW, thinW);
4195
+ addVerticalLine(-thinW, thinW);
4233
4196
  break;
4234
4197
  case 3 /* EndSong */:
4235
4198
  obj.setRect(new DivRect(-thicW - spaceW - thinW, 0, 0, top, 0, bottom));
4236
- addRect(-thinW - spaceW - thicW, thinW);
4237
- addRect(-thicW, thicW);
4199
+ addVerticalLine(-thinW - spaceW - thicW, thinW);
4200
+ addVerticalLine(-thicW, thicW);
4238
4201
  break;
4239
4202
  case 4 /* StartRepeat */:
4240
4203
  obj.setRect(new DivRect(0, 0, thicW + spaceW + thinW + spaceW + dotW, top, 0, bottom));
4241
- addRect(0, thicW);
4242
- addRect(thicW + spaceW, thinW);
4243
- addDots(thicW + spaceW + thinW + spaceW + dotRadius);
4204
+ addVerticalLine(0, thicW);
4205
+ addVerticalLine(thicW + spaceW, thinW);
4206
+ addDotPair(thicW + spaceW + thinW + spaceW + dotRadius);
4244
4207
  break;
4245
4208
  case 5 /* EndRepeat */:
4246
4209
  obj.setRect(new DivRect(-thicW - spaceW - thinW - spaceW - dotW, 0, 0, top, 0, bottom));
4247
- addRect(-thinW - spaceW - thicW, thinW);
4248
- addRect(-thicW, thicW);
4249
- addDots(-thinW - spaceW - thicW - spaceW - dotRadius);
4210
+ addVerticalLine(-thinW - spaceW - thicW, thinW);
4211
+ addVerticalLine(-thicW, thicW);
4212
+ addDotPair(-thinW - spaceW - thicW - spaceW - dotRadius);
4250
4213
  break;
4251
4214
  case 6 /* EndStartRepeat */:
4252
4215
  obj.setRect(new DivRect(-dotW - spaceW - thinW - spaceW - thicW / 2, 0, thicW / 2 + spaceW + thinW + spaceW + dotW, top, 0, bottom));
4253
- addRect(-thicW / 2, thicW);
4254
- addRect(-thicW / 2 - spaceW - thinW, thinW);
4255
- addRect(thicW / 2 + spaceW, thinW);
4256
- addDots(-thicW / 2 - spaceW - thinW - spaceW - dotRadius);
4257
- addDots(thicW / 2 + spaceW + thinW + spaceW + dotRadius);
4216
+ addVerticalLine(-thicW / 2, thicW);
4217
+ addVerticalLine(-thicW / 2 - spaceW - thinW, thinW);
4218
+ addVerticalLine(thicW / 2 + spaceW, thinW);
4219
+ addDotPair(-thicW / 2 - spaceW - thinW - spaceW - dotRadius);
4220
+ addDotPair(thicW / 2 + spaceW + thinW + spaceW + dotRadius);
4258
4221
  break;
4259
4222
  }
4260
4223
  this.staffTabObjects.push(obj);
4261
4224
  });
4225
+ this.staffTabObjectGroups = row.getInstrumentLineGroups().map(
4226
+ (lines) => lines.map((line) => this.staffTabObjects.find((obj) => obj.line === line)).filter((obj) => obj !== void 0)
4227
+ );
4262
4228
  }
4263
4229
  updateRect() {
4264
4230
  if (this.staffTabObjects.length > 0) {
@@ -4274,16 +4240,19 @@ var ObjBarLine = class extends MusicObject {
4274
4240
  this.staffTabObjects.forEach((obj) => obj.offset(dx, 0));
4275
4241
  this.requestRectUpdate();
4276
4242
  }
4277
- draw(renderer) {
4278
- const ctx = renderer.getCanvasContext();
4279
- if (!ctx || this.barLineType === 0 /* None */) {
4243
+ draw(ctx) {
4244
+ if (this.barLineType === 0 /* None */) {
4280
4245
  return;
4281
4246
  }
4282
- renderer.drawDebugRect(this.getRect());
4283
- ctx.strokeStyle = ctx.fillStyle = "black";
4284
- this.staffTabObjects.forEach((obj) => {
4285
- obj.lineRects.forEach((r) => ctx.fillRect(r.left, r.top, r.width, r.height));
4286
- obj.dotRects.forEach((r) => renderer.fillCircle(r.centerX, r.centerY, r.width / 2));
4247
+ ctx.drawDebugRect(this.getRect());
4248
+ ctx.color("black");
4249
+ this.staffTabObjectGroups.forEach((objs) => {
4250
+ if (objs.length > 0) {
4251
+ objs.forEach((obj) => obj.dots.forEach((d) => ctx.fillCircle(d.x, d.y, d.r)));
4252
+ let top = objs[0].getRect().top;
4253
+ let height = objs[objs.length - 1].getRect().bottom - top;
4254
+ objs[0].verticalLines.forEach((vline) => ctx.fillRect(vline.left, top, vline.width, height));
4255
+ }
4287
4256
  });
4288
4257
  }
4289
4258
  };
@@ -4389,14 +4358,14 @@ var ObjEnding = class extends MusicObject {
4389
4358
  pick(x, y) {
4390
4359
  return this.rect.contains(x, y) ? [this] : [];
4391
4360
  }
4392
- layout(renderer) {
4361
+ layout(ctx) {
4393
4362
  this.rect = new DivRect();
4394
4363
  this.shapeRects = [this.rect.copy()];
4395
4364
  }
4396
- layoutFitToMeasure(renderer) {
4397
- let { unitSize } = renderer;
4365
+ layoutFitToMeasure(ctx) {
4366
+ let { unitSize } = ctx;
4398
4367
  let { measure } = this;
4399
- this.endingText.layout(renderer);
4368
+ this.endingText.layout(ctx);
4400
4369
  let textRect = this.endingText.getRect();
4401
4370
  let measureContent = measure.getColumnsContentRect();
4402
4371
  let endingHeight = textRect.height;
@@ -4414,16 +4383,10 @@ var ObjEnding = class extends MusicObject {
4414
4383
  this.shapeRects.forEach((r) => r.offsetInPlace(dx, dy));
4415
4384
  this.rect.offsetInPlace(dx, dy);
4416
4385
  }
4417
- draw(renderer) {
4418
- let ctx = renderer.getCanvasContext();
4419
- if (!ctx) {
4420
- return;
4421
- }
4422
- let { lineWidth } = renderer;
4386
+ draw(ctx) {
4423
4387
  let { rect } = this;
4424
- renderer.drawDebugRect(this.rect);
4425
- ctx.strokeStyle = ctx.fillStyle = "black";
4426
- ctx.lineWidth = lineWidth;
4388
+ ctx.drawDebugRect(this.rect);
4389
+ ctx.color("black").lineWidth(1);
4427
4390
  ctx.beginPath();
4428
4391
  ctx.moveTo(rect.left, rect.bottom);
4429
4392
  ctx.lineTo(rect.left, rect.top);
@@ -4432,7 +4395,7 @@ var ObjEnding = class extends MusicObject {
4432
4395
  ctx.lineTo(rect.right, rect.bottom);
4433
4396
  }
4434
4397
  ctx.stroke();
4435
- this.endingText.draw(renderer);
4398
+ this.endingText.draw(ctx);
4436
4399
  }
4437
4400
  };
4438
4401
 
@@ -4565,9 +4528,9 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4565
4528
  }
4566
4529
  }
4567
4530
  symbols[0].row.getStaves().forEach((staff) => {
4568
- if (staff.getActualStaff(symbols[0].ownDiatonicId) && staff.containsVoiceId(symbols[0].voiceId)) {
4531
+ if (staff.getActualStaff(symbols[0].getDiatonicId(staff)) && staff.containsVoiceId(symbols[0].voiceId)) {
4569
4532
  symbols.forEach((sym) => {
4570
- let actualStaff = staff.getActualStaff(sym.ownDiatonicId);
4533
+ let actualStaff = staff.getActualStaff(sym.getDiatonicId(staff));
4571
4534
  if (!actualStaff || !actualStaff.containsVoiceId(sym.voiceId)) {
4572
4535
  throw new InvalidBeamGroup(this, "Some of beam or tuplet symbols are not visible!");
4573
4536
  }
@@ -4575,6 +4538,9 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4575
4538
  }
4576
4539
  });
4577
4540
  }
4541
+ get stemDir() {
4542
+ return this.symbols[0].stemDir;
4543
+ }
4578
4544
  get showTupletRatio() {
4579
4545
  var _a;
4580
4546
  return ((_a = this.tupletRatio) == null ? void 0 : _a.showRatio) === true;
@@ -4670,20 +4636,17 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4670
4636
  getLastSymbol() {
4671
4637
  return this.symbols[this.symbols.length - 1];
4672
4638
  }
4673
- get stemDir() {
4674
- return this.symbols[0].ownStemDir;
4675
- }
4676
4639
  get color() {
4677
4640
  return this.symbols[0].color;
4678
4641
  }
4679
- layout(renderer) {
4642
+ layout(ctx) {
4680
4643
  this.requestRectUpdate();
4681
4644
  this.staffObjects.length = 0;
4682
4645
  let symbols = this.getSymbols();
4683
4646
  if (symbols.length === 0) {
4684
4647
  return;
4685
4648
  }
4686
- let { unitSize } = renderer;
4649
+ let { unitSize } = ctx;
4687
4650
  let { stemDir, type } = this;
4688
4651
  let symbolsBeamCoords = symbols.map((s) => s.getBeamCoords());
4689
4652
  symbolsBeamCoords[0].map((s) => s == null ? void 0 : s.staff).forEach((mainStaff, index) => {
@@ -4767,7 +4730,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4767
4730
  obj.tupletNumberOffsetY = 0;
4768
4731
  } else if (type === 0 /* RegularBeam */ || type === 1 /* TupletBeam */) {
4769
4732
  raiseBeamY *= 0.5;
4770
- let { beamThickness } = renderer;
4733
+ let beamThickness = ctx._lineWidth * DocumentSettings.BeamThickness;
4771
4734
  const beamHeight = (i) => {
4772
4735
  let sym = symbols[i];
4773
4736
  if (sym instanceof ObjNoteGroup) {
@@ -4800,7 +4763,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4800
4763
  }
4801
4764
  if (this.isTuplet()) {
4802
4765
  obj.tupletNumber = new ObjText(this, this.getTupletRatioText(), 0.5, 0.5);
4803
- obj.tupletNumber.layout(renderer);
4766
+ obj.tupletNumber.layout(ctx);
4804
4767
  obj.tupletNumber.offset((leftX + rightX) / 2, (leftY + rightY) / 2 + obj.tupletNumberOffsetY);
4805
4768
  }
4806
4769
  if (obj.points.length >= 2) {
@@ -4843,10 +4806,11 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4843
4806
  this.staffObjects.forEach((obj) => obj.offset(dx, 0));
4844
4807
  this.requestRectUpdate();
4845
4808
  }
4846
- draw(renderer) {
4847
- let { unitSize, beamThickness, lineWidth } = renderer;
4809
+ draw(ctx) {
4810
+ let { unitSize } = ctx;
4848
4811
  let { stemDir, color, type } = this;
4849
4812
  if (type === 2 /* TupletGroup */) {
4813
+ ctx.color(color).lineWidth(1);
4850
4814
  let tipHeight = (stemDir === "up" /* Up */ ? 1 : -1) * unitSize;
4851
4815
  this.staffObjects.forEach((obj) => {
4852
4816
  let { x: lx, y: ly } = obj.points[0];
@@ -4855,15 +4819,16 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4855
4819
  let tf = obj.tupletNumber.getRect().width / (rx - lx) * 1.2;
4856
4820
  let lc = import_ts_utils_lib9.Utils.Math.interpolateCoord(lx, ly, rx, ry, 0.5 - tf / 2);
4857
4821
  let rc = import_ts_utils_lib9.Utils.Math.interpolateCoord(lx, ly, rx, ry, 0.5 + tf / 2);
4858
- renderer.drawLine(lx, ly, lc.x, lc.y, color, lineWidth);
4859
- renderer.drawLine(rc.x, rc.y, rx, ry, color, lineWidth);
4822
+ ctx.strokeLine(lx, ly, lc.x, lc.y);
4823
+ ctx.strokeLine(rc.x, rc.y, rx, ry);
4860
4824
  } else {
4861
- renderer.drawLine(lx, ly, rx, ry, color, lineWidth);
4825
+ ctx.strokeLine(lx, ly, rx, ry);
4862
4826
  }
4863
- renderer.drawLine(lx, ly, lx, ly + tipHeight, color, lineWidth);
4864
- renderer.drawLine(rx, ry, rx, ry + tipHeight, color, lineWidth);
4827
+ ctx.strokeLine(lx, ly, lx, ly + tipHeight);
4828
+ ctx.strokeLine(rx, ry, rx, ry + tipHeight);
4865
4829
  });
4866
4830
  } else if (type === 0 /* RegularBeam */ || type === 1 /* TupletBeam */) {
4831
+ ctx.color(color).lineWidth(DocumentSettings.BeamThickness);
4867
4832
  this.staffObjects.forEach((obj) => {
4868
4833
  let noteGroupPoints = obj.points.filter((p) => p.symbol instanceof ObjNoteGroup);
4869
4834
  let { x: lx, y: ly } = noteGroupPoints[0];
@@ -4876,11 +4841,11 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4876
4841
  let rightBeamCount = rsymbol.getLeftBeamCount();
4877
4842
  for (let beamId = 0; beamId < Math.max(leftBeamCount, rightBeamCount); beamId++) {
4878
4843
  if (beamId < leftBeamCount && beamId < rightBeamCount) {
4879
- renderer.drawLine(lx2, ly2, rx2, ry2, color, beamThickness);
4844
+ ctx.strokeLine(lx2, ly2, rx2, ry2);
4880
4845
  } else if (leftBeamCount > rightBeamCount) {
4881
- renderer.drawPartialLine(lx2, ly2, rx2, ry2, 0, 0.25, color, beamThickness);
4846
+ ctx.strokePartialLine(lx2, ly2, rx2, ry2, 0, 0.25);
4882
4847
  } else if (rightBeamCount > leftBeamCount) {
4883
- renderer.drawPartialLine(lx2, ly2, rx2, ry2, 0.75, 1, color, beamThickness);
4848
+ ctx.strokePartialLine(lx2, ly2, rx2, ry2, 0.75, 1);
4884
4849
  }
4885
4850
  ly2 += beamSeparation;
4886
4851
  ry2 += beamSeparation;
@@ -4890,7 +4855,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4890
4855
  }
4891
4856
  this.staffObjects.forEach((obj) => {
4892
4857
  var _a;
4893
- return (_a = obj.tupletNumber) == null ? void 0 : _a.draw(renderer);
4858
+ return (_a = obj.tupletNumber) == null ? void 0 : _a.draw(ctx);
4894
4859
  });
4895
4860
  }
4896
4861
  setBeamCounts() {
@@ -4990,8 +4955,8 @@ var ObjFermata = class extends MusicObject {
4990
4955
  pick(x, y) {
4991
4956
  return this.rect.contains(x, y) ? [this] : [];
4992
4957
  }
4993
- layout(renderer) {
4994
- let { unitSize } = renderer;
4958
+ layout(ctx) {
4959
+ let { unitSize } = ctx;
4995
4960
  let width = unitSize * 4;
4996
4961
  let height = unitSize * 3;
4997
4962
  this.rect = new DivRect(-width / 2, width / 2, -height, 0);
@@ -4999,12 +4964,8 @@ var ObjFermata = class extends MusicObject {
4999
4964
  offset(dx, dy) {
5000
4965
  this.rect.offsetInPlace(dx, dy);
5001
4966
  }
5002
- draw(renderer) {
5003
- let ctx = renderer.getCanvasContext();
5004
- if (!ctx) {
5005
- return;
5006
- }
5007
- let { lineWidth, unitSize } = renderer;
4967
+ draw(ctx) {
4968
+ let { unitSize } = ctx;
5008
4969
  let upsideDown = this.pos === 1 /* Below */;
5009
4970
  let dy = (upsideDown ? unitSize : -unitSize) * 0.7;
5010
4971
  let left = this.rect.left;
@@ -5012,9 +4973,8 @@ var ObjFermata = class extends MusicObject {
5012
4973
  let top = (upsideDown ? this.rect.bottom : this.rect.top) + dy;
5013
4974
  let bottom = (upsideDown ? this.rect.top : this.rect.bottom) + dy;
5014
4975
  let height = bottom - top;
5015
- renderer.drawDebugRect(this.rect);
5016
- ctx.strokeStyle = ctx.fillStyle = this.color;
5017
- ctx.lineWidth = lineWidth;
4976
+ ctx.drawDebugRect(this.rect);
4977
+ ctx.color("black").lineWidth(1);
5018
4978
  ctx.beginPath();
5019
4979
  ctx.moveTo(left, bottom);
5020
4980
  ctx.bezierCurveTo(left, top, right, top, right, bottom);
@@ -5022,7 +4982,7 @@ var ObjFermata = class extends MusicObject {
5022
4982
  ctx.stroke();
5023
4983
  ctx.fill();
5024
4984
  let r = height / 6;
5025
- renderer.fillCircle((left + right) / 2, bottom - r, Math.abs(r));
4985
+ ctx.fillCircle((left + right) / 2, bottom - r, Math.abs(r));
5026
4986
  }
5027
4987
  };
5028
4988
 
@@ -5065,8 +5025,8 @@ var ObjExtensionLine = class extends MusicObject {
5065
5025
  return this.rightObj.getRect().centerX;
5066
5026
  }
5067
5027
  }
5068
- layoutFitToMeasure(renderer) {
5069
- let { unitSize } = renderer;
5028
+ layoutFitToMeasure(ctx) {
5029
+ let { unitSize } = ctx;
5070
5030
  let lineLeft = this.getLineLeft();
5071
5031
  let lineRight = this.getLineRight();
5072
5032
  let lineRectH = unitSize;
@@ -5075,27 +5035,24 @@ var ObjExtensionLine = class extends MusicObject {
5075
5035
  pick(x, y) {
5076
5036
  return this.rect.contains(x, y) ? [this] : [];
5077
5037
  }
5078
- layout(renderer) {
5038
+ layout(ctx) {
5079
5039
  this.rect = new DivRect();
5080
5040
  }
5081
5041
  offset(dx, dy) {
5082
5042
  this.rect.offsetInPlace(dx, dy);
5083
5043
  }
5084
- draw(renderer) {
5085
- let ctx = renderer.getCanvasContext();
5086
- if (!ctx) {
5087
- return;
5088
- }
5044
+ draw(ctx) {
5089
5045
  let { rect } = this;
5090
5046
  if (this.extension.getLineStyle() === "dashed") {
5091
5047
  ctx.setLineDash([7, 3]);
5092
5048
  }
5093
- renderer.drawLine(rect.left, rect.centerY, rect.right, rect.centerY, "black", renderer.lineWidth);
5049
+ ctx.color("black").lineWidth(1);
5050
+ ctx.strokeLine(rect.left, rect.centerY, rect.right, rect.centerY);
5094
5051
  ctx.setLineDash([]);
5095
5052
  let tails = this.extension.getTails();
5096
5053
  if (tails.length > 0 && this === tails[tails.length - 1]) {
5097
- let tipH = rect.centerY > this.line.getRect().centerY ? -renderer.unitSize : renderer.unitSize;
5098
- renderer.drawLine(rect.right, rect.centerY, rect.right, rect.centerY + tipH, "black", renderer.lineWidth);
5054
+ let tipH = rect.centerY > this.line.getRect().centerY ? -ctx.unitSize : ctx.unitSize;
5055
+ ctx.strokeLine(rect.right, rect.centerY, rect.right, rect.centerY + tipH);
5099
5056
  }
5100
5057
  }
5101
5058
  };
@@ -5111,9 +5068,9 @@ var import_ts_utils_lib10 = require("@tspro/ts-utils-lib");
5111
5068
  var import_core12 = require("@tspro/web-music-score/core");
5112
5069
  var ObjConnective = class extends MusicObject {
5113
5070
  constructor(connectiveProps, line, measure, leftNoteGroup, leftNoteId, ...args) {
5071
+ var _a;
5114
5072
  super(measure);
5115
5073
  this.connectiveProps = connectiveProps;
5116
- this.line = line;
5117
5074
  this.measure = measure;
5118
5075
  __publicField(this, "lx", 0);
5119
5076
  __publicField(this, "ly", 0);
@@ -5124,12 +5081,14 @@ var ObjConnective = class extends MusicObject {
5124
5081
  __publicField(this, "cp2x", 0);
5125
5082
  __publicField(this, "cp2y", 0);
5126
5083
  __publicField(this, "arcHeight", 0);
5084
+ __publicField(this, "line");
5127
5085
  __publicField(this, "leftNoteGroup");
5128
5086
  __publicField(this, "leftNoteId");
5129
5087
  __publicField(this, "rightNoteGroup");
5130
5088
  __publicField(this, "rightNoteId");
5131
5089
  __publicField(this, "tieType");
5132
5090
  __publicField(this, "mi");
5091
+ this.line = (_a = this.measure.row.findMatchingLine(line)) != null ? _a : line;
5133
5092
  this.leftNoteGroup = leftNoteGroup;
5134
5093
  this.leftNoteId = leftNoteId;
5135
5094
  if (args[0] instanceof ObjNoteGroup && typeof args[1] === "number") {
@@ -5153,8 +5112,8 @@ var ObjConnective = class extends MusicObject {
5153
5112
  pick(x, y) {
5154
5113
  return this.rect.contains(x, y) ? [this] : [];
5155
5114
  }
5156
- layout(renderer) {
5157
- let { unitSize } = renderer;
5115
+ layout(ctx) {
5116
+ let { unitSize } = ctx;
5158
5117
  let { measure, line, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId, connectiveProps } = this;
5159
5118
  let { noteAnchor, arcDir } = connectiveProps;
5160
5119
  let { row } = measure;
@@ -5230,11 +5189,7 @@ var ObjConnective = class extends MusicObject {
5230
5189
  this.cp2y += dy;
5231
5190
  this.rect.offsetInPlace(dx, dy);
5232
5191
  }
5233
- draw(renderer) {
5234
- let ctx = renderer.getCanvasContext();
5235
- if (!ctx) {
5236
- return;
5237
- }
5192
+ draw(ctx) {
5238
5193
  if (this.rightNoteGroup === void 0) {
5239
5194
  } else if (this.leftNoteGroup.measure === this.rightNoteGroup.measure) {
5240
5195
  } else if (this.leftNoteGroup.row.getNextRow() === this.rightNoteGroup.row) {
@@ -5243,12 +5198,11 @@ var ObjConnective = class extends MusicObject {
5243
5198
  return;
5244
5199
  }
5245
5200
  let { rect } = this;
5246
- let { lineWidth } = renderer;
5247
- renderer.drawDebugRect(rect);
5248
- let t = lineWidth * 1.5;
5249
- let s = lineWidth * 0.25;
5250
- ctx.strokeStyle = ctx.fillStyle = "black";
5251
- ctx.lineWidth = lineWidth;
5201
+ let { _lineWidth } = ctx;
5202
+ ctx.drawDebugRect(rect);
5203
+ let t = _lineWidth * 1.5;
5204
+ let s = _lineWidth * 0.25;
5205
+ ctx.color("black").lineWidth(1);
5252
5206
  if (this.arcHeight === 0) {
5253
5207
  ctx.beginPath();
5254
5208
  ctx.moveTo(this.lx, this.ly);
@@ -5298,7 +5252,7 @@ var ConnectiveProps = class {
5298
5252
  return false;
5299
5253
  }
5300
5254
  }
5301
- computeParams() {
5255
+ computeParams(line) {
5302
5256
  let { stemDir } = this.noteGroups[0];
5303
5257
  let { hasStem } = this.noteGroups[0].rhythmProps;
5304
5258
  if (this.noteAnchor === "stemTip" /* StemTip */) {
@@ -5315,9 +5269,8 @@ var ConnectiveProps = class {
5315
5269
  this.noteAnchor = "below" /* Below */;
5316
5270
  }
5317
5271
  } else if (this.noteAnchor === "center" /* Center */) {
5318
- let { row } = this.noteGroups[0].measure;
5319
- let diatonicId = this.noteGroups[0].ownDiatonicId;
5320
- let staff = row.getStaff(diatonicId);
5272
+ let staff = line instanceof ObjStaff ? line : void 0;
5273
+ let diatonicId = this.noteGroups[0].getDiatonicId(staff);
5321
5274
  this.arcDir = !staff || diatonicId < staff.middleLineDiatonicId ? "down" : "up";
5322
5275
  } else if (this.noteAnchor === "above" /* Above */) {
5323
5276
  this.arcDir = "up";
@@ -5333,68 +5286,73 @@ var ConnectiveProps = class {
5333
5286
  this.noteGroups.length = 1;
5334
5287
  }
5335
5288
  createConnectives() {
5289
+ if (this.noteGroups.length === 0) {
5290
+ return;
5291
+ }
5336
5292
  this.getStartNoteGroup().collectConnectiveProps();
5337
- this.computeParams();
5338
5293
  let { connective, span } = this;
5339
- if (connective === "tie" /* Tie */) {
5340
- if (import_ts_utils_lib11.Utils.Is.isEnumValue(span, TieType)) {
5341
- let leftNoteGroup = this.noteGroups[0];
5342
- for (let noteId = 0; noteId < leftNoteGroup.notes.length; noteId++) {
5343
- this.createObjConnectiveWithTieType(leftNoteGroup, noteId, span);
5294
+ this.noteGroups[0].row.getNotationLines().forEach((line) => {
5295
+ this.computeParams(line);
5296
+ if (connective === "tie" /* Tie */) {
5297
+ if (import_ts_utils_lib11.Utils.Is.isEnumValue(span, TieType)) {
5298
+ let leftNoteGroup = this.noteGroups[0];
5299
+ for (let noteId = 0; noteId < leftNoteGroup.notes.length; noteId++) {
5300
+ this.createObjConnectiveWithTieType(line, leftNoteGroup, noteId, span);
5301
+ }
5302
+ } else if (this.noteGroups.length >= 2) {
5303
+ for (let i = 0; i < this.noteGroups.length - 1; i++) {
5304
+ let leftNoteGroup = this.noteGroups[i];
5305
+ let rightNoteGroup = this.noteGroups[i + 1];
5306
+ leftNoteGroup.notes.forEach((leftNote, leftNoteId) => {
5307
+ let rightNoteId = rightNoteGroup.notes.findIndex((rightNote) => import_theory8.Note.equals(rightNote, leftNote));
5308
+ if (rightNoteId >= 0) {
5309
+ this.createObjConnective(line, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId);
5310
+ }
5311
+ });
5312
+ }
5344
5313
  }
5345
- } else if (this.noteGroups.length >= 2) {
5346
- for (let i = 0; i < this.noteGroups.length - 1; i++) {
5347
- let leftNoteGroup = this.noteGroups[i];
5348
- let rightNoteGroup = this.noteGroups[i + 1];
5349
- leftNoteGroup.notes.forEach((leftNote, leftNoteId) => {
5350
- let rightNoteId = rightNoteGroup.notes.findIndex((rightNote) => import_theory8.Note.equals(rightNote, leftNote));
5351
- if (rightNoteId >= 0) {
5352
- this.createObjConnective(leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId);
5353
- }
5354
- });
5314
+ } else if (connective === "slur" /* Slur */) {
5315
+ if (typeof span === "number" && span >= 2 && this.noteGroups.length === span) {
5316
+ let leftNoteGroup = this.noteGroups[0];
5317
+ let rightNoteGroup = this.noteGroups[this.noteGroups.length - 1];
5318
+ this.createObjConnective(line, leftNoteGroup, 0, rightNoteGroup, 0);
5355
5319
  }
5356
- }
5357
- } else if (connective === "slur" /* Slur */) {
5358
- if (typeof span === "number" && span >= 2 && this.noteGroups.length === span) {
5359
- let leftNoteGroup = this.noteGroups[0];
5360
- let rightNoteGroup = this.noteGroups[this.noteGroups.length - 1];
5361
- this.createObjConnective(leftNoteGroup, 0, rightNoteGroup, 0);
5362
- }
5363
- } else if (connective === "slide" /* Slide */) {
5364
- if (this.noteGroups.length >= 2) {
5365
- for (let i = 0; i < this.noteGroups.length - 1; i++) {
5366
- let leftNoteGroup = this.noteGroups[i];
5367
- let rightNoteGroup = this.noteGroups[i + 1];
5368
- this.createObjConnective(leftNoteGroup, 0, rightNoteGroup, 0);
5320
+ } else if (connective === "slide" /* Slide */) {
5321
+ if (this.noteGroups.length >= 2) {
5322
+ for (let i = 0; i < this.noteGroups.length - 1; i++) {
5323
+ let leftNoteGroup = this.noteGroups[i];
5324
+ let rightNoteGroup = this.noteGroups[i + 1];
5325
+ this.createObjConnective(line, leftNoteGroup, 0, rightNoteGroup, 0);
5326
+ }
5369
5327
  }
5370
5328
  }
5371
- }
5329
+ });
5372
5330
  }
5373
- createObjConnectiveWithTieType(leftNoteGroup, leftNoteId, tieType) {
5374
- leftNoteGroup.row.getNotationLines().filter((line) => leftNoteGroup.enableConnective(line)).forEach((line) => {
5375
- if (line instanceof ObjStaff) {
5331
+ createObjConnectiveWithTieType(line, leftNoteGroup, leftNoteId, tieType) {
5332
+ if (!leftNoteGroup.enableConnective(line)) {
5333
+ return;
5334
+ } else if (line instanceof ObjStaff) {
5335
+ new ObjConnective(this, line, leftNoteGroup.measure, leftNoteGroup, leftNoteId, tieType);
5336
+ } else if (line instanceof ObjTab) {
5337
+ let leftString = leftNoteGroup.getFretNumberString(leftNoteId);
5338
+ if (leftString !== void 0) {
5376
5339
  new ObjConnective(this, line, leftNoteGroup.measure, leftNoteGroup, leftNoteId, tieType);
5377
- } else {
5378
- let leftString = leftNoteGroup.getFretNumberString(leftNoteId);
5379
- if (leftString !== void 0) {
5380
- new ObjConnective(this, line, leftNoteGroup.measure, leftNoteGroup, leftNoteId, tieType);
5381
- }
5382
5340
  }
5383
- });
5341
+ }
5384
5342
  }
5385
- createObjConnective(leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId) {
5343
+ createObjConnective(line, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId) {
5386
5344
  const addConnective = (measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2) => {
5387
- measure.row.getNotationLines().filter((line) => leftNoteGroup2.enableConnective(line) && rightNoteGroup2.enableConnective(line)).forEach((line) => {
5388
- if (line instanceof ObjStaff) {
5345
+ if (!(leftNoteGroup2.enableConnective(line) && rightNoteGroup2.enableConnective(line))) {
5346
+ return;
5347
+ } else if (line instanceof ObjStaff) {
5348
+ new ObjConnective(this, line, measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2);
5349
+ } else if (line instanceof ObjTab) {
5350
+ let leftString = leftNoteGroup2.getFretNumberString(leftNoteId2);
5351
+ let rightString = rightNoteGroup2.getFretNumberString(rightNoteId2);
5352
+ if (leftString !== void 0 && rightString !== void 0 && (leftString === rightString || this.connective === "slur" /* Slur */)) {
5389
5353
  new ObjConnective(this, line, measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2);
5390
- } else {
5391
- let leftString = leftNoteGroup2.getFretNumberString(leftNoteId2);
5392
- let rightString = rightNoteGroup2.getFretNumberString(rightNoteId2);
5393
- if (leftString !== void 0 && rightString !== void 0 && (leftString === rightString || this.connective === "slur" /* Slur */)) {
5394
- new ObjConnective(this, line, measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2);
5395
- }
5396
5354
  }
5397
- });
5355
+ }
5398
5356
  };
5399
5357
  if (leftNoteGroup.measure === rightNoteGroup.measure) {
5400
5358
  addConnective(leftNoteGroup.measure, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId);
@@ -5407,18 +5365,84 @@ var ConnectiveProps = class {
5407
5365
  }
5408
5366
  };
5409
5367
 
5410
- // src/score/engine/obj-tab-rhythm.ts
5368
+ // src/score/engine/obj-lyrics.ts
5411
5369
  var import_ts_utils_lib12 = require("@tspro/ts-utils-lib");
5370
+ var ObjLyrics = class extends MusicObject {
5371
+ constructor(col, verse, line, vpos, lyricsLength, lyricsText, lyricsOptions) {
5372
+ super(col);
5373
+ this.col = col;
5374
+ this.verse = verse;
5375
+ this.line = line;
5376
+ this.vpos = vpos;
5377
+ __publicField(this, "nextLyricsObject");
5378
+ __publicField(this, "rhythmProps");
5379
+ __publicField(this, "color", "black");
5380
+ __publicField(this, "hyphen");
5381
+ __publicField(this, "text");
5382
+ __publicField(this, "mi");
5383
+ this.rhythmProps = RhythmProps.get(lyricsLength);
5384
+ let halign = (lyricsOptions == null ? void 0 : lyricsOptions.align) === "left" /* Left */ ? 0 : (lyricsOptions == null ? void 0 : lyricsOptions.align) === "right" /* Right */ ? 1 : 0.5;
5385
+ this.hyphen = import_ts_utils_lib12.Utils.Is.isEnumValue(lyricsOptions == null ? void 0 : lyricsOptions.hyphen, LyricsHyphen) ? lyricsOptions == null ? void 0 : lyricsOptions.hyphen : void 0;
5386
+ this.text = new ObjText(this, { text: lyricsText, color: this.color, scale: 0.8 }, halign, 0);
5387
+ this.rect = new DivRect();
5388
+ this.mi = new MLyrics(this);
5389
+ }
5390
+ getMusicInterface() {
5391
+ return this.mi;
5392
+ }
5393
+ get measure() {
5394
+ return this.col.measure;
5395
+ }
5396
+ getText() {
5397
+ return this.text.getText();
5398
+ }
5399
+ setNextLyricsObject(lyricsObj) {
5400
+ this.nextLyricsObject = lyricsObj;
5401
+ }
5402
+ pick(x, y) {
5403
+ return this.rect.contains(x, y) ? [this] : [];
5404
+ }
5405
+ layout(ctx) {
5406
+ this.text.layout(ctx);
5407
+ this.rect = this.text.getRect().copy();
5408
+ }
5409
+ offset(dx, dy) {
5410
+ this.text.offset(dx, dy);
5411
+ this.rect.offsetInPlace(dx, dy);
5412
+ }
5413
+ draw(ctx) {
5414
+ var _a;
5415
+ this.text.draw(ctx);
5416
+ if (this.hyphen !== void 0) {
5417
+ ctx.color(this.color).lineWidth(1);
5418
+ let l = this.getRect();
5419
+ let r = (_a = this.nextLyricsObject) == null ? void 0 : _a.getRect();
5420
+ let hyphenw = ctx.unitSize * 1.5;
5421
+ let maxw = r ? (r.left - l.right) * 0.85 : hyphenw;
5422
+ let w = this.hyphen === "-" /* Hyphen */ ? Math.min(hyphenw, maxw) : maxw;
5423
+ if (w > 0) {
5424
+ let cx = r ? (r.left + l.right) / 2 : l.right + w / 0.85;
5425
+ let cy = (l.top + l.bottom) / 2;
5426
+ ctx.moveTo(cx - w / 2, cy);
5427
+ ctx.lineTo(cx + w / 2, cy);
5428
+ ctx.stroke();
5429
+ }
5430
+ }
5431
+ }
5432
+ };
5433
+
5434
+ // src/score/engine/obj-tab-rhythm.ts
5435
+ var import_ts_utils_lib13 = require("@tspro/ts-utils-lib");
5412
5436
  var ObjTabRhythm = class extends MusicObject {
5413
5437
  constructor(measure, tab) {
5414
5438
  super(measure);
5415
5439
  this.measure = measure;
5416
5440
  this.tab = tab;
5417
- __publicField(this, "voiceIds");
5441
+ __publicField(this, "voiceId");
5418
5442
  __publicField(this, "mi");
5419
5443
  // Keep non-static
5420
5444
  __publicField(this, "tupletPartsTextObjMap", /* @__PURE__ */ new Map());
5421
- this.voiceIds = getVoiceIds().filter((voiceId) => tab.containsVoiceId(voiceId));
5445
+ this.voiceId = getVoiceIds().filter((voiceId) => tab.containsVoiceId(voiceId));
5422
5446
  this.rect = new DivRect();
5423
5447
  this.mi = new MTabRhythm(this);
5424
5448
  }
@@ -5428,17 +5452,17 @@ var ObjTabRhythm = class extends MusicObject {
5428
5452
  pick(x, y) {
5429
5453
  return this.rect.contains(x, y) ? [this] : [];
5430
5454
  }
5431
- layout(renderer) {
5455
+ layout(ctx) {
5432
5456
  let columns = this.measure.getColumns();
5433
- let numColsInVoiceId = getVoiceIds().map((voiceId) => import_ts_utils_lib12.Utils.Math.sum(columns.map((col) => col.getVoiceSymbol(voiceId) ? 1 : 0)));
5434
- this.voiceIds.sort((a, b) => import_ts_utils_lib12.Utils.Math.cmp(numColsInVoiceId[a], numColsInVoiceId[b]));
5457
+ let numColsInVoiceId = getVoiceIds().map((voiceId) => import_ts_utils_lib13.Utils.Math.sum(columns.map((col) => col.getVoiceSymbol(voiceId) ? 1 : 0)));
5458
+ this.voiceId.sort((a, b) => import_ts_utils_lib13.Utils.Math.cmp(numColsInVoiceId[a], numColsInVoiceId[b]));
5435
5459
  this.rect = new DivRect();
5436
5460
  }
5437
5461
  hasTuplets() {
5438
5462
  return this.measure.getBeamGroups().some((beamGroup) => beamGroup.isTuplet());
5439
5463
  }
5440
- layoutFitToMeasure(renderer) {
5441
- let { unitSize, fontSize } = renderer;
5464
+ layoutFitToMeasure(ctx) {
5465
+ let { unitSize, fontSize } = ctx;
5442
5466
  let { measure } = this;
5443
5467
  let { left, right } = measure.getColumnsContentRect();
5444
5468
  let stemHeight = unitSize * 5;
@@ -5452,13 +5476,10 @@ var ObjTabRhythm = class extends MusicObject {
5452
5476
  offset(dx, dy) {
5453
5477
  this.rect.offsetInPlace(dx, dy);
5454
5478
  }
5455
- draw(renderer) {
5456
- const ctx = renderer.getCanvasContext();
5457
- if (!ctx) {
5458
- return;
5459
- }
5460
- renderer.drawDebugRect(this.rect);
5461
- let { unitSize, lineWidth, fontSize } = renderer;
5479
+ draw(ctx) {
5480
+ ctx.drawDebugRect(this.rect);
5481
+ ctx.color("black").lineWidth(1);
5482
+ let { unitSize, fontSize } = ctx;
5462
5483
  let flagSize = unitSize;
5463
5484
  let dotSpace = unitSize;
5464
5485
  let dotWidth = unitSize * 0.25;
@@ -5468,7 +5489,7 @@ var ObjTabRhythm = class extends MusicObject {
5468
5489
  let columns = this.measure.getColumns();
5469
5490
  for (let colId = 0; colId < columns.length; colId++) {
5470
5491
  let cur = columns[colId];
5471
- let curVoiceSymbol = this.voiceIds.map((voiceId) => cur.getVoiceSymbol(voiceId)).find((sym) => sym !== void 0);
5492
+ let curVoiceSymbol = this.voiceId.map((voiceId) => cur.getVoiceSymbol(voiceId)).find((sym) => sym !== void 0);
5472
5493
  if (!curVoiceSymbol) {
5473
5494
  continue;
5474
5495
  }
@@ -5480,16 +5501,17 @@ var ObjTabRhythm = class extends MusicObject {
5480
5501
  let colX = sym.col.getRect().centerX;
5481
5502
  if (sym instanceof ObjNoteGroup) {
5482
5503
  if (sym.rhythmProps.noteSize >= 2) {
5483
- let stemThickness = sym.rhythmProps.noteSize === 4 ? lineWidth * 2 : lineWidth;
5484
- renderer.drawLine(colX, stemBottom, colX, stemTop, "black", stemThickness);
5504
+ ctx.lineWidth(sym.rhythmProps.noteSize === 4 ? 2 : 1);
5505
+ ctx.strokeLine(colX, stemBottom, colX, stemTop);
5485
5506
  }
5507
+ ctx.lineWidth(1);
5486
5508
  if (symbols.length === 1) {
5487
5509
  for (let i = 0; i < sym.rhythmProps.flagCount; i++) {
5488
- renderer.drawFlag(new DivRect(colX, colX + flagSize, stemTop + i * flagSize, stemTop + (i + 2) * flagSize), "up");
5510
+ ctx.drawFlag(new DivRect(colX, colX + flagSize, stemTop + i * flagSize, stemTop + (i + 2) * flagSize), "up");
5489
5511
  }
5490
5512
  }
5491
5513
  for (let i = 0; i < sym.rhythmProps.dotCount; i++) {
5492
- renderer.fillCircle(colX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5514
+ ctx.fillCircle(colX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5493
5515
  }
5494
5516
  } else if (sym instanceof ObjRest) {
5495
5517
  let cx = colX;
@@ -5497,11 +5519,11 @@ var ObjTabRhythm = class extends MusicObject {
5497
5519
  let scale = 0.65;
5498
5520
  ctx.save();
5499
5521
  ctx.scale(scale, scale);
5500
- renderer.drawRest(sym.rhythmProps.noteSize, cx / scale, cy / scale, "black");
5522
+ ctx.drawRest(sym.rhythmProps.noteSize, cx / scale, cy / scale);
5501
5523
  ctx.restore();
5502
5524
  for (let i = 0; i < sym.rhythmProps.dotCount; i++) {
5503
5525
  cx += dotSpace * 1.5;
5504
- renderer.fillCircle(cx, cy + dotSpace, dotWidth);
5526
+ ctx.fillCircle(cx, cy + dotSpace, dotWidth);
5505
5527
  }
5506
5528
  }
5507
5529
  if (nextSym) {
@@ -5512,16 +5534,18 @@ var ObjTabRhythm = class extends MusicObject {
5512
5534
  let leftBeamCount = left.hasTuplet() ? 1 : left instanceof ObjNoteGroup ? left.getRightBeamCount() : 1;
5513
5535
  let rightBeamCount = right.hasTuplet() ? 1 : right instanceof ObjNoteGroup ? right.getLeftBeamCount() : 1;
5514
5536
  let maxBeamCount = Math.max(leftBeamCount, rightBeamCount);
5537
+ ctx.lineWidth(2);
5515
5538
  for (let i = 0; i < maxBeamCount; i++) {
5516
5539
  let leftT = rightBeamCount > leftBeamCount && i >= leftBeamCount ? 0.75 : 0;
5517
5540
  let rightT = leftBeamCount > rightBeamCount && i >= rightBeamCount ? 0.25 : 1;
5518
- renderer.drawPartialLine(leftX, stemTop + i * flagSize, rightX, stemTop + i * flagSize, leftT, rightT, "black", lineWidth * 2);
5541
+ ctx.strokePartialLine(leftX, stemTop + i * flagSize, rightX, stemTop + i * flagSize, leftT, rightT);
5519
5542
  }
5543
+ ctx.lineWidth(1);
5520
5544
  for (let i = 0; i < left.rhythmProps.dotCount; i++) {
5521
- renderer.fillCircle(leftX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5545
+ ctx.fillCircle(leftX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5522
5546
  }
5523
5547
  for (let i = 0; i < right.rhythmProps.dotCount; i++) {
5524
- renderer.fillCircle(rightX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5548
+ ctx.fillCircle(rightX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5525
5549
  }
5526
5550
  }
5527
5551
  if (beamGroup && beamGroup.isTuplet()) {
@@ -5530,11 +5554,11 @@ var ObjTabRhythm = class extends MusicObject {
5530
5554
  let textObj = this.tupletPartsTextObjMap.get(text);
5531
5555
  if (!textObj) {
5532
5556
  this.tupletPartsTextObjMap.set(text, textObj = new ObjText(this, { text, scale: 0.75 }, 0.5, 0.5));
5533
- textObj.layout(renderer);
5557
+ textObj.layout(ctx);
5534
5558
  }
5535
5559
  textObj.offset(-textObj.getRect().centerX, -textObj.getRect().centerY);
5536
5560
  textObj.offset(cx, stemTop - fontSize / 2);
5537
- textObj.draw(renderer);
5561
+ textObj.draw(ctx);
5538
5562
  }
5539
5563
  if (symbols.length > 1) {
5540
5564
  colId = columns.indexOf(symbols[symbols.length - 1].col);
@@ -5559,7 +5583,7 @@ function getExtensionTicks(extensionLength) {
5559
5583
  if (typeof extensionLength === "string") {
5560
5584
  extensionLength = [extensionLength];
5561
5585
  }
5562
- if (import_ts_utils_lib13.Utils.Is.isArray(extensionLength)) {
5586
+ if (import_ts_utils_lib14.Utils.Is.isArray(extensionLength)) {
5563
5587
  let totalTicks = 0;
5564
5588
  for (let i = 0; i < extensionLength.length; ) {
5565
5589
  let str = extensionLength[i];
@@ -5594,9 +5618,10 @@ function getVerseLayoutGroupId(verse) {
5594
5618
  }
5595
5619
  }
5596
5620
  var _ObjMeasure = class _ObjMeasure extends MusicObject {
5597
- constructor(row) {
5621
+ constructor(row, options) {
5598
5622
  super(row);
5599
5623
  this.row = row;
5624
+ this.options = options;
5600
5625
  __publicField(this, "prevMeasure");
5601
5626
  __publicField(this, "nextMeasure");
5602
5627
  __publicField(this, "keySignature", (0, import_theory9.getDefaultKeySignature)());
@@ -5618,9 +5643,6 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5618
5643
  __publicField(this, "leftSolidAreaWidth", 0);
5619
5644
  __publicField(this, "minColumnsAreaWidth", 0);
5620
5645
  __publicField(this, "rightSolidAreaWidth", 0);
5621
- __publicField(this, "useDiatonicId", []);
5622
- __publicField(this, "useStemDir", []);
5623
- __publicField(this, "useString", []);
5624
5646
  __publicField(this, "voiceSymbols", []);
5625
5647
  __publicField(this, "lastAddedRhythmColumn");
5626
5648
  __publicField(this, "lastAddedRhythmSymbol");
@@ -5637,7 +5659,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5637
5659
  // play twice.
5638
5660
  __publicField(this, "endRepeatPlayCountText");
5639
5661
  __publicField(this, "staticObjectsCache", /* @__PURE__ */ new Map());
5640
- __publicField(this, "lyricsObjectsCache", /* @__PURE__ */ new Map());
5662
+ __publicField(this, "lyricsObjectsCache", new import_ts_utils_lib14.Map3());
5641
5663
  __publicField(this, "mi");
5642
5664
  this.mi = new MMeasure(this);
5643
5665
  this.prevMeasure = row.doc.getLastMeasure();
@@ -5675,54 +5697,67 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5675
5697
  getPassCount() {
5676
5698
  return this.passCount;
5677
5699
  }
5678
- updateOwnDiatonicId(voiceId, setDiatonicId) {
5679
- if (typeof setDiatonicId == "number") {
5680
- this.useDiatonicId[voiceId] = setDiatonicId;
5681
- } else if (this.useDiatonicId[voiceId] === void 0) {
5682
- let prevMeasure = this.getPrevMeasure();
5683
- if (prevMeasure && prevMeasure.useDiatonicId[voiceId] !== void 0) {
5684
- this.useDiatonicId[voiceId] = prevMeasure.useDiatonicId[voiceId];
5685
- }
5686
- }
5687
- let diatonicId = this.useDiatonicId[voiceId];
5688
- if (diatonicId === void 0) {
5689
- if (this.row.hasStaff) {
5690
- diatonicId = this.row.getTopStaff().middleLineDiatonicId;
5691
- } else {
5692
- diatonicId = import_theory9.Note.getNote("C4").diatonicId;
5693
- }
5694
- }
5695
- return this.useDiatonicId[voiceId] = import_theory9.Note.validateDiatonicId(diatonicId);
5696
- }
5697
- updateOwnStemDir(symbol, setStemDir) {
5698
- var _a, _b;
5699
- let { voiceId } = symbol;
5700
- if (setStemDir !== void 0) {
5701
- this.useStemDir[voiceId] = setStemDir;
5702
- } else if (this.useStemDir[voiceId] === void 0) {
5703
- this.useStemDir[voiceId] = (_b = (_a = this.getPrevMeasure()) == null ? void 0 : _a.useStemDir[voiceId]) != null ? _b : "auto" /* Auto */;
5704
- }
5705
- let stemDir = this.useStemDir[voiceId];
5706
- if (stemDir === "auto" /* Auto */ || stemDir === void 0) {
5707
- let staff = this.row.getStaff(symbol.ownDiatonicId);
5708
- if (staff) {
5709
- return symbol.ownDiatonicId > staff.middleLineDiatonicId ? "down" /* Down */ : "up" /* Up */;
5710
- } else {
5711
- return "up" /* Up */;
5712
- }
5713
- } else {
5714
- return stemDir;
5715
- }
5716
- }
5717
- updateOwnString(symbol, setString) {
5718
- var _a, _b;
5719
- let { voiceId } = symbol;
5720
- if (setString !== void 0) {
5721
- this.useString[voiceId] = setString;
5722
- } else if (this.useString[voiceId] === void 0) {
5723
- this.useString[voiceId] = (_b = (_a = this.getPrevMeasure()) == null ? void 0 : _a.useString[voiceId]) != null ? _b : [];
5724
- }
5725
- return this.useString[voiceId];
5700
+ updateRunningArguments(runningArgs) {
5701
+ var _a;
5702
+ runningArgs != null ? runningArgs : runningArgs = [];
5703
+ let numVoices = import_ts_utils_lib14.Utils.Math.sum(getVoiceIds().map((voiceId) => this.getVoiceSymbols(voiceId).length > 0 ? 1 : 0));
5704
+ getVoiceIds().forEach((voiceId) => {
5705
+ var _a2;
5706
+ const getDefaultDiatonicId = () => {
5707
+ let staves = this.row.getStaves().filter((staff) => staff.containsVoiceId(voiceId));
5708
+ let tabs = this.row.getTabs().filter((tab) => tab.containsVoiceId(voiceId));
5709
+ return staves.length > 0 ? staves[0].middleLineDiatonicId : tabs.length > 0 ? tabs[0].getTuningStrings()[3].diatonicId : import_theory9.Note.getNote("G4").diatonicId;
5710
+ };
5711
+ const getDefaultStemDir = () => "auto" /* Auto */;
5712
+ const getDefaultStringNumbers = () => [];
5713
+ let args = (_a2 = runningArgs[voiceId]) != null ? _a2 : runningArgs[voiceId] = {
5714
+ diatonicId: getDefaultDiatonicId(),
5715
+ stemDir: getDefaultStemDir(),
5716
+ stringNumbers: getDefaultStringNumbers()
5717
+ };
5718
+ this.getVoiceSymbols(voiceId).forEach((sym, symId, symArr) => {
5719
+ var _a3, _b;
5720
+ if (sym.setDiatonicId === ObjRest.UndefinedDiatonicId) {
5721
+ if (numVoices < 2) {
5722
+ args.diatonicId = ObjRest.UndefinedDiatonicId;
5723
+ }
5724
+ } else {
5725
+ args.diatonicId = sym.setDiatonicId;
5726
+ }
5727
+ if (sym instanceof ObjNoteGroup) {
5728
+ if (sym.setStringsNumbers) {
5729
+ args.stringNumbers = sym.setStringsNumbers;
5730
+ }
5731
+ switch ((_a3 = sym.options) == null ? void 0 : _a3.stem) {
5732
+ case "up" /* Up */:
5733
+ case "up":
5734
+ args.stemDir = "up" /* Up */;
5735
+ break;
5736
+ case "down" /* Down */:
5737
+ case "down":
5738
+ args.stemDir = "down" /* Down */;
5739
+ break;
5740
+ case "auto" /* Auto */:
5741
+ case "auto":
5742
+ args.stemDir = "auto" /* Auto */;
5743
+ break;
5744
+ }
5745
+ }
5746
+ let beamSymbols = (_b = sym.getBeamGroup()) == null ? void 0 : _b.getSymbols();
5747
+ let setStemDir;
5748
+ if (beamSymbols === void 0) {
5749
+ setStemDir = args.stemDir === "auto" /* Auto */ ? this.row.solveAutoStemDir([sym]) : args.stemDir;
5750
+ } else {
5751
+ if (sym === beamSymbols[0]) {
5752
+ setStemDir = args.stemDir === "auto" /* Auto */ ? this.row.solveAutoStemDir(beamSymbols) : args.stemDir;
5753
+ } else {
5754
+ setStemDir = beamSymbols[0].stemDir;
5755
+ }
5756
+ }
5757
+ sym.updateRunningArguments(args.diatonicId, setStemDir, args.stringNumbers);
5758
+ });
5759
+ });
5760
+ (_a = this.getNextMeasure()) == null ? void 0 : _a.updateRunningArguments(runningArgs);
5726
5761
  }
5727
5762
  pick(x, y) {
5728
5763
  if (!this.getRect().contains(x, y)) {
@@ -5824,7 +5859,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5824
5859
  this.alterKeySignature = args[0];
5825
5860
  } else if (args[0] instanceof import_theory9.Scale) {
5826
5861
  this.alterKeySignature = args[0];
5827
- } else if (import_ts_utils_lib13.Utils.Is.isNonEmptyString(args[0])) {
5862
+ } else if (import_ts_utils_lib14.Utils.Is.isNonEmptyString(args[0])) {
5828
5863
  if (args.length === 1) {
5829
5864
  this.alterKeySignature = (0, import_theory9.getScale)(args[0]);
5830
5865
  } else if (args.length === 2) {
@@ -5935,7 +5970,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5935
5970
  let grp = this.doc.getStaffGroup(staffTabOrGroup);
5936
5971
  if (grp && !prevGroups.includes(staffTabOrGroup)) {
5937
5972
  let curGroups = [...prevGroups, staffTabOrGroup];
5938
- (import_ts_utils_lib13.Utils.Is.isArray(grp.staffsTabsAndGroups) ? grp.staffsTabsAndGroups : [grp.staffsTabsAndGroups]).forEach((staffTabOrGroup2) => {
5973
+ (import_ts_utils_lib14.Utils.Is.isArray(grp.staffsTabsAndGroups) ? grp.staffsTabsAndGroups : [grp.staffsTabsAndGroups]).forEach((staffTabOrGroup2) => {
5939
5974
  switch (grp.verticalPosition) {
5940
5975
  case "above" /* Above */:
5941
5976
  addToStaffTabOrGroup(staffTabOrGroup2, 0 /* Above */, curGroups);
@@ -5962,7 +5997,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5962
5997
  } else {
5963
5998
  addToStaffTabOrGroup(0, defaultVerticalPos);
5964
5999
  }
5965
- } else if (import_ts_utils_lib13.Utils.Is.isArray(staffTabOrGroups)) {
6000
+ } else if (import_ts_utils_lib14.Utils.Is.isArray(staffTabOrGroups)) {
5966
6001
  staffTabOrGroups.forEach((staffTabOrGroup) => addToStaffTabOrGroup(staffTabOrGroup, defaultVerticalPos));
5967
6002
  } else {
5968
6003
  addToStaffTabOrGroup(staffTabOrGroups, defaultVerticalPos);
@@ -6046,7 +6081,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6046
6081
  case "endRepeat" /* EndRepeat */:
6047
6082
  if (args.length === 0) {
6048
6083
  this.endRepeatPlayCount = 2;
6049
- } else if (import_ts_utils_lib13.Utils.Is.isIntegerGte(args[0], 2)) {
6084
+ } else if (import_ts_utils_lib14.Utils.Is.isIntegerGte(args[0], 2)) {
6050
6085
  this.endRepeatPlayCount = args[0];
6051
6086
  } else {
6052
6087
  throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Invalid end repeat play count (should be 2 or greater integer): " + args[0]);
@@ -6133,15 +6168,15 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6133
6168
  throw new import_core14.MusicError(import_core14.MusicErrorType.Score, "Connective can be added to note group only.");
6134
6169
  }
6135
6170
  if (connective === "tie" /* Tie */) {
6136
- let tieSpan = import_ts_utils_lib13.Utils.Is.isInteger(args[0]) || import_ts_utils_lib13.Utils.Is.isEnumValue(args[0], TieType) ? args[0] : 2;
6137
- let noteAnchor = import_ts_utils_lib13.Utils.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : "auto" /* Auto */;
6171
+ let tieSpan = import_ts_utils_lib14.Utils.Is.isInteger(args[0]) || import_ts_utils_lib14.Utils.Is.isEnumValue(args[0], TieType) ? args[0] : 2;
6172
+ let noteAnchor = import_ts_utils_lib14.Utils.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : "auto" /* Auto */;
6138
6173
  anchor.startConnective(new ConnectiveProps("tie" /* Tie */, tieSpan, noteAnchor, anchor));
6139
6174
  } else if (connective === "slur" /* Slur */) {
6140
- let slurSpan = import_ts_utils_lib13.Utils.Is.isInteger(args[0]) ? args[0] : 2;
6141
- let noteAnchor = import_ts_utils_lib13.Utils.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : "auto" /* Auto */;
6175
+ let slurSpan = import_ts_utils_lib14.Utils.Is.isInteger(args[0]) ? args[0] : 2;
6176
+ let noteAnchor = import_ts_utils_lib14.Utils.Is.isEnumValue(args[1], NoteAnchor) ? args[1] : "auto" /* Auto */;
6142
6177
  anchor.startConnective(new ConnectiveProps("slur" /* Slur */, slurSpan, noteAnchor, anchor));
6143
6178
  } else if (connective === "slide" /* Slide */) {
6144
- let noteAnchor = import_ts_utils_lib13.Utils.Is.isEnumValue(args[0], NoteAnchor) ? args[0] : "auto" /* Auto */;
6179
+ let noteAnchor = import_ts_utils_lib14.Utils.Is.isEnumValue(args[0], NoteAnchor) ? args[0] : "auto" /* Auto */;
6145
6180
  anchor.startConnective(new ConnectiveProps("slide" /* Slide */, 2, noteAnchor, anchor));
6146
6181
  }
6147
6182
  }
@@ -6223,16 +6258,15 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6223
6258
  }
6224
6259
  addLyrics(staffTabOrGroups, verse, lyricsLength, lyricsText, lyricsOptions) {
6225
6260
  this.forEachStaffGroup(staffTabOrGroups, 1 /* Below */, (line, vpos) => {
6261
+ var _a;
6226
6262
  let col = this.getRhythmColumn({ verse, line, vpos });
6227
- let lyricsContainer = col.getLyricsContainer(verse, line, vpos, (0, import_theory9.validateNoteLength)(lyricsLength));
6228
- if (lyricsContainer) {
6229
- let lyricsObj = new ObjLyrics(col, verse, line, vpos, lyricsText, lyricsOptions);
6230
- let lyricsArr = this.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
6231
- lyricsArr.push(lyricsObj);
6232
- lyricsArr.sort((a, b) => import_ts_utils_lib13.Utils.Math.cmp(a.col.positionTicks, b.col.positionTicks));
6233
- lyricsContainer.addLyricsObject(lyricsObj);
6234
- this.addLayoutObject(lyricsObj, line, getVerseLayoutGroupId(verse), vpos);
6235
- }
6263
+ let lyricsObj = new ObjLyrics(col, verse, line, vpos, (0, import_theory9.validateNoteLength)(lyricsLength), lyricsText, lyricsOptions);
6264
+ col.addLyricsObject(lyricsObj);
6265
+ let lyricsArr = this.getLyricsObjects(line, vpos, verse);
6266
+ lyricsArr.push(lyricsObj);
6267
+ lyricsArr.sort((a, b) => import_ts_utils_lib14.Utils.Math.cmp(a.col.positionTicks, b.col.positionTicks));
6268
+ (_a = lyricsObj.measure.getPrevLyricsObject(lyricsObj)) == null ? void 0 : _a.setNextLyricsObject(lyricsObj);
6269
+ this.addLayoutObject(lyricsObj, line, getVerseLayoutGroupId(verse), vpos);
6236
6270
  this.lastAddedRhythmColumn = col;
6237
6271
  });
6238
6272
  }
@@ -6245,7 +6279,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6245
6279
  let positionTicks = 0;
6246
6280
  for (let i = this.columns.length - 1; i >= 0 && positionTicks === 0; i--) {
6247
6281
  let col = this.columns[i];
6248
- let symbol = typeof arg === "number" ? col.getVoiceSymbol(arg) : col.getLyricsContainer(arg.verse, arg.line, arg.vpos);
6282
+ let symbol = typeof arg === "number" ? col.getVoiceSymbol(arg) : col.getLyricsObject(arg.verse, arg.line, arg.vpos);
6249
6283
  if (symbol) {
6250
6284
  positionTicks = col.positionTicks + symbol.rhythmProps.ticks;
6251
6285
  }
@@ -6313,28 +6347,21 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6313
6347
  return this.barLineRight.getRect().centerX;
6314
6348
  }
6315
6349
  getLyricsObjects(line, vpos, verse) {
6316
- let vposMap = this.lyricsObjectsCache.get(line);
6317
- if (vposMap === void 0) {
6318
- this.lyricsObjectsCache.set(line, vposMap = /* @__PURE__ */ new Map());
6319
- }
6320
- let verseMap = vposMap.get(vpos);
6321
- if (verseMap === void 0) {
6322
- vposMap.set(vpos, verseMap = /* @__PURE__ */ new Map());
6350
+ let lyricsObjs = this.lyricsObjectsCache.get(line, vpos, verse);
6351
+ if (!lyricsObjs) {
6352
+ this.lyricsObjectsCache.set(line, vpos, verse, lyricsObjs = []);
6323
6353
  }
6324
- let lyricsArr = verseMap.get(verse);
6325
- if (lyricsArr === void 0) {
6326
- verseMap.set(verse, lyricsArr = []);
6327
- }
6328
- return lyricsArr;
6354
+ return lyricsObjs;
6329
6355
  }
6330
6356
  getPrevLyricsObject(lyricsObj) {
6331
6357
  var _a;
6332
- let lyricsArr = this.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
6358
+ let { line, verse, vpos } = lyricsObj;
6359
+ let lyricsArr = this.getLyricsObjects(line, vpos, verse);
6333
6360
  let i = lyricsArr.indexOf(lyricsObj);
6334
6361
  if (i > 0) {
6335
6362
  return lyricsArr[i - 1];
6336
6363
  } else if (i === 0) {
6337
- let lyricsArr2 = (_a = lyricsObj.measure.getPrevMeasure()) == null ? void 0 : _a.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
6364
+ let lyricsArr2 = (_a = lyricsObj.measure.getPrevMeasure()) == null ? void 0 : _a.getLyricsObjects(line, vpos, verse);
6338
6365
  if (lyricsArr2 && lyricsArr2.length > 0) {
6339
6366
  return lyricsArr2[lyricsArr2.length - 1];
6340
6367
  }
@@ -6448,7 +6475,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6448
6475
  let beamGroupSize = ts.beamGroupSizes[groupId];
6449
6476
  let beamGroupSizeList = [beamGroupSize];
6450
6477
  if (beamGroupSize.length > 1) {
6451
- beamGroupSizeList.unshift([import_ts_utils_lib13.Utils.Math.sum(beamGroupSize)]);
6478
+ beamGroupSizeList.unshift([import_ts_utils_lib14.Utils.Math.sum(beamGroupSize)]);
6452
6479
  }
6453
6480
  let beamCreated = false;
6454
6481
  let groupStartTicksSave = groupStartTicks;
@@ -6463,7 +6490,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6463
6490
  let symbolEndTicks = symbolStartTicks + symbol.rhythmProps.ticks;
6464
6491
  return symbolStartTicks >= groupStartTicks && symbolEndTicks <= groupEndTicks;
6465
6492
  });
6466
- let groupSymbolsTicks = import_ts_utils_lib13.Utils.Math.sum(groupSymbols.map((sym) => sym.rhythmProps.ticks));
6493
+ let groupSymbolsTicks = import_ts_utils_lib14.Utils.Math.sum(groupSymbols.map((sym) => sym.rhythmProps.ticks));
6467
6494
  if (groupSymbolsTicks === beamGroupTicks && groupSymbols.every((n) => n instanceof ObjNoteGroup) && (groupSymbols.every((n) => n.rhythmProps.flagCount === 1) || beamGroupSizeList.length === 0)) {
6468
6495
  if (ObjBeamGroup.createBeam(groupSymbols)) {
6469
6496
  beamCreated = true;
@@ -6497,7 +6524,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6497
6524
  this.completeRests(getVoiceIds().filter((id) => this.getConsumedTicks(id) > 0));
6498
6525
  }
6499
6526
  return;
6500
- } else if (import_ts_utils_lib13.Utils.Is.isArray(voiceId)) {
6527
+ } else if (import_ts_utils_lib14.Utils.Is.isArray(voiceId)) {
6501
6528
  voiceId.forEach((id) => this.completeRests(id));
6502
6529
  return;
6503
6530
  } else {
@@ -6527,20 +6554,20 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6527
6554
  this.row.requestLayout();
6528
6555
  }
6529
6556
  }
6530
- layout(renderer) {
6557
+ layout(ctx) {
6531
6558
  var _a;
6532
6559
  if (!this.needLayout) {
6533
6560
  return;
6534
6561
  }
6535
6562
  this.staticObjectsCache.clear();
6536
6563
  this.requestRectUpdate();
6537
- let { unitSize } = renderer;
6564
+ let { unitSize } = ctx;
6538
6565
  this.postMeasureBreakWidth = this.hasPostMeasureBreak() ? DocumentSettings.PostMeasureBreakWidth * unitSize : 0;
6539
6566
  let isFirstMeasureInRow = this === this.row.getFirstMeasure();
6540
6567
  let isAfterMeasureBreak = ((_a = this.getPrevMeasure()) == null ? void 0 : _a.hasPostMeasureBreak()) === true;
6541
6568
  this.tabStringNotesWidth = isFirstMeasureInRow && this.row.hasTab ? unitSize * 4 : 0;
6542
6569
  let showClef = isFirstMeasureInRow || isAfterMeasureBreak;
6543
- let showMeasureNumber = isFirstMeasureInRow && !this.row.isFirstRow();
6570
+ let showMeasureNumber = this.options.showNumber === false ? false : this.options.showNumber === true || isFirstMeasureInRow && !this.row.isFirstRow();
6544
6571
  let showKeySignature = isFirstMeasureInRow || isAfterMeasureBreak || !!this.alterKeySignature;
6545
6572
  let showTimeSignature = !!this.alterTimeSignature;
6546
6573
  let showTempo = !!this.alterTempo;
@@ -6550,12 +6577,12 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6550
6577
  let oldSignature = this.signatures.filter((s) => s instanceof ObjStaffSignature).find((s) => s.staff === line);
6551
6578
  let signature = oldSignature != null ? oldSignature : new ObjStaffSignature(this, line);
6552
6579
  signature.staff.addObject(signature);
6553
- signature.updateClefImage(renderer, showClef);
6580
+ signature.updateClefImage(ctx, showClef);
6554
6581
  signature.updateMeasureNumber(showMeasureNumber && lineId === 0);
6555
6582
  signature.updateKeySignature(showKeySignature);
6556
6583
  signature.updateTimeSignature(showTimeSignature);
6557
6584
  signature.updateTempo(showTempo && lineId === 0);
6558
- signature.layout(renderer);
6585
+ signature.layout(ctx);
6559
6586
  this.signatures.push(signature);
6560
6587
  } else if (line instanceof ObjTab && (showMeasureNumber || showTimeSignature || showTempo)) {
6561
6588
  let oldSignature = this.signatures.filter((s) => s instanceof ObjTabSignature).find((s) => s.tab === line);
@@ -6564,7 +6591,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6564
6591
  signature.updateMeasureNumber(showMeasureNumber && lineId === 0);
6565
6592
  signature.updateTimeSignature(showTimeSignature);
6566
6593
  signature.updateTempo(showTempo && lineId === 0);
6567
- signature.layout(renderer);
6594
+ signature.layout(ctx);
6568
6595
  this.signatures.push(signature);
6569
6596
  }
6570
6597
  });
@@ -6574,29 +6601,29 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6574
6601
  for (let stringId = 0; stringId < 6; stringId++) {
6575
6602
  let note = tab.getTuningStrings()[stringId].format(import_theory9.PitchNotation.Helmholtz, import_theory9.SymbolSet.Unicode);
6576
6603
  let obj = new ObjText(this, { text: note, scale: 0.8 }, 1, 0.5);
6577
- obj.layout(renderer);
6604
+ obj.layout(ctx);
6578
6605
  obj.offset(this.tabStringNotesWidth * 0.8, tab.getStringY(stringId));
6579
6606
  this.tabStringNotes.push(obj);
6580
6607
  tab.addObject(obj);
6581
6608
  }
6582
6609
  });
6583
6610
  }
6584
- this.barLineLeft.layout(renderer);
6611
+ this.barLineLeft.layout(ctx);
6585
6612
  const accState = new AccidentalState(this);
6586
- this.columns.forEach((col) => col.layout(renderer, accState));
6587
- this.barLineRight.layout(renderer);
6613
+ this.columns.forEach((col) => col.layout(ctx, accState));
6614
+ this.barLineRight.layout(ctx);
6588
6615
  if (this.endRepeatPlayCountText) {
6589
- this.endRepeatPlayCountText.layout(renderer);
6616
+ this.endRepeatPlayCountText.layout(ctx);
6590
6617
  }
6591
- this.layoutObjects.forEach((layoutObj) => layoutObj.layout(renderer));
6592
- let padding = renderer.unitSize;
6618
+ this.layoutObjects.forEach((layoutObj) => layoutObj.layout(ctx));
6619
+ let padding = ctx.unitSize;
6593
6620
  this.leftSolidAreaWidth = this.tabStringNotesWidth + Math.max(0, ...this.signatures.map((signature) => signature.getRect().width)) + this.barLineLeft.getRect().width + padding;
6594
6621
  this.rightSolidAreaWidth = padding + this.barLineRight.getRect().width;
6595
6622
  this.minColumnsAreaWidth = 0;
6596
6623
  this.columns.forEach((col) => this.minColumnsAreaWidth += col.getRect().width);
6597
6624
  this.minColumnsAreaWidth = Math.max(this.minColumnsAreaWidth, _ObjMeasure.MinFlexContentWidth * unitSize);
6598
6625
  }
6599
- layoutWidth(renderer, width) {
6626
+ layoutWidth(ctx, width) {
6600
6627
  if (!this.needLayout) {
6601
6628
  return;
6602
6629
  }
@@ -6620,7 +6647,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6620
6647
  let columnsAreaLeft = this.rect.left + this.leftSolidAreaWidth;
6621
6648
  let columnsAreaRight = this.rect.right - this.rightSolidAreaWidth;
6622
6649
  let columnsAreaWidth = columnsAreaRight - columnsAreaLeft;
6623
- let columnsWidth = import_ts_utils_lib13.Utils.Math.sum(this.columns.map((col) => col.getRect().width));
6650
+ let columnsWidth = import_ts_utils_lib14.Utils.Math.sum(this.columns.map((col) => col.getRect().width));
6624
6651
  let columnScale = columnsAreaWidth / columnsWidth;
6625
6652
  let columnLeft = columnsAreaLeft;
6626
6653
  this.columns.forEach((col) => {
@@ -6630,22 +6657,22 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6630
6657
  columnLeft += rect.width * columnScale;
6631
6658
  });
6632
6659
  }
6633
- layoutConnectives(renderer) {
6660
+ layoutConnectives(ctx) {
6634
6661
  if (!this.needLayout) {
6635
6662
  return;
6636
6663
  }
6637
6664
  this.connectives.forEach((connective) => {
6638
- connective.layout(renderer);
6665
+ connective.layout(ctx);
6639
6666
  this.rect.top = Math.min(this.rect.top, connective.getRect().top);
6640
6667
  this.rect.bottom = Math.max(this.rect.bottom, connective.getRect().bottom);
6641
6668
  });
6642
6669
  }
6643
- layoutBeams(renderer) {
6670
+ layoutBeams(ctx) {
6644
6671
  if (!this.needLayout) {
6645
6672
  return;
6646
6673
  }
6647
6674
  this.beamGroups.forEach((beamGroup) => {
6648
- beamGroup.layout(renderer);
6675
+ beamGroup.layout(ctx);
6649
6676
  this.rect.top = Math.min(this.rect.top, beamGroup.getRect().top);
6650
6677
  this.rect.bottom = Math.max(this.rect.bottom, beamGroup.getRect().bottom);
6651
6678
  });
@@ -6705,13 +6732,13 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6705
6732
  this.rect.offsetInPlace(dx, dy);
6706
6733
  this.requestRectUpdate();
6707
6734
  }
6708
- draw(renderer) {
6709
- renderer.drawDebugRect(this.getRect());
6735
+ draw(ctx) {
6736
+ ctx.drawDebugRect(this.getRect());
6710
6737
  let left = this.getStaffLineLeft();
6711
6738
  let right = this.getStaffLineRight();
6712
- const drawLine = (y) => renderer.drawLine(left, y, right, y);
6713
- let { row } = this;
6714
- row.getNotationLines().forEach((line) => {
6739
+ ctx.color("black").lineWidth(1);
6740
+ const drawLine = (y) => ctx.strokeLine(left, y, right, y);
6741
+ this.row.getNotationLines().forEach((line) => {
6715
6742
  if (line instanceof ObjStaff) {
6716
6743
  for (let p = line.bottomLineDiatonicId; p <= line.topLineDiatonicId; p += 2) {
6717
6744
  drawLine(line.getDiatonicIdY(p));
@@ -6722,17 +6749,17 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6722
6749
  }
6723
6750
  }
6724
6751
  });
6725
- this.signatures.forEach((signature) => signature.draw(renderer));
6726
- this.tabStringNotes.forEach((obj) => obj.draw(renderer));
6727
- this.barLineLeft.draw(renderer);
6728
- this.columns.forEach((col) => col.draw(renderer));
6729
- this.barLineRight.draw(renderer);
6752
+ this.signatures.forEach((signature) => signature.draw(ctx));
6753
+ this.tabStringNotes.forEach((obj) => obj.draw(ctx));
6754
+ this.barLineLeft.draw(ctx);
6755
+ this.columns.forEach((col) => col.draw(ctx));
6756
+ this.barLineRight.draw(ctx);
6730
6757
  if (this.endRepeatPlayCountText) {
6731
- this.endRepeatPlayCountText.draw(renderer);
6758
+ this.endRepeatPlayCountText.draw(ctx);
6732
6759
  }
6733
- this.connectives.forEach((connective) => connective.draw(renderer));
6734
- this.layoutObjects.forEach((layoutObj) => layoutObj.musicObj.draw(renderer));
6735
- this.beamGroups.forEach((beam) => beam.draw(renderer));
6760
+ this.connectives.forEach((connective) => connective.draw(ctx));
6761
+ this.layoutObjects.forEach((layoutObj) => layoutObj.musicObj.draw(ctx));
6762
+ this.beamGroups.forEach((beam) => beam.draw(ctx));
6736
6763
  }
6737
6764
  };
6738
6765
  __publicField(_ObjMeasure, "MinFlexContentWidth", 10);
@@ -6802,11 +6829,11 @@ var LayoutObjectWrapper = class {
6802
6829
  isPositionResolved() {
6803
6830
  return this.positionResolved;
6804
6831
  }
6805
- resolveClosestToStaffY(renderer) {
6832
+ resolveClosestToStaffY(ctx) {
6806
6833
  let { musicObj, measure, verticalPos, line } = this;
6807
6834
  let lineTop = line.getTopLineY();
6808
6835
  let lineBottom = line.getBottomLineY();
6809
- let linePadding = renderer.unitSize * 2;
6836
+ let linePadding = ctx.unitSize * 2;
6810
6837
  let y = verticalPos === 1 /* Below */ ? lineBottom + linePadding + musicObj.getRect().toph : lineTop - linePadding - musicObj.getRect().bottomh;
6811
6838
  let staticObjects = measure.getStaticObjects(line);
6812
6839
  let objShapeRects = musicObj.getShapeRects();
@@ -6829,7 +6856,7 @@ var LayoutObjectWrapper = class {
6829
6856
  return void 0;
6830
6857
  }
6831
6858
  }
6832
- layout(renderer) {
6859
+ layout(ctx) {
6833
6860
  this.line.addObject(this);
6834
6861
  }
6835
6862
  offset(dx, dy) {
@@ -6864,20 +6891,21 @@ var LayoutGroup = class {
6864
6891
  }
6865
6892
  });
6866
6893
  }
6867
- clearPositionAndLayout(renderer) {
6894
+ clearPositionAndLayout(ctx) {
6868
6895
  this.layoutObjectTable.forEach((layoutObjects) => {
6869
6896
  layoutObjects.forEach((layoutObj) => {
6870
6897
  layoutObj.clearPositionResolved();
6871
- layoutObj.musicObj.layout(renderer);
6898
+ layoutObj.musicObj.layout(ctx);
6872
6899
  });
6873
6900
  });
6874
6901
  }
6875
6902
  };
6876
6903
 
6877
6904
  // src/score/engine/obj-staff-and-tab.ts
6878
- var ObjNotationLine4 = class extends MusicObject {
6879
- constructor(parent) {
6880
- super(parent);
6905
+ var ObjNotationLine5 = class extends MusicObject {
6906
+ constructor(row) {
6907
+ super(row);
6908
+ this.row = row;
6881
6909
  __publicField(this, "objects", []);
6882
6910
  __publicField(this, "layoutGroups", []);
6883
6911
  }
@@ -6894,18 +6922,18 @@ var ObjNotationLine4 = class extends MusicObject {
6894
6922
  }
6895
6923
  return layoutGroup;
6896
6924
  }
6897
- resetLayoutGroups(renderer) {
6925
+ resetLayoutGroups(ctx) {
6898
6926
  this.layoutGroups.forEach((layoutGroup) => {
6899
6927
  if (layoutGroup) {
6900
- layoutGroup.clearPositionAndLayout(renderer);
6928
+ layoutGroup.clearPositionAndLayout(ctx);
6901
6929
  }
6902
6930
  });
6903
6931
  }
6904
- layoutLayoutGroups(renderer) {
6932
+ layoutLayoutGroups(ctx) {
6905
6933
  this.layoutGroups.forEach((layoutGroup) => {
6906
6934
  if (layoutGroup) {
6907
- this.layoutLayoutGroup(renderer, layoutGroup, 0 /* Above */);
6908
- this.layoutLayoutGroup(renderer, layoutGroup, 1 /* Below */);
6935
+ this.layoutLayoutGroup(ctx, layoutGroup, 0 /* Above */);
6936
+ this.layoutLayoutGroup(ctx, layoutGroup, 1 /* Below */);
6909
6937
  }
6910
6938
  });
6911
6939
  }
@@ -6916,42 +6944,42 @@ var ObjNotationLine4 = class extends MusicObject {
6916
6944
  layoutObj.offset(0, y - layoutObj.getRect().centerY);
6917
6945
  layoutObj.setPositionResolved();
6918
6946
  }
6919
- alignObjectsY(renderer, layoutObjArr) {
6947
+ alignObjectsY(ctx, layoutObjArr) {
6920
6948
  layoutObjArr = layoutObjArr.filter((layoutObj) => !layoutObj.isPositionResolved());
6921
6949
  let rowY;
6922
6950
  layoutObjArr.forEach((layoutObj) => {
6923
- let y = layoutObj.resolveClosestToStaffY(renderer);
6951
+ let y = layoutObj.resolveClosestToStaffY(ctx);
6924
6952
  rowY = layoutObj.verticalPos === 1 /* Below */ ? Math.max(y, rowY != null ? rowY : y) : Math.min(y, rowY != null ? rowY : y);
6925
6953
  });
6926
6954
  layoutObjArr.forEach((layoutObj) => this.setObjectY(layoutObj, rowY));
6927
6955
  }
6928
- layoutLayoutGroup(renderer, layoutGroup, verticalPos) {
6956
+ layoutLayoutGroup(ctx, layoutGroup, verticalPos) {
6929
6957
  let rowLayoutObjs = layoutGroup.getLayoutObjects(verticalPos).filter((layoutObj) => !layoutObj.isPositionResolved());
6930
6958
  rowLayoutObjs.forEach((layoutObj) => {
6931
6959
  let { musicObj, anchor } = layoutObj;
6932
6960
  if (musicObj instanceof ObjEnding || musicObj instanceof ObjExtensionLine || musicObj instanceof ObjTabRhythm) {
6933
- musicObj.layoutFitToMeasure(renderer);
6961
+ musicObj.layoutFitToMeasure(ctx);
6934
6962
  } else {
6935
6963
  musicObj.offset(anchor.getRect().centerX - musicObj.getRect().centerX, 0);
6936
6964
  }
6937
6965
  });
6938
6966
  if (layoutGroup.rowAlign) {
6939
- this.alignObjectsY(renderer, rowLayoutObjs);
6967
+ this.alignObjectsY(ctx, rowLayoutObjs);
6940
6968
  } else {
6941
6969
  rowLayoutObjs.forEach((layoutObj) => {
6942
6970
  let link = layoutObj.musicObj.getLink();
6943
6971
  if (link && link.getHead() === layoutObj.musicObj) {
6944
6972
  let objectParts = [link.getHead(), ...link.getTails()];
6945
6973
  let layoutObjs = rowLayoutObjs.filter((layoutObj2) => objectParts.some((o) => o === layoutObj2.musicObj));
6946
- this.alignObjectsY(renderer, layoutObjs);
6974
+ this.alignObjectsY(ctx, layoutObjs);
6947
6975
  } else {
6948
- this.alignObjectsY(renderer, [layoutObj]);
6976
+ this.alignObjectsY(ctx, [layoutObj]);
6949
6977
  }
6950
6978
  });
6951
6979
  }
6952
6980
  }
6953
6981
  };
6954
- var ObjStaff = class extends ObjNotationLine4 {
6982
+ var ObjStaff = class extends ObjNotationLine5 {
6955
6983
  constructor(row, staffConfig, id) {
6956
6984
  super(row);
6957
6985
  this.row = row;
@@ -6970,11 +6998,11 @@ var ObjStaff = class extends ObjNotationLine4 {
6970
6998
  __publicField(this, "mi");
6971
6999
  const getDiatonicId = (noteName, isOctaveDown) => import_theory11.Note.getNote(noteName).diatonicId - (isOctaveDown ? 7 : 0);
6972
7000
  if (staffConfig.clef === "G" /* G */) {
6973
- this.clefImageAsset = 0 /* TrebleClefPng */;
7001
+ this.clefImageAsset = 0 /* G_Clef */;
6974
7002
  this.clefLineDiatonicId = getDiatonicId("G4", staffConfig.isOctaveDown === true);
6975
7003
  this.middleLineDiatonicId = this.clefLineDiatonicId + 2;
6976
7004
  } else if (staffConfig.clef === "F" /* F */) {
6977
- this.clefImageAsset = 1 /* BassClefPng */;
7005
+ this.clefImageAsset = 1 /* F_Clef */;
6978
7006
  this.clefLineDiatonicId = getDiatonicId("F3", staffConfig.isOctaveDown === true);
6979
7007
  this.middleLineDiatonicId = this.clefLineDiatonicId - 2;
6980
7008
  } else {
@@ -6996,6 +7024,9 @@ var ObjStaff = class extends ObjNotationLine4 {
6996
7024
  var _a;
6997
7025
  return (_a = this.staffConfig.name) != null ? _a : "";
6998
7026
  }
7027
+ getConfig() {
7028
+ return this.staffConfig;
7029
+ }
6999
7030
  getTopLineY() {
7000
7031
  return this.topLineY;
7001
7032
  }
@@ -7049,7 +7080,7 @@ var ObjStaff = class extends ObjNotationLine4 {
7049
7080
  return diatonicId % 2 !== this.middleLineDiatonicId % 2;
7050
7081
  }
7051
7082
  containsVoiceId(voiceId) {
7052
- return !this.staffConfig.voiceIds || this.staffConfig.voiceIds.includes(voiceId);
7083
+ return import_ts_utils_lib15.Utils.Is.isUndefined(this.staffConfig.voiceId) || import_ts_utils_lib15.Utils.Arr.toArray(this.staffConfig.voiceId).includes(voiceId);
7053
7084
  }
7054
7085
  calcTop() {
7055
7086
  let top = this.topLineY;
@@ -7072,16 +7103,16 @@ var ObjStaff = class extends ObjNotationLine4 {
7072
7103
  return bottom;
7073
7104
  }
7074
7105
  pick(x, y) {
7075
- return [this];
7106
+ return this.getRect().contains(x, y) ? [this] : [];
7076
7107
  }
7077
- layoutHeight(renderer) {
7078
- let { unitSize } = renderer;
7108
+ layoutHeight(ctx) {
7109
+ let { unitSize } = ctx;
7079
7110
  let h = unitSize * DocumentSettings.StaffHeight;
7080
7111
  this.topLineY = -h / 2;
7081
7112
  this.bottomLineY = h / 2;
7082
7113
  this.rect = new DivRect(0, 0, this.topLineY, this.bottomLineY);
7083
7114
  }
7084
- layoutWidth(renderer) {
7115
+ layoutWidth(ctx) {
7085
7116
  this.rect.left = this.row.getRect().left;
7086
7117
  this.rect.right = this.row.getRect().right;
7087
7118
  }
@@ -7097,10 +7128,10 @@ var ObjStaff = class extends ObjNotationLine4 {
7097
7128
  });
7098
7129
  this.rect.offsetInPlace(dx, dy);
7099
7130
  }
7100
- draw(renderer) {
7131
+ draw(ctx) {
7101
7132
  }
7102
7133
  };
7103
- var ObjTab = class extends ObjNotationLine4 {
7134
+ var ObjTab = class extends ObjNotationLine5 {
7104
7135
  constructor(row, tabConfig, id) {
7105
7136
  super(row);
7106
7137
  this.row = row;
@@ -7111,7 +7142,7 @@ var ObjTab = class extends ObjNotationLine4 {
7111
7142
  __publicField(this, "tuningName");
7112
7143
  __publicField(this, "tuningStrings");
7113
7144
  __publicField(this, "mi");
7114
- if (import_ts_utils_lib14.Utils.Is.isArray(tabConfig.tuning)) {
7145
+ if (import_ts_utils_lib15.Utils.Is.isArray(tabConfig.tuning)) {
7115
7146
  this.tuningName = void 0;
7116
7147
  this.tuningStrings = tabConfig.tuning.map((noteName) => import_theory11.Note.getNote(noteName)).reverse();
7117
7148
  } else if (typeof tabConfig.tuning === "string") {
@@ -7130,6 +7161,9 @@ var ObjTab = class extends ObjNotationLine4 {
7130
7161
  var _a;
7131
7162
  return (_a = this.tabConfig.name) != null ? _a : "";
7132
7163
  }
7164
+ getConfig() {
7165
+ return this.tabConfig;
7166
+ }
7133
7167
  getTuningName() {
7134
7168
  return this.tuningName;
7135
7169
  }
@@ -7159,7 +7193,7 @@ var ObjTab = class extends ObjNotationLine4 {
7159
7193
  return this.bottom;
7160
7194
  }
7161
7195
  containsVoiceId(voiceId) {
7162
- return !this.tabConfig.voiceIds || this.tabConfig.voiceIds.includes(voiceId);
7196
+ return import_ts_utils_lib15.Utils.Is.isUndefined(this.tabConfig.voiceId) || import_ts_utils_lib15.Utils.Arr.toArray(this.tabConfig.voiceId).includes(voiceId);
7163
7197
  }
7164
7198
  containsDiatonicId(diatonicId) {
7165
7199
  return true;
@@ -7175,16 +7209,16 @@ var ObjTab = class extends ObjNotationLine4 {
7175
7209
  return bottom;
7176
7210
  }
7177
7211
  pick(x, y) {
7178
- return [this];
7212
+ return this.getRect().contains(x, y) ? [this] : [];
7179
7213
  }
7180
- layoutHeight(renderer) {
7181
- let { unitSize } = renderer;
7214
+ layoutHeight(ctx) {
7215
+ let { unitSize } = ctx;
7182
7216
  let h = unitSize * DocumentSettings.TabHeight;
7183
7217
  this.top = -h / 2;
7184
7218
  this.bottom = h / 2;
7185
7219
  this.rect = new DivRect(0, 0, this.top, this.bottom);
7186
7220
  }
7187
- layoutWidth(renderer) {
7221
+ layoutWidth(ctx) {
7188
7222
  this.rect.left = this.row.getRect().left;
7189
7223
  this.rect.right = this.row.getRect().right;
7190
7224
  }
@@ -7200,12 +7234,13 @@ var ObjTab = class extends ObjNotationLine4 {
7200
7234
  });
7201
7235
  this.rect.offsetInPlace(dx, dy);
7202
7236
  }
7203
- draw(renderer) {
7237
+ draw(ctx) {
7204
7238
  }
7205
7239
  };
7206
7240
 
7207
7241
  // src/score/engine/obj-score-row.ts
7208
7242
  var import_core17 = require("@tspro/web-music-score/core");
7243
+ var import_ts_utils_lib16 = require("@tspro/ts-utils-lib");
7209
7244
  var ObjScoreRow = class extends MusicObject {
7210
7245
  constructor(doc, prevRow, scoreConfig) {
7211
7246
  super(doc);
@@ -7215,14 +7250,30 @@ var ObjScoreRow = class extends MusicObject {
7215
7250
  __publicField(this, "nextRow");
7216
7251
  __publicField(this, "minWidth", 0);
7217
7252
  __publicField(this, "notationLines");
7253
+ __publicField(this, "instrumentLineGroups");
7218
7254
  __publicField(this, "staves");
7219
7255
  __publicField(this, "tabs");
7256
+ __publicField(this, "instrumentNames");
7220
7257
  __publicField(this, "measures", []);
7221
7258
  __publicField(this, "needLayout", true);
7222
7259
  __publicField(this, "mi");
7223
7260
  this.notationLines = this.createNotationLines();
7224
7261
  this.staves = this.notationLines.filter((line) => line instanceof ObjStaff);
7225
7262
  this.tabs = this.notationLines.filter((line) => line instanceof ObjTab);
7263
+ let lineGroups = [];
7264
+ for (let i = 0; i < this.notationLines.length; i++) {
7265
+ let line = this.notationLines[i];
7266
+ let prevGroup = lineGroups[lineGroups.length - 1];
7267
+ if (prevGroup === void 0 || prevGroup[0].getConfig().instrument === void 0 || prevGroup[0].getConfig().instrument !== line.getConfig().instrument) {
7268
+ lineGroups.push([line]);
7269
+ } else {
7270
+ prevGroup.push(line);
7271
+ }
7272
+ }
7273
+ this.instrumentLineGroups = lineGroups;
7274
+ this.instrumentNames = this.instrumentLineGroups.map((lines) => {
7275
+ return lines.length > 0 && import_ts_utils_lib16.Utils.Is.isNonEmptyString(lines[0].getConfig().instrument) ? new ObjText(this, String(lines[0].getConfig().instrument), 0, 0.5) : void 0;
7276
+ });
7226
7277
  if (this.prevRow) {
7227
7278
  this.prevRow.nextRow = this;
7228
7279
  }
@@ -7246,6 +7297,14 @@ var ObjScoreRow = class extends MusicObject {
7246
7297
  getNotationLines() {
7247
7298
  return this.notationLines;
7248
7299
  }
7300
+ getInstrumentLineGroups() {
7301
+ return this.instrumentLineGroups;
7302
+ }
7303
+ findMatchingLine(line) {
7304
+ return line.row === this ? line : this.notationLines.find(
7305
+ (curLine) => import_ts_utils_lib16.Utils.Obj.deepEqual(line.row.scoreConfig, curLine.row.scoreConfig) && line.id === curLine.id || import_ts_utils_lib16.Utils.Is.isNonEmptyString(line.getConfig().name) && line.getConfig().name === curLine.getConfig().name && line.getConfig().type === curLine.getConfig().type
7306
+ );
7307
+ }
7249
7308
  getStaves() {
7250
7309
  return this.staves;
7251
7310
  }
@@ -7284,13 +7343,14 @@ var ObjScoreRow = class extends MusicObject {
7284
7343
  }
7285
7344
  return void 0;
7286
7345
  }
7287
- resetLayoutGroups(renderer) {
7288
- this.notationLines.forEach((line) => line.resetLayoutGroups(renderer));
7346
+ resetLayoutGroups(ctx) {
7347
+ this.notationLines.forEach((line) => line.resetLayoutGroups(ctx));
7289
7348
  }
7290
- layoutLayoutGroups(renderer) {
7291
- this.notationLines.forEach((line) => line.layoutLayoutGroups(renderer));
7349
+ layoutLayoutGroups(ctx) {
7350
+ this.notationLines.forEach((line) => line.layoutLayoutGroups(ctx));
7292
7351
  }
7293
7352
  pick(x, y) {
7353
+ var _a, _b;
7294
7354
  if (!this.getRect().contains(x, y)) {
7295
7355
  return [];
7296
7356
  }
@@ -7300,6 +7360,12 @@ var ObjScoreRow = class extends MusicObject {
7300
7360
  return [this, ...arr];
7301
7361
  }
7302
7362
  }
7363
+ for (let i = 0; i < this.instrumentNames.length; i++) {
7364
+ let arr = (_b = (_a = this.instrumentNames[i]) == null ? void 0 : _a.pick(x, y)) != null ? _b : [];
7365
+ if (arr.length > 0) {
7366
+ return [this, ...arr];
7367
+ }
7368
+ }
7303
7369
  for (let i = 0; i < this.notationLines.length; i++) {
7304
7370
  let arr = this.notationLines[i].pick(x, y);
7305
7371
  if (arr.length > 0) {
@@ -7351,61 +7417,78 @@ var ObjScoreRow = class extends MusicObject {
7351
7417
  getMinWidth() {
7352
7418
  return this.minWidth;
7353
7419
  }
7420
+ solveAutoStemDir(symbols) {
7421
+ if (symbols.length === 0) {
7422
+ return "up" /* Up */;
7423
+ } else {
7424
+ let voiceId = symbols[0].voiceId;
7425
+ let noteGroupDiatonicIds = symbols.filter((sym) => sym instanceof ObjNoteGroup).map((n) => n.setDiatonicId);
7426
+ let restDiatonicIds = symbols.filter((sym) => sym instanceof ObjRest && sym.setDiatonicId !== ObjRest.UndefinedDiatonicId).map((r) => r.setDiatonicId);
7427
+ if (noteGroupDiatonicIds.length === 0 && restDiatonicIds.length === 0) {
7428
+ return "up" /* Up */;
7429
+ }
7430
+ let diatonicIds = noteGroupDiatonicIds.length > 0 ? noteGroupDiatonicIds : restDiatonicIds;
7431
+ let avgDiatonicId = Math.floor(import_ts_utils_lib16.Utils.Math.avg(...diatonicIds));
7432
+ let staves = this.getStaves().filter((staff) => staff.containsVoiceId(voiceId) && staff.containsDiatonicId(avgDiatonicId));
7433
+ return staves.length > 0 ? avgDiatonicId >= staves[0].middleLineDiatonicId ? "down" /* Down */ : "up" /* Up */ : "up" /* Up */;
7434
+ }
7435
+ }
7436
+ getInstrumentNameWidth(ctx) {
7437
+ return Math.max(0, ...this.instrumentNames.map((obj) => obj ? obj.getRect().width : 0));
7438
+ }
7354
7439
  requestLayout() {
7355
7440
  if (!this.needLayout) {
7356
7441
  this.needLayout = true;
7357
7442
  this.doc.requestLayout();
7358
7443
  }
7359
7444
  }
7360
- layout(renderer) {
7445
+ layout(ctx) {
7361
7446
  if (!this.needLayout) {
7362
7447
  return;
7363
7448
  }
7364
7449
  this.requestRectUpdate();
7450
+ this.instrumentNames.forEach((obj) => obj == null ? void 0 : obj.layout(ctx));
7365
7451
  this.notationLines.forEach((line) => {
7366
7452
  line.removeObjects();
7367
- line.layoutHeight(renderer);
7453
+ line.layoutHeight(ctx);
7368
7454
  });
7369
- this.rect = new DivRect(0, 0, 0, 0);
7370
7455
  this.minWidth = 0;
7371
7456
  this.measures.forEach((m) => {
7372
- m.layout(renderer);
7457
+ m.layout(ctx);
7373
7458
  this.minWidth += m.getMinWidth();
7374
7459
  this.minWidth += m.getPostMeasureBreakWidth();
7375
7460
  });
7376
7461
  }
7377
- layoutWidth(renderer, width) {
7462
+ layoutWidth(ctx, left, right) {
7378
7463
  if (!this.needLayout) {
7379
7464
  return;
7380
7465
  }
7381
- let rowWidth = Math.max(width, this.minWidth);
7382
- this.rect.centerX = this.rect.left + rowWidth / 2;
7383
- this.rect.right = this.rect.left + rowWidth;
7384
- this.notationLines.forEach((line) => line.layoutWidth(renderer));
7385
- let targetColumnsAreaWidth = rowWidth;
7466
+ this.rect = new DivRect(0, right, 0, 0);
7467
+ this.notationLines.forEach((line) => line.layoutWidth(ctx));
7468
+ let targetColumnsAreaWidth = right - left;
7386
7469
  let minColumnsAreaWidth = 0;
7387
7470
  this.measures.forEach((m) => {
7388
7471
  targetColumnsAreaWidth -= m.getSolidAreaWidth() + m.getPostMeasureBreakWidth();
7389
7472
  minColumnsAreaWidth += m.getMinColumnsAreaWidth();
7390
7473
  });
7391
7474
  let columnsAreaScale = targetColumnsAreaWidth / minColumnsAreaWidth;
7392
- let x = 0;
7475
+ let x = this.doc.getInstrumentGroupSize(ctx).braceRight;
7393
7476
  this.measures.forEach((m) => {
7394
7477
  let newMeasureWidth = m.getSolidAreaWidth() + m.getMinColumnsAreaWidth() * columnsAreaScale;
7395
- m.layoutWidth(renderer, newMeasureWidth);
7478
+ m.layoutWidth(ctx, newMeasureWidth);
7396
7479
  let r = m.getRect();
7397
7480
  m.offset(x - r.left, -r.centerY);
7398
7481
  x += r.width;
7399
7482
  x += m.getPostMeasureBreakWidth();
7400
7483
  });
7401
7484
  this.measures.forEach((m) => {
7402
- m.layoutConnectives(renderer);
7403
- m.layoutBeams(renderer);
7485
+ m.layoutConnectives(ctx);
7486
+ m.layoutBeams(ctx);
7404
7487
  });
7405
7488
  }
7406
7489
  updateRect() {
7407
- let left = this.measures.length > 0 ? this.measures[0].getRect().left : 0;
7408
- let right = this.measures.length > 0 ? this.measures[this.measures.length - 1].getRect().right : 0;
7490
+ let left = 0;
7491
+ let right = this.measures.length > 0 ? this.measures[this.measures.length - 1].getRect().right : left;
7409
7492
  let top = this.measures.length > 0 ? Math.min(...this.measures.map((m) => m.getRect().top)) : 0;
7410
7493
  let bottom = this.measures.length > 0 ? Math.max(...this.measures.map((m) => m.getRect().bottom)) : 0;
7411
7494
  this.rect = new DivRect(left, right, top, bottom);
@@ -7413,8 +7496,8 @@ var ObjScoreRow = class extends MusicObject {
7413
7496
  alignStemsToBeams() {
7414
7497
  this.measures.forEach((m) => m.alignStemsToBeams());
7415
7498
  }
7416
- layoutSetNotationLines(renderer) {
7417
- let { unitSize } = renderer;
7499
+ layoutSetNotationLines(ctx) {
7500
+ let { unitSize } = ctx;
7418
7501
  for (let i = 1; i < this.notationLines.length; i++) {
7419
7502
  let prev = this.notationLines[i - 1];
7420
7503
  let cur = this.notationLines[i];
@@ -7438,11 +7521,20 @@ var ObjScoreRow = class extends MusicObject {
7438
7521
  });
7439
7522
  });
7440
7523
  });
7524
+ this.instrumentNames.forEach((obj, i) => {
7525
+ let grp = this.instrumentLineGroups[i];
7526
+ if (obj && grp.length > 0) {
7527
+ obj.offset(
7528
+ -obj.getRect().left,
7529
+ -obj.getRect().centerY + (grp[0].getRect().top + grp[grp.length - 1].getRect().bottom) / 2
7530
+ );
7531
+ }
7532
+ });
7441
7533
  this.alignStemsToBeams();
7442
7534
  this.requestRectUpdate();
7443
7535
  }
7444
- layoutPadding(renderer) {
7445
- let p = renderer.unitSize / 2;
7536
+ layoutPadding(ctx) {
7537
+ let p = ctx.unitSize / 2;
7446
7538
  this.getRect();
7447
7539
  this.rect.left -= p;
7448
7540
  this.rect.right += p;
@@ -7457,24 +7549,38 @@ var ObjScoreRow = class extends MusicObject {
7457
7549
  this.measures.forEach((m) => m.offset(dx, dy));
7458
7550
  this.rect.offsetInPlace(dx, dy);
7459
7551
  this.notationLines.forEach((l) => l.offset(dx, dy));
7552
+ this.instrumentNames.forEach((obj) => obj == null ? void 0 : obj.offset(dx, dy));
7460
7553
  }
7461
- draw(renderer) {
7462
- let ctx = renderer.getCanvasContext();
7463
- if (!ctx) {
7464
- return;
7465
- }
7466
- renderer.drawDebugRect(this.getRect());
7554
+ draw(ctx) {
7555
+ ctx.drawDebugRect(this.getRect());
7467
7556
  ctx.save();
7468
- ctx.rect(this.getRect().left, this.getRect().top, this.getRect().width, this.getRect().height);
7557
+ let { left, top, width, height } = this.getRect();
7558
+ ctx.rect(left, top, width, height);
7469
7559
  ctx.clip();
7470
7560
  if (this.getFirstMeasure() && (this.notationLines.length > 1 || this.notationLines[0] instanceof ObjTab)) {
7471
- let left = this.getFirstMeasure().getStaffLineLeft();
7472
- let top = Math.min(...this.notationLines.map((line) => line.getTopLineY()));
7561
+ let left2 = this.getFirstMeasure().getStaffLineLeft();
7562
+ let top2 = Math.min(...this.notationLines.map((line) => line.getTopLineY()));
7473
7563
  let bottom = Math.max(...this.notationLines.map((line) => line.getBottomLineY()));
7474
- renderer.drawLine(left, top, left, bottom);
7475
- }
7476
- this.measures.forEach((m) => m.draw(renderer));
7477
- this.notationLines.forEach((m) => m.draw(renderer));
7564
+ ctx.color("black").lineWidth(1).strokeLine(left2, top2, left2, bottom);
7565
+ }
7566
+ this.measures.forEach((m) => m.draw(ctx));
7567
+ this.notationLines.forEach((m) => m.draw(ctx));
7568
+ let grpSize = this.doc.getInstrumentGroupSize(ctx);
7569
+ this.instrumentNames.forEach((obj, i) => {
7570
+ let grp = this.instrumentLineGroups[i];
7571
+ if (grp.length > 1) {
7572
+ let r = new DivRect(
7573
+ grpSize.braceLeft,
7574
+ grpSize.braceRight,
7575
+ grp[0].getTopLineY(),
7576
+ grp[grp.length - 1].getBottomLineY()
7577
+ );
7578
+ ctx.color("brack").lineWidth(1).drawBrace(r, "left");
7579
+ }
7580
+ if (obj) {
7581
+ obj.draw(ctx);
7582
+ }
7583
+ });
7478
7584
  ctx.restore();
7479
7585
  }
7480
7586
  };
@@ -7522,24 +7628,24 @@ var ObjHeader = class extends MusicObject {
7522
7628
  }
7523
7629
  return [this];
7524
7630
  }
7525
- layoutWidth(renderer, width) {
7631
+ layoutWidth(ctx, left, right) {
7526
7632
  let top = 0;
7527
- this.rect = new DivRect(0, width, 0, 0);
7633
+ this.rect = new DivRect(left, right, 0, 0);
7528
7634
  if (this.titleText) {
7529
- this.titleText.layout(renderer);
7530
- this.titleText.offset(width / 2, top);
7635
+ this.titleText.layout(ctx);
7636
+ this.titleText.offset((left + right) / 2, top);
7531
7637
  top += this.titleText.getRect().height;
7532
7638
  this.rect.expandInPlace(this.titleText.getRect());
7533
7639
  }
7534
7640
  if (this.composerText) {
7535
- this.composerText.layout(renderer);
7536
- this.composerText.offset(width, top);
7641
+ this.composerText.layout(ctx);
7642
+ this.composerText.offset(right, top);
7537
7643
  top += this.composerText.getRect().height;
7538
7644
  this.rect.expandInPlace(this.composerText.getRect());
7539
7645
  }
7540
7646
  if (this.arrangerText) {
7541
- this.arrangerText.layout(renderer);
7542
- this.arrangerText.offset(width, top);
7647
+ this.arrangerText.layout(ctx);
7648
+ this.arrangerText.offset(right, top);
7543
7649
  top += this.arrangerText.getRect().height;
7544
7650
  this.rect.expandInPlace(this.arrangerText.getRect());
7545
7651
  }
@@ -7556,27 +7662,27 @@ var ObjHeader = class extends MusicObject {
7556
7662
  }
7557
7663
  this.rect.offsetInPlace(dx, dy);
7558
7664
  }
7559
- draw(renderer) {
7665
+ draw(ctx) {
7560
7666
  if (this.titleText) {
7561
- this.titleText.draw(renderer);
7667
+ this.titleText.draw(ctx);
7562
7668
  }
7563
7669
  if (this.composerText) {
7564
- this.composerText.draw(renderer);
7670
+ this.composerText.draw(ctx);
7565
7671
  }
7566
7672
  if (this.arrangerText) {
7567
- this.arrangerText.draw(renderer);
7673
+ this.arrangerText.draw(ctx);
7568
7674
  }
7569
7675
  }
7570
7676
  };
7571
7677
 
7572
7678
  // src/score/engine/obj-document.ts
7573
- var import_ts_utils_lib15 = require("@tspro/ts-utils-lib");
7679
+ var import_ts_utils_lib17 = require("@tspro/ts-utils-lib");
7574
7680
  var import_core18 = require("@tspro/web-music-score/core");
7575
7681
  var ObjDocument = class extends MusicObject {
7576
7682
  constructor() {
7577
7683
  super(void 0);
7578
7684
  __publicField(this, "needLayout", true);
7579
- __publicField(this, "renderer");
7685
+ __publicField(this, "ctx");
7580
7686
  __publicField(this, "rows", []);
7581
7687
  __publicField(this, "measures", []);
7582
7688
  __publicField(this, "measuresPerRow", Infinity);
@@ -7592,7 +7698,7 @@ var ObjDocument = class extends MusicObject {
7592
7698
  return this.mi;
7593
7699
  }
7594
7700
  setScoreConfiguration(config) {
7595
- if (import_ts_utils_lib15.Utils.Is.isEnumValue(config, StaffPreset)) {
7701
+ if (import_ts_utils_lib17.Utils.Is.isEnumValue(config, StaffPreset)) {
7596
7702
  switch (config) {
7597
7703
  default:
7598
7704
  case "treble" /* Treble */:
@@ -7620,7 +7726,7 @@ var ObjDocument = class extends MusicObject {
7620
7726
  ];
7621
7727
  break;
7622
7728
  }
7623
- } else if (import_ts_utils_lib15.Utils.Is.isArray(config)) {
7729
+ } else if (import_ts_utils_lib17.Utils.Is.isArray(config)) {
7624
7730
  this.curScoreConfig = config;
7625
7731
  } else {
7626
7732
  this.curScoreConfig = [config];
@@ -7681,17 +7787,17 @@ var ObjDocument = class extends MusicObject {
7681
7787
  addConnectiveProps(connectiveProps) {
7682
7788
  this.allConnectiveProps.push(connectiveProps);
7683
7789
  }
7684
- setRenderer(renderer) {
7685
- if (this.renderer === renderer) {
7790
+ setRenderContext(ctx) {
7791
+ if (this.ctx === ctx) {
7686
7792
  return;
7687
7793
  }
7688
- let prevRenderer = this.renderer;
7689
- this.renderer = renderer;
7690
- if (prevRenderer) {
7691
- prevRenderer.setDocument(void 0);
7794
+ let prevCtx = this.ctx;
7795
+ this.ctx = ctx;
7796
+ if (prevCtx) {
7797
+ prevCtx.setDocument(void 0);
7692
7798
  }
7693
- if (renderer) {
7694
- renderer.setDocument(this.mi);
7799
+ if (ctx) {
7800
+ ctx.setDocument(this.mi);
7695
7801
  }
7696
7802
  this.requestFullLayout();
7697
7803
  }
@@ -7740,13 +7846,13 @@ var ObjDocument = class extends MusicObject {
7740
7846
  requestNewRow() {
7741
7847
  this.newRowRequested = true;
7742
7848
  }
7743
- addMeasure() {
7849
+ addMeasure(measureOptions) {
7744
7850
  let lastRow = this.rows[this.rows.length - 1];
7745
7851
  if (!lastRow || this.newRowRequested && lastRow.getMeasures().length > 0 || lastRow.getMeasures().length >= this.measuresPerRow) {
7746
7852
  lastRow = this.addNewRow(lastRow);
7747
7853
  this.newRowRequested = false;
7748
7854
  }
7749
- let measure = new ObjMeasure2(lastRow);
7855
+ let measure = new ObjMeasure2(lastRow, measureOptions);
7750
7856
  this.measures.push(measure);
7751
7857
  lastRow.addMeasure(measure);
7752
7858
  this.requestLayout();
@@ -7777,9 +7883,21 @@ var ObjDocument = class extends MusicObject {
7777
7883
  this.measures.forEach((m) => m.resetPassCount());
7778
7884
  }
7779
7885
  updateCursorRect(cursorRect) {
7780
- if (this.renderer) {
7781
- this.renderer.updateCursorRect(cursorRect);
7782
- }
7886
+ if (this.ctx) {
7887
+ this.ctx.updateCursorRect(cursorRect);
7888
+ }
7889
+ }
7890
+ getInstrumentGroupSize(ctx) {
7891
+ let nameWidth = Math.max(0, ...this.rows.map((row) => row.getInstrumentNameWidth(ctx)));
7892
+ let hasName = nameWidth > 0;
7893
+ let padding = hasName ? ctx.unitSize : 0;
7894
+ let braceWidth = hasName ? ctx.unitSize * 5 : 0;
7895
+ return {
7896
+ nameLeft: 0,
7897
+ nameRight: nameWidth,
7898
+ braceLeft: nameWidth + padding,
7899
+ braceRight: nameWidth + padding + braceWidth + padding
7900
+ };
7783
7901
  }
7784
7902
  requestLayout() {
7785
7903
  this.needLayout = true;
@@ -7793,31 +7911,34 @@ var ObjDocument = class extends MusicObject {
7793
7911
  this.requestLayout();
7794
7912
  }
7795
7913
  layout() {
7914
+ var _a;
7796
7915
  if (!this.needLayout) {
7797
7916
  return;
7798
7917
  }
7799
- const { renderer } = this;
7800
- if (!renderer) {
7918
+ const { ctx } = this;
7919
+ if (!ctx) {
7801
7920
  return;
7802
7921
  }
7803
- let { unitSize } = renderer;
7922
+ let { unitSize } = ctx;
7804
7923
  this.forEachMeasure((m) => m.createBeams());
7924
+ (_a = this.getFirstMeasure()) == null ? void 0 : _a.updateRunningArguments();
7805
7925
  this.forEachMeasure((m) => m.createExtensions());
7806
7926
  this.allConnectiveProps.forEach((props) => props.removeConnectives());
7807
7927
  this.allConnectiveProps.forEach((props) => props.createConnectives());
7808
- this.rows.forEach((row) => row.resetLayoutGroups(renderer));
7809
- this.rows.forEach((row) => row.layout(renderer));
7810
- let rowWidth = Math.max(
7928
+ this.rows.forEach((row) => row.resetLayoutGroups(ctx));
7929
+ this.rows.forEach((row) => row.layout(ctx));
7930
+ let left = this.getInstrumentGroupSize(ctx).braceRight;
7931
+ let right = Math.max(
7811
7932
  DocumentSettings.DocumentMinWidth * unitSize,
7812
7933
  ...this.rows.map((row) => 1.4 * row.getMinWidth())
7813
7934
  );
7814
- this.rows.forEach((row) => row.layoutWidth(renderer, rowWidth));
7815
- this.rows.forEach((row) => row.layoutLayoutGroups(renderer));
7816
- this.rows.forEach((row) => row.layoutSetNotationLines(renderer));
7817
- this.rows.forEach((row) => row.layoutPadding(renderer));
7935
+ this.rows.forEach((row) => row.layoutWidth(ctx, left, right));
7936
+ this.rows.forEach((row) => row.layoutLayoutGroups(ctx));
7937
+ this.rows.forEach((row) => row.layoutSetNotationLines(ctx));
7938
+ this.rows.forEach((row) => row.layoutPadding(ctx));
7818
7939
  this.rect = new DivRect();
7819
7940
  if (this.header) {
7820
- this.header.layoutWidth(renderer, rowWidth);
7941
+ this.header.layoutWidth(ctx, left, right);
7821
7942
  this.rect.expandInPlace(this.header.getRect());
7822
7943
  }
7823
7944
  this.rows.forEach((row) => {
@@ -7828,13 +7949,13 @@ var ObjDocument = class extends MusicObject {
7828
7949
  this.needLayout = false;
7829
7950
  }
7830
7951
  drawContent() {
7831
- const { renderer } = this;
7832
- if (!renderer) {
7952
+ const { ctx } = this;
7953
+ if (!ctx) {
7833
7954
  return;
7834
7955
  }
7835
- this.rows.forEach((row) => row.draw(renderer));
7956
+ this.rows.forEach((row) => row.draw(ctx));
7836
7957
  if (this.header) {
7837
- this.header.draw(renderer);
7958
+ this.header.draw(ctx);
7838
7959
  }
7839
7960
  }
7840
7961
  pickStaffPosAt(x, y) {
@@ -7893,70 +8014,89 @@ function isNote(note) {
7893
8014
  }
7894
8015
  }
7895
8016
  function isVoiceId(value) {
7896
- return import_ts_utils_lib16.Utils.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
8017
+ return import_ts_utils_lib18.Utils.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
7897
8018
  }
7898
8019
  function isStringNumber(value) {
7899
- return import_ts_utils_lib16.Utils.Is.isNumber(value) && getStringNumbers().indexOf(value) >= 0;
8020
+ return import_ts_utils_lib18.Utils.Is.isNumber(value) && getStringNumbers().indexOf(value) >= 0;
7900
8021
  }
7901
8022
  function isVerseNumber(value) {
7902
- return import_ts_utils_lib16.Utils.Is.isNumber(value) && getVerseNumbers().indexOf(value) >= 0;
8023
+ return import_ts_utils_lib18.Utils.Is.isNumber(value) && getVerseNumbers().indexOf(value) >= 0;
7903
8024
  }
7904
8025
  function assertBaseConfig(baseConfig) {
7905
- assertArg(import_ts_utils_lib16.Utils.Is.isObject(baseConfig), "baseConfig", baseConfig);
7906
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(baseConfig.name), "baseConfig.name", baseConfig.name);
7907
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(baseConfig.voiceIds) || import_ts_utils_lib16.Utils.Is.isArray(baseConfig.voiceIds) && baseConfig.voiceIds.every((voiceId) => import_ts_utils_lib16.Utils.Is.isNumber(voiceId)), "baseConfig.voiceIds", baseConfig.voiceIds);
8026
+ var _a;
8027
+ assertArg(import_ts_utils_lib18.Utils.Is.isObject(baseConfig), "baseConfig", baseConfig);
8028
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(baseConfig.name), "baseConfig.name", baseConfig.name);
8029
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(baseConfig.voiceId) || isVoiceId(baseConfig.voiceId) || import_ts_utils_lib18.Utils.Is.isArray(baseConfig.voiceId) && baseConfig.voiceId.every((voiceId) => isVoiceId(voiceId)), "baseConfig.voiceId", baseConfig.voiceId);
8030
+ if (!import_ts_utils_lib18.Utils.Is.isUndefined(baseConfig.voiceIds)) {
8031
+ assertArg(isVoiceId(baseConfig.voiceIds) || import_ts_utils_lib18.Utils.Is.isArray(baseConfig.voiceIds) && baseConfig.voiceIds.every((voiceId) => isVoiceId(voiceId)), "baseConfig.voiceIds", baseConfig.voiceIds);
8032
+ console.warn(`Staff/tab config property 'voiceIds' is deprecated, use 'voiceId' instead.`);
8033
+ let arr = import_ts_utils_lib18.Utils.Arr.toArray((_a = baseConfig.voiceId) != null ? _a : []);
8034
+ import_ts_utils_lib18.Utils.Arr.toArray(baseConfig.voiceIds).forEach((voiceId) => arr.push(voiceId));
8035
+ baseConfig.voiceId = arr;
8036
+ }
8037
+ if (import_ts_utils_lib18.Utils.Is.isArray(baseConfig.voiceId)) {
8038
+ baseConfig.voiceId = import_ts_utils_lib18.Utils.Arr.removeDuplicates(baseConfig.voiceId);
8039
+ }
8040
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(baseConfig.instrument), "baseConfig.instrument", baseConfig.instrument);
7908
8041
  }
7909
8042
  function assertStaffConfig(staffConfig) {
7910
8043
  assertBaseConfig(staffConfig);
7911
- assertArg(import_ts_utils_lib16.Utils.Is.isObject(staffConfig), "staffConfig", staffConfig);
8044
+ assertArg(import_ts_utils_lib18.Utils.Is.isObject(staffConfig), "staffConfig", staffConfig);
7912
8045
  assertArg(staffConfig.type === "staff", "staffConfig.type", staffConfig.type);
7913
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(staffConfig.clef, Clef), "staffConfig.clef", staffConfig.clef);
7914
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(staffConfig.isOctaveDown), "staffConfig.isOctaveDown", staffConfig.isOctaveDown);
7915
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(staffConfig.minNote) || isNote(staffConfig.minNote), "staffConfig.minNote", staffConfig.minNote);
7916
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(staffConfig.maxNote) || isNote(staffConfig.maxNote), "staffConfig.maxNote", staffConfig.maxNote);
7917
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(staffConfig.grandId), "staffConfig.grandId", staffConfig.grandId);
7918
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(staffConfig.isGrand), "staffConfig.isGrand", staffConfig.isGrand);
8046
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(staffConfig.clef, Clef), "staffConfig.clef", staffConfig.clef);
8047
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(staffConfig.isOctaveDown), "staffConfig.isOctaveDown", staffConfig.isOctaveDown);
8048
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(staffConfig.minNote) || isNote(staffConfig.minNote), "staffConfig.minNote", staffConfig.minNote);
8049
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(staffConfig.maxNote) || isNote(staffConfig.maxNote), "staffConfig.maxNote", staffConfig.maxNote);
8050
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(staffConfig.grandId), "staffConfig.grandId", staffConfig.grandId);
8051
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(staffConfig.isGrand), "staffConfig.isGrand", staffConfig.isGrand);
8052
+ if (!import_ts_utils_lib18.Utils.Is.isUndefined(staffConfig.isGrand)) {
8053
+ console.warn(`Staff config property 'isGrand' is deprecated, use 'grandId' instead.`);
8054
+ }
7919
8055
  }
7920
8056
  function assertTabConfig(tabConfig) {
7921
8057
  assertBaseConfig(tabConfig);
7922
- assertArg(import_ts_utils_lib16.Utils.Is.isObject(tabConfig), "tabConfig", tabConfig);
8058
+ assertArg(import_ts_utils_lib18.Utils.Is.isObject(tabConfig), "tabConfig", tabConfig);
7923
8059
  assertArg(tabConfig.type === "tab", "tabConfig.type", tabConfig.type);
7924
- if (import_ts_utils_lib16.Utils.Is.isString(tabConfig.tuning)) {
8060
+ if (import_ts_utils_lib18.Utils.Is.isString(tabConfig.tuning)) {
7925
8061
  assertArg(import_theory13.TuningNameList.includes(tabConfig.tuning), "tabConfig.tuning", tabConfig.tuning);
7926
- } else if (import_ts_utils_lib16.Utils.Is.isArray(tabConfig.tuning)) {
8062
+ } else if (import_ts_utils_lib18.Utils.Is.isArray(tabConfig.tuning)) {
7927
8063
  assertArg(tabConfig.tuning.length === getStringNumbers().length && tabConfig.tuning.every((s) => isNote(s)), "tabConfig.tuning", tabConfig.tuning);
7928
8064
  }
7929
8065
  }
7930
8066
  function assertNoteOptions(noteOptions) {
7931
- assertArg(import_ts_utils_lib16.Utils.Is.isObject(noteOptions), "noteOptions", noteOptions);
7932
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(noteOptions.dotted) || import_ts_utils_lib16.Utils.Is.isIntegerGte(noteOptions.dotted, 0), "noteOptions.dotted", noteOptions.dotted);
7933
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(noteOptions.stem, Stem), "noteOptions.stem", noteOptions.stem);
7934
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(noteOptions.color), "noteOptions.color", noteOptions.color);
7935
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(noteOptions.arpeggio) || import_ts_utils_lib16.Utils.Is.isEnumValue(noteOptions.arpeggio, Arpeggio), "noteOptions.arpeggio", noteOptions.arpeggio);
7936
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(noteOptions.staccato), "noteOptions.staccato", noteOptions.staccato);
7937
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(noteOptions.diamond), "noteOptions.diamond", noteOptions.diamond);
7938
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(noteOptions.triplet), "noteOptions.triplet", noteOptions.triplet);
7939
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(noteOptions.string) || isStringNumber(noteOptions.string) || import_ts_utils_lib16.Utils.Is.isNonEmptyArray(noteOptions.string) && noteOptions.string.every((string) => isStringNumber(string)), "noteOptions.string", noteOptions.string);
7940
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(noteOptions.tieSpan), 'NoteOptions.tieSpan was removed. Use addConnective("tie", tieSpan)', "");
7941
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(noteOptions.slurSpan), 'NoteOptions.slurSpan was removed. Use addConnective("slur", slurSpan)', "");
8067
+ assertArg(import_ts_utils_lib18.Utils.Is.isObject(noteOptions), "noteOptions", noteOptions);
8068
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(noteOptions.dotted) || import_ts_utils_lib18.Utils.Is.isIntegerGte(noteOptions.dotted, 0), "noteOptions.dotted", noteOptions.dotted);
8069
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(noteOptions.stem, Stem), "noteOptions.stem", noteOptions.stem);
8070
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(noteOptions.color), "noteOptions.color", noteOptions.color);
8071
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(noteOptions.arpeggio) || import_ts_utils_lib18.Utils.Is.isEnumValue(noteOptions.arpeggio, Arpeggio), "noteOptions.arpeggio", noteOptions.arpeggio);
8072
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(noteOptions.staccato), "noteOptions.staccato", noteOptions.staccato);
8073
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(noteOptions.diamond), "noteOptions.diamond", noteOptions.diamond);
8074
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(noteOptions.triplet), "noteOptions.triplet", noteOptions.triplet);
8075
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(noteOptions.string) || isStringNumber(noteOptions.string) || import_ts_utils_lib18.Utils.Is.isNonEmptyArray(noteOptions.string) && noteOptions.string.every((string) => isStringNumber(string)), "noteOptions.string", noteOptions.string);
8076
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(noteOptions.tieSpan), 'NoteOptions.tieSpan was removed. Use addConnective("tie", tieSpan)', "");
8077
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(noteOptions.slurSpan), 'NoteOptions.slurSpan was removed. Use addConnective("slur", slurSpan)', "");
7942
8078
  }
7943
8079
  function assertRestOptions(restOptions) {
7944
- assertArg(import_ts_utils_lib16.Utils.Is.isObject(restOptions), "restOptions", restOptions);
7945
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(restOptions.dotted) || import_ts_utils_lib16.Utils.Is.isIntegerGte(restOptions.dotted, 0), "restOptions.dotted", restOptions.dotted);
7946
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(restOptions.staffPos) || import_ts_utils_lib16.Utils.Is.isInteger(restOptions.staffPos) || restOptions.staffPos instanceof import_theory13.Note, "restOptions.staffPos", restOptions.staffPos);
7947
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(restOptions.color), "restOptions.color", restOptions.color);
7948
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(restOptions.hide), "restOptions.hide", restOptions.hide);
7949
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(restOptions.triplet), "restOptions.triplet", restOptions.triplet);
8080
+ assertArg(import_ts_utils_lib18.Utils.Is.isObject(restOptions), "restOptions", restOptions);
8081
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(restOptions.dotted) || import_ts_utils_lib18.Utils.Is.isIntegerGte(restOptions.dotted, 0), "restOptions.dotted", restOptions.dotted);
8082
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(restOptions.staffPos) || import_ts_utils_lib18.Utils.Is.isInteger(restOptions.staffPos) || restOptions.staffPos instanceof import_theory13.Note, "restOptions.staffPos", restOptions.staffPos);
8083
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(restOptions.color), "restOptions.color", restOptions.color);
8084
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(restOptions.hide), "restOptions.hide", restOptions.hide);
8085
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(restOptions.triplet), "restOptions.triplet", restOptions.triplet);
7950
8086
  }
7951
8087
  function assertLyricsOptions(lyricsOptions) {
7952
- assertArg(import_ts_utils_lib16.Utils.Is.isObject(lyricsOptions), "lyricsOptions", lyricsOptions);
7953
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(lyricsOptions.align, LyricsAlign), "lyricsOptions.align", lyricsOptions.align);
7954
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(lyricsOptions.hyphen, LyricsHyphen), "lyricsOptions.hyphen", lyricsOptions.hyphen);
8088
+ assertArg(import_ts_utils_lib18.Utils.Is.isObject(lyricsOptions), "lyricsOptions", lyricsOptions);
8089
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(lyricsOptions.align, LyricsAlign), "lyricsOptions.align", lyricsOptions.align);
8090
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(lyricsOptions.hyphen, LyricsHyphen), "lyricsOptions.hyphen", lyricsOptions.hyphen);
8091
+ }
8092
+ function assertMeasureOptions(measureOptions) {
8093
+ assertArg(import_ts_utils_lib18.Utils.Is.isObject(measureOptions), "measureOptions", measureOptions);
8094
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(measureOptions.showNumber), "measureOptions.showNumber", measureOptions.showNumber);
7955
8095
  }
7956
8096
  function assertStaffTabOrGRoups(staffTabOrGroups) {
7957
8097
  assertArg(
7958
- import_ts_utils_lib16.Utils.Is.isStringOrUndefined(staffTabOrGroups) || import_ts_utils_lib16.Utils.Is.isIntegerGte(staffTabOrGroups, 0) || import_ts_utils_lib16.Utils.Is.isNonEmptyArray(staffTabOrGroups) && staffTabOrGroups.every(
7959
- (staffTabOrGroup) => import_ts_utils_lib16.Utils.Is.isString(staffTabOrGroup) || import_ts_utils_lib16.Utils.Is.isIntegerGte(staffTabOrGroup, 0)
8098
+ import_ts_utils_lib18.Utils.Is.isStringOrUndefined(staffTabOrGroups) || import_ts_utils_lib18.Utils.Is.isIntegerGte(staffTabOrGroups, 0) || import_ts_utils_lib18.Utils.Is.isNonEmptyArray(staffTabOrGroups) && staffTabOrGroups.every(
8099
+ (staffTabOrGroup) => import_ts_utils_lib18.Utils.Is.isString(staffTabOrGroup) || import_ts_utils_lib18.Utils.Is.isIntegerGte(staffTabOrGroup, 0)
7960
8100
  ),
7961
8101
  "staffTabOrGroup",
7962
8102
  staffTabOrGroups
@@ -7978,7 +8118,7 @@ function isTupletRatio(tupletRatio) {
7978
8118
  return false;
7979
8119
  }
7980
8120
  }
7981
- var DocumentBuilder = class {
8121
+ var _DocumentBuilder = class _DocumentBuilder {
7982
8122
  /**
7983
8123
  * Create new document builder instance.
7984
8124
  */
@@ -7988,19 +8128,19 @@ var DocumentBuilder = class {
7988
8128
  this.doc = new ObjDocument();
7989
8129
  }
7990
8130
  setScoreConfiguration(config) {
7991
- if (import_ts_utils_lib16.Utils.Is.isEnumValue(config, StaffPreset)) {
8131
+ if (import_ts_utils_lib18.Utils.Is.isEnumValue(config, StaffPreset)) {
7992
8132
  this.doc.setScoreConfiguration(config);
7993
- } else if (import_ts_utils_lib16.Utils.Is.isObject(config) && config.type === "staff") {
8133
+ } else if (import_ts_utils_lib18.Utils.Is.isObject(config) && config.type === "staff") {
7994
8134
  assertStaffConfig(config);
7995
8135
  this.doc.setScoreConfiguration(config);
7996
- } else if (import_ts_utils_lib16.Utils.Is.isObject(config) && config.type === "tab") {
8136
+ } else if (import_ts_utils_lib18.Utils.Is.isObject(config) && config.type === "tab") {
7997
8137
  assertTabConfig(config);
7998
8138
  this.doc.setScoreConfiguration(config);
7999
- } else if (import_ts_utils_lib16.Utils.Is.isNonEmptyArray(config)) {
8139
+ } else if (import_ts_utils_lib18.Utils.Is.isNonEmptyArray(config)) {
8000
8140
  config.forEach((c) => {
8001
- if (import_ts_utils_lib16.Utils.Is.isObject(c) && c.type === "staff") {
8141
+ if (import_ts_utils_lib18.Utils.Is.isObject(c) && c.type === "staff") {
8002
8142
  assertStaffConfig(c);
8003
- } else if (import_ts_utils_lib16.Utils.Is.isObject(c) && c.type === "tab") {
8143
+ } else if (import_ts_utils_lib18.Utils.Is.isObject(c) && c.type === "tab") {
8004
8144
  assertTabConfig(c);
8005
8145
  } else {
8006
8146
  assertArg(false, "config", config);
@@ -8014,7 +8154,7 @@ var DocumentBuilder = class {
8014
8154
  }
8015
8155
  getMeasure() {
8016
8156
  var _a;
8017
- return (_a = this.doc.getLastMeasure()) != null ? _a : this.doc.addMeasure();
8157
+ return (_a = this.doc.getLastMeasure()) != null ? _a : this.doc.addMeasure(_DocumentBuilder.DefaultMeasureOptions);
8018
8158
  }
8019
8159
  /**
8020
8160
  * Get music document after finished building.
@@ -8031,9 +8171,9 @@ var DocumentBuilder = class {
8031
8171
  * @returns - This document builder instance.
8032
8172
  */
8033
8173
  setHeader(title, composer, arranger) {
8034
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(title), "title", title);
8035
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(composer), "composer", composer);
8036
- assertArg(import_ts_utils_lib16.Utils.Is.isStringOrUndefined(arranger), "arranger", arranger);
8174
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(title), "title", title);
8175
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(composer), "composer", composer);
8176
+ assertArg(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(arranger), "arranger", arranger);
8037
8177
  this.doc.setHeader(title, composer, arranger);
8038
8178
  return this;
8039
8179
  }
@@ -8043,29 +8183,32 @@ var DocumentBuilder = class {
8043
8183
  * @returns - This document builder instance.
8044
8184
  */
8045
8185
  setMeasuresPerRow(measuresPerRow) {
8046
- assertArg(import_ts_utils_lib16.Utils.Is.isIntegerGte(measuresPerRow, 1) || import_ts_utils_lib16.Utils.Is.isPosInfinity(measuresPerRow), "measuresPerRow", measuresPerRow);
8186
+ assertArg(import_ts_utils_lib18.Utils.Is.isIntegerGte(measuresPerRow, 1) || import_ts_utils_lib18.Utils.Is.isPosInfinity(measuresPerRow), "measuresPerRow", measuresPerRow);
8047
8187
  this.doc.setMeasuresPerRow(measuresPerRow);
8048
8188
  return this;
8049
8189
  }
8050
8190
  /**
8051
8191
  * Add new measure.
8192
+ * @param measureOptions - Measure options.
8052
8193
  * @returns - This document builder instance.
8053
8194
  */
8054
- addMeasure() {
8055
- this.doc.addMeasure();
8195
+ addMeasure(measureOptions) {
8196
+ measureOptions != null ? measureOptions : measureOptions = {};
8197
+ assertMeasureOptions(measureOptions);
8198
+ this.doc.addMeasure(measureOptions);
8056
8199
  return this;
8057
8200
  }
8058
8201
  setKeySignature(...args) {
8059
- assertArg(args[0] instanceof import_theory13.Scale || args[0] instanceof import_theory13.KeySignature || import_ts_utils_lib16.Utils.Is.isNonEmptyString(args[0]) && (args.length === 1 || import_ts_utils_lib16.Utils.Is.isEnumValue(args[1], import_theory13.ScaleType)), "keySignature", args);
8202
+ assertArg(args[0] instanceof import_theory13.Scale || args[0] instanceof import_theory13.KeySignature || import_ts_utils_lib18.Utils.Is.isNonEmptyString(args[0]) && (args.length === 1 || import_ts_utils_lib18.Utils.Is.isEnumValue(args[1], import_theory13.ScaleType)), "keySignature", args);
8060
8203
  this.getMeasure().setKeySignature(...args);
8061
8204
  return this;
8062
8205
  }
8063
8206
  setTimeSignature(...args) {
8064
8207
  if (args[0] instanceof import_theory13.TimeSignature) {
8065
8208
  this.getMeasure().setTimeSignature(args[0]);
8066
- } else if (import_ts_utils_lib16.Utils.Is.isEnumValue(args[0], import_theory13.TimeSignatures) && import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(args[1], import_theory13.BeamGrouping)) {
8209
+ } else if (import_ts_utils_lib18.Utils.Is.isEnumValue(args[0], import_theory13.TimeSignatures) && import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(args[1], import_theory13.BeamGrouping)) {
8067
8210
  this.getMeasure().setTimeSignature(new import_theory13.TimeSignature(args[0], args[1]));
8068
- } else if (import_ts_utils_lib16.Utils.Is.isIntegerGte(args[0], 1) && import_ts_utils_lib16.Utils.Is.isIntegerGte(args[1], 1) && import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(args[2], import_theory13.BeamGrouping)) {
8211
+ } else if (import_ts_utils_lib18.Utils.Is.isIntegerGte(args[0], 1) && import_ts_utils_lib18.Utils.Is.isIntegerGte(args[1], 1) && import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(args[2], import_theory13.BeamGrouping)) {
8069
8212
  this.getMeasure().setTimeSignature(new import_theory13.TimeSignature(args[0], args[1], args[2]));
8070
8213
  } else {
8071
8214
  assertArg(false, "timeSignature args", args);
@@ -8073,12 +8216,12 @@ var DocumentBuilder = class {
8073
8216
  return this;
8074
8217
  }
8075
8218
  setTempo(beatsPerMinute, beatLength, dotted) {
8076
- assertArg(import_ts_utils_lib16.Utils.Is.isIntegerGte(beatsPerMinute, 1), "beatsPerMinute", beatsPerMinute);
8219
+ assertArg(import_ts_utils_lib18.Utils.Is.isIntegerGte(beatsPerMinute, 1), "beatsPerMinute", beatsPerMinute);
8077
8220
  if (beatLength === void 0) {
8078
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(dotted), "dotted", dotted);
8221
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(dotted), "dotted", dotted);
8079
8222
  } else {
8080
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(beatLength, import_theory13.NoteLength) || isNoteLength(beatLength), "beatLength", beatLength);
8081
- assertArg(import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(dotted) || import_ts_utils_lib16.Utils.Is.isIntegerGte(dotted, 0), "dotted", dotted);
8223
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(beatLength, import_theory13.NoteLength) || isNoteLength(beatLength), "beatLength", beatLength);
8224
+ assertArg(import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(dotted) || import_ts_utils_lib18.Utils.Is.isIntegerGte(dotted, 0), "dotted", dotted);
8082
8225
  }
8083
8226
  this.getMeasure().setTempo(beatsPerMinute, beatLength, dotted);
8084
8227
  return this;
@@ -8094,17 +8237,17 @@ var DocumentBuilder = class {
8094
8237
  addNote(voiceId, note, noteLength, noteOptions) {
8095
8238
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
8096
8239
  assertArg(
8097
- note instanceof import_theory13.Note || import_ts_utils_lib16.Utils.Is.isNonEmptyString(note) || import_ts_utils_lib16.Utils.Is.isArray(note) && note.every((note2) => note2 instanceof import_theory13.Note || import_ts_utils_lib16.Utils.Is.isNonEmptyString(note2)),
8240
+ note instanceof import_theory13.Note || import_ts_utils_lib18.Utils.Is.isNonEmptyString(note) || import_ts_utils_lib18.Utils.Is.isArray(note) && note.every((note2) => note2 instanceof import_theory13.Note || import_ts_utils_lib18.Utils.Is.isNonEmptyString(note2)),
8098
8241
  "note",
8099
8242
  note
8100
8243
  );
8101
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8244
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8102
8245
  noteOptions != null ? noteOptions : noteOptions = {};
8103
8246
  assertNoteOptions(noteOptions);
8104
- if (import_ts_utils_lib16.Utils.Is.isArray(note)) {
8247
+ if (import_ts_utils_lib18.Utils.Is.isArray(note)) {
8105
8248
  let string = noteOptions.string;
8106
8249
  note.forEach((note2, noteId) => {
8107
- noteOptions.string = import_ts_utils_lib16.Utils.Is.isArray(string) ? string[noteId] : string;
8250
+ noteOptions.string = import_ts_utils_lib18.Utils.Is.isArray(string) ? string[noteId] : string;
8108
8251
  this.getMeasure().addNoteGroup(voiceId, [note2], noteLength, noteOptions);
8109
8252
  });
8110
8253
  } else {
@@ -8122,8 +8265,8 @@ var DocumentBuilder = class {
8122
8265
  */
8123
8266
  addChord(voiceId, notes, noteLength, noteOptions) {
8124
8267
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
8125
- assertArg(import_ts_utils_lib16.Utils.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof import_theory13.Note || import_ts_utils_lib16.Utils.Is.isNonEmptyString(note)), "notes", notes);
8126
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8268
+ assertArg(import_ts_utils_lib18.Utils.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof import_theory13.Note || import_ts_utils_lib18.Utils.Is.isNonEmptyString(note)), "notes", notes);
8269
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8127
8270
  noteOptions != null ? noteOptions : noteOptions = {};
8128
8271
  assertNoteOptions(noteOptions);
8129
8272
  this.getMeasure().addNoteGroup(voiceId, notes, noteLength, noteOptions);
@@ -8138,7 +8281,7 @@ var DocumentBuilder = class {
8138
8281
  */
8139
8282
  addRest(voiceId, restLength, restOptions) {
8140
8283
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
8141
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(restLength, import_theory13.NoteLength) || isNoteLength(restLength), "restLength", restLength);
8284
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(restLength, import_theory13.NoteLength) || isNoteLength(restLength), "restLength", restLength);
8142
8285
  restOptions != null ? restOptions : restOptions = {};
8143
8286
  assertRestOptions(restOptions);
8144
8287
  this.getMeasure().addRest(voiceId, restLength, restOptions);
@@ -8161,24 +8304,24 @@ var DocumentBuilder = class {
8161
8304
  */
8162
8305
  addTuplet(voiceId, tupletRatio, tupletBuilder) {
8163
8306
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
8164
- assertArg(import_ts_utils_lib16.Utils.Is.isFunction(tupletBuilder), "tupletBuilder", tupletBuilder);
8165
- assertArg(isTupletRatio(tupletRatio) && import_ts_utils_lib16.Utils.Is.isBooleanOrUndefined(tupletRatio.showRatio), "tupletRatio", tupletRatio);
8307
+ assertArg(import_ts_utils_lib18.Utils.Is.isFunction(tupletBuilder), "tupletBuilder", tupletBuilder);
8308
+ assertArg(isTupletRatio(tupletRatio) && import_ts_utils_lib18.Utils.Is.isBooleanOrUndefined(tupletRatio.showRatio), "tupletRatio", tupletRatio);
8166
8309
  let tupletSymbols = [];
8167
8310
  const helper = {
8168
8311
  addNote: (note, noteLength, noteOptions) => {
8169
8312
  assertArg(
8170
- note instanceof import_theory13.Note || import_ts_utils_lib16.Utils.Is.isNonEmptyString(note) || import_ts_utils_lib16.Utils.Is.isArray(note) && note.every((note2) => note2 instanceof import_theory13.Note || import_ts_utils_lib16.Utils.Is.isNonEmptyString(note2)),
8313
+ note instanceof import_theory13.Note || import_ts_utils_lib18.Utils.Is.isNonEmptyString(note) || import_ts_utils_lib18.Utils.Is.isArray(note) && note.every((note2) => note2 instanceof import_theory13.Note || import_ts_utils_lib18.Utils.Is.isNonEmptyString(note2)),
8171
8314
  "note",
8172
8315
  note
8173
8316
  );
8174
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8317
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8175
8318
  noteOptions != null ? noteOptions : noteOptions = {};
8176
8319
  delete noteOptions.triplet;
8177
8320
  assertNoteOptions(noteOptions);
8178
- if (import_ts_utils_lib16.Utils.Is.isArray(note)) {
8321
+ if (import_ts_utils_lib18.Utils.Is.isArray(note)) {
8179
8322
  let string = noteOptions.string;
8180
8323
  note.forEach((note2, noteId) => {
8181
- noteOptions.string = import_ts_utils_lib16.Utils.Is.isArray(string) ? string[noteId] : string;
8324
+ noteOptions.string = import_ts_utils_lib18.Utils.Is.isArray(string) ? string[noteId] : string;
8182
8325
  let s = this.getMeasure().addNoteGroup(voiceId, [note2], noteLength, noteOptions, tupletRatio);
8183
8326
  tupletSymbols.push(s);
8184
8327
  });
@@ -8189,8 +8332,8 @@ var DocumentBuilder = class {
8189
8332
  return helper;
8190
8333
  },
8191
8334
  addChord: (notes, noteLength, noteOptions) => {
8192
- assertArg(import_ts_utils_lib16.Utils.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof import_theory13.Note || import_ts_utils_lib16.Utils.Is.isNonEmptyString(note)), "notes", notes);
8193
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8335
+ assertArg(import_ts_utils_lib18.Utils.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof import_theory13.Note || import_ts_utils_lib18.Utils.Is.isNonEmptyString(note)), "notes", notes);
8336
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8194
8337
  noteOptions != null ? noteOptions : noteOptions = {};
8195
8338
  delete noteOptions.triplet;
8196
8339
  assertNoteOptions(noteOptions);
@@ -8199,7 +8342,7 @@ var DocumentBuilder = class {
8199
8342
  return helper;
8200
8343
  },
8201
8344
  addRest: (restLength, restOptions) => {
8202
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(restLength, import_theory13.NoteLength) || isNoteLength(restLength), "restLength", restLength);
8345
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(restLength, import_theory13.NoteLength) || isNoteLength(restLength), "restLength", restLength);
8203
8346
  restOptions != null ? restOptions : restOptions = {};
8204
8347
  delete restOptions.triplet;
8205
8348
  assertRestOptions(restOptions);
@@ -8216,8 +8359,8 @@ var DocumentBuilder = class {
8216
8359
  var _a;
8217
8360
  assertStaffTabOrGRoups(staffTabOrGroups);
8218
8361
  assertArg(isVerseNumber(verse), "verse", verse);
8219
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(lyricsLength, import_theory13.NoteLength), "lyricsLength", lyricsLength);
8220
- assertArg(import_ts_utils_lib16.Utils.Is.isString(lyricsText) || import_ts_utils_lib16.Utils.Is.isArray(lyricsText) && lyricsText.every((text) => import_ts_utils_lib16.Utils.Is.isString(text)), "lyricsText", lyricsText);
8362
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(lyricsLength, import_theory13.NoteLength), "lyricsLength", lyricsLength);
8363
+ assertArg(import_ts_utils_lib18.Utils.Is.isString(lyricsText) || import_ts_utils_lib18.Utils.Is.isArray(lyricsText) && lyricsText.every((text) => import_ts_utils_lib18.Utils.Is.isString(text)), "lyricsText", lyricsText);
8221
8364
  lyricsOptions != null ? lyricsOptions : lyricsOptions = {};
8222
8365
  assertLyricsOptions(lyricsOptions);
8223
8366
  if (lyricsOptions.align !== void 0) {
@@ -8225,7 +8368,7 @@ var DocumentBuilder = class {
8225
8368
  } else {
8226
8369
  (_a = lyricsOptions.align) != null ? _a : lyricsOptions.align = this.currentLyricsAlign;
8227
8370
  }
8228
- if (import_ts_utils_lib16.Utils.Is.isArray(lyricsText)) {
8371
+ if (import_ts_utils_lib18.Utils.Is.isArray(lyricsText)) {
8229
8372
  lyricsText.forEach((text) => this.getMeasure().addLyrics(staffTabOrGroups, verse, lyricsLength, text, lyricsOptions));
8230
8373
  } else {
8231
8374
  this.getMeasure().addLyrics(staffTabOrGroups, verse, lyricsLength, lyricsText, lyricsOptions);
@@ -8257,7 +8400,7 @@ var DocumentBuilder = class {
8257
8400
  }
8258
8401
  addFermataInternal(staffTabOrGroups, fermata) {
8259
8402
  assertStaffTabOrGRoups(staffTabOrGroups);
8260
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(fermata, Fermata), "fermata", fermata);
8403
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(fermata, Fermata), "fermata", fermata);
8261
8404
  this.getMeasure().addFermata(staffTabOrGroups, fermata);
8262
8405
  return this;
8263
8406
  }
@@ -8280,11 +8423,11 @@ var DocumentBuilder = class {
8280
8423
  }
8281
8424
  addNavigationInternal(staffTabOrGroups, navigation, ...args) {
8282
8425
  assertStaffTabOrGRoups(staffTabOrGroups);
8283
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(navigation, Navigation), "navigation", navigation);
8426
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(navigation, Navigation), "navigation", navigation);
8284
8427
  if (navigation === "endRepeat" /* EndRepeat */ && args.length > 0) {
8285
- assertArg(import_ts_utils_lib16.Utils.Is.isIntegerGte(args[0], 1), "playCount", args[0]);
8428
+ assertArg(import_ts_utils_lib18.Utils.Is.isIntegerGte(args[0], 1), "playCount", args[0]);
8286
8429
  } else if (navigation === "ending" /* Ending */ && args.length > 0) {
8287
- assertArg(args.every((passage) => import_ts_utils_lib16.Utils.Is.isIntegerGte(passage, 1)), "passages", args);
8430
+ assertArg(args.every((passage) => import_ts_utils_lib18.Utils.Is.isIntegerGte(passage, 1)), "passages", args);
8288
8431
  }
8289
8432
  this.getMeasure().addNavigation(staffTabOrGroups, navigation, ...args);
8290
8433
  return this;
@@ -8301,8 +8444,8 @@ var DocumentBuilder = class {
8301
8444
  throw new import_core19.MusicError(import_core19.MusicErrorType.Score, `Annotation text "${text}" is not known annotation.`);
8302
8445
  }
8303
8446
  assertStaffTabOrGRoups(staffTabOrGroups);
8304
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(annotation, Annotation), "annotation", annotation);
8305
- assertArg(import_ts_utils_lib16.Utils.Is.isNonEmptyString(text), "text", text);
8447
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(annotation, Annotation), "annotation", annotation);
8448
+ assertArg(import_ts_utils_lib18.Utils.Is.isNonEmptyString(text), "text", text);
8306
8449
  this.getMeasure().addAnnotation(staffTabOrGroups, annotation, text);
8307
8450
  return this;
8308
8451
  }
@@ -8322,8 +8465,8 @@ var DocumentBuilder = class {
8322
8465
  }
8323
8466
  addLabelInternal(staffTabOrGroups, label, text) {
8324
8467
  assertStaffTabOrGRoups(staffTabOrGroups);
8325
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(label, Label), "label", label);
8326
- assertArg(import_ts_utils_lib16.Utils.Is.isNonEmptyString(text), "text", text);
8468
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(label, Label), "label", label);
8469
+ assertArg(import_ts_utils_lib18.Utils.Is.isNonEmptyString(text), "text", text);
8327
8470
  this.getMeasure().addLabel(staffTabOrGroups, label, text);
8328
8471
  return this;
8329
8472
  }
@@ -8347,21 +8490,21 @@ var DocumentBuilder = class {
8347
8490
  return this.addLabelInternal(staffTabOrGroups, label, text);
8348
8491
  }
8349
8492
  addConnective(connective, ...args) {
8350
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(connective, Connective), "connective", connective);
8493
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(connective, Connective), "connective", connective);
8351
8494
  if (connective === "tie" /* Tie */) {
8352
- assertArg(import_ts_utils_lib16.Utils.Is.isIntegerOrUndefined(args[0]) || import_ts_utils_lib16.Utils.Is.isEnumValue(args[0], TieType), "tieSpan", args[0]);
8353
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
8495
+ assertArg(import_ts_utils_lib18.Utils.Is.isIntegerOrUndefined(args[0]) || import_ts_utils_lib18.Utils.Is.isEnumValue(args[0], TieType), "tieSpan", args[0]);
8496
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
8354
8497
  let tieSpan = args[0];
8355
8498
  let noteAnchor = args[1];
8356
8499
  this.getMeasure().addConnective(connective, tieSpan, noteAnchor);
8357
8500
  } else if (connective === "slur" /* Slur */) {
8358
- assertArg(import_ts_utils_lib16.Utils.Is.isIntegerOrUndefined(args[0]), "slurSpan", args[0]);
8359
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
8501
+ assertArg(import_ts_utils_lib18.Utils.Is.isIntegerOrUndefined(args[0]), "slurSpan", args[0]);
8502
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
8360
8503
  let slurSpan = args[0];
8361
8504
  let noteAnchor = args[1];
8362
8505
  this.getMeasure().addConnective(connective, slurSpan, noteAnchor);
8363
8506
  } else if (connective === "slide" /* Slide */) {
8364
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValueOrUndefined(args[0], NoteAnchor), "noteAnchor", args[0]);
8507
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValueOrUndefined(args[0], NoteAnchor), "noteAnchor", args[0]);
8365
8508
  let noteAnchor = args[0];
8366
8509
  this.getMeasure().addConnective(connective, noteAnchor);
8367
8510
  }
@@ -8380,18 +8523,18 @@ var DocumentBuilder = class {
8380
8523
  * @returns - This document builder instance.
8381
8524
  */
8382
8525
  addExtension(extensionBuilder) {
8383
- assertArg(import_ts_utils_lib16.Utils.Is.isFunctionOrUndefined(extensionBuilder), "addExtension() has new usage, for e.g. addExtension(ext => ext.measures(2)). Please refer to README or API Reference.", extensionBuilder);
8526
+ assertArg(import_ts_utils_lib18.Utils.Is.isFunctionOrUndefined(extensionBuilder), "addExtension() has new usage, for e.g. addExtension(ext => ext.measures(2)). Please refer to README or API Reference.", extensionBuilder);
8384
8527
  let ticks = 0;
8385
8528
  let visible = true;
8386
8529
  const helper = {
8387
8530
  notes: (noteLength, noteCount) => {
8388
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8389
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(noteCount) || import_ts_utils_lib16.Utils.Is.isNumber(noteCount) && noteCount >= 0, "noteCount", noteCount);
8531
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(noteLength, import_theory13.NoteLength) || isNoteLength(noteLength), "noteLength", noteLength);
8532
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(noteCount) || import_ts_utils_lib18.Utils.Is.isNumber(noteCount) && noteCount >= 0, "noteCount", noteCount);
8390
8533
  ticks += import_theory13.RhythmProps.get(noteLength).ticks * (noteCount != null ? noteCount : 1);
8391
8534
  return helper;
8392
8535
  },
8393
8536
  measures: (measureCount) => {
8394
- assertArg(import_ts_utils_lib16.Utils.Is.isNumber(measureCount) && measureCount >= 1, "measureCount", measureCount);
8537
+ assertArg(import_ts_utils_lib18.Utils.Is.isNumber(measureCount) && measureCount >= 1, "measureCount", measureCount);
8395
8538
  ticks += this.getMeasure().getMeasureTicks() * measureCount;
8396
8539
  return helper;
8397
8540
  },
@@ -8420,13 +8563,13 @@ var DocumentBuilder = class {
8420
8563
  * @returns - This document builder instance.
8421
8564
  */
8422
8565
  addStaffGroup(groupName, staffsTabsAndGroups, verticalPosition = "auto" /* Auto */) {
8423
- assertArg(import_ts_utils_lib16.Utils.Is.isNonEmptyString(groupName), "groupName", groupName);
8566
+ assertArg(import_ts_utils_lib18.Utils.Is.isNonEmptyString(groupName), "groupName", groupName);
8424
8567
  assertArg(
8425
- import_ts_utils_lib16.Utils.Is.isNonEmptyString(staffsTabsAndGroups) || import_ts_utils_lib16.Utils.Is.isIntegerGte(staffsTabsAndGroups, 0) || import_ts_utils_lib16.Utils.Is.isNonEmptyArray(staffsTabsAndGroups) && staffsTabsAndGroups.every((line) => import_ts_utils_lib16.Utils.Is.isNonEmptyString(line) || import_ts_utils_lib16.Utils.Is.isIntegerGte(line, 0)),
8568
+ import_ts_utils_lib18.Utils.Is.isNonEmptyString(staffsTabsAndGroups) || import_ts_utils_lib18.Utils.Is.isIntegerGte(staffsTabsAndGroups, 0) || import_ts_utils_lib18.Utils.Is.isNonEmptyArray(staffsTabsAndGroups) && staffsTabsAndGroups.every((line) => import_ts_utils_lib18.Utils.Is.isNonEmptyString(line) || import_ts_utils_lib18.Utils.Is.isIntegerGte(line, 0)),
8426
8569
  "staffsTabsAndGroups",
8427
8570
  staffsTabsAndGroups
8428
8571
  );
8429
- assertArg(import_ts_utils_lib16.Utils.Is.isEnumValue(verticalPosition, VerticalPosition), "verticalPosition", verticalPosition);
8572
+ assertArg(import_ts_utils_lib18.Utils.Is.isEnumValue(verticalPosition, VerticalPosition), "verticalPosition", verticalPosition);
8430
8573
  this.doc.addStaffGroup(groupName, staffsTabsAndGroups, verticalPosition);
8431
8574
  return this;
8432
8575
  }
@@ -8461,7 +8604,7 @@ var DocumentBuilder = class {
8461
8604
  * @returns - This document builder instance.
8462
8605
  */
8463
8606
  completeRests(voiceId) {
8464
- assertArg(import_ts_utils_lib16.Utils.Is.isUndefined(voiceId) || isVoiceId(voiceId) || import_ts_utils_lib16.Utils.Is.isArray(voiceId) && voiceId.every((id) => isVoiceId(id)), "voiceId", voiceId);
8607
+ assertArg(import_ts_utils_lib18.Utils.Is.isUndefined(voiceId) || isVoiceId(voiceId) || import_ts_utils_lib18.Utils.Is.isArray(voiceId) && voiceId.every((id) => isVoiceId(id)), "voiceId", voiceId);
8465
8608
  this.getMeasure().completeRests(voiceId);
8466
8609
  return this;
8467
8610
  }
@@ -8473,8 +8616,8 @@ var DocumentBuilder = class {
8473
8616
  * @returns - This document builder instance.
8474
8617
  */
8475
8618
  addScaleArpeggio(scale, bottomNote, numOctaves) {
8476
- assertArg(import_ts_utils_lib16.Utils.Is.isNonEmptyString(bottomNote), "bottomNote", bottomNote);
8477
- assertArg(import_ts_utils_lib16.Utils.Is.isIntegerGte(numOctaves, 1), "numOctaves", numOctaves);
8619
+ assertArg(import_ts_utils_lib18.Utils.Is.isNonEmptyString(bottomNote), "bottomNote", bottomNote);
8620
+ assertArg(import_ts_utils_lib18.Utils.Is.isIntegerGte(numOctaves, 1), "numOctaves", numOctaves);
8478
8621
  let ts = this.getMeasure().getTimeSignature();
8479
8622
  let notes = scale.getScaleNotes(bottomNote, numOctaves);
8480
8623
  for (let i = 0; i < notes.length; i++) {
@@ -8488,6 +8631,8 @@ var DocumentBuilder = class {
8488
8631
  return this;
8489
8632
  }
8490
8633
  };
8634
+ __publicField(_DocumentBuilder, "DefaultMeasureOptions", {});
8635
+ var DocumentBuilder = _DocumentBuilder;
8491
8636
 
8492
8637
  // src/score/pub/event.ts
8493
8638
  var import_core20 = require("@tspro/web-music-score/core");
@@ -8504,32 +8649,44 @@ var ScoreStaffPosEvent = class extends ScoreEvent {
8504
8649
  /**
8505
8650
  * Create new score staff position event.
8506
8651
  * @param type - Score event type.
8507
- * @param renderer - Renderer.
8652
+ * @param renderContext - Render context.
8508
8653
  * @param scoreRow - Score row.
8509
8654
  * @param diatonicId - Diatonic id that was clicked/entered/left.
8510
8655
  */
8511
- constructor(type, renderer, scoreRow, diatonicId) {
8656
+ constructor(type, renderContext, scoreRow, diatonicId) {
8512
8657
  super(type);
8513
- this.renderer = renderer;
8658
+ this.renderContext = renderContext;
8514
8659
  this.scoreRow = scoreRow;
8515
8660
  this.diatonicId = diatonicId;
8516
8661
  }
8662
+ /**
8663
+ * @deprecated - Provided for legacy support, use renderContext instead.
8664
+ */
8665
+ get renderer() {
8666
+ return this.renderContext;
8667
+ }
8517
8668
  };
8518
8669
  var ScoreObjectEvent = class extends ScoreEvent {
8519
8670
  /**
8520
8671
  * Create new score object event.
8521
8672
  * @param type - Score event type.
8522
- * @param renderer - Renderer.
8673
+ * @param renderContext - Render context.
8523
8674
  * @param objects - Array of objects, last object in this array is the top object that was clicked/entered/left, previous objects are it's parent objects.
8524
8675
  */
8525
- constructor(type, renderer, objects) {
8676
+ constructor(type, renderContext, objects) {
8526
8677
  super(type);
8527
- this.renderer = renderer;
8678
+ this.renderContext = renderContext;
8528
8679
  this.objects = objects;
8529
8680
  if (arguments.length === 0) {
8530
8681
  throw new import_core20.MusicError(import_core20.MusicErrorType.Score, "Empty array in score object event!");
8531
8682
  }
8532
8683
  }
8684
+ /**
8685
+ * @deprecated - Provided for legacy support, use renderContext instead.
8686
+ */
8687
+ get renderer() {
8688
+ return this.renderContext;
8689
+ }
8533
8690
  /** Top object getter. */
8534
8691
  get topObject() {
8535
8692
  return this.objects[this.objects.length - 1];
@@ -8546,10 +8703,10 @@ var ScoreObjectEvent = class extends ScoreEvent {
8546
8703
 
8547
8704
  // src/score/pub/music-interface.ts
8548
8705
  var Audio2 = __toESM(require("@tspro/web-music-score/audio"));
8549
- var import_ts_utils_lib18 = require("@tspro/ts-utils-lib");
8706
+ var import_ts_utils_lib20 = require("@tspro/ts-utils-lib");
8550
8707
 
8551
8708
  // src/score/pub/music-objects.ts
8552
- var import_ts_utils_lib17 = require("@tspro/ts-utils-lib");
8709
+ var import_ts_utils_lib19 = require("@tspro/ts-utils-lib");
8553
8710
  var import_core21 = require("@tspro/web-music-score/core");
8554
8711
  function assertArg2(condition, argName, argValue) {
8555
8712
  if (!condition) {
@@ -8557,7 +8714,7 @@ function assertArg2(condition, argName, argValue) {
8557
8714
  }
8558
8715
  }
8559
8716
  function isVoiceId2(value) {
8560
- return import_ts_utils_lib17.Utils.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
8717
+ return import_ts_utils_lib19.Utils.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
8561
8718
  }
8562
8719
  function getNotationLine(line) {
8563
8720
  if (line instanceof ObjStaff || line instanceof ObjTab) {
@@ -8733,7 +8890,7 @@ var _MDocument = class _MDocument extends MusicInterface6 {
8733
8890
  * @returns - Player instance.
8734
8891
  */
8735
8892
  play(playStateChangeListener) {
8736
- assertArg2(import_ts_utils_lib17.Utils.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
8893
+ assertArg2(import_ts_utils_lib19.Utils.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
8737
8894
  return new MPlayer(this, playStateChangeListener).play();
8738
8895
  }
8739
8896
  };
@@ -8763,7 +8920,7 @@ var _MEnding = class _MEnding extends MusicInterface6 {
8763
8920
  * @returns - Boolean whether this ending has asked passage number.
8764
8921
  */
8765
8922
  hasPassage(passage) {
8766
- assertArg2(import_ts_utils_lib17.Utils.Is.isIntegerGte(passage, 1), "passage", passage);
8923
+ assertArg2(import_ts_utils_lib19.Utils.Is.isIntegerGte(passage, 1), "passage", passage);
8767
8924
  return this.obj.hasPassage(passage);
8768
8925
  }
8769
8926
  };
@@ -9450,7 +9607,7 @@ var _MPlayer = class _MPlayer {
9450
9607
  constructor(doc, playStateChangeListener) {
9451
9608
  __publicField(this, "player");
9452
9609
  assertArg3(doc instanceof MDocument2, "doc", doc);
9453
- assertArg3(import_ts_utils_lib18.Utils.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
9610
+ assertArg3(import_ts_utils_lib20.Utils.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
9454
9611
  this.player = new Player();
9455
9612
  this.player.setDocument(doc.getMusicObject());
9456
9613
  this.player.setCursorPositionChangeListener((cursorRect) => doc.getMusicObject().updateCursorRect(cursorRect));
@@ -9494,32 +9651,32 @@ var _MPlayer = class _MPlayer {
9494
9651
  };
9495
9652
  __publicField(_MPlayer, "currentlyPlaying", /* @__PURE__ */ new Set());
9496
9653
  var MPlayer = _MPlayer;
9497
- var MRenderer2 = class {
9654
+ var MRenderContext2 = class {
9498
9655
  /**
9499
- * Create new renderer instance.
9656
+ * Create new render context instance.
9500
9657
  */
9501
9658
  constructor() {
9502
- __publicField(this, "renderer");
9503
- this.renderer = new Renderer(this);
9659
+ __publicField(this, "ctx");
9660
+ this.ctx = new RenderContext(this);
9504
9661
  }
9505
9662
  /**
9506
- * Attach music document to this renderer.
9663
+ * Attach music document to this render context.
9507
9664
  * @param doc - Music document.
9508
- * @returns - This renderer instance.
9665
+ * @returns - This render context instance.
9509
9666
  */
9510
9667
  setDocument(doc) {
9511
- assertArg3(import_ts_utils_lib18.Utils.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9512
- this.renderer.setDocument(doc);
9668
+ assertArg3(import_ts_utils_lib20.Utils.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9669
+ this.ctx.setDocument(doc);
9513
9670
  return this;
9514
9671
  }
9515
9672
  /**
9516
- * Set target canvas html element for this renderer.
9673
+ * Set target canvas html element for this render context.
9517
9674
  * @param canvas - HTML canvas element or element id.
9518
- * @returns - This renderer instance.
9675
+ * @returns - This render context instance.
9519
9676
  */
9520
9677
  setCanvas(canvas) {
9521
- canvas = require_t(import_ts_utils_lib18.Utils.Dom.getCanvas(canvas), typeof canvas === "string" ? "Cannot set renderer canvas because invalid canvas id: " + canvas : "Cannot set renderer canvas because given canvas is undefined.");
9522
- this.renderer.setCanvas(canvas);
9678
+ canvas = require_t(import_ts_utils_lib20.Utils.Dom.getCanvas(canvas), typeof canvas === "string" ? "Cannot set render canvas because invalid canvas id: " + canvas : "Cannot set render canvas because given canvas is undefined.");
9679
+ this.ctx.setCanvas(canvas);
9523
9680
  return this;
9524
9681
  }
9525
9682
  /**
@@ -9527,22 +9684,22 @@ var MRenderer2 = class {
9527
9684
  * @param scoreEventListener - Score event listener.
9528
9685
  */
9529
9686
  setScoreEventListener(scoreEventListener) {
9530
- assertArg3(import_ts_utils_lib18.Utils.Is.isFunctionOrUndefined(scoreEventListener), "scoreEventListener", scoreEventListener);
9531
- this.renderer.setScoreEventListener(scoreEventListener);
9687
+ assertArg3(import_ts_utils_lib20.Utils.Is.isFunctionOrUndefined(scoreEventListener), "scoreEventListener", scoreEventListener);
9688
+ this.ctx.setScoreEventListener(scoreEventListener);
9532
9689
  }
9533
9690
  /**
9534
9691
  * Draw given music object hilighted.
9535
9692
  * @param obj - Music object or undefined to remove hilighting.
9536
9693
  */
9537
9694
  hilightObject(obj) {
9538
- this.renderer.hilightObject(obj == null ? void 0 : obj.getMusicObject());
9695
+ this.ctx.hilightObject(obj == null ? void 0 : obj.getMusicObject());
9539
9696
  }
9540
9697
  /**
9541
9698
  * Draw given staff position hilighted.
9542
9699
  * @param staffPos - Staff position (score row and diatonic id) or undefined to remove hilighting.
9543
9700
  */
9544
9701
  hilightStaffPos(staffPos) {
9545
- this.renderer.hilightStaffPos(staffPos ? {
9702
+ this.ctx.hilightStaffPos(staffPos ? {
9546
9703
  scoreRow: staffPos.scoreRow.getMusicObject(),
9547
9704
  diatonicId: staffPos.diatonicId
9548
9705
  } : void 0);
@@ -9552,13 +9709,14 @@ var MRenderer2 = class {
9552
9709
  */
9553
9710
  draw() {
9554
9711
  try {
9555
- this.renderer.draw();
9556
- } catch (e) {
9557
- console.log("Draw failed in music renderer.");
9558
- console.log(e);
9712
+ this.ctx.draw();
9713
+ } catch (err) {
9714
+ console.log("Draw failed in music render context!", err);
9559
9715
  }
9560
9716
  }
9561
9717
  };
9718
+ var MRenderer = class extends MRenderContext2 {
9719
+ };
9562
9720
  var _MPlaybackButtons = class _MPlaybackButtons {
9563
9721
  /**
9564
9722
  * Create new playback buttons helper class instance.
@@ -9601,7 +9759,7 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9601
9759
  * @returns
9602
9760
  */
9603
9761
  setDocument(doc) {
9604
- assertArg3(import_ts_utils_lib18.Utils.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9762
+ assertArg3(import_ts_utils_lib20.Utils.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9605
9763
  this.onStop();
9606
9764
  if (doc) {
9607
9765
  this.player = new MPlayer(doc, (playState) => {
@@ -9645,9 +9803,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9645
9803
  * @returns - This playback buttons class instance.
9646
9804
  */
9647
9805
  setPlayButton(btn, btnLabel) {
9648
- assertArg3(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9806
+ assertArg3(import_ts_utils_lib20.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9649
9807
  _MPlaybackButtons.removeOnClickListeners(this.playButton, this.onPlay);
9650
- this.playButton = require_t(import_ts_utils_lib18.Utils.Dom.getButton(btn), "Play button required!");
9808
+ this.playButton = require_t(import_ts_utils_lib20.Utils.Dom.getButton(btn), "Play button required!");
9651
9809
  this.playLabel = btnLabel != null ? btnLabel : "Play";
9652
9810
  _MPlaybackButtons.removeOnClickListeners(this.playButton, "all");
9653
9811
  _MPlaybackButtons.addOnClickListener(this.playButton, this.onPlay);
@@ -9661,9 +9819,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9661
9819
  * @returns - This playback buttons class instance.
9662
9820
  */
9663
9821
  setStopButton(btn, btnLabel) {
9664
- assertArg3(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9822
+ assertArg3(import_ts_utils_lib20.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9665
9823
  _MPlaybackButtons.removeOnClickListeners(this.stopButton, this.onStop);
9666
- this.stopButton = require_t(import_ts_utils_lib18.Utils.Dom.getButton(btn), "Stop button required!");
9824
+ this.stopButton = require_t(import_ts_utils_lib20.Utils.Dom.getButton(btn), "Stop button required!");
9667
9825
  this.stopLabel = btnLabel != null ? btnLabel : "Stop";
9668
9826
  _MPlaybackButtons.removeOnClickListeners(this.stopButton, "all");
9669
9827
  _MPlaybackButtons.addOnClickListener(this.stopButton, this.onStop);
@@ -9678,10 +9836,10 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9678
9836
  * @returns - This playback buttons class instance.
9679
9837
  */
9680
9838
  setPlayStopButton(btn, playLabel, stopLabel) {
9681
- assertArg3(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(playLabel), "playLabel", playLabel);
9682
- assertArg3(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(stopLabel), "stopLabel", stopLabel);
9839
+ assertArg3(import_ts_utils_lib20.Utils.Is.isStringOrUndefined(playLabel), "playLabel", playLabel);
9840
+ assertArg3(import_ts_utils_lib20.Utils.Is.isStringOrUndefined(stopLabel), "stopLabel", stopLabel);
9683
9841
  _MPlaybackButtons.removeOnClickListeners(this.playStopButton, this.onPlayStop);
9684
- this.playStopButton = require_t(import_ts_utils_lib18.Utils.Dom.getButton(btn), "Play/stop button required!");
9842
+ this.playStopButton = require_t(import_ts_utils_lib20.Utils.Dom.getButton(btn), "Play/stop button required!");
9685
9843
  this.playLabel = playLabel != null ? playLabel : "Play";
9686
9844
  this.stopLabel = stopLabel != null ? stopLabel : "Stop";
9687
9845
  _MPlaybackButtons.removeOnClickListeners(this.playStopButton, "all");
@@ -9696,9 +9854,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9696
9854
  * @returns - This playback buttons class instance.
9697
9855
  */
9698
9856
  setPauseButton(btn, btnLabel) {
9699
- assertArg3(import_ts_utils_lib18.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9857
+ assertArg3(import_ts_utils_lib20.Utils.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9700
9858
  _MPlaybackButtons.removeOnClickListeners(this.pauseButton, this.onPause);
9701
- this.pauseButton = require_t(import_ts_utils_lib18.Utils.Dom.getButton(btn), "Pause button required!");
9859
+ this.pauseButton = require_t(import_ts_utils_lib20.Utils.Dom.getButton(btn), "Pause button required!");
9702
9860
  this.pauseLabel = btnLabel != null ? btnLabel : "Pause";
9703
9861
  _MPlaybackButtons.removeOnClickListeners(this.pauseButton, "all");
9704
9862
  _MPlaybackButtons.addOnClickListener(this.pauseButton, this.onPause);
@@ -9720,7 +9878,7 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9720
9878
  }
9721
9879
  }
9722
9880
  static addOnClickListener(btn, onClick) {
9723
- assertArg3(import_ts_utils_lib18.Utils.Is.isFunction(onClick), "onClick", onClick);
9881
+ assertArg3(import_ts_utils_lib20.Utils.Is.isFunction(onClick), "onClick", onClick);
9724
9882
  btn.addEventListener("click", onClick);
9725
9883
  let clickListeners = this.savedOnClickListeners.get(btn) || [];
9726
9884
  this.savedOnClickListeners.set(btn, [...clickListeners, onClick]);
@@ -9762,6 +9920,7 @@ var import_core23 = require("@tspro/web-music-score/core");
9762
9920
  MNoteGroup,
9763
9921
  MPlaybackButtons,
9764
9922
  MPlayer,
9923
+ MRenderContext,
9765
9924
  MRenderer,
9766
9925
  MRest,
9767
9926
  MRhythmColumn,