瀏覽代碼

merge osmd-public: Vex.Flow -> VF refactor, don't autobeam tab notes by default with autoBeam option -> AutoBeamTabs EngravingRule

sschmidTU 3 年之前
父節點
當前提交
9096246142
共有 26 個文件被更改,包括 349 次插入299 次删除
  1. 2 0
      src/MusicalScore/Graphical/EngravingRules.ts
  2. 2 1
      src/MusicalScore/Graphical/GraphicalTie.ts
  3. 1 1
      src/MusicalScore/Graphical/MusicSheetDrawer.ts
  4. 9 8
      src/MusicalScore/Graphical/VexFlow/CanvasVexFlowBackend.ts
  5. 5 4
      src/MusicalScore/Graphical/VexFlow/SvgVexFlowBackend.ts
  6. 5 4
      src/MusicalScore/Graphical/VexFlow/VexFlowBackend.ts
  7. 92 83
      src/MusicalScore/Graphical/VexFlow/VexFlowConverter.ts
  8. 5 4
      src/MusicalScore/Graphical/VexFlow/VexFlowGraphicalNote.ts
  9. 2 1
      src/MusicalScore/Graphical/VexFlow/VexFlowGraphicalSymbolFactory.ts
  10. 2 1
      src/MusicalScore/Graphical/VexFlow/VexFlowInstrumentBrace.ts
  11. 6 5
      src/MusicalScore/Graphical/VexFlow/VexFlowInstrumentBracket.ts
  12. 112 108
      src/MusicalScore/Graphical/VexFlow/VexFlowMeasure.ts
  13. 5 4
      src/MusicalScore/Graphical/VexFlow/VexFlowMultiRestMeasure.ts
  14. 20 19
      src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetCalculator.ts
  15. 2 1
      src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetDrawer.ts
  16. 10 9
      src/MusicalScore/Graphical/VexFlow/VexFlowOctaveShift.ts
  17. 6 5
      src/MusicalScore/Graphical/VexFlow/VexFlowSlur.ts
  18. 4 3
      src/MusicalScore/Graphical/VexFlow/VexFlowStaffEntry.ts
  19. 7 6
      src/MusicalScore/Graphical/VexFlow/VexFlowTabMeasure.ts
  20. 4 3
      src/MusicalScore/Graphical/VexFlow/VexFlowVoiceEntry.ts
  21. 9 1
      src/MusicalScore/ScoreIO/InstrumentReader.ts
  22. 4 4
      src/MusicalScore/ScoreIO/VoiceGenerator.ts
  23. 1 1
      src/MusicalScore/VoiceData/Arpeggio.ts
  24. 8 1
      src/MusicalScore/VoiceData/TabNote.ts
  25. 20 16
      src/VexFlowPatch/readme.txt
  26. 6 6
      src/VexFlowPatch/src/beam.js

+ 2 - 0
src/MusicalScore/Graphical/EngravingRules.ts

@@ -56,6 +56,7 @@ export class EngravingRules {
     public AutoBeamNotes: boolean;
     /** Options for autoBeaming like whether to beam over rests. See AutoBeamOptions interface. */
     public AutoBeamOptions: AutoBeamOptions;
+    public AutoBeamTabs: boolean;
     public BeamWidth: number;
     public BeamSpaceWidth: number;
     public BeamForwardLength: number;
@@ -398,6 +399,7 @@ export class EngravingRules {
             beam_rests: false,
             maintain_stem_directions: false
         };
+        this.AutoBeamTabs = false;
 
         // Beam Sizing Variables
         this.BeamWidth = EngravingRules.unit / 2.0;

+ 2 - 1
src/MusicalScore/Graphical/GraphicalTie.ts

@@ -1,6 +1,7 @@
 import {Tie} from "../VoiceData/Tie";
 import {GraphicalNote} from "./GraphicalNote";
 import Vex from "vexflow";
+import VF = Vex.Flow;
 
 /**
  * The graphical counterpart of a [[Tie]].
@@ -9,7 +10,7 @@ export class GraphicalTie {
     private tie: Tie;
     private startNote: GraphicalNote;
     private endNote: GraphicalNote;
-    public vfTie: Vex.Flow.StaveTie;
+    public vfTie: VF.StaveTie;
 
     constructor(tie: Tie, start: GraphicalNote = undefined, end: GraphicalNote = undefined) {
         this.tie = tie;

+ 1 - 1
src/MusicalScore/Graphical/MusicSheetDrawer.ts

@@ -349,7 +349,7 @@ export abstract class MusicSheetDrawer {
                 }
             } else {
                 for (const bracket of musicSystem.GroupBrackets) {
-                    (bracket as VexFlowInstrumentBracket).Visible = false; //.setType(Vex.Flow.StaveConnector.type.NONE);
+                    (bracket as VexFlowInstrumentBracket).Visible = false; //.setType(VF.StaveConnector.type.NONE);
                 }
             }
         }

+ 9 - 8
src/MusicalScore/Graphical/VexFlow/CanvasVexFlowBackend.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 
 import {VexFlowBackend} from "./VexFlowBackend";
 import {FontStyles} from "../../../Common/Enums/FontStyles";
@@ -18,8 +19,8 @@ export class CanvasVexFlowBackend extends VexFlowBackend {
         this.rules = rules;
     }
 
-    public getVexflowBackendType(): Vex.Flow.Renderer.Backends {
-        return Vex.Flow.Renderer.Backends.CANVAS;
+    public getVexflowBackendType(): VF.Renderer.Backends {
+        return VF.Renderer.Backends.CANVAS;
     }
 
     public getOSMDBackendType(): BackendType {
@@ -47,8 +48,8 @@ export class CanvasVexFlowBackend extends VexFlowBackend {
         this.canvas.style.zIndex = "0";
         this.inner.appendChild(this.canvas);
         container.appendChild(this.inner);
-        this.renderer = new Vex.Flow.Renderer(this.canvas, this.getVexflowBackendType());
-        this.ctx = <Vex.Flow.CanvasContext>this.renderer.getContext();
+        this.renderer = new VF.Renderer(this.canvas, this.getVexflowBackendType());
+        this.ctx = <VF.CanvasContext>this.renderer.getContext();
     }
 
     /**
@@ -65,11 +66,11 @@ export class CanvasVexFlowBackend extends VexFlowBackend {
         this.canvas = document.createElement("canvas");
         (this.canvas as any).width = width;
         (this.canvas as any).height = height;
-        this.renderer = new Vex.Flow.Renderer(this.canvas, this.getVexflowBackendType());
-        this.ctx = <Vex.Flow.CanvasContext>this.renderer.getContext();
+        this.renderer = new VF.Renderer(this.canvas, this.getVexflowBackendType());
+        this.ctx = <VF.CanvasContext>this.renderer.getContext();
     }
 
-    public getContext(): Vex.Flow.CanvasContext {
+    public getContext(): VF.CanvasContext {
         return this.ctx;
     }
 
@@ -165,7 +166,7 @@ export class CanvasVexFlowBackend extends VexFlowBackend {
         return undefined;
     }
 
-    private ctx: Vex.Flow.CanvasContext;
+    private ctx: VF.CanvasContext;
 
     public get CanvasRenderingCtx(): CanvasRenderingContext2D {
         // This clusterfuck is only there to counter act my favorite vexflow line:

+ 5 - 4
src/MusicalScore/Graphical/VexFlow/SvgVexFlowBackend.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 
 import {VexFlowBackend} from "./VexFlowBackend";
 import {VexFlowConverter} from "./VexFlowConverter";
@@ -12,7 +13,7 @@ import log from "loglevel";
 
 export class SvgVexFlowBackend extends VexFlowBackend {
 
-    private ctx: Vex.Flow.SVGContext;
+    private ctx: VF.SVGContext;
     public zoom: number; // currently unused
 
     constructor(rules: EngravingRules) {
@@ -20,8 +21,8 @@ export class SvgVexFlowBackend extends VexFlowBackend {
         this.rules = rules;
     }
 
-    public getVexflowBackendType(): Vex.Flow.Renderer.Backends {
-        return Vex.Flow.Renderer.Backends.SVG;
+    public getVexflowBackendType(): VF.Renderer.Backends {
+        return VF.Renderer.Backends.SVG;
     }
 
     public getOSMDBackendType(): BackendType {
@@ -49,7 +50,7 @@ export class SvgVexFlowBackend extends VexFlowBackend {
         this.ctx.svg.id = "osmdSvgPage" + id;
     }
 
-    public getContext(): Vex.Flow.SVGContext {
+    public getContext(): VF.SVGContext {
         return this.ctx;
     }
 

+ 5 - 4
src/MusicalScore/Graphical/VexFlow/VexFlowBackend.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 import {FontStyles} from "../../../Common/Enums/FontStyles";
 import {Fonts} from "../../../Common/Enums/Fonts";
 import {RectangleF2D} from "../../../Common/DataObjects/RectangleF2D";
@@ -39,7 +40,7 @@ export abstract class VexFlowBackend {
   public getRenderElement(): HTMLElement {
     //console.log("backend type: " + this.getVexflowBackendType());
     let renderingHtmlElement: HTMLElement = this.canvas; // for SVGBackend
-    if (this.getVexflowBackendType() === Vex.Flow.Renderer.Backends.CANVAS) {
+    if (this.getVexflowBackendType() === VF.Renderer.Backends.CANVAS) {
       renderingHtmlElement = this.inner;
       // usage in removeFromContainer:
       // for SVG, this.canvas === this.inner, but for Canvas, removing this.canvas causes an error because it's not a child of container,
@@ -48,7 +49,7 @@ export abstract class VexFlowBackend {
     return renderingHtmlElement;
   }
 
-  public getRenderer(): Vex.Flow.Renderer {
+  public getRenderer(): VF.Renderer {
     return this.renderer;
   }
 
@@ -105,14 +106,14 @@ public abstract getContext(): Vex.IRenderContext;
 
   public abstract renderCurve(points: PointF2D[]): Node;
 
-  public abstract getVexflowBackendType(): Vex.Flow.Renderer.Backends;
+  public abstract getVexflowBackendType(): VF.Renderer.Backends;
 
   /** The general type of backend: Canvas or SVG.
    * This is not used for now (only VexflowBackendType used), but it may be useful when we don't want to use a Vexflow class.
    */
   public abstract getOSMDBackendType(): BackendType;
 
-  protected renderer: Vex.Flow.Renderer;
+  protected renderer: VF.Renderer;
   protected inner: HTMLElement;
   protected canvas: HTMLElement;
 }

+ 92 - 83
src/MusicalScore/Graphical/VexFlow/VexFlowConverter.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 import {ClefEnum} from "../../VoiceData/Instructions/ClefInstruction";
 import {ClefInstruction} from "../../VoiceData/Instructions/ClefInstruction";
 import {Pitch} from "../../../Common/DataObjects/Pitch";
@@ -24,7 +25,7 @@ import { Notehead, NoteHeadShape } from "../../VoiceData/Notehead";
 import { unitInPixels } from "./VexFlowMusicSheetDrawer";
 import { EngravingRules } from "../EngravingRules";
 import { Note } from "../../../MusicalScore/VoiceData/Note";
-import StaveNote = Vex.Flow.StaveNote;
+import StaveNote = VF.StaveNote;
 import { ArpeggioType } from "../../VoiceData/Arpeggio";
 import { TabNote } from "../../VoiceData/TabNote";
 import { PlacementEnum } from "../../VoiceData/Expressions/AbstractExpression";
@@ -220,11 +221,11 @@ export class VexFlowConverter {
         }
     }
 
