@coderline/alphatab 1.8.0-alpha.1640 → 1.8.0-alpha.1645

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,5 +1,5 @@
1
1
  /*!
2
- * alphaTab v1.8.0-alpha.1640 (develop, build 1640)
2
+ * alphaTab v1.8.0-alpha.1645 (develop, build 1645)
3
3
  *
4
4
  * Copyright © 2025, Daniel Kuschny and Contributors, All rights reserved.
5
5
  *
@@ -203,9 +203,9 @@ class AlphaTabError extends Error {
203
203
  * @internal
204
204
  */
205
205
  class VersionInfo {
206
- static version = '1.8.0-alpha.1640';
207
- static date = '2025-12-10T02:19:08.776Z';
208
- static commit = '343f59ee6b39b4f3a41636b3c33db34bccf631f9';
206
+ static version = '1.8.0-alpha.1645';
207
+ static date = '2025-12-15T02:24:53.193Z';
208
+ static commit = '2a0b11cc7b6660842c925dd2623b17a34ab325b7';
209
209
  static print(print) {
210
210
  print(`alphaTab ${VersionInfo.version}`);
211
211
  print(`commit: ${VersionInfo.commit}`);
@@ -4715,6 +4715,24 @@ class ModelUtils {
4715
4715
  static toArticulationId(plain) {
4716
4716
  return plain.replace(/[^a-zA-Z0-9]/g, '').toLowerCase();
4717
4717
  }
4718
+ static minBoundingBox(a, b) {
4719
+ if (Number.isNaN(a)) {
4720
+ return b;
4721
+ }
4722
+ else if (Number.isNaN(b)) {
4723
+ return a;
4724
+ }
4725
+ return a < b ? a : b;
4726
+ }
4727
+ static maxBoundingBox(a, b) {
4728
+ if (Number.isNaN(a)) {
4729
+ return b;
4730
+ }
4731
+ else if (Number.isNaN(b)) {
4732
+ return a;
4733
+ }
4734
+ return a > b ? a : b;
4735
+ }
4718
4736
  }
4719
4737
 
4720
4738
  /**
@@ -8121,6 +8139,11 @@ class AlphaTex1EnumMappings {
8121
8139
  ['explicit', 1]
8122
8140
  ]);
8123
8141
  static alphaTexAccidentalModeReversed = AlphaTex1EnumMappings._reverse(AlphaTex1EnumMappings.alphaTexAccidentalMode);
8142
+ static alphaTexVoiceMode = new Map([
8143
+ ['staffwise', 0],
8144
+ ['barwise', 1]
8145
+ ]);
8146
+ static alphaTexVoiceModeReversed = AlphaTex1EnumMappings._reverse(AlphaTex1EnumMappings.alphaTexVoiceMode);
8124
8147
  static noteAccidentalMode = new Map([
8125
8148
  ['default', 0],
8126
8149
  ['forcenone', 1],
@@ -8504,513 +8527,138 @@ class AlphaTex1LanguageDefinitions {
8504
8527
  // to reduce code size, the parameter types are specified as number values and then
8505
8528
  // translated inside AlphaTex1LanguageDefinitions._signatures during runtime
8506
8529
  static scoreMetaDataSignatures = AlphaTex1LanguageDefinitions._signatures([
8507
- [
8508
- 'title',
8509
- [
8510
- [
8511
- [[17, 10], 0],
8512
- [[17], 1],
8513
- [[10, 17], 1, ['left', 'center', 'right']]
8514
- ]
8515
- ]
8516
- ],
8517
- [
8518
- 'subtitle',
8519
- [
8520
- [
8521
- [[17, 10], 0],
8522
- [[17], 1],
8523
- [[10, 17], 1, ['left', 'center', 'right']]
8524
- ]
8525
- ]
8526
- ],
8527
- [
8528
- 'artist',
8529
- [
8530
- [
8531
- [[17, 10], 0],
8532
- [[17], 1],
8533
- [[10, 17], 1, ['left', 'center', 'right']]
8534
- ]
8535
- ]
8536
- ],
8537
- [
8538
- 'album',
8539
- [
8540
- [
8541
- [[17, 10], 0],
8542
- [[17], 1],
8543
- [[10, 17], 1, ['left', 'center', 'right']]
8544
- ]
8545
- ]
8546
- ],
8547
- [
8548
- 'words',
8549
- [
8550
- [
8551
- [[17, 10], 0],
8552
- [[17], 1],
8553
- [[10, 17], 1, ['left', 'center', 'right']]
8554
- ]
8555
- ]
8556
- ],
8557
- [
8558
- 'music',
8559
- [
8560
- [
8561
- [[17, 10], 0],
8562
- [[17], 1],
8563
- [[10, 17], 1, ['left', 'center', 'right']]
8564
- ]
8565
- ]
8566
- ],
8567
- [
8568
- 'wordsandmusic',
8569
- [
8570
- [
8571
- [[17], 0],
8572
- [[10, 17], 1, ['left', 'center', 'right']]
8573
- ]
8574
- ]
8575
- ],
8576
- [
8577
- 'copyright',
8578
- [
8579
- [
8580
- [[17, 10], 0],
8581
- [[17], 1],
8582
- [[10, 17], 1, ['left', 'center', 'right']]
8583
- ]
8584
- ]
8585
- ],
8586
- [
8587
- 'copyright2',
8588
- [
8589
- [
8590
- [[17], 0],
8591
- [[10, 17], 1, ['left', 'center', 'right']]
8592
- ]
8593
- ]
8594
- ],
8595
- ['instructions', [[[[17, 10], 0]]]],
8596
- ['notices', [[[[17, 10], 0]]]],
8597
- [
8598
- 'tab',
8599
- [
8600
- [
8601
- [[17, 10], 0],
8602
- [[17], 1],
8603
- [[10, 17], 1, ['left', 'center', 'right']]
8604
- ]
8605
- ]
8606
- ],
8607
- ['systemslayout', [[[[16], 5]]]],
8608
- ['defaultsystemslayout', [[[[16], 0]]]],
8609
- ['showdynamics', null],
8610
- ['hidedynamics', null],
8611
- ['usesystemsignseparator', null],
8612
- ['multibarrest', null],
8613
- ['bracketextendmode', [[[[10, 17], 0, ['nobrackets', 'groupstaves', 'groupsimilarinstruments']]]]],
8614
- ['singletracktracknamepolicy', [[[[10, 17], 0, ['hidden', 'firstsystem', 'allsystems']]]]],
8615
- ['multitracktracknamepolicy', [[[[10, 17], 0, ['hidden', 'firstsystem', 'allsystems']]]]],
8616
- ['firstsystemtracknamemode', [[[[10, 17], 0, ['fullname', 'shortname']]]]],
8617
- ['othersystemstracknamemode', [[[[10, 17], 0, ['fullname', 'shortname']]]]],
8618
- ['firstsystemtracknameorientation', [[[[10, 17], 0, ['horizontal', 'vertical']]]]],
8619
- ['othersystemstracknameorientation', [[[[10, 17], 0, ['horizontal', 'vertical']]]]],
8620
- ['extendbarlines', null]
8530
+ ["title", [[[[17, 10], 0], [[17], 1], [[10, 17], 1, ["left", "center", "right"]]]]],
8531
+ ["subtitle", [[[[17, 10], 0], [[17], 1], [[10, 17], 1, ["left", "center", "right"]]]]],
8532
+ ["artist", [[[[17, 10], 0], [[17], 1], [[10, 17], 1, ["left", "center", "right"]]]]],
8533
+ ["album", [[[[17, 10], 0], [[17], 1], [[10, 17], 1, ["left", "center", "right"]]]]],
8534
+ ["words", [[[[17, 10], 0], [[17], 1], [[10, 17], 1, ["left", "center", "right"]]]]],
8535
+ ["music", [[[[17, 10], 0], [[17], 1], [[10, 17], 1, ["left", "center", "right"]]]]],
8536
+ ["wordsandmusic", [[[[17], 0], [[10, 17], 1, ["left", "center", "right"]]]]],
8537
+ ["copyright", [[[[17, 10], 0], [[17], 1], [[10, 17], 1, ["left", "center", "right"]]]]],
8538
+ ["copyright2", [[[[17], 0], [[10, 17], 1, ["left", "center", "right"]]]]],
8539
+ ["instructions", [[[[17, 10], 0]]]],
8540
+ ["notices", [[[[17, 10], 0]]]],
8541
+ ["tab", [[[[17, 10], 0], [[17], 1], [[10, 17], 1, ["left", "center", "right"]]]]],
8542
+ ["systemslayout", [[[[16], 5]]]],
8543
+ ["defaultsystemslayout", [[[[16], 0]]]],
8544
+ ["showdynamics", null],
8545
+ ["hidedynamics", null],
8546
+ ["usesystemsignseparator", null],
8547
+ ["multibarrest", null],
8548
+ ["bracketextendmode", [[[[10, 17], 0, ["nobrackets", "groupstaves", "groupsimilarinstruments"]]]]],
8549
+ ["singletracktracknamepolicy", [[[[10, 17], 0, ["hidden", "firstsystem", "allsystems"]]]]],
8550
+ ["multitracktracknamepolicy", [[[[10, 17], 0, ["hidden", "firstsystem", "allsystems"]]]]],
8551
+ ["firstsystemtracknamemode", [[[[10, 17], 0, ["fullname", "shortname"]]]]],
8552
+ ["othersystemstracknamemode", [[[[10, 17], 0, ["fullname", "shortname"]]]]],
8553
+ ["firstsystemtracknameorientation", [[[[10, 17], 0, ["horizontal", "vertical"]]]]],
8554
+ ["othersystemstracknameorientation", [[[[10, 17], 0, ["horizontal", "vertical"]]]]],
8555
+ ["extendbarlines", null]
8621
8556
  ]);
8622
8557
  static staffMetaDataSignatures = AlphaTex1LanguageDefinitions._signatures([
8623
- ['tuning', [[[[10, 17], 0, ['piano', 'none', 'voice']]], [[[10, 17], 5]]]],
8624
- [
8625
- 'chord',
8626
- [
8627
- [
8628
- [[17, 10], 0],
8629
- [[10, 17, 16], 5]
8630
- ]
8631
- ]
8632
- ],
8633
- ['capo', [[[[16], 0]]]],
8634
- [
8635
- 'lyrics',
8636
- [
8637
- [[[17], 0]],
8638
- [
8639
- [[16], 0],
8640
- [[17], 0]
8641
- ]
8642
- ]
8643
- ],
8644
- [
8645
- 'articulation',
8646
- [
8647
- [[[10], 0, ['defaults']]],
8648
- [
8649
- [[17, 10], 0],
8650
- [[16], 0]
8651
- ]
8652
- ]
8653
- ],
8654
- ['displaytranspose', [[[[16], 0]]]],
8655
- ['transpose', [[[[16], 0]]]],
8656
- ['instrument', [[[[16], 0]], [[[17, 10], 0]], [[[10], 0, ['percussion']]]]]
8558
+ ["tuning", [[[[10, 17], 0, ["piano", "none", "voice"]]], [[[10, 17], 5]]]],
8559
+ ["chord", [[[[17, 10], 0], [[10, 17, 16], 5]]]],
8560
+ ["capo", [[[[16], 0]]]],
8561
+ ["lyrics", [[[[17], 0]], [[[16], 0], [[17], 0]]]],
8562
+ ["articulation", [[[[10], 0, ["defaults"]]], [[[17, 10], 0], [[16], 0]]]],
8563
+ ["displaytranspose", [[[[16], 0]]]],
8564
+ ["transpose", [[[[16], 0]]]],
8565
+ ["instrument", [[[[16], 0]], [[[17, 10], 0]], [[[10], 0, ["percussion"]]]]]
8657
8566
  ]);
8658
8567
  static structuralMetaDataSignatures = AlphaTex1LanguageDefinitions._signatures([
8659
- [
8660
- 'track',
8661
- [
8662
- [
8663
- [[17], 1],
8664
- [[17], 1]
8665
- ]
8666
- ]
8667
- ],
8668
- ['staff', null],
8669
- ['voice', null]
8568
+ ["track", [[[[17], 1], [[17], 1]]]],
8569
+ ["staff", null],
8570
+ ["voice", null]
8670
8571
  ]);
8671
8572
  static barMetaDataSignatures = AlphaTex1LanguageDefinitions._signatures([
8672
- [
8673
- 'ts',
8674
- [
8675
- [[[10, 17], 0, ['common']]],
8676
- [
8677
- [[16], 0],
8678
- [[16], 0]
8679
- ]
8680
- ]
8681
- ],
8682
- ['ro', null],
8683
- ['rc', [[[[16], 0]]]],
8684
- ['ae', [[[[16, 13], 4]]]],
8685
- [
8686
- 'ks',
8687
- [
8688
- [
8689
- [
8690
- [10, 17],
8691
- 0,
8692
- [
8693
- 'cb',
8694
- 'gb',
8695
- 'db',
8696
- 'ab',
8697
- 'eb',
8698
- 'bb',
8699
- 'f',
8700
- 'c',
8701
- 'g',
8702
- 'd',
8703
- 'a',
8704
- 'e',
8705
- 'b',
8706
- 'f#',
8707
- 'c#',
8708
- 'cbmajor',
8709
- 'abminor',
8710
- 'gbmajor',
8711
- 'ebminor',
8712
- 'dbmajor',
8713
- 'bbminor',
8714
- 'abmajor',
8715
- 'fminor',
8716
- 'ebmajor',
8717
- 'cminor',
8718
- 'bbmajor',
8719
- 'gminor',
8720
- 'fmajor',
8721
- 'dminor',
8722
- 'cmajor',
8723
- 'aminor',
8724
- 'gmajor',
8725
- 'eminor',
8726
- 'dmajor',
8727
- 'bminor',
8728
- 'amajor',
8729
- 'f#minor',
8730
- 'emajor',
8731
- 'c#minor',
8732
- 'bmajor',
8733
- 'g#minor',
8734
- 'f#major',
8735
- 'd#minor',
8736
- 'f#',
8737
- 'c#major',
8738
- 'a#minor',
8739
- 'c#'
8740
- ]
8741
- ]
8742
- ]
8743
- ]
8744
- ],
8745
- ['clef', [[[[10, 16, 17], 0, ['neutral', 'c3', 'c4', 'f4', 'g2', 'n', 'alto', 'tenor', 'bass', 'treble']]]]],
8746
- ['ottava', [[[[10, 17], 0, ['15ma', '8va', 'regular', '8vb', '15mb', '15ma', '8va', '8vb', '15mb']]]]],
8747
- [
8748
- 'tempo',
8749
- [
8750
- [
8751
- [[16], 2],
8752
- [[17], 1]
8753
- ],
8754
- [null, [[16], 2], [[17], 0], [[16], 1], [[10], 1, ['hide']]]
8755
- ]
8756
- ],
8757
- [
8758
- 'tf',
8759
- [
8760
- [
8761
- [
8762
- [10, 16, 17],
8763
- 0,
8764
- [
8765
- 'none',
8766
- 'triplet16th',
8767
- 'triplet8th',
8768
- 'dotted16th',
8769
- 'dotted8th',
8770
- 'scottish16th',
8771
- 'scottish8th',
8772
- 'none',
8773
- 'no',
8774
- 'notripletfeel',
8775
- 't16',
8776
- 'triplet-16th',
8777
- 't8',
8778
- 'triplet-8th',
8779
- 'd16',
8780
- 'dotted-16th',
8781
- 'd8',
8782
- 'dotted-8th',
8783
- 's16',
8784
- 'scottish-16th',
8785
- 's8',
8786
- 'scottish-8th'
8787
- ]
8788
- ]
8789
- ]
8790
- ]
8791
- ],
8792
- ['ac', null],
8793
- [
8794
- 'section',
8795
- [
8796
- [[[17, 10], 0]],
8797
- [
8798
- [[17, 10], 0],
8799
- [[17, 10], 0, null, ['x', '-', 'r']]
8800
- ]
8801
- ]
8802
- ],
8803
- [
8804
- 'jump',
8805
- [
8806
- [
8807
- [
8808
- [10, 17],
8809
- 0,
8810
- [
8811
- 'fine',
8812
- 'segno',
8813
- 'segnosegno',
8814
- 'coda',
8815
- 'doublecoda',
8816
- 'dacapo',
8817
- 'dacapoalcoda',
8818
- 'dacapoaldoublecoda',
8819
- 'dacapoalfine',
8820
- 'dalsegno',
8821
- 'dalsegnoalcoda',
8822
- 'dalsegnoaldoublecoda',
8823
- 'dalsegnoalfine',
8824
- 'dalsegnosegno',
8825
- 'dalsegnosegnoalcoda',
8826
- 'dalsegnosegnoaldoublecoda',
8827
- 'dalsegnosegnoalfine',
8828
- 'dacoda',
8829
- 'dadoublecoda'
8830
- ]
8831
- ]
8832
- ]
8833
- ]
8834
- ],
8835
- ['ft', null],
8836
- ['simile', [[[[10, 17], 0, ['none', 'simple', 'firstofdouble', 'secondofdouble']]]]],
8837
- [
8838
- 'barlineleft',
8839
- [
8840
- [
8841
- [
8842
- [10, 17],
8843
- 0,
8844
- [
8845
- 'automatic',
8846
- 'dashed',
8847
- 'dotted',
8848
- 'heavy',
8849
- 'heavyheavy',
8850
- 'heavylight',
8851
- 'lightheavy',
8852
- 'lightlight',
8853
- 'none',
8854
- 'regular',
8855
- 'short',
8856
- 'tick'
8857
- ]
8858
- ]
8859
- ]
8860
- ]
8861
- ],
8862
- [
8863
- 'barlineright',
8864
- [
8865
- [
8866
- [
8867
- [10, 17],
8868
- 0,
8869
- [
8870
- 'automatic',
8871
- 'dashed',
8872
- 'dotted',
8873
- 'heavy',
8874
- 'heavyheavy',
8875
- 'heavylight',
8876
- 'lightheavy',
8877
- 'lightlight',
8878
- 'none',
8879
- 'regular',
8880
- 'short',
8881
- 'tick'
8882
- ]
8883
- ]
8884
- ]
8885
- ]
8886
- ],
8887
- ['scale', [[[[16], 2]]]],
8888
- ['width', [[[[16], 2]]]],
8889
- [
8890
- 'sync',
8891
- [
8892
- [
8893
- [[16], 0],
8894
- [[16], 0],
8895
- [[16], 0],
8896
- [[16], 3]
8897
- ]
8898
- ]
8899
- ],
8900
- ['accidentals', [[[[10, 17], 0, ['auto', 'explicit']]]]],
8901
- ['spd', [[[[16], 2]]]],
8902
- ['sph', [[[[16], 2]]]],
8903
- ['spu', [[[[16], 2]]]],
8904
- ['db', null]
8573
+ ["ts", [[[[10, 17], 0, ["common"]]], [[[16], 0], [[16], 0]]]],
8574
+ ["ro", null],
8575
+ ["rc", [[[[16], 0]]]],
8576
+ ["ae", [[[[16, 13], 4]]]],
8577
+ ["ks", [[[[10, 17], 0, ["cb", "gb", "db", "ab", "eb", "bb", "f", "c", "g", "d", "a", "e", "b", "f#", "c#", "cbmajor", "abminor", "gbmajor", "ebminor", "dbmajor", "bbminor", "abmajor", "fminor", "ebmajor", "cminor", "bbmajor", "gminor", "fmajor", "dminor", "cmajor", "aminor", "gmajor", "eminor", "dmajor", "bminor", "amajor", "f#minor", "emajor", "c#minor", "bmajor", "g#minor", "f#major", "d#minor", "f#", "c#major", "a#minor", "c#"]]]]],
8578
+ ["clef", [[[[10, 16, 17], 0, ["neutral", "c3", "c4", "f4", "g2", "n", "alto", "tenor", "bass", "treble"]]]]],
8579
+ ["ottava", [[[[10, 17], 0, ["15ma", "8va", "regular", "8vb", "15mb", "15ma", "8va", "8vb", "15mb"]]]]],
8580
+ ["tempo", [[[[16], 2], [[17], 1]], [null, [[16], 2], [[17], 0], [[16], 1], [[10], 1, ["hide"]]]]],
8581
+ ["tf", [[[[10, 16, 17], 0, ["none", "triplet16th", "triplet8th", "dotted16th", "dotted8th", "scottish16th", "scottish8th", "none", "no", "notripletfeel", "t16", "triplet-16th", "t8", "triplet-8th", "d16", "dotted-16th", "d8", "dotted-8th", "s16", "scottish-16th", "s8", "scottish-8th"]]]]],
8582
+ ["ac", null],
8583
+ ["section", [[[[17, 10], 0]], [[[17, 10], 0], [[17, 10], 0, null, ["x", "-", "r"]]]]],
8584
+ ["jump", [[[[10, 17], 0, ["fine", "segno", "segnosegno", "coda", "doublecoda", "dacapo", "dacapoalcoda", "dacapoaldoublecoda", "dacapoalfine", "dalsegno", "dalsegnoalcoda", "dalsegnoaldoublecoda", "dalsegnoalfine", "dalsegnosegno", "dalsegnosegnoalcoda", "dalsegnosegnoaldoublecoda", "dalsegnosegnoalfine", "dacoda", "dadoublecoda"]]]]],
8585
+ ["ft", null],
8586
+ ["simile", [[[[10, 17], 0, ["none", "simple", "firstofdouble", "secondofdouble"]]]]],
8587
+ ["barlineleft", [[[[10, 17], 0, ["automatic", "dashed", "dotted", "heavy", "heavyheavy", "heavylight", "lightheavy", "lightlight", "none", "regular", "short", "tick"]]]]],
8588
+ ["barlineright", [[[[10, 17], 0, ["automatic", "dashed", "dotted", "heavy", "heavyheavy", "heavylight", "lightheavy", "lightlight", "none", "regular", "short", "tick"]]]]],
8589
+ ["scale", [[[[16], 2]]]],
8590
+ ["width", [[[[16], 2]]]],
8591
+ ["sync", [[[[16], 0], [[16], 0], [[16], 0], [[16], 3]]]],
8592
+ ["accidentals", [[[[10, 17], 0, ["auto", "explicit"]]]]],
8593
+ ["spd", [[[[16], 2]]]],
8594
+ ["sph", [[[[16], 2]]]],
8595
+ ["spu", [[[[16], 2]]]],
8596
+ ["db", null],
8597
+ ["voicemode", [[[[10, 17], 0, ["staffwise", "barwise"]]]]]
8905
8598
  ]);
8906
8599
  static metaDataProperties = AlphaTex1LanguageDefinitions._metaProps([
8907
- [
8908
- 'track',
8909
- [
8910
- ['color', [[[[17], 0]]]],
8911
- ['systemslayout', [[[[16], 5]]]],
8912
- ['defaultsystemslayout', [[[[16], 0]]]],
8913
- ['solo', null],
8914
- ['mute', null],
8915
- ['volume', [[[[16], 0]]]],
8916
- ['balance', [[[[16], 0]]]],
8917
- ['instrument', [[[[16], 0]], [[[17, 10], 0]], [[[10], 0, ['percussion']]]]],
8918
- ['bank', [[[[16], 0]]]],
8919
- ['multibarrest', null]
8920
- ]
8921
- ],
8922
- [
8923
- 'staff',
8924
- [
8925
- ['score', [[[[16], 1]]]],
8926
- ['tabs', null],
8927
- ['slash', null],
8928
- ['numbered', null]
8929
- ]
8930
- ],
8931
- ['voice', null],
8932
- ['title', null],
8933
- ['subtitle', null],
8934
- ['artist', null],
8935
- ['album', null],
8936
- ['words', null],
8937
- ['music', null],
8938
- ['wordsandmusic', null],
8939
- ['copyright', null],
8940
- ['copyright2', null],
8941
- ['instructions', null],
8942
- ['notices', null],
8943
- ['tab', null],
8944
- ['systemslayout', null],
8945
- ['defaultsystemslayout', null],
8946
- ['showdynamics', null],
8947
- ['hidedynamics', null],
8948
- ['usesystemsignseparator', null],
8949
- ['multibarrest', null],
8950
- ['bracketextendmode', null],
8951
- ['singletracktracknamepolicy', null],
8952
- ['multitracktracknamepolicy', null],
8953
- ['firstsystemtracknamemode', null],
8954
- ['othersystemstracknamemode', null],
8955
- ['firstsystemtracknameorientation', null],
8956
- ['othersystemstracknameorientation', null],
8957
- ['extendbarlines', null],
8958
- [
8959
- 'tuning',
8960
- [
8961
- ['hide', null],
8962
- ['label', [[[[17], 0]]]]
8963
- ]
8964
- ],
8965
- [
8966
- 'chord',
8967
- [
8968
- ['firstfret', [[[[16], 0]]]],
8969
- ['barre', [[[[16], 5]]]],
8970
- [
8971
- 'showdiagram',
8972
- [[], [[[17], 0, ['true', 'false']]], [[[10], 0, ['true', 'false']]], [[[16], 0, ['1', '0']]]]
8973
- ],
8974
- [
8975
- 'showfingering',
8976
- [[], [[[17], 0, ['true', 'false']]], [[[10], 0, ['true', 'false']]], [[[16], 0, ['1', '0']]]]
8977
- ],
8978
- [
8979
- 'showname',
8980
- [[], [[[17], 0, ['true', 'false']]], [[[10], 0, ['true', 'false']]], [[[16], 0, ['1', '0']]]]
8981
- ]
8982
- ]
8983
- ],
8984
- ['capo', null],
8985
- ['lyrics', null],
8986
- ['articulation', null],
8987
- ['displaytranspose', null],
8988
- ['transpose', null],
8989
- ['instrument', null],
8990
- ['ts', null],
8991
- ['ro', null],
8992
- ['rc', null],
8993
- ['ae', null],
8994
- ['ks', null],
8995
- ['clef', null],
8996
- ['ottava', null],
8997
- ['tempo', null],
8998
- ['tf', null],
8999
- ['ac', null],
9000
- ['section', null],
9001
- ['jump', null],
9002
- ['ft', null],
9003
- ['simile', null],
9004
- ['barlineleft', null],
9005
- ['barlineright', null],
9006
- ['scale', null],
9007
- ['width', null],
9008
- ['sync', null],
9009
- ['accidentals', null],
9010
- ['spd', null],
9011
- ['sph', null],
9012
- ['spu', null],
9013
- ['db', null]
8600
+ ["track", [["color", [[[[17], 0]]]], ["systemslayout", [[[[16], 5]]]], ["defaultsystemslayout", [[[[16], 0]]]], ["solo", null], ["mute", null], ["volume", [[[[16], 0]]]], ["balance", [[[[16], 0]]]], ["instrument", [[[[16], 0]], [[[17, 10], 0]], [[[10], 0, ["percussion"]]]]], ["bank", [[[[16], 0]]]], ["multibarrest", null]]],
8601
+ ["staff", [["score", [[[[16], 1]]]], ["tabs", null], ["slash", null], ["numbered", null]]],
8602
+ ["voice", null],
8603
+ ["title", null],
8604
+ ["subtitle", null],
8605
+ ["artist", null],
8606
+ ["album", null],
8607
+ ["words", null],
8608
+ ["music", null],
8609
+ ["wordsandmusic", null],
8610
+ ["copyright", null],
8611
+ ["copyright2", null],
8612
+ ["instructions", null],
8613
+ ["notices", null],
8614
+ ["tab", null],
8615
+ ["systemslayout", null],
8616
+ ["defaultsystemslayout", null],
8617
+ ["showdynamics", null],
8618
+ ["hidedynamics", null],
8619
+ ["usesystemsignseparator", null],
8620
+ ["multibarrest", null],
8621
+ ["bracketextendmode", null],
8622
+ ["singletracktracknamepolicy", null],
8623
+ ["multitracktracknamepolicy", null],
8624
+ ["firstsystemtracknamemode", null],
8625
+ ["othersystemstracknamemode", null],
8626
+ ["firstsystemtracknameorientation", null],
8627
+ ["othersystemstracknameorientation", null],
8628
+ ["extendbarlines", null],
8629
+ ["tuning", [["hide", null], ["label", [[[[17], 0]]]]]],
8630
+ ["chord", [["firstfret", [[[[16], 0]]]], ["barre", [[[[16], 5]]]], ["showdiagram", [[], [[[17], 0, ["true", "false"]]], [[[10], 0, ["true", "false"]]], [[[16], 0, ["1", "0"]]]]], ["showfingering", [[], [[[17], 0, ["true", "false"]]], [[[10], 0, ["true", "false"]]], [[[16], 0, ["1", "0"]]]]], ["showname", [[], [[[17], 0, ["true", "false"]]], [[[10], 0, ["true", "false"]]], [[[16], 0, ["1", "0"]]]]]]],
8631
+ ["capo", null],
8632
+ ["lyrics", null],
8633
+ ["articulation", null],
8634
+ ["displaytranspose", null],
8635
+ ["transpose", null],
8636
+ ["instrument", null],
8637
+ ["ts", null],
8638
+ ["ro", null],
8639
+ ["rc", null],
8640
+ ["ae", null],
8641
+ ["ks", null],
8642
+ ["clef", null],
8643
+ ["ottava", null],
8644
+ ["tempo", null],
8645
+ ["tf", null],
8646
+ ["ac", null],
8647
+ ["section", null],
8648
+ ["jump", null],
8649
+ ["ft", null],
8650
+ ["simile", null],
8651
+ ["barlineleft", null],
8652
+ ["barlineright", null],
8653
+ ["scale", null],
8654
+ ["width", null],
8655
+ ["sync", null],
8656
+ ["accidentals", null],
8657
+ ["spd", null],
8658
+ ["sph", null],
8659
+ ["spu", null],
8660
+ ["db", null],
8661
+ ["voicemode", null]
9014
8662
  ]);
9015
8663
  static metaDataSignatures = [
9016
8664
  AlphaTex1LanguageDefinitions.scoreMetaDataSignatures,
@@ -9019,348 +8667,101 @@ class AlphaTex1LanguageDefinitions {
9019
8667
  AlphaTex1LanguageDefinitions.barMetaDataSignatures
9020
8668
  ];
9021
8669
  static durationChangeProperties = AlphaTex1LanguageDefinitions._props([
9022
- [
9023
- 'tu',
9024
- [
9025
- [[[16], 0, ['3', '5', '6', '7', '9', '10', '12']]],
9026
- [
9027
- [[16], 0],
9028
- [[16], 0]
9029
- ]
9030
- ]
9031
- ]
8670
+ ["tu", [[[[16], 0, ["3", "5", "6", "7", "9", "10", "12"]]], [[[16], 0], [[16], 0]]]]
9032
8671
  ]);
9033
8672
  static beatProperties = AlphaTex1LanguageDefinitions._props([
9034
- ['f', null],
9035
- ['fo', null],
9036
- ['vs', null],
9037
- ['v', null],
9038
- ['vw', null],
9039
- ['s', null],
9040
- ['p', null],
9041
- ['tt', null],
9042
- ['d', null],
9043
- ['dd', null],
9044
- ['su', null],
9045
- ['sd', null],
9046
- ['cre', null],
9047
- ['dec', null],
9048
- ['spd', null],
9049
- ['sph', null],
9050
- ['spu', null],
9051
- ['spe', null],
9052
- ['slashed', null],
9053
- ['ds', null],
9054
- ['glpf', null],
9055
- ['glpt', null],
9056
- ['waho', null],
9057
- ['wahc', null],
9058
- ['legatoorigin', null],
9059
- ['timer', null],
9060
- [
9061
- 'tu',
9062
- [
9063
- [[[16], 0, ['3', '5', '6', '7', '9', '10', '12']]],
9064
- [
9065
- [[16], 0],
9066
- [[16], 0]
9067
- ]
9068
- ]
9069
- ],
9070
- ['txt', [[[[17, 10], 0]]]],
9071
- [
9072
- 'lyrics',
9073
- [
9074
- [[[17], 0]],
9075
- [
9076
- [[16], 0],
9077
- [[17], 0]
9078
- ]
9079
- ]
9080
- ],
9081
- [
9082
- 'tb',
9083
- [
9084
- [[[16], 5]],
9085
- [
9086
- [[10, 17], 0, ['custom', 'dive', 'dip', 'hold', 'predive', 'predivedive']],
9087
- [[16], 5]
9088
- ],
9089
- [
9090
- [[10, 17], 0, ['default', 'gradual', 'fast']],
9091
- [[16], 5]
9092
- ],
9093
- [
9094
- [[10, 17], 0, ['custom', 'dive', 'dip', 'hold', 'predive', 'predivedive']],
9095
- [[10, 17], 0, ['default', 'gradual', 'fast']],
9096
- [[16], 5]
9097
- ]
9098
- ]
9099
- ],
9100
- [
9101
- 'tbe',
9102
- [
9103
- [[[16], 5]],
9104
- [
9105
- [[10, 17], 0, ['custom', 'dive', 'dip', 'hold', 'predive', 'predivedive']],
9106
- [[16], 5]
9107
- ],
9108
- [
9109
- [[10, 17], 0, ['default', 'gradual', 'fast']],
9110
- [[16], 5]
9111
- ],
9112
- [
9113
- [[10, 17], 0, ['custom', 'dive', 'dip', 'hold', 'predive', 'predivedive']],
9114
- [[10, 17], 0, ['default', 'gradual', 'fast']],
9115
- [[16], 5]
9116
- ]
9117
- ]
9118
- ],
9119
- ['bu', [[[[16], 1]]]],
9120
- ['bd', [[[[16], 1]]]],
9121
- ['au', [[[[16], 1]]]],
9122
- ['ad', [[[[16], 1]]]],
9123
- ['ch', [[[[17, 10], 0]]]],
9124
- ['gr', [[[[10, 17], 1, ['onbeat', 'beforebeat', 'bendgrace', 'ob', 'bb', 'b']]]]],
9125
- [
9126
- 'dy',
9127
- [
9128
- [
9129
- [
9130
- [10, 17],
9131
- 0,
9132
- [
9133
- 'ppp',
9134
- 'pp',
9135
- 'p',
9136
- 'mp',
9137
- 'mf',
9138
- 'f',
9139
- 'ff',
9140
- 'fff',
9141
- 'pppp',
9142
- 'ppppp',
9143
- 'pppppp',
9144
- 'ffff',
9145
- 'fffff',
9146
- 'ffffff',
9147
- 'sf',
9148
- 'sfp',
9149
- 'sfpp',
9150
- 'fp',
9151
- 'rf',
9152
- 'rfz',
9153
- 'sfz',
9154
- 'sffz',
9155
- 'fz',
9156
- 'n',
9157
- 'pf',
9158
- 'sfzp'
9159
- ]
9160
- ]
9161
- ]
9162
- ]
9163
- ],
9164
- [
9165
- 'tempo',
9166
- [
9167
- [
9168
- [[16], 0],
9169
- [[10], 1, ['hide']]
9170
- ],
9171
- [
9172
- [[16], 0],
9173
- [[17], 0],
9174
- [[10], 1, ['hide']]
9175
- ]
9176
- ]
9177
- ],
9178
- ['volume', [[[[16], 0]]]],
9179
- ['balance', [[[[16], 0]]]],
9180
- ['tp', [[[[16], 0, ['8', '16', '32']]]]],
9181
- [
9182
- 'barre',
9183
- [
9184
- [
9185
- [[16], 0],
9186
- [[10, 17], 1, ['full', 'half']]
9187
- ]
9188
- ]
9189
- ],
9190
- [
9191
- 'rasg',
9192
- [
9193
- [
9194
- [
9195
- [10, 17],
9196
- 0,
9197
- [
9198
- 'ii',
9199
- 'mi',
9200
- 'miitriplet',
9201
- 'miianapaest',
9202
- 'pmptriplet',
9203
- 'pmpanapaest',
9204
- 'peitriplet',
9205
- 'peianapaest',
9206
- 'paitriplet',
9207
- 'paianapaest',
9208
- 'amitriplet',
9209
- 'amianapaest',
9210
- 'ppp',
9211
- 'amii',
9212
- 'amip',
9213
- 'eami',
9214
- 'eamii',
9215
- 'peami'
9216
- ]
9217
- ]
9218
- ]
9219
- ]
9220
- ],
9221
- ['ot', [[[[10, 17], 0, ['15ma', '8va', 'regular', '8vb', '15mb', '15ma', '8va', '8vb', '15mb']]]]],
9222
- ['instrument', [[[[16], 0]], [[[17, 10], 0]], [[[10], 0, ['percussion']]]]],
9223
- ['bank', [[[[16], 0]]]],
9224
- [
9225
- 'fermata',
9226
- [
9227
- [
9228
- [[10, 17], 0, ['short', 'medium', 'long']],
9229
- [[16], 3]
9230
- ]
9231
- ]
9232
- ],
9233
- ['beam', [[[[10, 17], 0, ['invert', 'up', 'down', 'auto', 'split', 'merge', 'splitsecondary']]]]]
8673
+ ["f", null],
8674
+ ["fo", null],
8675
+ ["vs", null],
8676
+ ["v", null],
8677
+ ["vw", null],
8678
+ ["s", null],
8679
+ ["p", null],
8680
+ ["tt", null],
8681
+ ["d", null],
8682
+ ["dd", null],
8683
+ ["su", null],
8684
+ ["sd", null],
8685
+ ["cre", null],
8686
+ ["dec", null],
8687
+ ["spd", null],
8688
+ ["sph", null],
8689
+ ["spu", null],
8690
+ ["spe", null],
8691
+ ["slashed", null],
8692
+ ["ds", null],
8693
+ ["glpf", null],
8694
+ ["glpt", null],
8695
+ ["waho", null],
8696
+ ["wahc", null],
8697
+ ["legatoorigin", null],
8698
+ ["timer", null],
8699
+ ["tu", [[[[16], 0, ["3", "5", "6", "7", "9", "10", "12"]]], [[[16], 0], [[16], 0]]]],
8700
+ ["txt", [[[[17, 10], 0]]]],
8701
+ ["lyrics", [[[[17], 0]], [[[16], 0], [[17], 0]]]],
8702
+ ["tb", [[[[16], 5]], [[[10, 17], 0, ["custom", "dive", "dip", "hold", "predive", "predivedive"]], [[16], 5]], [[[10, 17], 0, ["default", "gradual", "fast"]], [[16], 5]], [[[10, 17], 0, ["custom", "dive", "dip", "hold", "predive", "predivedive"]], [[10, 17], 0, ["default", "gradual", "fast"]], [[16], 5]]]],
8703
+ ["tbe", [[[[16], 5]], [[[10, 17], 0, ["custom", "dive", "dip", "hold", "predive", "predivedive"]], [[16], 5]], [[[10, 17], 0, ["default", "gradual", "fast"]], [[16], 5]], [[[10, 17], 0, ["custom", "dive", "dip", "hold", "predive", "predivedive"]], [[10, 17], 0, ["default", "gradual", "fast"]], [[16], 5]]]],
8704
+ ["bu", [[[[16], 1]]]],
8705
+ ["bd", [[[[16], 1]]]],
8706
+ ["au", [[[[16], 1]]]],
8707
+ ["ad", [[[[16], 1]]]],
8708
+ ["ch", [[[[17, 10], 0]]]],
8709
+ ["gr", [[[[10, 17], 1, ["onbeat", "beforebeat", "bendgrace", "ob", "bb", "b"]]]]],
8710
+ ["dy", [[[[10, 17], 0, ["ppp", "pp", "p", "mp", "mf", "f", "ff", "fff", "pppp", "ppppp", "pppppp", "ffff", "fffff", "ffffff", "sf", "sfp", "sfpp", "fp", "rf", "rfz", "sfz", "sffz", "fz", "n", "pf", "sfzp"]]]]],
8711
+ ["tempo", [[[[16], 0], [[10], 1, ["hide"]]], [[[16], 0], [[17], 0], [[10], 1, ["hide"]]]]],
8712
+ ["volume", [[[[16], 0]]]],
8713
+ ["balance", [[[[16], 0]]]],
8714
+ ["tp", [[[[16], 0, ["8", "16", "32"]]]]],
8715
+ ["barre", [[[[16], 0], [[10, 17], 1, ["full", "half"]]]]],
8716
+ ["rasg", [[[[10, 17], 0, ["ii", "mi", "miitriplet", "miianapaest", "pmptriplet", "pmpanapaest", "peitriplet", "peianapaest", "paitriplet", "paianapaest", "amitriplet", "amianapaest", "ppp", "amii", "amip", "eami", "eamii", "peami"]]]]],
8717
+ ["ot", [[[[10, 17], 0, ["15ma", "8va", "regular", "8vb", "15mb", "15ma", "8va", "8vb", "15mb"]]]]],
8718
+ ["instrument", [[[[16], 0]], [[[17, 10], 0]], [[[10], 0, ["percussion"]]]]],
8719
+ ["bank", [[[[16], 0]]]],
8720
+ ["fermata", [[[[10, 17], 0, ["short", "medium", "long"]], [[16], 3]]]],
8721
+ ["beam", [[[[10, 17], 0, ["invert", "up", "down", "auto", "split", "merge", "splitsecondary"]]]]]
9234
8722
  ]);
9235
8723
  static noteProperties = AlphaTex1LanguageDefinitions._props([
9236
- ['nh', null],
9237
- ['ah', [[[[16], 1]]]],
9238
- ['th', [[[[16], 1]]]],
9239
- ['ph', [[[[16], 1]]]],
9240
- ['sh', [[[[16], 1]]]],
9241
- ['fh', [[[[16], 1]]]],
9242
- ['v', null],
9243
- ['vw', null],
9244
- ['sl', null],
9245
- ['ss', null],
9246
- ['sib', null],
9247
- ['sia', null],
9248
- ['sou', null],
9249
- ['sod', null],
9250
- ['psu', null],
9251
- ['psd', null],
9252
- ['h', null],
9253
- ['lht', null],
9254
- ['g', null],
9255
- ['ac', null],
9256
- ['hac', null],
9257
- ['ten', null],
9258
- [
9259
- 'tr',
9260
- [
9261
- [
9262
- [[16], 0],
9263
- [[16], 1, ['16', '32', '64']]
9264
- ]
9265
- ]
9266
- ],
9267
- ['pm', null],
9268
- ['st', null],
9269
- ['lr', null],
9270
- ['x', null],
9271
- ['t', null],
9272
- ['turn', null],
9273
- ['iturn', null],
9274
- ['umordent', null],
9275
- ['lmordent', null],
9276
- ['string', null],
9277
- ['hide', null],
9278
- [
9279
- 'b',
9280
- [
9281
- [[[16], 5]],
9282
- [
9283
- [
9284
- [10, 17],
9285
- 0,
9286
- ['custom', 'bend', 'release', 'bendrelease', 'hold', 'prebend', 'prebendbend', 'prebendrelease']
9287
- ],
9288
- [[16], 5]
9289
- ],
9290
- [
9291
- [[10, 17], 0, ['default', 'gradual', 'fast']],
9292
- [[16], 5]
9293
- ],
9294
- [
9295
- [
9296
- [10, 17],
9297
- 0,
9298
- ['custom', 'bend', 'release', 'bendrelease', 'hold', 'prebend', 'prebendbend', 'prebendrelease']
9299
- ],
9300
- [[10, 17], 0, ['default', 'gradual', 'fast']],
9301
- [[16], 5]
9302
- ]
9303
- ]
9304
- ],
9305
- [
9306
- 'be',
9307
- [
9308
- [[[16], 5]],
9309
- [
9310
- [
9311
- [10, 17],
9312
- 0,
9313
- ['custom', 'bend', 'release', 'bendrelease', 'hold', 'prebend', 'prebendbend', 'prebendrelease']
9314
- ],
9315
- [[16], 5]
9316
- ],
9317
- [
9318
- [[10, 17], 0, ['default', 'gradual', 'fast']],
9319
- [[16], 5]
9320
- ],
9321
- [
9322
- [
9323
- [10, 17],
9324
- 0,
9325
- ['custom', 'bend', 'release', 'bendrelease', 'hold', 'prebend', 'prebendbend', 'prebendrelease']
9326
- ],
9327
- [[10, 17], 0, ['default', 'gradual', 'fast']],
9328
- [[16], 5]
9329
- ]
9330
- ]
9331
- ],
9332
- ['lf', [[[[16], 0, ['1', '2', '3', '4', '5']]]]],
9333
- ['rf', [[[[16], 0, ['1', '2', '3', '4', '5']]]]],
9334
- [
9335
- 'acc',
9336
- [
9337
- [
9338
- [
9339
- [10, 17],
9340
- 0,
9341
- [
9342
- 'default',
9343
- 'forcenone',
9344
- 'forcenatural',
9345
- 'forcesharp',
9346
- 'forcedoublesharp',
9347
- 'forceflat',
9348
- 'forcedoubleflat',
9349
- 'd',
9350
- '-',
9351
- 'n',
9352
- '#',
9353
- '##',
9354
- 'x',
9355
- 'b',
9356
- 'bb'
9357
- ]
9358
- ]
9359
- ]
9360
- ]
9361
- ],
9362
- ['slur', [[[[17], 0]], [[[10], 0]]]],
9363
- ['-', null]
8724
+ ["nh", null],
8725
+ ["ah", [[[[16], 1]]]],
8726
+ ["th", [[[[16], 1]]]],
8727
+ ["ph", [[[[16], 1]]]],
8728
+ ["sh", [[[[16], 1]]]],
8729
+ ["fh", [[[[16], 1]]]],
8730
+ ["v", null],
8731
+ ["vw", null],
8732
+ ["sl", null],
8733
+ ["ss", null],
8734
+ ["sib", null],
8735
+ ["sia", null],
8736
+ ["sou", null],
8737
+ ["sod", null],
8738
+ ["psu", null],
8739
+ ["psd", null],
8740
+ ["h", null],
8741
+ ["lht", null],
8742
+ ["g", null],
8743
+ ["ac", null],
8744
+ ["hac", null],
8745
+ ["ten", null],
8746
+ ["tr", [[[[16], 0], [[16], 1, ["16", "32", "64"]]]]],
8747
+ ["pm", null],
8748
+ ["st", null],
8749
+ ["lr", null],
8750
+ ["x", null],
8751
+ ["t", null],
8752
+ ["turn", null],
8753
+ ["iturn", null],
8754
+ ["umordent", null],
8755
+ ["lmordent", null],
8756
+ ["string", null],
8757
+ ["hide", null],
8758
+ ["b", [[[[16], 5]], [[[10, 17], 0, ["custom", "bend", "release", "bendrelease", "hold", "prebend", "prebendbend", "prebendrelease"]], [[16], 5]], [[[10, 17], 0, ["default", "gradual", "fast"]], [[16], 5]], [[[10, 17], 0, ["custom", "bend", "release", "bendrelease", "hold", "prebend", "prebendbend", "prebendrelease"]], [[10, 17], 0, ["default", "gradual", "fast"]], [[16], 5]]]],
8759
+ ["be", [[[[16], 5]], [[[10, 17], 0, ["custom", "bend", "release", "bendrelease", "hold", "prebend", "prebendbend", "prebendrelease"]], [[16], 5]], [[[10, 17], 0, ["default", "gradual", "fast"]], [[16], 5]], [[[10, 17], 0, ["custom", "bend", "release", "bendrelease", "hold", "prebend", "prebendbend", "prebendrelease"]], [[10, 17], 0, ["default", "gradual", "fast"]], [[16], 5]]]],
8760
+ ["lf", [[[[16], 0, ["1", "2", "3", "4", "5"]]]]],
8761
+ ["rf", [[[[16], 0, ["1", "2", "3", "4", "5"]]]]],
8762
+ ["acc", [[[[10, 17], 0, ["default", "forcenone", "forcenatural", "forcesharp", "forcedoublesharp", "forceflat", "forcedoubleflat", "d", "-", "n", "#", "##", "x", "b", "bb"]]]]],
8763
+ ["slur", [[[[17], 0]], [[[10], 0]]]],
8764
+ ["-", null]
9364
8765
  ]);
9365
8766
  }
9366
8767
 
@@ -9590,6 +8991,14 @@ var AlphaTexAccidentalMode;
9590
8991
  AlphaTexAccidentalMode[AlphaTexAccidentalMode["Auto"] = 0] = "Auto";
9591
8992
  AlphaTexAccidentalMode[AlphaTexAccidentalMode["Explicit"] = 1] = "Explicit";
9592
8993
  })(AlphaTexAccidentalMode || (AlphaTexAccidentalMode = {}));
8994
+ /**
8995
+ * @public
8996
+ */
8997
+ var AlphaTexVoiceMode;
8998
+ (function (AlphaTexVoiceMode) {
8999
+ AlphaTexVoiceMode[AlphaTexVoiceMode["StaffWise"] = 0] = "StaffWise";
9000
+ AlphaTexVoiceMode[AlphaTexVoiceMode["BarWise"] = 1] = "BarWise";
9001
+ })(AlphaTexVoiceMode || (AlphaTexVoiceMode = {}));
9593
9002
  /**
9594
9003
  * Lists the note kinds we can detect
9595
9004
  * @public
@@ -14227,6 +13636,8 @@ class AlphaTex1LanguageHandler {
14227
13636
  return ApplyNodeResult.Applied;
14228
13637
  case 'accidentals':
14229
13638
  return AlphaTex1LanguageHandler._handleAccidentalMode(importer, metaData.arguments);
13639
+ case 'voicemode':
13640
+ return AlphaTex1LanguageHandler._handleVoiceMode(importer, metaData.arguments);
14230
13641
  case 'jump':
14231
13642
  const direction = AlphaTex1LanguageHandler._parseEnumValue(importer, metaData.arguments, 'direction', AlphaTex1EnumMappings.direction);
14232
13643
  if (direction === undefined) {
@@ -14299,6 +13710,14 @@ class AlphaTex1LanguageHandler {
14299
13710
  importer.state.accidentalMode = accidentalMode;
14300
13711
  return ApplyNodeResult.Applied;
14301
13712
  }
13713
+ static _handleVoiceMode(importer, args) {
13714
+ const voiceMode = AlphaTex1LanguageHandler._parseEnumValue(importer, args, 'voice mode', AlphaTex1EnumMappings.alphaTexVoiceMode);
13715
+ if (voiceMode === undefined) {
13716
+ return ApplyNodeResult.NotAppliedSemanticError;
13717
+ }
13718
+ importer.state.voiceMode = voiceMode;
13719
+ return ApplyNodeResult.Applied;
13720
+ }
14302
13721
  static _getChordId(currentStaff, chordName) {
14303
13722
  return chordName.toLowerCase() + currentStaff.index + currentStaff.track.index;
14304
13723
  }
@@ -16553,6 +15972,7 @@ class AlphaTexImportState {
16553
15972
  syncPoints = [];
16554
15973
  currentDynamics = DynamicValue.F;
16555
15974
  accidentalMode = AlphaTexAccidentalMode.Explicit;
15975
+ voiceMode = AlphaTexVoiceMode.StaffWise;
16556
15976
  currentTupletNumerator = -1;
16557
15977
  currentTupletDenominator = -1;
16558
15978
  scoreNode;
@@ -16693,18 +16113,37 @@ class AlphaTexImporter extends ScoreImporter {
16693
16113
  }
16694
16114
  _bars(node) {
16695
16115
  if (node.bars.length > 0) {
16116
+ let previousBarCompleted = false;
16696
16117
  for (const b of node.bars) {
16697
- this._bar(b);
16118
+ this._bar(b, previousBarCompleted);
16119
+ switch (this.state.voiceMode) {
16120
+ case AlphaTexVoiceMode.StaffWise:
16121
+ // if voices are staff-wise, we definitly have a new bar here
16122
+ this._state.barIndex++;
16123
+ previousBarCompleted = true;
16124
+ break;
16125
+ case AlphaTexVoiceMode.BarWise:
16126
+ // if voices are bar-wise, the next bar might be another voice in the same bar
16127
+ // (barIndex increment is handled inside _barMeta)
16128
+ // if we have an explicit bar end, we can increase already
16129
+ if (b.pipe) {
16130
+ this._state.barIndex++;
16131
+ this._state.voiceIndex = 0;
16132
+ this._state.ignoredInitialVoice = false;
16133
+ previousBarCompleted = true;
16134
+ }
16135
+ break;
16136
+ }
16698
16137
  }
16699
16138
  }
16700
16139
  else {
16701
- this._newBar(this._state.currentStaff);
16140
+ this._getBar(this._state.currentStaff);
16702
16141
  this._detectTuningForStaff(this._state.currentStaff);
16703
16142
  this._handleTransposition(this._state.currentStaff);
16704
16143
  }
16705
16144
  }
16706
- _bar(node) {
16707
- const bar = this._barMeta(node);
16145
+ _bar(node, previousBarCompleted) {
16146
+ const bar = this._barMeta(node, previousBarCompleted);
16708
16147
  this._detectTuningForStaff(this._state.currentStaff);
16709
16148
  this._handleTransposition(this._state.currentStaff);
16710
16149
  if (bar.index === 0 && this._state.staffInitialClef.has(this._state.currentStaff)) {
@@ -17154,7 +16593,7 @@ class AlphaTexImporter extends ScoreImporter {
17154
16593
  this._state.staffTuningApplied.add(staff);
17155
16594
  }
17156
16595
  }
17157
- _barMeta(node) {
16596
+ _barMeta(node, previousBarCompleted) {
17158
16597
  // it might be a bit an edge case but a valid one:
17159
16598
  // one might repeat multiple structural metadata
17160
16599
  // in one bar starting multiple tracks/staves/voices which are
@@ -17169,6 +16608,7 @@ class AlphaTexImporter extends ScoreImporter {
17169
16608
  let previousStaff = this._state.currentStaff;
17170
16609
  let hadNewTrack = false;
17171
16610
  let hadNewStaff = false;
16611
+ let hadNewVoice = false;
17172
16612
  let applyInitialBarMetaToPreviousStaff = false;
17173
16613
  const resetInitialBarMeta = () => {
17174
16614
  // reset state
@@ -17179,10 +16619,16 @@ class AlphaTexImporter extends ScoreImporter {
17179
16619
  previousStaff = this._state.currentStaff;
17180
16620
  hadNewTrack = false;
17181
16621
  hadNewStaff = false;
16622
+ hadNewVoice = false;
17182
16623
  applyInitialBarMetaToPreviousStaff = false;
17183
16624
  };
17184
16625
  const bar = new Lazy(() => {
17185
- const b = this._newBar(this._state.currentStaff);
16626
+ // had a \voice in this bar -> barIndex and voice were updated already
16627
+ // if not, we start a new bar here
16628
+ if (!hadNewVoice && !previousBarCompleted) {
16629
+ this._state.barIndex++;
16630
+ }
16631
+ const b = this._getBar(this._state.currentStaff);
17186
16632
  if (initialBarMeta) {
17187
16633
  for (const initial of initialBarMeta) {
17188
16634
  this._handler.applyBarMetaData(this, b, initial);
@@ -17224,6 +16670,9 @@ class AlphaTexImporter extends ScoreImporter {
17224
16670
  // new bar needed on new structural level
17225
16671
  bar.reset();
17226
16672
  break;
16673
+ case ApplyStructuralMetaDataResult.AppliedNewVoice:
16674
+ hadNewVoice = true;
16675
+ break;
17227
16676
  }
17228
16677
  if (initialBarMeta) {
17229
16678
  if (applyInitialBarMetaToPreviousStaff) {
@@ -17283,14 +16732,13 @@ class AlphaTexImporter extends ScoreImporter {
17283
16732
  }
17284
16733
  return bar.value;
17285
16734
  }
17286
- _newBar(staff) {
16735
+ _getBar(staff) {
17287
16736
  // existing bar? -> e.g. in multi-voice setups where we fill empty voices later
17288
16737
  if (this._state.barIndex < staff.bars.length) {
17289
16738
  const bar = staff.bars[this._state.barIndex];
17290
- this._state.barIndex++;
17291
16739
  return bar;
17292
16740
  }
17293
- const voiceCount = staff.bars.length === 0 ? 1 : staff.bars[0].voices.length;
16741
+ const voiceCount = staff.bars.length === 0 ? this._state.voiceIndex + 1 : staff.bars[0].voices.length;
17294
16742
  // need new bar
17295
16743
  const newBar = new Bar();
17296
16744
  staff.addBar(newBar);
@@ -17300,7 +16748,7 @@ class AlphaTexImporter extends ScoreImporter {
17300
16748
  newBar.keySignature = newBar.previousBar.keySignature;
17301
16749
  newBar.keySignatureType = newBar.previousBar.keySignatureType;
17302
16750
  }
17303
- this._state.barIndex++;
16751
+ this._state.barIndex = newBar.index;
17304
16752
  if (newBar.index > 0) {
17305
16753
  newBar.clef = newBar.previousBar.clef;
17306
16754
  }
@@ -17354,26 +16802,62 @@ class AlphaTexImporter extends ScoreImporter {
17354
16802
  return this._state.currentTrack;
17355
16803
  }
17356
16804
  startNewVoice() {
17357
- if (this._state.voiceIndex === 0 &&
17358
- (this._state.currentStaff.bars.length === 0 ||
17359
- (this._state.currentStaff.bars.length === 1 &&
17360
- this._state.currentStaff.bars[0].isEmpty &&
17361
- !this._state.ignoredInitialVoice))) {
17362
- // voice marker on the begining of the first voice without any bar yet?
17363
- // -> ignore
16805
+ // only if we're on the first voice we might skip the initial \voice meta
16806
+ let shouldIgnoreInitialVoice = this._state.voiceIndex === 0 && !this._state.ignoredInitialVoice;
16807
+ // this logic is expanded for readability
16808
+ if (shouldIgnoreInitialVoice) {
16809
+ // if we have no bars created yet, we stay on the initial voice
16810
+ if (this._state.currentStaff.bars.length === 0) {
16811
+ shouldIgnoreInitialVoice = true;
16812
+ }
16813
+ else {
16814
+ switch (this._state.voiceMode) {
16815
+ case AlphaTexVoiceMode.StaffWise:
16816
+ // on staffwise voices, we can only ignore the "initial" voice if the
16817
+ // first bar we have is completely empty
16818
+ shouldIgnoreInitialVoice =
16819
+ this._state.currentStaff.bars.length === 1 && this._state.currentStaff.bars[0].isEmpty;
16820
+ break;
16821
+ case AlphaTexVoiceMode.BarWise:
16822
+ // on barwise voices, we ignore the bar count but check only the first voice of the current bar
16823
+ // to find out if it is the initial empty one
16824
+ if (this._state.barIndex < this._state.currentStaff.bars.length) {
16825
+ // bar exists -> check if empty
16826
+ const bar = this._state.currentStaff.bars[this._state.barIndex];
16827
+ shouldIgnoreInitialVoice = bar.voices[0].isEmpty;
16828
+ }
16829
+ else {
16830
+ // bar doesn't exist yet
16831
+ shouldIgnoreInitialVoice = true;
16832
+ }
16833
+ break;
16834
+ }
16835
+ }
16836
+ }
16837
+ if (shouldIgnoreInitialVoice) {
17364
16838
  this._state.ignoredInitialVoice = true;
17365
16839
  return;
17366
16840
  }
17367
- // create directly a new empty voice for all bars
16841
+ switch (this._state.voiceMode) {
16842
+ case AlphaTexVoiceMode.StaffWise:
16843
+ // start using the new voice (see newBar for details on matching)
16844
+ this._state.voiceIndex++;
16845
+ this._state.barIndex = 0;
16846
+ this._state.currentTupletDenominator = -1;
16847
+ this._state.currentTupletNumerator = -1;
16848
+ break;
16849
+ case AlphaTexVoiceMode.BarWise:
16850
+ this._state.voiceIndex++;
16851
+ this._state.currentTupletDenominator = -1;
16852
+ this._state.currentTupletNumerator = -1;
16853
+ break;
16854
+ }
16855
+ // create all missing voices
17368
16856
  for (const b of this._state.currentStaff.bars) {
17369
- const v = new Voice$1();
17370
- b.addVoice(v);
16857
+ while (b.voices.length <= this._state.voiceIndex) {
16858
+ b.addVoice(new Voice$1());
16859
+ }
17371
16860
  }
17372
- // start using the new voice (see newBar for details on matching)
17373
- this._state.voiceIndex++;
17374
- this._state.barIndex = 0;
17375
- this._state.currentTupletDenominator = -1;
17376
- this._state.currentTupletNumerator = -1;
17377
16861
  }
17378
16862
  }
17379
16863
 
@@ -48297,6 +47781,39 @@ class MidiFileGenerator {
48297
47781
  }
48298
47782
  }
48299
47783
 
47784
+ /**
47785
+ * Lists the different position modes for {@link BarRendererBase.getBeatX}
47786
+ * @internal
47787
+ */
47788
+ var BeatXPosition;
47789
+ (function (BeatXPosition) {
47790
+ /**
47791
+ * Gets the pre-notes position which is located before the accidentals
47792
+ */
47793
+ BeatXPosition[BeatXPosition["PreNotes"] = 0] = "PreNotes";
47794
+ /**
47795
+ * Gets the on-notes position which is located after the accidentals but before the note heads.
47796
+ */
47797
+ BeatXPosition[BeatXPosition["OnNotes"] = 1] = "OnNotes";
47798
+ /**
47799
+ * Gets the middle-notes position which is located after in the exact center of the note heads.
47800
+ */
47801
+ BeatXPosition[BeatXPosition["MiddleNotes"] = 2] = "MiddleNotes";
47802
+ /**
47803
+ * Gets position of the stem for this beat
47804
+ */
47805
+ BeatXPosition[BeatXPosition["Stem"] = 3] = "Stem";
47806
+ /**
47807
+ * Get the post-notes position which is located at after the note heads.
47808
+ */
47809
+ BeatXPosition[BeatXPosition["PostNotes"] = 4] = "PostNotes";
47810
+ /**
47811
+ * Get the end-beat position which is located at the end of the beat. This position is almost
47812
+ * equal to the pre-notes position of the next beat.
47813
+ */
47814
+ BeatXPosition[BeatXPosition["EndBeat"] = 5] = "EndBeat";
47815
+ })(BeatXPosition || (BeatXPosition = {}));
47816
+
48300
47817
  /**
48301
47818
  * A glyph is a single symbol which can be added to a GlyphBarRenderer for automated
48302
47819
  * layouting and drawing of stacked symbols.
@@ -48324,198 +47841,6 @@ class Glyph {
48324
47841
  }
48325
47842
  }
48326
47843
 
48327
- /**
48328
- * Effect-Glyphs implementing this public interface get notified
48329
- * as they are expanded over multiple beats.
48330
- * @internal
48331
- */
48332
- class EffectGlyph extends Glyph {
48333
- /**
48334
- * Gets or sets the beat where the glyph belongs to.
48335
- */
48336
- beat = null;
48337
- /**
48338
- * Gets or sets the next glyph of the same type in case
48339
- * the effect glyph is expanded when using {@link EffectBarGlyphSizing.groupedOnBeat}.
48340
- */
48341
- nextGlyph = null;
48342
- /**
48343
- * Gets or sets the previous glyph of the same type in case
48344
- * the effect glyph is expanded when using {@link EffectBarGlyphSizing.groupedOnBeat}.
48345
- */
48346
- previousGlyph = null;
48347
- constructor(x = 0, y = 0) {
48348
- super(x, y);
48349
- }
48350
- }
48351
-
48352
- /**
48353
- * @internal
48354
- */
48355
- class MusicFontGlyph extends EffectGlyph {
48356
- glyphScale = 0;
48357
- symbol;
48358
- center = false;
48359
- colorOverride;
48360
- offsetX = 0;
48361
- offsetY = 0;
48362
- constructor(x, y, glyphScale, symbol) {
48363
- super(x, y);
48364
- this.glyphScale = glyphScale;
48365
- this.symbol = symbol;
48366
- }
48367
- getBoundingBoxTop() {
48368
- const bBoxTop = this.renderer.smuflMetrics.glyphTop.get(this.symbol);
48369
- return this.y - this.offsetY - bBoxTop;
48370
- }
48371
- doLayout() {
48372
- this.width = this.renderer.smuflMetrics.glyphWidths.get(this.symbol) * this.glyphScale;
48373
- this.height = this.renderer.smuflMetrics.glyphHeights.get(this.symbol) * this.glyphScale;
48374
- }
48375
- paint(cx, cy, canvas) {
48376
- if (this.width === 0 && this.height === 0) {
48377
- return;
48378
- }
48379
- const c = canvas.color;
48380
- if (this.colorOverride) {
48381
- canvas.color = this.colorOverride;
48382
- }
48383
- canvas.fillMusicFontSymbol(cx + this.x + this.offsetX, cy + this.y + this.offsetY, this.glyphScale, this.symbol, this.center);
48384
- canvas.color = c;
48385
- }
48386
- }
48387
- /**
48388
- * @internal
48389
- */
48390
- class MusicFontTextGlyph extends EffectGlyph {
48391
- glyphScale = 0;
48392
- symbols;
48393
- center = false;
48394
- colorOverride;
48395
- offsetX = 0;
48396
- offsetY = 0;
48397
- constructor(x, y, glyphScale, symbols) {
48398
- super(x, y);
48399
- this.glyphScale = glyphScale;
48400
- this.symbols = symbols;
48401
- }
48402
- getBoundingBoxTop() {
48403
- let bBoxTop = 0;
48404
- for (let i = 0; i < this.symbols.length; i++) {
48405
- const gTop = this.renderer.smuflMetrics.glyphTop.get(this.symbols[i]);
48406
- if (i === 0 || gTop < bBoxTop) {
48407
- bBoxTop = gTop;
48408
- }
48409
- }
48410
- return this.y - this.offsetY - bBoxTop;
48411
- }
48412
- doLayout() {
48413
- this.width = 0;
48414
- this.height = 0;
48415
- for (let i = 0; i < this.symbols.length; i++) {
48416
- const gWidth = this.renderer.smuflMetrics.glyphWidths.get(this.symbols[i]) * this.glyphScale;
48417
- const gHeight = this.renderer.smuflMetrics.glyphHeights.get(this.symbols[i]) * this.glyphScale;
48418
- if (i === 0 || gWidth > this.width) {
48419
- this.width = gWidth;
48420
- }
48421
- if (i === 0 || gHeight > this.height) {
48422
- this.height = gHeight;
48423
- }
48424
- }
48425
- }
48426
- paint(cx, cy, canvas) {
48427
- if (this.width === 0 && this.height === 0) {
48428
- return;
48429
- }
48430
- const c = canvas.color;
48431
- if (this.colorOverride) {
48432
- canvas.color = this.colorOverride;
48433
- }
48434
- canvas.fillMusicFontSymbols(cx + this.x + this.offsetX, cy + this.y + this.offsetY, this.glyphScale, this.symbols, this.center);
48435
- canvas.color = c;
48436
- }
48437
- }
48438
-
48439
- /**
48440
- * @internal
48441
- */
48442
- class NoteHeadGlyph extends MusicFontGlyph {
48443
- // TODO: SmuFL
48444
- static GraceScale = 0.75;
48445
- centerOnStem = false;
48446
- constructor(x, y, duration, isGrace) {
48447
- super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, NoteHeadGlyph.getSymbol(duration));
48448
- }
48449
- paint(cx, cy, canvas) {
48450
- if (this.centerOnStem) {
48451
- this.center = true;
48452
- }
48453
- super.paint(cx, cy, canvas);
48454
- }
48455
- static getSymbol(duration) {
48456
- switch (duration) {
48457
- case Duration.QuadrupleWhole:
48458
- return MusicFontSymbol.NoteheadDoubleWholeSquare;
48459
- case Duration.DoubleWhole:
48460
- return MusicFontSymbol.NoteheadDoubleWhole;
48461
- case Duration.Whole:
48462
- return MusicFontSymbol.NoteheadWhole;
48463
- case Duration.Half:
48464
- return MusicFontSymbol.NoteheadHalf;
48465
- default:
48466
- return MusicFontSymbol.NoteheadBlack;
48467
- }
48468
- }
48469
- }
48470
-
48471
- /**
48472
- * @internal
48473
- */
48474
- class FlagGlyph extends MusicFontGlyph {
48475
- constructor(x, y, duration, direction, isGrace) {
48476
- super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, FlagGlyph.getSymbol(duration, direction, isGrace));
48477
- }
48478
- static getSymbol(duration, direction, isGrace) {
48479
- if (isGrace) {
48480
- duration = Duration.Eighth;
48481
- }
48482
- if (direction === BeamDirection.Up) {
48483
- switch (duration) {
48484
- case Duration.Eighth:
48485
- return MusicFontSymbol.Flag8thUp;
48486
- case Duration.Sixteenth:
48487
- return MusicFontSymbol.Flag16thUp;
48488
- case Duration.ThirtySecond:
48489
- return MusicFontSymbol.Flag32ndUp;
48490
- case Duration.SixtyFourth:
48491
- return MusicFontSymbol.Flag64thUp;
48492
- case Duration.OneHundredTwentyEighth:
48493
- return MusicFontSymbol.Flag128thUp;
48494
- case Duration.TwoHundredFiftySixth:
48495
- return MusicFontSymbol.Flag256thUp;
48496
- default:
48497
- return MusicFontSymbol.Flag8thUp;
48498
- }
48499
- }
48500
- switch (duration) {
48501
- case Duration.Eighth:
48502
- return MusicFontSymbol.Flag8thDown;
48503
- case Duration.Sixteenth:
48504
- return MusicFontSymbol.Flag16thDown;
48505
- case Duration.ThirtySecond:
48506
- return MusicFontSymbol.Flag32ndDown;
48507
- case Duration.SixtyFourth:
48508
- return MusicFontSymbol.Flag64thDown;
48509
- case Duration.OneHundredTwentyEighth:
48510
- return MusicFontSymbol.Flag128thDown;
48511
- case Duration.TwoHundredFiftySixth:
48512
- return MusicFontSymbol.Flag128thDown;
48513
- default:
48514
- return MusicFontSymbol.Flag8thDown;
48515
- }
48516
- }
48517
- }
48518
-
48519
47844
  /**
48520
47845
  * @internal
48521
47846
  */
