@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,12 +1,12 @@
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
  import {
3
3
  NoteLengthProps,
4
4
  RhythmProps,
5
5
  validateNoteLength
6
- } from "../chunk-XUGM7SCC.mjs";
6
+ } from "../chunk-ZBA5XLYR.mjs";
7
7
  import {
8
8
  __publicField
9
- } from "../chunk-LC5JMIVF.mjs";
9
+ } from "../chunk-C6UQDKWU.mjs";
10
10
 
11
11
  // src/score/pub/div-rect.ts
12
12
  import { Utils } from "@tspro/ts-utils-lib";
@@ -288,7 +288,7 @@ var DivRect = class _DivRect {
288
288
  };
289
289
 
290
290
  // src/score/pub/document-builder.ts
291
- import { Utils as Utils15 } from "@tspro/ts-utils-lib";
291
+ import { Utils as Utils16 } from "@tspro/ts-utils-lib";
292
292
 
293
293
  // src/score/pub/types.ts
294
294
  var StaffPreset = /* @__PURE__ */ ((StaffPreset3) => {
@@ -300,10 +300,10 @@ var StaffPreset = /* @__PURE__ */ ((StaffPreset3) => {
300
300
  StaffPreset3["GuitarCombined"] = "guitarCombined";
301
301
  return StaffPreset3;
302
302
  })(StaffPreset || {});
303
- var Clef = /* @__PURE__ */ ((Clef4) => {
304
- Clef4["G"] = "G";
305
- Clef4["F"] = "F";
306
- return Clef4;
303
+ var Clef = /* @__PURE__ */ ((Clef2) => {
304
+ Clef2["G"] = "G";
305
+ Clef2["F"] = "F";
306
+ return Clef2;
307
307
  })(Clef || {});
308
308
  function getVoiceIds() {
309
309
  return [0, 1, 2, 3];
@@ -499,7 +499,7 @@ import { Note as Note9 } from "@tspro/web-music-score/theory";
499
499
  // src/score/engine/obj-staff-and-tab.ts
500
500
  import { getTuningStrings, Note as Note8, validateTuningName } from "@tspro/web-music-score/theory";
501
501
 
502
- // src/score/engine/renderer.ts
502
+ // src/score/engine/render-context.ts
503
503
  import { Utils as Utils2, Vec2, Device } from "@tspro/ts-utils-lib";
504
504
 
505
505
  // src/score/engine/settings.ts
@@ -524,6 +524,7 @@ var DocumentSettings = {
524
524
  FlagSeparation: 2,
525
525
  BeamSeparation: 1.25,
526
526
  BeamAngleFactor: 0.5,
527
+ BeamThickness: 4,
527
528
  RestDotSpace: 0.5,
528
529
  LedgerLineWidth: 3.6,
529
530
  StubTieLength: 5,
@@ -531,22 +532,22 @@ var DocumentSettings = {
531
532
  TabHeight: 20
532
533
  };
533
534
 
534
- // src/score/engine/renderer.ts
535
+ // src/score/engine/render-context.ts
535
536
  import { MusicError as MusicError2, MusicErrorType as MusicErrorType2 } from "@tspro/web-music-score/core";
536
537
 
537
- // src/score/engine/assets/treble-clef.png
538
- 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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";
538
+ // src/score/engine/assets/F-clef.png
539
+ 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==";
539
540
 
540
- // src/score/engine/assets/bass-clef.png
541
- 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==";
541
+ // src/score/engine/assets/G-clef.png
542
+ 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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";
542
543
 
543
- // src/score/engine/renderer.ts
544
+ // src/score/engine/render-context.ts
544
545
  var HilightStaffPosRectColor = "#55cc55";
545
546
  var HilightObjectRectColor = "#55cc55";
546
547
  var PlayPosIndicatorColor = "#44aa44";
547
548
  var ImageAssets = /* @__PURE__ */ new Map([
548
- [0 /* TrebleClefPng */, { src: treble_clef_default }],
549
- [1 /* BassClefPng */, { src: bass_clef_default }]
549
+ [0 /* G_Clef */, { src: G_clef_default }],
550
+ [1 /* F_Clef */, { src: F_clef_default }]
550
551
  ]);
551
552
  function staffPosEquals(a, b) {
552
553
  if (!a && !b) return true;
@@ -558,14 +559,13 @@ function objectsEquals(a, b) {
558
559
  else if (!a || !b) return false;
559
560
  else return a.length === b.length && a.every((a2, i) => a2 === b[i]);
560
561
  }
561
- var Renderer = class {
562
+ var RenderContext = class {
562
563
  constructor(mi) {
563
564
  this.mi = mi;
564
565
  __publicField(this, "devicePixelRatio");
565
566
  __publicField(this, "fontSize");
566
567
  __publicField(this, "unitSize");
567
- __publicField(this, "lineWidth");
568
- __publicField(this, "beamThickness");
568
+ __publicField(this, "_lineWidth");
569
569
  __publicField(this, "scoreEventListener");
570
570
  __publicField(this, "canvas");
571
571
  __publicField(this, "ctx");
@@ -585,8 +585,7 @@ var Renderer = class {
585
585
  this.devicePixelRatio = window.devicePixelRatio;
586
586
  this.fontSize = Device.FontSize * DocumentSettings.DocumentScale * this.devicePixelRatio;
587
587
  this.unitSize = this.fontSize * 0.3;
588
- this.lineWidth = this.unitSize * 0.2;
589
- this.beamThickness = this.unitSize * 0.8;
588
+ this._lineWidth = this.unitSize * 0.2;
590
589
  ImageAssets.forEach((asset) => {
591
590
  if (asset.finished !== true) {
592
591
  const img = new Image();
@@ -632,10 +631,10 @@ var Renderer = class {
632
631
  let prevMDoc = this.mdoc;
633
632
  this.mdoc = mdoc;
634
633
  if (prevMDoc) {
635
- prevMDoc.getMusicObject().setRenderer(void 0);
634
+ prevMDoc.getMusicObject().setRenderContext(void 0);
636
635
  }
637
636
  if (mdoc) {
638
- mdoc.getMusicObject().setRenderer(this);
637
+ mdoc.getMusicObject().setRenderContext(this);
639
638
  }
640
639
  }
641
640
  setCanvas(canvas) {
@@ -771,22 +770,24 @@ var Renderer = class {
771
770
  }
772
771
  }
773
772
  draw() {
774
- let { ctx, doc } = this;
775
- if (!ctx || !doc) {
776
- return;
773
+ try {
774
+ let { doc } = this;
775
+ if (doc) {
776
+ doc.layout();
777
+ this.updateCanvasSize();
778
+ this.clearCanvas();
779
+ this.drawHilightStaffPosRect();
780
+ this.drawHilightObjectRect();
781
+ this.drawPlayCursor();
782
+ doc.drawContent();
783
+ }
784
+ } catch (err) {
785
+ console.error("Render failed!", err);
777
786
  }
778
- doc.layout();
779
- this.updateCanvasSize();
780
- this.clearCanvas();
781
- this.drawHilightStaffPosRect();
782
- this.drawHilightObjectRect();
783
- this.drawPlayCursor();
784
- doc.drawContent();
785
787
  }
786
788
  drawHilightStaffPosRect() {
787
- let ctx = this.getCanvasContext();
788
789
  let { mousePos, hilightedStaffPos, unitSize } = this;
789
- if (!ctx || !hilightedStaffPos) {
790
+ if (!hilightedStaffPos) {
790
791
  return;
791
792
  }
792
793
  let { scoreRow, diatonicId } = hilightedStaffPos;
@@ -794,26 +795,25 @@ var Renderer = class {
794
795
  if (!staff) {
795
796
  return;
796
797
  }
797
- ctx.fillStyle = HilightStaffPosRectColor;
798
- ctx.fillRect(0, staff.getDiatonicIdY(diatonicId) - unitSize, ctx.canvas.width, 2 * unitSize);
798
+ this.fillColor(HilightStaffPosRectColor);
799
+ this.fillRect(staff.row.getRect().left, staff.getDiatonicIdY(diatonicId) - unitSize, staff.row.getRect().width, 2 * unitSize);
799
800
  if (mousePos !== void 0) {
800
801
  this.drawLedgerLines(staff, diatonicId, mousePos.x);
801
802
  }
802
803
  }
803
804
  drawHilightObjectRect() {
804
- let ctx = this.getCanvasContext();
805
805
  let { hilightedObj } = this;
806
- if (!ctx || !hilightedObj) {
806
+ if (!hilightedObj) {
807
807
  return;
808
808
  }
809
809
  let rect = hilightedObj.getRect();
810
- ctx.strokeStyle = HilightObjectRectColor;
811
- ctx.strokeRect(rect.left, rect.top, rect.width, rect.height);
810
+ this.lineColor(HilightObjectRectColor);
811
+ this.strokeRect(rect.left, rect.top, rect.width, rect.height);
812
812
  }
813
813
  drawPlayCursor() {
814
- let { cursorRect: r, lineWidth } = this;
814
+ let { cursorRect: r } = this;
815
815
  if (r) {
816
- this.drawLine(r.centerX, r.top, r.centerX, r.bottom, PlayPosIndicatorColor, lineWidth * 2);
816
+ this.color(PlayPosIndicatorColor).lineWidth(2).strokeLine(r.centerX, r.top, r.centerX, r.bottom);
817
817
  }
818
818
  }
819
819
  txFromScreenCoord(screenCoord) {
@@ -822,75 +822,13 @@ var Renderer = class {
822
822
  txToScreenCoord(coord) {
823
823
  return coord.div(this.devicePixelRatio);
824
824
  }
825
- getCanvasContext() {
826
- return this.ctx;
827
- }
828
825
  clearCanvas() {
829
- let ctx = this.getCanvasContext();
830
- if (ctx) {
831
- ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
832
- }
833
- }
834
- getTextWidth(text, font) {
835
- let ctx = this.getCanvasContext();
836
- if (ctx) {
837
- let savedFont = ctx.font;
838
- ctx.font = font;
839
- let metrics = ctx.measureText(text);
840
- ctx.font = savedFont;
841
- return metrics.width;
842
- } else {
843
- return Utils2.Dom.getCanvasTextWidth(text, font);
844
- }
826
+ var _a;
827
+ (_a = this.ctx) == null ? void 0 : _a.clearRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
845
828
  }
846
829
  drawDebugRect(r) {
847
- if (!DebugSettings.DrawDebugRects) {
848
- return;
849
- }
850
- let ctx = this.getCanvasContext();
851
- if (ctx) {
852
- ctx.lineWidth = 1;
853
- ctx.strokeStyle = "red";
854
- ctx.beginPath();
855
- ctx.rect(r.left, r.top, r.right - r.left, r.bottom - r.top);
856
- ctx.stroke();
857
- }
858
- }
859
- fillCircle(x, y, radius, color) {
860
- let ctx = this.getCanvasContext();
861
- if (ctx) {
862
- if (color !== void 0) {
863
- ctx.fillStyle = color;
864
- }
865
- ctx.beginPath();
866
- ctx.arc(x, y, radius, 0, 2 * Math.PI);
867
- ctx.fill();
868
- }
869
- }
870
- drawLine(startX, startY, endX, endY, color, lineWidth) {
871
- let ctx = this.getCanvasContext();
872
- if (ctx) {
873
- ctx.strokeStyle = color != null ? color : "black";
874
- ctx.lineWidth = lineWidth != null ? lineWidth : this.lineWidth;
875
- ctx.beginPath();
876
- ctx.moveTo(startX, startY);
877
- ctx.lineTo(endX, endY);
878
- ctx.stroke();
879
- }
880
- }
881
- drawPartialLine(startX, startY, endX, endY, startT, endT, color, lineWidth) {
882
- let ctx = this.getCanvasContext();
883
- if (ctx) {
884
- let x1 = startX + (endX - startX) * startT;
885
- let y1 = startY + (endY - startY) * startT;
886
- let x2 = startX + (endX - startX) * endT;
887
- let y2 = startY + (endY - startY) * endT;
888
- ctx.strokeStyle = color != null ? color : "black";
889
- ctx.lineWidth = lineWidth != null ? lineWidth : this.lineWidth;
890
- ctx.beginPath();
891
- ctx.moveTo(x1, y1);
892
- ctx.lineTo(x2, y2);
893
- ctx.stroke();
830
+ if (DebugSettings.DrawDebugRects) {
831
+ this.color("red").lineWidth(1).strokeRect(r.left, r.top, r.width, r.height);
894
832
  }
895
833
  }
896
834
  drawLedgerLines(staff, diatonicId, x) {
@@ -900,14 +838,14 @@ var Renderer = class {
900
838
  for (let lineDiatonicId = staff.topLineDiatonicId + 2; lineDiatonicId <= diatonicId; lineDiatonicId += 2) {
901
839
  if (staff.containsDiatonicId(lineDiatonicId)) {
902
840
  let y = staff.getDiatonicIdY(lineDiatonicId);
903
- this.drawLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
841
+ this.strokeLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
904
842
  }
905
843
  }
906
844
  } else if (diatonicId <= staff.bottomLineDiatonicId - 2) {
907
845
  for (let lineDiatonicId = staff.bottomLineDiatonicId - 2; lineDiatonicId >= diatonicId; lineDiatonicId -= 2) {
908
846
  if (staff.containsDiatonicId(lineDiatonicId)) {
909
847
  let y = staff.getDiatonicIdY(lineDiatonicId);
910
- this.drawLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
848
+ this.strokeLine(x - ledgerLineWidth / 2, y, x + ledgerLineWidth / 2, y);
911
849
  }
912
850
  }
913
851
  }
@@ -943,44 +881,38 @@ var Renderer = class {
943
881
  }
944
882
  return new DivRect(-leftw, 0, rightw, -toph, 0, bottomh);
945
883
  }
946
- drawRest(restSize, x, y, color) {
947
- let ctx = this.getCanvasContext();
948
- if (!ctx) {
949
- return;
950
- }
951
- let { unitSize, lineWidth } = this;
884
+ drawRest(restSize, x, y) {
885
+ let { unitSize } = this;
952
886
  let { flagCount } = NoteLengthProps.get(validateNoteLength(restSize + "n"));
953
- ctx.strokeStyle = ctx.fillStyle = color;
954
- ctx.lineWidth = lineWidth;
955
887
  if (NoteLengthProps.equals(restSize, "1n" /* Whole */)) {
956
- ctx.fillRect(x - unitSize, y, unitSize * 2, unitSize);
888
+ this.fillRect(x - unitSize, y, unitSize * 2, unitSize);
957
889
  } else if (NoteLengthProps.equals(restSize, "2n" /* Half */)) {
958
- ctx.fillRect(x - unitSize, y - unitSize, unitSize * 2, unitSize);
890
+ this.fillRect(x - unitSize, y - unitSize, unitSize * 2, unitSize);
959
891
  } else if (NoteLengthProps.equals(restSize, "4n" /* Quarter */)) {
960
- ctx.beginPath();
961
- ctx.moveTo(x - unitSize * 0.6, y - unitSize * 3.2);
962
- ctx.lineTo(x + unitSize * 0.7, y - unitSize * 1.5);
963
- ctx.quadraticCurveTo(
892
+ this.beginPath();
893
+ this.moveTo(x - unitSize * 0.6, y - unitSize * 3.2);
894
+ this.lineTo(x + unitSize * 0.7, y - unitSize * 1.5);
895
+ this.quadraticCurveTo(
964
896
  x - unitSize * 0.8,
965
897
  y - unitSize * 0.5,
966
898
  x + unitSize * 1,
967
899
  y + unitSize * 1.5
968
900
  );
969
- ctx.lineTo(x - unitSize * 1, y - unitSize * 0.75);
970
- ctx.quadraticCurveTo(
901
+ this.lineTo(x - unitSize * 1, y - unitSize * 0.75);
902
+ this.quadraticCurveTo(
971
903
  x + unitSize * 0.2,
972
904
  y - unitSize * 1.5,
973
905
  x - unitSize * 0.6,
974
906
  y - unitSize * 3.2
975
907
  );
976
- ctx.moveTo(x + unitSize * 1, y + unitSize * 1.5);
977
- ctx.quadraticCurveTo(
908
+ this.moveTo(x + unitSize * 1, y + unitSize * 1.5);
909
+ this.quadraticCurveTo(
978
910
  x - unitSize * 0.8,
979
911
  y + unitSize * 1,
980
912
  x - unitSize * 0.2,
981
913
  y + unitSize * 2.8
982
914
  );
983
- ctx.bezierCurveTo(
915
+ this.bezierCurveTo(
984
916
  x - unitSize * 1.8,
985
917
  y + unitSize * 1.5,
986
918
  x - unitSize * 0.6,
@@ -988,46 +920,42 @@ var Renderer = class {
988
920
  x + unitSize * 0.9,
989
921
  y + unitSize * 1.5
990
922
  );
991
- ctx.fill();
992
- ctx.stroke();
923
+ this.fill();
924
+ this.stroke();
993
925
  } else if (flagCount > 0) {
994
926
  let adj = 1 - flagCount % 2;
995
927
  let fx = (p) => x + (-p * 0.25 + 0.5) * unitSize;
996
928
  let fy = (p) => y + (p + adj) * unitSize;
997
- ctx.beginPath();
998
- ctx.moveTo(fx(1 + flagCount), fy(1 + flagCount));
999
- ctx.lineTo(fx(-0.5 - flagCount), fy(-0.5 - flagCount));
1000
- ctx.stroke();
929
+ this.beginPath();
930
+ this.moveTo(fx(1 + flagCount), fy(1 + flagCount));
931
+ this.lineTo(fx(-0.5 - flagCount), fy(-0.5 - flagCount));
932
+ this.stroke();
1001
933
  for (let i = 0; i < flagCount; i++) {
1002
934
  let t = flagCount - i * 2;
1003
- ctx.beginPath();
1004
- ctx.moveTo(fx(t - 2.5), fy(t - 2.5));
1005
- ctx.quadraticCurveTo(
935
+ this.beginPath();
936
+ this.moveTo(fx(t - 2.5), fy(t - 2.5));
937
+ this.quadraticCurveTo(
1006
938
  fx(t - 0.5) + unitSize * 0.25,
1007
939
  fy(t - 1.5),
1008
940
  fx(t - 1.5) - unitSize * 1.5,
1009
941
  fy(t - 1.5)
1010
942
  );
1011
- ctx.stroke();
1012
- ctx.beginPath();
1013
- ctx.arc(fx(t - 2) - unitSize * 1.5, fy(t - 2), unitSize * 0.5, 0, Math.PI * 2);
1014
- ctx.fill();
943
+ this.stroke();
944
+ this.beginPath();
945
+ this.arc(fx(t - 2) - unitSize * 1.5, fy(t - 2), unitSize * 0.5, 0, Math.PI * 2);
946
+ this.fill();
1015
947
  }
1016
948
  }
1017
949
  }
1018
950
  drawFlag(rect, dir) {
1019
- let ctx = this.getCanvasContext();
1020
- if (!ctx) {
1021
- return;
1022
- }
1023
951
  let left = rect.left;
1024
952
  let right = rect.right;
1025
953
  let width = right - left;
1026
954
  let top = dir === "up" ? rect.top : rect.bottom;
1027
955
  let bottom = dir === "up" ? rect.bottom : rect.top;
1028
- ctx.beginPath();
1029
- ctx.moveTo(left, top);
1030
- ctx.bezierCurveTo(
956
+ this.beginPath();
957
+ this.moveTo(left, top);
958
+ this.bezierCurveTo(
1031
959
  left,
1032
960
  top * 0.75 + bottom * 0.25,
1033
961
  left + width * 1.5,
@@ -1035,7 +963,169 @@ var Renderer = class {
1035
963
  left + width * 0.5,
1036
964
  bottom
1037
965
  );
1038
- ctx.stroke();
966
+ this.stroke();
967
+ }
968
+ color(color) {
969
+ if (this.ctx) this.ctx.strokeStyle = this.ctx.fillStyle = color;
970
+ return this;
971
+ }
972
+ lineColor(color) {
973
+ if (this.ctx) this.ctx.strokeStyle = color;
974
+ return this;
975
+ }
976
+ fillColor(color) {
977
+ if (this.ctx) this.ctx.fillStyle = color;
978
+ return this;
979
+ }
980
+ lineWidth(lineWidth) {
981
+ if (this.ctx) this.ctx.lineWidth = this._lineWidth * (lineWidth != null ? lineWidth : 1);
982
+ return this;
983
+ }
984
+ font(font) {
985
+ if (this.ctx) this.ctx.font = font;
986
+ return this;
987
+ }
988
+ beginPath() {
989
+ if (this.ctx) this.ctx.beginPath();
990
+ return this;
991
+ }
992
+ stroke() {
993
+ if (this.ctx) this.ctx.stroke();
994
+ return this;
995
+ }
996
+ fill() {
997
+ if (this.ctx) this.ctx.fill();
998
+ return this;
999
+ }
1000
+ moveTo(x, y) {
1001
+ if (this.ctx) this.ctx.moveTo(x, y);
1002
+ return this;
1003
+ }
1004
+ lineTo(x, y) {
1005
+ if (this.ctx) this.ctx.lineTo(x, y);
1006
+ return this;
1007
+ }
1008
+ bezierCurveTo(x1, y1, x2, y2, x3, y3) {
1009
+ if (this.ctx) this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
1010
+ return this;
1011
+ }
1012
+ quadraticCurveTo(x1, y1, x2, y2) {
1013
+ if (this.ctx) this.ctx.quadraticCurveTo(x1, y1, x2, y2);
1014
+ return this;
1015
+ }
1016
+ fillRect(x, y, w, h) {
1017
+ if (this.ctx) this.ctx.fillRect(x, y, w, h);
1018
+ return this;
1019
+ }
1020
+ setLineDash(pattern) {
1021
+ if (this.ctx) this.ctx.setLineDash(pattern);
1022
+ return this;
1023
+ }
1024
+ drawImage(img, x, y, w, h) {
1025
+ if (this.ctx) this.ctx.drawImage(img, x, y, w, h);
1026
+ return this;
1027
+ }
1028
+ ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle) {
1029
+ if (this.ctx) this.ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle);
1030
+ return this;
1031
+ }
1032
+ clip() {
1033
+ if (this.ctx) this.ctx.clip();
1034
+ return this;
1035
+ }
1036
+ save() {
1037
+ if (this.ctx) this.ctx.save();
1038
+ return this;
1039
+ }
1040
+ restore() {
1041
+ if (this.ctx) this.ctx.restore();
1042
+ return this;
1043
+ }
1044
+ rect(x, y, w, h) {
1045
+ if (this.ctx) this.ctx.rect(x, y, w, h);
1046
+ return this;
1047
+ }
1048
+ scale(x, y) {
1049
+ if (this.ctx) this.ctx.scale(x, y);
1050
+ return this;
1051
+ }
1052
+ strokeRect(x, y, w, h) {
1053
+ if (this.ctx) this.ctx.strokeRect(x, y, w, h);
1054
+ return this;
1055
+ }
1056
+ fillText(text, x, y) {
1057
+ if (this.ctx) this.ctx.fillText(text, x, y);
1058
+ return this;
1059
+ }
1060
+ getTextWidth(text, font) {
1061
+ if (this.ctx) {
1062
+ let savedFont = this.ctx.font;
1063
+ this.ctx.font = font;
1064
+ let metrics = this.ctx.measureText(text);
1065
+ this.ctx.font = savedFont;
1066
+ return metrics.width;
1067
+ } else {
1068
+ return Utils2.Dom.getCanvasTextWidth(text, font);
1069
+ }
1070
+ }
1071
+ arc(x, y, radius, startRadians, endRadians) {
1072
+ var _a;
1073
+ (_a = this.ctx) == null ? void 0 : _a.arc(x, y, radius, startRadians, endRadians);
1074
+ }
1075
+ fillCircle(x, y, radius) {
1076
+ if (this.ctx) {
1077
+ this.ctx.beginPath();
1078
+ this.ctx.arc(x, y, radius, 0, 2 * Math.PI);
1079
+ this.ctx.fill();
1080
+ }
1081
+ }
1082
+ strokeLine(startX, startY, endX, endY) {
1083
+ if (this.ctx) {
1084
+ this.ctx.beginPath();
1085
+ this.ctx.moveTo(startX, startY);
1086
+ this.ctx.lineTo(endX, endY);
1087
+ this.ctx.stroke();
1088
+ }
1089
+ }
1090
+ strokePartialLine(startX, startY, endX, endY, startT, endT) {
1091
+ let x1 = startX + (endX - startX) * startT;
1092
+ let y1 = startY + (endY - startY) * startT;
1093
+ let x2 = startX + (endX - startX) * endT;
1094
+ let y2 = startY + (endY - startY) * endT;
1095
+ if (this.ctx) {
1096
+ this.ctx.beginPath();
1097
+ this.ctx.moveTo(x1, y1);
1098
+ this.ctx.lineTo(x2, y2);
1099
+ this.ctx.stroke();
1100
+ }
1101
+ }
1102
+ drawBrace(rect, side) {
1103
+ if (this.ctx) {
1104
+ let { left, right, width, top, bottom, centerY } = rect;
1105
+ if (side === "right") {
1106
+ [left, right, width] = [right, left, -width];
1107
+ }
1108
+ this.ctx.beginPath();
1109
+ this.ctx.moveTo(right, top);
1110
+ this.ctx.bezierCurveTo(
1111
+ left + width * 0.1,
1112
+ top,
1113
+ left + width * 0.8,
1114
+ centerY,
1115
+ left,
1116
+ centerY
1117
+ );
1118
+ this.ctx.moveTo(right, bottom);
1119
+ this.ctx.bezierCurveTo(
1120
+ left + width * 0.1,
1121
+ bottom,
1122
+ left + width * 0.8,
1123
+ centerY,
1124
+ left,
1125
+ centerY
1126
+ );
1127
+ this.ctx.stroke();
1128
+ }
1039
1129
  }
1040
1130
  };
1041
1131
 
@@ -1044,8 +1134,8 @@ import { MusicError as MusicError15, MusicErrorType as MusicErrorType15 } from "
1044
1134
  import { Utils as Utils13 } from "@tspro/ts-utils-lib";
1045
1135
 
1046
1136
  // src/score/engine/obj-measure.ts
1047
- import { Utils as Utils12 } from "@tspro/ts-utils-lib";
1048
- import { getScale, Scale, validateScaleType, Note as Note7, RhythmProps as RhythmProps5, KeySignature as KeySignature2, getDefaultKeySignature, PitchNotation, SymbolSet, validateNoteLength as validateNoteLength3, NoteLengthProps as NoteLengthProps5 } from "@tspro/web-music-score/theory";
1137
+ import { Map3 as Map32, Utils as Utils12 } from "@tspro/ts-utils-lib";
1138
+ import { getScale, Scale, validateScaleType, Note as Note7, RhythmProps as RhythmProps5, KeySignature as KeySignature2, getDefaultKeySignature, PitchNotation, SymbolSet, validateNoteLength as validateNoteLength2, NoteLengthProps as NoteLengthProps5 } from "@tspro/web-music-score/theory";
1049
1139
  import { getDefaultTempo, getDefaultTimeSignature } from "@tspro/web-music-score/theory";
1050
1140
 
1051
1141
  // src/score/engine/acc-state.ts
@@ -1090,9 +1180,9 @@ var ObjImage = class extends MusicObject {
1090
1180
  pick(x, y) {
1091
1181
  return this.rect.contains(x, y) ? [this] : [];
1092
1182
  }
1093
- layout(renderer) {
1183
+ layout(ctx) {
1094
1184
  let { anchorX, anchorY, image, imageScale } = this;
1095
- let { unitSize } = renderer;
1185
+ let { unitSize } = ctx;
1096
1186
  try {
1097
1187
  let w = image.naturalWidth * imageScale * unitSize;
1098
1188
  let h = image.naturalHeight * imageScale * unitSize;
@@ -1104,17 +1194,10 @@ var ObjImage = class extends MusicObject {
1104
1194
  offset(dx, dy) {
1105
1195
  this.rect.offsetInPlace(dx, dy);
1106
1196
  }
1107
- draw(renderer) {
1108
- let ctx = renderer.getCanvasContext();
1109
- if (!ctx) {
1110
- return;
1111
- }
1197
+ draw(ctx) {
1112
1198
  let r = this.rect;
1113
- renderer.drawDebugRect(r);
1114
- try {
1115
- ctx.drawImage(this.image, r.centerX - r.leftw, r.centerY - r.toph, r.width, r.height);
1116
- } catch (err) {
1117
- }
1199
+ ctx.drawDebugRect(r);
1200
+ ctx.drawImage(this.image, r.centerX - r.leftw, r.centerY - r.toph, r.width, r.height);
1118
1201
  }
1119
1202
  };
1120
1203
 
@@ -1135,8 +1218,8 @@ var ObjAccidental = class extends MusicObject {
1135
1218
  pick(x, y) {
1136
1219
  return this.rect.contains(x, y) ? [this] : [];
1137
1220
  }
1138
- layout(renderer) {
1139
- let { unitSize } = renderer;
1221
+ layout(ctx) {
1222
+ let { unitSize } = ctx;
1140
1223
  switch (this.accidental) {
1141
1224
  case -2:
1142
1225
  this.rect = DivRect.createSections(unitSize * 1.25, unitSize * 1.25, unitSize * 4, unitSize * 1.2);
@@ -1160,34 +1243,23 @@ var ObjAccidental = class extends MusicObject {
1160
1243
  offset(dx, dy) {
1161
1244
  this.rect.offsetInPlace(dx, dy);
1162
1245
  }
1163
- draw(renderer) {
1164
- let ctx = renderer.getCanvasContext();
1165
- if (!ctx) {
1166
- return;
1167
- }
1168
- renderer.drawDebugRect(this.rect);
1169
- let { unitSize, lineWidth } = renderer;
1246
+ draw(ctx) {
1247
+ ctx.drawDebugRect(this.rect);
1248
+ let { unitSize } = ctx;
1170
1249
  let { accidental } = this;
1171
1250
  let x = this.rect.centerX;
1172
1251
  let y = this.rect.centerY;
1173
- ctx.strokeStyle = ctx.fillStyle = this.color;
1174
- function draw_b(x2, y2) {
1175
- if (ctx) {
1176
- ctx.lineWidth = lineWidth;
1177
- ctx.beginPath();
1178
- ctx.moveTo(x2 - unitSize * 0.75, y2 - unitSize * 4);
1179
- ctx.lineTo(x2 - unitSize * 0.75, y2 + unitSize * 1.1);
1180
- ctx.bezierCurveTo(
1181
- x2 + unitSize * 0.75,
1182
- y2 - unitSize * 0,
1183
- x2 + unitSize * 0.75,
1184
- y2 - unitSize * 2.2,
1185
- x2 - unitSize * 0.75,
1186
- y2 - unitSize * 0.5
1187
- );
1188
- ctx.stroke();
1189
- }
1190
- }
1252
+ ctx.color(this.color);
1253
+ const draw_b = (x2, y2) => {
1254
+ ctx.lineWidth(1).beginPath().moveTo(x2 - unitSize * 0.75, y2 - unitSize * 4).lineTo(x2 - unitSize * 0.75, y2 + unitSize * 1.1).bezierCurveTo(
1255
+ x2 + unitSize * 0.75,
1256
+ y2 - unitSize * 0,
1257
+ x2 + unitSize * 0.75,
1258
+ y2 - unitSize * 2.2,
1259
+ x2 - unitSize * 0.75,
1260
+ y2 - unitSize * 0.5
1261
+ ).stroke();
1262
+ };
1191
1263
  if (accidental === -2) {
1192
1264
  draw_b(x - unitSize * 0.5, y);
1193
1265
  draw_b(x + unitSize * 0.5, y);
@@ -1195,47 +1267,11 @@ var ObjAccidental = class extends MusicObject {
1195
1267
  draw_b(x, y);
1196
1268
  }
1197
1269
  if (accidental === 0) {
1198
- ctx.beginPath();
1199
- ctx.lineWidth = lineWidth;
1200
- ctx.moveTo(x - unitSize * 0.5, y - unitSize * 2.2);
1201
- ctx.lineTo(x - unitSize * 0.5, y + unitSize * 1);
1202
- ctx.moveTo(x + unitSize * 0.5, y + unitSize * 2.2);
1203
- ctx.lineTo(x + unitSize * 0.5, y - unitSize * 1);
1204
- ctx.stroke();
1205
- ctx.beginPath();
1206
- ctx.lineWidth = lineWidth * 2;
1207
- ctx.moveTo(x - unitSize * 0.5, y + unitSize * 1);
1208
- ctx.lineTo(x + unitSize * 0.5, y + unitSize * 0.6);
1209
- ctx.moveTo(x + unitSize * 0.5, y - unitSize * 1);
1210
- ctx.lineTo(x - unitSize * 0.5, y - unitSize * 0.6);
1211
- ctx.stroke();
1270
+ 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();
1212
1271
  } else if (accidental === 1) {
1213
- ctx.lineWidth = lineWidth;
1214
- ctx.beginPath();
1215
- ctx.moveTo(x - unitSize * 0.3, y - unitSize * 1.6);
1216
- ctx.lineTo(x - unitSize * 0.3, y + unitSize * 2);
1217
- ctx.moveTo(x + unitSize * 0.3, y - unitSize * 2);
1218
- ctx.lineTo(x + unitSize * 0.3, y + unitSize * 1.6);
1219
- ctx.stroke();
1220
- ctx.lineWidth = lineWidth * 2;
1221
- ctx.beginPath();
1222
- ctx.moveTo(x - unitSize * 0.75, y - unitSize * 0.5);
1223
- ctx.lineTo(x + unitSize * 0.75, y - unitSize * 0.9);
1224
- ctx.moveTo(x - unitSize * 0.75, y + unitSize * 0.9);
1225
- ctx.lineTo(x + unitSize * 0.75, y + unitSize * 0.5);
1226
- ctx.stroke();
1272
+ 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();
1227
1273
  } else if (accidental === 2) {
1228
- ctx.lineWidth = lineWidth;
1229
- ctx.beginPath();
1230
- ctx.moveTo(x - unitSize * 0.75, y - unitSize * 0.75);
1231
- ctx.lineTo(x + unitSize * 0.75, y + unitSize * 0.75);
1232
- ctx.moveTo(x - unitSize * 0.75, y + unitSize * 0.75);
1233
- ctx.lineTo(x + unitSize * 0.75, y - unitSize * 0.75);
1234
- ctx.stroke();
1235
- ctx.fillRect(x - unitSize * 1, y - unitSize * 1, unitSize * 0.7, unitSize * 0.7);
1236
- ctx.fillRect(x + unitSize * 0.3, y - unitSize * 1, unitSize * 0.7, unitSize * 0.7);
1237
- ctx.fillRect(x - unitSize * 1, y + unitSize * 0.3, unitSize * 0.7, unitSize * 0.7);
1238
- ctx.fillRect(x + unitSize * 0.3, y + unitSize * 0.3, unitSize * 0.7, unitSize * 0.7);
1274
+ 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);
1239
1275
  }
1240
1276
  }
1241
1277
  };
@@ -1301,13 +1337,13 @@ var ObjText = class extends MusicObject {
1301
1337
  pick(x, y) {
1302
1338
  return this.rect.contains(x, y) ? [this] : [];
1303
1339
  }
1304
- layout(renderer) {
1340
+ layout(ctx) {
1305
1341
  let { scale, anchorX, anchorY, bold, italic } = this;
1306
- let fontSize = renderer.fontSize * scale;
1342
+ let fontSize = ctx.fontSize * scale;
1307
1343
  this.font = (italic ? "italic " : "") + (bold ? "bold " : "") + fontSize + "px Times New Roman";
1308
- this.lineWidths = this.textLines.map((text) => renderer.getTextWidth(text, this.font));
1344
+ this.lineWidths = this.textLines.map((text) => ctx.getTextWidth(text, this.font));
1309
1345
  this.lineHeight = fontSize;
1310
- let p = this.padding * renderer.unitSize;
1346
+ let p = this.padding * ctx.unitSize;
1311
1347
  let w = p + Math.max(...this.lineWidths) + p;
1312
1348
  let h = p + this.lineHeight * this.textLines.length + p;
1313
1349
  if (this.boxed === "square" || this.boxed === "circle") {
@@ -1318,19 +1354,14 @@ var ObjText = class extends MusicObject {
1318
1354
  offset(dx, dy) {
1319
1355
  this.rect.offsetInPlace(dx, dy);
1320
1356
  }
1321
- draw(renderer) {
1322
- const ctx = renderer.getCanvasContext();
1323
- if (!ctx) {
1324
- return;
1325
- }
1326
- renderer.drawDebugRect(this.rect);
1327
- ctx.lineWidth = renderer.lineWidth;
1328
- ctx.strokeStyle = ctx.fillStyle = this.color;
1329
- ctx.font = this.font;
1357
+ draw(ctx) {
1358
+ var _a;
1359
+ ctx.drawDebugRect(this.rect);
1360
+ ctx.lineWidth(1).font(this.font);
1330
1361
  let { rect, padding, lineHeight, lineWidths, anchorX, anchorY, italic } = this;
1331
1362
  if (this.bgcolor !== void 0) {
1332
1363
  ctx.save();
1333
- ctx.fillStyle = this.bgcolor;
1364
+ ctx.fillColor((_a = this.bgcolor) != null ? _a : "black");
1334
1365
  ctx.beginPath();
1335
1366
  ctx.fillRect(rect.left, rect.top, rect.width, rect.height);
1336
1367
  ctx.fill();
@@ -1338,10 +1369,11 @@ var ObjText = class extends MusicObject {
1338
1369
  }
1339
1370
  let lineCount = this.textLines.length;
1340
1371
  let textHeight = lineCount * lineHeight;
1341
- let fixY = -lineHeight * (italic ? 0.25 : 0.175);
1342
- let p = padding * renderer.unitSize;
1372
+ let fixY = -lineHeight * (italic ? 0.25 : 0.2);
1373
+ let p = padding * ctx.unitSize;
1343
1374
  let centerX = (rect.left + p) * (1 - anchorX) + (rect.right - p) * anchorX;
1344
1375
  let centerY = (rect.top + p) * (1 - anchorY) + (rect.bottom - p) * anchorY;
1376
+ ctx.color(this.color);
1345
1377
  this.textLines.forEach((textLine, i) => {
1346
1378
  let x = centerX - lineWidths[i] * anchorX;
1347
1379
  let y = centerY - textHeight * anchorY + lineHeight * (i + 1) + fixY;
@@ -1387,9 +1419,9 @@ var ObjStaffSignature = class extends MusicObject {
1387
1419
  getMusicInterface() {
1388
1420
  return this.mi;
1389
1421
  }
1390
- updateClefImage(renderer, showClef) {
1422
+ updateClefImage(ctx, showClef) {
1391
1423
  if (showClef) {
1392
- let img = renderer.getImageAsset(this.staff.clefImageAsset);
1424
+ let img = ctx.getImageAsset(this.staff.clefImageAsset);
1393
1425
  this.clefImage = img ? new ObjImage(this, img, 0, 0.5, 0.1) : void 0;
1394
1426
  this.eightBelowClef = this.clefImage && this.staff.isOctaveDown ? new ObjText(this, "8", 0.5, 0) : void 0;
1395
1427
  } else {
@@ -1520,29 +1552,29 @@ var ObjStaffSignature = class extends MusicObject {
1520
1552
  }
1521
1553
  return [this];
1522
1554
  }
1523
- layout(renderer) {
1555
+ layout(ctx) {
1524
1556
  var _a, _b, _c, _d, _e, _f;
1525
- let { unitSize } = renderer;
1557
+ let { unitSize } = ctx;
1526
1558
  let { staff } = this;
1527
1559
  let paddingX = unitSize;
1528
1560
  let x = 0;
1529
1561
  this.rect = new DivRect();
1530
1562
  if (this.clefImage) {
1531
1563
  x += paddingX;
1532
- this.clefImage.layout(renderer);
1564
+ this.clefImage.layout(ctx);
1533
1565
  this.clefImage.offset(x, staff.getDiatonicIdY(staff.clefLineDiatonicId));
1534
1566
  this.rect.expandInPlace(this.clefImage.getRect());
1535
1567
  x = this.rect.right;
1536
1568
  if (this.eightBelowClef) {
1537
1569
  let r = this.clefImage.getRect();
1538
- this.eightBelowClef.layout(renderer);
1570
+ this.eightBelowClef.layout(ctx);
1539
1571
  this.eightBelowClef.offset(r.left + r.width / 2, Math.max(r.centerY + r.height * 0.3, staff.getBottomLineY()));
1540
1572
  this.rect.expandInPlace(this.eightBelowClef.getRect());
1541
1573
  }
1542
1574
  }
1543
1575
  if (this.measureNumber) {
1544
- this.measureNumber.layout(renderer);
1545
- let y = this.clefImage ? this.clefImage.getRect().top : staff.getTopLineY();
1576
+ this.measureNumber.layout(ctx);
1577
+ let y = Math.min(staff.getTopLineY(), this.clefImage ? this.clefImage.getRect().top : staff.getTopLineY());
1546
1578
  this.measureNumber.offset(0, y);
1547
1579
  this.rect.expandInPlace(this.measureNumber.getRect());
1548
1580
  x = Math.max(x, this.rect.right);
@@ -1550,7 +1582,7 @@ var ObjStaffSignature = class extends MusicObject {
1550
1582
  if (this.ksNeutralizeAccidentals.length > 0) {
1551
1583
  x += paddingX;
1552
1584
  this.ksNeutralizeAccidentals.forEach((objAcc) => {
1553
- objAcc.layout(renderer);
1585
+ objAcc.layout(ctx);
1554
1586
  objAcc.offset(x + objAcc.getRect().leftw, staff.getDiatonicIdY(objAcc.diatonicId));
1555
1587
  this.rect.expandInPlace(objAcc.getRect());
1556
1588
  x = this.rect.right;
@@ -1559,15 +1591,15 @@ var ObjStaffSignature = class extends MusicObject {
1559
1591
  if (this.ksNewAccidentals) {
1560
1592
  x += paddingX;
1561
1593
  this.ksNewAccidentals.forEach((objAcc) => {
1562
- objAcc.layout(renderer);
1594
+ objAcc.layout(ctx);
1563
1595
  objAcc.offset(x + objAcc.getRect().leftw, staff.getDiatonicIdY(objAcc.diatonicId));
1564
1596
  this.rect.expandInPlace(objAcc.getRect());
1565
1597
  x = this.rect.right;
1566
1598
  });
1567
1599
  }
1568
1600
  let right = x;
1569
- (_a = this.beatCountText) == null ? void 0 : _a.layout(renderer);
1570
- (_b = this.beatSizeText) == null ? void 0 : _b.layout(renderer);
1601
+ (_a = this.beatCountText) == null ? void 0 : _a.layout(ctx);
1602
+ (_b = this.beatSizeText) == null ? void 0 : _b.layout(ctx);
1571
1603
  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);
1572
1604
  if (this.beatCountText) {
1573
1605
  this.beatCountText.offset(x + tsWidth / 2 + paddingX, staff.getDiatonicIdY(staff.middleLineDiatonicId + 2));
@@ -1586,7 +1618,7 @@ var ObjStaffSignature = class extends MusicObject {
1586
1618
  ...this.ksNeutralizeAccidentals.map((o) => o.getRect().top),
1587
1619
  ...this.ksNewAccidentals.map((o) => o.getRect().top)
1588
1620
  );
1589
- this.tempoText.layout(renderer);
1621
+ this.tempoText.layout(ctx);
1590
1622
  this.tempoText.offset(x, tempoBottom);
1591
1623
  this.rect.expandInPlace(this.tempoText.getRect());
1592
1624
  }
@@ -1604,16 +1636,16 @@ var ObjStaffSignature = class extends MusicObject {
1604
1636
  (_f = this.tempoText) == null ? void 0 : _f.offset(dx, dy);
1605
1637
  this.rect.offsetInPlace(dx, dy);
1606
1638
  }
1607
- draw(renderer) {
1639
+ draw(ctx) {
1608
1640
  var _a, _b, _c, _d, _e, _f;
1609
- (_a = this.clefImage) == null ? void 0 : _a.draw(renderer);
1610
- (_b = this.eightBelowClef) == null ? void 0 : _b.draw(renderer);
1611
- (_c = this.measureNumber) == null ? void 0 : _c.draw(renderer);
1612
- this.ksNeutralizeAccidentals.forEach((acc) => acc.draw(renderer));
1613
- this.ksNewAccidentals.forEach((acc) => acc.draw(renderer));
1614
- (_d = this.beatCountText) == null ? void 0 : _d.draw(renderer);
1615
- (_e = this.beatSizeText) == null ? void 0 : _e.draw(renderer);
1616
- (_f = this.tempoText) == null ? void 0 : _f.draw(renderer);
1641
+ (_a = this.clefImage) == null ? void 0 : _a.draw(ctx);
1642
+ (_b = this.eightBelowClef) == null ? void 0 : _b.draw(ctx);
1643
+ (_c = this.measureNumber) == null ? void 0 : _c.draw(ctx);
1644
+ this.ksNeutralizeAccidentals.forEach((acc) => acc.draw(ctx));
1645
+ this.ksNewAccidentals.forEach((acc) => acc.draw(ctx));
1646
+ (_d = this.beatCountText) == null ? void 0 : _d.draw(ctx);
1647
+ (_e = this.beatSizeText) == null ? void 0 : _e.draw(ctx);
1648
+ (_f = this.tempoText) == null ? void 0 : _f.draw(ctx);
1617
1649
  }
1618
1650
  };
1619
1651
  var ObjTabSignature = class extends MusicObject {
@@ -1688,22 +1720,22 @@ var ObjTabSignature = class extends MusicObject {
1688
1720
  }
1689
1721
  return [this];
1690
1722
  }
1691
- layout(renderer) {
1723
+ layout(ctx) {
1692
1724
  var _a, _b, _c, _d, _e, _f;
1693
- let { unitSize } = renderer;
1725
+ let { unitSize } = ctx;
1694
1726
  let { tab } = this;
1695
1727
  let paddingX = unitSize;
1696
1728
  let x = 0;
1697
1729
  let topLineY = tab.getTopLineY();
1698
1730
  this.rect = new DivRect();
1699
1731
  if (this.measureNumber) {
1700
- this.measureNumber.layout(renderer);
1732
+ this.measureNumber.layout(ctx);
1701
1733
  this.measureNumber.offset(0, topLineY);
1702
1734
  this.rect.expandInPlace(this.measureNumber.getRect());
1703
1735
  x = Math.max(x, this.rect.right);
1704
1736
  }
1705
- (_a = this.beatCountText) == null ? void 0 : _a.layout(renderer);
1706
- (_b = this.beatSizeText) == null ? void 0 : _b.layout(renderer);
1737
+ (_a = this.beatCountText) == null ? void 0 : _a.layout(ctx);
1738
+ (_b = this.beatSizeText) == null ? void 0 : _b.layout(ctx);
1707
1739
  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);
1708
1740
  if (this.beatCountText) {
1709
1741
  this.beatCountText.offset(0 + tsWidth / 2 + paddingX, tab.getRect().centerY - this.beatCountText.getRect().bottomh);
@@ -1714,7 +1746,7 @@ var ObjTabSignature = class extends MusicObject {
1714
1746
  this.rect.expandInPlace(this.beatSizeText.getRect());
1715
1747
  }
1716
1748
  if (this.tempoText) {
1717
- this.tempoText.layout(renderer);
1749
+ this.tempoText.layout(ctx);
1718
1750
  this.tempoText.offset(x + unitSize * 2, topLineY);
1719
1751
  this.rect.expandInPlace(this.tempoText.getRect());
1720
1752
  }
@@ -1728,22 +1760,22 @@ var ObjTabSignature = class extends MusicObject {
1728
1760
  (_d = this.tempoText) == null ? void 0 : _d.offset(dx, dy);
1729
1761
  this.rect.offsetInPlace(dx, dy);
1730
1762
  }
1731
- draw(renderer) {
1763
+ draw(ctx) {
1732
1764
  var _a, _b, _c, _d;
1733
- (_a = this.measureNumber) == null ? void 0 : _a.draw(renderer);
1734
- (_b = this.beatCountText) == null ? void 0 : _b.draw(renderer);
1735
- (_c = this.beatSizeText) == null ? void 0 : _c.draw(renderer);
1736
- (_d = this.tempoText) == null ? void 0 : _d.draw(renderer);
1765
+ (_a = this.measureNumber) == null ? void 0 : _a.draw(ctx);
1766
+ (_b = this.beatCountText) == null ? void 0 : _b.draw(ctx);
1767
+ (_c = this.beatSizeText) == null ? void 0 : _c.draw(ctx);
1768
+ (_d = this.tempoText) == null ? void 0 : _d.draw(ctx);
1737
1769
  }
1738
1770
  };
1739
1771
 
1740
1772
  // src/score/engine/player.ts
1741
- import { Utils as Utils6 } from "@tspro/ts-utils-lib";
1742
- import { NoteLength as NoteLength6, RhythmProps as RhythmProps4, alterTempoSpeed } from "@tspro/web-music-score/theory";
1773
+ import { Utils as Utils5 } from "@tspro/ts-utils-lib";
1774
+ import { NoteLength as NoteLength4, RhythmProps as RhythmProps4, alterTempoSpeed } from "@tspro/web-music-score/theory";
1743
1775
  import * as Audio from "@tspro/web-music-score/audio";
1744
1776
 
1745
1777
  // src/score/engine/obj-rhythm-column.ts
1746
- import { Note as Note5, validateNoteLength as validateNoteLength2 } from "@tspro/web-music-score/theory";
1778
+ import { Note as Note5 } from "@tspro/web-music-score/theory";
1747
1779
 
1748
1780
  // src/score/engine/obj-arpeggio.ts
1749
1781
  var ObjArpeggio = class extends MusicObject {
@@ -1766,8 +1798,8 @@ var ObjArpeggio = class extends MusicObject {
1766
1798
  pick(x, y) {
1767
1799
  return this.rect.contains(x, y) ? [this] : [];
1768
1800
  }
1769
- layout(renderer) {
1770
- let { unitSize } = renderer;
1801
+ layout(ctx) {
1802
+ let { unitSize } = ctx;
1771
1803
  this.topArrowHeight = this.arpeggioDir === "up" /* Up */ ? unitSize : 0;
1772
1804
  this.bottomArrowHeight = this.arpeggioDir === "down" /* Down */ ? unitSize : 0;
1773
1805
  let top = this.line.getTopLineY();
@@ -1781,16 +1813,11 @@ var ObjArpeggio = class extends MusicObject {
1781
1813
  offset(dx, dy) {
1782
1814
  this.rect.offsetInPlace(dx, dy);
1783
1815
  }
1784
- draw(renderer) {
1785
- let ctx = renderer.getCanvasContext();
1786
- if (!ctx) {
1787
- return;
1788
- }
1789
- let { lineWidth } = renderer;
1816
+ draw(ctx) {
1790
1817
  let { rect, topArrowHeight, bottomArrowHeight } = this;
1791
- renderer.drawDebugRect(this.rect);
1792
- ctx.strokeStyle = ctx.fillStyle = this.color;
1793
- ctx.lineWidth = lineWidth * 2;
1818
+ ctx.drawDebugRect(this.rect);
1819
+ ctx.color(this.color);
1820
+ ctx.lineWidth(2);
1794
1821
  ctx.beginPath();
1795
1822
  for (let i = 0, y = rect.top + topArrowHeight; i < this.numCycles; i++, y += this.cycleHeight) {
1796
1823
  ctx.moveTo(rect.centerX, y);
@@ -1857,40 +1884,33 @@ var ObjStaffRest = class extends MusicObject {
1857
1884
  this.dotRects.forEach((r) => this.rect.expandInPlace(r));
1858
1885
  }
1859
1886
  };
1860
- var ObjRest = class extends MusicObject {
1887
+ var _ObjRest = class _ObjRest extends MusicObject {
1861
1888
  constructor(col, voiceId, noteLength, options, tupletRatio) {
1862
- var _a, _b;
1889
+ var _a, _b, _c, _d;
1863
1890
  super(col);
1864
1891
  this.col = col;
1865
1892
  this.voiceId = voiceId;
1866
- __publicField(this, "ownStemDir");
1867
- __publicField(this, "ownDiatonicId");
1893
+ this.options = options;
1868
1894
  __publicField(this, "color");
1869
1895
  __publicField(this, "hide");
1870
1896
  __publicField(this, "oldStyleTriplet");
1871
1897
  __publicField(this, "rhythmProps");
1898
+ __publicField(this, "setDiatonicId");
1899
+ __publicField(this, "runningDiatonicId");
1900
+ // Staff position of rest.
1901
+ __publicField(this, "runningStemDir");
1872
1902
  __publicField(this, "beamGroup");
1873
1903
  __publicField(this, "staffObjects", []);
1874
1904
  __publicField(this, "mi");
1875
- let diatonicId = getDiatonicIdFromStaffPos(options == null ? void 0 : options.staffPos);
1876
- if (diatonicId !== void 0) {
1877
- let hasStaff = this.row.hasStaff;
1878
- let staff2 = this.row.getStaff(diatonicId);
1879
- if (hasStaff && !staff2) {
1880
- throw new MusicError5(MusicErrorType5.Score, "Rest staffPos is out of staff boundaries!");
1881
- }
1882
- }
1883
- this.ownDiatonicId = this.measure.updateOwnDiatonicId(voiceId, diatonicId);
1884
- this.ownStemDir = this.measure.updateOwnStemDir(
1885
- this
1886
- /*, options?.stem*/
1887
- );
1888
- let staff = this.row.getStaff(this.ownDiatonicId);
1889
- if (staff && staff.isSpace(this.ownDiatonicId)) {
1890
- this.ownDiatonicId += this.ownDiatonicId >= staff.middleLineDiatonicId ? 1 : -1;
1891
- }
1892
- this.color = (_a = options == null ? void 0 : options.color) != null ? _a : "black";
1893
- this.hide = (_b = options == null ? void 0 : options.hide) != null ? _b : false;
1905
+ this.setDiatonicId = (_b = getDiatonicIdFromStaffPos((_a = this.options) == null ? void 0 : _a.staffPos)) != null ? _b : _ObjRest.UndefinedDiatonicId;
1906
+ let staves = this.row.getStaves().filter((staff) => staff.containsVoiceId(this.voiceId));
1907
+ if (this.setDiatonicId !== _ObjRest.UndefinedDiatonicId && staves.length > 0 && staves[0].isSpace(this.setDiatonicId)) {
1908
+ this.setDiatonicId += this.setDiatonicId >= staves[0].middleLineDiatonicId ? 1 : -1;
1909
+ }
1910
+ this.runningDiatonicId = this.setDiatonicId;
1911
+ this.runningStemDir = "up" /* Up */;
1912
+ this.color = (_c = options == null ? void 0 : options.color) != null ? _c : "black";
1913
+ this.hide = (_d = options == null ? void 0 : options.hide) != null ? _d : false;
1894
1914
  this.oldStyleTriplet = tupletRatio === void 0 && ((options == null ? void 0 : options.triplet) === true || NoteLengthProps2.get(noteLength).isTriplet);
1895
1915
  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;
1896
1916
  this.rhythmProps = RhythmProps2.get(noteLength, dotCount, (tupletRatio != null ? tupletRatio : this.oldStyleTriplet) ? Tuplet.Triplet : void 0);
@@ -1911,8 +1931,27 @@ var ObjRest = class extends MusicObject {
1911
1931
  get noteLength() {
1912
1932
  return this.rhythmProps.noteLength;
1913
1933
  }
1934
+ getDiatonicId(staff) {
1935
+ if (this.runningDiatonicId === _ObjRest.UndefinedDiatonicId) {
1936
+ if (staff) {
1937
+ if (NoteLengthProps2.equals(this.noteLength, "1n")) {
1938
+ return staff.middleLineDiatonicId + 2;
1939
+ } else {
1940
+ return staff.middleLineDiatonicId;
1941
+ }
1942
+ } else {
1943
+ return Note3.getNote("G4").diatonicId;
1944
+ }
1945
+ } else {
1946
+ return this.runningDiatonicId;
1947
+ }
1948
+ }
1914
1949
  get stemDir() {
1915
- return this.beamGroup ? this.beamGroup.stemDir : this.ownStemDir;
1950
+ return this.runningStemDir;
1951
+ }
1952
+ updateRunningArguments(diatonicId, stemDir, stringNumbers) {
1953
+ this.runningDiatonicId = diatonicId;
1954
+ this.runningStemDir = stemDir;
1916
1955
  }
1917
1956
  getStaticObjects(line) {
1918
1957
  let staticObjects = [];
@@ -1984,28 +2023,28 @@ var ObjRest = class extends MusicObject {
1984
2023
  }
1985
2024
  updateAccidentalState(accState) {
1986
2025
  }
1987
- layout(renderer, accState) {
2026
+ layout(ctx, accState) {
1988
2027
  this.requestRectUpdate();
1989
2028
  this.staffObjects.length = 0;
1990
2029
  if (this.hide) {
1991
2030
  return;
1992
2031
  }
1993
- let { unitSize } = renderer;
1994
- let { ownDiatonicId } = this;
2032
+ let { unitSize } = ctx;
1995
2033
  let { noteSize, dotCount } = this.rhythmProps;
1996
2034
  this.row.getStaves().forEach((staff) => {
1997
- if (!staff.containsDiatonicId(ownDiatonicId) || !staff.containsVoiceId(this.voiceId)) {
2035
+ let diatonicId = this.getDiatonicId(staff);
2036
+ if (!staff.containsDiatonicId(diatonicId) || !staff.containsVoiceId(this.voiceId)) {
1998
2037
  return;
1999
2038
  }
2000
2039
  let obj = new ObjStaffRest(staff, this);
2001
- obj.restRect = renderer.getRestRect(noteSize);
2040
+ obj.restRect = ctx.getRestRect(noteSize);
2002
2041
  for (let i = 0; i < dotCount; i++) {
2003
2042
  let dotWidth = DocumentSettings.DotSize * unitSize;
2004
2043
  let dotX = obj.restRect.rightw + (DocumentSettings.RestDotSpace + DocumentSettings.DotSize * unitSize) + i * DocumentSettings.DotSize * unitSize * 1.5;
2005
2044
  let dotY = this.getRestDotVerticalDisplacement(noteSize) * unitSize;
2006
2045
  obj.dotRects.push(DivRect.createCentered(dotX, dotY, dotWidth, dotWidth));
2007
2046
  }
2008
- obj.offset(0, staff.getDiatonicIdY(ownDiatonicId));
2047
+ obj.offset(0, staff.getDiatonicIdY(diatonicId));
2009
2048
  this.staffObjects.push(obj);
2010
2049
  });
2011
2050
  }
@@ -2025,48 +2064,41 @@ var ObjRest = class extends MusicObject {
2025
2064
  this.staffObjects.forEach((s) => s.offset(dx, 0));
2026
2065
  this.requestRectUpdate();
2027
2066
  }
2028
- draw(renderer) {
2029
- let ctx = renderer.getCanvasContext();
2030
- if (!ctx || this.staffObjects.length === 0) {
2067
+ draw(ctx) {
2068
+ if (this.staffObjects.length === 0) {
2031
2069
  return;
2032
2070
  }
2033
- renderer.drawDebugRect(this.getRect());
2034
- let { lineWidth } = renderer;
2035
- let { color } = this;
2071
+ ctx.drawDebugRect(this.getRect());
2036
2072
  let { noteSize } = this.rhythmProps;
2037
- ctx.strokeStyle = ctx.fillStyle = color;
2038
- ctx.lineWidth = lineWidth;
2073
+ ctx.color(this.color).lineWidth(1);
2039
2074
  this.staffObjects.forEach((obj) => {
2040
2075
  let { dotRects, restRect } = obj;
2041
2076
  let x = restRect.centerX;
2042
2077
  let y = restRect.centerY;
2043
- renderer.drawRest(noteSize, x, y, color);
2044
- dotRects.forEach((r) => {
2045
- renderer.fillCircle(r.centerX, r.centerY, r.width / 2);
2046
- });
2078
+ ctx.drawRest(noteSize, x, y);
2079
+ dotRects.forEach((r) => ctx.fillCircle(r.centerX, r.centerY, r.width / 2));
2047
2080
  });
2048
2081
  }
2049
2082
  };
2083
+ __publicField(_ObjRest, "UndefinedDiatonicId", Infinity);
2084
+ var ObjRest = _ObjRest;
2050
2085
 
2051
2086
  // src/score/engine/obj-note-group.ts
2052
2087
  import { Utils as Utils3 } from "@tspro/ts-utils-lib";
2053
2088
  import { Note as Note4, NoteLengthProps as NoteLengthProps3, RhythmProps as RhythmProps3, Tuplet as Tuplet2 } from "@tspro/web-music-score/theory";
2054
2089
  import { MusicError as MusicError6, MusicErrorType as MusicErrorType6 } from "@tspro/web-music-score/core";
2055
- function getStem(stem) {
2056
- return Utils3.Is.isEnumValue(stem, Stem) ? stem : void 0;
2057
- }
2058
2090
  function getArpeggio(a) {
2059
2091
  return Utils3.Is.isEnumValue(a, Arpeggio) ? a : a === true ? "up" /* Up */ : void 0;
2060
2092
  }
2061
- function sortNoteStringData(notes, strings) {
2093
+ function sortNotesAndStrings(notes, strings) {
2062
2094
  let stringArr = Utils3.Arr.isArray(strings) ? strings : strings !== void 0 ? [strings] : [];
2063
2095
  let noteStringData = notes.map((note, i) => {
2064
2096
  return { note, string: stringArr[i] };
2065
2097
  });
2066
2098
  noteStringData = Utils3.Arr.removeDuplicatesCmp(noteStringData, (a, b) => Note4.equals(a.note, b.note)).sort((a, b) => Note4.compareFunc(a.note, b.note));
2067
2099
  return {
2068
- notes: noteStringData.map((e) => e.note),
2069
- strings: noteStringData.every((e) => e.string === void 0) ? void 0 : noteStringData.map((e) => e.string)
2100
+ sortedNotes: noteStringData.map((e) => e.note),
2101
+ sortedStrings: noteStringData.every((e) => e.string === void 0) ? void 0 : noteStringData.map((e) => e.string)
2070
2102
  };
2071
2103
  }
2072
2104
  var ObjStaffNoteGroup = class extends MusicObject {
@@ -2138,7 +2170,6 @@ var ObjTabNoteGroup = class extends MusicObject {
2138
2170
  this.noteGroup = noteGroup;
2139
2171
  __publicField(this, "fretNumbers", []);
2140
2172
  __publicField(this, "mi");
2141
- tab.addObject(this);
2142
2173
  this.mi = new MTabNoteGroup(this);
2143
2174
  }
2144
2175
  getMusicInterface() {
@@ -2164,12 +2195,13 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2164
2195
  this.col = col;
2165
2196
  this.voiceId = voiceId;
2166
2197
  this.notes = notes;
2167
- __publicField(this, "minDiatonicId");
2168
- __publicField(this, "maxDiatonicId");
2169
- __publicField(this, "ownDiatonicId");
2198
+ this.options = options;
2199
+ __publicField(this, "setDiatonicId");
2200
+ __publicField(this, "setStringsNumbers");
2201
+ __publicField(this, "runningDiatonicId");
2170
2202
  // Average diatonicId of notes.
2171
- __publicField(this, "ownStemDir");
2172
- __publicField(this, "ownString");
2203
+ __publicField(this, "runningStemDir");
2204
+ __publicField(this, "runningStringNumbers");
2173
2205
  __publicField(this, "color");
2174
2206
  __publicField(this, "staccato");
2175
2207
  __publicField(this, "diamond");
@@ -2187,13 +2219,13 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2187
2219
  if (!Utils3.Is.isIntegerGte(notes.length, 1)) {
2188
2220
  throw new MusicError6(MusicErrorType6.Score, "Cannot create note group object because notes array is empty.");
2189
2221
  }
2190
- let noteStringData = sortNoteStringData(notes, options == null ? void 0 : options.string);
2191
- this.notes = noteStringData.notes;
2192
- this.minDiatonicId = this.notes[0].diatonicId;
2193
- this.maxDiatonicId = this.notes[this.notes.length - 1].diatonicId;
2194
- this.ownDiatonicId = this.measure.updateOwnDiatonicId(voiceId, Math.round((this.minDiatonicId + this.maxDiatonicId) / 2));
2195
- this.ownStemDir = this.measure.updateOwnStemDir(this, getStem(options == null ? void 0 : options.stem));
2196
- this.ownString = this.measure.updateOwnString(this, noteStringData.strings);
2222
+ let { sortedNotes, sortedStrings } = sortNotesAndStrings(notes, options == null ? void 0 : options.string);
2223
+ this.notes = sortedNotes;
2224
+ this.setStringsNumbers = sortedStrings;
2225
+ this.setDiatonicId = Math.round((this.minDiatonicId + this.maxDiatonicId) / 2);
2226
+ this.runningDiatonicId = this.setDiatonicId;
2227
+ this.runningStemDir = "up" /* Up */;
2228
+ this.runningStringNumbers = [];
2197
2229
  this.color = (_a = options == null ? void 0 : options.color) != null ? _a : "black";
2198
2230
  this.staccato = (_b = options == null ? void 0 : options.staccato) != null ? _b : false;
2199
2231
  this.diamond = (_c = options == null ? void 0 : options.diamond) != null ? _c : false;
@@ -2215,11 +2247,20 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2215
2247
  get row() {
2216
2248
  return this.col.row;
2217
2249
  }
2250
+ get minDiatonicId() {
2251
+ return this.notes[0].diatonicId;
2252
+ }
2253
+ get maxDiatonicId() {
2254
+ return this.notes[this.notes.length - 1].diatonicId;
2255
+ }
2256
+ getDiatonicId(staff) {
2257
+ return this.runningDiatonicId;
2258
+ }
2218
2259
  get stemDir() {
2219
- return this.beamGroup ? this.beamGroup.stemDir : this.ownStemDir;
2260
+ return this.runningStemDir;
2220
2261
  }
2221
2262
  enableConnective(line) {
2222
- return line.containsVoiceId(this.voiceId) && (line instanceof ObjTab || line.containsDiatonicId(this.ownDiatonicId));
2263
+ return line.containsVoiceId(this.voiceId) && (line instanceof ObjTab || line.containsDiatonicId(this.runningDiatonicId));
2223
2264
  }
2224
2265
  startConnective(connectiveProps) {
2225
2266
  if (!this.row.hasStaff && connectiveProps.connective === "tie" /* Tie */) {
@@ -2230,6 +2271,11 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2230
2271
  this.startConnnectives.push(connectiveProps);
2231
2272
  this.doc.addConnectiveProps(connectiveProps);
2232
2273
  }
2274
+ updateRunningArguments(diatonicId, stemDir, stringNumbers) {
2275
+ this.runningDiatonicId = diatonicId === ObjRest.UndefinedDiatonicId ? this.setDiatonicId : diatonicId;
2276
+ this.runningStemDir = stemDir;
2277
+ this.runningStringNumbers = stringNumbers;
2278
+ }
2233
2279
  getStaticObjects(line) {
2234
2280
  let staticObjects = [];
2235
2281
  this.staffObjects.forEach((obj) => {
@@ -2269,12 +2315,12 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2269
2315
  return this.notes[0];
2270
2316
  }
2271
2317
  getConnectiveAnchorPoint(connectiveProps, line, noteIndex, noteAnchor, side) {
2318
+ var _a;
2272
2319
  if (line instanceof ObjStaff) {
2273
- let staff = line;
2274
2320
  if (noteIndex < 0 || noteIndex >= this.notes.length) {
2275
2321
  throw new MusicError6(MusicErrorType6.Score, "Invalid noteIndex: " + noteIndex);
2276
2322
  }
2277
- let obj = this.staffObjects.find((obj2) => obj2.staff === staff);
2323
+ let obj = this.staffObjects.find((obj2) => obj2.staff === line);
2278
2324
  if (!obj || noteIndex < 0 || noteIndex >= obj.noteHeadRects.length) {
2279
2325
  let r = this.getRect();
2280
2326
  return { x: r.centerX, y: r.bottom };
@@ -2322,11 +2368,9 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2322
2368
  default:
2323
2369
  throw new MusicError6(MusicErrorType6.Score, "Invalid noteAnchor: " + noteAnchor);
2324
2370
  }
2325
- } else {
2326
- let tab = line;
2327
- let obj = this.tabObjects.find((obj2) => obj2.tab === tab);
2328
- let fretNumber = obj == null ? void 0 : obj.fretNumbers[noteIndex];
2329
- if (!obj || !fretNumber) {
2371
+ } else if (line instanceof ObjTab) {
2372
+ let fretNumber = (_a = this.tabObjects.find((obj) => obj.tab === line)) == null ? void 0 : _a.fretNumbers[noteIndex];
2373
+ if (!fretNumber) {
2330
2374
  return { x: 0, y: 0 };
2331
2375
  }
2332
2376
  let r = fretNumber.getRect();
@@ -2334,26 +2378,29 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2334
2378
  let y;
2335
2379
  let s = 0.9;
2336
2380
  if (connectiveProps.connective === "slide" /* Slide */) {
2337
- let leftFretNumber = connectiveProps.noteGroups[0].getFretNumber(obj, 0);
2338
- let rightFretNumber = connectiveProps.noteGroups[1].getFretNumber(obj, 0);
2381
+ let leftFretNumber = connectiveProps.noteGroups[0].getFretNumber(line, 0);
2382
+ let rightFretNumber = connectiveProps.noteGroups[1].getFretNumber(line, 0);
2339
2383
  let slideUp = leftFretNumber === void 0 || rightFretNumber === void 0 || leftFretNumber <= rightFretNumber;
2340
2384
  if (side === "left") {
2341
- y = slideUp ? r.centerY + r.bottomh * s : r.centerY - r.toph * s;
2385
+ y = (slideUp ? r.centerY + r.bottomh : r.centerY - r.toph) * s;
2342
2386
  } else {
2343
- y = slideUp ? r.centerY - r.toph * s : r.centerY + r.bottomh * s;
2387
+ y = (slideUp ? r.centerY - r.toph : r.centerY + r.bottomh) * s;
2344
2388
  }
2345
2389
  } else {
2346
2390
  y = r.centerY + r.bottomh * s;
2347
2391
  }
2348
2392
  return { x, y };
2393
+ } else {
2394
+ return { x: 0, y: 0 };
2349
2395
  }
2350
2396
  }
2351
2397
  getFretNumberString(noteIndex) {
2352
- return this.ownString[noteIndex];
2398
+ return this.runningStringNumbers[noteIndex];
2353
2399
  }
2354
- getFretNumber(tabObj, noteIndex) {
2355
- let fretNumber = tabObj.fretNumbers[noteIndex];
2356
- return fretNumber === void 0 ? void 0 : +fretNumber.getText();
2400
+ getFretNumber(tab, noteIndex) {
2401
+ let tabObj = this.tabObjects.find((o) => o.tab === tab);
2402
+ let fretNumber = tabObj == null ? void 0 : tabObj.fretNumbers[noteIndex];
2403
+ return fretNumber ? parseInt(fretNumber.getText()) : void 0;
2357
2404
  }
2358
2405
  getNextNoteGroup() {
2359
2406
  let voiceNoteGroups = this.measure.getVoiceSymbols(this.voiceId).filter((s) => s instanceof _ObjNoteGroup);
@@ -2416,8 +2463,8 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2416
2463
  return { staff, x, y, stemHeight };
2417
2464
  });
2418
2465
  }
2419
- getStemHeight(renderer) {
2420
- let { unitSize } = renderer;
2466
+ getStemHeight(ctx) {
2467
+ let { unitSize } = ctx;
2421
2468
  let { flagCount, hasStem } = this.rhythmProps;
2422
2469
  if (hasStem) {
2423
2470
  let addY = this.hasBeamCount() ? DocumentSettings.BeamSeparation : DocumentSettings.FlagSeparation;
@@ -2480,9 +2527,9 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2480
2527
  }
2481
2528
  });
2482
2529
  }
2483
- layout(renderer, accState) {
2530
+ layout(ctx, accState) {
2484
2531
  this.requestRectUpdate();
2485
- let { unitSize } = renderer;
2532
+ let { unitSize } = ctx;
2486
2533
  let { row, stemDir } = this;
2487
2534
  let { dotCount, flagCount, hasStem } = this.rhythmProps;
2488
2535
  let dotWidth = DocumentSettings.DotSize * unitSize;
@@ -2490,7 +2537,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2490
2537
  let noteHeadHeight = (this.diamond ? DocumentSettings.DiamondNoteHeadSize : DocumentSettings.NoteHeadHeight) * unitSize;
2491
2538
  this.staffObjects.length = 0;
2492
2539
  row.getStaves().forEach((staff) => {
2493
- if (!staff.containsDiatonicId(this.ownDiatonicId) || !staff.containsVoiceId(this.voiceId)) {
2540
+ if (!staff.containsDiatonicId(this.runningDiatonicId) || !staff.containsVoiceId(this.voiceId)) {
2494
2541
  return;
2495
2542
  }
2496
2543
  let obj = new ObjStaffNoteGroup(staff, this);
@@ -2513,7 +2560,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2513
2560
  if (accState.needAccidental(note)) {
2514
2561
  let acc = obj.accidentals[noteIndex] = new ObjAccidental(this, note.diatonicId, note.accidental, this.color);
2515
2562
  if (acc) {
2516
- acc.layout(renderer);
2563
+ acc.layout(ctx);
2517
2564
  acc.offset(-noteHeadRect.leftw - unitSize * DocumentSettings.NoteAccSpace - acc.getRect().rightw, noteY);
2518
2565
  }
2519
2566
  noteStaff.addObject(acc);
@@ -2544,7 +2591,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2544
2591
  let bottomNoteY = obj.noteHeadRects[0].centerY;
2545
2592
  let topNoteY = obj.noteHeadRects[obj.noteHeadRects.length - 1].centerY;
2546
2593
  let stemX = stemDir === "up" /* Up */ ? noteHeadWidth / 2 : -noteHeadWidth / 2;
2547
- let stemHeight = this.getStemHeight(renderer);
2594
+ let stemHeight = this.getStemHeight(ctx);
2548
2595
  let stemTipY = stemDir === "up" /* Up */ ? topNoteY - stemHeight : bottomNoteY + stemHeight;
2549
2596
  let stemBaseY = stemDir === "up" /* Up */ ? bottomNoteY : topNoteY;
2550
2597
  if (hasStem) {
@@ -2571,20 +2618,21 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2571
2618
  }
2572
2619
  let obj = new ObjTabNoteGroup(tab, this);
2573
2620
  this.notes.forEach((note, noteIndex) => {
2574
- if (this.ownString[noteIndex] !== void 0) {
2575
- let stringId = this.ownString[noteIndex] - 1;
2576
- let fretId = note.chromaticId - tab.getTuningStrings()[stringId].chromaticId;
2621
+ let stringNumber = this.runningStringNumbers[noteIndex];
2622
+ if (Utils3.Is.isIntegerBetween(stringNumber, 1, 6)) {
2623
+ let fretId = note.chromaticId - tab.getTuningStrings()[stringNumber - 1].chromaticId;
2577
2624
  let color = fretId < 0 ? "red" : "black";
2578
2625
  let fretNumber = new ObjText(this, { text: String(fretId), color, bgcolor: "white" }, 0.5, 0.5);
2579
- obj.fretNumbers.push(fretNumber);
2580
- fretNumber.layout(renderer);
2626
+ fretNumber.layout(ctx);
2581
2627
  let x = this.col.getRect().centerX;
2582
- let y = tab.getStringY(stringId);
2628
+ let y = tab.getStringY(stringNumber - 1);
2583
2629
  fretNumber.offset(x, y);
2630
+ obj.fretNumbers.push(fretNumber);
2584
2631
  }
2585
2632
  });
2586
2633
  if (obj.fretNumbers.length > 0) {
2587
2634
  this.tabObjects.push(obj);
2635
+ tab.addObject(obj);
2588
2636
  }
2589
2637
  });
2590
2638
  }
@@ -2612,19 +2660,14 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2612
2660
  this.tabObjects.forEach((obj) => obj.offset(dx, 0));
2613
2661
  this.requestRectUpdate();
2614
2662
  }
2615
- draw(renderer) {
2616
- const ctx = renderer.getCanvasContext();
2617
- if (!ctx) {
2618
- return;
2619
- }
2620
- renderer.drawDebugRect(this.getRect());
2621
- let { lineWidth } = renderer;
2622
- let { color, stemDir } = this;
2663
+ draw(ctx) {
2664
+ ctx.drawDebugRect(this.getRect());
2665
+ let { stemDir } = this;
2623
2666
  let { isSolidNoteHead } = this.rhythmProps;
2624
2667
  this.staffObjects.forEach((obj) => {
2625
- obj.accidentals.forEach((d) => d.draw(renderer));
2626
- ctx.strokeStyle = ctx.fillStyle = color;
2627
- ctx.lineWidth = lineWidth;
2668
+ obj.accidentals.forEach((d) => d.draw(ctx));
2669
+ ctx.color(this.color);
2670
+ ctx.lineWidth(1);
2628
2671
  obj.noteHeadRects.forEach((r) => {
2629
2672
  if (this.diamond) {
2630
2673
  if (isSolidNoteHead) {
@@ -2637,14 +2680,14 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2637
2680
  ctx.fill();
2638
2681
  } else {
2639
2682
  ctx.beginPath();
2640
- ctx.lineWidth = lineWidth * 2.5;
2683
+ ctx.lineWidth(2.5);
2641
2684
  ctx.moveTo(r.centerX, r.top);
2642
2685
  ctx.lineTo(r.right, r.centerY);
2643
2686
  ctx.moveTo(r.left, r.centerY);
2644
2687
  ctx.lineTo(r.centerX, r.bottom);
2645
2688
  ctx.stroke();
2646
2689
  ctx.beginPath();
2647
- ctx.lineWidth = lineWidth;
2690
+ ctx.lineWidth(1);
2648
2691
  ctx.moveTo(r.right, r.centerY);
2649
2692
  ctx.lineTo(r.centerX, r.bottom);
2650
2693
  ctx.moveTo(r.centerX, r.top);
@@ -2661,16 +2704,16 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2661
2704
  }
2662
2705
  }
2663
2706
  });
2664
- obj.dotRects.forEach((r) => renderer.fillCircle(r.centerX, r.centerY, r.width / 2));
2707
+ obj.dotRects.forEach((r) => ctx.fillCircle(r.centerX, r.centerY, r.width / 2));
2665
2708
  if (obj.stemTip && obj.stemBase) {
2666
2709
  ctx.beginPath();
2667
2710
  ctx.moveTo(obj.stemBase.centerX, obj.stemBase.centerY);
2668
2711
  ctx.lineTo(obj.stemTip.centerX, obj.stemTip.centerY);
2669
2712
  ctx.stroke();
2670
2713
  }
2671
- obj.flagRects.forEach((rect) => renderer.drawFlag(rect, stemDir === "up" /* Up */ ? "up" : "down"));
2714
+ obj.flagRects.forEach((rect) => ctx.drawFlag(rect, stemDir === "up" /* Up */ ? "up" : "down"));
2672
2715
  });
2673
- this.tabObjects.forEach((obj) => obj.fretNumbers.forEach((fn) => fn.draw(renderer)));
2716
+ this.tabObjects.forEach((obj) => obj.fretNumbers.forEach((fn) => fn.draw(ctx)));
2674
2717
  }
2675
2718
  getDotVerticalDisplacement(staff, diatonicId, stemDir) {
2676
2719
  if (staff.isLine(diatonicId)) {
@@ -2696,87 +2739,7 @@ var ObjNoteGroup = class _ObjNoteGroup extends MusicObject {
2696
2739
 
2697
2740
  // src/score/engine/obj-rhythm-column.ts
2698
2741
  import { MusicError as MusicError7, MusicErrorType as MusicErrorType7 } from "@tspro/web-music-score/core";
2699
-
2700
- // src/score/engine/obj-lyrics.ts
2701
- import { Utils as Utils4 } from "@tspro/ts-utils-lib";
2702
- var LyricsContainer = class {
2703
- constructor(col, lyricsLength) {
2704
- this.col = col;
2705
- __publicField(this, "lyricsObjects", []);
2706
- __publicField(this, "rhythmProps");
2707
- this.rhythmProps = RhythmProps.get(lyricsLength);
2708
- }
2709
- addLyricsObject(lyricsObj) {
2710
- var _a;
2711
- this.lyricsObjects.push(lyricsObj);
2712
- (_a = lyricsObj.measure.getPrevLyricsObject(lyricsObj)) == null ? void 0 : _a.setNextLyricsObject(lyricsObj);
2713
- }
2714
- };
2715
- var ObjLyrics = class extends MusicObject {
2716
- constructor(col, verse, line, vpos, lyricsText, lyricsOptions) {
2717
- super(col);
2718
- this.col = col;
2719
- this.verse = verse;
2720
- this.line = line;
2721
- this.vpos = vpos;
2722
- __publicField(this, "nextLyricsObject");
2723
- __publicField(this, "color", "black");
2724
- __publicField(this, "hyphen");
2725
- __publicField(this, "text");
2726
- __publicField(this, "mi");
2727
- let halign = (lyricsOptions == null ? void 0 : lyricsOptions.align) === "left" /* Left */ ? 0 : (lyricsOptions == null ? void 0 : lyricsOptions.align) === "right" /* Right */ ? 1 : 0.5;
2728
- this.hyphen = Utils4.Is.isEnumValue(lyricsOptions == null ? void 0 : lyricsOptions.hyphen, LyricsHyphen) ? lyricsOptions == null ? void 0 : lyricsOptions.hyphen : void 0;
2729
- this.text = new ObjText(this, { text: lyricsText, color: this.color, scale: 0.8 }, halign, 0);
2730
- this.rect = new DivRect();
2731
- this.mi = new MLyrics(this);
2732
- }
2733
- getMusicInterface() {
2734
- return this.mi;
2735
- }
2736
- get measure() {
2737
- return this.col.measure;
2738
- }
2739
- getText() {
2740
- return this.text.getText();
2741
- }
2742
- setNextLyricsObject(lyricsObj) {
2743
- this.nextLyricsObject = lyricsObj;
2744
- }
2745
- pick(x, y) {
2746
- return this.rect.contains(x, y) ? [this] : [];
2747
- }
2748
- layout(renderer) {
2749
- this.text.layout(renderer);
2750
- this.rect = this.text.getRect().copy();
2751
- }
2752
- offset(dx, dy) {
2753
- this.text.offset(dx, dy);
2754
- this.rect.offsetInPlace(dx, dy);
2755
- }
2756
- draw(renderer) {
2757
- var _a;
2758
- this.text.draw(renderer);
2759
- const ctx = renderer.getCanvasContext();
2760
- if (ctx && this.hyphen !== void 0) {
2761
- let l = this.getRect();
2762
- let r = (_a = this.nextLyricsObject) == null ? void 0 : _a.getRect();
2763
- let hyphenw = renderer.unitSize * 1.5;
2764
- let maxw = r ? (r.left - l.right) * 0.85 : hyphenw;
2765
- let w = this.hyphen === "-" /* Hyphen */ ? Math.min(hyphenw, maxw) : maxw;
2766
- if (w > 0) {
2767
- ctx.lineWidth = renderer.lineWidth;
2768
- ctx.strokeStyle = ctx.fillStyle = this.color;
2769
- let cx = r ? (r.left + l.right) / 2 : l.right + w / 0.85;
2770
- let cy = (l.top + l.bottom) / 2;
2771
- ctx.moveTo(cx - w / 2, cy);
2772
- ctx.lineTo(cx + w / 2, cy);
2773
- ctx.stroke();
2774
- }
2775
- }
2776
- }
2777
- };
2778
-
2779
- // src/score/engine/obj-rhythm-column.ts
2742
+ import { Map3 } from "@tspro/ts-utils-lib";
2780
2743
  var noteHeadDataCompareFunc = (a, b) => {
2781
2744
  let cmp = Note5.compareFunc(a.note, b.note);
2782
2745
  if (cmp === 0) {
@@ -2790,7 +2753,7 @@ var ObjRhythmColumn = class extends MusicObject {
2790
2753
  this.measure = measure;
2791
2754
  this.positionTicks = positionTicks;
2792
2755
  __publicField(this, "voiceSymbol", []);
2793
- __publicField(this, "lyricsContainerCache", /* @__PURE__ */ new Map());
2756
+ __publicField(this, "lyricsObject", new Map3());
2794
2757
  __publicField(this, "minDiatonicId");
2795
2758
  __publicField(this, "maxDiatonicId");
2796
2759
  __publicField(this, "staffMinDiatonicId", /* @__PURE__ */ new Map());
@@ -2900,8 +2863,11 @@ var ObjRhythmColumn = class extends MusicObject {
2900
2863
  validateVoiceId(voiceId);
2901
2864
  this.voiceSymbol[voiceId] = symbol;
2902
2865
  if (symbol instanceof ObjRest && !symbol.hide) {
2903
- this.minDiatonicId = this.minDiatonicId === void 0 ? symbol.ownDiatonicId : Math.min(this.minDiatonicId, symbol.ownDiatonicId);
2904
- this.maxDiatonicId = this.maxDiatonicId === void 0 ? symbol.ownDiatonicId : Math.max(this.maxDiatonicId, symbol.ownDiatonicId);
2866
+ this.row.getStaves().forEach((staff) => {
2867
+ let diatonicId = symbol.getDiatonicId(staff);
2868
+ this.minDiatonicId = this.minDiatonicId === void 0 ? diatonicId : Math.min(this.minDiatonicId, diatonicId);
2869
+ this.maxDiatonicId = this.maxDiatonicId === void 0 ? diatonicId : Math.max(this.maxDiatonicId, diatonicId);
2870
+ });
2905
2871
  } else if (symbol instanceof ObjNoteGroup) {
2906
2872
  this.minDiatonicId = this.minDiatonicId === void 0 ? symbol.notes[0].diatonicId : Math.min(this.minDiatonicId, symbol.notes[0].diatonicId);
2907
2873
  this.maxDiatonicId = this.maxDiatonicId === void 0 ? symbol.notes[symbol.notes.length - 1].diatonicId : Math.max(this.maxDiatonicId, symbol.notes[symbol.notes.length - 1].diatonicId);
@@ -2916,20 +2882,11 @@ var ObjRhythmColumn = class extends MusicObject {
2916
2882
  getVoiceSymbol(voiceId) {
2917
2883
  return this.voiceSymbol[voiceId];
2918
2884
  }
2919
- getLyricsContainer(verse, line, vpos, lyricsLength) {
2920
- let vposMap = this.lyricsContainerCache.get(line);
2921
- if (vposMap === void 0) {
2922
- this.lyricsContainerCache.set(line, vposMap = /* @__PURE__ */ new Map());
2923
- }
2924
- let verseMap = vposMap.get(vpos);
2925
- if (verseMap === void 0) {
2926
- vposMap.set(vpos, verseMap = /* @__PURE__ */ new Map());
2927
- }
2928
- let lyricsContainer = verseMap.get(verse);
2929
- if (lyricsContainer === void 0 && lyricsLength !== void 0) {
2930
- verseMap.set(verse, lyricsContainer = new LyricsContainer(this, validateNoteLength2(lyricsLength)));
2931
- }
2932
- return lyricsContainer;
2885
+ getLyricsObject(verse, line, vpos) {
2886
+ return this.lyricsObject.get(verse, line, vpos);
2887
+ }
2888
+ addLyricsObject(lyricsObj) {
2889
+ this.lyricsObject.set(lyricsObj.verse, lyricsObj.line, lyricsObj.vpos, lyricsObj);
2933
2890
  }
2934
2891
  getMinWidth() {
2935
2892
  let maxNoteSize = Math.max(...this.voiceSymbol.map((s) => s.rhythmProps.noteSize));
@@ -3040,19 +2997,19 @@ var ObjRhythmColumn = class extends MusicObject {
3040
2997
  this.measure.requestLayout();
3041
2998
  }
3042
2999
  }
3043
- layout(renderer, accState) {
3000
+ layout(ctx, accState) {
3044
3001
  if (!this.needLayout) {
3045
3002
  return;
3046
3003
  }
3047
3004
  this.requestRectUpdate();
3048
3005
  this.rect = new DivRect();
3049
3006
  let { row } = this;
3050
- let { unitSize } = renderer;
3007
+ let { unitSize } = ctx;
3051
3008
  let halfMinWidth = this.getMinWidth() * unitSize / 2;
3052
3009
  let leftw = halfMinWidth;
3053
3010
  let rightw = halfMinWidth;
3054
3011
  this.voiceSymbol.forEach((symbol) => {
3055
- symbol.layout(renderer, accState);
3012
+ symbol.layout(ctx, accState);
3056
3013
  let r = symbol.getRect();
3057
3014
  leftw = Math.max(leftw, r.leftw);
3058
3015
  rightw = Math.max(rightw, r.rightw);
@@ -3061,7 +3018,7 @@ var ObjRhythmColumn = class extends MusicObject {
3061
3018
  let arpeggioWidth = 0;
3062
3019
  this.arpeggios = row.getNotationLines().map((line) => {
3063
3020
  let arpeggio = new ObjArpeggio(this, line, this.getArpeggioDir());
3064
- arpeggio.layout(renderer);
3021
+ arpeggio.layout(ctx);
3065
3022
  arpeggio.offset(-leftw - arpeggio.getRect().right, line.getRect().centerY - arpeggio.getRect().centerY);
3066
3023
  arpeggioWidth = Math.max(arpeggioWidth, arpeggio.getRect().width);
3067
3024
  line.addObject(arpeggio);
@@ -3091,8 +3048,9 @@ var ObjRhythmColumn = class extends MusicObject {
3091
3048
  minDiatonicId = minDiatonicId === void 0 ? symbol.minDiatonicId : Math.min(minDiatonicId, symbol.minDiatonicId);
3092
3049
  maxDiatonicId = maxDiatonicId === void 0 ? symbol.maxDiatonicId : Math.max(maxDiatonicId, symbol.maxDiatonicId);
3093
3050
  } else if (symbol instanceof ObjRest) {
3094
- minDiatonicId = minDiatonicId === void 0 ? symbol.ownDiatonicId : Math.min(minDiatonicId, symbol.ownDiatonicId);
3095
- maxDiatonicId = maxDiatonicId === void 0 ? symbol.ownDiatonicId : Math.max(maxDiatonicId, symbol.ownDiatonicId);
3051
+ let diatonicId = symbol.getDiatonicId(staff);
3052
+ minDiatonicId = minDiatonicId === void 0 ? diatonicId : Math.min(minDiatonicId, diatonicId);
3053
+ maxDiatonicId = maxDiatonicId === void 0 ? diatonicId : Math.max(maxDiatonicId, diatonicId);
3096
3054
  }
3097
3055
  }
3098
3056
  });
@@ -3126,23 +3084,23 @@ var ObjRhythmColumn = class extends MusicObject {
3126
3084
  this.shapeRects.forEach((r) => r.offsetInPlace(dx, dy));
3127
3085
  this.rect.offsetInPlace(dx, dy);
3128
3086
  }
3129
- draw(renderer) {
3087
+ draw(ctx) {
3130
3088
  this.row.getStaves().forEach((staff) => {
3131
3089
  let minDiatonicId = this.staffMinDiatonicId.get(staff);
3132
3090
  let maxDiatonicId = this.staffMaxDiatonicId.get(staff);
3133
3091
  if (minDiatonicId !== void 0) {
3134
- renderer.drawLedgerLines(staff, minDiatonicId, this.getRect().centerX);
3092
+ ctx.drawLedgerLines(staff, minDiatonicId, this.getRect().centerX);
3135
3093
  }
3136
3094
  if (maxDiatonicId !== void 0) {
3137
- renderer.drawLedgerLines(staff, maxDiatonicId, this.getRect().centerX);
3095
+ ctx.drawLedgerLines(staff, maxDiatonicId, this.getRect().centerX);
3138
3096
  }
3139
3097
  });
3140
3098
  this.voiceSymbol.forEach((symbol) => {
3141
3099
  if (symbol) {
3142
- symbol.draw(renderer);
3100
+ symbol.draw(ctx);
3143
3101
  }
3144
3102
  });
3145
- this.arpeggios.forEach((arpeggio) => arpeggio.draw(renderer));
3103
+ this.arpeggios.forEach((arpeggio) => arpeggio.draw(ctx));
3146
3104
  }
3147
3105
  };
3148
3106
 
@@ -3150,7 +3108,7 @@ var ObjRhythmColumn = class extends MusicObject {
3150
3108
  import { MusicError as MusicError8, MusicErrorType as MusicErrorType8 } from "@tspro/web-music-score/core";
3151
3109
 
3152
3110
  // src/score/engine/element-data.ts
3153
- import { Utils as Utils5 } from "@tspro/ts-utils-lib";
3111
+ import { Utils as Utils4 } from "@tspro/ts-utils-lib";
3154
3112
 
3155
3113
  // src/score/engine/obj-special-text.ts
3156
3114
  var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
@@ -3190,13 +3148,13 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3190
3148
  pick(x, y) {
3191
3149
  return this.rect.contains(x, y) ? [this] : [];
3192
3150
  }
3193
- layout(renderer) {
3151
+ layout(ctx) {
3194
3152
  switch (this.text) {
3195
3153
  case _ObjSpecialText.Coda: {
3196
3154
  let codaSym = this.components[0];
3197
3155
  let codaText = this.components[1];
3198
- codaSym.layout(renderer);
3199
- codaText.layout(renderer);
3156
+ codaSym.layout(ctx);
3157
+ codaText.layout(ctx);
3200
3158
  codaSym.offset(0, (codaText.getRect().top + codaText.getRect().bottom) / 2);
3201
3159
  codaText.offset(codaSym.getRect().right, 0);
3202
3160
  this.rect = new DivRect(
@@ -3212,8 +3170,8 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3212
3170
  case _ObjSpecialText.toCoda: {
3213
3171
  let toCodaText = this.components[0];
3214
3172
  let codaSym = this.components[1];
3215
- toCodaText.layout(renderer);
3216
- codaSym.layout(renderer);
3173
+ toCodaText.layout(ctx);
3174
+ codaSym.layout(ctx);
3217
3175
  codaSym.offset(0, (toCodaText.getRect().top + toCodaText.getRect().bottom) / 2);
3218
3176
  toCodaText.offset(codaSym.getRect().left, 0);
3219
3177
  this.rect = new DivRect(
@@ -3228,7 +3186,7 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3228
3186
  }
3229
3187
  default: {
3230
3188
  let text = this.components[0];
3231
- text.layout(renderer);
3189
+ text.layout(ctx);
3232
3190
  this.rect = text.getRect().copy();
3233
3191
  break;
3234
3192
  }
@@ -3238,9 +3196,9 @@ var _ObjSpecialText = class _ObjSpecialText extends MusicObject {
3238
3196
  this.components.forEach((c) => c.offset(dx, dy));
3239
3197
  this.rect.offsetInPlace(dx, dy);
3240
3198
  }
3241
- draw(renderer) {
3242
- renderer.drawDebugRect(this.rect);
3243
- this.components.forEach((c) => c.draw(renderer));
3199
+ draw(ctx) {
3200
+ ctx.drawDebugRect(this.rect);
3201
+ this.components.forEach((c) => c.draw(ctx));
3244
3202
  }
3245
3203
  };
3246
3204
  __publicField(_ObjSpecialText, "toCoda", "\u{1D10C} toCoda");
@@ -3272,23 +3230,23 @@ function getNavigationString(navigation) {
3272
3230
  }
3273
3231
  }
3274
3232
  function isDynamicsText(text) {
3275
- return Utils5.Is.isEnumValue(text, DynamicsAnnotation);
3233
+ return Utils4.Is.isEnumValue(text, DynamicsAnnotation);
3276
3234
  }
3277
3235
  function getDynamicsVolume(text) {
3278
3236
  if (/^(p+|f+|m|mp|mf)$/.test(text)) {
3279
- let volume = 0.5 - Utils5.Str.charCount(text, "p") * 0.1 + Utils5.Str.charCount(text, "f") * 0.1;
3280
- return Utils5.Math.clamp(volume, 0, 1);
3237
+ let volume = 0.5 - Utils4.Str.charCount(text, "p") * 0.1 + Utils4.Str.charCount(text, "f") * 0.1;
3238
+ return Utils4.Math.clamp(volume, 0, 1);
3281
3239
  } else {
3282
3240
  return void 0;
3283
3241
  }
3284
3242
  }
3285
3243
  function isTempoText(text) {
3286
- return Utils5.Is.isEnumValue(text, TempoAnnotation);
3244
+ return Utils4.Is.isEnumValue(text, TempoAnnotation);
3287
3245
  }
3288
3246
  function getAnnotation(text) {
3289
- if (Utils5.Is.isEnumValue(text, DynamicsAnnotation)) {
3247
+ if (Utils4.Is.isEnumValue(text, DynamicsAnnotation)) {
3290
3248
  return "dynamics" /* Dynamics */;
3291
- } else if (Utils5.Is.isEnumValue(text, TempoAnnotation)) {
3249
+ } else if (Utils4.Is.isEnumValue(text, TempoAnnotation)) {
3292
3250
  return "tempo" /* Tempo */;
3293
3251
  } else {
3294
3252
  return void 0;
@@ -3444,7 +3402,7 @@ var PlayerColumnProps = class {
3444
3402
  return this.speed;
3445
3403
  }
3446
3404
  getTempo() {
3447
- let speed = Utils6.Math.clamp(this.getSpeed(), 0.1, 10);
3405
+ let speed = Utils5.Math.clamp(this.getSpeed(), 0.1, 10);
3448
3406
  return alterTempoSpeed(this.measure.getTempo(), speed);
3449
3407
  }
3450
3408
  setVolume(volume) {
@@ -3469,7 +3427,7 @@ var PlayerColumnProps = class {
3469
3427
  if (symbolsTicks.length === 0) {
3470
3428
  return 0;
3471
3429
  } else {
3472
- return Utils6.Math.sum(symbolsTicks) / symbolsTicks.length;
3430
+ return Utils5.Math.sum(symbolsTicks) / symbolsTicks.length;
3473
3431
  }
3474
3432
  }
3475
3433
  }
@@ -3618,7 +3576,7 @@ var Player = class _Player {
3618
3576
  } else if (layoutObj.musicObj.getLink() instanceof Extension) {
3619
3577
  let extension = layoutObj.musicObj.getLink();
3620
3578
  let { columnRange, extensionBreakText } = extension.getExtensionRangeInfo();
3621
- let totalTicks = Utils6.Math.sum(columnRange.map((c) => c.getTicksToNextColumn()));
3579
+ let totalTicks = Utils5.Math.sum(columnRange.map((c) => c.getTicksToNextColumn()));
3622
3580
  switch (text) {
3623
3581
  case "accel." /* accel */: {
3624
3582
  let startSpeed = curSpeed;
@@ -3672,11 +3630,11 @@ var Player = class _Player {
3672
3630
  });
3673
3631
  let speedArr = (_a = speedMap.get(col)) != null ? _a : [];
3674
3632
  if (speedArr.length > 0) {
3675
- curSpeed = Utils6.Math.sum(speedArr) / speedArr.length;
3633
+ curSpeed = Utils5.Math.sum(speedArr) / speedArr.length;
3676
3634
  }
3677
3635
  let volumeArr = (_b = volumeMap.get(col)) != null ? _b : [];
3678
3636
  if (volumeArr.length > 0) {
3679
- curVolume = Utils6.Math.sum(volumeArr) / volumeArr.length;
3637
+ curVolume = Utils5.Math.sum(volumeArr) / volumeArr.length;
3680
3638
  }
3681
3639
  col.getPlayerProps().setSpeed(curSpeed);
3682
3640
  col.getPlayerProps().setVolume(curVolume);
@@ -3718,11 +3676,11 @@ var Player = class _Player {
3718
3676
  } else {
3719
3677
  let playerNotes = col.getPlayerNotes();
3720
3678
  playerNotes.forEach((note, i) => {
3721
- let arpeggioDelayTicks = col.hasArpeggio() ? RhythmProps4.get(NoteLength6.ThirtySecond).ticks * i : 0;
3679
+ let arpeggioDelayTicks = col.hasArpeggio() ? RhythmProps4.get(NoteLength4.ThirtySecond).ticks * i : 0;
3722
3680
  let noteSeconds = getDuration(note.ticks + fermataHoldTicks - arpeggioDelayTicks, tempo);
3723
3681
  if (noteSeconds > 0) {
3724
3682
  if (note.staccato) {
3725
- noteSeconds = Math.min(getDuration(RhythmProps4.get(NoteLength6.Eighth).ticks, tempo) / 2, noteSeconds / 2);
3683
+ noteSeconds = Math.min(getDuration(RhythmProps4.get(NoteLength4.Eighth).ticks, tempo) / 2, noteSeconds / 2);
3726
3684
  }
3727
3685
  let volume = adjustVolume(col.getPlayerProps().getVolume());
3728
3686
  if (note.slur === "slurred") {
@@ -3807,8 +3765,8 @@ var ObjStaffTabBarLine = class extends MusicObject {
3807
3765
  super(line);
3808
3766
  this.barLine = barLine;
3809
3767
  this.line = line;
3810
- __publicField(this, "lineRects", []);
3811
- __publicField(this, "dotRects", []);
3768
+ __publicField(this, "verticalLines", []);
3769
+ __publicField(this, "dots", []);
3812
3770
  __publicField(this, "mi");
3813
3771
  line.addObject(this);
3814
3772
  this.mi = new MStaffTabBarLine(this);
@@ -3823,8 +3781,11 @@ var ObjStaffTabBarLine = class extends MusicObject {
3823
3781
  this.rect = r;
3824
3782
  }
3825
3783
  offset(dx, dy) {
3826
- this.lineRects.forEach((r) => r.offsetInPlace(dx, dy));
3827
- this.dotRects.forEach((r) => r.offsetInPlace(dx, dy));
3784
+ this.verticalLines.forEach((l) => l.left += dx);
3785
+ this.dots.forEach((d) => {
3786
+ d.x += dx;
3787
+ d.y += dy;
3788
+ });
3828
3789
  this.rect.offsetInPlace(dx, dy);
3829
3790
  }
3830
3791
  };
@@ -3833,6 +3794,7 @@ var ObjBarLine = class extends MusicObject {
3833
3794
  super(measure);
3834
3795
  this.measure = measure;
3835
3796
  __publicField(this, "staffTabObjects", []);
3797
+ __publicField(this, "staffTabObjectGroups", []);
3836
3798
  __publicField(this, "barLineType", 0 /* None */);
3837
3799
  }
3838
3800
  pick(x, y) {
@@ -3847,14 +3809,14 @@ var ObjBarLine = class extends MusicObject {
3847
3809
  }
3848
3810
  return [this];
3849
3811
  }
3850
- layout(renderer) {
3812
+ layout(ctx) {
3851
3813
  this.requestRectUpdate();
3852
3814
  this.staffTabObjects.length = 0;
3853
3815
  this.barLineType = this.solveBarLineType();
3854
- let { unitSize, lineWidth } = renderer;
3816
+ let { unitSize, _lineWidth } = ctx;
3855
3817
  let { measure, barLineType } = this;
3856
3818
  let { row } = measure;
3857
- let thinW = lineWidth;
3819
+ let thinW = _lineWidth;
3858
3820
  let thicW = 0.7 * unitSize;
3859
3821
  let spaceW = 0.7 * unitSize;
3860
3822
  let dotW = DocumentSettings.DotSize * unitSize;
@@ -3864,13 +3826,13 @@ var ObjBarLine = class extends MusicObject {
3864
3826
  let lineCenterY;
3865
3827
  let lineDotOff;
3866
3828
  let top, bottom;
3867
- const addRect = (left, width) => {
3868
- obj.lineRects.push(new DivRect(left, left + width / 2, left + width, top, 0, bottom));
3829
+ const addVerticalLine = (left, width) => {
3830
+ obj.verticalLines.push({ left, width });
3869
3831
  };
3870
- const addDots = (cx) => {
3832
+ const addDotPair = (cx) => {
3871
3833
  for (let i = -1; i <= 1; i += 2) {
3872
3834
  let y = lineCenterY + i * lineDotOff;
3873
- obj.dotRects.push(new DivRect(cx - dotRadius, cx, cx + dotRadius, y - dotRadius, y, y + dotRadius));
3835
+ obj.dots.push({ x: cx, y, r: dotRadius });
3874
3836
  }
3875
3837
  };
3876
3838
  if (line instanceof ObjStaff) {
@@ -3888,41 +3850,44 @@ var ObjBarLine = class extends MusicObject {
3888
3850
  break;
3889
3851
  case 1 /* Single */:
3890
3852
  obj.setRect(new DivRect(-thinW, 0, 0, top, 0, bottom));
3891
- addRect(-thinW, thinW);
3853
+ addVerticalLine(-thinW, thinW);
3892
3854
  break;
3893
3855
  case 2 /* Double */:
3894
3856
  obj.setRect(new DivRect(-thinW - spaceW - thinW, 0, 0, top, 0, bottom));
3895
- addRect(-thinW - spaceW - thinW, thinW);
3896
- addRect(-thinW, thinW);
3857
+ addVerticalLine(-thinW - spaceW - thinW, thinW);
3858
+ addVerticalLine(-thinW, thinW);
3897
3859
  break;
3898
3860
  case 3 /* EndSong */:
3899
3861
  obj.setRect(new DivRect(-thicW - spaceW - thinW, 0, 0, top, 0, bottom));
3900
- addRect(-thinW - spaceW - thicW, thinW);
3901
- addRect(-thicW, thicW);
3862
+ addVerticalLine(-thinW - spaceW - thicW, thinW);
3863
+ addVerticalLine(-thicW, thicW);
3902
3864
  break;
3903
3865
  case 4 /* StartRepeat */:
3904
3866
  obj.setRect(new DivRect(0, 0, thicW + spaceW + thinW + spaceW + dotW, top, 0, bottom));
3905
- addRect(0, thicW);
3906
- addRect(thicW + spaceW, thinW);
3907
- addDots(thicW + spaceW + thinW + spaceW + dotRadius);
3867
+ addVerticalLine(0, thicW);
3868
+ addVerticalLine(thicW + spaceW, thinW);
3869
+ addDotPair(thicW + spaceW + thinW + spaceW + dotRadius);
3908
3870
  break;
3909
3871
  case 5 /* EndRepeat */:
3910
3872
  obj.setRect(new DivRect(-thicW - spaceW - thinW - spaceW - dotW, 0, 0, top, 0, bottom));
3911
- addRect(-thinW - spaceW - thicW, thinW);
3912
- addRect(-thicW, thicW);
3913
- addDots(-thinW - spaceW - thicW - spaceW - dotRadius);
3873
+ addVerticalLine(-thinW - spaceW - thicW, thinW);
3874
+ addVerticalLine(-thicW, thicW);
3875
+ addDotPair(-thinW - spaceW - thicW - spaceW - dotRadius);
3914
3876
  break;
3915
3877
  case 6 /* EndStartRepeat */:
3916
3878
  obj.setRect(new DivRect(-dotW - spaceW - thinW - spaceW - thicW / 2, 0, thicW / 2 + spaceW + thinW + spaceW + dotW, top, 0, bottom));
3917
- addRect(-thicW / 2, thicW);
3918
- addRect(-thicW / 2 - spaceW - thinW, thinW);
3919
- addRect(thicW / 2 + spaceW, thinW);
3920
- addDots(-thicW / 2 - spaceW - thinW - spaceW - dotRadius);
3921
- addDots(thicW / 2 + spaceW + thinW + spaceW + dotRadius);
3879
+ addVerticalLine(-thicW / 2, thicW);
3880
+ addVerticalLine(-thicW / 2 - spaceW - thinW, thinW);
3881
+ addVerticalLine(thicW / 2 + spaceW, thinW);
3882
+ addDotPair(-thicW / 2 - spaceW - thinW - spaceW - dotRadius);
3883
+ addDotPair(thicW / 2 + spaceW + thinW + spaceW + dotRadius);
3922
3884
  break;
3923
3885
  }
3924
3886
  this.staffTabObjects.push(obj);
3925
3887
  });
3888
+ this.staffTabObjectGroups = row.getInstrumentLineGroups().map(
3889
+ (lines) => lines.map((line) => this.staffTabObjects.find((obj) => obj.line === line)).filter((obj) => obj !== void 0)
3890
+ );
3926
3891
  }
3927
3892
  updateRect() {
3928
3893
  if (this.staffTabObjects.length > 0) {
@@ -3938,16 +3903,19 @@ var ObjBarLine = class extends MusicObject {
3938
3903
  this.staffTabObjects.forEach((obj) => obj.offset(dx, 0));
3939
3904
  this.requestRectUpdate();
3940
3905
  }
3941
- draw(renderer) {
3942
- const ctx = renderer.getCanvasContext();
3943
- if (!ctx || this.barLineType === 0 /* None */) {
3906
+ draw(ctx) {
3907
+ if (this.barLineType === 0 /* None */) {
3944
3908
  return;
3945
3909
  }
3946
- renderer.drawDebugRect(this.getRect());
3947
- ctx.strokeStyle = ctx.fillStyle = "black";
3948
- this.staffTabObjects.forEach((obj) => {
3949
- obj.lineRects.forEach((r) => ctx.fillRect(r.left, r.top, r.width, r.height));
3950
- obj.dotRects.forEach((r) => renderer.fillCircle(r.centerX, r.centerY, r.width / 2));
3910
+ ctx.drawDebugRect(this.getRect());
3911
+ ctx.color("black");
3912
+ this.staffTabObjectGroups.forEach((objs) => {
3913
+ if (objs.length > 0) {
3914
+ objs.forEach((obj) => obj.dots.forEach((d) => ctx.fillCircle(d.x, d.y, d.r)));
3915
+ let top = objs[0].getRect().top;
3916
+ let height = objs[objs.length - 1].getRect().bottom - top;
3917
+ objs[0].verticalLines.forEach((vline) => ctx.fillRect(vline.left, top, vline.width, height));
3918
+ }
3951
3919
  });
3952
3920
  }
3953
3921
  };
@@ -4013,7 +3981,7 @@ var ObjBarLineRight = class extends ObjBarLine {
4013
3981
  };
4014
3982
 
4015
3983
  // src/score/engine/obj-ending.ts
4016
- import { Utils as Utils7 } from "@tspro/ts-utils-lib";
3984
+ import { Utils as Utils6 } from "@tspro/ts-utils-lib";
4017
3985
  import { MusicError as MusicError9, MusicErrorType as MusicErrorType9 } from "@tspro/web-music-score/core";
4018
3986
  var ObjEnding = class extends MusicObject {
4019
3987
  constructor(measure, passages) {
@@ -4024,9 +3992,9 @@ var ObjEnding = class extends MusicObject {
4024
3992
  __publicField(this, "shapeRects", []);
4025
3993
  __publicField(this, "mi");
4026
3994
  this.mi = new MEnding(this);
4027
- if (!Utils7.Is.isIntegerGte(passages.length, 1)) {
3995
+ if (!Utils6.Is.isIntegerGte(passages.length, 1)) {
4028
3996
  throw new MusicError9(MusicErrorType9.Score, "Passages is empty.");
4029
- } else if (!this.passages.every((p) => Utils7.Is.isIntegerGte(p, 1))) {
3997
+ } else if (!this.passages.every((p) => Utils6.Is.isIntegerGte(p, 1))) {
4030
3998
  throw new MusicError9(MusicErrorType9.Score, "Invalid passages: " + this.passages);
4031
3999
  }
4032
4000
  this.passages.sort((a, b) => a - b);
@@ -4053,14 +4021,14 @@ var ObjEnding = class extends MusicObject {
4053
4021
  pick(x, y) {
4054
4022
  return this.rect.contains(x, y) ? [this] : [];
4055
4023
  }
4056
- layout(renderer) {
4024
+ layout(ctx) {
4057
4025
  this.rect = new DivRect();
4058
4026
  this.shapeRects = [this.rect.copy()];
4059
4027
  }
4060
- layoutFitToMeasure(renderer) {
4061
- let { unitSize } = renderer;
4028
+ layoutFitToMeasure(ctx) {
4029
+ let { unitSize } = ctx;
4062
4030
  let { measure } = this;
4063
- this.endingText.layout(renderer);
4031
+ this.endingText.layout(ctx);
4064
4032
  let textRect = this.endingText.getRect();
4065
4033
  let measureContent = measure.getColumnsContentRect();
4066
4034
  let endingHeight = textRect.height;
@@ -4078,16 +4046,10 @@ var ObjEnding = class extends MusicObject {
4078
4046
  this.shapeRects.forEach((r) => r.offsetInPlace(dx, dy));
4079
4047
  this.rect.offsetInPlace(dx, dy);
4080
4048
  }
4081
- draw(renderer) {
4082
- let ctx = renderer.getCanvasContext();
4083
- if (!ctx) {
4084
- return;
4085
- }
4086
- let { lineWidth } = renderer;
4049
+ draw(ctx) {
4087
4050
  let { rect } = this;
4088
- renderer.drawDebugRect(this.rect);
4089
- ctx.strokeStyle = ctx.fillStyle = "black";
4090
- ctx.lineWidth = lineWidth;
4051
+ ctx.drawDebugRect(this.rect);
4052
+ ctx.color("black").lineWidth(1);
4091
4053
  ctx.beginPath();
4092
4054
  ctx.moveTo(rect.left, rect.bottom);
4093
4055
  ctx.lineTo(rect.left, rect.top);
@@ -4096,13 +4058,13 @@ var ObjEnding = class extends MusicObject {
4096
4058
  ctx.lineTo(rect.right, rect.bottom);
4097
4059
  }
4098
4060
  ctx.stroke();
4099
- this.endingText.draw(renderer);
4061
+ this.endingText.draw(ctx);
4100
4062
  }
4101
4063
  };
4102
4064
 
4103
4065
  // src/score/engine/obj-beam-group.ts
4104
- import { Utils as Utils8 } from "@tspro/ts-utils-lib";
4105
- import { NoteLength as NoteLength7, Tuplet as Tuplet3, NoteLengthProps as NoteLengthProps4 } from "@tspro/web-music-score/theory";
4066
+ import { Utils as Utils7 } from "@tspro/ts-utils-lib";
4067
+ import { NoteLength as NoteLength5, Tuplet as Tuplet3, NoteLengthProps as NoteLengthProps4 } from "@tspro/web-music-score/theory";
4106
4068
  import { MusicError as MusicError10, MusicErrorType as MusicErrorType10 } from "@tspro/web-music-score/core";
4107
4069
  var adjustBeamAngle = (dx, dy) => {
4108
4070
  let T = DocumentSettings.BeamAngleFactor;
@@ -4197,7 +4159,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4197
4159
  if (symbols.length >= 3 && symbols[0] instanceof ObjNoteGroup && symbols[symbols.length - 1] instanceof ObjNoteGroup && symbols[0].rhythmProps.flagCount === symbols[symbols.length - 1].rhythmProps.flagCount) {
4198
4160
  isGroup = false;
4199
4161
  }
4200
- if (symbols.some((s) => NoteLengthProps4.cmp(s.rhythmProps.noteLength, NoteLength7.Quarter) >= 0)) {
4162
+ if (symbols.some((s) => NoteLengthProps4.cmp(s.rhythmProps.noteLength, NoteLength5.Quarter) >= 0)) {
4201
4163
  isGroup = true;
4202
4164
  }
4203
4165
  this.type = isGroup ? 2 /* TupletGroup */ : 1 /* TupletBeam */;
@@ -4229,9 +4191,9 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4229
4191
  }
4230
4192
  }
4231
4193
  symbols[0].row.getStaves().forEach((staff) => {
4232
- if (staff.getActualStaff(symbols[0].ownDiatonicId) && staff.containsVoiceId(symbols[0].voiceId)) {
4194
+ if (staff.getActualStaff(symbols[0].getDiatonicId(staff)) && staff.containsVoiceId(symbols[0].voiceId)) {
4233
4195
  symbols.forEach((sym) => {
4234
- let actualStaff = staff.getActualStaff(sym.ownDiatonicId);
4196
+ let actualStaff = staff.getActualStaff(sym.getDiatonicId(staff));
4235
4197
  if (!actualStaff || !actualStaff.containsVoiceId(sym.voiceId)) {
4236
4198
  throw new InvalidBeamGroup(this, "Some of beam or tuplet symbols are not visible!");
4237
4199
  }
@@ -4239,6 +4201,9 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4239
4201
  }
4240
4202
  });
4241
4203
  }
4204
+ get stemDir() {
4205
+ return this.symbols[0].stemDir;
4206
+ }
4242
4207
  get showTupletRatio() {
4243
4208
  var _a;
4244
4209
  return ((_a = this.tupletRatio) == null ? void 0 : _a.showRatio) === true;
@@ -4334,20 +4299,17 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4334
4299
  getLastSymbol() {
4335
4300
  return this.symbols[this.symbols.length - 1];
4336
4301
  }
4337
- get stemDir() {
4338
- return this.symbols[0].ownStemDir;
4339
- }
4340
4302
  get color() {
4341
4303
  return this.symbols[0].color;
4342
4304
  }
4343
- layout(renderer) {
4305
+ layout(ctx) {
4344
4306
  this.requestRectUpdate();
4345
4307
  this.staffObjects.length = 0;
4346
4308
  let symbols = this.getSymbols();
4347
4309
  if (symbols.length === 0) {
4348
4310
  return;
4349
4311
  }
4350
- let { unitSize } = renderer;
4312
+ let { unitSize } = ctx;
4351
4313
  let { stemDir, type } = this;
4352
4314
  let symbolsBeamCoords = symbols.map((s) => s.getBeamCoords());
4353
4315
  symbolsBeamCoords[0].map((s) => s == null ? void 0 : s.staff).forEach((mainStaff, index) => {
@@ -4409,7 +4371,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4409
4371
  symbolY.forEach((symY, i) => {
4410
4372
  let symX = symbolX[i];
4411
4373
  if (symX !== void 0 && symY !== void 0) {
4412
- let beamY = Utils8.Math.interpolateY(leftX, leftY, rightX, rightY, symX);
4374
+ let beamY = Utils7.Math.interpolateY(leftX, leftY, rightX, rightY, symX);
4413
4375
  let raiseY = symY - beamY;
4414
4376
  if (stemDir === "up" /* Up */ && raiseY < 0) {
4415
4377
  raiseBeamY = Math.min(raiseBeamY, raiseY);
@@ -4424,14 +4386,14 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4424
4386
  let obj = new ObjStaffBeamGroup(mainStaff, this);
4425
4387
  if (type === 2 /* TupletGroup */) {
4426
4388
  let ef = unitSize / (rightX - leftX);
4427
- let l = Utils8.Math.interpolateCoord(leftX, leftY + groupLineDy, rightX, rightY + groupLineDy, -ef);
4428
- let r = Utils8.Math.interpolateCoord(leftX, leftY + groupLineDy, rightX, rightY + groupLineDy, 1 + ef);
4389
+ let l = Utils7.Math.interpolateCoord(leftX, leftY + groupLineDy, rightX, rightY + groupLineDy, -ef);
4390
+ let r = Utils7.Math.interpolateCoord(leftX, leftY + groupLineDy, rightX, rightY + groupLineDy, 1 + ef);
4429
4391
  obj.points.push(new BeamPoint(leftStaff, this, leftSymbol, l.x, l.y));
4430
4392
  obj.points.push(new BeamPoint(rightStaff, this, rightSymbol, r.x, r.y));
4431
4393
  obj.tupletNumberOffsetY = 0;
4432
4394
  } else if (type === 0 /* RegularBeam */ || type === 1 /* TupletBeam */) {
4433
4395
  raiseBeamY *= 0.5;
4434
- let { beamThickness } = renderer;
4396
+ let beamThickness = ctx._lineWidth * DocumentSettings.BeamThickness;
4435
4397
  const beamHeight = (i) => {
4436
4398
  let sym = symbols[i];
4437
4399
  if (sym instanceof ObjNoteGroup) {
@@ -4464,7 +4426,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4464
4426
  }
4465
4427
  if (this.isTuplet()) {
4466
4428
  obj.tupletNumber = new ObjText(this, this.getTupletRatioText(), 0.5, 0.5);
4467
- obj.tupletNumber.layout(renderer);
4429
+ obj.tupletNumber.layout(ctx);
4468
4430
  obj.tupletNumber.offset((leftX + rightX) / 2, (leftY + rightY) / 2 + obj.tupletNumberOffsetY);
4469
4431
  }
4470
4432
  if (obj.points.length >= 2) {
@@ -4491,7 +4453,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4491
4453
  obj.points.forEach((pt) => {
4492
4454
  if (pt.symbol instanceof ObjNoteGroup) {
4493
4455
  if (pt !== left && pt !== right) {
4494
- pt.y = Utils8.Math.interpolateY(left.x, left.y, right.x, right.y, pt.x);
4456
+ pt.y = Utils7.Math.interpolateY(left.x, left.y, right.x, right.y, pt.x);
4495
4457
  }
4496
4458
  pt.symbol.setStemTipY(pt.staff, pt.y);
4497
4459
  }
@@ -4507,27 +4469,29 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4507
4469
  this.staffObjects.forEach((obj) => obj.offset(dx, 0));
4508
4470
  this.requestRectUpdate();
4509
4471
  }
4510
- draw(renderer) {
4511
- let { unitSize, beamThickness, lineWidth } = renderer;
4472
+ draw(ctx) {
4473
+ let { unitSize } = ctx;
4512
4474
  let { stemDir, color, type } = this;
4513
4475
  if (type === 2 /* TupletGroup */) {
4476
+ ctx.color(color).lineWidth(1);
4514
4477
  let tipHeight = (stemDir === "up" /* Up */ ? 1 : -1) * unitSize;
4515
4478
  this.staffObjects.forEach((obj) => {
4516
4479
  let { x: lx, y: ly } = obj.points[0];
4517
4480
  let { x: rx, y: ry } = obj.points[obj.points.length - 1];
4518
4481
  if (obj.tupletNumber) {
4519
4482
  let tf = obj.tupletNumber.getRect().width / (rx - lx) * 1.2;
4520
- let lc = Utils8.Math.interpolateCoord(lx, ly, rx, ry, 0.5 - tf / 2);
4521
- let rc = Utils8.Math.interpolateCoord(lx, ly, rx, ry, 0.5 + tf / 2);
4522
- renderer.drawLine(lx, ly, lc.x, lc.y, color, lineWidth);
4523
- renderer.drawLine(rc.x, rc.y, rx, ry, color, lineWidth);
4483
+ let lc = Utils7.Math.interpolateCoord(lx, ly, rx, ry, 0.5 - tf / 2);
4484
+ let rc = Utils7.Math.interpolateCoord(lx, ly, rx, ry, 0.5 + tf / 2);
4485
+ ctx.strokeLine(lx, ly, lc.x, lc.y);
4486
+ ctx.strokeLine(rc.x, rc.y, rx, ry);
4524
4487
  } else {
4525
- renderer.drawLine(lx, ly, rx, ry, color, lineWidth);
4488
+ ctx.strokeLine(lx, ly, rx, ry);
4526
4489
  }
4527
- renderer.drawLine(lx, ly, lx, ly + tipHeight, color, lineWidth);
4528
- renderer.drawLine(rx, ry, rx, ry + tipHeight, color, lineWidth);
4490
+ ctx.strokeLine(lx, ly, lx, ly + tipHeight);
4491
+ ctx.strokeLine(rx, ry, rx, ry + tipHeight);
4529
4492
  });
4530
4493
  } else if (type === 0 /* RegularBeam */ || type === 1 /* TupletBeam */) {
4494
+ ctx.color(color).lineWidth(DocumentSettings.BeamThickness);
4531
4495
  this.staffObjects.forEach((obj) => {
4532
4496
  let noteGroupPoints = obj.points.filter((p) => p.symbol instanceof ObjNoteGroup);
4533
4497
  let { x: lx, y: ly } = noteGroupPoints[0];
@@ -4540,11 +4504,11 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4540
4504
  let rightBeamCount = rsymbol.getLeftBeamCount();
4541
4505
  for (let beamId = 0; beamId < Math.max(leftBeamCount, rightBeamCount); beamId++) {
4542
4506
  if (beamId < leftBeamCount && beamId < rightBeamCount) {
4543
- renderer.drawLine(lx2, ly2, rx2, ry2, color, beamThickness);
4507
+ ctx.strokeLine(lx2, ly2, rx2, ry2);
4544
4508
  } else if (leftBeamCount > rightBeamCount) {
4545
- renderer.drawPartialLine(lx2, ly2, rx2, ry2, 0, 0.25, color, beamThickness);
4509
+ ctx.strokePartialLine(lx2, ly2, rx2, ry2, 0, 0.25);
4546
4510
  } else if (rightBeamCount > leftBeamCount) {
4547
- renderer.drawPartialLine(lx2, ly2, rx2, ry2, 0.75, 1, color, beamThickness);
4511
+ ctx.strokePartialLine(lx2, ly2, rx2, ry2, 0.75, 1);
4548
4512
  }
4549
4513
  ly2 += beamSeparation;
4550
4514
  ry2 += beamSeparation;
@@ -4554,7 +4518,7 @@ var ObjBeamGroup = class _ObjBeamGroup extends MusicObject {
4554
4518
  }
4555
4519
  this.staffObjects.forEach((obj) => {
4556
4520
  var _a;
4557
- return (_a = obj.tupletNumber) == null ? void 0 : _a.draw(renderer);
4521
+ return (_a = obj.tupletNumber) == null ? void 0 : _a.draw(ctx);
4558
4522
  });
4559
4523
  }
4560
4524
  setBeamCounts() {
@@ -4654,8 +4618,8 @@ var ObjFermata = class extends MusicObject {
4654
4618
  pick(x, y) {
4655
4619
  return this.rect.contains(x, y) ? [this] : [];
4656
4620
  }
4657
- layout(renderer) {
4658
- let { unitSize } = renderer;
4621
+ layout(ctx) {
4622
+ let { unitSize } = ctx;
4659
4623
  let width = unitSize * 4;
4660
4624
  let height = unitSize * 3;
4661
4625
  this.rect = new DivRect(-width / 2, width / 2, -height, 0);
@@ -4663,12 +4627,8 @@ var ObjFermata = class extends MusicObject {
4663
4627
  offset(dx, dy) {
4664
4628
  this.rect.offsetInPlace(dx, dy);
4665
4629
  }
4666
- draw(renderer) {
4667
- let ctx = renderer.getCanvasContext();
4668
- if (!ctx) {
4669
- return;
4670
- }
4671
- let { lineWidth, unitSize } = renderer;
4630
+ draw(ctx) {
4631
+ let { unitSize } = ctx;
4672
4632
  let upsideDown = this.pos === 1 /* Below */;
4673
4633
  let dy = (upsideDown ? unitSize : -unitSize) * 0.7;
4674
4634
  let left = this.rect.left;
@@ -4676,9 +4636,8 @@ var ObjFermata = class extends MusicObject {
4676
4636
  let top = (upsideDown ? this.rect.bottom : this.rect.top) + dy;
4677
4637
  let bottom = (upsideDown ? this.rect.top : this.rect.bottom) + dy;
4678
4638
  let height = bottom - top;
4679
- renderer.drawDebugRect(this.rect);
4680
- ctx.strokeStyle = ctx.fillStyle = this.color;
4681
- ctx.lineWidth = lineWidth;
4639
+ ctx.drawDebugRect(this.rect);
4640
+ ctx.color("black").lineWidth(1);
4682
4641
  ctx.beginPath();
4683
4642
  ctx.moveTo(left, bottom);
4684
4643
  ctx.bezierCurveTo(left, top, right, top, right, bottom);
@@ -4686,7 +4645,7 @@ var ObjFermata = class extends MusicObject {
4686
4645
  ctx.stroke();
4687
4646
  ctx.fill();
4688
4647
  let r = height / 6;
4689
- renderer.fillCircle((left + right) / 2, bottom - r, Math.abs(r));
4648
+ ctx.fillCircle((left + right) / 2, bottom - r, Math.abs(r));
4690
4649
  }
4691
4650
  };
4692
4651
 
@@ -4729,8 +4688,8 @@ var ObjExtensionLine = class extends MusicObject {
4729
4688
  return this.rightObj.getRect().centerX;
4730
4689
  }
4731
4690
  }
4732
- layoutFitToMeasure(renderer) {
4733
- let { unitSize } = renderer;
4691
+ layoutFitToMeasure(ctx) {
4692
+ let { unitSize } = ctx;
4734
4693
  let lineLeft = this.getLineLeft();
4735
4694
  let lineRight = this.getLineRight();
4736
4695
  let lineRectH = unitSize;
@@ -4739,27 +4698,24 @@ var ObjExtensionLine = class extends MusicObject {
4739
4698
  pick(x, y) {
4740
4699
  return this.rect.contains(x, y) ? [this] : [];
4741
4700
  }
4742
- layout(renderer) {
4701
+ layout(ctx) {
4743
4702
  this.rect = new DivRect();
4744
4703
  }
4745
4704
  offset(dx, dy) {
4746
4705
  this.rect.offsetInPlace(dx, dy);
4747
4706
  }
4748
- draw(renderer) {
4749
- let ctx = renderer.getCanvasContext();
4750
- if (!ctx) {
4751
- return;
4752
- }
4707
+ draw(ctx) {
4753
4708
  let { rect } = this;
4754
4709
  if (this.extension.getLineStyle() === "dashed") {
4755
4710
  ctx.setLineDash([7, 3]);
4756
4711
  }
4757
- renderer.drawLine(rect.left, rect.centerY, rect.right, rect.centerY, "black", renderer.lineWidth);
4712
+ ctx.color("black").lineWidth(1);
4713
+ ctx.strokeLine(rect.left, rect.centerY, rect.right, rect.centerY);
4758
4714
  ctx.setLineDash([]);
4759
4715
  let tails = this.extension.getTails();
4760
4716
  if (tails.length > 0 && this === tails[tails.length - 1]) {
4761
- let tipH = rect.centerY > this.line.getRect().centerY ? -renderer.unitSize : renderer.unitSize;
4762
- renderer.drawLine(rect.right, rect.centerY, rect.right, rect.centerY + tipH, "black", renderer.lineWidth);
4717
+ let tipH = rect.centerY > this.line.getRect().centerY ? -ctx.unitSize : ctx.unitSize;
4718
+ ctx.strokeLine(rect.right, rect.centerY, rect.right, rect.centerY + tipH);
4763
4719
  }
4764
4720
  }
4765
4721
  };
@@ -4771,13 +4727,13 @@ import { MusicError as MusicError13, MusicErrorType as MusicErrorType13 } from "
4771
4727
  import { Note as Note6 } from "@tspro/web-music-score/theory";
4772
4728
 
4773
4729
  // src/score/engine/obj-connective.ts
4774
- import { Utils as Utils9 } from "@tspro/ts-utils-lib";
4730
+ import { Utils as Utils8 } from "@tspro/ts-utils-lib";
4775
4731
  import { MusicError as MusicError11, MusicErrorType as MusicErrorType11 } from "@tspro/web-music-score/core";
4776
4732
  var ObjConnective = class extends MusicObject {
4777
4733
  constructor(connectiveProps, line, measure, leftNoteGroup, leftNoteId, ...args) {
4734
+ var _a;
4778
4735
  super(measure);
4779
4736
  this.connectiveProps = connectiveProps;
4780
- this.line = line;
4781
4737
  this.measure = measure;
4782
4738
  __publicField(this, "lx", 0);
4783
4739
  __publicField(this, "ly", 0);
@@ -4788,19 +4744,21 @@ var ObjConnective = class extends MusicObject {
4788
4744
  __publicField(this, "cp2x", 0);
4789
4745
  __publicField(this, "cp2y", 0);
4790
4746
  __publicField(this, "arcHeight", 0);
4747
+ __publicField(this, "line");
4791
4748
  __publicField(this, "leftNoteGroup");
4792
4749
  __publicField(this, "leftNoteId");
4793
4750
  __publicField(this, "rightNoteGroup");
4794
4751
  __publicField(this, "rightNoteId");
4795
4752
  __publicField(this, "tieType");
4796
4753
  __publicField(this, "mi");
4754
+ this.line = (_a = this.measure.row.findMatchingLine(line)) != null ? _a : line;
4797
4755
  this.leftNoteGroup = leftNoteGroup;
4798
4756
  this.leftNoteId = leftNoteId;
4799
4757
  if (args[0] instanceof ObjNoteGroup && typeof args[1] === "number") {
4800
4758
  this.rightNoteGroup = args[0];
4801
4759
  this.rightNoteId = args[1];
4802
4760
  this.tieType = void 0;
4803
- } else if (Utils9.Is.isEnumValue(args[0], TieType)) {
4761
+ } else if (Utils8.Is.isEnumValue(args[0], TieType)) {
4804
4762
  this.rightNoteGroup = void 0;
4805
4763
  this.rightNoteId = void 0;
4806
4764
  this.tieType = args[0];
@@ -4817,8 +4775,8 @@ var ObjConnective = class extends MusicObject {
4817
4775
  pick(x, y) {
4818
4776
  return this.rect.contains(x, y) ? [this] : [];
4819
4777
  }
4820
- layout(renderer) {
4821
- let { unitSize } = renderer;
4778
+ layout(ctx) {
4779
+ let { unitSize } = ctx;
4822
4780
  let { measure, line, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId, connectiveProps } = this;
4823
4781
  let { noteAnchor, arcDir } = connectiveProps;
4824
4782
  let { row } = measure;
@@ -4870,7 +4828,7 @@ var ObjConnective = class extends MusicObject {
4870
4828
  this.rx = rx;
4871
4829
  this.ry = ry;
4872
4830
  this.arcHeight = this.connectiveProps.connective === "slide" /* Slide */ ? 0 : arcHeight;
4873
- let { nx, ny } = Utils9.Math.calcNormal(lx, ly, rx, ry);
4831
+ let { nx, ny } = Utils8.Math.calcNormal(lx, ly, rx, ry);
4874
4832
  this.cp1x = lx * 0.7 + rx * 0.3 + nx * this.arcHeight;
4875
4833
  this.cp1y = ly * 0.7 + ry * 0.3 + ny * this.arcHeight;
4876
4834
  this.cp2x = lx * 0.3 + rx * 0.7 + nx * this.arcHeight;
@@ -4894,11 +4852,7 @@ var ObjConnective = class extends MusicObject {
4894
4852
  this.cp2y += dy;
4895
4853
  this.rect.offsetInPlace(dx, dy);
4896
4854
  }
4897
- draw(renderer) {
4898
- let ctx = renderer.getCanvasContext();
4899
- if (!ctx) {
4900
- return;
4901
- }
4855
+ draw(ctx) {
4902
4856
  if (this.rightNoteGroup === void 0) {
4903
4857
  } else if (this.leftNoteGroup.measure === this.rightNoteGroup.measure) {
4904
4858
  } else if (this.leftNoteGroup.row.getNextRow() === this.rightNoteGroup.row) {
@@ -4907,12 +4861,11 @@ var ObjConnective = class extends MusicObject {
4907
4861
  return;
4908
4862
  }
4909
4863
  let { rect } = this;
4910
- let { lineWidth } = renderer;
4911
- renderer.drawDebugRect(rect);
4912
- let t = lineWidth * 1.5;
4913
- let s = lineWidth * 0.25;
4914
- ctx.strokeStyle = ctx.fillStyle = "black";
4915
- ctx.lineWidth = lineWidth;
4864
+ let { _lineWidth } = ctx;
4865
+ ctx.drawDebugRect(rect);
4866
+ let t = _lineWidth * 1.5;
4867
+ let s = _lineWidth * 0.25;
4868
+ ctx.color("black").lineWidth(1);
4916
4869
  if (this.arcHeight === 0) {
4917
4870
  ctx.beginPath();
4918
4871
  ctx.moveTo(this.lx, this.ly);
@@ -4931,7 +4884,7 @@ var ObjConnective = class extends MusicObject {
4931
4884
 
4932
4885
  // src/score/engine/connective-props.ts
4933
4886
  import { MusicError as MusicError12, MusicErrorType as MusicErrorType12 } from "@tspro/web-music-score/core";
4934
- import { Utils as Utils10 } from "@tspro/ts-utils-lib";
4887
+ import { Utils as Utils9 } from "@tspro/ts-utils-lib";
4935
4888
  var ConnectiveProps = class {
4936
4889
  constructor(connective, span, noteAnchor, startNoteGroup) {
4937
4890
  this.connective = connective;
@@ -4962,7 +4915,7 @@ var ConnectiveProps = class {
4962
4915
  return false;
4963
4916
  }
4964
4917
  }
4965
- computeParams() {
4918
+ computeParams(line) {
4966
4919
  let { stemDir } = this.noteGroups[0];
4967
4920
  let { hasStem } = this.noteGroups[0].rhythmProps;
4968
4921
  if (this.noteAnchor === "stemTip" /* StemTip */) {
@@ -4979,9 +4932,8 @@ var ConnectiveProps = class {
4979
4932
  this.noteAnchor = "below" /* Below */;
4980
4933
  }
4981
4934
  } else if (this.noteAnchor === "center" /* Center */) {
4982
- let { row } = this.noteGroups[0].measure;
4983
- let diatonicId = this.noteGroups[0].ownDiatonicId;
4984
- let staff = row.getStaff(diatonicId);
4935
+ let staff = line instanceof ObjStaff ? line : void 0;
4936
+ let diatonicId = this.noteGroups[0].getDiatonicId(staff);
4985
4937
  this.arcDir = !staff || diatonicId < staff.middleLineDiatonicId ? "down" : "up";
4986
4938
  } else if (this.noteAnchor === "above" /* Above */) {
4987
4939
  this.arcDir = "up";
@@ -4997,68 +4949,73 @@ var ConnectiveProps = class {
4997
4949
  this.noteGroups.length = 1;
4998
4950
  }
4999
4951
  createConnectives() {
4952
+ if (this.noteGroups.length === 0) {
4953
+ return;
4954
+ }
5000
4955
  this.getStartNoteGroup().collectConnectiveProps();
5001
- this.computeParams();
5002
4956
  let { connective, span } = this;
5003
- if (connective === "tie" /* Tie */) {
5004
- if (Utils10.Is.isEnumValue(span, TieType)) {
5005
- let leftNoteGroup = this.noteGroups[0];
5006
- for (let noteId = 0; noteId < leftNoteGroup.notes.length; noteId++) {
5007
- this.createObjConnectiveWithTieType(leftNoteGroup, noteId, span);
4957
+ this.noteGroups[0].row.getNotationLines().forEach((line) => {
4958
+ this.computeParams(line);
4959
+ if (connective === "tie" /* Tie */) {
4960
+ if (Utils9.Is.isEnumValue(span, TieType)) {
4961
+ let leftNoteGroup = this.noteGroups[0];
4962
+ for (let noteId = 0; noteId < leftNoteGroup.notes.length; noteId++) {
4963
+ this.createObjConnectiveWithTieType(line, leftNoteGroup, noteId, span);
4964
+ }
4965
+ } else if (this.noteGroups.length >= 2) {
4966
+ for (let i = 0; i < this.noteGroups.length - 1; i++) {
4967
+ let leftNoteGroup = this.noteGroups[i];
4968
+ let rightNoteGroup = this.noteGroups[i + 1];
4969
+ leftNoteGroup.notes.forEach((leftNote, leftNoteId) => {
4970
+ let rightNoteId = rightNoteGroup.notes.findIndex((rightNote) => Note6.equals(rightNote, leftNote));
4971
+ if (rightNoteId >= 0) {
4972
+ this.createObjConnective(line, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId);
4973
+ }
4974
+ });
4975
+ }
5008
4976
  }
5009
- } else if (this.noteGroups.length >= 2) {
5010
- for (let i = 0; i < this.noteGroups.length - 1; i++) {
5011
- let leftNoteGroup = this.noteGroups[i];
5012
- let rightNoteGroup = this.noteGroups[i + 1];
5013
- leftNoteGroup.notes.forEach((leftNote, leftNoteId) => {
5014
- let rightNoteId = rightNoteGroup.notes.findIndex((rightNote) => Note6.equals(rightNote, leftNote));
5015
- if (rightNoteId >= 0) {
5016
- this.createObjConnective(leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId);
5017
- }
5018
- });
4977
+ } else if (connective === "slur" /* Slur */) {
4978
+ if (typeof span === "number" && span >= 2 && this.noteGroups.length === span) {
4979
+ let leftNoteGroup = this.noteGroups[0];
4980
+ let rightNoteGroup = this.noteGroups[this.noteGroups.length - 1];
4981
+ this.createObjConnective(line, leftNoteGroup, 0, rightNoteGroup, 0);
5019
4982
  }
5020
- }
5021
- } else if (connective === "slur" /* Slur */) {
5022
- if (typeof span === "number" && span >= 2 && this.noteGroups.length === span) {
5023
- let leftNoteGroup = this.noteGroups[0];
5024
- let rightNoteGroup = this.noteGroups[this.noteGroups.length - 1];
5025
- this.createObjConnective(leftNoteGroup, 0, rightNoteGroup, 0);
5026
- }
5027
- } else if (connective === "slide" /* Slide */) {
5028
- if (this.noteGroups.length >= 2) {
5029
- for (let i = 0; i < this.noteGroups.length - 1; i++) {
5030
- let leftNoteGroup = this.noteGroups[i];
5031
- let rightNoteGroup = this.noteGroups[i + 1];
5032
- this.createObjConnective(leftNoteGroup, 0, rightNoteGroup, 0);
4983
+ } else if (connective === "slide" /* Slide */) {
4984
+ if (this.noteGroups.length >= 2) {
4985
+ for (let i = 0; i < this.noteGroups.length - 1; i++) {
4986
+ let leftNoteGroup = this.noteGroups[i];
4987
+ let rightNoteGroup = this.noteGroups[i + 1];
4988
+ this.createObjConnective(line, leftNoteGroup, 0, rightNoteGroup, 0);
4989
+ }
5033
4990
  }
5034
4991
  }
5035
- }
4992
+ });
5036
4993
  }
5037
- createObjConnectiveWithTieType(leftNoteGroup, leftNoteId, tieType) {
5038
- leftNoteGroup.row.getNotationLines().filter((line) => leftNoteGroup.enableConnective(line)).forEach((line) => {
5039
- if (line instanceof ObjStaff) {
4994
+ createObjConnectiveWithTieType(line, leftNoteGroup, leftNoteId, tieType) {
4995
+ if (!leftNoteGroup.enableConnective(line)) {
4996
+ return;
4997
+ } else if (line instanceof ObjStaff) {
4998
+ new ObjConnective(this, line, leftNoteGroup.measure, leftNoteGroup, leftNoteId, tieType);
4999
+ } else if (line instanceof ObjTab) {
5000
+ let leftString = leftNoteGroup.getFretNumberString(leftNoteId);
5001
+ if (leftString !== void 0) {
5040
5002
  new ObjConnective(this, line, leftNoteGroup.measure, leftNoteGroup, leftNoteId, tieType);
5041
- } else {
5042
- let leftString = leftNoteGroup.getFretNumberString(leftNoteId);
5043
- if (leftString !== void 0) {
5044
- new ObjConnective(this, line, leftNoteGroup.measure, leftNoteGroup, leftNoteId, tieType);
5045
- }
5046
5003
  }
5047
- });
5004
+ }
5048
5005
  }
5049
- createObjConnective(leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId) {
5006
+ createObjConnective(line, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId) {
5050
5007
  const addConnective = (measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2) => {
5051
- measure.row.getNotationLines().filter((line) => leftNoteGroup2.enableConnective(line) && rightNoteGroup2.enableConnective(line)).forEach((line) => {
5052
- if (line instanceof ObjStaff) {
5008
+ if (!(leftNoteGroup2.enableConnective(line) && rightNoteGroup2.enableConnective(line))) {
5009
+ return;
5010
+ } else if (line instanceof ObjStaff) {
5011
+ new ObjConnective(this, line, measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2);
5012
+ } else if (line instanceof ObjTab) {
5013
+ let leftString = leftNoteGroup2.getFretNumberString(leftNoteId2);
5014
+ let rightString = rightNoteGroup2.getFretNumberString(rightNoteId2);
5015
+ if (leftString !== void 0 && rightString !== void 0 && (leftString === rightString || this.connective === "slur" /* Slur */)) {
5053
5016
  new ObjConnective(this, line, measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2);
5054
- } else {
5055
- let leftString = leftNoteGroup2.getFretNumberString(leftNoteId2);
5056
- let rightString = rightNoteGroup2.getFretNumberString(rightNoteId2);
5057
- if (leftString !== void 0 && rightString !== void 0 && (leftString === rightString || this.connective === "slur" /* Slur */)) {
5058
- new ObjConnective(this, line, measure, leftNoteGroup2, leftNoteId2, rightNoteGroup2, rightNoteId2);
5059
- }
5060
5017
  }
5061
- });
5018
+ }
5062
5019
  };
5063
5020
  if (leftNoteGroup.measure === rightNoteGroup.measure) {
5064
5021
  addConnective(leftNoteGroup.measure, leftNoteGroup, leftNoteId, rightNoteGroup, rightNoteId);
@@ -5071,6 +5028,72 @@ var ConnectiveProps = class {
5071
5028
  }
5072
5029
  };
5073
5030
 
5031
+ // src/score/engine/obj-lyrics.ts
5032
+ import { Utils as Utils10 } from "@tspro/ts-utils-lib";
5033
+ var ObjLyrics = class extends MusicObject {
5034
+ constructor(col, verse, line, vpos, lyricsLength, lyricsText, lyricsOptions) {
5035
+ super(col);
5036
+ this.col = col;
5037
+ this.verse = verse;
5038
+ this.line = line;
5039
+ this.vpos = vpos;
5040
+ __publicField(this, "nextLyricsObject");
5041
+ __publicField(this, "rhythmProps");
5042
+ __publicField(this, "color", "black");
5043
+ __publicField(this, "hyphen");
5044
+ __publicField(this, "text");
5045
+ __publicField(this, "mi");
5046
+ this.rhythmProps = RhythmProps.get(lyricsLength);
5047
+ let halign = (lyricsOptions == null ? void 0 : lyricsOptions.align) === "left" /* Left */ ? 0 : (lyricsOptions == null ? void 0 : lyricsOptions.align) === "right" /* Right */ ? 1 : 0.5;
5048
+ this.hyphen = Utils10.Is.isEnumValue(lyricsOptions == null ? void 0 : lyricsOptions.hyphen, LyricsHyphen) ? lyricsOptions == null ? void 0 : lyricsOptions.hyphen : void 0;
5049
+ this.text = new ObjText(this, { text: lyricsText, color: this.color, scale: 0.8 }, halign, 0);
5050
+ this.rect = new DivRect();
5051
+ this.mi = new MLyrics(this);
5052
+ }
5053
+ getMusicInterface() {
5054
+ return this.mi;
5055
+ }
5056
+ get measure() {
5057
+ return this.col.measure;
5058
+ }
5059
+ getText() {
5060
+ return this.text.getText();
5061
+ }
5062
+ setNextLyricsObject(lyricsObj) {
5063
+ this.nextLyricsObject = lyricsObj;
5064
+ }
5065
+ pick(x, y) {
5066
+ return this.rect.contains(x, y) ? [this] : [];
5067
+ }
5068
+ layout(ctx) {
5069
+ this.text.layout(ctx);
5070
+ this.rect = this.text.getRect().copy();
5071
+ }
5072
+ offset(dx, dy) {
5073
+ this.text.offset(dx, dy);
5074
+ this.rect.offsetInPlace(dx, dy);
5075
+ }
5076
+ draw(ctx) {
5077
+ var _a;
5078
+ this.text.draw(ctx);
5079
+ if (this.hyphen !== void 0) {
5080
+ ctx.color(this.color).lineWidth(1);
5081
+ let l = this.getRect();
5082
+ let r = (_a = this.nextLyricsObject) == null ? void 0 : _a.getRect();
5083
+ let hyphenw = ctx.unitSize * 1.5;
5084
+ let maxw = r ? (r.left - l.right) * 0.85 : hyphenw;
5085
+ let w = this.hyphen === "-" /* Hyphen */ ? Math.min(hyphenw, maxw) : maxw;
5086
+ if (w > 0) {
5087
+ let cx = r ? (r.left + l.right) / 2 : l.right + w / 0.85;
5088
+ let cy = (l.top + l.bottom) / 2;
5089
+ ctx.moveTo(cx - w / 2, cy);
5090
+ ctx.lineTo(cx + w / 2, cy);
5091
+ ctx.stroke();
5092
+ }
5093
+ }
5094
+ }
5095
+ };
5096
+
5074
5097
  // src/score/engine/obj-tab-rhythm.ts
5075
5098
  import { Utils as Utils11 } from "@tspro/ts-utils-lib";
5076
5099
  var ObjTabRhythm = class extends MusicObject {
@@ -5078,11 +5101,11 @@ var ObjTabRhythm = class extends MusicObject {
5078
5101
  super(measure);
5079
5102
  this.measure = measure;
5080
5103
  this.tab = tab;
5081
- __publicField(this, "voiceIds");
5104
+ __publicField(this, "voiceId");
5082
5105
  __publicField(this, "mi");
5083
5106
  // Keep non-static
5084
5107
  __publicField(this, "tupletPartsTextObjMap", /* @__PURE__ */ new Map());
5085
- this.voiceIds = getVoiceIds().filter((voiceId) => tab.containsVoiceId(voiceId));
5108
+ this.voiceId = getVoiceIds().filter((voiceId) => tab.containsVoiceId(voiceId));
5086
5109
  this.rect = new DivRect();
5087
5110
  this.mi = new MTabRhythm(this);
5088
5111
  }
@@ -5092,17 +5115,17 @@ var ObjTabRhythm = class extends MusicObject {
5092
5115
  pick(x, y) {
5093
5116
  return this.rect.contains(x, y) ? [this] : [];
5094
5117
  }
5095
- layout(renderer) {
5118
+ layout(ctx) {
5096
5119
  let columns = this.measure.getColumns();
5097
5120
  let numColsInVoiceId = getVoiceIds().map((voiceId) => Utils11.Math.sum(columns.map((col) => col.getVoiceSymbol(voiceId) ? 1 : 0)));
5098
- this.voiceIds.sort((a, b) => Utils11.Math.cmp(numColsInVoiceId[a], numColsInVoiceId[b]));
5121
+ this.voiceId.sort((a, b) => Utils11.Math.cmp(numColsInVoiceId[a], numColsInVoiceId[b]));
5099
5122
  this.rect = new DivRect();
5100
5123
  }
5101
5124
  hasTuplets() {
5102
5125
  return this.measure.getBeamGroups().some((beamGroup) => beamGroup.isTuplet());
5103
5126
  }
5104
- layoutFitToMeasure(renderer) {
5105
- let { unitSize, fontSize } = renderer;
5127
+ layoutFitToMeasure(ctx) {
5128
+ let { unitSize, fontSize } = ctx;
5106
5129
  let { measure } = this;
5107
5130
  let { left, right } = measure.getColumnsContentRect();
5108
5131
  let stemHeight = unitSize * 5;
@@ -5116,13 +5139,10 @@ var ObjTabRhythm = class extends MusicObject {
5116
5139
  offset(dx, dy) {
5117
5140
  this.rect.offsetInPlace(dx, dy);
5118
5141
  }
5119
- draw(renderer) {
5120
- const ctx = renderer.getCanvasContext();
5121
- if (!ctx) {
5122
- return;
5123
- }
5124
- renderer.drawDebugRect(this.rect);
5125
- let { unitSize, lineWidth, fontSize } = renderer;
5142
+ draw(ctx) {
5143
+ ctx.drawDebugRect(this.rect);
5144
+ ctx.color("black").lineWidth(1);
5145
+ let { unitSize, fontSize } = ctx;
5126
5146
  let flagSize = unitSize;
5127
5147
  let dotSpace = unitSize;
5128
5148
  let dotWidth = unitSize * 0.25;
@@ -5132,7 +5152,7 @@ var ObjTabRhythm = class extends MusicObject {
5132
5152
  let columns = this.measure.getColumns();
5133
5153
  for (let colId = 0; colId < columns.length; colId++) {
5134
5154
  let cur = columns[colId];
5135
- let curVoiceSymbol = this.voiceIds.map((voiceId) => cur.getVoiceSymbol(voiceId)).find((sym) => sym !== void 0);
5155
+ let curVoiceSymbol = this.voiceId.map((voiceId) => cur.getVoiceSymbol(voiceId)).find((sym) => sym !== void 0);
5136
5156
  if (!curVoiceSymbol) {
5137
5157
  continue;
5138
5158
  }
@@ -5144,16 +5164,17 @@ var ObjTabRhythm = class extends MusicObject {
5144
5164
  let colX = sym.col.getRect().centerX;
5145
5165
  if (sym instanceof ObjNoteGroup) {
5146
5166
  if (sym.rhythmProps.noteSize >= 2) {
5147
- let stemThickness = sym.rhythmProps.noteSize === 4 ? lineWidth * 2 : lineWidth;
5148
- renderer.drawLine(colX, stemBottom, colX, stemTop, "black", stemThickness);
5167
+ ctx.lineWidth(sym.rhythmProps.noteSize === 4 ? 2 : 1);
5168
+ ctx.strokeLine(colX, stemBottom, colX, stemTop);
5149
5169
  }
5170
+ ctx.lineWidth(1);
5150
5171
  if (symbols.length === 1) {
5151
5172
  for (let i = 0; i < sym.rhythmProps.flagCount; i++) {
5152
- renderer.drawFlag(new DivRect(colX, colX + flagSize, stemTop + i * flagSize, stemTop + (i + 2) * flagSize), "up");
5173
+ ctx.drawFlag(new DivRect(colX, colX + flagSize, stemTop + i * flagSize, stemTop + (i + 2) * flagSize), "up");
5153
5174
  }
5154
5175
  }
5155
5176
  for (let i = 0; i < sym.rhythmProps.dotCount; i++) {
5156
- renderer.fillCircle(colX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5177
+ ctx.fillCircle(colX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5157
5178
  }
5158
5179
  } else if (sym instanceof ObjRest) {
5159
5180
  let cx = colX;
@@ -5161,11 +5182,11 @@ var ObjTabRhythm = class extends MusicObject {
5161
5182
  let scale = 0.65;
5162
5183
  ctx.save();
5163
5184
  ctx.scale(scale, scale);
5164
- renderer.drawRest(sym.rhythmProps.noteSize, cx / scale, cy / scale, "black");
5185
+ ctx.drawRest(sym.rhythmProps.noteSize, cx / scale, cy / scale);
5165
5186
  ctx.restore();
5166
5187
  for (let i = 0; i < sym.rhythmProps.dotCount; i++) {
5167
5188
  cx += dotSpace * 1.5;
5168
- renderer.fillCircle(cx, cy + dotSpace, dotWidth);
5189
+ ctx.fillCircle(cx, cy + dotSpace, dotWidth);
5169
5190
  }
5170
5191
  }
5171
5192
  if (nextSym) {
@@ -5176,16 +5197,18 @@ var ObjTabRhythm = class extends MusicObject {
5176
5197
  let leftBeamCount = left.hasTuplet() ? 1 : left instanceof ObjNoteGroup ? left.getRightBeamCount() : 1;
5177
5198
  let rightBeamCount = right.hasTuplet() ? 1 : right instanceof ObjNoteGroup ? right.getLeftBeamCount() : 1;
5178
5199
  let maxBeamCount = Math.max(leftBeamCount, rightBeamCount);
5200
+ ctx.lineWidth(2);
5179
5201
  for (let i = 0; i < maxBeamCount; i++) {
5180
5202
  let leftT = rightBeamCount > leftBeamCount && i >= leftBeamCount ? 0.75 : 0;
5181
5203
  let rightT = leftBeamCount > rightBeamCount && i >= rightBeamCount ? 0.25 : 1;
5182
- renderer.drawPartialLine(leftX, stemTop + i * flagSize, rightX, stemTop + i * flagSize, leftT, rightT, "black", lineWidth * 2);
5204
+ ctx.strokePartialLine(leftX, stemTop + i * flagSize, rightX, stemTop + i * flagSize, leftT, rightT);
5183
5205
  }
5206
+ ctx.lineWidth(1);
5184
5207
  for (let i = 0; i < left.rhythmProps.dotCount; i++) {
5185
- renderer.fillCircle(leftX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5208
+ ctx.fillCircle(leftX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5186
5209
  }
5187
5210
  for (let i = 0; i < right.rhythmProps.dotCount; i++) {
5188
- renderer.fillCircle(rightX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5211
+ ctx.fillCircle(rightX + dotSpace * (i + 1), stemBottom - dotWidth, dotWidth);
5189
5212
  }
5190
5213
  }
5191
5214
  if (beamGroup && beamGroup.isTuplet()) {
@@ -5194,11 +5217,11 @@ var ObjTabRhythm = class extends MusicObject {
5194
5217
  let textObj = this.tupletPartsTextObjMap.get(text);
5195
5218
  if (!textObj) {
5196
5219
  this.tupletPartsTextObjMap.set(text, textObj = new ObjText(this, { text, scale: 0.75 }, 0.5, 0.5));
5197
- textObj.layout(renderer);
5220
+ textObj.layout(ctx);
5198
5221
  }
5199
5222
  textObj.offset(-textObj.getRect().centerX, -textObj.getRect().centerY);
5200
5223
  textObj.offset(cx, stemTop - fontSize / 2);
5201
- textObj.draw(renderer);
5224
+ textObj.draw(ctx);
5202
5225
  }
5203
5226
  if (symbols.length > 1) {
5204
5227
  colId = columns.indexOf(symbols[symbols.length - 1].col);
@@ -5258,9 +5281,10 @@ function getVerseLayoutGroupId(verse) {
5258
5281
  }
5259
5282
  }
5260
5283
  var _ObjMeasure = class _ObjMeasure extends MusicObject {
5261
- constructor(row) {
5284
+ constructor(row, options) {
5262
5285
  super(row);
5263
5286
  this.row = row;
5287
+ this.options = options;
5264
5288
  __publicField(this, "prevMeasure");
5265
5289
  __publicField(this, "nextMeasure");
5266
5290
  __publicField(this, "keySignature", getDefaultKeySignature());
@@ -5282,9 +5306,6 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5282
5306
  __publicField(this, "leftSolidAreaWidth", 0);
5283
5307
  __publicField(this, "minColumnsAreaWidth", 0);
5284
5308
  __publicField(this, "rightSolidAreaWidth", 0);
5285
- __publicField(this, "useDiatonicId", []);
5286
- __publicField(this, "useStemDir", []);
5287
- __publicField(this, "useString", []);
5288
5309
  __publicField(this, "voiceSymbols", []);
5289
5310
  __publicField(this, "lastAddedRhythmColumn");
5290
5311
  __publicField(this, "lastAddedRhythmSymbol");
@@ -5301,7 +5322,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5301
5322
  // play twice.
5302
5323
  __publicField(this, "endRepeatPlayCountText");
5303
5324
  __publicField(this, "staticObjectsCache", /* @__PURE__ */ new Map());
5304
- __publicField(this, "lyricsObjectsCache", /* @__PURE__ */ new Map());
5325
+ __publicField(this, "lyricsObjectsCache", new Map32());
5305
5326
  __publicField(this, "mi");
5306
5327
  this.mi = new MMeasure(this);
5307
5328
  this.prevMeasure = row.doc.getLastMeasure();
@@ -5339,54 +5360,67 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5339
5360
  getPassCount() {
5340
5361
  return this.passCount;
5341
5362
  }
5342
- updateOwnDiatonicId(voiceId, setDiatonicId) {
5343
- if (typeof setDiatonicId == "number") {
5344
- this.useDiatonicId[voiceId] = setDiatonicId;
5345
- } else if (this.useDiatonicId[voiceId] === void 0) {
5346
- let prevMeasure = this.getPrevMeasure();
5347
- if (prevMeasure && prevMeasure.useDiatonicId[voiceId] !== void 0) {
5348
- this.useDiatonicId[voiceId] = prevMeasure.useDiatonicId[voiceId];
5349
- }
5350
- }
5351
- let diatonicId = this.useDiatonicId[voiceId];
5352
- if (diatonicId === void 0) {
5353
- if (this.row.hasStaff) {
5354
- diatonicId = this.row.getTopStaff().middleLineDiatonicId;
5355
- } else {
5356
- diatonicId = Note7.getNote("C4").diatonicId;
5357
- }
5358
- }
5359
- return this.useDiatonicId[voiceId] = Note7.validateDiatonicId(diatonicId);
5360
- }
5361
- updateOwnStemDir(symbol, setStemDir) {
5362
- var _a, _b;
5363
- let { voiceId } = symbol;
5364
- if (setStemDir !== void 0) {
5365
- this.useStemDir[voiceId] = setStemDir;
5366
- } else if (this.useStemDir[voiceId] === void 0) {
5367
- this.useStemDir[voiceId] = (_b = (_a = this.getPrevMeasure()) == null ? void 0 : _a.useStemDir[voiceId]) != null ? _b : "auto" /* Auto */;
5368
- }
5369
- let stemDir = this.useStemDir[voiceId];
5370
- if (stemDir === "auto" /* Auto */ || stemDir === void 0) {
5371
- let staff = this.row.getStaff(symbol.ownDiatonicId);
5372
- if (staff) {
5373
- return symbol.ownDiatonicId > staff.middleLineDiatonicId ? "down" /* Down */ : "up" /* Up */;
5374
- } else {
5375
- return "up" /* Up */;
5376
- }
5377
- } else {
5378
- return stemDir;
5379
- }
5380
- }
5381
- updateOwnString(symbol, setString) {
5382
- var _a, _b;
5383
- let { voiceId } = symbol;
5384
- if (setString !== void 0) {
5385
- this.useString[voiceId] = setString;
5386
- } else if (this.useString[voiceId] === void 0) {
5387
- this.useString[voiceId] = (_b = (_a = this.getPrevMeasure()) == null ? void 0 : _a.useString[voiceId]) != null ? _b : [];
5388
- }
5389
- return this.useString[voiceId];
5363
+ updateRunningArguments(runningArgs) {
5364
+ var _a;
5365
+ runningArgs != null ? runningArgs : runningArgs = [];
5366
+ let numVoices = Utils12.Math.sum(getVoiceIds().map((voiceId) => this.getVoiceSymbols(voiceId).length > 0 ? 1 : 0));
5367
+ getVoiceIds().forEach((voiceId) => {
5368
+ var _a2;
5369
+ const getDefaultDiatonicId = () => {
5370
+ let staves = this.row.getStaves().filter((staff) => staff.containsVoiceId(voiceId));
5371
+ let tabs = this.row.getTabs().filter((tab) => tab.containsVoiceId(voiceId));
5372
+ return staves.length > 0 ? staves[0].middleLineDiatonicId : tabs.length > 0 ? tabs[0].getTuningStrings()[3].diatonicId : Note7.getNote("G4").diatonicId;
5373
+ };
5374
+ const getDefaultStemDir = () => "auto" /* Auto */;
5375
+ const getDefaultStringNumbers = () => [];
5376
+ let args = (_a2 = runningArgs[voiceId]) != null ? _a2 : runningArgs[voiceId] = {
5377
+ diatonicId: getDefaultDiatonicId(),
5378
+ stemDir: getDefaultStemDir(),
5379
+ stringNumbers: getDefaultStringNumbers()
5380
+ };
5381
+ this.getVoiceSymbols(voiceId).forEach((sym, symId, symArr) => {
5382
+ var _a3, _b;
5383
+ if (sym.setDiatonicId === ObjRest.UndefinedDiatonicId) {
5384
+ if (numVoices < 2) {
5385
+ args.diatonicId = ObjRest.UndefinedDiatonicId;
5386
+ }
5387
+ } else {
5388
+ args.diatonicId = sym.setDiatonicId;
5389
+ }
5390
+ if (sym instanceof ObjNoteGroup) {
5391
+ if (sym.setStringsNumbers) {
5392
+ args.stringNumbers = sym.setStringsNumbers;
5393
+ }
5394
+ switch ((_a3 = sym.options) == null ? void 0 : _a3.stem) {
5395
+ case "up" /* Up */:
5396
+ case "up":
5397
+ args.stemDir = "up" /* Up */;
5398
+ break;
5399
+ case "down" /* Down */:
5400
+ case "down":
5401
+ args.stemDir = "down" /* Down */;
5402
+ break;
5403
+ case "auto" /* Auto */:
5404
+ case "auto":
5405
+ args.stemDir = "auto" /* Auto */;
5406
+ break;
5407
+ }
5408
+ }
5409
+ let beamSymbols = (_b = sym.getBeamGroup()) == null ? void 0 : _b.getSymbols();
5410
+ let setStemDir;
5411
+ if (beamSymbols === void 0) {
5412
+ setStemDir = args.stemDir === "auto" /* Auto */ ? this.row.solveAutoStemDir([sym]) : args.stemDir;
5413
+ } else {
5414
+ if (sym === beamSymbols[0]) {
5415
+ setStemDir = args.stemDir === "auto" /* Auto */ ? this.row.solveAutoStemDir(beamSymbols) : args.stemDir;
5416
+ } else {
5417
+ setStemDir = beamSymbols[0].stemDir;
5418
+ }
5419
+ }
5420
+ sym.updateRunningArguments(args.diatonicId, setStemDir, args.stringNumbers);
5421
+ });
5422
+ });
5423
+ (_a = this.getNextMeasure()) == null ? void 0 : _a.updateRunningArguments(runningArgs);
5390
5424
  }
5391
5425
  pick(x, y) {
5392
5426
  if (!this.getRect().contains(x, y)) {
@@ -5543,7 +5577,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5543
5577
  } else {
5544
5578
  let dotCount = typeof dotted === "number" && dotted > 0 ? dotted : dotted === true ? 1 : NoteLengthProps5.get(beatLength).dotCount;
5545
5579
  let options = {
5546
- beatLength: validateNoteLength3(beatLength),
5580
+ beatLength: validateNoteLength2(beatLength),
5547
5581
  dotCount: dotCount > 0 ? dotCount : void 0
5548
5582
  };
5549
5583
  this.alterTempo = { beatsPerMinute, options };
@@ -5887,16 +5921,15 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5887
5921
  }
5888
5922
  addLyrics(staffTabOrGroups, verse, lyricsLength, lyricsText, lyricsOptions) {
5889
5923
  this.forEachStaffGroup(staffTabOrGroups, 1 /* Below */, (line, vpos) => {
5924
+ var _a;
5890
5925
  let col = this.getRhythmColumn({ verse, line, vpos });
5891
- let lyricsContainer = col.getLyricsContainer(verse, line, vpos, validateNoteLength3(lyricsLength));
5892
- if (lyricsContainer) {
5893
- let lyricsObj = new ObjLyrics(col, verse, line, vpos, lyricsText, lyricsOptions);
5894
- let lyricsArr = this.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
5895
- lyricsArr.push(lyricsObj);
5896
- lyricsArr.sort((a, b) => Utils12.Math.cmp(a.col.positionTicks, b.col.positionTicks));
5897
- lyricsContainer.addLyricsObject(lyricsObj);
5898
- this.addLayoutObject(lyricsObj, line, getVerseLayoutGroupId(verse), vpos);
5899
- }
5926
+ let lyricsObj = new ObjLyrics(col, verse, line, vpos, validateNoteLength2(lyricsLength), lyricsText, lyricsOptions);
5927
+ col.addLyricsObject(lyricsObj);
5928
+ let lyricsArr = this.getLyricsObjects(line, vpos, verse);
5929
+ lyricsArr.push(lyricsObj);
5930
+ lyricsArr.sort((a, b) => Utils12.Math.cmp(a.col.positionTicks, b.col.positionTicks));
5931
+ (_a = lyricsObj.measure.getPrevLyricsObject(lyricsObj)) == null ? void 0 : _a.setNextLyricsObject(lyricsObj);
5932
+ this.addLayoutObject(lyricsObj, line, getVerseLayoutGroupId(verse), vpos);
5900
5933
  this.lastAddedRhythmColumn = col;
5901
5934
  });
5902
5935
  }
@@ -5909,7 +5942,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5909
5942
  let positionTicks = 0;
5910
5943
  for (let i = this.columns.length - 1; i >= 0 && positionTicks === 0; i--) {
5911
5944
  let col = this.columns[i];
5912
- let symbol = typeof arg === "number" ? col.getVoiceSymbol(arg) : col.getLyricsContainer(arg.verse, arg.line, arg.vpos);
5945
+ let symbol = typeof arg === "number" ? col.getVoiceSymbol(arg) : col.getLyricsObject(arg.verse, arg.line, arg.vpos);
5913
5946
  if (symbol) {
5914
5947
  positionTicks = col.positionTicks + symbol.rhythmProps.ticks;
5915
5948
  }
@@ -5977,28 +6010,21 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
5977
6010
  return this.barLineRight.getRect().centerX;
5978
6011
  }
5979
6012
  getLyricsObjects(line, vpos, verse) {
5980
- let vposMap = this.lyricsObjectsCache.get(line);
5981
- if (vposMap === void 0) {
5982
- this.lyricsObjectsCache.set(line, vposMap = /* @__PURE__ */ new Map());
5983
- }
5984
- let verseMap = vposMap.get(vpos);
5985
- if (verseMap === void 0) {
5986
- vposMap.set(vpos, verseMap = /* @__PURE__ */ new Map());
5987
- }
5988
- let lyricsArr = verseMap.get(verse);
5989
- if (lyricsArr === void 0) {
5990
- verseMap.set(verse, lyricsArr = []);
6013
+ let lyricsObjs = this.lyricsObjectsCache.get(line, vpos, verse);
6014
+ if (!lyricsObjs) {
6015
+ this.lyricsObjectsCache.set(line, vpos, verse, lyricsObjs = []);
5991
6016
  }
5992
- return lyricsArr;
6017
+ return lyricsObjs;
5993
6018
  }
5994
6019
  getPrevLyricsObject(lyricsObj) {
5995
6020
  var _a;
5996
- let lyricsArr = this.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
6021
+ let { line, verse, vpos } = lyricsObj;
6022
+ let lyricsArr = this.getLyricsObjects(line, vpos, verse);
5997
6023
  let i = lyricsArr.indexOf(lyricsObj);
5998
6024
  if (i > 0) {
5999
6025
  return lyricsArr[i - 1];
6000
6026
  } else if (i === 0) {
6001
- let lyricsArr2 = (_a = lyricsObj.measure.getPrevMeasure()) == null ? void 0 : _a.getLyricsObjects(lyricsObj.line, lyricsObj.vpos, lyricsObj.verse);
6027
+ let lyricsArr2 = (_a = lyricsObj.measure.getPrevMeasure()) == null ? void 0 : _a.getLyricsObjects(line, vpos, verse);
6002
6028
  if (lyricsArr2 && lyricsArr2.length > 0) {
6003
6029
  return lyricsArr2[lyricsArr2.length - 1];
6004
6030
  }
@@ -6191,20 +6217,20 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6191
6217
  this.row.requestLayout();
6192
6218
  }
6193
6219
  }
6194
- layout(renderer) {
6220
+ layout(ctx) {
6195
6221
  var _a;
6196
6222
  if (!this.needLayout) {
6197
6223
  return;
6198
6224
  }
6199
6225
  this.staticObjectsCache.clear();
6200
6226
  this.requestRectUpdate();
6201
- let { unitSize } = renderer;
6227
+ let { unitSize } = ctx;
6202
6228
  this.postMeasureBreakWidth = this.hasPostMeasureBreak() ? DocumentSettings.PostMeasureBreakWidth * unitSize : 0;
6203
6229
  let isFirstMeasureInRow = this === this.row.getFirstMeasure();
6204
6230
  let isAfterMeasureBreak = ((_a = this.getPrevMeasure()) == null ? void 0 : _a.hasPostMeasureBreak()) === true;
6205
6231
  this.tabStringNotesWidth = isFirstMeasureInRow && this.row.hasTab ? unitSize * 4 : 0;
6206
6232
  let showClef = isFirstMeasureInRow || isAfterMeasureBreak;
6207
- let showMeasureNumber = isFirstMeasureInRow && !this.row.isFirstRow();
6233
+ let showMeasureNumber = this.options.showNumber === false ? false : this.options.showNumber === true || isFirstMeasureInRow && !this.row.isFirstRow();
6208
6234
  let showKeySignature = isFirstMeasureInRow || isAfterMeasureBreak || !!this.alterKeySignature;
6209
6235
  let showTimeSignature = !!this.alterTimeSignature;
6210
6236
  let showTempo = !!this.alterTempo;
@@ -6214,12 +6240,12 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6214
6240
  let oldSignature = this.signatures.filter((s) => s instanceof ObjStaffSignature).find((s) => s.staff === line);
6215
6241
  let signature = oldSignature != null ? oldSignature : new ObjStaffSignature(this, line);
6216
6242
  signature.staff.addObject(signature);
6217
- signature.updateClefImage(renderer, showClef);
6243
+ signature.updateClefImage(ctx, showClef);
6218
6244
  signature.updateMeasureNumber(showMeasureNumber && lineId === 0);
6219
6245
  signature.updateKeySignature(showKeySignature);
6220
6246
  signature.updateTimeSignature(showTimeSignature);
6221
6247
  signature.updateTempo(showTempo && lineId === 0);
6222
- signature.layout(renderer);
6248
+ signature.layout(ctx);
6223
6249
  this.signatures.push(signature);
6224
6250
  } else if (line instanceof ObjTab && (showMeasureNumber || showTimeSignature || showTempo)) {
6225
6251
  let oldSignature = this.signatures.filter((s) => s instanceof ObjTabSignature).find((s) => s.tab === line);
@@ -6228,7 +6254,7 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6228
6254
  signature.updateMeasureNumber(showMeasureNumber && lineId === 0);
6229
6255
  signature.updateTimeSignature(showTimeSignature);
6230
6256
  signature.updateTempo(showTempo && lineId === 0);
6231
- signature.layout(renderer);
6257
+ signature.layout(ctx);
6232
6258
  this.signatures.push(signature);
6233
6259
  }
6234
6260
  });
@@ -6238,29 +6264,29 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6238
6264
  for (let stringId = 0; stringId < 6; stringId++) {
6239
6265
  let note = tab.getTuningStrings()[stringId].format(PitchNotation.Helmholtz, SymbolSet.Unicode);
6240
6266
  let obj = new ObjText(this, { text: note, scale: 0.8 }, 1, 0.5);
6241
- obj.layout(renderer);
6267
+ obj.layout(ctx);
6242
6268
  obj.offset(this.tabStringNotesWidth * 0.8, tab.getStringY(stringId));
6243
6269
  this.tabStringNotes.push(obj);
6244
6270
  tab.addObject(obj);
6245
6271
  }
6246
6272
  });
6247
6273
  }
6248
- this.barLineLeft.layout(renderer);
6274
+ this.barLineLeft.layout(ctx);
6249
6275
  const accState = new AccidentalState(this);
6250
- this.columns.forEach((col) => col.layout(renderer, accState));
6251
- this.barLineRight.layout(renderer);
6276
+ this.columns.forEach((col) => col.layout(ctx, accState));
6277
+ this.barLineRight.layout(ctx);
6252
6278
  if (this.endRepeatPlayCountText) {
6253
- this.endRepeatPlayCountText.layout(renderer);
6279
+ this.endRepeatPlayCountText.layout(ctx);
6254
6280
  }
6255
- this.layoutObjects.forEach((layoutObj) => layoutObj.layout(renderer));
6256
- let padding = renderer.unitSize;
6281
+ this.layoutObjects.forEach((layoutObj) => layoutObj.layout(ctx));
6282
+ let padding = ctx.unitSize;
6257
6283
  this.leftSolidAreaWidth = this.tabStringNotesWidth + Math.max(0, ...this.signatures.map((signature) => signature.getRect().width)) + this.barLineLeft.getRect().width + padding;
6258
6284
  this.rightSolidAreaWidth = padding + this.barLineRight.getRect().width;
6259
6285
  this.minColumnsAreaWidth = 0;
6260
6286
  this.columns.forEach((col) => this.minColumnsAreaWidth += col.getRect().width);
6261
6287
  this.minColumnsAreaWidth = Math.max(this.minColumnsAreaWidth, _ObjMeasure.MinFlexContentWidth * unitSize);
6262
6288
  }
6263
- layoutWidth(renderer, width) {
6289
+ layoutWidth(ctx, width) {
6264
6290
  if (!this.needLayout) {
6265
6291
  return;
6266
6292
  }
@@ -6294,22 +6320,22 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6294
6320
  columnLeft += rect.width * columnScale;
6295
6321
  });
6296
6322
  }
6297
- layoutConnectives(renderer) {
6323
+ layoutConnectives(ctx) {
6298
6324
  if (!this.needLayout) {
6299
6325
  return;
6300
6326
  }
6301
6327
  this.connectives.forEach((connective) => {
6302
- connective.layout(renderer);
6328
+ connective.layout(ctx);
6303
6329
  this.rect.top = Math.min(this.rect.top, connective.getRect().top);
6304
6330
  this.rect.bottom = Math.max(this.rect.bottom, connective.getRect().bottom);
6305
6331
  });
6306
6332
  }
6307
- layoutBeams(renderer) {
6333
+ layoutBeams(ctx) {
6308
6334
  if (!this.needLayout) {
6309
6335
  return;
6310
6336
  }
6311
6337
  this.beamGroups.forEach((beamGroup) => {
6312
- beamGroup.layout(renderer);
6338
+ beamGroup.layout(ctx);
6313
6339
  this.rect.top = Math.min(this.rect.top, beamGroup.getRect().top);
6314
6340
  this.rect.bottom = Math.max(this.rect.bottom, beamGroup.getRect().bottom);
6315
6341
  });
@@ -6369,13 +6395,13 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6369
6395
  this.rect.offsetInPlace(dx, dy);
6370
6396
  this.requestRectUpdate();
6371
6397
  }
6372
- draw(renderer) {
6373
- renderer.drawDebugRect(this.getRect());
6398
+ draw(ctx) {
6399
+ ctx.drawDebugRect(this.getRect());
6374
6400
  let left = this.getStaffLineLeft();
6375
6401
  let right = this.getStaffLineRight();
6376
- const drawLine = (y) => renderer.drawLine(left, y, right, y);
6377
- let { row } = this;
6378
- row.getNotationLines().forEach((line) => {
6402
+ ctx.color("black").lineWidth(1);
6403
+ const drawLine = (y) => ctx.strokeLine(left, y, right, y);
6404
+ this.row.getNotationLines().forEach((line) => {
6379
6405
  if (line instanceof ObjStaff) {
6380
6406
  for (let p = line.bottomLineDiatonicId; p <= line.topLineDiatonicId; p += 2) {
6381
6407
  drawLine(line.getDiatonicIdY(p));
@@ -6386,17 +6412,17 @@ var _ObjMeasure = class _ObjMeasure extends MusicObject {
6386
6412
  }
6387
6413
  }
6388
6414
  });
6389
- this.signatures.forEach((signature) => signature.draw(renderer));
6390
- this.tabStringNotes.forEach((obj) => obj.draw(renderer));
6391
- this.barLineLeft.draw(renderer);
6392
- this.columns.forEach((col) => col.draw(renderer));
6393
- this.barLineRight.draw(renderer);
6415
+ this.signatures.forEach((signature) => signature.draw(ctx));
6416
+ this.tabStringNotes.forEach((obj) => obj.draw(ctx));
6417
+ this.barLineLeft.draw(ctx);
6418
+ this.columns.forEach((col) => col.draw(ctx));
6419
+ this.barLineRight.draw(ctx);
6394
6420
  if (this.endRepeatPlayCountText) {
6395
- this.endRepeatPlayCountText.draw(renderer);
6421
+ this.endRepeatPlayCountText.draw(ctx);
6396
6422
  }
6397
- this.connectives.forEach((connective) => connective.draw(renderer));
6398
- this.layoutObjects.forEach((layoutObj) => layoutObj.musicObj.draw(renderer));
6399
- this.beamGroups.forEach((beam) => beam.draw(renderer));
6423
+ this.connectives.forEach((connective) => connective.draw(ctx));
6424
+ this.layoutObjects.forEach((layoutObj) => layoutObj.musicObj.draw(ctx));
6425
+ this.beamGroups.forEach((beam) => beam.draw(ctx));
6400
6426
  }
6401
6427
  };
6402
6428
  __publicField(_ObjMeasure, "MinFlexContentWidth", 10);
@@ -6466,11 +6492,11 @@ var LayoutObjectWrapper = class {
6466
6492
  isPositionResolved() {
6467
6493
  return this.positionResolved;
6468
6494
  }
6469
- resolveClosestToStaffY(renderer) {
6495
+ resolveClosestToStaffY(ctx) {
6470
6496
  let { musicObj, measure, verticalPos, line } = this;
6471
6497
  let lineTop = line.getTopLineY();
6472
6498
  let lineBottom = line.getBottomLineY();
6473
- let linePadding = renderer.unitSize * 2;
6499
+ let linePadding = ctx.unitSize * 2;
6474
6500
  let y = verticalPos === 1 /* Below */ ? lineBottom + linePadding + musicObj.getRect().toph : lineTop - linePadding - musicObj.getRect().bottomh;
6475
6501
  let staticObjects = measure.getStaticObjects(line);
6476
6502
  let objShapeRects = musicObj.getShapeRects();
@@ -6493,7 +6519,7 @@ var LayoutObjectWrapper = class {
6493
6519
  return void 0;
6494
6520
  }
6495
6521
  }
6496
- layout(renderer) {
6522
+ layout(ctx) {
6497
6523
  this.line.addObject(this);
6498
6524
  }
6499
6525
  offset(dx, dy) {
@@ -6528,20 +6554,21 @@ var LayoutGroup = class {
6528
6554
  }
6529
6555
  });
6530
6556
  }
6531
- clearPositionAndLayout(renderer) {
6557
+ clearPositionAndLayout(ctx) {
6532
6558
  this.layoutObjectTable.forEach((layoutObjects) => {
6533
6559
  layoutObjects.forEach((layoutObj) => {
6534
6560
  layoutObj.clearPositionResolved();
6535
- layoutObj.musicObj.layout(renderer);
6561
+ layoutObj.musicObj.layout(ctx);
6536
6562
  });
6537
6563
  });
6538
6564
  }
6539
6565
  };
6540
6566
 
6541
6567
  // src/score/engine/obj-staff-and-tab.ts
6542
- var ObjNotationLine4 = class extends MusicObject {
6543
- constructor(parent) {
6544
- super(parent);
6568
+ var ObjNotationLine5 = class extends MusicObject {
6569
+ constructor(row) {
6570
+ super(row);
6571
+ this.row = row;
6545
6572
  __publicField(this, "objects", []);
6546
6573
  __publicField(this, "layoutGroups", []);
6547
6574
  }
@@ -6558,18 +6585,18 @@ var ObjNotationLine4 = class extends MusicObject {
6558
6585
  }
6559
6586
  return layoutGroup;
6560
6587
  }
6561
- resetLayoutGroups(renderer) {
6588
+ resetLayoutGroups(ctx) {
6562
6589
  this.layoutGroups.forEach((layoutGroup) => {
6563
6590
  if (layoutGroup) {
6564
- layoutGroup.clearPositionAndLayout(renderer);
6591
+ layoutGroup.clearPositionAndLayout(ctx);
6565
6592
  }
6566
6593
  });
6567
6594
  }
6568
- layoutLayoutGroups(renderer) {
6595
+ layoutLayoutGroups(ctx) {
6569
6596
  this.layoutGroups.forEach((layoutGroup) => {
6570
6597
  if (layoutGroup) {
6571
- this.layoutLayoutGroup(renderer, layoutGroup, 0 /* Above */);
6572
- this.layoutLayoutGroup(renderer, layoutGroup, 1 /* Below */);
6598
+ this.layoutLayoutGroup(ctx, layoutGroup, 0 /* Above */);
6599
+ this.layoutLayoutGroup(ctx, layoutGroup, 1 /* Below */);
6573
6600
  }
6574
6601
  });
6575
6602
  }
@@ -6580,42 +6607,42 @@ var ObjNotationLine4 = class extends MusicObject {
6580
6607
  layoutObj.offset(0, y - layoutObj.getRect().centerY);
6581
6608
  layoutObj.setPositionResolved();
6582
6609
  }
6583
- alignObjectsY(renderer, layoutObjArr) {
6610
+ alignObjectsY(ctx, layoutObjArr) {
6584
6611
  layoutObjArr = layoutObjArr.filter((layoutObj) => !layoutObj.isPositionResolved());
6585
6612
  let rowY;
6586
6613
  layoutObjArr.forEach((layoutObj) => {
6587
- let y = layoutObj.resolveClosestToStaffY(renderer);
6614
+ let y = layoutObj.resolveClosestToStaffY(ctx);
6588
6615
  rowY = layoutObj.verticalPos === 1 /* Below */ ? Math.max(y, rowY != null ? rowY : y) : Math.min(y, rowY != null ? rowY : y);
6589
6616
  });
6590
6617
  layoutObjArr.forEach((layoutObj) => this.setObjectY(layoutObj, rowY));
6591
6618
  }
6592
- layoutLayoutGroup(renderer, layoutGroup, verticalPos) {
6619
+ layoutLayoutGroup(ctx, layoutGroup, verticalPos) {
6593
6620
  let rowLayoutObjs = layoutGroup.getLayoutObjects(verticalPos).filter((layoutObj) => !layoutObj.isPositionResolved());
6594
6621
  rowLayoutObjs.forEach((layoutObj) => {
6595
6622
  let { musicObj, anchor } = layoutObj;
6596
6623
  if (musicObj instanceof ObjEnding || musicObj instanceof ObjExtensionLine || musicObj instanceof ObjTabRhythm) {
6597
- musicObj.layoutFitToMeasure(renderer);
6624
+ musicObj.layoutFitToMeasure(ctx);
6598
6625
  } else {
6599
6626
  musicObj.offset(anchor.getRect().centerX - musicObj.getRect().centerX, 0);
6600
6627
  }
6601
6628
  });
6602
6629
  if (layoutGroup.rowAlign) {
6603
- this.alignObjectsY(renderer, rowLayoutObjs);
6630
+ this.alignObjectsY(ctx, rowLayoutObjs);
6604
6631
  } else {
6605
6632
  rowLayoutObjs.forEach((layoutObj) => {
6606
6633
  let link = layoutObj.musicObj.getLink();
6607
6634
  if (link && link.getHead() === layoutObj.musicObj) {
6608
6635
  let objectParts = [link.getHead(), ...link.getTails()];
6609
6636
  let layoutObjs = rowLayoutObjs.filter((layoutObj2) => objectParts.some((o) => o === layoutObj2.musicObj));
6610
- this.alignObjectsY(renderer, layoutObjs);
6637
+ this.alignObjectsY(ctx, layoutObjs);
6611
6638
  } else {
6612
- this.alignObjectsY(renderer, [layoutObj]);
6639
+ this.alignObjectsY(ctx, [layoutObj]);
6613
6640
  }
6614
6641
  });
6615
6642
  }
6616
6643
  }
6617
6644
  };
6618
- var ObjStaff = class extends ObjNotationLine4 {
6645
+ var ObjStaff = class extends ObjNotationLine5 {
6619
6646
  constructor(row, staffConfig, id) {
6620
6647
  super(row);
6621
6648
  this.row = row;
@@ -6634,11 +6661,11 @@ var ObjStaff = class extends ObjNotationLine4 {
6634
6661
  __publicField(this, "mi");
6635
6662
  const getDiatonicId = (noteName, isOctaveDown) => Note8.getNote(noteName).diatonicId - (isOctaveDown ? 7 : 0);
6636
6663
  if (staffConfig.clef === "G" /* G */) {
6637
- this.clefImageAsset = 0 /* TrebleClefPng */;
6664
+ this.clefImageAsset = 0 /* G_Clef */;
6638
6665
  this.clefLineDiatonicId = getDiatonicId("G4", staffConfig.isOctaveDown === true);
6639
6666
  this.middleLineDiatonicId = this.clefLineDiatonicId + 2;
6640
6667
  } else if (staffConfig.clef === "F" /* F */) {
6641
- this.clefImageAsset = 1 /* BassClefPng */;
6668
+ this.clefImageAsset = 1 /* F_Clef */;
6642
6669
  this.clefLineDiatonicId = getDiatonicId("F3", staffConfig.isOctaveDown === true);
6643
6670
  this.middleLineDiatonicId = this.clefLineDiatonicId - 2;
6644
6671
  } else {
@@ -6660,6 +6687,9 @@ var ObjStaff = class extends ObjNotationLine4 {
6660
6687
  var _a;
6661
6688
  return (_a = this.staffConfig.name) != null ? _a : "";
6662
6689
  }
6690
+ getConfig() {
6691
+ return this.staffConfig;
6692
+ }
6663
6693
  getTopLineY() {
6664
6694
  return this.topLineY;
6665
6695
  }
@@ -6713,7 +6743,7 @@ var ObjStaff = class extends ObjNotationLine4 {
6713
6743
  return diatonicId % 2 !== this.middleLineDiatonicId % 2;
6714
6744
  }
6715
6745
  containsVoiceId(voiceId) {
6716
- return !this.staffConfig.voiceIds || this.staffConfig.voiceIds.includes(voiceId);
6746
+ return Utils13.Is.isUndefined(this.staffConfig.voiceId) || Utils13.Arr.toArray(this.staffConfig.voiceId).includes(voiceId);
6717
6747
  }
6718
6748
  calcTop() {
6719
6749
  let top = this.topLineY;
@@ -6736,16 +6766,16 @@ var ObjStaff = class extends ObjNotationLine4 {
6736
6766
  return bottom;
6737
6767
  }
6738
6768
  pick(x, y) {
6739
- return [this];
6769
+ return this.getRect().contains(x, y) ? [this] : [];
6740
6770
  }
6741
- layoutHeight(renderer) {
6742
- let { unitSize } = renderer;
6771
+ layoutHeight(ctx) {
6772
+ let { unitSize } = ctx;
6743
6773
  let h = unitSize * DocumentSettings.StaffHeight;
6744
6774
  this.topLineY = -h / 2;
6745
6775
  this.bottomLineY = h / 2;
6746
6776
  this.rect = new DivRect(0, 0, this.topLineY, this.bottomLineY);
6747
6777
  }
6748
- layoutWidth(renderer) {
6778
+ layoutWidth(ctx) {
6749
6779
  this.rect.left = this.row.getRect().left;
6750
6780
  this.rect.right = this.row.getRect().right;
6751
6781
  }
@@ -6761,10 +6791,10 @@ var ObjStaff = class extends ObjNotationLine4 {
6761
6791
  });
6762
6792
  this.rect.offsetInPlace(dx, dy);
6763
6793
  }
6764
- draw(renderer) {
6794
+ draw(ctx) {
6765
6795
  }
6766
6796
  };
6767
- var ObjTab = class extends ObjNotationLine4 {
6797
+ var ObjTab = class extends ObjNotationLine5 {
6768
6798
  constructor(row, tabConfig, id) {
6769
6799
  super(row);
6770
6800
  this.row = row;
@@ -6794,6 +6824,9 @@ var ObjTab = class extends ObjNotationLine4 {
6794
6824
  var _a;
6795
6825
  return (_a = this.tabConfig.name) != null ? _a : "";
6796
6826
  }
6827
+ getConfig() {
6828
+ return this.tabConfig;
6829
+ }
6797
6830
  getTuningName() {
6798
6831
  return this.tuningName;
6799
6832
  }
@@ -6823,7 +6856,7 @@ var ObjTab = class extends ObjNotationLine4 {
6823
6856
  return this.bottom;
6824
6857
  }
6825
6858
  containsVoiceId(voiceId) {
6826
- return !this.tabConfig.voiceIds || this.tabConfig.voiceIds.includes(voiceId);
6859
+ return Utils13.Is.isUndefined(this.tabConfig.voiceId) || Utils13.Arr.toArray(this.tabConfig.voiceId).includes(voiceId);
6827
6860
  }
6828
6861
  containsDiatonicId(diatonicId) {
6829
6862
  return true;
@@ -6839,16 +6872,16 @@ var ObjTab = class extends ObjNotationLine4 {
6839
6872
  return bottom;
6840
6873
  }
6841
6874
  pick(x, y) {
6842
- return [this];
6875
+ return this.getRect().contains(x, y) ? [this] : [];
6843
6876
  }
6844
- layoutHeight(renderer) {
6845
- let { unitSize } = renderer;
6877
+ layoutHeight(ctx) {
6878
+ let { unitSize } = ctx;
6846
6879
  let h = unitSize * DocumentSettings.TabHeight;
6847
6880
  this.top = -h / 2;
6848
6881
  this.bottom = h / 2;
6849
6882
  this.rect = new DivRect(0, 0, this.top, this.bottom);
6850
6883
  }
6851
- layoutWidth(renderer) {
6884
+ layoutWidth(ctx) {
6852
6885
  this.rect.left = this.row.getRect().left;
6853
6886
  this.rect.right = this.row.getRect().right;
6854
6887
  }
@@ -6864,12 +6897,13 @@ var ObjTab = class extends ObjNotationLine4 {
6864
6897
  });
6865
6898
  this.rect.offsetInPlace(dx, dy);
6866
6899
  }
6867
- draw(renderer) {
6900
+ draw(ctx) {
6868
6901
  }
6869
6902
  };
6870
6903
 
6871
6904
  // src/score/engine/obj-score-row.ts
6872
6905
  import { MusicError as MusicError16, MusicErrorType as MusicErrorType16 } from "@tspro/web-music-score/core";
6906
+ import { Utils as Utils14 } from "@tspro/ts-utils-lib";
6873
6907
  var ObjScoreRow = class extends MusicObject {
6874
6908
  constructor(doc, prevRow, scoreConfig) {
6875
6909
  super(doc);
@@ -6879,14 +6913,30 @@ var ObjScoreRow = class extends MusicObject {
6879
6913
  __publicField(this, "nextRow");
6880
6914
  __publicField(this, "minWidth", 0);
6881
6915
  __publicField(this, "notationLines");
6916
+ __publicField(this, "instrumentLineGroups");
6882
6917
  __publicField(this, "staves");
6883
6918
  __publicField(this, "tabs");
6919
+ __publicField(this, "instrumentNames");
6884
6920
  __publicField(this, "measures", []);
6885
6921
  __publicField(this, "needLayout", true);
6886
6922
  __publicField(this, "mi");
6887
6923
  this.notationLines = this.createNotationLines();
6888
6924
  this.staves = this.notationLines.filter((line) => line instanceof ObjStaff);
6889
6925
  this.tabs = this.notationLines.filter((line) => line instanceof ObjTab);
6926
+ let lineGroups = [];
6927
+ for (let i = 0; i < this.notationLines.length; i++) {
6928
+ let line = this.notationLines[i];
6929
+ let prevGroup = lineGroups[lineGroups.length - 1];
6930
+ if (prevGroup === void 0 || prevGroup[0].getConfig().instrument === void 0 || prevGroup[0].getConfig().instrument !== line.getConfig().instrument) {
6931
+ lineGroups.push([line]);
6932
+ } else {
6933
+ prevGroup.push(line);
6934
+ }
6935
+ }
6936
+ this.instrumentLineGroups = lineGroups;
6937
+ this.instrumentNames = this.instrumentLineGroups.map((lines) => {
6938
+ return lines.length > 0 && Utils14.Is.isNonEmptyString(lines[0].getConfig().instrument) ? new ObjText(this, String(lines[0].getConfig().instrument), 0, 0.5) : void 0;
6939
+ });
6890
6940
  if (this.prevRow) {
6891
6941
  this.prevRow.nextRow = this;
6892
6942
  }
@@ -6910,6 +6960,14 @@ var ObjScoreRow = class extends MusicObject {
6910
6960
  getNotationLines() {
6911
6961
  return this.notationLines;
6912
6962
  }
6963
+ getInstrumentLineGroups() {
6964
+ return this.instrumentLineGroups;
6965
+ }
6966
+ findMatchingLine(line) {
6967
+ return line.row === this ? line : this.notationLines.find(
6968
+ (curLine) => Utils14.Obj.deepEqual(line.row.scoreConfig, curLine.row.scoreConfig) && line.id === curLine.id || Utils14.Is.isNonEmptyString(line.getConfig().name) && line.getConfig().name === curLine.getConfig().name && line.getConfig().type === curLine.getConfig().type
6969
+ );
6970
+ }
6913
6971
  getStaves() {
6914
6972
  return this.staves;
6915
6973
  }
@@ -6948,13 +7006,14 @@ var ObjScoreRow = class extends MusicObject {
6948
7006
  }
6949
7007
  return void 0;
6950
7008
  }
6951
- resetLayoutGroups(renderer) {
6952
- this.notationLines.forEach((line) => line.resetLayoutGroups(renderer));
7009
+ resetLayoutGroups(ctx) {
7010
+ this.notationLines.forEach((line) => line.resetLayoutGroups(ctx));
6953
7011
  }
6954
- layoutLayoutGroups(renderer) {
6955
- this.notationLines.forEach((line) => line.layoutLayoutGroups(renderer));
7012
+ layoutLayoutGroups(ctx) {
7013
+ this.notationLines.forEach((line) => line.layoutLayoutGroups(ctx));
6956
7014
  }
6957
7015
  pick(x, y) {
7016
+ var _a, _b;
6958
7017
  if (!this.getRect().contains(x, y)) {
6959
7018
  return [];
6960
7019
  }
@@ -6964,6 +7023,12 @@ var ObjScoreRow = class extends MusicObject {
6964
7023
  return [this, ...arr];
6965
7024
  }
6966
7025
  }
7026
+ for (let i = 0; i < this.instrumentNames.length; i++) {
7027
+ let arr = (_b = (_a = this.instrumentNames[i]) == null ? void 0 : _a.pick(x, y)) != null ? _b : [];
7028
+ if (arr.length > 0) {
7029
+ return [this, ...arr];
7030
+ }
7031
+ }
6967
7032
  for (let i = 0; i < this.notationLines.length; i++) {
6968
7033
  let arr = this.notationLines[i].pick(x, y);
6969
7034
  if (arr.length > 0) {
@@ -7015,61 +7080,78 @@ var ObjScoreRow = class extends MusicObject {
7015
7080
  getMinWidth() {
7016
7081
  return this.minWidth;
7017
7082
  }
7083
+ solveAutoStemDir(symbols) {
7084
+ if (symbols.length === 0) {
7085
+ return "up" /* Up */;
7086
+ } else {
7087
+ let voiceId = symbols[0].voiceId;
7088
+ let noteGroupDiatonicIds = symbols.filter((sym) => sym instanceof ObjNoteGroup).map((n) => n.setDiatonicId);
7089
+ let restDiatonicIds = symbols.filter((sym) => sym instanceof ObjRest && sym.setDiatonicId !== ObjRest.UndefinedDiatonicId).map((r) => r.setDiatonicId);
7090
+ if (noteGroupDiatonicIds.length === 0 && restDiatonicIds.length === 0) {
7091
+ return "up" /* Up */;
7092
+ }
7093
+ let diatonicIds = noteGroupDiatonicIds.length > 0 ? noteGroupDiatonicIds : restDiatonicIds;
7094
+ let avgDiatonicId = Math.floor(Utils14.Math.avg(...diatonicIds));
7095
+ let staves = this.getStaves().filter((staff) => staff.containsVoiceId(voiceId) && staff.containsDiatonicId(avgDiatonicId));
7096
+ return staves.length > 0 ? avgDiatonicId >= staves[0].middleLineDiatonicId ? "down" /* Down */ : "up" /* Up */ : "up" /* Up */;
7097
+ }
7098
+ }
7099
+ getInstrumentNameWidth(ctx) {
7100
+ return Math.max(0, ...this.instrumentNames.map((obj) => obj ? obj.getRect().width : 0));
7101
+ }
7018
7102
  requestLayout() {
7019
7103
  if (!this.needLayout) {
7020
7104
  this.needLayout = true;
7021
7105
  this.doc.requestLayout();
7022
7106
  }
7023
7107
  }
7024
- layout(renderer) {
7108
+ layout(ctx) {
7025
7109
  if (!this.needLayout) {
7026
7110
  return;
7027
7111
  }
7028
7112
  this.requestRectUpdate();
7113
+ this.instrumentNames.forEach((obj) => obj == null ? void 0 : obj.layout(ctx));
7029
7114
  this.notationLines.forEach((line) => {
7030
7115
  line.removeObjects();
7031
- line.layoutHeight(renderer);
7116
+ line.layoutHeight(ctx);
7032
7117
  });
7033
- this.rect = new DivRect(0, 0, 0, 0);
7034
7118
  this.minWidth = 0;
7035
7119
  this.measures.forEach((m) => {
7036
- m.layout(renderer);
7120
+ m.layout(ctx);
7037
7121
  this.minWidth += m.getMinWidth();
7038
7122
  this.minWidth += m.getPostMeasureBreakWidth();
7039
7123
  });
7040
7124
  }
7041
- layoutWidth(renderer, width) {
7125
+ layoutWidth(ctx, left, right) {
7042
7126
  if (!this.needLayout) {
7043
7127
  return;
7044
7128
  }
7045
- let rowWidth = Math.max(width, this.minWidth);
7046
- this.rect.centerX = this.rect.left + rowWidth / 2;
7047
- this.rect.right = this.rect.left + rowWidth;
7048
- this.notationLines.forEach((line) => line.layoutWidth(renderer));
7049
- let targetColumnsAreaWidth = rowWidth;
7129
+ this.rect = new DivRect(0, right, 0, 0);
7130
+ this.notationLines.forEach((line) => line.layoutWidth(ctx));
7131
+ let targetColumnsAreaWidth = right - left;
7050
7132
  let minColumnsAreaWidth = 0;
7051
7133
  this.measures.forEach((m) => {
7052
7134
  targetColumnsAreaWidth -= m.getSolidAreaWidth() + m.getPostMeasureBreakWidth();
7053
7135
  minColumnsAreaWidth += m.getMinColumnsAreaWidth();
7054
7136
  });
7055
7137
  let columnsAreaScale = targetColumnsAreaWidth / minColumnsAreaWidth;
7056
- let x = 0;
7138
+ let x = this.doc.getInstrumentGroupSize(ctx).braceRight;
7057
7139
  this.measures.forEach((m) => {
7058
7140
  let newMeasureWidth = m.getSolidAreaWidth() + m.getMinColumnsAreaWidth() * columnsAreaScale;
7059
- m.layoutWidth(renderer, newMeasureWidth);
7141
+ m.layoutWidth(ctx, newMeasureWidth);
7060
7142
  let r = m.getRect();
7061
7143
  m.offset(x - r.left, -r.centerY);
7062
7144
  x += r.width;
7063
7145
  x += m.getPostMeasureBreakWidth();
7064
7146
  });
7065
7147
  this.measures.forEach((m) => {
7066
- m.layoutConnectives(renderer);
7067
- m.layoutBeams(renderer);
7148
+ m.layoutConnectives(ctx);
7149
+ m.layoutBeams(ctx);
7068
7150
  });
7069
7151
  }
7070
7152
  updateRect() {
7071
- let left = this.measures.length > 0 ? this.measures[0].getRect().left : 0;
7072
- let right = this.measures.length > 0 ? this.measures[this.measures.length - 1].getRect().right : 0;
7153
+ let left = 0;
7154
+ let right = this.measures.length > 0 ? this.measures[this.measures.length - 1].getRect().right : left;
7073
7155
  let top = this.measures.length > 0 ? Math.min(...this.measures.map((m) => m.getRect().top)) : 0;
7074
7156
  let bottom = this.measures.length > 0 ? Math.max(...this.measures.map((m) => m.getRect().bottom)) : 0;
7075
7157
  this.rect = new DivRect(left, right, top, bottom);
@@ -7077,8 +7159,8 @@ var ObjScoreRow = class extends MusicObject {
7077
7159
  alignStemsToBeams() {
7078
7160
  this.measures.forEach((m) => m.alignStemsToBeams());
7079
7161
  }
7080
- layoutSetNotationLines(renderer) {
7081
- let { unitSize } = renderer;
7162
+ layoutSetNotationLines(ctx) {
7163
+ let { unitSize } = ctx;
7082
7164
  for (let i = 1; i < this.notationLines.length; i++) {
7083
7165
  let prev = this.notationLines[i - 1];
7084
7166
  let cur = this.notationLines[i];
@@ -7102,11 +7184,20 @@ var ObjScoreRow = class extends MusicObject {
7102
7184
  });
7103
7185
  });
7104
7186
  });
7187
+ this.instrumentNames.forEach((obj, i) => {
7188
+ let grp = this.instrumentLineGroups[i];
7189
+ if (obj && grp.length > 0) {
7190
+ obj.offset(
7191
+ -obj.getRect().left,
7192
+ -obj.getRect().centerY + (grp[0].getRect().top + grp[grp.length - 1].getRect().bottom) / 2
7193
+ );
7194
+ }
7195
+ });
7105
7196
  this.alignStemsToBeams();
7106
7197
  this.requestRectUpdate();
7107
7198
  }
7108
- layoutPadding(renderer) {
7109
- let p = renderer.unitSize / 2;
7199
+ layoutPadding(ctx) {
7200
+ let p = ctx.unitSize / 2;
7110
7201
  this.getRect();
7111
7202
  this.rect.left -= p;
7112
7203
  this.rect.right += p;
@@ -7121,24 +7212,38 @@ var ObjScoreRow = class extends MusicObject {
7121
7212
  this.measures.forEach((m) => m.offset(dx, dy));
7122
7213
  this.rect.offsetInPlace(dx, dy);
7123
7214
  this.notationLines.forEach((l) => l.offset(dx, dy));
7215
+ this.instrumentNames.forEach((obj) => obj == null ? void 0 : obj.offset(dx, dy));
7124
7216
  }
7125
- draw(renderer) {
7126
- let ctx = renderer.getCanvasContext();
7127
- if (!ctx) {
7128
- return;
7129
- }
7130
- renderer.drawDebugRect(this.getRect());
7217
+ draw(ctx) {
7218
+ ctx.drawDebugRect(this.getRect());
7131
7219
  ctx.save();
7132
- ctx.rect(this.getRect().left, this.getRect().top, this.getRect().width, this.getRect().height);
7220
+ let { left, top, width, height } = this.getRect();
7221
+ ctx.rect(left, top, width, height);
7133
7222
  ctx.clip();
7134
7223
  if (this.getFirstMeasure() && (this.notationLines.length > 1 || this.notationLines[0] instanceof ObjTab)) {
7135
- let left = this.getFirstMeasure().getStaffLineLeft();
7136
- let top = Math.min(...this.notationLines.map((line) => line.getTopLineY()));
7224
+ let left2 = this.getFirstMeasure().getStaffLineLeft();
7225
+ let top2 = Math.min(...this.notationLines.map((line) => line.getTopLineY()));
7137
7226
  let bottom = Math.max(...this.notationLines.map((line) => line.getBottomLineY()));
7138
- renderer.drawLine(left, top, left, bottom);
7139
- }
7140
- this.measures.forEach((m) => m.draw(renderer));
7141
- this.notationLines.forEach((m) => m.draw(renderer));
7227
+ ctx.color("black").lineWidth(1).strokeLine(left2, top2, left2, bottom);
7228
+ }
7229
+ this.measures.forEach((m) => m.draw(ctx));
7230
+ this.notationLines.forEach((m) => m.draw(ctx));
7231
+ let grpSize = this.doc.getInstrumentGroupSize(ctx);
7232
+ this.instrumentNames.forEach((obj, i) => {
7233
+ let grp = this.instrumentLineGroups[i];
7234
+ if (grp.length > 1) {
7235
+ let r = new DivRect(
7236
+ grpSize.braceLeft,
7237
+ grpSize.braceRight,
7238
+ grp[0].getTopLineY(),
7239
+ grp[grp.length - 1].getBottomLineY()
7240
+ );
7241
+ ctx.color("brack").lineWidth(1).drawBrace(r, "left");
7242
+ }
7243
+ if (obj) {
7244
+ obj.draw(ctx);
7245
+ }
7246
+ });
7142
7247
  ctx.restore();
7143
7248
  }
7144
7249
  };
@@ -7186,24 +7291,24 @@ var ObjHeader = class extends MusicObject {
7186
7291
  }
7187
7292
  return [this];
7188
7293
  }
7189
- layoutWidth(renderer, width) {
7294
+ layoutWidth(ctx, left, right) {
7190
7295
  let top = 0;
7191
- this.rect = new DivRect(0, width, 0, 0);
7296
+ this.rect = new DivRect(left, right, 0, 0);
7192
7297
  if (this.titleText) {
7193
- this.titleText.layout(renderer);
7194
- this.titleText.offset(width / 2, top);
7298
+ this.titleText.layout(ctx);
7299
+ this.titleText.offset((left + right) / 2, top);
7195
7300
  top += this.titleText.getRect().height;
7196
7301
  this.rect.expandInPlace(this.titleText.getRect());
7197
7302
  }
7198
7303
  if (this.composerText) {
7199
- this.composerText.layout(renderer);
7200
- this.composerText.offset(width, top);
7304
+ this.composerText.layout(ctx);
7305
+ this.composerText.offset(right, top);
7201
7306
  top += this.composerText.getRect().height;
7202
7307
  this.rect.expandInPlace(this.composerText.getRect());
7203
7308
  }
7204
7309
  if (this.arrangerText) {
7205
- this.arrangerText.layout(renderer);
7206
- this.arrangerText.offset(width, top);
7310
+ this.arrangerText.layout(ctx);
7311
+ this.arrangerText.offset(right, top);
7207
7312
  top += this.arrangerText.getRect().height;
7208
7313
  this.rect.expandInPlace(this.arrangerText.getRect());
7209
7314
  }
@@ -7220,27 +7325,27 @@ var ObjHeader = class extends MusicObject {
7220
7325
  }
7221
7326
  this.rect.offsetInPlace(dx, dy);
7222
7327
  }
7223
- draw(renderer) {
7328
+ draw(ctx) {
7224
7329
  if (this.titleText) {
7225
- this.titleText.draw(renderer);
7330
+ this.titleText.draw(ctx);
7226
7331
  }
7227
7332
  if (this.composerText) {
7228
- this.composerText.draw(renderer);
7333
+ this.composerText.draw(ctx);
7229
7334
  }
7230
7335
  if (this.arrangerText) {
7231
- this.arrangerText.draw(renderer);
7336
+ this.arrangerText.draw(ctx);
7232
7337
  }
7233
7338
  }
7234
7339
  };
7235
7340
 
7236
7341
  // src/score/engine/obj-document.ts
7237
- import { Utils as Utils14 } from "@tspro/ts-utils-lib";
7342
+ import { Utils as Utils15 } from "@tspro/ts-utils-lib";
7238
7343
  import { MusicError as MusicError17, MusicErrorType as MusicErrorType17 } from "@tspro/web-music-score/core";
7239
7344
  var ObjDocument = class extends MusicObject {
7240
7345
  constructor() {
7241
7346
  super(void 0);
7242
7347
  __publicField(this, "needLayout", true);
7243
- __publicField(this, "renderer");
7348
+ __publicField(this, "ctx");
7244
7349
  __publicField(this, "rows", []);
7245
7350
  __publicField(this, "measures", []);
7246
7351
  __publicField(this, "measuresPerRow", Infinity);
@@ -7256,7 +7361,7 @@ var ObjDocument = class extends MusicObject {
7256
7361
  return this.mi;
7257
7362
  }
7258
7363
  setScoreConfiguration(config) {
7259
- if (Utils14.Is.isEnumValue(config, StaffPreset)) {
7364
+ if (Utils15.Is.isEnumValue(config, StaffPreset)) {
7260
7365
  switch (config) {
7261
7366
  default:
7262
7367
  case "treble" /* Treble */:
@@ -7284,7 +7389,7 @@ var ObjDocument = class extends MusicObject {
7284
7389
  ];
7285
7390
  break;
7286
7391
  }
7287
- } else if (Utils14.Is.isArray(config)) {
7392
+ } else if (Utils15.Is.isArray(config)) {
7288
7393
  this.curScoreConfig = config;
7289
7394
  } else {
7290
7395
  this.curScoreConfig = [config];
@@ -7345,17 +7450,17 @@ var ObjDocument = class extends MusicObject {
7345
7450
  addConnectiveProps(connectiveProps) {
7346
7451
  this.allConnectiveProps.push(connectiveProps);
7347
7452
  }
7348
- setRenderer(renderer) {
7349
- if (this.renderer === renderer) {
7453
+ setRenderContext(ctx) {
7454
+ if (this.ctx === ctx) {
7350
7455
  return;
7351
7456
  }
7352
- let prevRenderer = this.renderer;
7353
- this.renderer = renderer;
7354
- if (prevRenderer) {
7355
- prevRenderer.setDocument(void 0);
7457
+ let prevCtx = this.ctx;
7458
+ this.ctx = ctx;
7459
+ if (prevCtx) {
7460
+ prevCtx.setDocument(void 0);
7356
7461
  }
7357
- if (renderer) {
7358
- renderer.setDocument(this.mi);
7462
+ if (ctx) {
7463
+ ctx.setDocument(this.mi);
7359
7464
  }
7360
7465
  this.requestFullLayout();
7361
7466
  }
@@ -7404,13 +7509,13 @@ var ObjDocument = class extends MusicObject {
7404
7509
  requestNewRow() {
7405
7510
  this.newRowRequested = true;
7406
7511
  }
7407
- addMeasure() {
7512
+ addMeasure(measureOptions) {
7408
7513
  let lastRow = this.rows[this.rows.length - 1];
7409
7514
  if (!lastRow || this.newRowRequested && lastRow.getMeasures().length > 0 || lastRow.getMeasures().length >= this.measuresPerRow) {
7410
7515
  lastRow = this.addNewRow(lastRow);
7411
7516
  this.newRowRequested = false;
7412
7517
  }
7413
- let measure = new ObjMeasure2(lastRow);
7518
+ let measure = new ObjMeasure2(lastRow, measureOptions);
7414
7519
  this.measures.push(measure);
7415
7520
  lastRow.addMeasure(measure);
7416
7521
  this.requestLayout();
@@ -7441,9 +7546,21 @@ var ObjDocument = class extends MusicObject {
7441
7546
  this.measures.forEach((m) => m.resetPassCount());
7442
7547
  }
7443
7548
  updateCursorRect(cursorRect) {
7444
- if (this.renderer) {
7445
- this.renderer.updateCursorRect(cursorRect);
7446
- }
7549
+ if (this.ctx) {
7550
+ this.ctx.updateCursorRect(cursorRect);
7551
+ }
7552
+ }
7553
+ getInstrumentGroupSize(ctx) {
7554
+ let nameWidth = Math.max(0, ...this.rows.map((row) => row.getInstrumentNameWidth(ctx)));
7555
+ let hasName = nameWidth > 0;
7556
+ let padding = hasName ? ctx.unitSize : 0;
7557
+ let braceWidth = hasName ? ctx.unitSize * 5 : 0;
7558
+ return {
7559
+ nameLeft: 0,
7560
+ nameRight: nameWidth,
7561
+ braceLeft: nameWidth + padding,
7562
+ braceRight: nameWidth + padding + braceWidth + padding
7563
+ };
7447
7564
  }
7448
7565
  requestLayout() {
7449
7566
  this.needLayout = true;
@@ -7457,31 +7574,34 @@ var ObjDocument = class extends MusicObject {
7457
7574
  this.requestLayout();
7458
7575
  }
7459
7576
  layout() {
7577
+ var _a;
7460
7578
  if (!this.needLayout) {
7461
7579
  return;
7462
7580
  }
7463
- const { renderer } = this;
7464
- if (!renderer) {
7581
+ const { ctx } = this;
7582
+ if (!ctx) {
7465
7583
  return;
7466
7584
  }
7467
- let { unitSize } = renderer;
7585
+ let { unitSize } = ctx;
7468
7586
  this.forEachMeasure((m) => m.createBeams());
7587
+ (_a = this.getFirstMeasure()) == null ? void 0 : _a.updateRunningArguments();
7469
7588
  this.forEachMeasure((m) => m.createExtensions());
7470
7589
  this.allConnectiveProps.forEach((props) => props.removeConnectives());
7471
7590
  this.allConnectiveProps.forEach((props) => props.createConnectives());
7472
- this.rows.forEach((row) => row.resetLayoutGroups(renderer));
7473
- this.rows.forEach((row) => row.layout(renderer));
7474
- let rowWidth = Math.max(
7591
+ this.rows.forEach((row) => row.resetLayoutGroups(ctx));
7592
+ this.rows.forEach((row) => row.layout(ctx));
7593
+ let left = this.getInstrumentGroupSize(ctx).braceRight;
7594
+ let right = Math.max(
7475
7595
  DocumentSettings.DocumentMinWidth * unitSize,
7476
7596
  ...this.rows.map((row) => 1.4 * row.getMinWidth())
7477
7597
  );
7478
- this.rows.forEach((row) => row.layoutWidth(renderer, rowWidth));
7479
- this.rows.forEach((row) => row.layoutLayoutGroups(renderer));
7480
- this.rows.forEach((row) => row.layoutSetNotationLines(renderer));
7481
- this.rows.forEach((row) => row.layoutPadding(renderer));
7598
+ this.rows.forEach((row) => row.layoutWidth(ctx, left, right));
7599
+ this.rows.forEach((row) => row.layoutLayoutGroups(ctx));
7600
+ this.rows.forEach((row) => row.layoutSetNotationLines(ctx));
7601
+ this.rows.forEach((row) => row.layoutPadding(ctx));
7482
7602
  this.rect = new DivRect();
7483
7603
  if (this.header) {
7484
- this.header.layoutWidth(renderer, rowWidth);
7604
+ this.header.layoutWidth(ctx, left, right);
7485
7605
  this.rect.expandInPlace(this.header.getRect());
7486
7606
  }
7487
7607
  this.rows.forEach((row) => {
@@ -7492,13 +7612,13 @@ var ObjDocument = class extends MusicObject {
7492
7612
  this.needLayout = false;
7493
7613
  }
7494
7614
  drawContent() {
7495
- const { renderer } = this;
7496
- if (!renderer) {
7615
+ const { ctx } = this;
7616
+ if (!ctx) {
7497
7617
  return;
7498
7618
  }
7499
- this.rows.forEach((row) => row.draw(renderer));
7619
+ this.rows.forEach((row) => row.draw(ctx));
7500
7620
  if (this.header) {
7501
- this.header.draw(renderer);
7621
+ this.header.draw(ctx);
7502
7622
  }
7503
7623
  }
7504
7624
  pickStaffPosAt(x, y) {
@@ -7541,7 +7661,7 @@ var ObjDocument = class extends MusicObject {
7541
7661
  };
7542
7662
 
7543
7663
  // src/score/pub/document-builder.ts
7544
- import { BeamGrouping, KeySignature as KeySignature3, Note as Note10, NoteLength as NoteLength9, RhythmProps as RhythmProps6, Scale as Scale2, ScaleType, SymbolSet as SymbolSet2, TimeSignature as TimeSignature2, TimeSignatures, TuningNameList, validateNoteLength as validateNoteLength4, validateTupletRatio } from "@tspro/web-music-score/theory";
7664
+ import { BeamGrouping, KeySignature as KeySignature3, Note as Note10, NoteLength as NoteLength8, RhythmProps as RhythmProps6, Scale as Scale2, ScaleType, SymbolSet as SymbolSet2, TimeSignature as TimeSignature2, TimeSignatures, TuningNameList, validateNoteLength as validateNoteLength3, validateTupletRatio } from "@tspro/web-music-score/theory";
7545
7665
  import { MusicError as MusicError18, MusicErrorType as MusicErrorType18 } from "@tspro/web-music-score/core";
7546
7666
  function assertArg(condition, argName, argValue) {
7547
7667
  if (!condition) {
@@ -7557,70 +7677,89 @@ function isNote(note) {
7557
7677
  }
7558
7678
  }
7559
7679
  function isVoiceId(value) {
7560
- return Utils15.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
7680
+ return Utils16.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
7561
7681
  }
7562
7682
  function isStringNumber(value) {
7563
- return Utils15.Is.isNumber(value) && getStringNumbers().indexOf(value) >= 0;
7683
+ return Utils16.Is.isNumber(value) && getStringNumbers().indexOf(value) >= 0;
7564
7684
  }
7565
7685
  function isVerseNumber(value) {
7566
- return Utils15.Is.isNumber(value) && getVerseNumbers().indexOf(value) >= 0;
7686
+ return Utils16.Is.isNumber(value) && getVerseNumbers().indexOf(value) >= 0;
7567
7687
  }
7568
7688
  function assertBaseConfig(baseConfig) {
7569
- assertArg(Utils15.Is.isObject(baseConfig), "baseConfig", baseConfig);
7570
- assertArg(Utils15.Is.isStringOrUndefined(baseConfig.name), "baseConfig.name", baseConfig.name);
7571
- assertArg(Utils15.Is.isUndefined(baseConfig.voiceIds) || Utils15.Is.isArray(baseConfig.voiceIds) && baseConfig.voiceIds.every((voiceId) => Utils15.Is.isNumber(voiceId)), "baseConfig.voiceIds", baseConfig.voiceIds);
7689
+ var _a;
7690
+ assertArg(Utils16.Is.isObject(baseConfig), "baseConfig", baseConfig);
7691
+ assertArg(Utils16.Is.isStringOrUndefined(baseConfig.name), "baseConfig.name", baseConfig.name);
7692
+ assertArg(Utils16.Is.isUndefined(baseConfig.voiceId) || isVoiceId(baseConfig.voiceId) || Utils16.Is.isArray(baseConfig.voiceId) && baseConfig.voiceId.every((voiceId) => isVoiceId(voiceId)), "baseConfig.voiceId", baseConfig.voiceId);
7693
+ if (!Utils16.Is.isUndefined(baseConfig.voiceIds)) {
7694
+ assertArg(isVoiceId(baseConfig.voiceIds) || Utils16.Is.isArray(baseConfig.voiceIds) && baseConfig.voiceIds.every((voiceId) => isVoiceId(voiceId)), "baseConfig.voiceIds", baseConfig.voiceIds);
7695
+ console.warn(`Staff/tab config property 'voiceIds' is deprecated, use 'voiceId' instead.`);
7696
+ let arr = Utils16.Arr.toArray((_a = baseConfig.voiceId) != null ? _a : []);
7697
+ Utils16.Arr.toArray(baseConfig.voiceIds).forEach((voiceId) => arr.push(voiceId));
7698
+ baseConfig.voiceId = arr;
7699
+ }
7700
+ if (Utils16.Is.isArray(baseConfig.voiceId)) {
7701
+ baseConfig.voiceId = Utils16.Arr.removeDuplicates(baseConfig.voiceId);
7702
+ }
7703
+ assertArg(Utils16.Is.isStringOrUndefined(baseConfig.instrument), "baseConfig.instrument", baseConfig.instrument);
7572
7704
  }
7573
7705
  function assertStaffConfig(staffConfig) {
7574
7706
  assertBaseConfig(staffConfig);
7575
- assertArg(Utils15.Is.isObject(staffConfig), "staffConfig", staffConfig);
7707
+ assertArg(Utils16.Is.isObject(staffConfig), "staffConfig", staffConfig);
7576
7708
  assertArg(staffConfig.type === "staff", "staffConfig.type", staffConfig.type);
7577
- assertArg(Utils15.Is.isEnumValue(staffConfig.clef, Clef), "staffConfig.clef", staffConfig.clef);
7578
- assertArg(Utils15.Is.isBooleanOrUndefined(staffConfig.isOctaveDown), "staffConfig.isOctaveDown", staffConfig.isOctaveDown);
7579
- assertArg(Utils15.Is.isUndefined(staffConfig.minNote) || isNote(staffConfig.minNote), "staffConfig.minNote", staffConfig.minNote);
7580
- assertArg(Utils15.Is.isUndefined(staffConfig.maxNote) || isNote(staffConfig.maxNote), "staffConfig.maxNote", staffConfig.maxNote);
7581
- assertArg(Utils15.Is.isStringOrUndefined(staffConfig.grandId), "staffConfig.grandId", staffConfig.grandId);
7582
- assertArg(Utils15.Is.isBooleanOrUndefined(staffConfig.isGrand), "staffConfig.isGrand", staffConfig.isGrand);
7709
+ assertArg(Utils16.Is.isEnumValue(staffConfig.clef, Clef), "staffConfig.clef", staffConfig.clef);
7710
+ assertArg(Utils16.Is.isBooleanOrUndefined(staffConfig.isOctaveDown), "staffConfig.isOctaveDown", staffConfig.isOctaveDown);
7711
+ assertArg(Utils16.Is.isUndefined(staffConfig.minNote) || isNote(staffConfig.minNote), "staffConfig.minNote", staffConfig.minNote);
7712
+ assertArg(Utils16.Is.isUndefined(staffConfig.maxNote) || isNote(staffConfig.maxNote), "staffConfig.maxNote", staffConfig.maxNote);
7713
+ assertArg(Utils16.Is.isStringOrUndefined(staffConfig.grandId), "staffConfig.grandId", staffConfig.grandId);
7714
+ assertArg(Utils16.Is.isBooleanOrUndefined(staffConfig.isGrand), "staffConfig.isGrand", staffConfig.isGrand);
7715
+ if (!Utils16.Is.isUndefined(staffConfig.isGrand)) {
7716
+ console.warn(`Staff config property 'isGrand' is deprecated, use 'grandId' instead.`);
7717
+ }
7583
7718
  }
7584
7719
  function assertTabConfig(tabConfig) {
7585
7720
  assertBaseConfig(tabConfig);
7586
- assertArg(Utils15.Is.isObject(tabConfig), "tabConfig", tabConfig);
7721
+ assertArg(Utils16.Is.isObject(tabConfig), "tabConfig", tabConfig);
7587
7722
  assertArg(tabConfig.type === "tab", "tabConfig.type", tabConfig.type);
7588
- if (Utils15.Is.isString(tabConfig.tuning)) {
7723
+ if (Utils16.Is.isString(tabConfig.tuning)) {
7589
7724
  assertArg(TuningNameList.includes(tabConfig.tuning), "tabConfig.tuning", tabConfig.tuning);
7590
- } else if (Utils15.Is.isArray(tabConfig.tuning)) {
7725
+ } else if (Utils16.Is.isArray(tabConfig.tuning)) {
7591
7726
  assertArg(tabConfig.tuning.length === getStringNumbers().length && tabConfig.tuning.every((s) => isNote(s)), "tabConfig.tuning", tabConfig.tuning);
7592
7727
  }
7593
7728
  }
7594
7729
  function assertNoteOptions(noteOptions) {
7595
- assertArg(Utils15.Is.isObject(noteOptions), "noteOptions", noteOptions);
7596
- assertArg(Utils15.Is.isBooleanOrUndefined(noteOptions.dotted) || Utils15.Is.isIntegerGte(noteOptions.dotted, 0), "noteOptions.dotted", noteOptions.dotted);
7597
- assertArg(Utils15.Is.isEnumValueOrUndefined(noteOptions.stem, Stem), "noteOptions.stem", noteOptions.stem);
7598
- assertArg(Utils15.Is.isStringOrUndefined(noteOptions.color), "noteOptions.color", noteOptions.color);
7599
- assertArg(Utils15.Is.isBooleanOrUndefined(noteOptions.arpeggio) || Utils15.Is.isEnumValue(noteOptions.arpeggio, Arpeggio), "noteOptions.arpeggio", noteOptions.arpeggio);
7600
- assertArg(Utils15.Is.isBooleanOrUndefined(noteOptions.staccato), "noteOptions.staccato", noteOptions.staccato);
7601
- assertArg(Utils15.Is.isBooleanOrUndefined(noteOptions.diamond), "noteOptions.diamond", noteOptions.diamond);
7602
- assertArg(Utils15.Is.isBooleanOrUndefined(noteOptions.triplet), "noteOptions.triplet", noteOptions.triplet);
7603
- assertArg(Utils15.Is.isUndefined(noteOptions.string) || isStringNumber(noteOptions.string) || Utils15.Is.isNonEmptyArray(noteOptions.string) && noteOptions.string.every((string) => isStringNumber(string)), "noteOptions.string", noteOptions.string);
7604
- assertArg(Utils15.Is.isUndefined(noteOptions.tieSpan), 'NoteOptions.tieSpan was removed. Use addConnective("tie", tieSpan)', "");
7605
- assertArg(Utils15.Is.isUndefined(noteOptions.slurSpan), 'NoteOptions.slurSpan was removed. Use addConnective("slur", slurSpan)', "");
7730
+ assertArg(Utils16.Is.isObject(noteOptions), "noteOptions", noteOptions);
7731
+ assertArg(Utils16.Is.isBooleanOrUndefined(noteOptions.dotted) || Utils16.Is.isIntegerGte(noteOptions.dotted, 0), "noteOptions.dotted", noteOptions.dotted);
7732
+ assertArg(Utils16.Is.isEnumValueOrUndefined(noteOptions.stem, Stem), "noteOptions.stem", noteOptions.stem);
7733
+ assertArg(Utils16.Is.isStringOrUndefined(noteOptions.color), "noteOptions.color", noteOptions.color);
7734
+ assertArg(Utils16.Is.isBooleanOrUndefined(noteOptions.arpeggio) || Utils16.Is.isEnumValue(noteOptions.arpeggio, Arpeggio), "noteOptions.arpeggio", noteOptions.arpeggio);
7735
+ assertArg(Utils16.Is.isBooleanOrUndefined(noteOptions.staccato), "noteOptions.staccato", noteOptions.staccato);
7736
+ assertArg(Utils16.Is.isBooleanOrUndefined(noteOptions.diamond), "noteOptions.diamond", noteOptions.diamond);
7737
+ assertArg(Utils16.Is.isBooleanOrUndefined(noteOptions.triplet), "noteOptions.triplet", noteOptions.triplet);
7738
+ assertArg(Utils16.Is.isUndefined(noteOptions.string) || isStringNumber(noteOptions.string) || Utils16.Is.isNonEmptyArray(noteOptions.string) && noteOptions.string.every((string) => isStringNumber(string)), "noteOptions.string", noteOptions.string);
7739
+ assertArg(Utils16.Is.isUndefined(noteOptions.tieSpan), 'NoteOptions.tieSpan was removed. Use addConnective("tie", tieSpan)', "");
7740
+ assertArg(Utils16.Is.isUndefined(noteOptions.slurSpan), 'NoteOptions.slurSpan was removed. Use addConnective("slur", slurSpan)', "");
7606
7741
  }
7607
7742
  function assertRestOptions(restOptions) {
7608
- assertArg(Utils15.Is.isObject(restOptions), "restOptions", restOptions);
7609
- assertArg(Utils15.Is.isBooleanOrUndefined(restOptions.dotted) || Utils15.Is.isIntegerGte(restOptions.dotted, 0), "restOptions.dotted", restOptions.dotted);
7610
- assertArg(Utils15.Is.isStringOrUndefined(restOptions.staffPos) || Utils15.Is.isInteger(restOptions.staffPos) || restOptions.staffPos instanceof Note10, "restOptions.staffPos", restOptions.staffPos);
7611
- assertArg(Utils15.Is.isStringOrUndefined(restOptions.color), "restOptions.color", restOptions.color);
7612
- assertArg(Utils15.Is.isBooleanOrUndefined(restOptions.hide), "restOptions.hide", restOptions.hide);
7613
- assertArg(Utils15.Is.isBooleanOrUndefined(restOptions.triplet), "restOptions.triplet", restOptions.triplet);
7743
+ assertArg(Utils16.Is.isObject(restOptions), "restOptions", restOptions);
7744
+ assertArg(Utils16.Is.isBooleanOrUndefined(restOptions.dotted) || Utils16.Is.isIntegerGte(restOptions.dotted, 0), "restOptions.dotted", restOptions.dotted);
7745
+ assertArg(Utils16.Is.isStringOrUndefined(restOptions.staffPos) || Utils16.Is.isInteger(restOptions.staffPos) || restOptions.staffPos instanceof Note10, "restOptions.staffPos", restOptions.staffPos);
7746
+ assertArg(Utils16.Is.isStringOrUndefined(restOptions.color), "restOptions.color", restOptions.color);
7747
+ assertArg(Utils16.Is.isBooleanOrUndefined(restOptions.hide), "restOptions.hide", restOptions.hide);
7748
+ assertArg(Utils16.Is.isBooleanOrUndefined(restOptions.triplet), "restOptions.triplet", restOptions.triplet);
7614
7749
  }
7615
7750
  function assertLyricsOptions(lyricsOptions) {
7616
- assertArg(Utils15.Is.isObject(lyricsOptions), "lyricsOptions", lyricsOptions);
7617
- assertArg(Utils15.Is.isEnumValueOrUndefined(lyricsOptions.align, LyricsAlign), "lyricsOptions.align", lyricsOptions.align);
7618
- assertArg(Utils15.Is.isEnumValueOrUndefined(lyricsOptions.hyphen, LyricsHyphen), "lyricsOptions.hyphen", lyricsOptions.hyphen);
7751
+ assertArg(Utils16.Is.isObject(lyricsOptions), "lyricsOptions", lyricsOptions);
7752
+ assertArg(Utils16.Is.isEnumValueOrUndefined(lyricsOptions.align, LyricsAlign), "lyricsOptions.align", lyricsOptions.align);
7753
+ assertArg(Utils16.Is.isEnumValueOrUndefined(lyricsOptions.hyphen, LyricsHyphen), "lyricsOptions.hyphen", lyricsOptions.hyphen);
7754
+ }
7755
+ function assertMeasureOptions(measureOptions) {
7756
+ assertArg(Utils16.Is.isObject(measureOptions), "measureOptions", measureOptions);
7757
+ assertArg(Utils16.Is.isBooleanOrUndefined(measureOptions.showNumber), "measureOptions.showNumber", measureOptions.showNumber);
7619
7758
  }
7620
7759
  function assertStaffTabOrGRoups(staffTabOrGroups) {
7621
7760
  assertArg(
7622
- Utils15.Is.isStringOrUndefined(staffTabOrGroups) || Utils15.Is.isIntegerGte(staffTabOrGroups, 0) || Utils15.Is.isNonEmptyArray(staffTabOrGroups) && staffTabOrGroups.every(
7623
- (staffTabOrGroup) => Utils15.Is.isString(staffTabOrGroup) || Utils15.Is.isIntegerGte(staffTabOrGroup, 0)
7761
+ Utils16.Is.isStringOrUndefined(staffTabOrGroups) || Utils16.Is.isIntegerGte(staffTabOrGroups, 0) || Utils16.Is.isNonEmptyArray(staffTabOrGroups) && staffTabOrGroups.every(
7762
+ (staffTabOrGroup) => Utils16.Is.isString(staffTabOrGroup) || Utils16.Is.isIntegerGte(staffTabOrGroup, 0)
7624
7763
  ),
7625
7764
  "staffTabOrGroup",
7626
7765
  staffTabOrGroups
@@ -7628,7 +7767,7 @@ function assertStaffTabOrGRoups(staffTabOrGroups) {
7628
7767
  }
7629
7768
  function isNoteLength(noteLen) {
7630
7769
  try {
7631
- validateNoteLength4(noteLen);
7770
+ validateNoteLength3(noteLen);
7632
7771
  return true;
7633
7772
  } catch (e) {
7634
7773
  return false;
@@ -7642,7 +7781,7 @@ function isTupletRatio(tupletRatio) {
7642
7781
  return false;
7643
7782
  }
7644
7783
  }
7645
- var DocumentBuilder = class {
7784
+ var _DocumentBuilder = class _DocumentBuilder {
7646
7785
  /**
7647
7786
  * Create new document builder instance.
7648
7787
  */
@@ -7652,19 +7791,19 @@ var DocumentBuilder = class {
7652
7791
  this.doc = new ObjDocument();
7653
7792
  }
7654
7793
  setScoreConfiguration(config) {
7655
- if (Utils15.Is.isEnumValue(config, StaffPreset)) {
7794
+ if (Utils16.Is.isEnumValue(config, StaffPreset)) {
7656
7795
  this.doc.setScoreConfiguration(config);
7657
- } else if (Utils15.Is.isObject(config) && config.type === "staff") {
7796
+ } else if (Utils16.Is.isObject(config) && config.type === "staff") {
7658
7797
  assertStaffConfig(config);
7659
7798
  this.doc.setScoreConfiguration(config);
7660
- } else if (Utils15.Is.isObject(config) && config.type === "tab") {
7799
+ } else if (Utils16.Is.isObject(config) && config.type === "tab") {
7661
7800
  assertTabConfig(config);
7662
7801
  this.doc.setScoreConfiguration(config);
7663
- } else if (Utils15.Is.isNonEmptyArray(config)) {
7802
+ } else if (Utils16.Is.isNonEmptyArray(config)) {
7664
7803
  config.forEach((c) => {
7665
- if (Utils15.Is.isObject(c) && c.type === "staff") {
7804
+ if (Utils16.Is.isObject(c) && c.type === "staff") {
7666
7805
  assertStaffConfig(c);
7667
- } else if (Utils15.Is.isObject(c) && c.type === "tab") {
7806
+ } else if (Utils16.Is.isObject(c) && c.type === "tab") {
7668
7807
  assertTabConfig(c);
7669
7808
  } else {
7670
7809
  assertArg(false, "config", config);
@@ -7678,7 +7817,7 @@ var DocumentBuilder = class {
7678
7817
  }
7679
7818
  getMeasure() {
7680
7819
  var _a;
7681
- return (_a = this.doc.getLastMeasure()) != null ? _a : this.doc.addMeasure();
7820
+ return (_a = this.doc.getLastMeasure()) != null ? _a : this.doc.addMeasure(_DocumentBuilder.DefaultMeasureOptions);
7682
7821
  }
7683
7822
  /**
7684
7823
  * Get music document after finished building.
@@ -7695,9 +7834,9 @@ var DocumentBuilder = class {
7695
7834
  * @returns - This document builder instance.
7696
7835
  */
7697
7836
  setHeader(title, composer, arranger) {
7698
- assertArg(Utils15.Is.isStringOrUndefined(title), "title", title);
7699
- assertArg(Utils15.Is.isStringOrUndefined(composer), "composer", composer);
7700
- assertArg(Utils15.Is.isStringOrUndefined(arranger), "arranger", arranger);
7837
+ assertArg(Utils16.Is.isStringOrUndefined(title), "title", title);
7838
+ assertArg(Utils16.Is.isStringOrUndefined(composer), "composer", composer);
7839
+ assertArg(Utils16.Is.isStringOrUndefined(arranger), "arranger", arranger);
7701
7840
  this.doc.setHeader(title, composer, arranger);
7702
7841
  return this;
7703
7842
  }
@@ -7707,29 +7846,32 @@ var DocumentBuilder = class {
7707
7846
  * @returns - This document builder instance.
7708
7847
  */
7709
7848
  setMeasuresPerRow(measuresPerRow) {
7710
- assertArg(Utils15.Is.isIntegerGte(measuresPerRow, 1) || Utils15.Is.isPosInfinity(measuresPerRow), "measuresPerRow", measuresPerRow);
7849
+ assertArg(Utils16.Is.isIntegerGte(measuresPerRow, 1) || Utils16.Is.isPosInfinity(measuresPerRow), "measuresPerRow", measuresPerRow);
7711
7850
  this.doc.setMeasuresPerRow(measuresPerRow);
7712
7851
  return this;
7713
7852
  }
7714
7853
  /**
7715
7854
  * Add new measure.
7855
+ * @param measureOptions - Measure options.
7716
7856
  * @returns - This document builder instance.
7717
7857
  */
7718
- addMeasure() {
7719
- this.doc.addMeasure();
7858
+ addMeasure(measureOptions) {
7859
+ measureOptions != null ? measureOptions : measureOptions = {};
7860
+ assertMeasureOptions(measureOptions);
7861
+ this.doc.addMeasure(measureOptions);
7720
7862
  return this;
7721
7863
  }
7722
7864
  setKeySignature(...args) {
7723
- assertArg(args[0] instanceof Scale2 || args[0] instanceof KeySignature3 || Utils15.Is.isNonEmptyString(args[0]) && (args.length === 1 || Utils15.Is.isEnumValue(args[1], ScaleType)), "keySignature", args);
7865
+ assertArg(args[0] instanceof Scale2 || args[0] instanceof KeySignature3 || Utils16.Is.isNonEmptyString(args[0]) && (args.length === 1 || Utils16.Is.isEnumValue(args[1], ScaleType)), "keySignature", args);
7724
7866
  this.getMeasure().setKeySignature(...args);
7725
7867
  return this;
7726
7868
  }
7727
7869
  setTimeSignature(...args) {
7728
7870
  if (args[0] instanceof TimeSignature2) {
7729
7871
  this.getMeasure().setTimeSignature(args[0]);
7730
- } else if (Utils15.Is.isEnumValue(args[0], TimeSignatures) && Utils15.Is.isEnumValueOrUndefined(args[1], BeamGrouping)) {
7872
+ } else if (Utils16.Is.isEnumValue(args[0], TimeSignatures) && Utils16.Is.isEnumValueOrUndefined(args[1], BeamGrouping)) {
7731
7873
  this.getMeasure().setTimeSignature(new TimeSignature2(args[0], args[1]));
7732
- } else if (Utils15.Is.isIntegerGte(args[0], 1) && Utils15.Is.isIntegerGte(args[1], 1) && Utils15.Is.isEnumValueOrUndefined(args[2], BeamGrouping)) {
7874
+ } else if (Utils16.Is.isIntegerGte(args[0], 1) && Utils16.Is.isIntegerGte(args[1], 1) && Utils16.Is.isEnumValueOrUndefined(args[2], BeamGrouping)) {
7733
7875
  this.getMeasure().setTimeSignature(new TimeSignature2(args[0], args[1], args[2]));
7734
7876
  } else {
7735
7877
  assertArg(false, "timeSignature args", args);
@@ -7737,12 +7879,12 @@ var DocumentBuilder = class {
7737
7879
  return this;
7738
7880
  }
7739
7881
  setTempo(beatsPerMinute, beatLength, dotted) {
7740
- assertArg(Utils15.Is.isIntegerGte(beatsPerMinute, 1), "beatsPerMinute", beatsPerMinute);
7882
+ assertArg(Utils16.Is.isIntegerGte(beatsPerMinute, 1), "beatsPerMinute", beatsPerMinute);
7741
7883
  if (beatLength === void 0) {
7742
- assertArg(Utils15.Is.isUndefined(dotted), "dotted", dotted);
7884
+ assertArg(Utils16.Is.isUndefined(dotted), "dotted", dotted);
7743
7885
  } else {
7744
- assertArg(Utils15.Is.isEnumValue(beatLength, NoteLength9) || isNoteLength(beatLength), "beatLength", beatLength);
7745
- assertArg(Utils15.Is.isBooleanOrUndefined(dotted) || Utils15.Is.isIntegerGte(dotted, 0), "dotted", dotted);
7886
+ assertArg(Utils16.Is.isEnumValue(beatLength, NoteLength8) || isNoteLength(beatLength), "beatLength", beatLength);
7887
+ assertArg(Utils16.Is.isBooleanOrUndefined(dotted) || Utils16.Is.isIntegerGte(dotted, 0), "dotted", dotted);
7746
7888
  }
7747
7889
  this.getMeasure().setTempo(beatsPerMinute, beatLength, dotted);
7748
7890
  return this;
@@ -7758,17 +7900,17 @@ var DocumentBuilder = class {
7758
7900
  addNote(voiceId, note, noteLength, noteOptions) {
7759
7901
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7760
7902
  assertArg(
7761
- note instanceof Note10 || Utils15.Is.isNonEmptyString(note) || Utils15.Is.isArray(note) && note.every((note2) => note2 instanceof Note10 || Utils15.Is.isNonEmptyString(note2)),
7903
+ note instanceof Note10 || Utils16.Is.isNonEmptyString(note) || Utils16.Is.isArray(note) && note.every((note2) => note2 instanceof Note10 || Utils16.Is.isNonEmptyString(note2)),
7762
7904
  "note",
7763
7905
  note
7764
7906
  );
7765
- assertArg(Utils15.Is.isEnumValue(noteLength, NoteLength9) || isNoteLength(noteLength), "noteLength", noteLength);
7907
+ assertArg(Utils16.Is.isEnumValue(noteLength, NoteLength8) || isNoteLength(noteLength), "noteLength", noteLength);
7766
7908
  noteOptions != null ? noteOptions : noteOptions = {};
7767
7909
  assertNoteOptions(noteOptions);
7768
- if (Utils15.Is.isArray(note)) {
7910
+ if (Utils16.Is.isArray(note)) {
7769
7911
  let string = noteOptions.string;
7770
7912
  note.forEach((note2, noteId) => {
7771
- noteOptions.string = Utils15.Is.isArray(string) ? string[noteId] : string;
7913
+ noteOptions.string = Utils16.Is.isArray(string) ? string[noteId] : string;
7772
7914
  this.getMeasure().addNoteGroup(voiceId, [note2], noteLength, noteOptions);
7773
7915
  });
7774
7916
  } else {
@@ -7786,8 +7928,8 @@ var DocumentBuilder = class {
7786
7928
  */
7787
7929
  addChord(voiceId, notes, noteLength, noteOptions) {
7788
7930
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7789
- assertArg(Utils15.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof Note10 || Utils15.Is.isNonEmptyString(note)), "notes", notes);
7790
- assertArg(Utils15.Is.isEnumValue(noteLength, NoteLength9) || isNoteLength(noteLength), "noteLength", noteLength);
7931
+ assertArg(Utils16.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof Note10 || Utils16.Is.isNonEmptyString(note)), "notes", notes);
7932
+ assertArg(Utils16.Is.isEnumValue(noteLength, NoteLength8) || isNoteLength(noteLength), "noteLength", noteLength);
7791
7933
  noteOptions != null ? noteOptions : noteOptions = {};
7792
7934
  assertNoteOptions(noteOptions);
7793
7935
  this.getMeasure().addNoteGroup(voiceId, notes, noteLength, noteOptions);
@@ -7802,7 +7944,7 @@ var DocumentBuilder = class {
7802
7944
  */
7803
7945
  addRest(voiceId, restLength, restOptions) {
7804
7946
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7805
- assertArg(Utils15.Is.isEnumValue(restLength, NoteLength9) || isNoteLength(restLength), "restLength", restLength);
7947
+ assertArg(Utils16.Is.isEnumValue(restLength, NoteLength8) || isNoteLength(restLength), "restLength", restLength);
7806
7948
  restOptions != null ? restOptions : restOptions = {};
7807
7949
  assertRestOptions(restOptions);
7808
7950
  this.getMeasure().addRest(voiceId, restLength, restOptions);
@@ -7825,24 +7967,24 @@ var DocumentBuilder = class {
7825
7967
  */
7826
7968
  addTuplet(voiceId, tupletRatio, tupletBuilder) {
7827
7969
  assertArg(isVoiceId(voiceId), "voiceId", voiceId);
7828
- assertArg(Utils15.Is.isFunction(tupletBuilder), "tupletBuilder", tupletBuilder);
7829
- assertArg(isTupletRatio(tupletRatio) && Utils15.Is.isBooleanOrUndefined(tupletRatio.showRatio), "tupletRatio", tupletRatio);
7970
+ assertArg(Utils16.Is.isFunction(tupletBuilder), "tupletBuilder", tupletBuilder);
7971
+ assertArg(isTupletRatio(tupletRatio) && Utils16.Is.isBooleanOrUndefined(tupletRatio.showRatio), "tupletRatio", tupletRatio);
7830
7972
  let tupletSymbols = [];
7831
7973
  const helper = {
7832
7974
  addNote: (note, noteLength, noteOptions) => {
7833
7975
  assertArg(
7834
- note instanceof Note10 || Utils15.Is.isNonEmptyString(note) || Utils15.Is.isArray(note) && note.every((note2) => note2 instanceof Note10 || Utils15.Is.isNonEmptyString(note2)),
7976
+ note instanceof Note10 || Utils16.Is.isNonEmptyString(note) || Utils16.Is.isArray(note) && note.every((note2) => note2 instanceof Note10 || Utils16.Is.isNonEmptyString(note2)),
7835
7977
  "note",
7836
7978
  note
7837
7979
  );
7838
- assertArg(Utils15.Is.isEnumValue(noteLength, NoteLength9) || isNoteLength(noteLength), "noteLength", noteLength);
7980
+ assertArg(Utils16.Is.isEnumValue(noteLength, NoteLength8) || isNoteLength(noteLength), "noteLength", noteLength);
7839
7981
  noteOptions != null ? noteOptions : noteOptions = {};
7840
7982
  delete noteOptions.triplet;
7841
7983
  assertNoteOptions(noteOptions);
7842
- if (Utils15.Is.isArray(note)) {
7984
+ if (Utils16.Is.isArray(note)) {
7843
7985
  let string = noteOptions.string;
7844
7986
  note.forEach((note2, noteId) => {
7845
- noteOptions.string = Utils15.Is.isArray(string) ? string[noteId] : string;
7987
+ noteOptions.string = Utils16.Is.isArray(string) ? string[noteId] : string;
7846
7988
  let s = this.getMeasure().addNoteGroup(voiceId, [note2], noteLength, noteOptions, tupletRatio);
7847
7989
  tupletSymbols.push(s);
7848
7990
  });
@@ -7853,8 +7995,8 @@ var DocumentBuilder = class {
7853
7995
  return helper;
7854
7996
  },
7855
7997
  addChord: (notes, noteLength, noteOptions) => {
7856
- assertArg(Utils15.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof Note10 || Utils15.Is.isNonEmptyString(note)), "notes", notes);
7857
- assertArg(Utils15.Is.isEnumValue(noteLength, NoteLength9) || isNoteLength(noteLength), "noteLength", noteLength);
7998
+ assertArg(Utils16.Is.isNonEmptyArray(notes) && notes.every((note) => note instanceof Note10 || Utils16.Is.isNonEmptyString(note)), "notes", notes);
7999
+ assertArg(Utils16.Is.isEnumValue(noteLength, NoteLength8) || isNoteLength(noteLength), "noteLength", noteLength);
7858
8000
  noteOptions != null ? noteOptions : noteOptions = {};
7859
8001
  delete noteOptions.triplet;
7860
8002
  assertNoteOptions(noteOptions);
@@ -7863,7 +8005,7 @@ var DocumentBuilder = class {
7863
8005
  return helper;
7864
8006
  },
7865
8007
  addRest: (restLength, restOptions) => {
7866
- assertArg(Utils15.Is.isEnumValue(restLength, NoteLength9) || isNoteLength(restLength), "restLength", restLength);
8008
+ assertArg(Utils16.Is.isEnumValue(restLength, NoteLength8) || isNoteLength(restLength), "restLength", restLength);
7867
8009
  restOptions != null ? restOptions : restOptions = {};
7868
8010
  delete restOptions.triplet;
7869
8011
  assertRestOptions(restOptions);
@@ -7880,8 +8022,8 @@ var DocumentBuilder = class {
7880
8022
  var _a;
7881
8023
  assertStaffTabOrGRoups(staffTabOrGroups);
7882
8024
  assertArg(isVerseNumber(verse), "verse", verse);
7883
- assertArg(Utils15.Is.isEnumValue(lyricsLength, NoteLength9), "lyricsLength", lyricsLength);
7884
- assertArg(Utils15.Is.isString(lyricsText) || Utils15.Is.isArray(lyricsText) && lyricsText.every((text) => Utils15.Is.isString(text)), "lyricsText", lyricsText);
8025
+ assertArg(Utils16.Is.isEnumValue(lyricsLength, NoteLength8), "lyricsLength", lyricsLength);
8026
+ assertArg(Utils16.Is.isString(lyricsText) || Utils16.Is.isArray(lyricsText) && lyricsText.every((text) => Utils16.Is.isString(text)), "lyricsText", lyricsText);
7885
8027
  lyricsOptions != null ? lyricsOptions : lyricsOptions = {};
7886
8028
  assertLyricsOptions(lyricsOptions);
7887
8029
  if (lyricsOptions.align !== void 0) {
@@ -7889,7 +8031,7 @@ var DocumentBuilder = class {
7889
8031
  } else {
7890
8032
  (_a = lyricsOptions.align) != null ? _a : lyricsOptions.align = this.currentLyricsAlign;
7891
8033
  }
7892
- if (Utils15.Is.isArray(lyricsText)) {
8034
+ if (Utils16.Is.isArray(lyricsText)) {
7893
8035
  lyricsText.forEach((text) => this.getMeasure().addLyrics(staffTabOrGroups, verse, lyricsLength, text, lyricsOptions));
7894
8036
  } else {
7895
8037
  this.getMeasure().addLyrics(staffTabOrGroups, verse, lyricsLength, lyricsText, lyricsOptions);
@@ -7921,7 +8063,7 @@ var DocumentBuilder = class {
7921
8063
  }
7922
8064
  addFermataInternal(staffTabOrGroups, fermata) {
7923
8065
  assertStaffTabOrGRoups(staffTabOrGroups);
7924
- assertArg(Utils15.Is.isEnumValue(fermata, Fermata), "fermata", fermata);
8066
+ assertArg(Utils16.Is.isEnumValue(fermata, Fermata), "fermata", fermata);
7925
8067
  this.getMeasure().addFermata(staffTabOrGroups, fermata);
7926
8068
  return this;
7927
8069
  }
@@ -7944,11 +8086,11 @@ var DocumentBuilder = class {
7944
8086
  }
7945
8087
  addNavigationInternal(staffTabOrGroups, navigation, ...args) {
7946
8088
  assertStaffTabOrGRoups(staffTabOrGroups);
7947
- assertArg(Utils15.Is.isEnumValue(navigation, Navigation), "navigation", navigation);
8089
+ assertArg(Utils16.Is.isEnumValue(navigation, Navigation), "navigation", navigation);
7948
8090
  if (navigation === "endRepeat" /* EndRepeat */ && args.length > 0) {
7949
- assertArg(Utils15.Is.isIntegerGte(args[0], 1), "playCount", args[0]);
8091
+ assertArg(Utils16.Is.isIntegerGte(args[0], 1), "playCount", args[0]);
7950
8092
  } else if (navigation === "ending" /* Ending */ && args.length > 0) {
7951
- assertArg(args.every((passage) => Utils15.Is.isIntegerGte(passage, 1)), "passages", args);
8093
+ assertArg(args.every((passage) => Utils16.Is.isIntegerGte(passage, 1)), "passages", args);
7952
8094
  }
7953
8095
  this.getMeasure().addNavigation(staffTabOrGroups, navigation, ...args);
7954
8096
  return this;
@@ -7965,8 +8107,8 @@ var DocumentBuilder = class {
7965
8107
  throw new MusicError18(MusicErrorType18.Score, `Annotation text "${text}" is not known annotation.`);
7966
8108
  }
7967
8109
  assertStaffTabOrGRoups(staffTabOrGroups);
7968
- assertArg(Utils15.Is.isEnumValue(annotation, Annotation), "annotation", annotation);
7969
- assertArg(Utils15.Is.isNonEmptyString(text), "text", text);
8110
+ assertArg(Utils16.Is.isEnumValue(annotation, Annotation), "annotation", annotation);
8111
+ assertArg(Utils16.Is.isNonEmptyString(text), "text", text);
7970
8112
  this.getMeasure().addAnnotation(staffTabOrGroups, annotation, text);
7971
8113
  return this;
7972
8114
  }
@@ -7986,8 +8128,8 @@ var DocumentBuilder = class {
7986
8128
  }
7987
8129
  addLabelInternal(staffTabOrGroups, label, text) {
7988
8130
  assertStaffTabOrGRoups(staffTabOrGroups);
7989
- assertArg(Utils15.Is.isEnumValue(label, Label), "label", label);
7990
- assertArg(Utils15.Is.isNonEmptyString(text), "text", text);
8131
+ assertArg(Utils16.Is.isEnumValue(label, Label), "label", label);
8132
+ assertArg(Utils16.Is.isNonEmptyString(text), "text", text);
7991
8133
  this.getMeasure().addLabel(staffTabOrGroups, label, text);
7992
8134
  return this;
7993
8135
  }
@@ -8011,21 +8153,21 @@ var DocumentBuilder = class {
8011
8153
  return this.addLabelInternal(staffTabOrGroups, label, text);
8012
8154
  }
8013
8155
  addConnective(connective, ...args) {
8014
- assertArg(Utils15.Is.isEnumValue(connective, Connective), "connective", connective);
8156
+ assertArg(Utils16.Is.isEnumValue(connective, Connective), "connective", connective);
8015
8157
  if (connective === "tie" /* Tie */) {
8016
- assertArg(Utils15.Is.isIntegerOrUndefined(args[0]) || Utils15.Is.isEnumValue(args[0], TieType), "tieSpan", args[0]);
8017
- assertArg(Utils15.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
8158
+ assertArg(Utils16.Is.isIntegerOrUndefined(args[0]) || Utils16.Is.isEnumValue(args[0], TieType), "tieSpan", args[0]);
8159
+ assertArg(Utils16.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
8018
8160
  let tieSpan = args[0];
8019
8161
  let noteAnchor = args[1];
8020
8162
  this.getMeasure().addConnective(connective, tieSpan, noteAnchor);
8021
8163
  } else if (connective === "slur" /* Slur */) {
8022
- assertArg(Utils15.Is.isIntegerOrUndefined(args[0]), "slurSpan", args[0]);
8023
- assertArg(Utils15.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
8164
+ assertArg(Utils16.Is.isIntegerOrUndefined(args[0]), "slurSpan", args[0]);
8165
+ assertArg(Utils16.Is.isEnumValueOrUndefined(args[1], NoteAnchor), "noteAnchor", args[1]);
8024
8166
  let slurSpan = args[0];
8025
8167
  let noteAnchor = args[1];
8026
8168
  this.getMeasure().addConnective(connective, slurSpan, noteAnchor);
8027
8169
  } else if (connective === "slide" /* Slide */) {
8028
- assertArg(Utils15.Is.isEnumValueOrUndefined(args[0], NoteAnchor), "noteAnchor", args[0]);
8170
+ assertArg(Utils16.Is.isEnumValueOrUndefined(args[0], NoteAnchor), "noteAnchor", args[0]);
8029
8171
  let noteAnchor = args[0];
8030
8172
  this.getMeasure().addConnective(connective, noteAnchor);
8031
8173
  }
@@ -8044,18 +8186,18 @@ var DocumentBuilder = class {
8044
8186
  * @returns - This document builder instance.
8045
8187
  */
8046
8188
  addExtension(extensionBuilder) {
8047
- assertArg(Utils15.Is.isFunctionOrUndefined(extensionBuilder), "addExtension() has new usage, for e.g. addExtension(ext => ext.measures(2)). Please refer to README or API Reference.", extensionBuilder);
8189
+ assertArg(Utils16.Is.isFunctionOrUndefined(extensionBuilder), "addExtension() has new usage, for e.g. addExtension(ext => ext.measures(2)). Please refer to README or API Reference.", extensionBuilder);
8048
8190
  let ticks = 0;
8049
8191
  let visible = true;
8050
8192
  const helper = {
8051
8193
  notes: (noteLength, noteCount) => {
8052
- assertArg(Utils15.Is.isEnumValue(noteLength, NoteLength9) || isNoteLength(noteLength), "noteLength", noteLength);
8053
- assertArg(Utils15.Is.isUndefined(noteCount) || Utils15.Is.isNumber(noteCount) && noteCount >= 0, "noteCount", noteCount);
8194
+ assertArg(Utils16.Is.isEnumValue(noteLength, NoteLength8) || isNoteLength(noteLength), "noteLength", noteLength);
8195
+ assertArg(Utils16.Is.isUndefined(noteCount) || Utils16.Is.isNumber(noteCount) && noteCount >= 0, "noteCount", noteCount);
8054
8196
  ticks += RhythmProps6.get(noteLength).ticks * (noteCount != null ? noteCount : 1);
8055
8197
  return helper;
8056
8198
  },
8057
8199
  measures: (measureCount) => {
8058
- assertArg(Utils15.Is.isNumber(measureCount) && measureCount >= 1, "measureCount", measureCount);
8200
+ assertArg(Utils16.Is.isNumber(measureCount) && measureCount >= 1, "measureCount", measureCount);
8059
8201
  ticks += this.getMeasure().getMeasureTicks() * measureCount;
8060
8202
  return helper;
8061
8203
  },
@@ -8084,13 +8226,13 @@ var DocumentBuilder = class {
8084
8226
  * @returns - This document builder instance.
8085
8227
  */
8086
8228
  addStaffGroup(groupName, staffsTabsAndGroups, verticalPosition = "auto" /* Auto */) {
8087
- assertArg(Utils15.Is.isNonEmptyString(groupName), "groupName", groupName);
8229
+ assertArg(Utils16.Is.isNonEmptyString(groupName), "groupName", groupName);
8088
8230
  assertArg(
8089
- Utils15.Is.isNonEmptyString(staffsTabsAndGroups) || Utils15.Is.isIntegerGte(staffsTabsAndGroups, 0) || Utils15.Is.isNonEmptyArray(staffsTabsAndGroups) && staffsTabsAndGroups.every((line) => Utils15.Is.isNonEmptyString(line) || Utils15.Is.isIntegerGte(line, 0)),
8231
+ Utils16.Is.isNonEmptyString(staffsTabsAndGroups) || Utils16.Is.isIntegerGte(staffsTabsAndGroups, 0) || Utils16.Is.isNonEmptyArray(staffsTabsAndGroups) && staffsTabsAndGroups.every((line) => Utils16.Is.isNonEmptyString(line) || Utils16.Is.isIntegerGte(line, 0)),
8090
8232
  "staffsTabsAndGroups",
8091
8233
  staffsTabsAndGroups
8092
8234
  );
8093
- assertArg(Utils15.Is.isEnumValue(verticalPosition, VerticalPosition), "verticalPosition", verticalPosition);
8235
+ assertArg(Utils16.Is.isEnumValue(verticalPosition, VerticalPosition), "verticalPosition", verticalPosition);
8094
8236
  this.doc.addStaffGroup(groupName, staffsTabsAndGroups, verticalPosition);
8095
8237
  return this;
8096
8238
  }
@@ -8125,7 +8267,7 @@ var DocumentBuilder = class {
8125
8267
  * @returns - This document builder instance.
8126
8268
  */
8127
8269
  completeRests(voiceId) {
8128
- assertArg(Utils15.Is.isUndefined(voiceId) || isVoiceId(voiceId) || Utils15.Is.isArray(voiceId) && voiceId.every((id) => isVoiceId(id)), "voiceId", voiceId);
8270
+ assertArg(Utils16.Is.isUndefined(voiceId) || isVoiceId(voiceId) || Utils16.Is.isArray(voiceId) && voiceId.every((id) => isVoiceId(id)), "voiceId", voiceId);
8129
8271
  this.getMeasure().completeRests(voiceId);
8130
8272
  return this;
8131
8273
  }
@@ -8137,8 +8279,8 @@ var DocumentBuilder = class {
8137
8279
  * @returns - This document builder instance.
8138
8280
  */
8139
8281
  addScaleArpeggio(scale, bottomNote, numOctaves) {
8140
- assertArg(Utils15.Is.isNonEmptyString(bottomNote), "bottomNote", bottomNote);
8141
- assertArg(Utils15.Is.isIntegerGte(numOctaves, 1), "numOctaves", numOctaves);
8282
+ assertArg(Utils16.Is.isNonEmptyString(bottomNote), "bottomNote", bottomNote);
8283
+ assertArg(Utils16.Is.isIntegerGte(numOctaves, 1), "numOctaves", numOctaves);
8142
8284
  let ts = this.getMeasure().getTimeSignature();
8143
8285
  let notes = scale.getScaleNotes(bottomNote, numOctaves);
8144
8286
  for (let i = 0; i < notes.length; i++) {
@@ -8152,6 +8294,8 @@ var DocumentBuilder = class {
8152
8294
  return this;
8153
8295
  }
8154
8296
  };
8297
+ __publicField(_DocumentBuilder, "DefaultMeasureOptions", {});
8298
+ var DocumentBuilder = _DocumentBuilder;
8155
8299
 
8156
8300
  // src/score/pub/event.ts
8157
8301
  import { MusicError as MusicError19, MusicErrorType as MusicErrorType19 } from "@tspro/web-music-score/core";
@@ -8168,32 +8312,44 @@ var ScoreStaffPosEvent = class extends ScoreEvent {
8168
8312
  /**
8169
8313
  * Create new score staff position event.
8170
8314
  * @param type - Score event type.
8171
- * @param renderer - Renderer.
8315
+ * @param renderContext - Render context.
8172
8316
  * @param scoreRow - Score row.
8173
8317
  * @param diatonicId - Diatonic id that was clicked/entered/left.
8174
8318
  */
8175
- constructor(type, renderer, scoreRow, diatonicId) {
8319
+ constructor(type, renderContext, scoreRow, diatonicId) {
8176
8320
  super(type);
8177
- this.renderer = renderer;
8321
+ this.renderContext = renderContext;
8178
8322
  this.scoreRow = scoreRow;
8179
8323
  this.diatonicId = diatonicId;
8180
8324
  }
8325
+ /**
8326
+ * @deprecated - Provided for legacy support, use renderContext instead.
8327
+ */
8328
+ get renderer() {
8329
+ return this.renderContext;
8330
+ }
8181
8331
  };
8182
8332
  var ScoreObjectEvent = class extends ScoreEvent {
8183
8333
  /**
8184
8334
  * Create new score object event.
8185
8335
  * @param type - Score event type.
8186
- * @param renderer - Renderer.
8336
+ * @param renderContext - Render context.
8187
8337
  * @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.
8188
8338
  */
8189
- constructor(type, renderer, objects) {
8339
+ constructor(type, renderContext, objects) {
8190
8340
  super(type);
8191
- this.renderer = renderer;
8341
+ this.renderContext = renderContext;
8192
8342
  this.objects = objects;
8193
8343
  if (arguments.length === 0) {
8194
8344
  throw new MusicError19(MusicErrorType19.Score, "Empty array in score object event!");
8195
8345
  }
8196
8346
  }
8347
+ /**
8348
+ * @deprecated - Provided for legacy support, use renderContext instead.
8349
+ */
8350
+ get renderer() {
8351
+ return this.renderContext;
8352
+ }
8197
8353
  /** Top object getter. */
8198
8354
  get topObject() {
8199
8355
  return this.objects[this.objects.length - 1];
@@ -8210,10 +8366,10 @@ var ScoreObjectEvent = class extends ScoreEvent {
8210
8366
 
8211
8367
  // src/score/pub/music-interface.ts
8212
8368
  import * as Audio2 from "@tspro/web-music-score/audio";
8213
- import { Utils as Utils17 } from "@tspro/ts-utils-lib";
8369
+ import { Utils as Utils18 } from "@tspro/ts-utils-lib";
8214
8370
 
8215
8371
  // src/score/pub/music-objects.ts
8216
- import { Utils as Utils16 } from "@tspro/ts-utils-lib";
8372
+ import { Utils as Utils17 } from "@tspro/ts-utils-lib";
8217
8373
  import { MusicError as MusicError20, MusicErrorType as MusicErrorType20 } from "@tspro/web-music-score/core";
8218
8374
  function assertArg2(condition, argName, argValue) {
8219
8375
  if (!condition) {
@@ -8221,7 +8377,7 @@ function assertArg2(condition, argName, argValue) {
8221
8377
  }
8222
8378
  }
8223
8379
  function isVoiceId2(value) {
8224
- return Utils16.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
8380
+ return Utils17.Is.isNumber(value) && getVoiceIds().indexOf(value) >= 0;
8225
8381
  }
8226
8382
  function getNotationLine(line) {
8227
8383
  if (line instanceof ObjStaff || line instanceof ObjTab) {
@@ -8397,7 +8553,7 @@ var _MDocument = class _MDocument extends MusicInterface6 {
8397
8553
  * @returns - Player instance.
8398
8554
  */
8399
8555
  play(playStateChangeListener) {
8400
- assertArg2(Utils16.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
8556
+ assertArg2(Utils17.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
8401
8557
  return new MPlayer(this, playStateChangeListener).play();
8402
8558
  }
8403
8559
  };
@@ -8427,7 +8583,7 @@ var _MEnding = class _MEnding extends MusicInterface6 {
8427
8583
  * @returns - Boolean whether this ending has asked passage number.
8428
8584
  */
8429
8585
  hasPassage(passage) {
8430
- assertArg2(Utils16.Is.isIntegerGte(passage, 1), "passage", passage);
8586
+ assertArg2(Utils17.Is.isIntegerGte(passage, 1), "passage", passage);
8431
8587
  return this.obj.hasPassage(passage);
8432
8588
  }
8433
8589
  };
@@ -9114,7 +9270,7 @@ var _MPlayer = class _MPlayer {
9114
9270
  constructor(doc, playStateChangeListener) {
9115
9271
  __publicField(this, "player");
9116
9272
  assertArg3(doc instanceof MDocument2, "doc", doc);
9117
- assertArg3(Utils17.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
9273
+ assertArg3(Utils18.Is.isFunctionOrUndefined(playStateChangeListener), "playStateChangeListener", playStateChangeListener);
9118
9274
  this.player = new Player();
9119
9275
  this.player.setDocument(doc.getMusicObject());
9120
9276
  this.player.setCursorPositionChangeListener((cursorRect) => doc.getMusicObject().updateCursorRect(cursorRect));
@@ -9158,32 +9314,32 @@ var _MPlayer = class _MPlayer {
9158
9314
  };
9159
9315
  __publicField(_MPlayer, "currentlyPlaying", /* @__PURE__ */ new Set());
9160
9316
  var MPlayer = _MPlayer;
9161
- var MRenderer2 = class {
9317
+ var MRenderContext2 = class {
9162
9318
  /**
9163
- * Create new renderer instance.
9319
+ * Create new render context instance.
9164
9320
  */
9165
9321
  constructor() {
9166
- __publicField(this, "renderer");
9167
- this.renderer = new Renderer(this);
9322
+ __publicField(this, "ctx");
9323
+ this.ctx = new RenderContext(this);
9168
9324
  }
9169
9325
  /**
9170
- * Attach music document to this renderer.
9326
+ * Attach music document to this render context.
9171
9327
  * @param doc - Music document.
9172
- * @returns - This renderer instance.
9328
+ * @returns - This render context instance.
9173
9329
  */
9174
9330
  setDocument(doc) {
9175
- assertArg3(Utils17.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9176
- this.renderer.setDocument(doc);
9331
+ assertArg3(Utils18.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9332
+ this.ctx.setDocument(doc);
9177
9333
  return this;
9178
9334
  }
9179
9335
  /**
9180
- * Set target canvas html element for this renderer.
9336
+ * Set target canvas html element for this render context.
9181
9337
  * @param canvas - HTML canvas element or element id.
9182
- * @returns - This renderer instance.
9338
+ * @returns - This render context instance.
9183
9339
  */
9184
9340
  setCanvas(canvas) {
9185
- canvas = require_t(Utils17.Dom.getCanvas(canvas), typeof canvas === "string" ? "Cannot set renderer canvas because invalid canvas id: " + canvas : "Cannot set renderer canvas because given canvas is undefined.");
9186
- this.renderer.setCanvas(canvas);
9341
+ canvas = require_t(Utils18.Dom.getCanvas(canvas), typeof canvas === "string" ? "Cannot set render canvas because invalid canvas id: " + canvas : "Cannot set render canvas because given canvas is undefined.");
9342
+ this.ctx.setCanvas(canvas);
9187
9343
  return this;
9188
9344
  }
9189
9345
  /**
@@ -9191,22 +9347,22 @@ var MRenderer2 = class {
9191
9347
  * @param scoreEventListener - Score event listener.
9192
9348
  */
9193
9349
  setScoreEventListener(scoreEventListener) {
9194
- assertArg3(Utils17.Is.isFunctionOrUndefined(scoreEventListener), "scoreEventListener", scoreEventListener);
9195
- this.renderer.setScoreEventListener(scoreEventListener);
9350
+ assertArg3(Utils18.Is.isFunctionOrUndefined(scoreEventListener), "scoreEventListener", scoreEventListener);
9351
+ this.ctx.setScoreEventListener(scoreEventListener);
9196
9352
  }
9197
9353
  /**
9198
9354
  * Draw given music object hilighted.
9199
9355
  * @param obj - Music object or undefined to remove hilighting.
9200
9356
  */
9201
9357
  hilightObject(obj) {
9202
- this.renderer.hilightObject(obj == null ? void 0 : obj.getMusicObject());
9358
+ this.ctx.hilightObject(obj == null ? void 0 : obj.getMusicObject());
9203
9359
  }
9204
9360
  /**
9205
9361
  * Draw given staff position hilighted.
9206
9362
  * @param staffPos - Staff position (score row and diatonic id) or undefined to remove hilighting.
9207
9363
  */
9208
9364
  hilightStaffPos(staffPos) {
9209
- this.renderer.hilightStaffPos(staffPos ? {
9365
+ this.ctx.hilightStaffPos(staffPos ? {
9210
9366
  scoreRow: staffPos.scoreRow.getMusicObject(),
9211
9367
  diatonicId: staffPos.diatonicId
9212
9368
  } : void 0);
@@ -9216,13 +9372,14 @@ var MRenderer2 = class {
9216
9372
  */
9217
9373
  draw() {
9218
9374
  try {
9219
- this.renderer.draw();
9220
- } catch (e) {
9221
- console.log("Draw failed in music renderer.");
9222
- console.log(e);
9375
+ this.ctx.draw();
9376
+ } catch (err) {
9377
+ console.log("Draw failed in music render context!", err);
9223
9378
  }
9224
9379
  }
9225
9380
  };
9381
+ var MRenderer = class extends MRenderContext2 {
9382
+ };
9226
9383
  var _MPlaybackButtons = class _MPlaybackButtons {
9227
9384
  /**
9228
9385
  * Create new playback buttons helper class instance.
@@ -9265,7 +9422,7 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9265
9422
  * @returns
9266
9423
  */
9267
9424
  setDocument(doc) {
9268
- assertArg3(Utils17.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9425
+ assertArg3(Utils18.Is.isUndefined(doc) || doc instanceof MDocument2, "doc", doc);
9269
9426
  this.onStop();
9270
9427
  if (doc) {
9271
9428
  this.player = new MPlayer(doc, (playState) => {
@@ -9309,9 +9466,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9309
9466
  * @returns - This playback buttons class instance.
9310
9467
  */
9311
9468
  setPlayButton(btn, btnLabel) {
9312
- assertArg3(Utils17.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9469
+ assertArg3(Utils18.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9313
9470
  _MPlaybackButtons.removeOnClickListeners(this.playButton, this.onPlay);
9314
- this.playButton = require_t(Utils17.Dom.getButton(btn), "Play button required!");
9471
+ this.playButton = require_t(Utils18.Dom.getButton(btn), "Play button required!");
9315
9472
  this.playLabel = btnLabel != null ? btnLabel : "Play";
9316
9473
  _MPlaybackButtons.removeOnClickListeners(this.playButton, "all");
9317
9474
  _MPlaybackButtons.addOnClickListener(this.playButton, this.onPlay);
@@ -9325,9 +9482,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9325
9482
  * @returns - This playback buttons class instance.
9326
9483
  */
9327
9484
  setStopButton(btn, btnLabel) {
9328
- assertArg3(Utils17.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9485
+ assertArg3(Utils18.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9329
9486
  _MPlaybackButtons.removeOnClickListeners(this.stopButton, this.onStop);
9330
- this.stopButton = require_t(Utils17.Dom.getButton(btn), "Stop button required!");
9487
+ this.stopButton = require_t(Utils18.Dom.getButton(btn), "Stop button required!");
9331
9488
  this.stopLabel = btnLabel != null ? btnLabel : "Stop";
9332
9489
  _MPlaybackButtons.removeOnClickListeners(this.stopButton, "all");
9333
9490
  _MPlaybackButtons.addOnClickListener(this.stopButton, this.onStop);
@@ -9342,10 +9499,10 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9342
9499
  * @returns - This playback buttons class instance.
9343
9500
  */
9344
9501
  setPlayStopButton(btn, playLabel, stopLabel) {
9345
- assertArg3(Utils17.Is.isStringOrUndefined(playLabel), "playLabel", playLabel);
9346
- assertArg3(Utils17.Is.isStringOrUndefined(stopLabel), "stopLabel", stopLabel);
9502
+ assertArg3(Utils18.Is.isStringOrUndefined(playLabel), "playLabel", playLabel);
9503
+ assertArg3(Utils18.Is.isStringOrUndefined(stopLabel), "stopLabel", stopLabel);
9347
9504
  _MPlaybackButtons.removeOnClickListeners(this.playStopButton, this.onPlayStop);
9348
- this.playStopButton = require_t(Utils17.Dom.getButton(btn), "Play/stop button required!");
9505
+ this.playStopButton = require_t(Utils18.Dom.getButton(btn), "Play/stop button required!");
9349
9506
  this.playLabel = playLabel != null ? playLabel : "Play";
9350
9507
  this.stopLabel = stopLabel != null ? stopLabel : "Stop";
9351
9508
  _MPlaybackButtons.removeOnClickListeners(this.playStopButton, "all");
@@ -9360,9 +9517,9 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9360
9517
  * @returns - This playback buttons class instance.
9361
9518
  */
9362
9519
  setPauseButton(btn, btnLabel) {
9363
- assertArg3(Utils17.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9520
+ assertArg3(Utils18.Is.isStringOrUndefined(btnLabel), "btnLabel", btnLabel);
9364
9521
  _MPlaybackButtons.removeOnClickListeners(this.pauseButton, this.onPause);
9365
- this.pauseButton = require_t(Utils17.Dom.getButton(btn), "Pause button required!");
9522
+ this.pauseButton = require_t(Utils18.Dom.getButton(btn), "Pause button required!");
9366
9523
  this.pauseLabel = btnLabel != null ? btnLabel : "Pause";
9367
9524
  _MPlaybackButtons.removeOnClickListeners(this.pauseButton, "all");
9368
9525
  _MPlaybackButtons.addOnClickListener(this.pauseButton, this.onPause);
@@ -9384,7 +9541,7 @@ var _MPlaybackButtons = class _MPlaybackButtons {
9384
9541
  }
9385
9542
  }
9386
9543
  static addOnClickListener(btn, onClick) {
9387
- assertArg3(Utils17.Is.isFunction(onClick), "onClick", onClick);
9544
+ assertArg3(Utils18.Is.isFunction(onClick), "onClick", onClick);
9388
9545
  btn.addEventListener("click", onClick);
9389
9546
  let clickListeners = this.savedOnClickListeners.get(btn) || [];
9390
9547
  this.savedOnClickListeners.set(btn, [...clickListeners, onClick]);
@@ -9425,7 +9582,8 @@ export {
9425
9582
  MNoteGroup,
9426
9583
  MPlaybackButtons,
9427
9584
  MPlayer,
9428
- MRenderer2 as MRenderer,
9585
+ MRenderContext2 as MRenderContext,
9586
+ MRenderer,
9429
9587
  MRest,
9430
9588
  MRhythmColumn,
9431
9589
  MScoreRow,