-    public static GhostNotes(frac: Fraction): Vex.Flow.GhostNote[] {
-        const ghostNotes: Vex.Flow.GhostNote[] = [];
+    public static GhostNotes(frac: Fraction): VF.GhostNote[] {
+        const ghostNotes: VF.GhostNote[] = [];
         const durations: string[] = VexFlowConverter.durations(frac, false);
         for (const duration of durations) {
-            ghostNotes.push(new Vex.Flow.GhostNote({
+            ghostNotes.push(new VF.GhostNote({
                 duration: duration,
                 //dots: dots
             }));
@@ -235,9 +236,9 @@ export class VexFlowConverter {
     /**
      * Convert a GraphicalVoiceEntry to a VexFlow StaveNote
      * @param gve the GraphicalVoiceEntry which can hold a note or a chord on the staff belonging to one voice
-     * @returns {Vex.Flow.StaveNote}
+     * @returns {VF.StaveNote}
      */
-    public static StaveNote(gve: GraphicalVoiceEntry): Vex.Flow.StaveNote {
+    public static StaveNote(gve: GraphicalVoiceEntry): VF.StaveNote {
         // if (gve.octaveShiftValue !== OctaveEnum.NONE) { // gves with accidentals in octave shift brackets can be unsorted
         gve.sortForVexflow(); // also necessary for some other cases, see test_sorted_notes... sample
         //   sort and reverse replace the array anyways, so we might as well directly sort them reversely for now.
@@ -443,7 +444,7 @@ export class VexFlowConverter {
             duration += "r";
         }
 
-        let vfnote: Vex.Flow.StaveNote;
+        let vfnote: VF.StaveNote;
         const vfnoteStruct: any = {
             align_center: alignCenter,
             auto_stem: true,
@@ -455,14 +456,14 @@ export class VexFlowConverter {
 
         const firstNote: Note = gve.notes[0].sourceNote;
         if (firstNote.IsCueNote) {
-            vfnoteStruct.glyph_font_scale = Vex.Flow.DEFAULT_NOTATION_FONT_SCALE * Vex.Flow.GraceNote.SCALE;
-            vfnoteStruct.stroke_px = Vex.Flow.GraceNote.LEDGER_LINE_OFFSET;
+            vfnoteStruct.glyph_font_scale = VF.DEFAULT_NOTATION_FONT_SCALE * VF.GraceNote.SCALE;
+            vfnoteStruct.stroke_px = VF.GraceNote.LEDGER_LINE_OFFSET;
         }
 
         if (gve.parentVoiceEntry.IsGrace || gve.notes[0].sourceNote.IsCueNote) {
-            vfnote = new Vex.Flow.GraceNote(vfnoteStruct);
+            vfnote = new VF.GraceNote(vfnoteStruct);
         } else {
-            vfnote = new Vex.Flow.StaveNote(vfnoteStruct);
+            vfnote = new VF.StaveNote(vfnoteStruct);
             (vfnote as any).stagger_same_whole_notes = rules.StaggerSameWholeNotes;
             //   it would be nice to only save this once, not for every note, but has to be accessible in stavenote.js
         }
@@ -516,11 +517,11 @@ export class VexFlowConverter {
             const wantedStemDirection: StemDirectionType = gve.parentVoiceEntry.WantedStemDirection;
             switch (wantedStemDirection) {
                 case(StemDirectionType.Up):
-                    vfnote.setStemDirection(Vex.Flow.Stem.UP);
+                    vfnote.setStemDirection(VF.Stem.UP);
                     gve.parentVoiceEntry.StemDirection = StemDirectionType.Up;
                     break;
                 case (StemDirectionType.Down):
-                    vfnote.setStemDirection(Vex.Flow.Stem.DOWN);
+                    vfnote.setStemDirection(VF.Stem.DOWN);
                     gve.parentVoiceEntry.StemDirection = StemDirectionType.Down;
                     break;
                 default:
@@ -532,21 +533,21 @@ export class VexFlowConverter {
             (notes[i] as VexFlowGraphicalNote).setIndex(vfnote, i);
             if (accidentals[i]) {
                 if (accidentals[i] === "###") { // triple sharp
-                    vfnote.addAccidental(i, new Vex.Flow.Accidental("##"));
-                    vfnote.addAccidental(i, new Vex.Flow.Accidental("#"));
+                    vfnote.addAccidental(i, new VF.Accidental("##"));
+                    vfnote.addAccidental(i, new VF.Accidental("#"));
                     continue;
                 } else if (accidentals[i] === "bbs") { // triple flat
-                    vfnote.addAccidental(i, new Vex.Flow.Accidental("bb"));
-                    vfnote.addAccidental(i, new Vex.Flow.Accidental("b"));
+                    vfnote.addAccidental(i, new VF.Accidental("bb"));
+                    vfnote.addAccidental(i, new VF.Accidental("b"));
                     continue;
                 }
-                vfnote.addAccidental(i, new Vex.Flow.Accidental(accidentals[i])); // normal accidental
+                vfnote.addAccidental(i, new VF.Accidental(accidentals[i])); // normal accidental
             }
 
             // add Tremolo strokes (only single note tremolos for now, Vexflow doesn't have beams for two-note tremolos yet)
             const tremoloStrokes: number = notes[i].sourceNote.TremoloStrokes;
             if (tremoloStrokes > 0) {
-                const tremolo: Vex.Flow.Tremolo = new Vex.Flow.Tremolo(tremoloStrokes);
+                const tremolo: VF.Tremolo = new VF.Tremolo(tremoloStrokes);
                 (tremolo as any).extra_stroke_scale = rules.TremoloStrokeScale;
                 (tremolo as any).y_spacing_scale = rules.TremoloYSpacingScale;
                 vfnote.addModifier(i, tremolo);
@@ -567,90 +568,90 @@ export class VexFlowConverter {
         return vfnote;
     }
 
-    public static generateArticulations(vfnote: Vex.Flow.StemmableNote, articulations: Articulation[],
+    public static generateArticulations(vfnote: VF.StemmableNote, articulations: Articulation[],
                                         rules: EngravingRules): void {
         if (!vfnote || vfnote.getAttribute("type") === "GhostNote") {
             return;
         }
 
         for (const articulation of articulations) {
-            let vfArtPosition: number = Vex.Flow.Modifier.Position.ABOVE;
+            let vfArtPosition: number = VF.Modifier.Position.ABOVE;
 
-            if (vfnote.getStemDirection() === Vex.Flow.Stem.UP) {
-                vfArtPosition = Vex.Flow.Modifier.Position.BELOW;
+            if (vfnote.getStemDirection() === VF.Stem.UP) {
+                vfArtPosition = VF.Modifier.Position.BELOW;
             }
-            let vfArt: Vex.Flow.Articulation = undefined;
+            let vfArt: VF.Articulation = undefined;
             const articulationEnum: ArticulationEnum = articulation.articulationEnum;
             if (rules.ArticulationPlacementFromXML) {
                 if (articulation.placement === PlacementEnum.Above) {
-                    vfArtPosition = Vex.Flow.Modifier.Position.ABOVE;
+                    vfArtPosition = VF.Modifier.Position.ABOVE;
                 } else if (articulation.placement === PlacementEnum.Below) {
-                    vfArtPosition = Vex.Flow.Modifier.Position.BELOW;
+                    vfArtPosition = VF.Modifier.Position.BELOW;
                 } // else if undefined: don't change
             }
             switch (articulationEnum) {
                 case ArticulationEnum.accent: {
-                    vfArt = new Vex.Flow.Articulation("a>");
+                    vfArt = new VF.Articulation("a>");
                     break;
                 }
                 case ArticulationEnum.downbow: {
-                    vfArt = new Vex.Flow.Articulation("am");
+                    vfArt = new VF.Articulation("am");
                     if (articulation.placement === undefined) { // downbow/upbow should be above by default
-                        vfArtPosition = Vex.Flow.Modifier.Position.ABOVE;
+                        vfArtPosition = VF.Modifier.Position.ABOVE;
                     }
                     break;
                 }
                 case ArticulationEnum.fermata: {
-                    vfArt = new Vex.Flow.Articulation("a@a");
-                    vfArtPosition = Vex.Flow.Modifier.Position.ABOVE;
+                    vfArt = new VF.Articulation("a@a");
+                    vfArtPosition = VF.Modifier.Position.ABOVE;
                     break;
                 }
                 case ArticulationEnum.marcatodown: {
-                    vfArt = new Vex.Flow.Articulation("a|"); // Vexflow only knows marcato up, so we use a down stroke here.
+                    vfArt = new VF.Articulation("a|"); // Vexflow only knows marcato up, so we use a down stroke here.
                     break;
                 }
                 case ArticulationEnum.marcatoup: {
-                    vfArt = new Vex.Flow.Articulation("a^");
+                    vfArt = new VF.Articulation("a^");
                     break;
                 }
                 case ArticulationEnum.invertedfermata: {
-                    vfArt = new Vex.Flow.Articulation("a@u");
-                    vfArtPosition = Vex.Flow.Modifier.Position.BELOW;
+                    vfArt = new VF.Articulation("a@u");
+                    vfArtPosition = VF.Modifier.Position.BELOW;
                     break;
                 }
                 case ArticulationEnum.lefthandpizzicato: {
-                    vfArt = new Vex.Flow.Articulation("a+");
+                    vfArt = new VF.Articulation("a+");
                     break;
                 }
                 case ArticulationEnum.naturalharmonic: {
-                    vfArt = new Vex.Flow.Articulation("ah");
+                    vfArt = new VF.Articulation("ah");
                     break;
                 }
                 case ArticulationEnum.snappizzicato: {
-                    vfArt = new Vex.Flow.Articulation("ao");
+                    vfArt = new VF.Articulation("ao");
                     break;
                 }
                 case ArticulationEnum.staccatissimo: {
-                    vfArt = new Vex.Flow.Articulation("av");
+                    vfArt = new VF.Articulation("av");
                     break;
                 }
                 case ArticulationEnum.staccato: {
-                    vfArt = new Vex.Flow.Articulation("a.");
+                    vfArt = new VF.Articulation("a.");
                     break;
                 }
                 case ArticulationEnum.tenuto: {
-                    vfArt = new Vex.Flow.Articulation("a-");
+                    vfArt = new VF.Articulation("a-");
                     break;
                 }
                 case ArticulationEnum.upbow: {
-                    vfArt = new Vex.Flow.Articulation("a|");
+                    vfArt = new VF.Articulation("a|");
                     if (articulation.placement === undefined) { // downbow/upbow should be above by default
-                        vfArtPosition = Vex.Flow.Modifier.Position.ABOVE;
+                        vfArtPosition = VF.Modifier.Position.ABOVE;
                     }
                     break;
                 }
                 case ArticulationEnum.strongaccent: {
-                    vfArt = new Vex.Flow.Articulation("a^");
+                    vfArt = new VF.Articulation("a^");
                     break;
                 }
                 default: {
@@ -664,46 +665,46 @@ export class VexFlowConverter {
         }
     }
 
-    public static generateOrnaments(vfnote: Vex.Flow.StemmableNote, oContainer: OrnamentContainer): void {
-        let vfPosition: number = Vex.Flow.Modifier.Position.ABOVE;
+    public static generateOrnaments(vfnote: VF.StemmableNote, oContainer: OrnamentContainer): void {
+        let vfPosition: number = VF.Modifier.Position.ABOVE;
         if (oContainer.placement === PlacementEnum.Below) {
-            vfPosition = Vex.Flow.Modifier.Position.BELOW;
+            vfPosition = VF.Modifier.Position.BELOW;
         }
 
-        let vfOrna: Vex.Flow.Ornament = undefined;
+        let vfOrna: VF.Ornament = undefined;
         switch (oContainer.GetOrnament) {
             case OrnamentEnum.DelayedInvertedTurn: {
-                vfOrna = new Vex.Flow.Ornament("turn_inverted");
+                vfOrna = new VF.Ornament("turn_inverted");
                 vfOrna.setDelayed(true);
                 break;
             }
             case OrnamentEnum.DelayedTurn: {
-                vfOrna = new Vex.Flow.Ornament("turn");
+                vfOrna = new VF.Ornament("turn");
                 vfOrna.setDelayed(true);
                 break;
             }
             case OrnamentEnum.InvertedMordent: {
-                vfOrna = new Vex.Flow.Ornament("mordent"); // Vexflow uses baroque, not MusicXML definition
+                vfOrna = new VF.Ornament("mordent"); // Vexflow uses baroque, not MusicXML definition
                 vfOrna.setDelayed(false);
                 break;
             }
             case OrnamentEnum.InvertedTurn: {
-                vfOrna = new Vex.Flow.Ornament("turn_inverted");
+                vfOrna = new VF.Ornament("turn_inverted");
                 vfOrna.setDelayed(false);
                 break;
             }
             case OrnamentEnum.Mordent: {
-                vfOrna = new Vex.Flow.Ornament("mordent_inverted");
+                vfOrna = new VF.Ornament("mordent_inverted");
                 vfOrna.setDelayed(false);
                 break;
             }
             case OrnamentEnum.Trill: {
-                vfOrna = new Vex.Flow.Ornament("tr");
+                vfOrna = new VF.Ornament("tr");
                 vfOrna.setDelayed(false);
                 break;
             }
             case OrnamentEnum.Turn: {
-                vfOrna = new Vex.Flow.Ornament("turn");
+                vfOrna = new VF.Ornament("turn");
                 vfOrna.setDelayed(false);
                 break;
             }
@@ -724,33 +725,33 @@ export class VexFlowConverter {
         }
     }
 
-    public static StrokeTypeFromArpeggioType(arpeggioType: ArpeggioType): Vex.Flow.Stroke.Type {
+    public static StrokeTypeFromArpeggioType(arpeggioType: ArpeggioType): VF.Stroke.Type {
         switch (arpeggioType) {
             case ArpeggioType.ARPEGGIO_DIRECTIONLESS:
-                return Vex.Flow.Stroke.Type.ARPEGGIO_DIRECTIONLESS;
+                return VF.Stroke.Type.ARPEGGIO_DIRECTIONLESS;
             case ArpeggioType.BRUSH_DOWN:
-                return Vex.Flow.Stroke.Type.BRUSH_UP; // TODO somehow up and down are mixed up in Vexflow right now
+                return VF.Stroke.Type.BRUSH_UP; // TODO somehow up and down are mixed up in Vexflow right now
             case ArpeggioType.BRUSH_UP:
-                return Vex.Flow.Stroke.Type.BRUSH_DOWN; // TODO somehow up and down are mixed up in Vexflow right now
+                return VF.Stroke.Type.BRUSH_DOWN; // TODO somehow up and down are mixed up in Vexflow right now
             case ArpeggioType.RASQUEDO_DOWN:
-                return Vex.Flow.Stroke.Type.RASQUEDO_UP;
+                return VF.Stroke.Type.RASQUEDO_UP;
             case ArpeggioType.RASQUEDO_UP:
-                return Vex.Flow.Stroke.Type.RASQUEDO_DOWN;
+                return VF.Stroke.Type.RASQUEDO_DOWN;
             case ArpeggioType.ROLL_DOWN:
-                return Vex.Flow.Stroke.Type.ROLL_UP; // TODO somehow up and down are mixed up in Vexflow right now
+                return VF.Stroke.Type.ROLL_UP; // TODO somehow up and down are mixed up in Vexflow right now
             case ArpeggioType.ROLL_UP:
-                return Vex.Flow.Stroke.Type.ROLL_DOWN; // TODO somehow up and down are mixed up in Vexflow right now
+                return VF.Stroke.Type.ROLL_DOWN; // TODO somehow up and down are mixed up in Vexflow right now
             default:
-                return Vex.Flow.Stroke.Type.ARPEGGIO_DIRECTIONLESS;
+                return VF.Stroke.Type.ARPEGGIO_DIRECTIONLESS;
         }
     }
 
     /**
      * Convert a set of GraphicalNotes to a VexFlow StaveNote
      * @param notes form a chord on the staff
-     * @returns {Vex.Flow.StaveNote}
+     * @returns {VF.StaveNote}
      */
-    public static CreateTabNote(gve: GraphicalVoiceEntry): Vex.Flow.TabNote {
+    public static CreateTabNote(gve: GraphicalVoiceEntry): VF.TabNote {
         const tabPositions: {str: number, fret: number}[] = [];
         const notes: GraphicalNote[] = gve.notes.reverse();
         const tabPhrases: { type: number, text: string, width: number }[] = [];
@@ -758,6 +759,7 @@ export class VexFlowConverter {
         const isTuplet: boolean = gve.notes[0].sourceNote.NoteTuplet !== undefined;
         let duration: string = VexFlowConverter.durations(frac, isTuplet)[0];
         let numDots: number = 0;
+        let tabVibrato: boolean = false;
         for (const note of gve.notes) {
             const tabNote: TabNote = note.sourceNote as TabNote;
             const tabPosition: {str: number, fret: number} = {str: tabNote.StringNumberTab, fret: tabNote.FretNumber};
@@ -774,13 +776,17 @@ export class VexFlowConverter {
                         phraseText = "1/4";
                     }
                     if (bend.direction === "up") {
-                        tabPhrases.push({type: Vex.Flow.Bend.UP, text: phraseText, width: 10});
+                        tabPhrases.push({type: VF.Bend.UP, text: phraseText, width: 10});
                     } else {
-                        tabPhrases.push({type: Vex.Flow.Bend.DOWN, text: phraseText, width: 10});
+                        tabPhrases.push({type: VF.Bend.DOWN, text: phraseText, width: 10});
                     }
                 });
             }
 
+            if (tabNote.VibratoStroke) {
+                tabVibrato = true;
+            }
+
             if (numDots < note.numberOfDots) {
                 numDots = note.numberOfDots;
             }
@@ -789,7 +795,7 @@ export class VexFlowConverter {
             duration += "d";
         }
 
-        const vfnote: Vex.Flow.TabNote = new Vex.Flow.TabNote({
+        const vfnote: VF.TabNote = new VF.TabNote({
             duration: duration,
             positions: tabPositions,
         });
@@ -799,12 +805,15 @@ export class VexFlowConverter {
         }
 
         tabPhrases.forEach(function(phrase: { type: number, text: string, width: number }): void {
-            if (phrase.type === Vex.Flow.Bend.UP) {
-                vfnote.addModifier (new Vex.Flow.Bend(phrase.text, false));
+            if (phrase.type === VF.Bend.UP) {
+                vfnote.addModifier (new VF.Bend(phrase.text, false));
             } else {
-                vfnote.addModifier (new Vex.Flow.Bend(phrase.text, true));
+                vfnote.addModifier (new VF.Bend(phrase.text, true));
             }
         });
+        if (tabVibrato) {
+            vfnote.addModifier(new VF.Vibrato());
+        }
 
         return vfnote;
     }
@@ -916,10 +925,10 @@ export class VexFlowConverter {
     /**
      * Convert a RhythmInstruction to a VexFlow TimeSignature object
      * @param rhythm
-     * @returns {Vex.Flow.TimeSignature}
+     * @returns {VF.TimeSignature}
      * @constructor
      */
-    public static TimeSignature(rhythm: RhythmInstruction): Vex.Flow.TimeSignature {
+    public static TimeSignature(rhythm: RhythmInstruction): VF.TimeSignature {
         let timeSpec: string;
         switch (rhythm.SymbolEnum) {
             case RhythmSymbolEnum.NONE:
@@ -933,7 +942,7 @@ export class VexFlowConverter {
                 break;
             default:
         }
-        return new Vex.Flow.TimeSignature(timeSpec);
+        return new VF.TimeSignature(timeSpec);
     }
 
     /**
@@ -972,21 +981,21 @@ export class VexFlowConverter {
         switch (lineType) {
             case SystemLinesEnum.SingleThin:
                 if (linePosition === SystemLinePosition.MeasureBegin) {
-                    return Vex.Flow.StaveConnector.type.SINGLE;
+                    return VF.StaveConnector.type.SINGLE;
                 }
-                return Vex.Flow.StaveConnector.type.SINGLE_RIGHT;
+                return VF.StaveConnector.type.SINGLE_RIGHT;
             case SystemLinesEnum.DoubleThin:
-                return Vex.Flow.StaveConnector.type.THIN_DOUBLE;
+                return VF.StaveConnector.type.THIN_DOUBLE;
             case SystemLinesEnum.ThinBold:
-                return Vex.Flow.StaveConnector.type.BOLD_DOUBLE_RIGHT;
+                return VF.StaveConnector.type.BOLD_DOUBLE_RIGHT;
             case SystemLinesEnum.BoldThinDots:
-                return Vex.Flow.StaveConnector.type.BOLD_DOUBLE_LEFT;
+                return VF.StaveConnector.type.BOLD_DOUBLE_LEFT;
             case SystemLinesEnum.DotsThinBold:
-                return Vex.Flow.StaveConnector.type.BOLD_DOUBLE_RIGHT;
+                return VF.StaveConnector.type.BOLD_DOUBLE_RIGHT;
             case SystemLinesEnum.DotsBoldBoldDots:
-                return Vex.Flow.StaveConnector.type.BOLD_DOUBLE_RIGHT;
+                return VF.StaveConnector.type.BOLD_DOUBLE_RIGHT;
             case SystemLinesEnum.None:
-                return Vex.Flow.StaveConnector.type.NONE;
+                return VF.StaveConnector.type.NONE;
             default:
         }
     }

+ 5 - 4
src/MusicalScore/Graphical/VexFlow/VexFlowGraphicalNote.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 import {GraphicalNote} from "../GraphicalNote";
 import {Note} from "../../VoiceData/Note";
 import {ClefInstruction} from "../../VoiceData/Instructions/ClefInstruction";
@@ -32,7 +33,7 @@ export class VexFlowGraphicalNote extends GraphicalNote {
     // The pitch of this note as given by VexFlowConverter.pitch
     public vfpitch: [string, string, ClefInstruction];
     // The corresponding VexFlow StaveNote (plus its index in the chord)
-    public vfnote: [Vex.Flow.StemmableNote, number];
+    public vfnote: [VF.StemmableNote, number];
     public vfnoteIndex: number;
     // The current clef
     private clef: ClefInstruction;
@@ -48,7 +49,7 @@ export class VexFlowGraphicalNote extends GraphicalNote {
         //     const acc: string = Pitch.accidentalVexflow(pitch.Accidental);
         //     if (acc) {
         //         alert(acc);
-        //         this.vfnote[0].addAccidental(this.vfnote[1], new Vex.Flow.Accidental(acc));
+        //         this.vfnote[0].addAccidental(this.vfnote[1], new VF.Accidental(acc));
         //     }
         // } else {
         // revert octave shift, as the placement of the note is independent of octave brackets
@@ -76,12 +77,12 @@ export class VexFlowGraphicalNote extends GraphicalNote {
      * @param note
      * @param index
      */
-    public setIndex(note: Vex.Flow.StemmableNote, index: number): void {
+    public setIndex(note: VF.StemmableNote, index: number): void {
         this.vfnote = [note, index];
         this.vfnoteIndex = index;
     }
 
-    public notehead(vfNote: Vex.Flow.StemmableNote = undefined): {line: number} {
+    public notehead(vfNote: VF.StemmableNote = undefined): {line: number} {
         let vfnote: any = vfNote;
         if (!vfnote) {
             vfnote = (this.vfnote[0] as any);

+ 2 - 1
src/MusicalScore/Graphical/VexFlow/VexFlowGraphicalSymbolFactory.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 import {IGraphicalSymbolFactory} from "../../Interfaces/IGraphicalSymbolFactory";
 import {MusicSystem} from "../MusicSystem";
 import {VexFlowMusicSystem} from "./VexFlowMusicSystem";
@@ -196,7 +197,7 @@ export class VexFlowGraphicalSymbolFactory implements IGraphicalSymbolFactory {
     public createInStaffClef(graphicalStaffEntry: GraphicalStaffEntry, clefInstruction: ClefInstruction): void {
         const se: VexFlowStaffEntry = graphicalStaffEntry as VexFlowStaffEntry;
         const vfClefParams: { type: string, size: string, annotation: string } = VexFlowConverter.Clef(clefInstruction, "small");
-        se.vfClefBefore = new Vex.Flow.ClefNote(vfClefParams.type, vfClefParams.size, vfClefParams.annotation);
+        se.vfClefBefore = new VF.ClefNote(vfClefParams.type, vfClefParams.size, vfClefParams.annotation);
         return;
     }
 

+ 2 - 1
src/MusicalScore/Graphical/VexFlow/VexFlowInstrumentBrace.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 import { VexFlowInstrumentBracket } from "./VexFlowInstrumentBracket";
 import { VexFlowStaffLine } from "./VexFlowStaffLine";
 
@@ -9,6 +10,6 @@ export class VexFlowInstrumentBrace extends VexFlowInstrumentBracket {
 
     constructor(firstVexFlowStaffLine: VexFlowStaffLine, lastVexFlowStaffLine: VexFlowStaffLine, depth: number = 0) {
         super(firstVexFlowStaffLine, lastVexFlowStaffLine, depth);
-        this.vexflowConnector.setType(Vex.Flow.StaveConnector.type.BRACE);
+        this.vexflowConnector.setType(VF.StaveConnector.type.BRACE);
     }
 }

+ 6 - 5
src/MusicalScore/Graphical/VexFlow/VexFlowInstrumentBracket.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 import { GraphicalObject } from "../GraphicalObject";
 import { VexFlowStaffLine } from "./VexFlowStaffLine";
 import { BoundingBox } from "../BoundingBox";
@@ -10,7 +11,7 @@ import { unitInPixels } from "./VexFlowMusicSheetDrawer";
  */
 export class VexFlowInstrumentBracket extends GraphicalObject {
 
-    public vexflowConnector: Vex.Flow.StaveConnector;
+    public vexflowConnector: VF.StaveConnector;
     public Visible: boolean = true;
 
     constructor(firstVexFlowStaffLine: VexFlowStaffLine, lastVexFlowStaffLine: VexFlowStaffLine, depth: number = 0) {
@@ -18,7 +19,7 @@ export class VexFlowInstrumentBracket extends GraphicalObject {
         this.PositionAndShape = new BoundingBox(this, firstVexFlowStaffLine.ParentMusicSystem.PositionAndShape);
         const firstVexMeasure: VexFlowMeasure = firstVexFlowStaffLine.Measures[0] as VexFlowMeasure;
         const lastVexMeasure: VexFlowMeasure = lastVexFlowStaffLine.Measures[0] as VexFlowMeasure;
-        this.addConnector(firstVexMeasure.getVFStave(), lastVexMeasure.getVFStave(), Vex.Flow.StaveConnector.type.BRACKET, depth);
+        this.addConnector(firstVexMeasure.getVFStave(), lastVexMeasure.getVFStave(), VF.StaveConnector.type.BRACKET, depth);
     }
 
     /**
@@ -31,7 +32,7 @@ export class VexFlowInstrumentBracket extends GraphicalObject {
             this.vexflowConnector.setContext(ctx).draw();
         }
         // Set bounding box
-        const con: Vex.Flow.StaveConnector = this.vexflowConnector;
+        const con: VF.StaveConnector = this.vexflowConnector;
         // First line in first stave
         const topY: number = con.top_stave.getYForLine(0);
         // Last line in last stave
@@ -49,8 +50,8 @@ export class VexFlowInstrumentBracket extends GraphicalObject {
      * @param {Stave} stave2: Second stave
      * @param {Flow.StaveConnector.type} type: Type of connector
      */
-    private addConnector(stave1: Vex.Flow.Stave, stave2: Vex.Flow.Stave, type: any, depth: number): void {
-        this.vexflowConnector = new Vex.Flow.StaveConnector(stave1, stave2)
+    private addConnector(stave1: VF.Stave, stave2: VF.Stave, type: any, depth: number): void {
+        this.vexflowConnector = new VF.StaveConnector(stave1, stave2)
         .setType(type)
         .setXShift(depth * -5);
     }

+ 112 - 108
src/MusicalScore/Graphical/VexFlow/VexFlowMeasure.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 import {GraphicalMeasure} from "../GraphicalMeasure";
 import {SourceMeasure} from "../../VoiceData/SourceMeasure";
 import {Staff} from "../../VoiceData/Staff";
@@ -12,10 +13,10 @@ import {VexFlowStaffEntry} from "./VexFlowStaffEntry";
 import {Beam} from "../../VoiceData/Beam";
 import {GraphicalNote} from "../GraphicalNote";
 import {GraphicalStaffEntry} from "../GraphicalStaffEntry";
-import StaveConnector = Vex.Flow.StaveConnector;
-import StaveNote = Vex.Flow.StaveNote;
-import StemmableNote = Vex.Flow.StemmableNote;
-import NoteSubGroup = Vex.Flow.NoteSubGroup;
+import StaveConnector = VF.StaveConnector;
+import StaveNote = VF.StaveNote;
+import StemmableNote = VF.StemmableNote;
+import NoteSubGroup = VF.NoteSubGroup;
 import log from "loglevel";
 import {unitInPixels} from "./VexFlowMusicSheetDrawer";
 import {Tuplet} from "../../VoiceData/Tuplet";
@@ -37,7 +38,7 @@ import { NoteType } from "../../VoiceData/NoteType";
 import { Arpeggio } from "../../VoiceData/Arpeggio";
 import { GraphicalTie } from "../GraphicalTie";
 
-// type StemmableNote = Vex.Flow.StemmableNote;
+// type StemmableNote = VF.StemmableNote;
 
 export class VexFlowMeasure extends GraphicalMeasure {
     constructor(staff: Staff, sourceMeasure: SourceMeasure = undefined, staffLine: StaffLine = undefined) {
@@ -62,29 +63,29 @@ export class VexFlowMeasure extends GraphicalMeasure {
     /** octaveOffset according to active clef */
     public octaveOffset: number = 3;
     /** The VexFlow Voices in the measure */
-    public vfVoices: { [voiceID: number]: Vex.Flow.Voice } = {};
+    public vfVoices: { [voiceID: number]: VF.Voice } = {};
     /** Call this function (if present) to x-format all the voices in the measure */
     public formatVoices: (width: number, parent: VexFlowMeasure) => void;
     /** The VexFlow Ties in the measure */
-    public vfTies: Vex.Flow.StaveTie[] = [];
+    public vfTies: VF.StaveTie[] = [];
     /** The repetition instructions given as words or symbols (coda, dal segno..) */
-    public vfRepetitionWords: Vex.Flow.Repetition[] = [];
+    public vfRepetitionWords: VF.Repetition[] = [];
     /** The VexFlow Stave (= one measure in a staffline) */
-    protected stave: Vex.Flow.Stave;
+    protected stave: VF.Stave;
     /** VexFlow StaveConnectors (vertical lines) */
-    protected connectors: Vex.Flow.StaveConnector[] = [];
+    protected connectors: VF.StaveConnector[] = [];
     /** Intermediate object to construct beams */
     private beams: { [voiceID: number]: [Beam, VexFlowVoiceEntry[]][] } = {};
     /** Beams created by (optional) autoBeam function. */
-    private autoVfBeams: Vex.Flow.Beam[];
+    private autoVfBeams: VF.Beam[];
     /** Beams of tuplet notes created by (optional) autoBeam function. */
-    private autoTupletVfBeams: Vex.Flow.Beam[];
+    private autoTupletVfBeams: VF.Beam[];
     /** VexFlow Beams */
-    private vfbeams: { [voiceID: number]: Vex.Flow.Beam[] };
+    private vfbeams: { [voiceID: number]: VF.Beam[] };
     /** Intermediate object to construct tuplets */
     protected tuplets: { [voiceID: number]: [Tuplet, VexFlowVoiceEntry[]][] } = {};
     /** VexFlow Tuplets */
-    private vftuplets: { [voiceID: number]: Vex.Flow.Tuplet[] } = {};
+    private vftuplets: { [voiceID: number]: VF.Tuplet[] } = {};
     // The engraving rules of OSMD.
     public rules: EngravingRules;
 
@@ -105,7 +106,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
 
         // TODO save beginning and end bar type, set these again after new stave.
 
-        this.stave = new Vex.Flow.Stave(0, 0, 0, {
+        this.stave = new VF.Stave(0, 0, 0, {
             fill_style: this.rules.StaffLineColor,
             space_above_staff_ln: 0,
             space_below_staff_ln: 0
@@ -118,10 +119,10 @@ export class VexFlowMeasure extends GraphicalMeasure {
         }
         // constructor sets beginning and end bar type to standard
 
-        this.stave.setBegBarType(Vex.Flow.Barline.type.NONE); // technically not correct, but we'd need to set the next measure's beginning bar type
+        this.stave.setBegBarType(VF.Barline.type.NONE); // technically not correct, but we'd need to set the next measure's beginning bar type
         if (this.parentSourceMeasure && this.parentSourceMeasure.endingBarStyleEnum === SystemLinesEnum.None) {
             // fix for vexflow ignoring ending barline style after new stave, apparently
-            this.stave.setEndBarType(Vex.Flow.Barline.type.NONE);
+            this.stave.setEndBarType(VF.Barline.type.NONE);
         }
         // the correct bar types seem to be set later
 
@@ -174,7 +175,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
             this.stave.addClef("tab", undefined, undefined, undefined);
         } else {
         const vfclef: { type: string, size: string, annotation: string } = VexFlowConverter.Clef(clef, "default");
-        this.stave.addClef(vfclef.type, vfclef.size, vfclef.annotation, Vex.Flow.StaveModifier.Position.BEGIN);
+        this.stave.addClef(vfclef.type, vfclef.size, vfclef.annotation, VF.StaveModifier.Position.BEGIN);
         }
         this.updateInstructionWidth();
     }
@@ -191,7 +192,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
                     return this.getYForLine(this.options.num_lines);
                 };
             } else if (lineNumber === 1) {
-                // Vex.Flow.Stave.setNumLines hides all but the top line.
+                // VF.Stave.setNumLines hides all but the top line.
                 // this is better
                 (this.stave.options as any).line_config = [
                     { visible: false },
@@ -262,10 +263,10 @@ export class VexFlowMeasure extends GraphicalMeasure {
      * @param rhythm
      */
     public addRhythmAtBegin(rhythm: RhythmInstruction): void {
-        const timeSig: Vex.Flow.TimeSignature = VexFlowConverter.TimeSignature(rhythm);
+        const timeSig: VF.TimeSignature = VexFlowConverter.TimeSignature(rhythm);
         this.stave.addModifier(
             timeSig,
-            Vex.Flow.StaveModifier.Position.BEGIN
+            VF.StaveModifier.Position.BEGIN
         );
         this.updateInstructionWidth();
     }
@@ -284,8 +285,8 @@ export class VexFlowMeasure extends GraphicalMeasure {
         for (const modifier of this.stave.getModifiers()) {
             if (!visible) {
                 // make clef invisible in vexflow. (only rendered to correct layout and staffentry boundingbox)
-                if (modifier.getCategory() === "clefs" && modifier.getPosition() === Vex.Flow.StaveModifier.Position.END) {
-                    if ((modifier as any).type === vfclef.type) { // any = Vex.Flow.Clef
+                if (modifier.getCategory() === "clefs" && modifier.getPosition() === VF.StaveModifier.Position.END) {
+                    if ((modifier as any).type === vfclef.type) { // any = VF.Clef
                         const transparentStyle: string = "#12345600";
                         const originalStyle: any = (modifier as any).getStyle();
                         if (originalStyle) {
@@ -323,27 +324,27 @@ export class VexFlowMeasure extends GraphicalMeasure {
                     case SystemLinesEnum.BoldThinDots:
                         //customize the barline draw function if repeat is beginning of system
                         if (!renderInitialLine) {
-                            (this.stave as any).modifiers[0].draw = function(stave: Vex.Flow.Stave): void {
+                            (this.stave as any).modifiers[0].draw = function(stave: VF.Stave): void {
                                 (stave as any).checkContext();
                                 this.setRendered();
                                 switch (this.type) {
-                                    case Vex.Flow.Barline.type.SINGLE:
+                                    case VF.Barline.type.SINGLE:
                                     this.drawVerticalBar(stave, this.x, false);
                                     break;
-                                    case Vex.Flow.Barline.type.DOUBLE:
+                                    case VF.Barline.type.DOUBLE:
                                     this.drawVerticalBar(stave, this.x, true);
                                     break;
-                                    case Vex.Flow.Barline.type.END:
+                                    case VF.Barline.type.END:
                                     this.drawVerticalEndBar(stave, this.x);
                                     break;
-                                    case Vex.Flow.Barline.type.REPEAT_BEGIN:
+                                    case VF.Barline.type.REPEAT_BEGIN:
                                     //removed the vertical line rendering that exists in VF codebase
                                     this.drawRepeatBar(stave, this.x, true);
                                     break;
-                                    case Vex.Flow.Barline.type.REPEAT_END:
+                                    case VF.Barline.type.REPEAT_END:
                                     this.drawRepeatBar(stave, this.x, false);
                                     break;
-                                    case Vex.Flow.Barline.type.REPEAT_BOTH:
+                                    case VF.Barline.type.REPEAT_BOTH:
                                     this.drawRepeatBar(stave, this.x, false);
                                     this.drawRepeatBar(stave, this.x, true);
                                     break;
@@ -353,29 +354,29 @@ export class VexFlowMeasure extends GraphicalMeasure {
                                 }
                             };
                         }
-                        this.stave.setBegBarType(Vex.Flow.Barline.type.REPEAT_BEGIN);
+                        this.stave.setBegBarType(VF.Barline.type.REPEAT_BEGIN);
                         break;
                     default:
-                        //this.stave.setBegBarType(Vex.Flow.Barline.type.NONE); // not necessary, it seems
+                        //this.stave.setBegBarType(VF.Barline.type.NONE); // not necessary, it seems
                         break;
                 }
                 break;
             case SystemLinePosition.MeasureEnd:
                 switch (lineType) {
                     case SystemLinesEnum.DotsBoldBoldDots:
-                        this.stave.setEndBarType(Vex.Flow.Barline.type.REPEAT_BOTH);
+                        this.stave.setEndBarType(VF.Barline.type.REPEAT_BOTH);
                         break;
                     case SystemLinesEnum.DotsThinBold:
-                        this.stave.setEndBarType(Vex.Flow.Barline.type.REPEAT_END);
+                        this.stave.setEndBarType(VF.Barline.type.REPEAT_END);
                         break;
                     case SystemLinesEnum.DoubleThin:
-                        this.stave.setEndBarType(Vex.Flow.Barline.type.DOUBLE);
+                        this.stave.setEndBarType(VF.Barline.type.DOUBLE);
                         break;
                     case SystemLinesEnum.ThinBold:
-                        this.stave.setEndBarType(Vex.Flow.Barline.type.END);
+                        this.stave.setEndBarType(VF.Barline.type.END);
                         break;
                     case SystemLinesEnum.None:
-                        this.stave.setEndBarType(Vex.Flow.Barline.type.NONE);
+                        this.stave.setEndBarType(VF.Barline.type.NONE);
                         break;
                     // TODO: Add support for additional Barline types when VexFlow supports them
                     default:
@@ -394,7 +395,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
      */
     public addMeasureNumber(): void {
         const text: string = this.MeasureNumber.toString();
-        const position: number = StavePositionEnum.ABOVE;  //Vex.Flow.StaveModifier.Position.ABOVE;
+        const position: number = StavePositionEnum.ABOVE;  //VF.StaveModifier.Position.ABOVE;
         const options: any = {
             justification: 1,
             shift_x: 0,
@@ -405,49 +406,49 @@ export class VexFlowMeasure extends GraphicalMeasure {
     }
 
     public addWordRepetition(repetitionInstruction: RepetitionInstruction): void {
-        let instruction: Vex.Flow.Repetition.type = undefined;
-        let position: any = Vex.Flow.StaveModifier.Position.END;
+        let instruction: VF.Repetition.type = undefined;
+        let position: any = VF.StaveModifier.Position.END;
         const xShift: number = this.beginInstructionsWidth;
         switch (repetitionInstruction.type) {
           case RepetitionInstructionEnum.Segno:
             // create Segno Symbol:
-            instruction = Vex.Flow.Repetition.type.SEGNO_LEFT;
-            position = Vex.Flow.StaveModifier.Position.LEFT;
+            instruction = VF.Repetition.type.SEGNO_LEFT;
+            position = VF.StaveModifier.Position.LEFT;
             break;
           case RepetitionInstructionEnum.Coda:
             // create Coda Symbol:
-            instruction = Vex.Flow.Repetition.type.CODA_LEFT;
-            position = Vex.Flow.StaveModifier.Position.LEFT;
+            instruction = VF.Repetition.type.CODA_LEFT;
+            position = VF.StaveModifier.Position.LEFT;
             break;
           case RepetitionInstructionEnum.DaCapo:
-            instruction = Vex.Flow.Repetition.type.DC;
+            instruction = VF.Repetition.type.DC;
             break;
           case RepetitionInstructionEnum.DalSegno:
-            instruction = Vex.Flow.Repetition.type.DS;
+            instruction = VF.Repetition.type.DS;
             break;
           case RepetitionInstructionEnum.Fine:
-            instruction = Vex.Flow.Repetition.type.FINE;
+            instruction = VF.Repetition.type.FINE;
             break;
           case RepetitionInstructionEnum.ToCoda:
-            instruction = (Vex.Flow.Repetition as any).type.TO_CODA;
+            instruction = (VF.Repetition as any).type.TO_CODA;
             break;
           case RepetitionInstructionEnum.DaCapoAlFine:
-            instruction = Vex.Flow.Repetition.type.DC_AL_FINE;
+            instruction = VF.Repetition.type.DC_AL_FINE;
             break;
           case RepetitionInstructionEnum.DaCapoAlCoda:
-            instruction = Vex.Flow.Repetition.type.DC_AL_CODA;
+            instruction = VF.Repetition.type.DC_AL_CODA;
             break;
           case RepetitionInstructionEnum.DalSegnoAlFine:
-            instruction = Vex.Flow.Repetition.type.DS_AL_FINE;
+            instruction = VF.Repetition.type.DS_AL_FINE;
             break;
           case RepetitionInstructionEnum.DalSegnoAlCoda:
-            instruction = Vex.Flow.Repetition.type.DS_AL_CODA;
+            instruction = VF.Repetition.type.DS_AL_CODA;
             break;
           default:
             break;
         }
         if (instruction) {
-            const repetition: Vex.Flow.Repetition = new Vex.Flow.Repetition(instruction, xShift, -this.rules.RepetitionSymbolsYOffset);
+            const repetition: VF.Repetition = new VF.Repetition(instruction, xShift, -this.rules.RepetitionSymbolsYOffset);
             this.stave.addModifier(repetition, position);
             return;
         }
@@ -456,23 +457,23 @@ export class VexFlowMeasure extends GraphicalMeasure {
     }
 
     protected addVolta(repetitionInstruction: RepetitionInstruction): void {
-        let voltaType: number = Vex.Flow.Volta.type.BEGIN;
+        let voltaType: number = VF.Volta.type.BEGIN;
         if (repetitionInstruction.type === RepetitionInstructionEnum.Ending) {
             switch (repetitionInstruction.alignment) {
                 case AlignmentType.Begin:
                     if (this.parentSourceMeasure.endsRepetitionEnding()) {
-                        voltaType = Vex.Flow.Volta.type.BEGIN_END;
+                        voltaType = VF.Volta.type.BEGIN_END;
                     } else {
-                        voltaType = Vex.Flow.Volta.type.BEGIN;
+                        voltaType = VF.Volta.type.BEGIN;
                     }
                     break;
                 case AlignmentType.End:
                     if (this.parentSourceMeasure.beginsRepetitionEnding()) {
-                        //voltaType = Vex.Flow.Volta.type.BEGIN_END;
+                        //voltaType = VF.Volta.type.BEGIN_END;
                         // don't add BEGIN_END volta a second time:
                         return;
                     } else {
-                        voltaType = Vex.Flow.Volta.type.END;
+                        voltaType = VF.Volta.type.END;
                     }
                     break;
                 default:
@@ -520,9 +521,9 @@ export class VexFlowMeasure extends GraphicalMeasure {
             }
 
             if (prevMeasure) {
-                const prevStaveModifiers: Vex.Flow.StaveModifier[] = prevMeasure.stave.getModifiers();
+                const prevStaveModifiers: VF.StaveModifier[] = prevMeasure.stave.getModifiers();
                 for (let i: number = 0; i < prevStaveModifiers.length; i++) {
-                    const nextStaveModifier: Vex.Flow.StaveModifier = prevStaveModifiers[i];
+                    const nextStaveModifier: VF.StaveModifier = prevStaveModifiers[i];
                     if (nextStaveModifier.hasOwnProperty("volta")) {
                         const prevskyBottomLineCalculator: SkyBottomLineCalculator = prevMeasure.ParentStaffLine.SkyBottomLineCalculator;
                         const prevStart: number = prevMeasure.PositionAndShape.AbsolutePosition.x + prevMeasure.PositionAndShape.BorderMarginLeft + 0.4;
@@ -556,7 +557,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
      */
     public setWidth(width: number): void {
         super.setWidth(width);
-        // Set the width of the Vex.Flow.Stave
+        // Set the width of the VF.Stave
         this.stave.setWidth(width * unitInPixels);
         // Force the width of the Begin Instructions
         //this.stave.setNoteStartX(this.beginInstructionsWidth * UnitInPixels);
@@ -672,7 +673,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
                     if (!gNote?.vfnote) { // can happen were invisible, then multi rest measure. TODO fix multi rest measure not removed
                         return;
                     }
-                    const vfnote: Vex.Flow.StemmableNote = gNote.vfnote[0];
+                    const vfnote: VF.StemmableNote = gNote.vfnote[0];
                     // if (note.isRest()) // TODO somehow there are never rest notes in ve.Notes
                     // TODO also, grace notes are not included here, need to be fixed as well. (and a few triple beamed notes in Bach Air)
                     let relPosY: number = 0;
@@ -793,7 +794,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
     }
 
     private createGhostGves(duration: Fraction): VexFlowVoiceEntry[] {
-        const vfghosts: Vex.Flow.GhostNote[] = VexFlowConverter.GhostNotes(duration);
+        const vfghosts: VF.GhostNote[] = VexFlowConverter.GhostNotes(duration);
         const ghostGves: VexFlowVoiceEntry[] = [];
         for (const vfghost of vfghosts) {
             const ghostGve: VexFlowVoiceEntry = new VexFlowVoiceEntry(undefined, undefined);
@@ -864,7 +865,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
         const beamedNotes: StaveNote[] = []; // already beamed notes, will be ignored by this.autoBeamNotes()
         for (const voiceID in this.beams) {
             if (this.beams.hasOwnProperty(voiceID)) {
-                let vfbeams: Vex.Flow.Beam[] = this.vfbeams[voiceID];
+                let vfbeams: VF.Beam[] = this.vfbeams[voiceID];
                 if (!vfbeams) {
                     vfbeams = this.vfbeams[voiceID] = [];
                 }
@@ -883,7 +884,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
                         continue;
                     }
 
-                    const notes: Vex.Flow.StaveNote[] = [];
+                    const notes: VF.StaveNote[] = [];
                     const psBeam: Beam = beam[0];
                     const voiceEntries: VexFlowVoiceEntry[] = beam[1];
 
@@ -903,7 +904,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
                     let beamColor: string;
                     const stemColors: string[] = [];
                     for (const entry of voiceEntries) {
-                        const note: Vex.Flow.StaveNote = ((<VexFlowVoiceEntry>entry).vfStaveNote as StaveNote);
+                        const note: VF.StaveNote = ((<VexFlowVoiceEntry>entry).vfStaveNote as StaveNote);
                         if (note) {
                           notes.push(note);
                           beamedNotes.push(note);
@@ -916,7 +917,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
                         }
                     }
                     if (notes.length > 1) {
-                        const vfBeam: Vex.Flow.Beam = new Vex.Flow.Beam(notes, autoStemBeam);
+                        const vfBeam: VF.Beam = new VF.Beam(notes, autoStemBeam);
                         if (isGraceBeam) {
                             // smaller beam, as in Vexflow.GraceNoteGroup.beamNotes()
                             (<any>vfBeam).render_options.beam_width = 3;
@@ -954,13 +955,16 @@ export class VexFlowMeasure extends GraphicalMeasure {
      * @param beamedNotes notes that will not be autobeamed (usually because they are already beamed)
      */
     private autoBeamNotes(beamedNotes: StemmableNote[]): void {
+        if (!this.rules.AutoBeamTabs && this.isTabMeasure) { // could also use an option tabBeams to disable beams there completely
+            return;
+        }
         let notesToAutoBeam: StemmableNote[] = [];
         let consecutiveBeamableNotes: StemmableNote[] = [];
         let currentTuplet: Tuplet;
         let tupletNotesToAutoBeam: StaveNote[] = [];
         this.autoTupletVfBeams = [];
         const separateAutoBeams: StemmableNote[][] = []; // a set of separate beams, each having a set of notes (StemmableNote[]).
-        this.autoVfBeams = []; // final Vex.Flow.Beams will be pushed/collected into this
+        this.autoVfBeams = []; // final VF.Beams will be pushed/collected into this
         let timeSignature: Fraction = this.parentSourceMeasure.ActiveTimeSignature;
         if (!timeSignature) { // this doesn't happen in OSMD, but maybe in a SourceGenerator
             timeSignature = this.parentSourceMeasure.Duration; // suboptimal, can be 1/1 in a 4/4 time signature
@@ -1034,7 +1038,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
                     } else {
                         if (currentTuplet !== noteTuplet) { // new tuplet, finish old one
                             if (tupletNotesToAutoBeam.length > 1) {
-                                const vfBeam: Vex.Flow.Beam = new Vex.Flow.Beam(tupletNotesToAutoBeam, true);
+                                const vfBeam: VF.Beam = new VF.Beam(tupletNotesToAutoBeam, true);
                                 if (this.rules.FlatBeams) {
                                     (<any>vfBeam).render_options.flat_beams = true;
                                     (<any>vfBeam).render_options.flat_beam_offset = this.rules.FlatBeamOffset;
@@ -1058,7 +1062,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
             }
         }
         if (tupletNotesToAutoBeam.length >= 2) {
-            const vfBeam: Vex.Flow.Beam = new Vex.Flow.Beam(tupletNotesToAutoBeam, true);
+            const vfBeam: VF.Beam = new VF.Beam(tupletNotesToAutoBeam, true);
             if (this.rules.FlatBeams) {
                 (<any>vfBeam).render_options.flat_beams = true;
                 (<any>vfBeam).render_options.flat_beam_offset = this.rules.FlatBeamOffset;
@@ -1081,15 +1085,15 @@ export class VexFlowMeasure extends GraphicalMeasure {
             maintain_stem_directions: autoBeamOptions.maintain_stem_directions,
         };
         if (autoBeamOptions.groups && autoBeamOptions.groups.length) {
-            const groups: Vex.Flow.Fraction[] = [];
+            const groups: VF.Fraction[] = [];
             for (const fraction of autoBeamOptions.groups) {
-                groups.push(new Vex.Flow.Fraction(fraction[0], fraction[1]));
+                groups.push(new VF.Fraction(fraction[0], fraction[1]));
             }
             generateBeamOptions.groups = groups;
         }
 
         for (const notesForSeparateAutoBeam of separateAutoBeams) {
-            const newBeams: Vex.Flow.Beam[] = Vex.Flow.Beam.generateBeams(notesForSeparateAutoBeam, generateBeamOptions);
+            const newBeams: VF.Beam[] = VF.Beam.generateBeams(notesForSeparateAutoBeam, generateBeamOptions);
             for (const vfBeam of newBeams) {
                 if (this.rules.FlatBeams) {
                     (<any>vfBeam).render_options.flat_beams = true;
@@ -1111,12 +1115,12 @@ export class VexFlowMeasure extends GraphicalMeasure {
         this.vftuplets = {};
         for (const voiceID in this.tuplets) {
             if (this.tuplets.hasOwnProperty(voiceID)) {
-                let vftuplets: Vex.Flow.Tuplet[] = this.vftuplets[voiceID];
+                let vftuplets: VF.Tuplet[] = this.vftuplets[voiceID];
                 if (!vftuplets) {
                     vftuplets = this.vftuplets[voiceID] = [];
                 }
                 for (const tupletBuilder of this.tuplets[voiceID]) {
-                    const tupletStaveNotes: Vex.Flow.StaveNote[] = [];
+                    const tupletStaveNotes: VF.StaveNote[] = [];
                     const tupletVoiceEntries: VexFlowVoiceEntry[] = tupletBuilder[1];
                     for (const tupletVoiceEntry of tupletVoiceEntries) {
                       tupletStaveNotes.push(((tupletVoiceEntry).vfStaveNote as StaveNote));
@@ -1127,11 +1131,11 @@ export class VexFlowMeasure extends GraphicalMeasure {
                       const bracketed: boolean = tuplet.Bracket ||
                         (tuplet.TupletLabelNumber === 3 && this.rules.TripletsBracketed) ||
                         (tuplet.TupletLabelNumber !== 3 && this.rules.TupletsBracketed);
-                      let location: number = Vex.Flow.Tuplet.LOCATION_TOP;
+                      let location: number = VF.Tuplet.LOCATION_TOP;
                       if (tuplet.tupletLabelNumberPlacement === PlacementEnum.Below) {
-                          location = Vex.Flow.Tuplet.LOCATION_BOTTOM;
+                          location = VF.Tuplet.LOCATION_BOTTOM;
                       }
-                      vftuplets.push(new Vex.Flow.Tuplet( tupletStaveNotes,
+                      vftuplets.push(new VF.Tuplet( tupletStaveNotes,
                                                           {
                                                             bracketed: bracketed,
                                                             location: location,
@@ -1181,7 +1185,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
                 //}
                 if (graceGVoiceEntriesBefore.length > 0) {
                     // add grace notes that came before this main note to a GraceNoteGroup in Vexflow, attached to the main note
-                    const graceNotes: Vex.Flow.GraceNote[] = [];
+                    const graceNotes: VF.GraceNote[] = [];
                     for (let i: number = 0; i < graceGVoiceEntriesBefore.length; i++) {
                         const gveGrace: VexFlowVoiceEntry = <VexFlowVoiceEntry>graceGVoiceEntriesBefore[i];
                         //if (gveGrace.notes[0].sourceNote.PrintObject) {
@@ -1195,7 +1199,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
                         gveGrace.vfStaveNote = vfStaveNote;
                         graceNotes.push(vfStaveNote);
                     }
-                    const graceNoteGroup: Vex.Flow.GraceNoteGroup = new Vex.Flow.GraceNoteGroup(graceNotes, graceSlur);
+                    const graceNoteGroup: VF.GraceNoteGroup = new VF.GraceNoteGroup(graceNotes, graceSlur);
                     ((gve as VexFlowVoiceEntry).vfStaveNote as StaveNote).addModifier(0, graceNoteGroup);
                     graceGVoiceEntriesBefore = [];
                 }
@@ -1232,11 +1236,11 @@ export class VexFlowMeasure extends GraphicalMeasure {
             //const isMainVoice: boolean = !(voice instanceof LinkedVoice);
 
             // add a vexFlow voice for this voice:
-            this.vfVoices[voice.VoiceId] = new Vex.Flow.Voice({
+            this.vfVoices[voice.VoiceId] = new VF.Voice({
                         beat_value: this.parentSourceMeasure.Duration.Denominator,
                         num_beats: this.parentSourceMeasure.Duration.Numerator,
-                        resolution: Vex.Flow.RESOLUTION,
-                    }).setMode(Vex.Flow.Voice.Mode.SOFT);
+                        resolution: VF.RESOLUTION,
+                    }).setMode(VF.Voice.Mode.SOFT);
 
             const restFilledEntries: GraphicalVoiceEntry[] = this.getRestFilledVexFlowStaveNotesPerVoice(voice);
                     // .sort((a,b) => a.)
@@ -1270,7 +1274,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
                     // The cast is necesary because...vexflow -> see types
                     if (vexFlowVoiceEntry.vfStaveNote.getCategory && vexFlowVoiceEntry.vfStaveNote.getCategory() === "stavenotes") {
                         // GhostNotes and other StemmableNotes don't have this function
-                        (vexFlowVoiceEntry.vfStaveNote as Vex.Flow.StaveNote).addModifier(0, clefModifier);
+                        (vexFlowVoiceEntry.vfStaveNote as VF.StaveNote).addModifier(0, clefModifier);
                     }
                 }
 
@@ -1305,8 +1309,8 @@ export class VexFlowMeasure extends GraphicalMeasure {
             // TODO right now our arpeggio object has all arpeggio notes from arpeggios across all voices.
             // see VoiceGenerator. Doesn't matter for Vexflow for now though
             if (voiceEntry.notes && voiceEntry.notes.length > 1) {
-                const type: Vex.Flow.Stroke.Type = VexFlowConverter.StrokeTypeFromArpeggioType(arpeggio.type);
-                const stroke: Vex.Flow.Stroke = new Vex.Flow.Stroke(type, {
+                const type: VF.Stroke.Type = VexFlowConverter.StrokeTypeFromArpeggioType(arpeggio.type);
+                const stroke: VF.Stroke = new VF.Stroke(type, {
                     all_voices: this.rules.ArpeggiosGoAcrossVoices
                     // default: false. This causes arpeggios to always go across all voices, which is often unwanted.
                     // also, this can cause infinite height of stroke, see #546
@@ -1338,10 +1342,10 @@ export class VexFlowMeasure extends GraphicalMeasure {
 
                     const vfStemDir: number = vfnote[0].getStemDirection();
                     switch (vfStemDir) {
-                        case (Vex.Flow.Stem.UP):
+                        case (VF.Stem.UP):
                             gVoiceEntry.parentVoiceEntry.StemDirection = StemDirectionType.Up;
                             break;
-                        case (Vex.Flow.Stem.DOWN):
+                        case (VF.Stem.DOWN):
                             gVoiceEntry.parentVoiceEntry.StemDirection = StemDirectionType.Down;
                             break;
                         default:
@@ -1419,37 +1423,37 @@ export class VexFlowMeasure extends GraphicalMeasure {
                 fingeringPosition = fingering.placement;
             }
             let offsetX: number = this.rules.FingeringOffsetX;
-            let modifierPosition: number; // Vex.Flow.Stavemodifier.Position
+            let modifierPosition: number; // VF.Stavemodifier.Position
             switch (fingeringPosition) {
                 default:
                 case PlacementEnum.Left:
-                    modifierPosition = Vex.Flow.StaveModifier.Position.LEFT;
+                    modifierPosition = VF.StaveModifier.Position.LEFT;
                     offsetX -= note.baseFingeringXOffset * unitInPixels;
                     break;
                 case PlacementEnum.Right:
-                    modifierPosition = Vex.Flow.StaveModifier.Position.RIGHT;
+                    modifierPosition = VF.StaveModifier.Position.RIGHT;
                     offsetX += note.baseFingeringXOffset * unitInPixels;
                     break;
                 case PlacementEnum.Above:
-                    modifierPosition = Vex.Flow.StaveModifier.Position.ABOVE;
+                    modifierPosition = VF.StaveModifier.Position.ABOVE;
                     break;
                 case PlacementEnum.Below:
-                    modifierPosition = Vex.Flow.StaveModifier.Position.BELOW;
+                    modifierPosition = VF.StaveModifier.Position.BELOW;
                     break;
                 case PlacementEnum.NotYetDefined: // automatic fingering placement, could be more complex/customizable
                     const sourceStaff: Staff = voiceEntry.parentStaffEntry.sourceStaffEntry.ParentStaff;
                     if (voiceEntry.notes.length > 1 || voiceEntry.parentStaffEntry.graphicalVoiceEntries.length > 1) {
-                        modifierPosition = Vex.Flow.StaveModifier.Position.LEFT;
+                        modifierPosition = VF.StaveModifier.Position.LEFT;
                     } else if (sourceStaff.idInMusicSheet === 0) {
-                        modifierPosition = Vex.Flow.StaveModifier.Position.ABOVE;
+                        modifierPosition = VF.StaveModifier.Position.ABOVE;
                         fingeringPosition = PlacementEnum.Above;
                     } else {
-                        modifierPosition = Vex.Flow.StaveModifier.Position.BELOW;
+                        modifierPosition = VF.StaveModifier.Position.BELOW;
                         fingeringPosition = PlacementEnum.Below;
                     }
             }
 
-            const fretFinger: Vex.Flow.FretHandFinger = new Vex.Flow.FretHandFinger(fingering.value);
+            const fretFinger: VF.FretHandFinger = new VF.FretHandFinger(fingering.value);
             fretFinger.setPosition(modifierPosition);
             fretFinger.setOffsetX(offsetX);
             if (fingeringPosition === PlacementEnum.Above || fingeringPosition === PlacementEnum.Below) {
@@ -1463,7 +1467,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
                     const shiftCount: number = numberOfFingerings * 2.5;
                     fretFinger.setOffsetY(offsetYSign * (ordering + shiftCount) * perFingeringShift);
                 } else if (!this.rules.FingeringInsideStafflines) { // use StringNumber for placement above/below stafflines
-                    const stringNumber: Vex.Flow.StringNumber = new Vex.Flow.StringNumber(fingering.value);
+                    const stringNumber: VF.StringNumber = new VF.StringNumber(fingering.value);
                     (<any>stringNumber).radius = 0; // hack to remove the circle around the number
                     stringNumber.setPosition(modifierPosition);
                     stringNumber.setOffsetY(offsetYSign * ordering * stringNumber.getWidth() * 2 / 3);
@@ -1513,7 +1517,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
                         // log.warn("stringNumber > 6 not supported"); // TODO do we need to support more?
                         // leave stringNumber as is, warning not really necessary
                 }
-                const vfStringNumber: Vex.Flow.StringNumber = new Vex.Flow.StringNumber(stringNumber);
+                const vfStringNumber: VF.StringNumber = new VF.StringNumber(stringNumber);
                 // Remove circle from string number. Not needed for
                 // disambiguation from fingerings since we use Roman
                 // Numerals for RenderStringNumbersClassical
@@ -1525,9 +1529,9 @@ export class VexFlowMeasure extends GraphicalMeasure {
                 // }
                 if (voiceEntry.notes.length > 1 || voiceEntry.parentStaffEntry.graphicalVoiceEntries.length > 1) {
                     vfStringNumber.setOffsetX(note.baseStringNumberXOffset * 13);
-                    vfStringNumber.setPosition(Vex.Flow.Modifier.Position.RIGHT);
+                    vfStringNumber.setPosition(VF.Modifier.Position.RIGHT);
                 } else {
-                    vfStringNumber.setPosition(Vex.Flow.Modifier.Position.ABOVE);
+                    vfStringNumber.setPosition(VF.Modifier.Position.ABOVE);
                 }
                 vfStringNumber.setOffsetY(offsetY);
 
@@ -1542,16 +1546,16 @@ export class VexFlowMeasure extends GraphicalMeasure {
      * @param lineType
      */
     public lineTo(top: VexFlowMeasure, lineType: any): void {
-        const connector: StaveConnector = new Vex.Flow.StaveConnector(top.getVFStave(), this.stave);
+        const connector: StaveConnector = new VF.StaveConnector(top.getVFStave(), this.stave);
         connector.setType(lineType);
         this.connectors.push(connector);
     }
 
     /**
      * Return the VexFlow Stave corresponding to this graphicalMeasure
-     * @returns {Vex.Flow.Stave}
+     * @returns {VF.Stave}
      */
-    public getVFStave(): Vex.Flow.Stave {
+    public getVFStave(): VF.Stave {
         return this.stave;
     }
 
@@ -1562,11 +1566,11 @@ export class VexFlowMeasure extends GraphicalMeasure {
     protected updateInstructionWidth(): void {
         let vfBeginInstructionsWidth: number = 0;
         let vfEndInstructionsWidth: number = 0;
-        const modifiers: Vex.Flow.StaveModifier[] = this.stave.getModifiers();
+        const modifiers: VF.StaveModifier[] = this.stave.getModifiers();
         for (const mod of modifiers) {
-            if (mod.getPosition() === StavePositionEnum.BEGIN) {  //Vex.Flow.StaveModifier.Position.BEGIN) {
+            if (mod.getPosition() === StavePositionEnum.BEGIN) {  //VF.StaveModifier.Position.BEGIN) {
                 vfBeginInstructionsWidth += mod.getWidth() + mod.getPadding(undefined);
-            } else if (mod.getPosition() === StavePositionEnum.END) { //Vex.Flow.StaveModifier.Position.END) {
+            } else if (mod.getPosition() === StavePositionEnum.END) { //VF.StaveModifier.Position.END) {
                 vfEndInstructionsWidth += mod.getWidth() + mod.getPadding(undefined);
             }
         }
@@ -1575,7 +1579,7 @@ export class VexFlowMeasure extends GraphicalMeasure {
         this.endInstructionsWidth = (vfEndInstructionsWidth ?? 0) / unitInPixels;
     }
 
-    public addStaveTie(stavetie: Vex.Flow.StaveTie, graphicalTie: GraphicalTie): void {
+    public addStaveTie(stavetie: VF.StaveTie, graphicalTie: GraphicalTie): void {
         this.vfTies.push(stavetie);
         graphicalTie.vfTie = stavetie;
     }

+ 5 - 4
src/MusicalScore/Graphical/VexFlow/VexFlowMultiRestMeasure.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 import {SourceMeasure} from "../../VoiceData/SourceMeasure";
 import {Staff} from "../../VoiceData/Staff";
 import {StaffLine} from "../StaffLine";
@@ -10,7 +11,7 @@ import {GraphicalVoiceEntry} from "../GraphicalVoiceEntry";
 import {Voice} from "../../VoiceData/Voice";
 import {VexFlowMeasure} from "./VexFlowMeasure";
 
-// type StemmableNote = Vex.Flow.StemmableNote;
+// type StemmableNote = VF.StemmableNote;
 
 /** A GraphicalMeasure drawing a multiple-rest measure in Vexflow.
  *  Mostly copied from VexFlowMeasure.
@@ -36,7 +37,7 @@ export class VexFlowMultiRestMeasure extends VexFlowMeasure {
 
         this.resetLayout();
 
-        this.multiRestElement = new Vex.Flow.MultiMeasureRest(sourceMeasure.multipleRestMeasures, {
+        this.multiRestElement = new VF.MultiMeasureRest(sourceMeasure.multipleRestMeasures, {
             // number_line: 3
         });
     }
@@ -155,9 +156,9 @@ export class VexFlowMultiRestMeasure extends VexFlowMeasure {
 
     /**
      * Return the VexFlow Stave corresponding to this graphicalMeasure
-     * @returns {Vex.Flow.Stave}
+     * @returns {VF.Stave}
      */
-    public getVFStave(): Vex.Flow.Stave {
+    public getVFStave(): VF.Stave {
         return this.stave;
     }
 }

+ 20 - 19
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetCalculator.ts

@@ -21,6 +21,7 @@ import { Tuplet } from "../../VoiceData/Tuplet";
 import { VexFlowMeasure } from "./VexFlowMeasure";
 import { VexFlowTextMeasurer } from "./VexFlowTextMeasurer";
 import Vex from "vexflow";
+import VF = Vex.Flow;
 import log from "loglevel";
 import { unitInPixels } from "./VexFlowMusicSheetDrawer";
 import { VexFlowGraphicalNote } from "./VexFlowGraphicalNote";
@@ -151,8 +152,8 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
     measures = visibleMeasures;
 
     // Format the voices
-    const allVoices: Vex.Flow.Voice[] = [];
-    const formatter: Vex.Flow.Formatter = new Vex.Flow.Formatter({
+    const allVoices: VF.Voice[] = [];
+    const formatter: VF.Formatter = new VF.Formatter({
       // maxIterations: 2,
       softmaxFactor: this.rules.SoftmaxFactorVexFlow // this setting is only applied in Vexflow 3.x. also this needs @types/vexflow ^3.0.0
     });
@@ -172,8 +173,8 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
         maxStaffEntries = Math.max(measure.staffEntries.length, maxStaffEntries);
         maxStaffEntriesPlusAccidentals = Math.max(measure.staffEntries.length + measureAccidentals, maxStaffEntriesPlusAccidentals);
       }
-      const mvoices: { [voiceID: number]: Vex.Flow.Voice } = (measure as VexFlowMeasure).vfVoices;
-      const voices: Vex.Flow.Voice[] = [];
+      const mvoices: { [voiceID: number]: VF.Voice } = (measure as VexFlowMeasure).vfVoices;
+      const voices: VF.Voice[] = [];
       for (const voiceID in mvoices) {
         if (mvoices.hasOwnProperty(voiceID)) {
           voices.push(mvoices[voiceID]);
@@ -304,8 +305,8 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
       if (!measure) {
         continue;
       }
-      const mvoices: { [voiceID: number]: Vex.Flow.Voice } = (measure as VexFlowMeasure).vfVoices;
-      const voices: Vex.Flow.Voice[] = [];
+      const mvoices: { [voiceID: number]: VF.Voice } = (measure as VexFlowMeasure).vfVoices;
+      const voices: VF.Voice[] = [];
       for (const voiceID in mvoices) {
         if (mvoices.hasOwnProperty(voiceID)) {
           voices.push(mvoices[voiceID]);
@@ -604,14 +605,14 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
     const startNote: VexFlowGraphicalNote = (tie.StartNote as VexFlowGraphicalNote);
     const endNote: VexFlowGraphicalNote = (tie.EndNote as VexFlowGraphicalNote);
 
-    let vfStartNote: Vex.Flow.StemmableNote  = undefined;
+    let vfStartNote: VF.StemmableNote  = undefined;
     let startNoteIndexInTie: number = 0;
     if (startNote && startNote.vfnote && startNote.vfnote.length >= 2) {
       vfStartNote = startNote.vfnote[0];
       startNoteIndexInTie = startNote.vfnote[1];
     }
 
-    let vfEndNote: Vex.Flow.StemmableNote  = undefined;
+    let vfEndNote: VF.StemmableNote  = undefined;
     let endNoteIndexInTie: number = 0;
     if (endNote && endNote.vfnote && endNote.vfnote.length >= 2) {
       vfEndNote = endNote.vfnote[0];
@@ -621,7 +622,7 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
     if (tieIsAtSystemBreak) {
       // split tie into two ties:
       if (vfStartNote) { // first_note or last_note must be not null in Vexflow
-        const vfTie1: Vex.Flow.StaveTie = new Vex.Flow.StaveTie({
+        const vfTie1: VF.StaveTie = new VF.StaveTie({
           first_indices: [startNoteIndexInTie],
           first_note: vfStartNote
         });
@@ -630,7 +631,7 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
       }
 
       if (vfEndNote) {
-        const vfTie2: Vex.Flow.StaveTie = new Vex.Flow.StaveTie({
+        const vfTie2: VF.StaveTie = new VF.StaveTie({
           last_indices: [endNoteIndexInTie],
           last_note: vfEndNote
         });
@@ -650,7 +651,7 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
             if (startTieNote.FretNumber > endTieNote.FretNumber) {
               slideDirection = -1;
             }
-            vfTie = new Vex.Flow.TabSlide(
+            vfTie = new VF.TabSlide(
               {
                 first_indices: [startNoteIndexInTie],
                 first_note: vfStartNote,
@@ -660,7 +661,7 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
               slideDirection
             );
           } else {
-            vfTie = new Vex.Flow.TabTie(
+            vfTie = new VF.TabTie(
               {
                 first_indices: [startNoteIndexInTie],
                 first_note: vfStartNote,
@@ -672,7 +673,7 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
           }
 
         } else { // not Tab (guitar), normal StaveTie
-          vfTie = new Vex.Flow.StaveTie({
+          vfTie = new VF.StaveTie({
             first_indices: [startNoteIndexInTie],
             first_note: vfStartNote,
             last_indices: [endNoteIndexInTie],
@@ -757,8 +758,8 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
     const measureNumber: number = Math.max(metronomeExpression.ParentMultiTempoExpression.SourceMeasureParent.MeasureNumber - 1, 0);
     const staffNumber: number = Math.max(metronomeExpression.StaffNumber - 1, 0);
     const firstMetronomeMark: boolean = measureNumber === 0 && staffNumber === 0;
-    const vfStave: Vex.Flow.Stave = (this.graphicalMusicSheet.MeasureList[measureNumber][staffNumber] as VexFlowMeasure).getVFStave();
-    //vfStave.addModifier(new Vex.Flow.StaveTempo( // needs Vexflow PR
+    const vfStave: VF.Stave = (this.graphicalMusicSheet.MeasureList[measureNumber][staffNumber] as VexFlowMeasure).getVFStave();
+    //vfStave.addModifier(new VF.StaveTempo( // needs Vexflow PR
     let vexflowDuration: string = "q";
     if (metronomeExpression.beatUnit) {
       const duration: Fraction = NoteTypeHandler.getNoteDurationFromType(metronomeExpression.beatUnit);
@@ -813,7 +814,7 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
     const firstMeasureNumber: number = this.graphicalMusicSheet.MeasureList[0][0].MeasureNumber; // 0 for pickup, 1 otherwise
     const measureNumber: number = Math.max(measure.MeasureNumber - firstMeasureNumber, 0);
     const staffNumber: number = 0;
-    const vfStave: Vex.Flow.Stave = (this.graphicalMusicSheet.MeasureList[measureNumber][staffNumber] as VexFlowMeasure)?.getVFStave();
+    const vfStave: VF.Stave = (this.graphicalMusicSheet.MeasureList[measureNumber][staffNumber] as VexFlowMeasure)?.getVFStave();
     if (!vfStave) { // potentially multi measure rest
       return;
     }
@@ -822,7 +823,7 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
     if (measure.IsSystemStartMeasure) {
       xOffset += this.rules.RehearsalMarkXOffsetSystemStartMeasure;
     }
-    // const section: Vex.Flow.StaveSection = new Vex.Flow.StaveSection(rehearsalExpression.label, vfStave.getX(), yOffset);
+    // const section: VF.StaveSection = new VF.StaveSection(rehearsalExpression.label, vfStave.getX(), yOffset);
     // (vfStave as any).modifiers.push(section);
     const fontSize: number = this.rules.RehearsalMarkFontSize;
     (vfStave as any).setSection(rehearsalExpression.label, yOffset, xOffset, fontSize); // fontSize is an extra argument from VexFlowPatch
@@ -1513,10 +1514,10 @@ export class VexFlowMusicSheetCalculator extends MusicSheetCalculator {
     const startX: number = startStaffEntry.PositionAndShape.AbsolutePosition.x - startXOffset;
     const stopX: number = endStaffEntry.PositionAndShape.AbsolutePosition.x + endXOffset;
     vfOctaveShift.PositionAndShape.Size.width = startX - stopX;
-    const textBracket: Vex.Flow.TextBracket = vfOctaveShift.getTextBracket();
+    const textBracket: VF.TextBracket = vfOctaveShift.getTextBracket();
     const fontSize: number = (textBracket as any).font.size / 10;
 
-    if ((<any>textBracket).position === Vex.Flow.TextBracket.Positions.TOP) {
+    if ((<any>textBracket).position === VF.TextBracket.Positions.TOP) {
       const headroom: number = Math.ceil(parentStaffline.SkyBottomLineCalculator.getSkyLineMinInRange(startX, stopX));
       if (headroom === Infinity) { // will cause Vexflow error
         return;

+ 2 - 1
src/MusicalScore/Graphical/VexFlow/VexFlowMusicSheetDrawer.ts

@@ -1,5 +1,6 @@
 import Vex from "vexflow";
 import { LabelRenderSpecs, MusicSheetDrawer } from "../MusicSheetDrawer";
+import VF = Vex.Flow;
 import { RectangleF2D } from "../../../Common/DataObjects/RectangleF2D";
 import { VexFlowMeasure } from "./VexFlowMeasure";
 import { PointF2D } from "../../../Common/DataObjects/PointF2D";
@@ -367,7 +368,7 @@ export class VexFlowMusicSheetDrawer extends MusicSheetDrawer {
             if (graphicalOctaveShift) {
                 const vexFlowOctaveShift: VexFlowOctaveShift = graphicalOctaveShift as VexFlowOctaveShift;
                 const ctx: Vex.IRenderContext = this.backend.getContext();
-                const textBracket: Vex.Flow.TextBracket = vexFlowOctaveShift.getTextBracket();
+                const textBracket: VF.TextBracket = vexFlowOctaveShift.getTextBracket();
                 textBracket.setContext(ctx);
                 try {
                     textBracket.draw();

+ 10 - 9
src/MusicalScore/Graphical/VexFlow/VexFlowOctaveShift.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 import { GraphicalOctaveShift } from "../GraphicalOctaveShift";
 import { OctaveShift, OctaveEnum } from "../../VoiceData/Expressions/ContinuousExpressions/OctaveShift";
 import { BoundingBox } from "../BoundingBox";
@@ -12,11 +13,11 @@ import log from "loglevel";
 export class VexFlowOctaveShift extends GraphicalOctaveShift {
 
     /** Defines the note where the octave shift starts */
-    public startNote: Vex.Flow.StemmableNote;
+    public startNote: VF.StemmableNote;
     /** Defines the note where the octave shift ends */
-    public endNote: Vex.Flow.StemmableNote;
+    public endNote: VF.StemmableNote;
     /** Top or bottom of the staffline */
-    private position: Vex.Flow.TextBracket.Positions;
+    private position: VF.TextBracket.Positions;
     /** Supscript is a smaller text after the regular text (e.g. va after 8) */
     private supscript: string;
     /** Main text element */
@@ -31,22 +32,22 @@ export class VexFlowOctaveShift extends GraphicalOctaveShift {
         super(octaveShift, parent);
         switch (octaveShift.Type) {
             case OctaveEnum.VA8:
-                this.position = Vex.Flow.TextBracket.Positions.TOP;
+                this.position = VF.TextBracket.Positions.TOP;
                 this.supscript = "va";
                 this.text = "8";
                 break;
             case OctaveEnum.MA15:
-                this.position = Vex.Flow.TextBracket.Positions.TOP;
+                this.position = VF.TextBracket.Positions.TOP;
                 this.supscript = "ma";
                 this.text = "15";
                 break;
             case OctaveEnum.VB8:
-                this.position = Vex.Flow.TextBracket.Positions.BOTTOM;
+                this.position = VF.TextBracket.Positions.BOTTOM;
                 this.supscript = "vb";
                 this.text = "8";
                 break;
             case OctaveEnum.MB15:
-                this.position = Vex.Flow.TextBracket.Positions.BOTTOM;
+                this.position = VF.TextBracket.Positions.BOTTOM;
                 this.supscript = "mb";
                 this.text = "15";
                 break;
@@ -90,8 +91,8 @@ export class VexFlowOctaveShift extends GraphicalOctaveShift {
     /**
      * Get the actual vexflow text bracket used for drawing
      */
-    public getTextBracket(): Vex.Flow.TextBracket {
-        return new Vex.Flow.TextBracket({
+    public getTextBracket(): VF.TextBracket {
+        return new VF.TextBracket({
             position: this.position,
             start: this.startNote,
             stop: this.endNote,

+ 6 - 5
src/MusicalScore/Graphical/VexFlow/VexFlowSlur.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 import { Slur } from "../../VoiceData/Expressions/ContinuousExpressions/Slur";
 
 export interface ICurveOptions {
@@ -36,10 +37,10 @@ export class VexFlowSlur {
 
     private parentSlur: Slur;
 
-    public vfStartNote: Vex.Flow.StemmableNote = undefined;
-    public vfEndNote: Vex.Flow.StemmableNote = undefined;
+    public vfStartNote: VF.StemmableNote = undefined;
+    public vfEndNote: VF.StemmableNote = undefined;
 
-    public vfCurve: Vex.Flow.Curve;
+    public vfCurve: VF.Curve;
 
     public curve_Options(): ICurveOptions {
         return {
@@ -56,14 +57,14 @@ export class VexFlowSlur {
 
     // public createVexFlowCurve(): void {
     //     if (this.voiceentrySlurStart || this.voiceentrySlurEnd) {
-    //         this.vfCurve = new Vex.Flow.Curve( (this.voiceentrySlurStart as VexFlowVoiceEntry).vfStaveNote,
+    //         this.vfCurve = new VF.Curve( (this.voiceentrySlurStart as VexFlowVoiceEntry).vfStaveNote,
     //                                            (this.voiceentrySlurEnd as VexFlowVoiceEntry).vfStaveNote,
     //                                            this.curve_Options()
     //                                         );
     //     }
     // }
     public createVexFlowCurve(): void {
-            this.vfCurve = new Vex.Flow.Curve( this.vfStartNote,
+            this.vfCurve = new VF.Curve( this.vfStartNote,
                                                this.vfEndNote,
                                                undefined//this.curve_Options()
                                             );

+ 4 - 3
src/MusicalScore/Graphical/VexFlow/VexFlowStaffEntry.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 import { GraphicalNote } from "../GraphicalNote";
 import { GraphicalStaffEntry } from "../GraphicalStaffEntry";
 import { VexFlowMeasure } from "./VexFlowMeasure";
@@ -14,8 +15,8 @@ export class VexFlowStaffEntry extends GraphicalStaffEntry {
     }
 
     // if there is a in-measure clef given before this staffEntry,
-    // it will be converted to a Vex.Flow.ClefNote and assigned to this variable:
-    public vfClefBefore: Vex.Flow.ClefNote;
+    // it will be converted to a VF.ClefNote and assigned to this variable:
+    public vfClefBefore: VF.ClefNote;
 
     /**
      * Calculates the staff entry positions from the VexFlow stave information and the tickabels inside the staff.
@@ -23,7 +24,7 @@ export class VexFlowStaffEntry extends GraphicalStaffEntry {
      * It is also needed to be done after formatting!
      */
     public calculateXPosition(): void {
-        const stave: Vex.Flow.Stave = (this.parentMeasure as VexFlowMeasure).getVFStave();
+        const stave: VF.Stave = (this.parentMeasure as VexFlowMeasure).getVFStave();
 
         // sets the vexflow x positions back into the bounding boxes of the staff entries in the osmd object model.
         // The positions are needed for cursor placement and mouse/tap interactions

+ 7 - 6
src/MusicalScore/Graphical/VexFlow/VexFlowTabMeasure.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 import { Staff } from "../../VoiceData/Staff";
 import { SourceMeasure } from "../../VoiceData/SourceMeasure";
 import { VexFlowMeasure } from "./VexFlowMeasure";
@@ -27,7 +28,7 @@ export class VexFlowTabMeasure extends VexFlowMeasure {
         //this.beginInstructionsWidth = 20 / UnitInPixels;
         //this.endInstructionsWidth = 20 / UnitInPixels;
         const stafflineCount: number = this.ParentStaff.StafflineCount ?? 6; // if undefined, 6 by default (same as Vexflow default)
-        this.stave = new Vex.Flow.TabStave(0, 0, 0, {
+        this.stave = new VF.TabStave(0, 0, 0, {
             space_above_staff_ln: 0,
             space_below_staff_ln: 0,
             num_lines: stafflineCount
@@ -62,11 +63,11 @@ export class VexFlowTabMeasure extends VexFlowMeasure {
             }
 
             // add a vexFlow voice for this voice:
-            this.vfVoices[voice.VoiceId] = new Vex.Flow.Voice({
+            this.vfVoices[voice.VoiceId] = new VF.Voice({
                         beat_value: this.parentSourceMeasure.Duration.Denominator,
                         num_beats: this.parentSourceMeasure.Duration.Numerator,
-                        resolution: Vex.Flow.RESOLUTION,
-                    }).setMode(Vex.Flow.Voice.Mode.SOFT);
+                        resolution: VF.RESOLUTION,
+                    }).setMode(VF.Voice.Mode.SOFT);
 
             const restFilledEntries: GraphicalVoiceEntry[] =  this.getRestFilledVexFlowStaveNotesPerVoice(voice);
             // create vex flow voices and add tickables to it:
@@ -95,8 +96,8 @@ export class VexFlowTabMeasure extends VexFlowMeasure {
                     // TODO right now our arpeggio object has all arpeggio notes from arpeggios across all voices.
                     // see VoiceGenerator. Doesn't matter for Vexflow for now though
                     if (voiceEntry.notes && voiceEntry.notes.length > 1) {
-                        const type: Vex.Flow.Stroke.Type = VexFlowConverter.StrokeTypeFromArpeggioType(arpeggio.type);
-                        const stroke: Vex.Flow.Stroke = new Vex.Flow.Stroke(type, {
+                        const type: VF.Stroke.Type = VexFlowConverter.StrokeTypeFromArpeggioType(arpeggio.type);
+                        const stroke: VF.Stroke = new VF.Stroke(type, {
                             all_voices: this.rules.ArpeggiosGoAcrossVoices
                             // default: false. This causes arpeggios to always go across all voices, which is often unwanted.
                             // also, this can cause infinite height of stroke, see #546

+ 4 - 3
src/MusicalScore/Graphical/VexFlow/VexFlowVoiceEntry.ts

@@ -1,4 +1,5 @@
 import Vex from "vexflow";
+import VF = Vex.Flow;
 import { VoiceEntry } from "../../VoiceData/VoiceEntry";
 import { GraphicalVoiceEntry } from "../GraphicalVoiceEntry";
 import { GraphicalStaffEntry } from "../GraphicalStaffEntry";
@@ -9,7 +10,7 @@ import { ColoringModes } from "./../DrawingParameters";
 import { GraphicalNote } from "../GraphicalNote";
 
 export class VexFlowVoiceEntry extends GraphicalVoiceEntry {
-    private mVexFlowStaveNote: Vex.Flow.StemmableNote;
+    private mVexFlowStaveNote: VF.StemmableNote;
 
     constructor(parentVoiceEntry: VoiceEntry, parentStaffEntry: GraphicalStaffEntry) {
         super(parentVoiceEntry, parentStaffEntry);
@@ -30,11 +31,11 @@ export class VexFlowVoiceEntry extends GraphicalVoiceEntry {
         this.PositionAndShape.BorderRight = (boundingBox.w - modifierWidth) / unitInPixels; // Right of x origin is the note
     }
 
-    public set vfStaveNote(value: Vex.Flow.StemmableNote) {
+    public set vfStaveNote(value: VF.StemmableNote) {
         this.mVexFlowStaveNote = value;
     }
 
-    public get vfStaveNote(): Vex.Flow.StemmableNote {
+    public get vfStaveNote(): VF.StemmableNote {
         return this.mVexFlowStaveNote;
     }
 

+ 9 - 1
src/MusicalScore/ScoreIO/InstrumentReader.ts

@@ -299,6 +299,7 @@ export class InstrumentReader {
 
           // check Tremolo
           let tremoloStrokes: number = 0;
+          let vibratoStrokes: boolean = false;
           if (notationsNode) {
             const ornamentsNode: IXmlElement = notationsNode.element("ornaments");
             if (ornamentsNode) {
@@ -313,6 +314,13 @@ export class InstrumentReader {
                 }
                 // TODO implement type "start". Vexflow doesn't have tremolo beams yet though (shorter than normal beams)
               }
+              const vibratoNode: IXmlElement = ornamentsNode.element("wavy-line");
+              if (vibratoNode !== undefined) {
+                const vibratoType: Attr = vibratoNode.attribute("type");
+                if (vibratoType && vibratoType.value === "start") {
+                  vibratoStrokes = true;
+                }
+              }
               const wavyLineNodes: IXmlElement[] = ornamentsNode.elements("wavy-line");
               if (wavyLineNodes !== undefined) {
                 /* As mentioned elsewhere, the wavy-line is technically an ornament element, but is specified and behaves
@@ -412,7 +420,7 @@ export class InstrumentReader {
             this.currentStaffEntry, this.currentMeasure,
             measureStartAbsoluteTimestamp,
             this.maxTieNoteFraction, isChord, octavePlusOne,
-            printObject, isCueNote, isGraceNote, stemDirectionXml, tremoloStrokes, stemColorXml, noteheadColorXml,
+            printObject, isCueNote, isGraceNote, stemDirectionXml, tremoloStrokes, stemColorXml, noteheadColorXml, vibratoStrokes,
             dots
           );
 

+ 4 - 4
src/MusicalScore/ScoreIO/VoiceGenerator.ts

@@ -154,7 +154,7 @@ export class VoiceGenerator {
               parentStaffEntry: SourceStaffEntry, parentMeasure: SourceMeasure,
               measureStartAbsoluteTimestamp: Fraction, maxTieNoteFraction: Fraction, chord: boolean, octavePlusOne: boolean,
               printObject: boolean, isCueNote: boolean, isGraceNote: boolean, stemDirectionXml: StemDirectionType, tremoloStrokes: number,
-              stemColorXml: string, noteheadColorXml: string,
+              stemColorXml: string, noteheadColorXml: string, vibratoStrokes: boolean,
               dotsXml: number): Note {
     this.currentStaffEntry = parentStaffEntry;
     this.currentMeasure = parentMeasure;
@@ -164,7 +164,7 @@ export class VoiceGenerator {
       this.currentNote = restNote
         ? this.addRestNote(noteNode.element("rest"), noteDuration, noteTypeXml, normalNotes, printObject, isCueNote, noteheadColorXml)
         : this.addSingleNote(noteNode, noteDuration, noteTypeXml, typeDuration, normalNotes, chord, octavePlusOne,
-                             printObject, isCueNote, isGraceNote, stemDirectionXml, tremoloStrokes, stemColorXml, noteheadColorXml);
+                             printObject, isCueNote, isGraceNote, stemDirectionXml, tremoloStrokes, stemColorXml, noteheadColorXml, vibratoStrokes);
       this.currentNote.DotsXml = dotsXml;
       // read lyrics
       const lyricElements: IXmlElement[] = noteNode.elements("lyric");
@@ -369,7 +369,7 @@ export class VoiceGenerator {
   private addSingleNote(node: IXmlElement, noteDuration: Fraction, noteTypeXml: NoteType, typeDuration: Fraction,
                         normalNotes: number, chord: boolean, octavePlusOne: boolean,
                         printObject: boolean, isCueNote: boolean, isGraceNote: boolean, stemDirectionXml: StemDirectionType, tremoloStrokes: number,
-                        stemColorXml: string, noteheadColorXml: string): Note {
+                        stemColorXml: string, noteheadColorXml: string, vibratoStrokes: boolean): Note {
     //log.debug("addSingleNote called");
     let noteAlter: number = 0;
     let accidentalValue: string;
@@ -523,7 +523,7 @@ export class VoiceGenerator {
     } else {
       // create TabNote
       note = new TabNote(this.currentVoiceEntry, this.currentStaffEntry, noteLength, pitch, this.currentMeasure,
-                         stringNumber, fretNumber, bends);
+                         stringNumber, fretNumber, bends, vibratoStrokes);
     }
 
     this.addNoteInfo(note, noteTypeXml, printObject, isCueNote, normalNotes,

+ 1 - 1
src/MusicalScore/VoiceData/Arpeggio.ts

@@ -18,7 +18,7 @@ export class Arpeggio {
     }
 }
 
-/** Corresponds to Vex.Flow.Stroke.Type for now. But we don't want VexFlow as a dependency here. */
+/** Corresponds to VF.Stroke.Type for now. But we don't want VexFlow as a dependency here. */
 export enum ArpeggioType {
     BRUSH_DOWN = 1,
     BRUSH_UP,

+ 8 - 1
src/MusicalScore/VoiceData/TabNote.ts

@@ -7,16 +7,19 @@ import { SourceMeasure } from "./SourceMeasure";
 
 export class TabNote extends Note {
     constructor(voiceEntry: VoiceEntry, parentStaffEntry: SourceStaffEntry, length: Fraction, pitch: Pitch, sourceMeasure: SourceMeasure,
-                stringNumber: number, fretNumber: number, bendArray: { bendalter: number, direction: string }[]) {
+                stringNumber: number, fretNumber: number, bendArray: { bendalter: number, direction: string }[],
+                vibratoStroke: boolean) {
         super(voiceEntry, parentStaffEntry, length, pitch, sourceMeasure);
         this.stringNumberTab = stringNumber;
         this.fretNumber = fretNumber;
         this.bendArray = bendArray;
+        this.vibratoStroke = vibratoStroke;
     }
 
     private stringNumberTab: number; // there can also be string numbers for e.g. violin in treble clef.
     private fretNumber: number;
     private bendArray: { bendalter: number, direction: string }[];
+    private vibratoStroke: boolean;
 
     /** Returns the string number the note should be played on. Note there can also be violin string numbers in treble clef. */
     public get StringNumberTab(): number {
@@ -30,4 +33,8 @@ export class TabNote extends Note {
     public get BendArray(): { bendalter: number, direction: string }[] {
         return this.bendArray;
     }
+
+    public get VibratoStroke(): boolean {
+        return this.vibratoStroke;
+    }
 }

+ 20 - 16
src/VexFlowPatch/readme.txt

@@ -11,13 +11,13 @@ Each .js has comments like "// VexFlowPatch: [explanation]" to indicate what was
 (a diff can be created from the base vexflow version)
 
 beam.js (custom addition):
-add flat_beams, flat_beam_offset, flat_beam_offset_per_beam render_option
-able to add svg node id+class to beam
+add flat_beams, flat_beam_offset, flat_beam_offset_per_beam render_option (fixed in vexflow 4)
+able to add svg node id+class to beam (not yet in vexflow 4)
 
-clef.js (custom addition):
+clef.js (merged vexflow 4):
 open group to get SVG group+class for clef
 
-keysignature.js (custom addition):
+keysignature.js (merged vexflow 4):
 open group to get SVG group+class for key signature
 
 pedalmarking.js (custom addition):
@@ -25,48 +25,49 @@ Add rendering options for pedals that break across systems.
 clef.js (custom addition):
 open group to get SVG group+class for clef
 
-stave.js (custom addition):
-prevent a bug where a modifier width is NaN, leading to a VexFlow error
+stave.js (merged/fixed vexflow 4):
+prevent a bug where a modifier width is NaN, leading to a VexFlow error (fixed vexflow 4)
 stave.setSection(section, y, xOffset = 0, fontSize = 12):
-add xOffset, fontSize arguments (see stavesection.js)
+add xOffset, fontSize arguments (see stavesection.js) (merged vexflow 4.x)
 
 stavenote.js (custom addition):
 Fix stem/flag formatting. Instead of shifting notes by default, update the stem/flag rendering to render different voices aligned.
   Only offset if a note is the same voice, same note.
-able to add svg node id+class to stem
+  (not yet in vexflow 4, PR 1263 open)
+able to add svg node id+class to stem (merged vexflow 4.x)
 
-staverepetition.js (custom addition):
+staverepetition.js (fixed vexflow 4):
 add TO_CODA enum to type() and draw()
 fix x-positioning for TO_CODA and DS_AL_CODA in drawSymbolText()
 fix y-shift
 
-stavesection.js (custom addition):
+stavesection.js (half-fixed vexflow 4.x, collision, box not removable):
 stavesection.draw():
 adjust rectangle positioning, make height depend on text height
 
-stavetie.js (custom addition):
+stavetie.js (merged vexflow 4.x):
 context opens group for stavetie, can get stavetie SVG element via getAttribute("el")
 
 stavevolta.js (merged Vexflow 3.x):
 Fix the length of voltas for first measures in a system
 (whose lengths were wrongly extended by the width of the clef, key signature, etc. (beginInstructions) in Vexflow 1.2.93)
 
-stem.js (custom addition):
+stem.js (fixed vexflow 4 (or earlier)):
 able to give an id+class to the stem node in SVG
 
-stemmablenote.js (custom addition):
+stemmablenote.js (custom addition, see stavenote.js):
 Add manual flag rendering variable so we can choose not to render flags if notes are sharing a stem.
 
-svgcontext.js (custom addition):
+svgcontext.js (custom addition, probably not necessary for vexflow 4):
 able to add extra attributes (like svg node id) to a stroke (e.g. stem)
 
 tabnote.js (merged Vexflow 3.x):
 Add a context group for each tabnote, so that it can be found in the SVG DOM ("vf-tabnote")
 
-tremolo.js (custom addition):
+tremolo.js (fixed vexflow 4):
 Add extra_stroke_scale, y_spacing_scale
 
-timesignature.js (custom addition):
+timesignature.js (fixed vexflow 4):
 open group to get SVG group+class for key signature
 
 Currently, we are using Vexflow 1.2.93, because of some formatter advantages
@@ -74,3 +75,6 @@ compared to Vexflow 3.x versions, see this issue:
 https://github.com/opensheetmusicdisplay/opensheetmusicdisplay/issues/915
 
 Because of that, we need to patch in a few fixes that came after 1.2.93, as well as making custom additions for our needs.
+
+For vexflow 4 state of these changes, also see PR 1139 (vexflow 4 -> develop):
+https://github.com/opensheetmusicdisplay/opensheetmusicdisplay/pull/1139

+ 6 - 6
src/VexFlowPatch/src/beam.js

@@ -806,7 +806,9 @@ export class Beam extends Element {
   drawStems() {
     this.notes.forEach(note => {
       if (note.getStem()) {
+        this.context.openGroup('stem', note.getAttribute('id') + '-stem');
         note.getStem().setContext(this.context).draw();
+        this.context.closeGroup();
       }
     }, this);
   }
@@ -844,18 +846,16 @@ export class Beam extends Element {
         const lastBeamX = beam_line.end;
         const lastBeamY = this.getSlopeY(lastBeamX, firstStemX, beamY, this.slope);
 
+        const noteSVGId = startNoteId;
+        this.context.openGroup('beam', `${noteSVGId}-beam${beamNumber}`);
         this.context.beginPath();
         this.context.moveTo(startBeamX, startBeamY);
         this.context.lineTo(startBeamX, startBeamY + beamThickness);
         this.context.lineTo(lastBeamX + 1, lastBeamY + beamThickness);
         this.context.lineTo(lastBeamX + 1, lastBeamY);
         this.context.closePath();
-        if (this.context.svg) {
-          const noteSVGId = Vex.Prefix(startNoteId);
-          this.context.fill({class: Vex.Prefix("beam"), id: `${noteSVGId}-beam${beamNumber}`});
-        } else {
-          this.context.fill();
-        }
+        this.context.fill();
+        this.context.closeGroup();
       }
 
       beamY += beamThickness * 1.5;