@@ -48542,28 +47867,20 @@ class BeatContainerGlyph extends Glyph {
48542
47867
  this.renderer.registerTie(tie);
48543
47868
  }
48544
47869
  getBoundingBoxTop() {
48545
- return Math.min(this.preNotes.getBoundingBoxTop(), this.onNotes.getBoundingBoxTop());
47870
+ return ModelUtils.minBoundingBox(this.preNotes.getBoundingBoxTop(), this.onNotes.getBoundingBoxTop());
48546
47871
  }
48547
47872
  getBoundingBoxBottom() {
48548
- return Math.max(this.preNotes.getBoundingBoxBottom(), this.onNotes.getBoundingBoxBottom());
47873
+ return ModelUtils.maxBoundingBox(this.preNotes.getBoundingBoxBottom(), this.onNotes.getBoundingBoxBottom());
48549
47874
  }
48550
47875
  drawBeamHelperAsFlags(helper) {
48551
47876
  return helper.hasFlag(false, undefined);
48552
47877
  }
47878
+ get postBeatStretch() {
47879
+ return this.onNotes.computedWidth - this.onNotes.onTimeX;
47880
+ }
48553
47881
  registerLayoutingInfo(layoutings) {
48554
47882
  const preBeatStretch = this.preNotes.computedWidth + this.onNotes.onTimeX;
48555
- let postBeatStretch = this.onNotes.computedWidth - this.onNotes.onTimeX;
48556
- // make space for flag
48557
- const helper = this.renderer.helpers.getBeamingHelperForBeat(this.beat);
48558
- if (this.beat.graceType !== GraceType.None) {
48559
- // always use flag size as spacing on grace notes
48560
- postBeatStretch +=
48561
- this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
48562
- }
48563
- else if (helper && this.drawBeamHelperAsFlags(helper)) {
48564
- postBeatStretch +=
48565
- this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
48566
- }
47883
+ let postBeatStretch = this.postBeatStretch;
48567
47884
  for (const tie of this._ties) {
48568
47885
  const tg = tie;
48569
47886
  postBeatStretch += tg.width;
@@ -48578,7 +47895,6 @@ class BeatContainerGlyph extends Glyph {
48578
47895
  });
48579
47896
  }
48580
47897
  applyLayoutingInfo(_info) {
48581
- this.onNotes.updateBeamingHelper();
48582
47898
  this.updateWidth();
48583
47899
  }
48584
47900
  doLayout() {
@@ -48590,7 +47906,6 @@ class BeatContainerGlyph extends Glyph {
48590
47906
  this.onNotes.renderer = this.renderer;
48591
47907
  this.onNotes.container = this;
48592
47908
  this.onNotes.doLayout();
48593
- this.onNotes.updateBeamingHelper();
48594
47909
  let i = this.beat.notes.length - 1;
48595
47910
  while (i >= 0) {
48596
47911
  this.createTies(this.beat.notes[i--]);
@@ -48599,15 +47914,6 @@ class BeatContainerGlyph extends Glyph {
48599
47914
  }
48600
47915
  updateWidth() {
48601
47916
  this.minWidth = this.preNotes.width + this.onNotes.width;
48602
- if (!this.beat.isRest) {
48603
- if (this.onNotes.beamingHelper.beats.length === 1) {
48604
- // make space for flag
48605
- if (this.beat.duration >= Duration.Eighth) {
48606
- const symbol = FlagGlyph.getSymbol(this.beat.duration, this.onNotes.beamingHelper.direction, this.beat.graceType !== GraceType.None);
48607
- this.minWidth += this.renderer.smuflMetrics.glyphWidths.get(symbol);
48608
- }
48609
- }
48610
- }
48611
47917
  let tieWidth = 0;
48612
47918
  for (const tie of this._ties) {
48613
47919
  const tg = tie;
@@ -48618,10 +47924,6 @@ class BeatContainerGlyph extends Glyph {
48618
47924
  this.minWidth += tieWidth;
48619
47925
  this.width = this.minWidth;
48620
47926
  }
48621
- scaleToWidth(beatWidth) {
48622
- this.onNotes.updateBeamingHelper();
48623
- this.width = beatWidth;
48624
- }
48625
47927
  createTies(_n) {
48626
47928
  }
48627
47929
  static getGroupId(beat) {
@@ -48631,8 +47933,11 @@ class BeatContainerGlyph extends Glyph {
48631
47933
  // var c = canvas.color;
48632
47934
  // canvas.color = Color.random();
48633
47935
  // canvas.fillRect(cx + this.x, cy + this.y + this.preNotes.getBoundingBoxTop(), this.width, this.renderer.height);
48634
- // canvas.color = Color.random();
48635
47936
  // canvas.fillRect(cx + this.x, cy + this.y + this.onNotes.getBoundingBoxTop(), this.width, this.renderer.height);
47937
+ // canvas.color = Color.random();
47938
+ // const top = this.getBoundingBoxTop();
47939
+ // const bottom = this.getBoundingBoxBottom();
47940
+ // canvas.fillRect(cx + this.x, cy + this.y + top, this.width, bottom-top);
48636
47941
  // canvas.color = c;
48637
47942
  // var c = canvas.color;
48638
47943
  // var ta = canvas.textAlign;
@@ -48711,7 +48016,7 @@ class BeatContainerGlyph extends Glyph {
48711
48016
  }
48712
48017
  let visualEndX = 0;
48713
48018
  if (!this.onNotes.isEmpty) {
48714
- visualEndX = cx + this.x + this.onNotes.x + this.onNotes.width;
48019
+ visualEndX = cx + this.x + this.onNotes.x + this.onNotes.onTimeX + this.postBeatStretch;
48715
48020
  }
48716
48021
  else if (!this.preNotes.isEmpty) {
48717
48022
  visualEndX = cx + this.x + this.preNotes.x + this.preNotes.width;
@@ -48720,12 +48025,6 @@ class BeatContainerGlyph extends Glyph {
48720
48025
  visualEndX = cx + this.x + this.width;
48721
48026
  }
48722
48027
  beatBoundings.visualBounds.w = visualEndX - beatBoundings.visualBounds.x;
48723
- const helper = this.renderer.helpers.getBeamingHelperForBeat(this.beat);
48724
- if ((helper && this.drawBeamHelperAsFlags(helper)) || this.beat.graceType !== GraceType.None) {
48725
- beatBoundings.visualBounds.w +=
48726
- this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) *
48727
- (this.beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1);
48728
- }
48729
48028
  beatBoundings.visualBounds.y = barBounds.visualBounds.y;
48730
48029
  beatBoundings.visualBounds.h = barBounds.visualBounds.h;
48731
48030
  beatBoundings.realBounds = new Bounds();
@@ -48740,6 +48039,26 @@ class BeatContainerGlyph extends Glyph {
48740
48039
  this.onNotes.buildBoundingsLookup(beatBoundings, cx + this.x, cy + this.y);
48741
48040
  }
48742
48041
  }
48042
+ getBeatX(requestedPosition, useSharedSizes = false) {
48043
+ switch (requestedPosition) {
48044
+ case BeatXPosition.PreNotes:
48045
+ return this.preNotes.x;
48046
+ case BeatXPosition.OnNotes:
48047
+ return this.onNotes.x;
48048
+ case BeatXPosition.MiddleNotes:
48049
+ return this.onNotes.x + this.onNotes.middleX;
48050
+ case BeatXPosition.Stem:
48051
+ return this.onNotes.x + this.onNotes.stemX;
48052
+ case BeatXPosition.PostNotes:
48053
+ const onNoteSize = useSharedSizes
48054
+ ? (this.renderer.layoutingInfo.getBeatSizes(this.beat)?.onBeatSize ?? this.onNotes.width)
48055
+ : this.onNotes.width;
48056
+ return this.onNotes.x + onNoteSize;
48057
+ case BeatXPosition.EndBeat:
48058
+ return this.width;
48059
+ }
48060
+ return this.preNotes.x;
48061
+ }
48743
48062
  }
48744
48063
 
48745
48064
  /**
@@ -56498,6 +55817,31 @@ var EffectBarGlyphSizing;
56498
55817
  EffectBarGlyphSizing[EffectBarGlyphSizing["FullBar"] = 5] = "FullBar";
56499
55818
  })(EffectBarGlyphSizing || (EffectBarGlyphSizing = {}));
56500
55819
 
55820
+ /**
55821
+ * Effect-Glyphs implementing this public interface get notified
55822
+ * as they are expanded over multiple beats.
55823
+ * @internal
55824
+ */
55825
+ class EffectGlyph extends Glyph {
55826
+ /**
55827
+ * Gets or sets the beat where the glyph belongs to.
55828
+ */
55829
+ beat = null;
55830
+ /**
55831
+ * Gets or sets the next glyph of the same type in case
55832
+ * the effect glyph is expanded when using {@link EffectBarGlyphSizing.groupedOnBeat}.
55833
+ */
55834
+ nextGlyph = null;
55835
+ /**
55836
+ * Gets or sets the previous glyph of the same type in case
55837
+ * the effect glyph is expanded when using {@link EffectBarGlyphSizing.groupedOnBeat}.
55838
+ */
55839
+ previousGlyph = null;
55840
+ constructor(x = 0, y = 0) {
55841
+ super(x, y);
55842
+ }
55843
+ }
55844
+
56501
55845
  /**
56502
55846
  * @internal
56503
55847
  */
@@ -56625,39 +55969,6 @@ class AlternateEndingsEffectInfo extends EffectInfo {
56625
55969
  }
56626
55970
  }
56627
55971
 
56628
- /**
56629
- * Lists the different position modes for {@link BarRendererBase.getBeatX}
56630
- * @internal
56631
- */
56632
- var BeatXPosition;
56633
- (function (BeatXPosition) {
56634
- /**
56635
- * Gets the pre-notes position which is located before the accidentals
56636
- */
56637
- BeatXPosition[BeatXPosition["PreNotes"] = 0] = "PreNotes";
56638
- /**
56639
- * Gets the on-notes position which is located after the accidentals but before the note heads.
56640
- */
56641
- BeatXPosition[BeatXPosition["OnNotes"] = 1] = "OnNotes";
56642
- /**
56643
- * Gets the middle-notes position which is located after in the exact center of the note heads.
56644
- */
56645
- BeatXPosition[BeatXPosition["MiddleNotes"] = 2] = "MiddleNotes";
56646
- /**
56647
- * Gets position of the stem for this beat
56648
- */
56649
- BeatXPosition[BeatXPosition["Stem"] = 3] = "Stem";
56650
- /**
56651
- * Get the post-notes position which is located at after the note heads.
56652
- */
56653
- BeatXPosition[BeatXPosition["PostNotes"] = 4] = "PostNotes";
56654
- /**
56655
- * Get the end-beat position which is located at the end of the beat. This position is almost
56656
- * equal to the pre-notes position of the next beat.
56657
- */
56658
- BeatXPosition[BeatXPosition["EndBeat"] = 5] = "EndBeat";
56659
- })(BeatXPosition || (BeatXPosition = {}));
56660
-
56661
55972
  /**
56662
55973
  * @internal
56663
55974
  */
@@ -57256,6 +56567,93 @@ class DirectionsEffectInfo extends EffectInfo {
57256
56567
  }
57257
56568
  }
57258
56569
 
56570
+ /**
56571
+ * @internal
56572
+ */
56573
+ class MusicFontGlyph extends EffectGlyph {
56574
+ glyphScale = 0;
56575
+ symbol;
56576
+ center = false;
56577
+ colorOverride;
56578
+ offsetX = 0;
56579
+ offsetY = 0;
56580
+ constructor(x, y, glyphScale, symbol) {
56581
+ super(x, y);
56582
+ this.glyphScale = glyphScale;
56583
+ this.symbol = symbol;
56584
+ }
56585
+ getBoundingBoxTop() {
56586
+ const bBoxTop = this.renderer.smuflMetrics.glyphTop.get(this.symbol);
56587
+ return this.y - this.offsetY - bBoxTop;
56588
+ }
56589
+ doLayout() {
56590
+ this.width = this.renderer.smuflMetrics.glyphWidths.get(this.symbol) * this.glyphScale;
56591
+ this.height = this.renderer.smuflMetrics.glyphHeights.get(this.symbol) * this.glyphScale;
56592
+ }
56593
+ paint(cx, cy, canvas) {
56594
+ if (this.width === 0 && this.height === 0) {
56595
+ return;
56596
+ }
56597
+ const c = canvas.color;
56598
+ if (this.colorOverride) {
56599
+ canvas.color = this.colorOverride;
56600
+ }
56601
+ canvas.fillMusicFontSymbol(cx + this.x + this.offsetX, cy + this.y + this.offsetY, this.glyphScale, this.symbol, this.center);
56602
+ canvas.color = c;
56603
+ }
56604
+ }
56605
+ /**
56606
+ * @internal
56607
+ */
56608
+ class MusicFontTextGlyph extends EffectGlyph {
56609
+ glyphScale = 0;
56610
+ symbols;
56611
+ center = false;
56612
+ colorOverride;
56613
+ offsetX = 0;
56614
+ offsetY = 0;
56615
+ constructor(x, y, glyphScale, symbols) {
56616
+ super(x, y);
56617
+ this.glyphScale = glyphScale;
56618
+ this.symbols = symbols;
56619
+ }
56620
+ getBoundingBoxTop() {
56621
+ let bBoxTop = 0;
56622
+ for (let i = 0; i < this.symbols.length; i++) {
56623
+ const gTop = this.renderer.smuflMetrics.glyphTop.get(this.symbols[i]);
56624
+ if (i === 0 || gTop < bBoxTop) {
56625
+ bBoxTop = gTop;
56626
+ }
56627
+ }
56628
+ return this.y - this.offsetY - bBoxTop;
56629
+ }
56630
+ doLayout() {
56631
+ this.width = 0;
56632
+ this.height = 0;
56633
+ for (let i = 0; i < this.symbols.length; i++) {
56634
+ const gWidth = this.renderer.smuflMetrics.glyphWidths.get(this.symbols[i]) * this.glyphScale;
56635
+ const gHeight = this.renderer.smuflMetrics.glyphHeights.get(this.symbols[i]) * this.glyphScale;
56636
+ if (i === 0 || gWidth > this.width) {
56637
+ this.width = gWidth;
56638
+ }
56639
+ if (i === 0 || gHeight > this.height) {
56640
+ this.height = gHeight;
56641
+ }
56642
+ }
56643
+ }
56644
+ paint(cx, cy, canvas) {
56645
+ if (this.width === 0 && this.height === 0) {
56646
+ return;
56647
+ }
56648
+ const c = canvas.color;
56649
+ if (this.colorOverride) {
56650
+ canvas.color = this.colorOverride;
56651
+ }
56652
+ canvas.fillMusicFontSymbols(cx + this.x + this.offsetX, cy + this.y + this.offsetY, this.glyphScale, this.symbols, this.center);
56653
+ canvas.color = c;
56654
+ }
56655
+ }
56656
+
57259
56657
  /**
57260
56658
  * @internal
57261
56659
  */
@@ -57494,17 +56892,6 @@ class FermataEffectInfo extends EffectInfo {
57494
56892
  }
57495
56893
  }
57496
56894
 
57497
- /**
57498
- * This simple glyph allows to put an empty region in to a BarRenderer.
57499
- * @internal
57500
- */
57501
- class SpacingGlyph extends Glyph {
57502
- constructor(x, y, width) {
57503
- super(x, y);
57504
- this.width = width;
57505
- }
57506
- }
57507
-
57508
56895
  /**
57509
56896
  * This glyph allows to group several other glyphs to be
57510
56897
  * drawn at the same x position
@@ -57520,34 +56907,20 @@ class GlyphGroup extends Glyph {
57520
56907
  const glyphs = this.glyphs;
57521
56908
  if (glyphs) {
57522
56909
  for (const g of glyphs) {
57523
- // only count real visual glyphs
57524
- if (g instanceof SpacingGlyph) {
57525
- continue;
57526
- }
57527
- const gTop = g.getBoundingBoxTop();
57528
- if (Number.isNaN(top) || gTop < top) {
57529
- top = gTop;
57530
- }
56910
+ top = ModelUtils.minBoundingBox(top, g.getBoundingBoxTop());
57531
56911
  }
57532
56912
  }
57533
- return Number.isNaN(top) ? this.y : top;
56913
+ return top;
57534
56914
  }
57535
56915
  getBoundingBoxBottom() {
57536
56916
  let bottom = Number.NaN;
57537
56917
  const glyphs = this.glyphs;
57538
56918
  if (glyphs) {
57539
56919
  for (const g of glyphs) {
57540
- // only count real visual glyphs
57541
- if (g instanceof SpacingGlyph) {
57542
- continue;
57543
- }
57544
- const gBottom = g.getBoundingBoxBottom();
57545
- if (Number.isNaN(bottom) || gBottom > bottom) {
57546
- bottom = gBottom;
57547
- }
56920
+ bottom = ModelUtils.maxBoundingBox(bottom, g.getBoundingBoxBottom());
57548
56921
  }
57549
56922
  }
57550
- return Number.isNaN(bottom) ? this.y + this.height : bottom;
56923
+ return bottom;
57551
56924
  }
57552
56925
  doLayout() {
57553
56926
  if (!this.glyphs || this.glyphs.length === 0) {
@@ -57963,6 +57336,38 @@ class FreeTimeEffectInfo extends EffectInfo {
57963
57336
  }
57964
57337
  }
57965
57338
 
57339
+ /**
57340
+ * @internal
57341
+ */
57342
+ class NoteHeadGlyph extends MusicFontGlyph {
57343
+ // TODO: SmuFL
57344
+ static GraceScale = 0.75;
57345
+ centerOnStem = false;
57346
+ constructor(x, y, duration, isGrace) {
57347
+ super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, NoteHeadGlyph.getSymbol(duration));
57348
+ }
57349
+ paint(cx, cy, canvas) {
57350
+ if (this.centerOnStem) {
57351
+ this.center = true;
57352
+ }
57353
+ super.paint(cx, cy, canvas);
57354
+ }
57355
+ static getSymbol(duration) {
57356
+ switch (duration) {
57357
+ case Duration.QuadrupleWhole:
57358
+ return MusicFontSymbol.NoteheadDoubleWholeSquare;
57359
+ case Duration.DoubleWhole:
57360
+ return MusicFontSymbol.NoteheadDoubleWhole;
57361
+ case Duration.Whole:
57362
+ return MusicFontSymbol.NoteheadWhole;
57363
+ case Duration.Half:
57364
+ return MusicFontSymbol.NoteheadHalf;
57365
+ default:
57366
+ return MusicFontSymbol.NoteheadBlack;
57367
+ }
57368
+ }
57369
+ }
57370
+
57966
57371
  /**
57967
57372
  * @internal
57968
57373
  */
@@ -59581,12 +58986,12 @@ class VoiceContainerGlyph extends GlyphGroup {
59581
58986
  // of the next glyph
59582
58987
  if (i > 0) {
59583
58988
  const beatWidth = currentBeatGlyph.x - beatGlyphs[i - 1].x;
59584
- beatGlyphs[i - 1].scaleToWidth(beatWidth);
58989
+ beatGlyphs[i - 1].width = beatWidth;
59585
58990
  }
59586
58991
  // for the last glyph size based on the full width
59587
58992
  if (i === j - 1) {
59588
58993
  const beatWidth = this.width - beatGlyphs[beatGlyphs.length - 1].x;
59589
- currentBeatGlyph.scaleToWidth(beatWidth);
58994
+ currentBeatGlyph.width = beatWidth;
59590
58995
  }
59591
58996
  }
59592
58997
  }
@@ -61286,7 +60691,7 @@ class StaffSystem {
61286
60691
  if (!masterBarBoundsLookup.has(renderer.bar.masterBar.index)) {
61287
60692
  masterBarBounds = new MasterBarBounds();
61288
60693
  masterBarBounds.index = renderer.bar.masterBar.index;
61289
- masterBarBounds.isFirstOfLine = renderer.isFirstOfLine;
60694
+ masterBarBounds.isFirstOfLine = renderer.isFirstOfStaff;
61290
60695
  masterBarBounds.realBounds = new Bounds();
61291
60696
  masterBarBounds.realBounds.x = x + renderer.x;
61292
60697
  masterBarBounds.realBounds.y = realTop;
@@ -61818,11 +61223,9 @@ class BeatGlyphBase extends GlyphGroup {
61818
61223
  * @internal
61819
61224
  */
61820
61225
  class BeatOnNoteGlyphBase extends BeatGlyphBase {
61821
- beamingHelper;
61822
61226
  onTimeX = 0;
61823
61227
  middleX = 0;
61824
- updateBeamingHelper() {
61825
- }
61228
+ stemX = 0;
61826
61229
  buildBoundingsLookup(_beatBounds, _cx, _cy) {
61827
61230
  }
61828
61231
  getNoteX(_note, _requestedPosition) {
@@ -61964,14 +61367,6 @@ class MultiBarRestBeatContainerGlyph extends BeatContainerGlyph {
61964
61367
  }
61965
61368
  }
61966
61369
 
61967
- /**
61968
- * @internal
61969
- */
61970
- class BeatLinePositions {
61971
- staffId = '';
61972
- up = 0;
61973
- down = 0;
61974
- }
61975
61370
  /**
61976
61371
  * @internal
61977
61372
  */
@@ -62002,10 +61397,7 @@ class BeamingHelperDrawInfo {
62002
61397
  */
62003
61398
  class BeamingHelper {
62004
61399
  _staff;
62005
- _beatLineXPositions = new Map();
62006
61400
  _renderer;
62007
- _firstNonRestBeat = null;
62008
- _lastNonRestBeat = null;
62009
61401
  voice = null;
62010
61402
  beats = [];
62011
61403
  shortestDuration = Duration.QuadrupleWhole;
@@ -62015,6 +61407,7 @@ class BeamingHelper {
62015
61407
  */
62016
61408
  hasTuplet = false;
62017
61409
  slashBeats = [];
61410
+ restBeats = [];
62018
61411
  lowestNoteInHelper = null;
62019
61412
  _lowestNoteCompareValueInHelper = -1;
62020
61413
  highestNoteInHelper = null;
@@ -62022,25 +61415,21 @@ class BeamingHelper {
62022
61415
  invertBeamDirection = false;
62023
61416
  preferredBeamDirection = null;
62024
61417
  graceType = GraceType.None;
62025
- minRestSteps = null;
62026
- beatOfMinRestSteps = null;
62027
- maxRestSteps = null;
62028
- beatOfMaxRestSteps = null;
62029
61418
  get isRestBeamHelper() {
62030
61419
  return this.beats.length === 1 && this.beats[0].isRest;
62031
61420
  }
62032
- hasLine(forceFlagOnSingleBeat, beat) {
62033
- return ((forceFlagOnSingleBeat && this._beatHasLine(beat)) ||
62034
- (!forceFlagOnSingleBeat && this.beats.length === 1 && this._beatHasLine(beat)));
61421
+ hasStem(forceFlagOnSingleBeat, beat) {
61422
+ return ((forceFlagOnSingleBeat && this._beatHasStem(beat)) ||
61423
+ (!forceFlagOnSingleBeat && this.beats.length === 1 && this._beatHasStem(beat)));
62035
61424
  }
62036
- _beatHasLine(beat) {
61425
+ _beatHasStem(beat) {
62037
61426
  return beat.duration > Duration.Whole;
62038
61427
  }
62039
61428
  hasFlag(forceFlagOnSingleBeat, beat) {
62040
- return ((forceFlagOnSingleBeat && this._beatHasFlag(beat)) ||
62041
- (!forceFlagOnSingleBeat && this.beats.length === 1 && this._beatHasFlag(this.beats[0])));
61429
+ return ((forceFlagOnSingleBeat && BeamingHelper.beatHasFlag(beat)) ||
61430
+ (!forceFlagOnSingleBeat && this.beats.length === 1 && BeamingHelper.beatHasFlag(this.beats[0])));
62042
61431
  }
62043
- _beatHasFlag(beat) {
61432
+ static beatHasFlag(beat) {
62044
61433
  return (!beat.deadSlapped && !beat.isRest && (beat.duration > Duration.Quarter || beat.graceType !== GraceType.None));
62045
61434
  }
62046
61435
  constructor(staff, renderer) {
@@ -62048,38 +61437,12 @@ class BeamingHelper {
62048
61437
  this._renderer = renderer;
62049
61438
  this.beats = [];
62050
61439
  }
62051
- getBeatLineX(beat, direction) {
62052
- direction = direction ?? this.direction;
62053
- if (this.hasBeatLineX(beat)) {
62054
- if (direction === BeamDirection.Up) {
62055
- return this._beatLineXPositions.get(beat.index).up;
62056
- }
62057
- return this._beatLineXPositions.get(beat.index).down;
62058
- }
62059
- return 0;
62060
- }
62061
- hasBeatLineX(beat) {
62062
- return this._beatLineXPositions.has(beat.index);
62063
- }
62064
- registerBeatLineX(staffId, beat, up, down) {
62065
- const positions = this._getOrCreateBeatPositions(beat);
62066
- positions.staffId = staffId;
62067
- positions.up = up;
62068
- positions.down = down;
61440
+ alignWithBeats() {
62069
61441
  for (const v of this.drawingInfos.values()) {
62070
- if (v.startBeat === beat) {
62071
- v.startX = this.getBeatLineX(beat);
62072
- }
62073
- else if (v.endBeat === beat) {
62074
- v.endX = this.getBeatLineX(beat);
62075
- }
62076
- }
62077
- }
62078
- _getOrCreateBeatPositions(beat) {
62079
- if (!this._beatLineXPositions.has(beat.index)) {
62080
- this._beatLineXPositions.set(beat.index, new BeatLinePositions());
61442
+ v.startX = this._renderer.getBeatX(v.startBeat, BeatXPosition.Stem);
61443
+ v.endX = this._renderer.getBeatX(v.endBeat, BeatXPosition.Stem);
61444
+ this.drawingInfos.clear();
62081
61445
  }
62082
- return this._beatLineXPositions.get(beat.index);
62083
61446
  }
62084
61447
  direction = BeamDirection.Up;
62085
61448
  finish() {
@@ -62145,36 +61508,6 @@ class BeamingHelper {
62145
61508
  }
62146
61509
  return [0, 0];
62147
61510
  }
62148
- /**
62149
- * Registers a rest beat within the accidental helper so the rest
62150
- * symbol is considered properly during beaming.
62151
- * @param beat The rest beat.
62152
- * @param steps The steps on which the rest symbol is placed
62153
- */
62154
- applyRest(beat, steps) {
62155
- // do not accept rests after the last beat which has notes
62156
- if ((this._lastNonRestBeat && beat.index >= this._lastNonRestBeat.index) ||
62157
- (this._firstNonRestBeat && beat.index <= this._firstNonRestBeat.index)) {
62158
- return;
62159
- }
62160
- // correct the line of the glyph to a note which would
62161
- // be placed at the upper / lower end of the glyph.
62162
- let aboveRest = steps;
62163
- let belowRest = steps;
62164
- const offsets = BeamingHelper.computeLineHeightsForRest(beat.duration);
62165
- aboveRest -= offsets[0];
62166
- belowRest += offsets[1];
62167
- const minRestSteps = this.minRestSteps;
62168
- const maxRestSteps = this.maxRestSteps;
62169
- if (minRestSteps === null || minRestSteps > aboveRest) {
62170
- this.minRestSteps = aboveRest;
62171
- this.beatOfMinRestSteps = beat;
62172
- }
62173
- if (maxRestSteps === null || maxRestSteps < belowRest) {
62174
- this.maxRestSteps = belowRest;
62175
- this.beatOfMaxRestSteps = beat;
62176
- }
62177
- }
62178
61511
  _invert(direction) {
62179
61512
  if (!this.invertBeamDirection) {
62180
61513
  return direction;
@@ -62238,14 +61571,13 @@ class BeamingHelper {
62238
61571
  if (this.shortestDuration < beat.duration) {
62239
61572
  this.shortestDuration = beat.duration;
62240
61573
  }
62241
- if (!this._firstNonRestBeat) {
62242
- this._firstNonRestBeat = beat;
62243
- }
62244
- this._lastNonRestBeat = beat;
62245
61574
  }
62246
61575
  else if (this.beats.length === 0) {
62247
61576
  this.beats.push(beat);
62248
61577
  }
61578
+ else {
61579
+ this.restBeats.push(beat);
61580
+ }
62249
61581
  if (beat.slashed) {
62250
61582
  this.slashBeats.push(beat);
62251
61583
  }
@@ -62354,19 +61686,6 @@ class BeamingHelper {
62354
61686
  get beatOfHighestNote() {
62355
61687
  return this.highestNoteInHelper.beat;
62356
61688
  }
62357
- /**
62358
- * Returns whether the the position of the given beat, was registered by the staff of the given ID
62359
- * @param staffId
62360
- * @param beat
62361
- * @returns
62362
- */
62363
- isPositionFrom(staffId, beat) {
62364
- if (!this._beatLineXPositions.has(beat.index)) {
62365
- return true;
62366
- }
62367
- return (this._beatLineXPositions.get(beat.index).staffId === staffId ||
62368
- !this._beatLineXPositions.get(beat.index).staffId);
62369
- }
62370
61689
  drawingInfos = new Map();
62371
61690
  }
62372
61691
 
@@ -62518,8 +61837,8 @@ class BarCollisionHelper {
62518
61837
  */
62519
61838
  class BarHelpers {
62520
61839
  _renderer;
61840
+ _beamHelperLookup = new Map();
62521
61841
  beamHelpers = [];
62522
- beamHelperLookup = [];
62523
61842
  collisionHelper;
62524
61843
  preferredBeamDirection = null;
62525
61844
  constructor(renderer) {
@@ -62534,7 +61853,6 @@ class BarHelpers {
62534
61853
  for (let i = 0, j = bar.voices.length; i < j; i++) {
62535
61854
  const v = bar.voices[i];
62536
61855
  this.beamHelpers.push([]);
62537
- this.beamHelperLookup.push(new Map());
62538
61856
  for (let k = 0, l = v.beats.length; k < l; k++) {
62539
61857
  const b = v.beats[k];
62540
61858
  let helperForBeat;
@@ -62543,6 +61861,9 @@ class BarHelpers {
62543
61861
  }
62544
61862
  else {
62545
61863
  helperForBeat = currentBeamHelper;
61864
+ if (currentGraceBeamHelper) {
61865
+ currentGraceBeamHelper.finish();
61866
+ }
62546
61867
  currentGraceBeamHelper = null;
62547
61868
  }
62548
61869
  // if a new beaming helper was started, we close our tuplet grouping as well
@@ -62563,7 +61884,7 @@ class BarHelpers {
62563
61884
  }
62564
61885
  this.beamHelpers[v.index].push(helperForBeat);
62565
61886
  }
62566
- this.beamHelperLookup[v.index].set(b.index, helperForBeat);
61887
+ this._beamHelperLookup.set(b.id, helperForBeat);
62567
61888
  }
62568
61889
  if (currentBeamHelper) {
62569
61890
  currentBeamHelper.finish();
@@ -62576,7 +61897,7 @@ class BarHelpers {
62576
61897
  }
62577
61898
  }
62578
61899
  getBeamingHelperForBeat(beat) {
62579
- return this.beamHelperLookup[beat.voice.index].get(beat.index);
61900
+ return this._beamHelperLookup.has(beat.id) ? this._beamHelperLookup.get(beat.id) : undefined;
62580
61901
  }
62581
61902
  }
62582
61903
 
@@ -62686,6 +62007,9 @@ class BarRendererBase {
62686
62007
  return this._contentBottomOverflow + this.bottomEffects.height;
62687
62008
  }
62688
62009
  helpers;
62010
+ get collisionHelper() {
62011
+ return this.helpers.collisionHelper;
62012
+ }
62689
62013
  /**
62690
62014
  * Gets or sets whether this renderer is linked to the next one
62691
62015
  * by some glyphs like a vibrato effect
@@ -62745,6 +62069,11 @@ class BarRendererBase {
62745
62069
  for (const container of this._voiceContainers.values()) {
62746
62070
  container.scaleToWidth(containerWidth);
62747
62071
  }
62072
+ for (const v of this.helpers.beamHelpers) {
62073
+ for (const h of v) {
62074
+ h.alignWithBeats();
62075
+ }
62076
+ }
62748
62077
  this._postBeatGlyphs.x = this._preBeatGlyphs.x + this._preBeatGlyphs.width + containerWidth;
62749
62078
  this.width = width;
62750
62079
  this.topEffects.alignGlyphs();
@@ -62773,10 +62102,13 @@ class BarRendererBase {
62773
62102
  get barDisplayWidth() {
62774
62103
  return this.staff.system.staves.length > 1 ? this.bar.masterBar.displayWidth : this.bar.displayWidth;
62775
62104
  }
62776
- wasFirstOfLine = false;
62777
- get isFirstOfLine() {
62105
+ wasFirstOfStaff = false;
62106
+ get isFirstOfStaff() {
62778
62107
  return this.index === 0;
62779
62108
  }
62109
+ get isLastOfStaff() {
62110
+ return this.index === this.staff.barRenderers.length - 1;
62111
+ }
62780
62112
  get isLast() {
62781
62113
  return !this.bar || this.bar.index === this.scoreRenderer.layout.lastBarIndex;
62782
62114
  }
@@ -62991,6 +62323,18 @@ class BarRendererBase {
62991
62323
  }
62992
62324
  }
62993
62325
  }
62326
+ for (const v of this._voiceContainers.values()) {
62327
+ for (const b of v.beatGlyphs) {
62328
+ const topY = b.getBoundingBoxTop();
62329
+ if (topY < 0) {
62330
+ this.registerOverflowTop(topY * -1);
62331
+ }
62332
+ const bottomY = b.getBoundingBoxBottom();
62333
+ if (bottomY > rendererBottom) {
62334
+ this.registerOverflowBottom(bottomY - rendererBottom);
62335
+ }
62336
+ }
62337
+ }
62994
62338
  const beatEffectsMinY = this.beatEffectsMinY;
62995
62339
  if (!Number.isNaN(beatEffectsMinY)) {
62996
62340
  const beatEffectTopOverflow = -beatEffectsMinY;
@@ -63044,7 +62388,6 @@ class BarRendererBase {
63044
62388
  g.renderer = this;
63045
62389
  g.preNotes.renderer = this;
63046
62390
  g.onNotes.renderer = this;
63047
- g.onNotes.beamingHelper = this.helpers.beamHelperLookup[g.beat.voice.index].get(g.beat.index);
63048
62391
  this.getVoiceContainer(g.beat.voice).addGlyph(g);
63049
62392
  }
63050
62393
  getVoiceContainer(voice) {
@@ -63123,7 +62466,7 @@ class BarRendererBase {
63123
62466
  this._postBeatGlyphs.addGlyph(g);
63124
62467
  }
63125
62468
  createPreBeatGlyphs() {
63126
- this.wasFirstOfLine = this.isFirstOfLine;
62469
+ this.wasFirstOfStaff = this.isFirstOfStaff;
63127
62470
  }
63128
62471
  createBeatGlyphs() {
63129
62472
  for (const voice of this.bar.voices) {
@@ -63150,26 +62493,7 @@ class BarRendererBase {
63150
62493
  getBeatX(beat, requestedPosition = BeatXPosition.PreNotes, useSharedSizes = false) {
63151
62494
  const container = this.getBeatContainer(beat);
63152
62495
  if (container) {
63153
- switch (requestedPosition) {
63154
- case BeatXPosition.PreNotes:
63155
- return container.voiceContainer.x + container.x;
63156
- case BeatXPosition.OnNotes:
63157
- return container.voiceContainer.x + container.x + container.onNotes.x;
63158
- case BeatXPosition.MiddleNotes:
63159
- return container.voiceContainer.x + container.x + container.onNotes.x + container.onNotes.middleX;
63160
- case BeatXPosition.Stem:
63161
- const offset = container.onNotes.beamingHelper
63162
- ? container.onNotes.beamingHelper.getBeatLineX(beat)
63163
- : container.onNotes.x + container.onNotes.width / 2;
63164
- return container.voiceContainer.x + offset;
63165
- case BeatXPosition.PostNotes:
63166
- const onNoteSize = useSharedSizes
63167
- ? (this.layoutingInfo.getBeatSizes(beat)?.onBeatSize ?? container.onNotes.width)
63168
- : container.onNotes.width;
63169
- return container.voiceContainer.x + container.x + container.onNotes.x + onNoteSize;
63170
- case BeatXPosition.EndBeat:
63171
- return container.voiceContainer.x + container.x + container.width;
63172
- }
62496
+ return container.voiceContainer.x + container.x + container.getBeatX(requestedPosition, useSharedSizes);
63173
62497
  }
63174
62498
  return 0;
63175
62499
  }
@@ -63204,7 +62528,7 @@ class BarRendererBase {
63204
62528
  this.updateSizes();
63205
62529
  // there are some glyphs which are shown only for renderers at the line start, so we simply recreate them
63206
62530
  // but we only need to recreate them for the renderers that were the first of the line or are now the first of the line
63207
- if ((this.wasFirstOfLine && !this.isFirstOfLine) || (!this.wasFirstOfLine && this.isFirstOfLine)) {
62531
+ if ((this.wasFirstOfStaff && !this.isFirstOfStaff) || (!this.wasFirstOfStaff && this.isFirstOfStaff)) {
63208
62532
  this.recreatePreBeatGlyphs();
63209
62533
  this._postBeatGlyphs.doLayout();
63210
62534
  }
@@ -63241,7 +62565,7 @@ class BarRendererBase {
63241
62565
  completeBeamingHelper(_helper) {
63242
62566
  }
63243
62567
  getBeatDirection(beat) {
63244
- return this.helpers.getBeamingHelperForBeat(beat).direction;
62568
+ return this.helpers.getBeamingHelperForBeat(beat)?.direction ?? BeamDirection.Up;
63245
62569
  }
63246
62570
  }
63247
62571
 
@@ -65608,8 +64932,18 @@ class BarLineGlyph extends LeftToRightLayoutingGlyphGroup {
65608
64932
  }
65609
64933
  const lineRenderer = this.renderer;
65610
64934
  const lineYOffset = lineRenderer.smuflMetrics.staffLineThickness;
65611
- const top = this.y - lineYOffset;
65612
- const bottom = this.y + this.renderer.height;
64935
+ let top = this.y;
64936
+ let bottom = this.y;
64937
+ if (lineRenderer.drawnLineCount < 2 ||
64938
+ (!this._isRight && lineRenderer.isFirstOfStaff) ||
64939
+ (this._isRight && lineRenderer.isLastOfStaff)) {
64940
+ top -= lineYOffset;
64941
+ bottom += lineRenderer.height;
64942
+ }
64943
+ else {
64944
+ top += lineRenderer.getLineY(0);
64945
+ bottom += lineRenderer.getLineY(lineRenderer.drawnLineCount - 1);
64946
+ }
65613
64947
  const h = bottom - top;
65614
64948
  // round up to have pixel-aligned bar lines, x-shift will be used during rendering
65615
64949
  // to avoid shifting again all glyphs
@@ -65695,6 +65029,54 @@ class BarNumberGlyph extends Glyph {
65695
65029
  }
65696
65030
  }
65697
65031
 
65032
+ /**
65033
+ * @internal
65034
+ */
65035
+ class FlagGlyph extends MusicFontGlyph {
65036
+ constructor(x, y, duration, direction, isGrace) {
65037
+ super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, FlagGlyph.getSymbol(duration, direction, isGrace));
65038
+ }
65039
+ static getSymbol(duration, direction, isGrace) {
65040
+ if (isGrace) {
65041
+ duration = Duration.Eighth;
65042
+ }
65043
+ if (direction === BeamDirection.Up) {
65044
+ switch (duration) {
65045
+ case Duration.Eighth:
65046
+ return MusicFontSymbol.Flag8thUp;
65047
+ case Duration.Sixteenth:
65048
+ return MusicFontSymbol.Flag16thUp;
65049
+ case Duration.ThirtySecond:
65050
+ return MusicFontSymbol.Flag32ndUp;
65051
+ case Duration.SixtyFourth:
65052
+ return MusicFontSymbol.Flag64thUp;
65053
+ case Duration.OneHundredTwentyEighth:
65054
+ return MusicFontSymbol.Flag128thUp;
65055
+ case Duration.TwoHundredFiftySixth:
65056
+ return MusicFontSymbol.Flag256thUp;
65057
+ default:
65058
+ return MusicFontSymbol.Flag8thUp;
65059
+ }
65060
+ }
65061
+ switch (duration) {
65062
+ case Duration.Eighth:
65063
+ return MusicFontSymbol.Flag8thDown;
65064
+ case Duration.Sixteenth:
65065
+ return MusicFontSymbol.Flag16thDown;
65066
+ case Duration.ThirtySecond:
65067
+ return MusicFontSymbol.Flag32ndDown;
65068
+ case Duration.SixtyFourth:
65069
+ return MusicFontSymbol.Flag64thDown;
65070
+ case Duration.OneHundredTwentyEighth:
65071
+ return MusicFontSymbol.Flag128thDown;
65072
+ case Duration.TwoHundredFiftySixth:
65073
+ return MusicFontSymbol.Flag128thDown;
65074
+ default:
65075
+ return MusicFontSymbol.Flag8thDown;
65076
+ }
65077
+ }
65078
+ }
65079
+
65698
65080
  /**
65699
65081
  * @internal
65700
65082
  */
@@ -65730,6 +65112,23 @@ class RepeatCountGlyph extends Glyph {
65730
65112
  }
65731
65113
  }
65732
65114
 
65115
+ /**
65116
+ * This simple glyph allows to put an empty region in to a BarRenderer.
65117
+ * @internal
65118
+ */
65119
+ class SpacingGlyph extends Glyph {
65120
+ constructor(x, y, width) {
65121
+ super(x, y);
65122
+ this.width = width;
65123
+ }
65124
+ getBoundingBoxTop() {
65125
+ return Number.NaN;
65126
+ }
65127
+ getBoundingBoxBottom() {
65128
+ return Number.NaN;
65129
+ }
65130
+ }
65131
+
65733
65132
  /**
65734
65133
  * This is a base class for any bar renderer which renders music notation on a staff
65735
65134
  * with lines like Standard Notation, Guitar Tablatures and Slash Notation.
@@ -65853,7 +65252,7 @@ class LineBarRenderer extends BarRendererBase {
65853
65252
  if (this.hasVoiceContainer(voice)) {
65854
65253
  const container = this.getVoiceContainer(voice);
65855
65254
  for (const tupletGroup of container.tupletGroups) {
65856
- this._paintTupletHelper(cx + this.beatGlyphsStart, cy, canvas, tupletGroup, beatElement, bracketsAsArcs);
65255
+ this._paintTupletHelper(cx, cy, canvas, tupletGroup, beatElement, bracketsAsArcs);
65857
65256
  }
65858
65257
  }
65859
65258
  }
@@ -65927,26 +65326,27 @@ class LineBarRenderer extends BarRendererBase {
65927
65326
  // check if we need to paint simple footer
65928
65327
  const offset = this.tupletOffset;
65929
65328
  const size = this.tupletSize;
65329
+ const shift = offset + size * 0.5;
65930
65330
  const _ = ElementStyleHelper.beat(canvas, beatElement, h.beats[0]);
65931
65331
  try {
65932
65332
  const l = canvas.lineWidth;
65933
65333
  canvas.lineWidth = this.smuflMetrics.tupletBracketThickness;
65934
65334
  if (h.beats.length === 1 || !h.isFull) {
65935
65335
  for (const beat of h.beats) {
65936
- const beamingHelper = this.helpers.beamHelperLookup[h.voice.index].get(beat.index);
65336
+ const beamingHelper = this.helpers.getBeamingHelperForBeat(beat);
65937
65337
  if (!beamingHelper) {
65938
65338
  continue;
65939
65339
  }
65940
65340
  const direction = this.getTupletBeamDirection(beamingHelper);
65941
- const tupletX = beamingHelper.getBeatLineX(beat);
65341
+ const tupletX = this.getBeatX(beat, BeatXPosition.Stem);
65942
65342
  let tupletY = this.calculateBeamYWithDirection(beamingHelper, tupletX, direction);
65943
65343
  if (direction === BeamDirection.Down) {
65944
- tupletY += offset + size;
65344
+ tupletY += shift;
65945
65345
  }
65946
65346
  else {
65947
- tupletY -= offset + size;
65347
+ tupletY -= shift;
65948
65348
  }
65949
- canvas.fillMusicFontSymbols(cx + this.x + tupletX, cy + this.y + tupletY, 1, s, true);
65349
+ canvas.fillMusicFontSymbols(cx + this.x + tupletX, cy + this.y + tupletY + size * 0.5, 1, s, true);
65950
65350
  }
65951
65351
  }
65952
65352
  else {
@@ -65976,12 +65376,12 @@ class LineBarRenderer extends BarRendererBase {
65976
65376
  }
65977
65377
  //
65978
65378
  // Calculate the overall area of the tuplet bracket
65979
- const startX = this.getBeatX(firstBeat, BeatXPosition.OnNotes) - this.beatGlyphsStart;
65980
- const endX = this.getBeatX(lastBeat, BeatXPosition.PostNotes) - this.beatGlyphsStart;
65379
+ const startX = this.getBeatX(firstBeat, BeatXPosition.OnNotes);
65380
+ const endX = this.getBeatX(lastBeat, BeatXPosition.PostNotes);
65981
65381
  //
65982
65382
  // calculate the y positions for our bracket
65983
- const firstNonRestBeamingHelper = this.helpers.beamHelperLookup[h.voice.index].get(firstNonRestBeat.index);
65984
- const lastNonRestBeamingHelper = this.helpers.beamHelperLookup[h.voice.index].get(lastNonRestBeat.index);
65383
+ const firstNonRestBeamingHelper = this.helpers.getBeamingHelperForBeat(firstNonRestBeat);
65384
+ const lastNonRestBeamingHelper = this.helpers.getBeamingHelperForBeat(lastNonRestBeat);
65985
65385
  const direction = this.getTupletBeamDirection(firstNonRestBeamingHelper);
65986
65386
  let startY = this.calculateBeamYWithDirection(firstNonRestBeamingHelper, startX, direction);
65987
65387
  let endY = this.calculateBeamYWithDirection(lastNonRestBeamingHelper, endX, direction);
@@ -65990,7 +65390,6 @@ class LineBarRenderer extends BarRendererBase {
65990
65390
  endY = startY;
65991
65391
  }
65992
65392
  // align line centered in available space
65993
- const shift = offset + size * 0.5;
65994
65393
  if (direction === BeamDirection.Down) {
65995
65394
  startY += shift;
65996
65395
  endY += shift;
@@ -66055,14 +65454,24 @@ class LineBarRenderer extends BarRendererBase {
66055
65454
  paintBeams(cx, cy, canvas, flagsElement, beamsElement) {
66056
65455
  for (const v of this.helpers.beamHelpers) {
66057
65456
  for (const h of v) {
66058
- this._paintBeamHelper(cx + this.beatGlyphsStart, cy, canvas, h, flagsElement, beamsElement);
65457
+ this.paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement);
66059
65458
  }
66060
65459
  }
66061
65460
  }
66062
65461
  drawBeamHelperAsFlags(h) {
66063
65462
  return h.beats.length === 1;
66064
65463
  }
66065
- _paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement) {
65464
+ hasFlag(beat) {
65465
+ if (beat.isRest) {
65466
+ return false;
65467
+ }
65468
+ const helper = this.helpers.getBeamingHelperForBeat(beat);
65469
+ if (helper) {
65470
+ return helper.hasFlag(this.drawBeamHelperAsFlags(helper), beat);
65471
+ }
65472
+ return BeamingHelper.beatHasFlag(beat);
65473
+ }
65474
+ paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement) {
66066
65475
  canvas.color = h.voice.index === 0 ? this.resources.mainGlyphColor : this.resources.secondaryGlyphColor;
66067
65476
  if (!h.isRestBeamHelper) {
66068
65477
  if (this.drawBeamHelperAsFlags(h)) {
@@ -66073,7 +65482,7 @@ class LineBarRenderer extends BarRendererBase {
66073
65482
  }
66074
65483
  }
66075
65484
  }
66076
- shouldPaintFlag(beat, h) {
65485
+ shouldPaintFlag(beat) {
66077
65486
  // no flags for bend grace beats
66078
65487
  if (beat.graceType === GraceType.BendGrace) {
66079
65488
  return false;
@@ -66081,10 +65490,6 @@ class LineBarRenderer extends BarRendererBase {
66081
65490
  if (beat.deadSlapped) {
66082
65491
  return false;
66083
65492
  }
66084
- // we don't have an X-position: cannot paint a flag
66085
- if (!h.hasBeatLineX(beat)) {
66086
- return false;
66087
- }
66088
65493
  // no flags for any grace notes on songbook mode
66089
65494
  if (beat.graceType !== GraceType.None && this.settings.notation.notationMode === NotationMode.SongBook) {
66090
65495
  return false;
@@ -66099,14 +65504,14 @@ class LineBarRenderer extends BarRendererBase {
66099
65504
  }
66100
65505
  paintFlag(cx, cy, canvas, h, flagsElement) {
66101
65506
  for (const beat of h.beats) {
66102
- if (!this.shouldPaintFlag(beat, h)) {
65507
+ if (!this.shouldPaintFlag(beat)) {
66103
65508
  continue;
66104
65509
  }
66105
65510
  const isGrace = beat.graceType !== GraceType.None;
66106
65511
  //
66107
65512
  // draw line
66108
65513
  //
66109
- const beatLineX = h.getBeatLineX(beat);
65514
+ const beatLineX = this.getBeatX(beat, BeatXPosition.Stem);
66110
65515
  const direction = this.getBeamDirection(h);
66111
65516
  const topY = cy + this.y + this.getFlagTopY(beat, direction);
66112
65517
  const bottomY = cy + this.y + this.getFlagBottomY(beat, direction);
@@ -66117,7 +65522,7 @@ class LineBarRenderer extends BarRendererBase {
66117
65522
  else {
66118
65523
  flagY = topY;
66119
65524
  }
66120
- if (!h.hasLine(true, beat)) {
65525
+ if (!h.hasStem(true, beat)) {
66121
65526
  continue;
66122
65527
  }
66123
65528
  this.paintBeamingStem(beat, cy + this.y, cx + this.x + beatLineX, topY, bottomY, canvas);
@@ -66203,10 +65608,10 @@ class LineBarRenderer extends BarRendererBase {
66203
65608
  }
66204
65609
  for (let i = 0, j = h.beats.length; i < j; i++) {
66205
65610
  const beat = h.beats[i];
66206
- if (!h.hasBeatLineX(beat) || beat.deadSlapped) {
65611
+ if (beat.deadSlapped) {
66207
65612
  continue;
66208
65613
  }
66209
- const beatLineX = h.getBeatLineX(beat);
65614
+ const beatLineX = this.getBeatX(beat, BeatXPosition.Stem);
66210
65615
  const y1 = cy + this.y + this.getBarLineStart(beat, direction);
66211
65616
  // ensure we are pixel aligned on the end of the stem to avoid anti-aliasing artifacts
66212
65617
  // when combining stems and beams on sub-pixel level
@@ -66244,7 +65649,7 @@ class LineBarRenderer extends BarRendererBase {
66244
65649
  barEndY = barY + this.calculateBeamY(h, barEndX);
66245
65650
  LineBarRenderer.paintSingleBar(canvas, cx + this.x + barStartX, barStartY, cx + this.x + barEndX, barEndY, barSize);
66246
65651
  // end part
66247
- barEndX = h.getBeatLineX(h.beats[i + 1]);
65652
+ barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.Stem);
66248
65653
  barStartX = barEndX - brokenBarOffset;
66249
65654
  barStartY = barY + this.calculateBeamY(h, barStartX);
66250
65655
  barEndY = barY + this.calculateBeamY(h, barEndX);
@@ -66254,7 +65659,7 @@ class LineBarRenderer extends BarRendererBase {
66254
65659
  if (isFullBarJoin) {
66255
65660
  // full bar?
66256
65661
  barStartX = beatLineX;
66257
- barEndX = h.getBeatLineX(h.beats[i + 1]);
65662
+ barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.Stem);
66258
65663
  }
66259
65664
  else if (i === 0 || !BeamingHelper.isFullBarJoin(h.beats[i - 1], beat, barIndex)) {
66260
65665
  barStartX = beatLineX;
@@ -66289,7 +65694,7 @@ class LineBarRenderer extends BarRendererBase {
66289
65694
  }
66290
65695
  }
66291
65696
  if (h.graceType === GraceType.BeforeBeat) {
66292
- const beatLineX = h.getBeatLineX(h.beats[0]);
65697
+ const beatLineX = this.getBeatX(h.beats[0], BeatXPosition.Stem);
66293
65698
  const flagWidth = this.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
66294
65699
  let slashY = (cy + this.y + this.calculateBeamY(h, beatLineX)) | 0;
66295
65700
  slashY += barSize + barSpacing;
@@ -66316,20 +65721,7 @@ class LineBarRenderer extends BarRendererBase {
66316
65721
  const noteOverflowPadding = this.getLineHeight(0.5);
66317
65722
  for (const v of this.helpers.beamHelpers) {
66318
65723
  for (const h of v) {
66319
- if (h.isRestBeamHelper) {
66320
- if (h.minRestSteps) {
66321
- const topY = this.getLineY(h.maxRestSteps / 2) - noteOverflowPadding;
66322
- if (topY < maxNoteY) {
66323
- maxNoteY = topY;
66324
- }
66325
- }
66326
- if (h.maxRestSteps) {
66327
- const bottomY = this.getLineY(h.maxRestSteps & 2) + noteOverflowPadding;
66328
- if (bottomY < maxNoteY) {
66329
- maxNoteY = bottomY;
66330
- }
66331
- }
66332
- }
65724
+ if (h.isRestBeamHelper) ;
66333
65725
  else if (h.beats.length === 1 && h.beats[0].duration >= Duration.Half) {
66334
65726
  if (h.direction === BeamDirection.Up) {
66335
65727
  let topY = this.getFlagTopY(h.beats[0], h.direction);
@@ -66380,17 +65772,6 @@ class LineBarRenderer extends BarRendererBase {
66380
65772
  }
66381
65773
  }
66382
65774
  }
66383
- const beatContainer = this.getBeatContainer(h.beats[0]);
66384
- if (beatContainer) {
66385
- const bBoxTop = beatContainer.getBoundingBoxTop();
66386
- const bBoxBottom = beatContainer.getBoundingBoxBottom();
66387
- if (bBoxBottom > minNoteY) {
66388
- minNoteY = bBoxBottom;
66389
- }
66390
- if (bBoxTop < maxNoteY) {
66391
- maxNoteY = bBoxTop;
66392
- }
66393
- }
66394
65775
  }
66395
65776
  }
66396
65777
  if (maxNoteY < rendererTop) {
@@ -66406,25 +65787,6 @@ class LineBarRenderer extends BarRendererBase {
66406
65787
  }
66407
65788
  const scale = h.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
66408
65789
  const barCount = ModelUtils.getIndex(h.shortestDuration) - 2;
66409
- let stemSize = this.smuflMetrics.standardStemLength * scale;
66410
- if (h.tremoloDuration) {
66411
- // for 16th and shorter beats we need more space for all tremolos
66412
- // for 8th beats we need only more space for 32nd tremolos
66413
- // the logic here is not perfect but there is no SMuFL guideline
66414
- // on how tremolos need to extend stems
66415
- const oneBeamSize = (this.smuflMetrics.beamThickness + this.smuflMetrics.beamSpacing) * scale;
66416
- if (h.shortestDuration > Duration.Eighth) {
66417
- if (h.tremoloDuration === Duration.Eighth) {
66418
- stemSize += oneBeamSize;
66419
- }
66420
- else {
66421
- stemSize += oneBeamSize * 1.5;
66422
- }
66423
- }
66424
- else if (h.tremoloDuration === Duration.ThirtySecond) {
66425
- stemSize += oneBeamSize * 1.5;
66426
- }
66427
- }
66428
65790
  const drawingInfo = new BeamingHelperDrawInfo();
66429
65791
  h.drawingInfos.set(direction, drawingInfo);
66430
65792
  // the beaming logic works like this:
@@ -66437,33 +65799,17 @@ class LineBarRenderer extends BarRendererBase {
66437
65799
  const isRest = h.isRestBeamHelper;
66438
65800
  // 1. put direct diagonal line.
66439
65801
  drawingInfo.startBeat = firstBeat;
66440
- drawingInfo.startX = h.getBeatLineX(firstBeat);
66441
- if (isRest) {
66442
- drawingInfo.startY =
66443
- direction === BeamDirection.Up
66444
- ? this.getLineY(h.minRestSteps / 2)
66445
- : this.getLineY(h.maxRestSteps / 2);
66446
- }
66447
- else {
66448
- drawingInfo.startY =
66449
- direction === BeamDirection.Up
66450
- ? this.getFlagTopY(firstBeat, direction)
66451
- : this.getFlagBottomY(firstBeat, direction);
66452
- }
65802
+ drawingInfo.startX = this.getBeatX(firstBeat, BeatXPosition.Stem);
65803
+ drawingInfo.startY =
65804
+ direction === BeamDirection.Up
65805
+ ? this.getFlagTopY(firstBeat, direction)
65806
+ : this.getFlagBottomY(firstBeat, direction);
66453
65807
  drawingInfo.endBeat = lastBeat;
66454
- drawingInfo.endX = h.getBeatLineX(lastBeat);
66455
- if (isRest) {
66456
- drawingInfo.endY =
66457
- direction === BeamDirection.Up
66458
- ? this.getLineY(h.minRestSteps / 2)
66459
- : this.getLineY(h.maxRestSteps / 2);
66460
- }
66461
- else {
66462
- drawingInfo.endY =
66463
- direction === BeamDirection.Up
66464
- ? this.getFlagTopY(lastBeat, direction)
66465
- : this.getFlagBottomY(lastBeat, direction);
66466
- }
65808
+ drawingInfo.endX = this.getBeatX(lastBeat, BeatXPosition.Stem);
65809
+ drawingInfo.endY =
65810
+ direction === BeamDirection.Up
65811
+ ? this.getFlagTopY(lastBeat, direction)
65812
+ : this.getFlagBottomY(lastBeat, direction);
66467
65813
  // 2. ensure max slope
66468
65814
  // we use the min/max notes to place the beam along their real position
66469
65815
  // we only want a maximum of 10 offset for their gradient
@@ -66488,12 +65834,41 @@ class LineBarRenderer extends BarRendererBase {
66488
65834
  drawingInfo.startY - drawingInfo.endY > maxSlope) {
66489
65835
  drawingInfo.startY = drawingInfo.endY + maxSlope;
66490
65836
  }
66491
- // 3. let middle elements shift up/down
65837
+ // 3. adjust beam drawing order
65838
+ // we can only draw up to 2 beams towards the noteheads, then we have to grow to the other side
65839
+ // here we shift accordingly
65840
+ let barDrawingShift = 0;
65841
+ if (barCount > 2 && !isRest) {
65842
+ const beamSpacing = this.smuflMetrics.beamSpacing * scale;
65843
+ const beamThickness = this.smuflMetrics.beamThickness * scale;
65844
+ const totalBarsHeight = barCount * beamThickness + (barCount - 1) * beamSpacing;
65845
+ if (direction === BeamDirection.Up) {
65846
+ const bottomBarY = drawingInfo.startY + 2 * beamThickness + beamSpacing;
65847
+ const barTopY = bottomBarY - totalBarsHeight;
65848
+ const diff = drawingInfo.startY - barTopY;
65849
+ if (diff > 0) {
65850
+ barDrawingShift = diff * -1;
65851
+ drawingInfo.startY -= diff;
65852
+ drawingInfo.endY -= diff;
65853
+ }
65854
+ }
65855
+ else {
65856
+ const topBarY = drawingInfo.startY - 2 * beamThickness + beamSpacing;
65857
+ const barBottomY = topBarY + totalBarsHeight;
65858
+ const diff = barBottomY - drawingInfo.startY;
65859
+ if (diff > 0) {
65860
+ barDrawingShift = diff;
65861
+ drawingInfo.startY += diff;
65862
+ drawingInfo.endY += diff;
65863
+ }
65864
+ }
65865
+ }
65866
+ // 4. let middle elements shift up/down
66492
65867
  if (h.beats.length > 1) {
66493
65868
  // check if highest note shifts bar up or down
66494
65869
  if (direction === BeamDirection.Up) {
66495
- const yNeededForHighestNote = this.getLineY(this.getMinLineOfBeat(h.beatOfHighestNote)) - stemSize;
66496
- const yGivenByCurrentValues = drawingInfo.calcY(h.getBeatLineX(h.beatOfHighestNote));
65870
+ const yNeededForHighestNote = barDrawingShift + this.getFlagTopY(h.beatOfHighestNote, direction);
65871
+ const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(h.beatOfHighestNote, BeatXPosition.Stem));
66497
65872
  const diff = yGivenByCurrentValues - yNeededForHighestNote;
66498
65873
  if (diff > 0) {
66499
65874
  drawingInfo.startY -= diff;
@@ -66501,8 +65876,8 @@ class LineBarRenderer extends BarRendererBase {
66501
65876
  }
66502
65877
  }
66503
65878
  else {
66504
- const yNeededForLowestNote = this.getLineY(this.getMaxLineOfBeat(h.beatOfLowestNote)) + stemSize;
66505
- const yGivenByCurrentValues = drawingInfo.calcY(h.getBeatLineX(h.beatOfLowestNote));
65879
+ const yNeededForLowestNote = barDrawingShift + this.getFlagBottomY(h.beatOfLowestNote, direction);
65880
+ const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(h.beatOfLowestNote, BeatXPosition.Stem));
66506
65881
  const diff = yNeededForLowestNote - yGivenByCurrentValues;
66507
65882
  if (diff > 0) {
66508
65883
  drawingInfo.startY += diff;
@@ -66510,33 +65885,39 @@ class LineBarRenderer extends BarRendererBase {
66510
65885
  }
66511
65886
  }
66512
65887
  // check if rest shifts bar up or down
66513
- if (h.minRestSteps !== null || h.maxRestSteps !== null) {
65888
+ let barSpacing = 0;
65889
+ if (h.restBeats.length > 0) {
65890
+ // space needed for the bars, rests need to be below them
66514
65891
  const scaleMod = h.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
66515
- let barSpacing = barCount * (this.smuflMetrics.beamSpacing + this.smuflMetrics.beamThickness) * scaleMod;
66516
- barSpacing += this.smuflMetrics.beamSpacing;
66517
- if (direction === BeamDirection.Up && h.minRestSteps !== null) {
66518
- const yNeededForRest = this.getLineY(h.minRestSteps / 2) - barSpacing;
66519
- const yGivenByCurrentValues = drawingInfo.calcY(h.getBeatLineX(h.beatOfMinRestSteps));
66520
- const diff = yGivenByCurrentValues - yNeededForRest;
66521
- if (diff > 0) {
66522
- drawingInfo.startY -= diff;
66523
- drawingInfo.endY -= diff;
65892
+ barSpacing = barCount * (this.smuflMetrics.beamSpacing + this.smuflMetrics.beamThickness) * scaleMod;
65893
+ }
65894
+ for (const b of h.restBeats) {
65895
+ // rest beats which are "under" the beam
65896
+ if (b.isRest && b.index < h.beats[h.beats.length - 1].index) {
65897
+ if (direction === BeamDirection.Up) {
65898
+ const yNeededForRest = this.getBeatContainer(b).getBoundingBoxTop() - barSpacing;
65899
+ const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(b, BeatXPosition.Stem));
65900
+ const diff = yGivenByCurrentValues - yNeededForRest;
65901
+ if (diff > 0) {
65902
+ drawingInfo.startY -= diff;
65903
+ drawingInfo.endY -= diff;
65904
+ }
66524
65905
  }
66525
- }
66526
- else if (direction === BeamDirection.Down && h.maxRestSteps !== null) {
66527
- const yNeededForRest = this.getLineHeight(h.maxRestSteps / 2) + barSpacing;
66528
- const yGivenByCurrentValues = drawingInfo.calcY(h.getBeatLineX(h.beatOfMaxRestSteps));
66529
- const diff = yNeededForRest - yGivenByCurrentValues;
66530
- if (diff > 0) {
66531
- drawingInfo.startY += diff;
66532
- drawingInfo.endY += diff;
65906
+ else if (direction === BeamDirection.Down) {
65907
+ const yNeededForRest = this.getBeatContainer(b).getBoundingBoxBottom() + barSpacing;
65908
+ const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(b, BeatXPosition.Stem));
65909
+ const diff = yNeededForRest - yGivenByCurrentValues;
65910
+ if (diff > 0) {
65911
+ drawingInfo.startY += diff;
65912
+ drawingInfo.endY += diff;
65913
+ }
66533
65914
  }
66534
65915
  }
66535
65916
  }
66536
65917
  // check if slash shifts bar up or down
66537
65918
  if (h.slashBeats.length > 0) {
66538
65919
  for (const b of h.slashBeats) {
66539
- const yGivenByCurrentValues = drawingInfo.calcY(h.getBeatLineX(b));
65920
+ const yGivenByCurrentValues = drawingInfo.calcY(this.getBeatX(b, BeatXPosition.Stem));
66540
65921
  const yNeededForSlash = h.direction === BeamDirection.Up
66541
65922
  ? this.getFlagTopY(b, h.direction)
66542
65923
  : this.getFlagBottomY(b, h.direction);
@@ -66548,31 +65929,6 @@ class LineBarRenderer extends BarRendererBase {
66548
65929
  }
66549
65930
  }
66550
65931
  }
66551
- // we can only draw up to 2 beams towards the noteheads, then we have to grow to the other side
66552
- // here we shift accordingly
66553
- if (barCount > 2 && !isRest) {
66554
- const beamSpacing = this.smuflMetrics.beamSpacing * scale;
66555
- const beamThickness = this.smuflMetrics.beamThickness * scale;
66556
- const totalBarsHeight = barCount * beamThickness + (barCount - 1) * beamSpacing;
66557
- if (direction === BeamDirection.Up) {
66558
- const bottomBarY = drawingInfo.startY + 2 * beamThickness + beamSpacing;
66559
- const barTopY = bottomBarY - totalBarsHeight;
66560
- const diff = drawingInfo.startY - barTopY;
66561
- if (diff > 0) {
66562
- drawingInfo.startY -= diff;
66563
- drawingInfo.endY -= diff;
66564
- }
66565
- }
66566
- else {
66567
- const topBarY = drawingInfo.startY - 2 * beamThickness + beamSpacing;
66568
- const barBottomY = topBarY + totalBarsHeight;
66569
- const diff = barBottomY - drawingInfo.startY;
66570
- if (diff > 0) {
66571
- drawingInfo.startY += diff;
66572
- drawingInfo.endY += diff;
66573
- }
66574
- }
66575
- }
66576
65932
  }
66577
65933
  getMinLineOfBeat(_beat) {
66578
65934
  return 0;
@@ -67093,20 +66449,6 @@ class NumberedBeatGlyph extends BeatOnNoteGlyphBase {
67093
66449
  }
67094
66450
  return 0;
67095
66451
  }
67096
- updateBeamingHelper() {
67097
- if (this.beamingHelper) {
67098
- let g = null;
67099
- if (this.noteHeads) {
67100
- g = this.noteHeads;
67101
- }
67102
- else if (this.deadSlapped) {
67103
- g = this.deadSlapped;
67104
- }
67105
- if (g) {
67106
- this.beamingHelper.registerBeatLineX('numbered', this.container.beat, this.container.x + this.x + g.x, this.container.x + this.x + g.x + g.width);
67107
- }
67108
- }
67109
- }
67110
66452
  static majorKeySignatureOneValues = [
67111
66453
  // Flats
67112
66454
  59, 66, 61, 68, 63, 58, 65,
@@ -67231,6 +66573,7 @@ class NumberedBeatGlyph extends BeatOnNoteGlyphBase {
67231
66573
  this.onTimeX = this.deadSlapped.x + this.deadSlapped.width / 2;
67232
66574
  }
67233
66575
  this.middleX = this.onTimeX;
66576
+ this.stemX = this.middleX;
67234
66577
  }
67235
66578
  }
67236
66579
 
@@ -67643,7 +66986,7 @@ class NumberedBarRenderer extends LineBarRenderer {
67643
66986
  const barSize = this.smuflMetrics.numberedBarRendererBarSize;
67644
66987
  const barCount = ModelUtils.getIndex(beat.duration) - 2;
67645
66988
  const barStart = cy + this.y;
67646
- const beatLineX = this.getBeatX(beat, BeatXPosition.PreNotes) - this.beatGlyphsStart;
66989
+ const beatLineX = this.getBeatX(beat, BeatXPosition.PreNotes);
67647
66990
  const beamY = this.calculateBeamY(h, beatLineX);
67648
66991
  for (let barIndex = 0; barIndex < barCount; barIndex++) {
67649
66992
  let barStartX = 0;
@@ -67652,11 +66995,11 @@ class NumberedBarRenderer extends LineBarRenderer {
67652
66995
  const barY = barStart + barIndex * barSpacing;
67653
66996
  if (i === h.beats.length - 1) {
67654
66997
  barStartX = beatLineX;
67655
- barEndX = this.getBeatX(beat, BeatXPosition.PostNotes) - this.beatGlyphsStart;
66998
+ barEndX = this.getBeatX(beat, BeatXPosition.PostNotes);
67656
66999
  }
67657
67000
  else {
67658
67001
  barStartX = beatLineX;
67659
- barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.PreNotes) - this.beatGlyphsStart;
67002
+ barEndX = this.getBeatX(h.beats[i + 1], BeatXPosition.PreNotes);
67660
67003
  }
67661
67004
  barStartY = barY + beamY;
67662
67005
  canvas.fillRect(cx + this.x + barStartX, barStartY, barEndX - barStartX, barSize);
@@ -67674,7 +67017,7 @@ class NumberedBarRenderer extends LineBarRenderer {
67674
67017
  dotsY = barStart + beamY + barCount * (barSpacing + barSize);
67675
67018
  dotsOffset = dotSpacing;
67676
67019
  }
67677
- const dotX = this.getBeatX(beat, BeatXPosition.MiddleNotes) - this.beatGlyphsStart;
67020
+ const dotX = this.getBeatX(beat, BeatXPosition.MiddleNotes);
67678
67021
  dotCount = Math.abs(dotCount);
67679
67022
  for (let d = 0; d < dotCount; d++) {
67680
67023
  CanvasHelper.fillMusicFontSymbolSafe(canvas, cx + this.x + dotX, dotsY, 1, MusicFontSymbol.AugmentationDot, true);
@@ -67723,7 +67066,7 @@ class NumberedBarRenderer extends LineBarRenderer {
67723
67066
  return this.getLineY(0) - noteHeadHeight / 2;
67724
67067
  }
67725
67068
  createPreBeatGlyphs() {
67726
- this.wasFirstOfLine = this.isFirstOfLine;
67069
+ this.wasFirstOfStaff = this.isFirstOfStaff;
67727
67070
  if (this.index === 0 || (this.bar.masterBar.isRepeatStart && this._isOnlyNumbered)) {
67728
67071
  this.addPreBeatGlyph(new BarLineGlyph(false, this.bar.staff.track.score.stylesheet.extendBarLines));
67729
67072
  }
@@ -67779,6 +67122,11 @@ class NumberedBarRenderer extends LineBarRenderer {
67779
67122
  }
67780
67123
  paintBeamingStem(_beat, _cy, _x, _topY, _bottomY, _canvas) {
67781
67124
  }
67125
+ paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement) {
67126
+ if (h.voice?.index === 0) {
67127
+ super.paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement);
67128
+ }
67129
+ }
67782
67130
  }
67783
67131
 
67784
67132
  /**
@@ -68315,9 +67663,8 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
68315
67663
  aboveBeatEffects = new Map();
68316
67664
  belowBeatEffects = new Map();
68317
67665
  beat;
68318
- beamingHelper;
68319
67666
  get direction() {
68320
- return this.beamingHelper.direction;
67667
+ return this.renderer.getBeatDirection(this.beat);
68321
67668
  }
68322
67669
  get scale() {
68323
67670
  return this.beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
@@ -68359,7 +67706,7 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
68359
67706
  : 0) * scale;
68360
67707
  // stem size according to duration
68361
67708
  pos -= this.renderer.smuflMetrics.standardStemLength * scale;
68362
- const topCenterY = this.renderer.centerStaffStemY(this.beamingHelper);
67709
+ const topCenterY = this.renderer.centerStaffStemY(this.direction);
68363
67710
  return Math.min(topCenterY, pos);
68364
67711
  case NoteYPosition.Top:
68365
67712
  pos -= n.height / 2;
@@ -68376,7 +67723,7 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
68376
67723
  : -this.renderer.smuflMetrics.glyphHeights.get(n.symbol) / 2) * scale;
68377
67724
  // stem size according to duration
68378
67725
  pos += this.renderer.smuflMetrics.standardStemLength * scale;
68379
- const bottomCenterY = this.renderer.centerStaffStemY(this.beamingHelper);
67726
+ const bottomCenterY = this.renderer.centerStaffStemY(this.direction);
68380
67727
  return Math.max(bottomCenterY, pos);
68381
67728
  case NoteYPosition.StemUp:
68382
67729
  pos -=
@@ -68401,11 +67748,6 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
68401
67748
  addEffectNoteGlyph(noteGlyph, noteLine) {
68402
67749
  super.add(noteGlyph, noteLine);
68403
67750
  }
68404
- updateBeamingHelper(cx) {
68405
- if (this.beamingHelper) {
68406
- this.beamingHelper.registerBeatLineX('score', this.beat, cx + this.x + this.upLineX, cx + this.x + this.downLineX);
68407
- }
68408
- }
68409
67751
  doLayout() {
68410
67752
  super.doLayout();
68411
67753
  const scoreRenderer = this.renderer;
@@ -68533,7 +67875,6 @@ class ScoreNoteChordGlyph extends ScoreNoteChordGlyphBase {
68533
67875
  * @internal
68534
67876
  */
68535
67877
  class ScoreRestGlyph extends MusicFontGlyph {
68536
- beamingHelper;
68537
67878
  constructor(x, y, duration) {
68538
67879
  super(x, y, 1, ScoreRestGlyph.getSymbol(duration));
68539
67880
  }
@@ -68565,11 +67906,6 @@ class ScoreRestGlyph extends MusicFontGlyph {
68565
67906
  return MusicFontSymbol.None;
68566
67907
  }
68567
67908
  }
68568
- updateBeamingHelper(cx) {
68569
- if (this.beamingHelper) {
68570
- this.beamingHelper.registerBeatLineX('score', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
68571
- }
68572
- }
68573
67909
  paint(cx, cy, canvas) {
68574
67910
  this.internalPaint(cx, cy, canvas, BeatSubElement.StandardNotationRests);
68575
67911
  }
@@ -69061,10 +68397,11 @@ class StringNumberContainerGlyph extends EffectGlyph {
69061
68397
  */
69062
68398
  class SlashNoteHeadGlyph extends MusicFontGlyph {
69063
68399
  beatEffects = new Map();
69064
- beamingHelper;
69065
68400
  noteHeadElement = NoteSubElement.SlashNoteHead;
69066
68401
  effectElement = BeatSubElement.SlashEffects;
69067
68402
  _symbol;
68403
+ upLineX = 0;
68404
+ downLineX = 0;
69068
68405
  constructor(x, y, duration, isGrace, beat) {
69069
68406
  super(x, y, isGrace ? NoteHeadGlyph.GraceScale : 1, SlashNoteHeadGlyph.getSymbol(duration));
69070
68407
  this._symbol = SlashNoteHeadGlyph.getSymbol(duration);
@@ -69115,6 +68452,15 @@ class SlashNoteHeadGlyph extends MusicFontGlyph {
69115
68452
  if (!Number.isNaN(minEffectY)) {
69116
68453
  this.renderer.registerBeatEffectOverflows(minEffectY, maxEffectY);
69117
68454
  }
68455
+ const symbol = this._symbol;
68456
+ const stemInfoUp = this.renderer.smuflMetrics.stemUp.has(symbol)
68457
+ ? this.renderer.smuflMetrics.stemUp.get(symbol).x
68458
+ : 0;
68459
+ this.upLineX = stemInfoUp;
68460
+ const stemInfoDown = this.renderer.smuflMetrics.stemDown.has(symbol)
68461
+ ? this.renderer.smuflMetrics.stemDown.get(symbol).x
68462
+ : 0;
68463
+ this.downLineX = stemInfoDown;
69118
68464
  }
69119
68465
  static getSymbol(duration) {
69120
68466
  switch (duration) {
@@ -69128,25 +68474,13 @@ class SlashNoteHeadGlyph extends MusicFontGlyph {
69128
68474
  return MusicFontSymbol.NoteheadSlashHorizontalEnds;
69129
68475
  }
69130
68476
  }
69131
- updateBeamingHelper(cx) {
69132
- if (this.beamingHelper) {
69133
- const symbol = this._symbol;
69134
- const stemInfoUp = this.renderer.smuflMetrics.stemUp.has(symbol)
69135
- ? this.renderer.smuflMetrics.stemUp.get(symbol).x
69136
- : 0;
69137
- const stemInfoDown = this.renderer.smuflMetrics.stemDown.has(symbol)
69138
- ? this.renderer.smuflMetrics.stemDown.get(symbol).x
69139
- : 0;
69140
- this.beamingHelper.registerBeatLineX('slash', this.beat, cx + this.x + stemInfoUp, cx + this.x + stemInfoDown);
69141
- }
69142
- }
69143
68477
  }
69144
68478
 
69145
68479
  /**
69146
68480
  * @internal
69147
68481
  */
69148
68482
  class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
69149
- _collisionOffset = -1e3;
68483
+ _collisionOffset = Number.NaN;
69150
68484
  _skipPaint = false;
69151
68485
  _whammy;
69152
68486
  noteHeads = null;
@@ -69197,22 +68531,19 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
69197
68531
  getNoteY(note, requestedPosition) {
69198
68532
  return this.noteHeads ? this.noteHeads.getNoteY(note, requestedPosition) : 0;
69199
68533
  }
69200
- updateBeamingHelper() {
69201
- if (this.noteHeads) {
69202
- this.noteHeads.updateBeamingHelper(this.container.x + this.x);
68534
+ applyRestCollisionOffset() {
68535
+ if (!this.restGlyph) {
68536
+ return;
69203
68537
  }
69204
- else if (this.restGlyph) {
69205
- this.restGlyph.updateBeamingHelper(this.container.x + this.x);
69206
- if (this.renderer.bar.isMultiVoice && this._collisionOffset === -1e3) {
69207
- this._collisionOffset = this.renderer.helpers.collisionHelper.applyRestCollisionOffset(this.container.beat, this.restGlyph.y, this.renderer.getScoreHeight(1));
69208
- this.y += this._collisionOffset;
69209
- const existingRests = this.renderer.helpers.collisionHelper.restDurationsByDisplayTime;
69210
- if (existingRests.has(this.container.beat.playbackStart) &&
69211
- existingRests.get(this.container.beat.playbackStart).has(this.container.beat.playbackDuration) &&
69212
- existingRests.get(this.container.beat.playbackStart).get(this.container.beat.playbackDuration) !==
69213
- this.container.beat.id) {
69214
- this._skipPaint = true;
69215
- }
68538
+ if (this.renderer.bar.isMultiVoice && Number.isNaN(this._collisionOffset)) {
68539
+ this._collisionOffset = this.renderer.collisionHelper.applyRestCollisionOffset(this.container.beat, this.restGlyph.y, this.renderer.getScoreHeight(1));
68540
+ this.y += this._collisionOffset;
68541
+ const existingRests = this.renderer.collisionHelper.restDurationsByDisplayTime;
68542
+ if (existingRests.has(this.container.beat.playbackStart) &&
68543
+ existingRests.get(this.container.beat.playbackStart).has(this.container.beat.playbackDuration) &&
68544
+ existingRests.get(this.container.beat.playbackStart).get(this.container.beat.playbackDuration) !==
68545
+ this.container.beat.id) {
68546
+ this._skipPaint = true;
69216
68547
  }
69217
68548
  }
69218
68549
  }
@@ -69232,7 +68563,6 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
69232
68563
  const noteHeads = new ScoreNoteChordGlyph();
69233
68564
  this.noteHeads = noteHeads;
69234
68565
  noteHeads.beat = this.container.beat;
69235
- noteHeads.beamingHelper = this.beamingHelper;
69236
68566
  const ghost = new GhostNoteContainerGlyph(false);
69237
68567
  ghost.renderer = this.renderer;
69238
68568
  for (const note of this.container.beat.notes) {
@@ -69282,22 +68612,18 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
69282
68612
  const restGlyph = new ScoreRestGlyph(0, sr.getScoreY(steps), this.container.beat.duration);
69283
68613
  this.restGlyph = restGlyph;
69284
68614
  restGlyph.beat = this.container.beat;
69285
- restGlyph.beamingHelper = this.beamingHelper;
69286
68615
  this.addNormal(restGlyph);
69287
68616
  if (this.renderer.bar.isMultiVoice) {
69288
68617
  if (this.container.beat.voice.index === 0) {
69289
68618
  const restSizes = BeamingHelper.computeLineHeightsForRest(this.container.beat.duration);
69290
68619
  const restTop = restGlyph.y - sr.getScoreHeight(restSizes[0]);
69291
68620
  const restBottom = restGlyph.y + sr.getScoreHeight(restSizes[1]);
69292
- this.renderer.helpers.collisionHelper.reserveBeatSlot(this.container.beat, restTop, restBottom);
68621
+ this.renderer.collisionHelper.reserveBeatSlot(this.container.beat, restTop, restBottom);
69293
68622
  }
69294
68623
  else {
69295
- this.renderer.helpers.collisionHelper.registerRest(this.container.beat);
68624
+ this.renderer.collisionHelper.registerRest(this.container.beat);
69296
68625
  }
69297
68626
  }
69298
- if (this.beamingHelper) {
69299
- this.beamingHelper.applyRest(this.container.beat, steps);
69300
- }
69301
68627
  //
69302
68628
  // Note dots
69303
68629
  //
@@ -69312,17 +68638,24 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
69312
68638
  }
69313
68639
  }
69314
68640
  super.doLayout();
68641
+ this.applyRestCollisionOffset();
69315
68642
  if (this.container.beat.isEmpty) {
69316
68643
  this.onTimeX = this.width / 2;
69317
68644
  this.middleX = this.onTimeX;
68645
+ this.stemX = this.middleX;
69318
68646
  }
69319
68647
  else if (this.restGlyph) {
69320
68648
  this.onTimeX = this.restGlyph.x + this.restGlyph.width / 2;
69321
68649
  this.middleX = this.onTimeX;
68650
+ this.stemX = this.middleX;
69322
68651
  }
69323
68652
  else if (this.noteHeads) {
69324
68653
  this.onTimeX = this.noteHeads.x + this.noteHeads.onTimeX;
69325
68654
  this.middleX = this.noteHeads.x + this.noteHeads.width / 2;
68655
+ const direction = this.renderer.getBeatDirection(this.container.beat);
68656
+ this.stemX =
68657
+ this.noteHeads.x +
68658
+ (direction === BeamDirection.Up ? this.noteHeads.upLineX : this.noteHeads.downLineX);
69326
68659
  }
69327
68660
  }
69328
68661
  _createBeatDot(line, group) {
@@ -69394,7 +68727,7 @@ class ScoreBeatGlyph extends BeatOnNoteGlyphBase {
69394
68727
  }
69395
68728
  const belowBeatEffects = this.noteHeads.belowBeatEffects;
69396
68729
  const aboveBeatEffects = this.noteHeads.aboveBeatEffects;
69397
- const outsideBeatEffects = this.beamingHelper.direction === BeamDirection.Up
68730
+ const outsideBeatEffects = this.renderer.getBeatDirection(this.container.beat) === BeamDirection.Up
69398
68731
  ? this.noteHeads.belowBeatEffects
69399
68732
  : this.noteHeads.aboveBeatEffects;
69400
68733
  if (n.isStaccato && !belowBeatEffects.has('Staccato')) {
@@ -69830,7 +69163,7 @@ class ScoreBendGlyph extends ScoreHelperNotesBaseGlyph {
69830
69163
  // if we have a line break we draw only a line until the end
69831
69164
  if (!endNoteRenderer || endNoteRenderer.staff !== startNoteRenderer.staff) {
69832
69165
  const endX = cx + startNoteRenderer.x + startNoteRenderer.width;
69833
- const noteValueToDraw = note.tieDestination.realValue;
69166
+ const noteValueToDraw = note.tieDestination.displayValue;
69834
69167
  startNoteRenderer.accidentalHelper.applyAccidentalForValue(note.beat, noteValueToDraw, false, true);
69835
69168
  const endY = cy +
69836
69169
  startNoteRenderer.y +
@@ -70366,6 +69699,22 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
70366
69699
  doLayout() {
70367
69700
  this._effectSlur = null;
70368
69701
  this._effectEndSlur = null;
69702
+ // make space for flag
69703
+ const sr = this.renderer;
69704
+ const beat = this.beat;
69705
+ const isGrace = beat.graceType !== GraceType.None;
69706
+ if (sr.hasFlag(beat)) {
69707
+ const direction = this.renderer.getBeatDirection(beat);
69708
+ const scale = isGrace ? NoteHeadGlyph.GraceScale : 1;
69709
+ const symbol = FlagGlyph.getSymbol(beat.duration, direction, isGrace);
69710
+ const flagWidth = this.renderer.smuflMetrics.glyphWidths.get(symbol) * scale;
69711
+ this._flagStretch = flagWidth;
69712
+ }
69713
+ else if (isGrace) {
69714
+ // always use flag size as spacing on grace notes
69715
+ const graceSpacing = this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
69716
+ this._flagStretch = graceSpacing;
69717
+ }
70369
69718
  super.doLayout();
70370
69719
  if (this._bend) {
70371
69720
  this._bend.renderer = this.renderer;
@@ -70375,7 +69724,7 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
70375
69724
  }
70376
69725
  getBoundingBoxTop() {
70377
69726
  if (this._bend !== null) {
70378
- return Math.min(this._bend.getBoundingBoxTop(), super.getBoundingBoxTop());
69727
+ return ModelUtils.minBoundingBox(this._bend.getBoundingBoxTop(), super.getBoundingBoxTop());
70379
69728
  }
70380
69729
  else {
70381
69730
  return super.getBoundingBoxTop();
@@ -70383,7 +69732,7 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
70383
69732
  }
70384
69733
  getBoundingBoxBottom() {
70385
69734
  if (this._bend !== null) {
70386
- return Math.max(this._bend.getBoundingBoxBottom(), super.getBoundingBoxTop());
69735
+ return ModelUtils.maxBoundingBox(this._bend.getBoundingBoxBottom(), super.getBoundingBoxTop());
70387
69736
  }
70388
69737
  else {
70389
69738
  return super.getBoundingBoxBottom();
@@ -70431,7 +69780,7 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
70431
69780
  }
70432
69781
  // end effect slur on last beat
70433
69782
  if (!this._effectEndSlur && n.beat.isEffectSlurDestination && n.beat.effectSlurOrigin) {
70434
- const direction = this.onNotes.beamingHelper.direction;
69783
+ const direction = this.renderer.getBeatDirection(n.beat);
70435
69784
  const startNote = direction === BeamDirection.Up ? n.beat.effectSlurOrigin.minNote : n.beat.effectSlurOrigin.maxNote;
70436
69785
  const endNote = direction === BeamDirection.Up ? n.beat.minNote : n.beat.maxNote;
70437
69786
  const effectEndSlur = new ScoreSlurGlyph(`score.slur.effect.${startNote.beat.id}`, startNote, endNote, true);
@@ -70470,6 +69819,15 @@ class ScoreBeatContainerGlyph extends BeatContainerGlyph {
70470
69819
  }
70471
69820
  }
70472
69821
  }
69822
+ _flagStretch = 0;
69823
+ get postBeatStretch() {
69824
+ return super.postBeatStretch + this._flagStretch;
69825
+ }
69826
+ updateWidth() {
69827
+ super.updateWidth();
69828
+ this.width += this._flagStretch;
69829
+ this.minWidth += this._flagStretch;
69830
+ }
70473
69831
  }
70474
69832
 
70475
69833
  /**
@@ -70504,7 +69862,7 @@ class ScoreBarRenderer extends LineBarRenderer {
70504
69862
  return this.smuflMetrics.oneStaffSpace;
70505
69863
  }
70506
69864
  get heightLineCount() {
70507
- return 5;
69865
+ return Math.max(5, this.bar.staff.standardNotationLineCount);
70508
69866
  }
70509
69867
  get drawnLineCount() {
70510
69868
  return this.bar.staff.standardNotationLineCount;
@@ -70561,7 +69919,9 @@ class ScoreBarRenderer extends LineBarRenderer {
70561
69919
  slashY -= this.smuflMetrics.stemUp.has(symbol)
70562
69920
  ? this.smuflMetrics.stemUp.get(symbol).bottomY * scale
70563
69921
  : 0;
70564
- slashY -= this.smuflMetrics.standardStemLength + scale;
69922
+ if (!beat.isRest) {
69923
+ slashY -= this.smuflMetrics.standardStemLength + scale;
69924
+ }
70565
69925
  }
70566
69926
  return slashY;
70567
69927
  }
@@ -70570,7 +69930,7 @@ class ScoreBarRenderer extends LineBarRenderer {
70570
69930
  return this.getBeatContainer(beat).onNotes.getNoteY(minNote, direction === BeamDirection.Up ? NoteYPosition.TopWithStem : NoteYPosition.StemDown);
70571
69931
  }
70572
69932
  let y = this.getScoreY(this.accidentalHelper.getMinSteps(beat));
70573
- if (direction === BeamDirection.Up) {
69933
+ if (direction === BeamDirection.Up && !beat.isRest) {
70574
69934
  const scale = beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
70575
69935
  y -= this.smuflMetrics.standardStemLength * scale;
70576
69936
  }
@@ -70608,14 +69968,14 @@ class ScoreBarRenderer extends LineBarRenderer {
70608
69968
  getBeamDirection(helper) {
70609
69969
  return helper.direction;
70610
69970
  }
70611
- centerStaffStemY(helper) {
69971
+ centerStaffStemY(direction) {
70612
69972
  const isStandardFive = this.bar.staff.standardNotationLineCount === Staff.DefaultStandardNotationLineCount;
70613
69973
  if (isStandardFive) {
70614
69974
  // center on the middle line for a standard 5-line staff
70615
69975
  return this.getScoreY(this.bar.staff.standardNotationLineCount - 1);
70616
69976
  }
70617
69977
  // for other staff line counts, we align the stem either on the top or bottom line
70618
- if (helper.direction === BeamDirection.Up) {
69978
+ if (direction === BeamDirection.Up) {
70619
69979
  return this.getScoreY(this.bar.staff.standardNotationLineCount * 2);
70620
69980
  }
70621
69981
  return this.getScoreY(0);
@@ -70717,7 +70077,7 @@ class ScoreBarRenderer extends LineBarRenderer {
70717
70077
  createLinePreBeatGlyphs() {
70718
70078
  // Clef
70719
70079
  let hasClef = false;
70720
- if (this.isFirstOfLine ||
70080
+ if (this.isFirstOfStaff ||
70721
70081
  this.bar.clef !== this.bar.previousBar.clef ||
70722
70082
  this.bar.clefOttava !== this.bar.previousBar.clefOttava) {
70723
70083
  // SMUFL: Clefs should be positioned such that the pitch the clef refers to is on the baseline
@@ -70922,6 +70282,25 @@ class SlashTieGlyph extends NoteTieGlyph {
70922
70282
  */
70923
70283
  class SlashBeatContainerGlyph extends BeatContainerGlyph {
70924
70284
  _tiedNoteTie = null;
70285
+ doLayout() {
70286
+ // make space for flag
70287
+ const sr = this.renderer;
70288
+ const beat = this.beat;
70289
+ const isGrace = beat.graceType !== GraceType.None;
70290
+ if (sr.hasFlag(beat)) {
70291
+ const direction = this.renderer.getBeatDirection(beat);
70292
+ const scale = isGrace ? NoteHeadGlyph.GraceScale : 1;
70293
+ const symbol = FlagGlyph.getSymbol(beat.duration, direction, isGrace);
70294
+ const flagWidth = this.renderer.smuflMetrics.glyphWidths.get(symbol) * scale;
70295
+ this._flagStretch = flagWidth;
70296
+ }
70297
+ else if (isGrace) {
70298
+ // always use flag size as spacing on grace notes
70299
+ const graceSpacing = this.renderer.smuflMetrics.glyphWidths.get(MusicFontSymbol.Flag8thUp) * NoteHeadGlyph.GraceScale;
70300
+ this._flagStretch = graceSpacing;
70301
+ }
70302
+ super.doLayout();
70303
+ }
70925
70304
  createTies(n) {
70926
70305
  // create a tie if any effect requires it
70927
70306
  if (!n.isVisible) {
@@ -70938,17 +70317,21 @@ class SlashBeatContainerGlyph extends BeatContainerGlyph {
70938
70317
  this.addTie(tie);
70939
70318
  }
70940
70319
  }
70320
+ _flagStretch = 0;
70321
+ get postBeatStretch() {
70322
+ return super.postBeatStretch + this._flagStretch;
70323
+ }
70324
+ updateWidth() {
70325
+ super.updateWidth();
70326
+ this.width += this._flagStretch;
70327
+ this.minWidth += this._flagStretch;
70328
+ }
70941
70329
  }
70942
70330
 
70943
70331
  /**
70944
70332
  * @internal
70945
70333
  */
70946
70334
  class SlashRestGlyph extends ScoreRestGlyph {
70947
- updateBeamingHelper(cx) {
70948
- if (this.beamingHelper) {
70949
- this.beamingHelper.registerBeatLineX('slash', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
70950
- }
70951
- }
70952
70335
  paint(cx, cy, canvas) {
70953
70336
  super.internalPaint(cx, cy, canvas, BeatSubElement.SlashRests);
70954
70337
  }
@@ -71044,19 +70427,6 @@ class SlashBeatGlyph extends BeatOnNoteGlyphBase {
71044
70427
  }
71045
70428
  return 0;
71046
70429
  }
71047
- updateBeamingHelper() {
71048
- if (this.noteHeads) {
71049
- this.noteHeads.updateBeamingHelper(this.container.x + this.x);
71050
- }
71051
- else if (this.deadSlapped) {
71052
- if (this.beamingHelper) {
71053
- this.beamingHelper.registerBeatLineX('slash', this.container.beat, this.container.x + this.x + this.deadSlapped.x + this.width, this.container.x + this.x + this.deadSlapped.x);
71054
- }
71055
- }
71056
- else if (this.restGlyph) {
71057
- this.restGlyph.updateBeamingHelper(this.container.x + this.x);
71058
- }
71059
- }
71060
70430
  doLayout() {
71061
70431
  // create glyphs
71062
70432
  const sr = this.renderer;
@@ -71074,18 +70444,13 @@ class SlashBeatGlyph extends BeatOnNoteGlyphBase {
71074
70444
  const noteHeadGlyph = new SlashNoteHeadGlyph(0, glyphY, this.container.beat.duration, isGrace, this.container.beat);
71075
70445
  this.noteHeads = noteHeadGlyph;
71076
70446
  noteHeadGlyph.beat = this.container.beat;
71077
- noteHeadGlyph.beamingHelper = this.beamingHelper;
71078
70447
  this.addNormal(noteHeadGlyph);
71079
70448
  }
71080
70449
  else {
71081
70450
  const restGlyph = new SlashRestGlyph(0, glyphY, this.container.beat.duration);
71082
70451
  this.restGlyph = restGlyph;
71083
70452
  restGlyph.beat = this.container.beat;
71084
- restGlyph.beamingHelper = this.beamingHelper;
71085
70453
  this.addNormal(restGlyph);
71086
- if (this.beamingHelper) {
71087
- this.beamingHelper.applyRest(this.container.beat, 0);
71088
- }
71089
70454
  }
71090
70455
  }
71091
70456
  //
@@ -71099,15 +70464,22 @@ class SlashBeatGlyph extends BeatOnNoteGlyphBase {
71099
70464
  super.doLayout();
71100
70465
  if (this.container.beat.isEmpty) {
71101
70466
  this.onTimeX = this.width / 2;
70467
+ this.stemX = this.onTimeX;
71102
70468
  }
71103
70469
  else if (this.restGlyph) {
71104
70470
  this.onTimeX = this.restGlyph.x + this.restGlyph.width / 2;
70471
+ this.stemX = this.onTimeX;
71105
70472
  }
71106
70473
  else if (this.noteHeads) {
71107
70474
  this.onTimeX = this.noteHeads.x + this.noteHeads.width / 2;
70475
+ const direction = this.renderer.getBeatDirection(this.container.beat);
70476
+ this.stemX =
70477
+ this.noteHeads.x +
70478
+ (direction === BeamDirection.Up ? this.noteHeads.upLineX : this.noteHeads.downLineX);
71108
70479
  }
71109
70480
  else if (this.deadSlapped) {
71110
70481
  this.onTimeX = this.deadSlapped.x + this.deadSlapped.width / 2;
70482
+ this.stemX = this.onTimeX;
71111
70483
  }
71112
70484
  this.middleX = this.onTimeX;
71113
70485
  }
@@ -71184,7 +70556,9 @@ class SlashBarRenderer extends LineBarRenderer {
71184
70556
  const symbol = SlashNoteHeadGlyph.getSymbol(beat.duration);
71185
70557
  const scale = beat.graceType !== GraceType.None ? NoteHeadGlyph.GraceScale : 1;
71186
70558
  slashY -= this.smuflMetrics.stemUp.has(symbol) ? this.smuflMetrics.stemUp.get(symbol).bottomY * scale : 0;
71187
- slashY -= this.smuflMetrics.standardStemLength + scale;
70559
+ if (!beat.isRest) {
70560
+ slashY -= this.smuflMetrics.standardStemLength + scale;
70561
+ }
71188
70562
  return slashY;
71189
70563
  }
71190
70564
  getFlagBottomY(beat, _direction) {
@@ -71268,6 +70642,11 @@ class SlashBarRenderer extends LineBarRenderer {
71268
70642
  _?.[Symbol.dispose]?.();
71269
70643
  }
71270
70644
  }
70645
+ paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement) {
70646
+ if (h.voice?.index === 0) {
70647
+ super.paintBeamHelper(cx, cy, canvas, h, flagsElement, beamsElement);
70648
+ }
70649
+ }
71271
70650
  }
71272
70651
 
71273
70652
  /**
@@ -71724,7 +71103,6 @@ class TabNoteChordGlyph extends Glyph {
71724
71103
  _deadSlapped = null;
71725
71104
  _isGrace;
71726
71105
  beat;
71727
- beamingHelper;
71728
71106
  maxStringNote = null;
71729
71107
  minStringNote = null;
71730
71108
  beatEffects = new Map();
@@ -71873,11 +71251,6 @@ class TabNoteChordGlyph extends Glyph {
71873
71251
  }
71874
71252
  }
71875
71253
  }
71876
- updateBeamingHelper(cx) {
71877
- if (this.beamingHelper && this.beamingHelper.isPositionFrom('tab', this.beat)) {
71878
- this.beamingHelper.registerBeatLineX('tab', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
71879
- }
71880
- }
71881
71254
  }
71882
71255
 
71883
71256
  /**
@@ -71885,7 +71258,6 @@ class TabNoteChordGlyph extends Glyph {
71885
71258
  */
71886
71259
  class TabRestGlyph extends MusicFontGlyph {
71887
71260
  _isVisibleRest;
71888
- beamingHelper;
71889
71261
  constructor(x, y, isVisibleRest, duration) {
71890
71262
  super(x, y, 1, ScoreRestGlyph.getSymbol(duration));
71891
71263
  this._isVisibleRest = isVisibleRest;
@@ -71893,11 +71265,6 @@ class TabRestGlyph extends MusicFontGlyph {
71893
71265
  doLayout() {
71894
71266
  super.doLayout();
71895
71267
  }
71896
- updateBeamingHelper(cx) {
71897
- if (this.beamingHelper && this.beamingHelper.isPositionFrom('tab', this.beat)) {
71898
- this.beamingHelper.registerBeatLineX('tab', this.beat, cx + this.x + this.width / 2, cx + this.x + this.width / 2);
71899
- }
71900
- }
71901
71268
  paint(cx, cy, canvas) {
71902
71269
  if (this._isVisibleRest) {
71903
71270
  const _ = ElementStyleHelper.beat(canvas, BeatSubElement.GuitarTabRests, this.beat);
@@ -71954,7 +71321,6 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
71954
71321
  slashNoteHead.effectElement = BeatSubElement.GuitarTabEffects;
71955
71322
  this.slash = slashNoteHead;
71956
71323
  slashNoteHead.beat = this.container.beat;
71957
- slashNoteHead.beamingHelper = this.beamingHelper;
71958
71324
  this.addNormal(slashNoteHead);
71959
71325
  beatEffects = slashNoteHead.beatEffects;
71960
71326
  }
@@ -71962,7 +71328,6 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
71962
71328
  const tabNoteNumbers = new TabNoteChordGlyph(0, 0, isGrace);
71963
71329
  this.noteNumbers = tabNoteNumbers;
71964
71330
  tabNoteNumbers.beat = this.container.beat;
71965
- tabNoteNumbers.beamingHelper = this.beamingHelper;
71966
71331
  for (const note of this.container.beat.notes) {
71967
71332
  if (note.isVisible) {
71968
71333
  this._createNoteGlyph(note);
@@ -71984,9 +71349,9 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
71984
71349
  // Note dots
71985
71350
  //
71986
71351
  if (this.container.beat.dots > 0 && tabRenderer.rhythmMode !== TabRhythmMode.Hidden) {
71352
+ const y = tabRenderer.getFlagAndBarPos();
71987
71353
  for (let i = 0; i < this.container.beat.dots; i++) {
71988
- this.addEffect(new AugmentationDotGlyph(0, tabRenderer.lineOffset * tabRenderer.bar.staff.tuning.length +
71989
- tabRenderer.settings.notation.rhythmHeight));
71354
+ this.addEffect(new AugmentationDotGlyph(0, y));
71990
71355
  }
71991
71356
  }
71992
71357
  }
@@ -71996,7 +71361,6 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
71996
71361
  const restGlyph = new TabRestGlyph(0, y, tabRenderer.showRests, this.container.beat.duration);
71997
71362
  this.restGlyph = restGlyph;
71998
71363
  restGlyph.beat = this.container.beat;
71999
- restGlyph.beamingHelper = this.beamingHelper;
72000
71364
  this.addNormal(restGlyph);
72001
71365
  //
72002
71366
  // Note dots
@@ -72034,21 +71398,11 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
72034
71398
  this.onTimeX = this.slash.x + this.slash.width / 2;
72035
71399
  }
72036
71400
  this.middleX = this.onTimeX;
71401
+ this.stemX = this.middleX;
72037
71402
  for (const g of centeredEffectGlyphs) {
72038
71403
  g.x = this.onTimeX;
72039
71404
  }
72040
71405
  }
72041
- updateBeamingHelper() {
72042
- if (this.noteNumbers) {
72043
- this.noteNumbers.updateBeamingHelper(this.container.x + this.x);
72044
- }
72045
- else if (this.restGlyph) {
72046
- this.restGlyph.updateBeamingHelper(this.container.x + this.x);
72047
- }
72048
- else if (this.slash) {
72049
- this.slash.updateBeamingHelper(this.container.x + this.x);
72050
- }
72051
- }
72052
71406
  _createNoteGlyph(n) {
72053
71407
  const tr = this.renderer;
72054
71408
  const noteNumberGlyph = new NoteNumberGlyph(0, 0, n);
@@ -72059,7 +71413,7 @@ class TabBeatGlyph extends BeatOnNoteGlyphBase {
72059
71413
  this.noteNumbers.addNoteGlyph(noteNumberGlyph, n);
72060
71414
  const topY = noteNumberGlyph.y - noteNumberGlyph.height / 2;
72061
71415
  const bottomY = topY + noteNumberGlyph.height;
72062
- this.renderer.helpers.collisionHelper.reserveBeatSlot(this.container.beat, topY, bottomY);
71416
+ this.renderer.collisionHelper.reserveBeatSlot(this.container.beat, topY, bottomY);
72063
71417
  const minString = tr.minString;
72064
71418
  const maxString = tr.maxString;
72065
71419
  if (Number.isNaN(minString) || minString < n.string) {
@@ -72331,7 +71685,7 @@ class TabBarRenderer extends LineBarRenderer {
72331
71685
  }
72332
71686
  createLinePreBeatGlyphs() {
72333
71687
  // Clef
72334
- if (this.isFirstOfLine) {
71688
+ if (this.isFirstOfStaff) {
72335
71689
  const center = (this.bar.staff.tuning.length - 1) / 2;
72336
71690
  this.createStartSpacing();
72337
71691
  this.addPreBeatGlyph(new TabClefGlyph(0, this.getLineY(center)));
@@ -72422,14 +71776,14 @@ class TabBarRenderer extends LineBarRenderer {
72422
71776
  // currently only used for duplets
72423
71777
  return this.getFlagAndBarPos();
72424
71778
  }
72425
- shouldPaintFlag(beat, h) {
72426
- if (!super.shouldPaintFlag(beat, h)) {
71779
+ shouldPaintFlag(beat) {
71780
+ if (!super.shouldPaintFlag(beat)) {
72427
71781
  return false;
72428
71782
  }
72429
71783
  if (beat.graceType !== GraceType.None) {
72430
71784
  return false;
72431
71785
  }
72432
- return this.drawBeamHelperAsFlags(h);
71786
+ return true;
72433
71787
  }
72434
71788
  paintBeamingStem(beat, cy, x, topY, bottomY, canvas) {
72435
71789
  if (bottomY < topY) {
@@ -73367,6 +72721,7 @@ const _barrel$7 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty(
73367
72721
  get AlphaTexParseMode () { return AlphaTexParseMode; },
73368
72722
  AlphaTexParser,
73369
72723
  get AlphaTexStaffNoteKind () { return AlphaTexStaffNoteKind; },
72724
+ get AlphaTexVoiceMode () { return AlphaTexVoiceMode; },
73370
72725
  get ArgumentListParseTypesMode () { return ArgumentListParseTypesMode; }
73371
72726
  }, Symbol.toStringTag, { value: 'Module' }));
73372
72727