Kaynağa Gözat

Merge pull request #4 from opensheetmusicdisplay/feature/npmPackage

Prepare for first public npm package
Andrea Condoluci 9 yıl önce
ebeveyn
işleme
1ae89f4a66
100 değiştirilmiş dosya ile 9734 ekleme ve 7 silme
  1. 0 3
      .gitignore
  2. 0 2
      .travis.yml
  3. 4 0
      AUTHORS
  4. 1 1
      Gruntfile.js
  5. 1 1
      LICENSE
  6. 10 0
      dist/src/Common/DataObjects/MusicSheetErrors.d.ts
  7. 25 0
      dist/src/Common/DataObjects/MusicSheetErrors.js
  8. 8 0
      dist/src/Common/DataObjects/PointF2D.d.ts
  9. 26 0
      dist/src/Common/DataObjects/PointF2D.js
  10. 12 0
      dist/src/Common/DataObjects/RectangleF2D.d.ts
  11. 34 0
      dist/src/Common/DataObjects/RectangleF2D.js
  12. 5 0
      dist/src/Common/DataObjects/SizeF2D.d.ts
  13. 11 0
      dist/src/Common/DataObjects/SizeF2D.js
  14. 30 0
      dist/src/Common/DataObjects/fraction.d.ts
  15. 191 0
      dist/src/Common/DataObjects/fraction.js
  16. 19 0
      dist/src/Common/DataObjects/osmdColor.d.ts
  17. 100 0
      dist/src/Common/DataObjects/osmdColor.js
  18. 64 0
      dist/src/Common/DataObjects/pitch.d.ts
  19. 267 0
      dist/src/Common/DataObjects/pitch.js
  20. 7 0
      dist/src/Common/Enums/FontStyles.d.ts
  21. 9 0
      dist/src/Common/Enums/FontStyles.js
  22. 4 0
      dist/src/Common/Enums/Fonts.d.ts
  23. 6 0
      dist/src/Common/Enums/Fonts.js
  24. 11 0
      dist/src/Common/Enums/TextAlignment.d.ts
  25. 13 0
      dist/src/Common/Enums/TextAlignment.js
  26. 2 0
      dist/src/Common/FileIO/Mxl.d.ts
  27. 44 0
      dist/src/Common/FileIO/Mxl.js
  28. 15 0
      dist/src/Common/FileIO/Xml.d.ts
  29. 60 0
      dist/src/Common/FileIO/Xml.js
  30. 7 0
      dist/src/Common/logging.d.ts
  31. 24 0
      dist/src/Common/logging.js
  32. 16 0
      dist/src/MusicSheetAPI.d.ts
  33. 67 0
      dist/src/MusicSheetAPI.js
  34. 22 0
      dist/src/MusicalScore/Calculation/MeasureSizeCalculator.d.ts
  35. 176 0
      dist/src/MusicalScore/Calculation/MeasureSizeCalculator.js
  36. 15 0
      dist/src/MusicalScore/Exceptions.d.ts
  37. 27 0
      dist/src/MusicalScore/Exceptions.js
  38. 7 0
      dist/src/MusicalScore/Graphical/AbstractGraphicalInstruction.d.ts
  39. 26 0
      dist/src/MusicalScore/Graphical/AbstractGraphicalInstruction.js
  40. 16 0
      dist/src/MusicalScore/Graphical/AccidentalCalculator.d.ts
  41. 72 0
      dist/src/MusicalScore/Graphical/AccidentalCalculator.js
  42. 76 0
      dist/src/MusicalScore/Graphical/BoundingBox.d.ts
  43. 595 0
      dist/src/MusicalScore/Graphical/BoundingBox.js
  44. 4 0
      dist/src/MusicalScore/Graphical/Clickable.d.ts
  45. 15 0
      dist/src/MusicalScore/Graphical/Clickable.js
  46. 61 0
      dist/src/MusicalScore/Graphical/DrawingEnums.d.ts
  47. 66 0
      dist/src/MusicalScore/Graphical/DrawingEnums.js
  48. 24 0
      dist/src/MusicalScore/Graphical/DrawingMode.d.ts
  49. 28 0
      dist/src/MusicalScore/Graphical/DrawingMode.js
  50. 14 0
      dist/src/MusicalScore/Graphical/DrawingParameters.d.ts
  51. 40 0
      dist/src/MusicalScore/Graphical/DrawingParameters.js
  52. 279 0
      dist/src/MusicalScore/Graphical/EngravingRules.d.ts
  53. 1524 0
      dist/src/MusicalScore/Graphical/EngravingRules.js
  54. 12 0
      dist/src/MusicalScore/Graphical/GraphicalChordSymbolContainer.d.ts
  55. 44 0
      dist/src/MusicalScore/Graphical/GraphicalChordSymbolContainer.js
  56. 6 0
      dist/src/MusicalScore/Graphical/GraphicalComment.d.ts
  57. 9 0
      dist/src/MusicalScore/Graphical/GraphicalComment.js
  58. 10 0
      dist/src/MusicalScore/Graphical/GraphicalLabel.d.ts
  59. 102 0
      dist/src/MusicalScore/Graphical/GraphicalLabel.js
  60. 12 0
      dist/src/MusicalScore/Graphical/GraphicalLine.d.ts
  61. 44 0
      dist/src/MusicalScore/Graphical/GraphicalLine.js
  62. 15 0
      dist/src/MusicalScore/Graphical/GraphicalLyricEntry.d.ts
  63. 52 0
      dist/src/MusicalScore/Graphical/GraphicalLyricEntry.js
  64. 11 0
      dist/src/MusicalScore/Graphical/GraphicalLyricWord.d.ts
  65. 40 0
      dist/src/MusicalScore/Graphical/GraphicalLyricWord.js
  66. 9 0
      dist/src/MusicalScore/Graphical/GraphicalMarkedArea.d.ts
  67. 14 0
      dist/src/MusicalScore/Graphical/GraphicalMarkedArea.js
  68. 21 0
      dist/src/MusicalScore/Graphical/GraphicalMusicPage.d.ts
  69. 83 0
      dist/src/MusicalScore/Graphical/GraphicalMusicPage.js
  70. 100 0
      dist/src/MusicalScore/Graphical/GraphicalMusicSheet.d.ts
  71. 812 0
      dist/src/MusicalScore/Graphical/GraphicalMusicSheet.js
  72. 16 0
      dist/src/MusicalScore/Graphical/GraphicalNote.d.ts
  73. 40 0
      dist/src/MusicalScore/Graphical/GraphicalNote.js
  74. 5 0
      dist/src/MusicalScore/Graphical/GraphicalObject.d.ts
  75. 17 0
      dist/src/MusicalScore/Graphical/GraphicalObject.js
  76. 16 0
      dist/src/MusicalScore/Graphical/GraphicalOctaveShift.d.ts
  77. 42 0
      dist/src/MusicalScore/Graphical/GraphicalOctaveShift.js
  78. 8 0
      dist/src/MusicalScore/Graphical/GraphicalRectangle.d.ts
  79. 21 0
      dist/src/MusicalScore/Graphical/GraphicalRectangle.js
  80. 50 0
      dist/src/MusicalScore/Graphical/GraphicalStaffEntry.d.ts
  81. 273 0
      dist/src/MusicalScore/Graphical/GraphicalStaffEntry.js
  82. 13 0
      dist/src/MusicalScore/Graphical/GraphicalStaffEntryLink.d.ts
  83. 60 0
      dist/src/MusicalScore/Graphical/GraphicalStaffEntryLink.js
  84. 11 0
      dist/src/MusicalScore/Graphical/GraphicalTie.d.ts
  85. 39 0
      dist/src/MusicalScore/Graphical/GraphicalTie.js
  86. 137 0
      dist/src/MusicalScore/Graphical/MusicSheetCalculator.d.ts
  87. 1313 0
      dist/src/MusicalScore/Graphical/MusicSheetCalculator.js
  88. 70 0
      dist/src/MusicalScore/Graphical/MusicSheetDrawer.d.ts
  89. 438 0
      dist/src/MusicalScore/Graphical/MusicSheetDrawer.js
  90. 87 0
      dist/src/MusicalScore/Graphical/MusicSymbol.d.ts
  91. 89 0
      dist/src/MusicalScore/Graphical/MusicSymbol.js
  92. 95 0
      dist/src/MusicalScore/Graphical/MusicSystem.d.ts
  93. 420 0
      dist/src/MusicalScore/Graphical/MusicSystem.js
  94. 71 0
      dist/src/MusicalScore/Graphical/MusicSystemBuilder.d.ts
  95. 725 0
      dist/src/MusicalScore/Graphical/MusicSystemBuilder.js
  96. 8 0
      dist/src/MusicalScore/Graphical/OctaveShiftParams.d.ts
  97. 10 0
      dist/src/MusicalScore/Graphical/OctaveShiftParams.js
  98. 10 0
      dist/src/MusicalScore/Graphical/SelectionEndSymbol.d.ts
  99. 65 0
      dist/src/MusicalScore/Graphical/SelectionEndSymbol.js
  100. 9 0
      dist/src/MusicalScore/Graphical/SelectionStartSymbol.d.ts

+ 0 - 3
.gitignore

@@ -1,6 +1,3 @@
-# Distribution
-dist
-
 # Build
 build
 

+ 0 - 2
.travis.yml

@@ -2,8 +2,6 @@ sudo: false
 language: node_js
 node_js:
   - "5"
-before_script:
-  - npm start
 notifications:
   email: false
   slack:

+ 4 - 0
AUTHORS

@@ -0,0 +1,4 @@
+Andrea Condoluci <a.condoluci@phonicscore.com> (http://llliii.ooo)
+Oliver Hörbinger <o.hoerbinger@phonicscore.com> ()
+Matthias Uiberacker <m.uiberacker@phonicscore.com> ()
+Sebastian Haas <s.haas@phonicscore.com> (http://sebastianhaas.at)

+ 1 - 1
Gruntfile.js

@@ -130,7 +130,7 @@ module.exports = function (grunt) {
                 src: [
                     '<%= outputDir.build %>',
                     '<%= outputDir.dist %>',
-                    'node-modules',
+                    'node_modules',
                     'typings',
                     '.tscache',
                     'src/**/*.js', 'test/**/*.js'

+ 1 - 1
LICENSE

@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2016 Thomas Buchstaetter
+Copyright (c) 2016 PhonicScore
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal

+ 10 - 0
dist/src/Common/DataObjects/MusicSheetErrors.d.ts

@@ -0,0 +1,10 @@
+export declare class MusicSheetErrors {
+    measureErrors: {
+        [n: number]: string[];
+    };
+    private errors;
+    private tempErrors;
+    finalizeMeasure(measureNumber: number): void;
+    pushMeasureError(errorMsg: string): void;
+    push(errorMsg: string): void;
+}

+ 25 - 0
dist/src/Common/DataObjects/MusicSheetErrors.js

@@ -0,0 +1,25 @@
+// skeleton by Andrea
+"use strict";
+var MusicSheetErrors = (function () {
+    function MusicSheetErrors() {
+        this.measureErrors = {};
+        this.errors = [];
+        this.tempErrors = [];
+    }
+    MusicSheetErrors.prototype.finalizeMeasure = function (measureNumber) {
+        var list = this.measureErrors[measureNumber];
+        if (list === undefined) {
+            list = [];
+        }
+        this.measureErrors[measureNumber] = list.concat(this.tempErrors);
+        this.tempErrors = [];
+    };
+    MusicSheetErrors.prototype.pushMeasureError = function (errorMsg) {
+        this.tempErrors.push(errorMsg);
+    };
+    MusicSheetErrors.prototype.push = function (errorMsg) {
+        this.errors.push(errorMsg);
+    };
+    return MusicSheetErrors;
+}());
+exports.MusicSheetErrors = MusicSheetErrors;

+ 8 - 0
dist/src/Common/DataObjects/PointF2D.d.ts

@@ -0,0 +1,8 @@
+export declare class PointF2D {
+    x: number;
+    y: number;
+    constructor(x?: number, y?: number);
+    static Empty: PointF2D;
+    static pointsAreEqual(p1: PointF2D, p2: PointF2D): boolean;
+    ToString(): string;
+}

+ 26 - 0
dist/src/Common/DataObjects/PointF2D.js

@@ -0,0 +1,26 @@
+"use strict";
+var PointF2D = (function () {
+    function PointF2D(x, y) {
+        if (x === void 0) { x = 0; }
+        if (y === void 0) { y = 0; }
+        this.x = 0;
+        this.y = 0;
+        this.x = x;
+        this.y = y;
+    }
+    Object.defineProperty(PointF2D, "Empty", {
+        get: function () {
+            return new PointF2D();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    PointF2D.pointsAreEqual = function (p1, p2) {
+        return (p1.x === p2.x && p1.y === p2.y);
+    };
+    PointF2D.prototype.ToString = function () {
+        return "[" + this.x + ", " + this.y + "]";
+    };
+    return PointF2D;
+}());
+exports.PointF2D = PointF2D;

+ 12 - 0
dist/src/Common/DataObjects/RectangleF2D.d.ts

@@ -0,0 +1,12 @@
+import { SizeF2D } from "./SizeF2D";
+import { PointF2D } from "./PointF2D";
+export declare class RectangleF2D {
+    x: number;
+    y: number;
+    width: number;
+    height: number;
+    constructor(x: number, y: number, width: number, height: number);
+    static createFromLocationAndSize(location: PointF2D, size: SizeF2D): RectangleF2D;
+    Location: PointF2D;
+    Size: SizeF2D;
+}

+ 34 - 0
dist/src/Common/DataObjects/RectangleF2D.js

@@ -0,0 +1,34 @@
+"use strict";
+var SizeF2D_1 = require("./SizeF2D");
+var PointF2D_1 = require("./PointF2D");
+var RectangleF2D = (function () {
+    function RectangleF2D(x, y, width, height) {
+        this.x = 0;
+        this.y = 0;
+        this.width = 0;
+        this.height = 0;
+        this.x = x;
+        this.y = y;
+        this.width = width;
+        this.height = height;
+    }
+    RectangleF2D.createFromLocationAndSize = function (location, size) {
+        return new RectangleF2D(location.x, location.y, size.width, size.height);
+    };
+    Object.defineProperty(RectangleF2D.prototype, "Location", {
+        get: function () {
+            return new PointF2D_1.PointF2D(this.x, this.y);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(RectangleF2D.prototype, "Size", {
+        get: function () {
+            return new SizeF2D_1.SizeF2D(this.width, this.height);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    return RectangleF2D;
+}());
+exports.RectangleF2D = RectangleF2D;

+ 5 - 0
dist/src/Common/DataObjects/SizeF2D.d.ts

@@ -0,0 +1,5 @@
+export declare class SizeF2D {
+    width: number;
+    height: number;
+    constructor(width?: number, height?: number);
+}

+ 11 - 0
dist/src/Common/DataObjects/SizeF2D.js

@@ -0,0 +1,11 @@
+"use strict";
+var SizeF2D = (function () {
+    function SizeF2D(width, height) {
+        if (width === void 0) { width = 0; }
+        if (height === void 0) { height = 0; }
+        this.width = width;
+        this.height = height;
+    }
+    return SizeF2D;
+}());
+exports.SizeF2D = SizeF2D;

+ 30 - 0
dist/src/Common/DataObjects/fraction.d.ts

@@ -0,0 +1,30 @@
+export declare class Fraction {
+    private static maximumAllowedNumber;
+    private numerator;
+    private denominator;
+    private realValue;
+    static max(f1: Fraction, f2: Fraction): Fraction;
+    static Equal(f1: Fraction, f2: Fraction): boolean;
+    static createFromFraction(fraction: Fraction): Fraction;
+    static plus(f1: Fraction, f2: Fraction): Fraction;
+    static minus(f1: Fraction, f2: Fraction): Fraction;
+    private static greatestCommonDenominator(a, b);
+    constructor(numerator?: number, denominator?: number, simplify?: boolean);
+    toString(): string;
+    clone(): Fraction;
+    Numerator: number;
+    Denominator: number;
+    RealValue: number;
+    multiplyWithFactor(factor: number): void;
+    multiplyDenominatorWithFactor(factor: number): void;
+    Add(fraction: Fraction): void;
+    Sub(fraction: Fraction): void;
+    Quantize(maxAllowedDenominator: number): Fraction;
+    Equals(obj: Fraction): boolean;
+    CompareTo(obj: Fraction): number;
+    lt(frac: Fraction): boolean;
+    lte(frac: Fraction): boolean;
+    GetInversion(): Fraction;
+    private setRealValue();
+    private simplify();
+}

+ 191 - 0
dist/src/Common/DataObjects/fraction.js

@@ -0,0 +1,191 @@
+// FIXME: Check the operators' names
+// FIXME: This class should probably be immutable?
+"use strict";
+var Fraction = (function () {
+    function Fraction(numerator, denominator, simplify) {
+        if (numerator === void 0) { numerator = 0; }
+        if (denominator === void 0) { denominator = 1; }
+        if (simplify === void 0) { simplify = true; }
+        this.numerator = 0;
+        this.denominator = 1;
+        this.numerator = numerator;
+        this.denominator = denominator;
+        if (simplify) {
+            this.simplify();
+        }
+        this.setRealValue();
+    }
+    Fraction.max = function (f1, f2) {
+        if (f1.RealValue > f2.RealValue) {
+            return f1;
+        }
+        else {
+            return f2;
+        }
+    };
+    Fraction.Equal = function (f1, f2) {
+        // FIXME
+        return f1.Denominator === f2.Denominator && f1.Numerator === f2.Numerator;
+    };
+    Fraction.createFromFraction = function (fraction) {
+        return new Fraction(fraction.numerator, fraction.denominator);
+    };
+    Fraction.plus = function (f1, f2) {
+        var sum = f1.clone();
+        sum.Add(f2);
+        return sum;
+    };
+    Fraction.minus = function (f1, f2) {
+        var sum = f1.clone();
+        sum.Sub(f2);
+        return sum;
+    };
+    Fraction.greatestCommonDenominator = function (a, b) {
+        if (a === 0) {
+            return b;
+        }
+        if (b === 1) {
+            return 1;
+        }
+        while (b !== 0) {
+            if (a > b) {
+                a -= b;
+            }
+            else {
+                b -= a;
+            }
+        }
+        return a;
+    };
+    Fraction.prototype.toString = function () {
+        return this.numerator + "/" + this.denominator;
+    };
+    Fraction.prototype.clone = function () {
+        return new Fraction(this.numerator, this.denominator, false);
+    };
+    Object.defineProperty(Fraction.prototype, "Numerator", {
+        get: function () {
+            return this.numerator;
+        },
+        set: function (value) {
+            if (this.numerator !== value) {
+                this.numerator = value;
+                this.simplify();
+                this.setRealValue();
+            }
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Fraction.prototype, "Denominator", {
+        get: function () {
+            return this.denominator;
+        },
+        set: function (value) {
+            if (this.denominator !== value) {
+                this.denominator = value;
+                if (this.numerator !== 0) {
+                    this.simplify();
+                }
+                this.setRealValue();
+            }
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Fraction.prototype, "RealValue", {
+        get: function () {
+            return this.realValue;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Fraction.prototype.multiplyWithFactor = function (factor) {
+        this.numerator *= factor;
+        this.denominator *= factor;
+    };
+    Fraction.prototype.multiplyDenominatorWithFactor = function (factor) {
+        this.denominator *= factor;
+        this.setRealValue();
+    };
+    Fraction.prototype.Add = function (fraction) {
+        this.numerator = this.numerator * fraction.denominator + fraction.numerator * this.denominator;
+        this.denominator = this.denominator * fraction.denominator;
+        this.simplify();
+        this.setRealValue();
+    };
+    Fraction.prototype.Sub = function (fraction) {
+        this.numerator = this.numerator * fraction.denominator - fraction.numerator * this.denominator;
+        this.denominator = this.denominator * fraction.denominator;
+        this.simplify();
+        this.setRealValue();
+    };
+    Fraction.prototype.Quantize = function (maxAllowedDenominator) {
+        if (this.denominator <= maxAllowedDenominator) {
+            return this;
+        }
+        var upTestFraction = new Fraction(this.numerator + 1, this.denominator);
+        while (upTestFraction.Denominator > maxAllowedDenominator) {
+            upTestFraction.Numerator++;
+        }
+        if (this.numerator > this.denominator) {
+            var downTestFraction = new Fraction(this.numerator - 1, this.denominator);
+            while (downTestFraction.Denominator > maxAllowedDenominator) {
+                downTestFraction.Numerator--;
+            }
+            if (downTestFraction.Denominator < upTestFraction.Denominator) {
+                return downTestFraction;
+            }
+        }
+        return upTestFraction;
+    };
+    Fraction.prototype.Equals = function (obj) {
+        return this.RealValue === obj.RealValue;
+    };
+    Fraction.prototype.CompareTo = function (obj) {
+        var diff = this.numerator * obj.Denominator - this.denominator * obj.Numerator;
+        // Return the sign of diff
+        return diff ? diff < 0 ? -1 : 1 : 0;
+    };
+    Fraction.prototype.lt = function (frac) {
+        return (this.numerator * frac.Denominator - this.denominator * frac.Numerator) < 0;
+    };
+    Fraction.prototype.lte = function (frac) {
+        return (this.numerator * frac.Denominator - this.denominator * frac.Numerator) <= 0;
+    };
+    //public Equals(f: Fraction): boolean {
+    //    if (ReferenceEquals(this, f))
+    //        return true;
+    //    if (ReferenceEquals(f, undefined))
+    //        return false;
+    //    return <number>this.numerator * f.denominator === <number>f.numerator * this.denominator;
+    //}
+    Fraction.prototype.GetInversion = function () {
+        return new Fraction(this.denominator, this.numerator);
+    };
+    Fraction.prototype.setRealValue = function () {
+        this.realValue = this.numerator / this.denominator;
+    };
+    Fraction.prototype.simplify = function () {
+        if (this.numerator === 0) {
+            this.denominator = 1;
+            return;
+        }
+        var i = Fraction.greatestCommonDenominator(Math.abs(this.numerator), Math.abs(this.denominator));
+        this.numerator /= i;
+        this.denominator /= i;
+        if (this.denominator > Fraction.maximumAllowedNumber) {
+            var factor = this.denominator / Fraction.maximumAllowedNumber;
+            this.numerator = Math.round(this.numerator / factor);
+            this.denominator = Math.round(this.denominator / factor);
+        }
+        if (this.numerator > Fraction.maximumAllowedNumber) {
+            var factor = this.numerator / Fraction.maximumAllowedNumber;
+            this.numerator = Math.round(this.numerator / factor);
+            this.denominator = Math.round(this.denominator / factor);
+        }
+    };
+    Fraction.maximumAllowedNumber = 46340;
+    return Fraction;
+}());
+exports.Fraction = Fraction;

+ 19 - 0
dist/src/Common/DataObjects/osmdColor.d.ts

@@ -0,0 +1,19 @@
+export declare class OSMDColor {
+    alpha: number;
+    red: number;
+    green: number;
+    blue: number;
+    constructor(red: number, green: number, blue: number);
+    static Black: OSMDColor;
+    static DeepSkyBlue: OSMDColor;
+    static Green: OSMDColor;
+    static Magenta: OSMDColor;
+    static Orange: OSMDColor;
+    static Red: OSMDColor;
+    static Disabled: OSMDColor;
+    static DarkBlue: OSMDColor;
+    static Debug1: OSMDColor;
+    static Debug2: OSMDColor;
+    static Debug3: OSMDColor;
+    toString(): string;
+}

+ 100 - 0
dist/src/Common/DataObjects/osmdColor.js

@@ -0,0 +1,100 @@
+"use strict";
+var OSMDColor = (function () {
+    // FIXME:
+    /*constructor(alpha: number, red: number, green: number, blue: number) {
+        this.alpha = alpha;
+        this.red = red;
+        this.green = green;
+        this.blue = blue;
+    }*/
+    function OSMDColor(red, green, blue) {
+        this.alpha = 255;
+        this.red = red;
+        this.green = green;
+        this.blue = blue;
+    }
+    Object.defineProperty(OSMDColor, "Black", {
+        get: function () {
+            return new OSMDColor(0, 0, 0);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(OSMDColor, "DeepSkyBlue", {
+        get: function () {
+            return new OSMDColor(0, 191, 255);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(OSMDColor, "Green", {
+        get: function () {
+            return new OSMDColor(20, 160, 20);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(OSMDColor, "Magenta", {
+        get: function () {
+            return new OSMDColor(255, 0, 255);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(OSMDColor, "Orange", {
+        get: function () {
+            return new OSMDColor(255, 128, 0);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(OSMDColor, "Red", {
+        get: function () {
+            return new OSMDColor(240, 20, 20);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(OSMDColor, "Disabled", {
+        get: function () {
+            return new OSMDColor(225, 225, 225);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(OSMDColor, "DarkBlue", {
+        get: function () {
+            return new OSMDColor(0, 0, 140);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(OSMDColor, "Debug1", {
+        // For debugging:
+        get: function () {
+            return new OSMDColor(200, 0, 140);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(OSMDColor, "Debug2", {
+        get: function () {
+            return new OSMDColor(100, 100, 200);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(OSMDColor, "Debug3", {
+        get: function () {
+            return new OSMDColor(0, 50, 140);
+        },
+        enumerable: true,
+        configurable: true
+    });
+    OSMDColor.prototype.toString = function () {
+        // FIXME RGBA
+        return "rgb(" + this.red + "," + this.green + "," + this.blue + ")";
+    };
+    return OSMDColor;
+}());
+exports.OSMDColor = OSMDColor;

+ 64 - 0
dist/src/Common/DataObjects/pitch.d.ts

@@ -0,0 +1,64 @@
+export declare enum NoteEnum {
+    C = 0,
+    D = 2,
+    E = 4,
+    F = 5,
+    G = 7,
+    A = 9,
+    B = 11,
+}
+export declare enum AccidentalEnum {
+    DOUBLEFLAT = -2,
+    FLAT = -1,
+    NONE = 0,
+    SHARP = 1,
+    DOUBLESHARP = 2,
+}
+export declare class Pitch {
+    static pitchEnumValues: NoteEnum[];
+    private static halftoneFactor;
+    private static octXmlDiff;
+    private octave;
+    private fundamentalNote;
+    private accidental;
+    private frequency;
+    private halfTone;
+    static getNoteEnumString(note: NoteEnum): string;
+    /**
+     * @param the input pitch
+     * @param the number of halftones to transpose with
+     * @returns ret[0] = the transposed fundamental.
+     *          ret[1] = the octave shift (not the new octave!)
+     * @constructor
+     */
+    static CalculateTransposedHalfTone(pitch: Pitch, transpose: number): {
+        value: number;
+        overflow: number;
+    };
+    static WrapAroundCheck(value: number, limit: number): {
+        value: number;
+        overflow: number;
+    };
+    static calcFrequency(obj: Pitch | number): number;
+    static calcFractionalKey(frequency: number): number;
+    static fromFrequency(frequency: number): Pitch;
+    static fromHalftone(halftone: number): Pitch;
+    static ceiling(halftone: number): NoteEnum;
+    static floor(halftone: number): NoteEnum;
+    constructor(fundamentalNote: NoteEnum, octave: number, accidental: AccidentalEnum);
+    Octave: number;
+    FundamentalNote: NoteEnum;
+    Accidental: AccidentalEnum;
+    Frequency: number;
+    static OctaveXmlDifference: number;
+    getHalfTone(): number;
+    getTransposedPitch(factor: number): Pitch;
+    DoEnharmonicChange(): void;
+    ToString(): string;
+    OperatorEquals(p2: Pitch): boolean;
+    OperatorNotEqual(p2: Pitch): boolean;
+    private getHigherPitchByTransposeFactor(factor);
+    private getLowerPitchByTransposeFactor(factor);
+    private getNextFundamentalNote(fundamental);
+    private getPreviousFundamentalNote(fundamental);
+}

+ 267 - 0
dist/src/Common/DataObjects/pitch.js

@@ -0,0 +1,267 @@
+"use strict";
+(function (NoteEnum) {
+    NoteEnum[NoteEnum["C"] = 0] = "C";
+    NoteEnum[NoteEnum["D"] = 2] = "D";
+    NoteEnum[NoteEnum["E"] = 4] = "E";
+    NoteEnum[NoteEnum["F"] = 5] = "F";
+    NoteEnum[NoteEnum["G"] = 7] = "G";
+    NoteEnum[NoteEnum["A"] = 9] = "A";
+    NoteEnum[NoteEnum["B"] = 11] = "B";
+})(exports.NoteEnum || (exports.NoteEnum = {}));
+var NoteEnum = exports.NoteEnum;
+(function (AccidentalEnum) {
+    AccidentalEnum[AccidentalEnum["DOUBLEFLAT"] = -2] = "DOUBLEFLAT";
+    AccidentalEnum[AccidentalEnum["FLAT"] = -1] = "FLAT";
+    AccidentalEnum[AccidentalEnum["NONE"] = 0] = "NONE";
+    AccidentalEnum[AccidentalEnum["SHARP"] = 1] = "SHARP";
+    AccidentalEnum[AccidentalEnum["DOUBLESHARP"] = 2] = "DOUBLESHARP";
+})(exports.AccidentalEnum || (exports.AccidentalEnum = {}));
+var AccidentalEnum = exports.AccidentalEnum;
+var Pitch = (function () {
+    function Pitch(fundamentalNote, octave, accidental) {
+        this.accidental = AccidentalEnum.NONE;
+        this.fundamentalNote = fundamentalNote;
+        this.octave = octave;
+        this.accidental = accidental;
+        this.halfTone = (fundamentalNote) + (octave + Pitch.octXmlDiff) * 12 + accidental;
+        this.frequency = Pitch.calcFrequency(this);
+    }
+    Pitch.getNoteEnumString = function (note) {
+        switch (note) {
+            case NoteEnum.C:
+                return "C";
+            case NoteEnum.D:
+                return "D";
+            case NoteEnum.E:
+                return "E";
+            case NoteEnum.F:
+                return "F";
+            case NoteEnum.G:
+                return "G";
+            case NoteEnum.A:
+                return "A";
+            case NoteEnum.B:
+                return "B";
+            default:
+                return "";
+        }
+    };
+    /**
+     * @param the input pitch
+     * @param the number of halftones to transpose with
+     * @returns ret[0] = the transposed fundamental.
+     *          ret[1] = the octave shift (not the new octave!)
+     * @constructor
+     */
+    Pitch.CalculateTransposedHalfTone = function (pitch, transpose) {
+        var newHalfTone = pitch.fundamentalNote + pitch.accidental + transpose;
+        return Pitch.WrapAroundCheck(newHalfTone, 12);
+    };
+    Pitch.WrapAroundCheck = function (value, limit) {
+        var overflow = 0;
+        while (value < 0) {
+            value += limit;
+            overflow--; // the octave change
+        }
+        while (value >= limit) {
+            value -= limit;
+            overflow++; // the octave change
+        }
+        return { overflow: overflow, value: value };
+    };
+    //public static calcFrequency(pitch: Pitch): number;
+    //public static calcFrequency(fractionalKey: number): number;
+    Pitch.calcFrequency = function (obj) {
+        var octaveSteps = 0;
+        var halftoneSteps;
+        if (obj instanceof Pitch) {
+            // obj is a pitch
+            var pitch = obj;
+            octaveSteps = pitch.octave - 1;
+            halftoneSteps = pitch.fundamentalNote - NoteEnum.A + pitch.accidental;
+        }
+        else if (typeof obj === "number") {
+            // obj is a fractional key
+            var fractionalKey = obj;
+            halftoneSteps = fractionalKey - 57.0;
+        }
+        // Return frequency:
+        return 440.0 * Math.pow(2, octaveSteps) * Math.pow(2, halftoneSteps / 12.0);
+    };
+    Pitch.calcFractionalKey = function (frequency) {
+        // Return half-tone frequency:
+        return Math.log(frequency / 440.0) / Math.LN10 * Pitch.halftoneFactor + 57.0;
+    };
+    Pitch.fromFrequency = function (frequency) {
+        var key = Pitch.calcFractionalKey(frequency) + 0.5;
+        var octave = Math.floor(key / 12) - Pitch.octXmlDiff;
+        var halftone = Math.floor(key) % 12;
+        var fundamentalNote = halftone;
+        var accidental = AccidentalEnum.NONE;
+        if (this.pitchEnumValues.indexOf(fundamentalNote) === -1) {
+            fundamentalNote = (halftone - 1);
+            accidental = AccidentalEnum.SHARP;
+        }
+        return new Pitch(fundamentalNote, octave, accidental);
+    };
+    Pitch.fromHalftone = function (halftone) {
+        var octave = Math.floor(halftone / 12) - Pitch.octXmlDiff;
+        var halftoneInOctave = halftone % 12;
+        var fundamentalNote = halftoneInOctave;
+        var accidental = AccidentalEnum.NONE;
+        if (this.pitchEnumValues.indexOf(fundamentalNote) === -1) {
+            fundamentalNote = (halftoneInOctave - 1);
+            accidental = AccidentalEnum.SHARP;
+        }
+        return new Pitch(fundamentalNote, octave, accidental);
+    };
+    Pitch.ceiling = function (halftone) {
+        halftone = (halftone) % 12;
+        var fundamentalNote = halftone;
+        if (this.pitchEnumValues.indexOf(fundamentalNote) === -1) {
+            fundamentalNote = (halftone + 1);
+        }
+        return fundamentalNote;
+    };
+    Pitch.floor = function (halftone) {
+        halftone = halftone % 12;
+        var fundamentalNote = halftone;
+        if (this.pitchEnumValues.indexOf(fundamentalNote) === -1) {
+            fundamentalNote = (halftone - 1);
+        }
+        return fundamentalNote;
+    };
+    Object.defineProperty(Pitch.prototype, "Octave", {
+        get: function () {
+            return this.octave;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Pitch.prototype, "FundamentalNote", {
+        get: function () {
+            return this.fundamentalNote;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Pitch.prototype, "Accidental", {
+        get: function () {
+            return this.accidental;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Pitch.prototype, "Frequency", {
+        get: function () {
+            return this.frequency;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(Pitch, "OctaveXmlDifference", {
+        get: function () {
+            return Pitch.octXmlDiff;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Pitch.prototype.getHalfTone = function () {
+        return this.halfTone;
+    };
+    Pitch.prototype.getTransposedPitch = function (factor) {
+        if (factor > 12) {
+            throw new Error("rewrite this method to handle bigger octave changes or don't use is with bigger octave changes!");
+        }
+        if (factor > 0) {
+            return this.getHigherPitchByTransposeFactor(factor);
+        }
+        if (factor < 0) {
+            return this.getLowerPitchByTransposeFactor(-factor);
+        }
+        return this;
+    };
+    Pitch.prototype.DoEnharmonicChange = function () {
+        switch (this.accidental) {
+            case AccidentalEnum.FLAT:
+            case AccidentalEnum.DOUBLEFLAT:
+                this.fundamentalNote = this.getPreviousFundamentalNote(this.fundamentalNote);
+                this.accidental = (this.halfTone - ((this.fundamentalNote) +
+                    (this.octave + Pitch.octXmlDiff) * 12));
+                break;
+            case AccidentalEnum.SHARP:
+            case AccidentalEnum.DOUBLESHARP:
+                this.fundamentalNote = this.getNextFundamentalNote(this.fundamentalNote);
+                this.accidental = (this.halfTone - ((this.fundamentalNote) +
+                    (this.octave + Pitch.octXmlDiff) * 12));
+                break;
+            default:
+                return;
+        }
+    };
+    Pitch.prototype.ToString = function () {
+        return "Note: " + this.fundamentalNote + ", octave: " + this.octave.toString() + ", alter: " +
+            this.accidental;
+    };
+    Pitch.prototype.OperatorEquals = function (p2) {
+        var p1 = this;
+        // if (ReferenceEquals(p1, p2)) {
+        //     return true;
+        // }
+        if ((p1 === undefined) || (p2 === undefined)) {
+            return false;
+        }
+        return (p1.FundamentalNote === p2.FundamentalNote && p1.Octave === p2.Octave && p1.Accidental === p2.Accidental);
+    };
+    Pitch.prototype.OperatorNotEqual = function (p2) {
+        var p1 = this;
+        return !(p1 === p2);
+    };
+    Pitch.prototype.getHigherPitchByTransposeFactor = function (factor) {
+        var noteEnumIndex = Pitch.pitchEnumValues.indexOf(this.fundamentalNote);
+        var newOctave = this.octave;
+        var newNoteEnum;
+        if (noteEnumIndex + factor > Pitch.pitchEnumValues.length - 1) {
+            newNoteEnum = Pitch.pitchEnumValues[noteEnumIndex + factor - Pitch.pitchEnumValues.length];
+            newOctave++;
+        }
+        else {
+            newNoteEnum = Pitch.pitchEnumValues[noteEnumIndex + factor];
+        }
+        return new Pitch(newNoteEnum, newOctave, AccidentalEnum.NONE);
+    };
+    Pitch.prototype.getLowerPitchByTransposeFactor = function (factor) {
+        var noteEnumIndex = Pitch.pitchEnumValues.indexOf(this.fundamentalNote);
+        var newOctave = this.octave;
+        var newNoteEnum;
+        if (noteEnumIndex - factor < 0) {
+            newNoteEnum = Pitch.pitchEnumValues[Pitch.pitchEnumValues.length + noteEnumIndex - factor];
+            newOctave--;
+        }
+        else {
+            newNoteEnum = Pitch.pitchEnumValues[noteEnumIndex - factor];
+        }
+        return new Pitch(newNoteEnum, newOctave, AccidentalEnum.NONE);
+    };
+    Pitch.prototype.getNextFundamentalNote = function (fundamental) {
+        var i = Pitch.pitchEnumValues.indexOf(fundamental);
+        i = (i + 1) % Pitch.pitchEnumValues.length;
+        return Pitch.pitchEnumValues[i];
+    };
+    Pitch.prototype.getPreviousFundamentalNote = function (fundamental) {
+        var i = Pitch.pitchEnumValues.indexOf(fundamental);
+        if (i > 0) {
+            return Pitch.pitchEnumValues[i - 1];
+        }
+        else {
+            return Pitch.pitchEnumValues[Pitch.pitchEnumValues.length - 1];
+        }
+    };
+    Pitch.pitchEnumValues = [
+        NoteEnum.C, NoteEnum.D, NoteEnum.E, NoteEnum.F, NoteEnum.G, NoteEnum.A, NoteEnum.B,
+    ];
+    Pitch.halftoneFactor = 12 / (Math.LN2 / Math.LN10);
+    Pitch.octXmlDiff = 3;
+    return Pitch;
+}());
+exports.Pitch = Pitch;

+ 7 - 0
dist/src/Common/Enums/FontStyles.d.ts

@@ -0,0 +1,7 @@
+export declare enum FontStyles {
+    Regular = 0,
+    Bold = 1,
+    Italic = 2,
+    BoldItalic = 3,
+    Underlined = 4,
+}

+ 9 - 0
dist/src/Common/Enums/FontStyles.js

@@ -0,0 +1,9 @@
+"use strict";
+(function (FontStyles) {
+    FontStyles[FontStyles["Regular"] = 0] = "Regular";
+    FontStyles[FontStyles["Bold"] = 1] = "Bold";
+    FontStyles[FontStyles["Italic"] = 2] = "Italic";
+    FontStyles[FontStyles["BoldItalic"] = 3] = "BoldItalic";
+    FontStyles[FontStyles["Underlined"] = 4] = "Underlined";
+})(exports.FontStyles || (exports.FontStyles = {}));
+var FontStyles = exports.FontStyles;

+ 4 - 0
dist/src/Common/Enums/Fonts.d.ts

@@ -0,0 +1,4 @@
+export declare enum Fonts {
+    TimesNewRoman = 0,
+    Kokila = 1,
+}

+ 6 - 0
dist/src/Common/Enums/Fonts.js

@@ -0,0 +1,6 @@
+"use strict";
+(function (Fonts) {
+    Fonts[Fonts["TimesNewRoman"] = 0] = "TimesNewRoman";
+    Fonts[Fonts["Kokila"] = 1] = "Kokila";
+})(exports.Fonts || (exports.Fonts = {}));
+var Fonts = exports.Fonts;

+ 11 - 0
dist/src/Common/Enums/TextAlignment.d.ts

@@ -0,0 +1,11 @@
+export declare enum TextAlignment {
+    LeftTop = 0,
+    LeftCenter = 1,
+    LeftBottom = 2,
+    CenterTop = 3,
+    CenterCenter = 4,
+    CenterBottom = 5,
+    RightTop = 6,
+    RightCenter = 7,
+    RightBottom = 8,
+}

+ 13 - 0
dist/src/Common/Enums/TextAlignment.js

@@ -0,0 +1,13 @@
+"use strict";
+(function (TextAlignment) {
+    TextAlignment[TextAlignment["LeftTop"] = 0] = "LeftTop";
+    TextAlignment[TextAlignment["LeftCenter"] = 1] = "LeftCenter";
+    TextAlignment[TextAlignment["LeftBottom"] = 2] = "LeftBottom";
+    TextAlignment[TextAlignment["CenterTop"] = 3] = "CenterTop";
+    TextAlignment[TextAlignment["CenterCenter"] = 4] = "CenterCenter";
+    TextAlignment[TextAlignment["CenterBottom"] = 5] = "CenterBottom";
+    TextAlignment[TextAlignment["RightTop"] = 6] = "RightTop";
+    TextAlignment[TextAlignment["RightCenter"] = 7] = "RightCenter";
+    TextAlignment[TextAlignment["RightBottom"] = 8] = "RightBottom";
+})(exports.TextAlignment || (exports.TextAlignment = {}));
+var TextAlignment = exports.TextAlignment;

+ 2 - 0
dist/src/Common/FileIO/Mxl.d.ts

@@ -0,0 +1,2 @@
+import { Promise } from "es6-promise";
+export declare function extractSheetFromMxl(data: string): Promise<any>;

+ 44 - 0
dist/src/Common/FileIO/Mxl.js

@@ -0,0 +1,44 @@
+"use strict";
+var Xml_1 = require("./Xml");
+var es6_promise_1 = require("es6-promise");
+var JSZip = require("jszip");
+// Usage for extractSheetMusicFromMxl:
+// extractSheetFromMxl(" *** binary content *** ").then(
+//   (score: IXmlElement) => {
+//     // Success! use the score here!
+//   },
+//   (error: any) => {
+//     // There was an error.
+//     // Handle it here.
+//   }
+// )
+function extractSheetFromMxl(data) {
+    "use strict";
+    // _zip_ must be of type 'any' for now, since typings for JSZip are not up-to-date
+    var zip = new JSZip();
+    // asynchronously load zip file and process it - with Promises
+    return zip.loadAsync(data).then(function (_) {
+        return zip.file("META-INF/container.xml").async("string");
+    }, function (err) {
+        throw err;
+    }).then(function (content) {
+        var parser = new DOMParser();
+        var doc = parser.parseFromString(content, "text/xml");
+        var rootFile = doc.getElementsByTagName("rootfile")[0].getAttribute("full-path");
+        return zip.file(rootFile).async("string");
+    }, function (err) {
+        throw err;
+    }).then(function (content) {
+        var parser = new DOMParser();
+        var xml = parser.parseFromString(content, "text/xml");
+        var doc = new Xml_1.IXmlElement(xml.documentElement);
+        return es6_promise_1.Promise.resolve(doc);
+    }, function (err) {
+        throw err;
+    }).then(function (content) {
+        return es6_promise_1.Promise.resolve(content);
+    }, function (err) {
+        throw new Error("extractSheetFromMxl: " + err.message);
+    });
+}
+exports.extractSheetFromMxl = extractSheetFromMxl;

+ 15 - 0
dist/src/Common/FileIO/Xml.d.ts

@@ -0,0 +1,15 @@
+export declare type IXmlAttribute = Attr;
+export declare class IXmlElement {
+    name: string;
+    value: string;
+    hasAttributes: boolean;
+    firstAttribute: IXmlAttribute;
+    hasElements: boolean;
+    private attrs;
+    private elem;
+    constructor(elem: Element);
+    attribute(attributeName: string): IXmlAttribute;
+    attributes(): IXmlAttribute[];
+    element(elementName: string): IXmlElement;
+    elements(nodeName?: string): IXmlElement[];
+}

+ 60 - 0
dist/src/Common/FileIO/Xml.js

@@ -0,0 +1,60 @@
+"use strict";
+var IXmlElement = (function () {
+    function IXmlElement(elem) {
+        this.hasAttributes = false;
+        this.elem = elem;
+        this.name = elem.nodeName.toLowerCase();
+        if (elem.hasAttributes()) {
+            this.hasAttributes = true;
+            this.firstAttribute = elem.attributes[0];
+        }
+        this.hasElements = elem.hasChildNodes();
+        // Look for a value
+        if (elem.childNodes.length === 1 && elem.childNodes[0].nodeType === Node.TEXT_NODE) {
+            this.value = elem.childNodes[0].nodeValue;
+        }
+        else {
+            this.value = "";
+        }
+    }
+    IXmlElement.prototype.attribute = function (attributeName) {
+        return this.elem.attributes.getNamedItem(attributeName);
+    };
+    IXmlElement.prototype.attributes = function () {
+        if (typeof this.attrs === "undefined") {
+            var attributes = this.elem.attributes;
+            var attrs = [];
+            for (var i = 0; i < attributes.length; i += 1) {
+                attrs.push(attributes[i]);
+            }
+            this.attrs = attrs;
+        }
+        return this.attrs;
+    };
+    IXmlElement.prototype.element = function (elementName) {
+        return this.elements(elementName)[0];
+    };
+    IXmlElement.prototype.elements = function (nodeName) {
+        var nodes = this.elem.childNodes;
+        var ret = [];
+        var nameUnset = nodeName === undefined;
+        if (!nameUnset) {
+            nodeName = nodeName.toLowerCase();
+        }
+        // console.log("-", nodeName, nodes.length, this.elem.childElementCount, this.elem.getElementsByTagName(nodeName).length);
+        // if (nodeName === "measure") {
+        //   console.log(this.elem);
+        // }
+        for (var i = 0; i < nodes.length; i += 1) {
+            var node = nodes[i];
+            //console.log("node: ", this.elem.nodeName, ">>", node.nodeName, node.nodeType === Node.ELEMENT_NODE);
+            if (node.nodeType === Node.ELEMENT_NODE &&
+                (nameUnset || node.nodeName.toLowerCase() === nodeName)) {
+                ret.push(new IXmlElement(node));
+            }
+        }
+        return ret;
+    };
+    return IXmlElement;
+}());
+exports.IXmlElement = IXmlElement;

+ 7 - 0
dist/src/Common/logging.d.ts

@@ -0,0 +1,7 @@
+/**
+ * Created by acondolu on 26/04/16.
+ */
+export declare class Logging {
+    static debug(...args: any[]): void;
+    static log(...args: any[]): void;
+}

+ 24 - 0
dist/src/Common/logging.js

@@ -0,0 +1,24 @@
+/**
+ * Created by acondolu on 26/04/16.
+ */
+"use strict";
+var Logging = (function () {
+    function Logging() {
+    }
+    Logging.debug = function () {
+        var args = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            args[_i - 0] = arguments[_i];
+        }
+        console.log("[OSMD] DEBUG: ", args.join(" "));
+    };
+    Logging.log = function () {
+        var args = [];
+        for (var _i = 0; _i < arguments.length; _i++) {
+            args[_i - 0] = arguments[_i];
+        }
+        console.log("[OSMD] ", args.join(" "));
+    };
+    return Logging;
+}());
+exports.Logging = Logging;

+ 16 - 0
dist/src/MusicSheetAPI.d.ts

@@ -0,0 +1,16 @@
+export declare class MusicSheetAPI {
+    constructor();
+    private canvas;
+    private sheet;
+    private drawer;
+    private graphic;
+    private width;
+    private zoom;
+    private unit;
+    load(sheet: Element): void;
+    setCanvas(canvas: HTMLCanvasElement): void;
+    setWidth(width: number): void;
+    scale(k: number): void;
+    display(): void;
+    free(): void;
+}

+ 67 - 0
dist/src/MusicSheetAPI.js

@@ -0,0 +1,67 @@
+"use strict";
+var Xml_1 = require("./Common/FileIO/Xml");
+var VexFlowMusicSheetCalculator_1 = require("./MusicalScore/Graphical/VexFlow/VexFlowMusicSheetCalculator");
+var MusicSheetReader_1 = require("./MusicalScore/ScoreIO/MusicSheetReader");
+var GraphicalMusicSheet_1 = require("./MusicalScore/Graphical/GraphicalMusicSheet");
+var VexFlowMusicSheetDrawer_1 = require("./MusicalScore/Graphical/VexFlow/VexFlowMusicSheetDrawer");
+var VexFlowTextMeasurer_1 = require("./MusicalScore/Graphical/VexFlow/VexFlowTextMeasurer");
+var MusicSheetAPI = (function () {
+    function MusicSheetAPI() {
+        this.zoom = 1.0;
+        this.unit = 10;
+        return;
+    }
+    MusicSheetAPI.prototype.load = function (sheet) {
+        var score = new Xml_1.IXmlElement(sheet.getElementsByTagName("score-partwise")[0]);
+        var calc = new VexFlowMusicSheetCalculator_1.VexFlowMusicSheetCalculator();
+        var reader = new MusicSheetReader_1.MusicSheetReader();
+        this.sheet = reader.createMusicSheet(score, "path missing");
+        this.graphic = new GraphicalMusicSheet_1.GraphicalMusicSheet(this.sheet, calc);
+        this.display();
+    };
+    MusicSheetAPI.prototype.setCanvas = function (canvas) {
+        this.canvas = canvas;
+        this.drawer = new VexFlowMusicSheetDrawer_1.VexFlowMusicSheetDrawer(canvas, new VexFlowTextMeasurer_1.VexFlowTextMeasurer());
+    };
+    MusicSheetAPI.prototype.setWidth = function (width) {
+        if (width === this.width) {
+            return;
+        }
+        this.width = width;
+        this.display();
+    };
+    MusicSheetAPI.prototype.scale = function (k) {
+        this.zoom = k;
+        this.display();
+    };
+    MusicSheetAPI.prototype.display = function () {
+        if (this.width === undefined) {
+            return;
+        }
+        if (this.canvas === undefined) {
+            return;
+        }
+        if (this.sheet === undefined) {
+            return;
+        }
+        this.sheet.pageWidth = this.width / this.zoom / this.unit;
+        this.graphic.reCalculate();
+        // Update Sheet Page
+        var height = this.graphic.MusicPages[0].PositionAndShape.BorderBottom * this.unit * this.zoom;
+        this.drawer.resize(this.width, height);
+        // Fix the label problem
+        this.drawer.translate(0, 100);
+        this.drawer.scale(this.zoom);
+        this.drawer.drawSheet(this.graphic);
+    };
+    MusicSheetAPI.prototype.free = function () {
+        this.canvas = undefined;
+        this.sheet = undefined;
+        return;
+    };
+    return MusicSheetAPI;
+}());
+exports.MusicSheetAPI = MusicSheetAPI;
+window.osmd = {
+    "MusicSheet": MusicSheetAPI,
+};

+ 22 - 0
dist/src/MusicalScore/Calculation/MeasureSizeCalculator.d.ts

@@ -0,0 +1,22 @@
+import Vex = require("vexflow");
+import StaveNote = Vex.Flow.StaveNote;
+export declare type PositionAndShapeInfo = any;
+export declare class MeasureSizeCalculator {
+    private stave;
+    private voices;
+    private formatter;
+    private offsetLeft;
+    private offsetRight;
+    private voicesWidth;
+    private topBorder;
+    private bottomBorder;
+    constructor(stave: Vex.Flow.Stave, voices: Vex.Flow.Voice[], formatter: Vex.Flow.Formatter);
+    static getVexFlowStaveNoteShape(note: StaveNote): PositionAndShapeInfo;
+    static getClefBoundingBox(clef: Vex.Flow.Clef): Vex.Flow.BoundingBox;
+    static getKeySignatureBoundingBox(sig: any): Vex.Flow.BoundingBox;
+    getWidth(): number;
+    getHeight(): number;
+    getTopBorder(): number;
+    getBottomBorder(): number;
+    private format();
+}

+ 176 - 0
dist/src/MusicalScore/Calculation/MeasureSizeCalculator.js

@@ -0,0 +1,176 @@
+"use strict";
+var Vex = require("vexflow");
+/* TODO
+ * Complete support for StaveModifiers
+ * Take into account Ties and Slurs
+ */
+/* Measure Size Calculator
+ *  Given a stave, voices and a formatter, calculates
+ *  through VexFlow the size of a measure.
+ *  !!! before using this, call the methods
+ *  !!! joinVoices and preCalculateMinTotalWidth
+ *  !!! of the formatter!
+ *
+ * Usage:
+ *   let stave: Vex.Flow.Stave = ...;
+ *   let formatter = new Vex.Flow.Formatter()
+ *   let voices: Vex.Flor.Voice[] = ...;
+ *   formatter.preCalculateMinTotalWidth(voices);
+ *   let calc = new MeasureSizeCalculator(stave, voices, formatter);
+ *   calc.???
+ */
+var MeasureSizeCalculator = (function () {
+    function MeasureSizeCalculator(stave, voices, formatter) {
+        this.stave = stave;
+        this.voices = voices;
+        this.formatter = formatter;
+        // the stave must be initialized with width, x, y 0
+        // the voices must be already joined and (pre)formatted
+        if (!formatter.hasMinTotalWidth) {
+            throw "Must first call Formatter.preCalculateMinTotalWidth " +
+                "with all the voices in the measure (vertical)";
+        }
+        this.format();
+    }
+    // Returns the shape of the note head at position _index_ inside _note_.
+    // Remember: in VexFlow, StaveNote correspond to PhonicScore's VoiceEntries.
+    //  public static getVexFlowNoteHeadShape(note: StaveNote, index: number): PositionAndShapeInfo {
+    //  // note_heads is not public in StaveNote, but we access it anyway...
+    //  let bb = note.note_heads[index].getBoundingBox();
+    //  let info: any = new PositionAndShapeInfo();
+    //  let x: number = bb.getX();
+    //  let y: number = bb.getY();
+    //  let w: number = bb.getW();
+    //  let h: number = bb.getH();
+    //  info.Left = info.Right = bb.getW() / 2;
+    //  info.Top = info.Bottom = bb.getH() / 2;
+    //  info.X = bb.getX() + info.Left;
+    //  info.Y = bb.getY() + info.Bottom;
+    //  return info;
+    //}
+    // Returns the shape of all the note heads inside a StaveNote.
+    // Remember: in VexFlow, StaveNote correspond to PhonicScore's VoiceEntries.
+    MeasureSizeCalculator.getVexFlowStaveNoteShape = function (note) {
+        var info = {};
+        var bounds = note.getNoteHeadBounds();
+        var beginX = note.getNoteHeadBeginX();
+        var endX = note.getNoteHeadEndX();
+        info.Left = info.Right = (endX - beginX) / 2;
+        info.Top = info.Bottom = (bounds.y_top - bounds.y_bottom) / 2;
+        info.X = beginX + info.Left;
+        info.Y = bounds.y_bottom + info.Bottom;
+        return info;
+    };
+    MeasureSizeCalculator.getClefBoundingBox = function (clef) {
+        var clef2 = clef;
+        clef2.placeGlyphOnLine(clef2.glyph, clef2.stave, clef2.clef.line);
+        var glyph = clef.glyph;
+        var posX = clef.x + glyph.x_shift;
+        var posY = clef.stave.getYForGlyphs() + glyph.y_shift;
+        var scale = glyph.scale;
+        var outline = glyph.metrics.outline;
+        var xmin = 0, xmax = 0, ymin = 0, ymax = 0;
+        function update(i) {
+            var x = outline[i + 1];
+            var y = outline[i + 2];
+            xmin = Math.min(xmin, x);
+            xmax = Math.max(xmax, x);
+            ymin = Math.min(ymin, y);
+            ymax = Math.max(ymax, y);
+        }
+        for (var i = 0, len = outline.length; i < len; i += 3) {
+            switch (outline[i]) {
+                case "m":
+                    update(i);
+                    break;
+                case "l":
+                    update(i);
+                    break;
+                case "q":
+                    i += 2;
+                    update(i);
+                    break;
+                case "b":
+                    i += 4;
+                    update(i);
+                    break;
+                default: break;
+            }
+        }
+        return new Vex.Flow.BoundingBox(posX + xmin * scale, posY - ymin * scale, (xmax - xmin) * scale, (ymin - ymax) * scale);
+    };
+    MeasureSizeCalculator.getKeySignatureBoundingBox = function (sig) {
+        // FIXME: Maybe use Vex.Flow.keySignature(this.keySpec);
+        var stave = sig.getStave();
+        var width = sig.getWidth();
+        var maxLine = 1;
+        var minLine = 1;
+        for (var _i = 0, _a = sig.accList; _i < _a.length; _i++) {
+            var acc = _a[_i];
+            maxLine = Math.max(acc.line, maxLine);
+            minLine = Math.min(acc.line, minLine);
+        }
+        var y = sig.getStave().getYForLine(minLine);
+        var height = stave.getSpacingBetweenLines() * (maxLine - minLine);
+        var x = 0; // FIXME
+        return new Vex.Flow.BoundingBox(x, y, width, height);
+    };
+    MeasureSizeCalculator.prototype.getWidth = function () {
+        // begin_modifiers + voices + end_modifiers
+        return this.offsetLeft + this.voicesWidth + this.offsetRight;
+        // = stave.end_x - stave.x
+    };
+    MeasureSizeCalculator.prototype.getHeight = function () {
+        // FIXME this formula does not take into account
+        // other things like staves and ties!
+        return this.stave.getSpacingBetweenLines()
+            * (this.topBorder - this.bottomBorder);
+    };
+    // The following methods return a number
+    // where 0 is the upper line of the stave.
+    MeasureSizeCalculator.prototype.getTopBorder = function () {
+        return this.topBorder;
+    };
+    MeasureSizeCalculator.prototype.getBottomBorder = function () {
+        return this.bottomBorder;
+    };
+    MeasureSizeCalculator.prototype.format = function () {
+        var stave = this.stave;
+        var voices = this.voices;
+        var voicesBoundingBox;
+        var bb;
+        // Compute widths
+        this.voicesWidth = this.formatter.minTotalWidth;
+        stave.setWidth(this.voicesWidth);
+        stave.format();
+        this.offsetLeft = stave.getNoteStartX() - stave.x;
+        this.offsetRight = stave.end_x - stave.getWidth() - stave.start_x;
+        // Compute heights
+        // Height is:
+        //// height of StaveModifiers + BoundingBox of notes + height of NoteMod's
+        for (var i = 0; i < this.voices.length; i++) {
+            voices[i].setStave(stave);
+            bb = voices[i].getBoundingBox();
+            if (voicesBoundingBox === undefined) {
+                voicesBoundingBox = bb;
+            }
+            else {
+                voicesBoundingBox = voicesBoundingBox.mergeWith(bb);
+            }
+        }
+        // TODO voicesBoundingBox.getW() should be similar to this.voicesWidth?
+        //console.log("this.width", this.voicesWidth);
+        //console.log("voicesBB", voicesBoundingBox.getW());
+        //this.height = voicesBoundingBox.getH(); FIXME
+        // Consider clefs
+        var clefs = stave.getModifiers(Vex.Flow.Modifier.Position.LEFT, Vex.Flow.Clef.category);
+        for (var _i = 0, clefs_1 = clefs; _i < clefs_1.length; _i++) {
+            var clef = clefs_1[_i];
+            voicesBoundingBox = voicesBoundingBox.mergeWith(MeasureSizeCalculator.getClefBoundingBox(clef));
+        }
+        this.topBorder = Math.min(0, Math.floor(stave.getLineForY(voicesBoundingBox.getY())));
+        this.bottomBorder = Math.max(stave.getNumLines(), Math.ceil(stave.getLineForY(voicesBoundingBox.getY() + voicesBoundingBox.getH())));
+    };
+    return MeasureSizeCalculator;
+}());
+exports.MeasureSizeCalculator = MeasureSizeCalculator;

+ 15 - 0
dist/src/MusicalScore/Exceptions.d.ts

@@ -0,0 +1,15 @@
+export declare class MusicSheetReadingException implements Error {
+    name: string;
+    message: string;
+    constructor(message: string, e?: Error);
+}
+export declare class ArgumentOutOfRangeException implements Error {
+    name: string;
+    message: string;
+    constructor(message: string);
+}
+export declare class InvalidEnumArgumentException implements Error {
+    name: string;
+    message: string;
+    constructor(message: string);
+}

+ 27 - 0
dist/src/MusicalScore/Exceptions.js

@@ -0,0 +1,27 @@
+"use strict";
+var MusicSheetReadingException = (function () {
+    function MusicSheetReadingException(message, e) {
+        //super(message);
+        this.message = message;
+        if (e !== undefined) {
+            this.message += " " + e.toString();
+        }
+    }
+    return MusicSheetReadingException;
+}());
+exports.MusicSheetReadingException = MusicSheetReadingException;
+var ArgumentOutOfRangeException = (function () {
+    function ArgumentOutOfRangeException(message) {
+        //super(message);
+        this.message = message;
+    }
+    return ArgumentOutOfRangeException;
+}());
+exports.ArgumentOutOfRangeException = ArgumentOutOfRangeException;
+var InvalidEnumArgumentException = (function () {
+    function InvalidEnumArgumentException(message) {
+        this.message = message;
+    }
+    return InvalidEnumArgumentException;
+}());
+exports.InvalidEnumArgumentException = InvalidEnumArgumentException;

+ 7 - 0
dist/src/MusicalScore/Graphical/AbstractGraphicalInstruction.d.ts

@@ -0,0 +1,7 @@
+import { GraphicalStaffEntry } from "./GraphicalStaffEntry";
+import { GraphicalObject } from "./GraphicalObject";
+export declare abstract class AbstractGraphicalInstruction extends GraphicalObject {
+    protected parent: GraphicalStaffEntry;
+    constructor(parent: GraphicalStaffEntry);
+    Parent: GraphicalStaffEntry;
+}

+ 26 - 0
dist/src/MusicalScore/Graphical/AbstractGraphicalInstruction.js

@@ -0,0 +1,26 @@
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var GraphicalObject_1 = require("./GraphicalObject");
+var AbstractGraphicalInstruction = (function (_super) {
+    __extends(AbstractGraphicalInstruction, _super);
+    function AbstractGraphicalInstruction(parent) {
+        _super.call(this);
+        this.parent = parent;
+    }
+    Object.defineProperty(AbstractGraphicalInstruction.prototype, "Parent", {
+        get: function () {
+            return this.parent;
+        },
+        set: function (value) {
+            this.parent = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    return AbstractGraphicalInstruction;
+}(GraphicalObject_1.GraphicalObject));
+exports.AbstractGraphicalInstruction = AbstractGraphicalInstruction;

+ 16 - 0
dist/src/MusicalScore/Graphical/AccidentalCalculator.d.ts

@@ -0,0 +1,16 @@
+import { IGraphicalSymbolFactory } from "../Interfaces/IGraphicalSymbolFactory";
+import { KeyInstruction } from "../VoiceData/Instructions/KeyInstruction";
+import { GraphicalNote } from "./GraphicalNote";
+import { Pitch } from "../../Common/DataObjects/pitch";
+export declare class AccidentalCalculator {
+    private symbolFactory;
+    private keySignatureNoteAlterationsDict;
+    private currentAlterationsComparedToKeyInstructionDict;
+    private currentInMeasureNoteAlterationsDict;
+    private activeKeyInstruction;
+    constructor(symbolFactory: IGraphicalSymbolFactory);
+    ActiveKeyInstruction: KeyInstruction;
+    doCalculationsAtEndOfMeasure(): void;
+    checkAccidental(graphicalNote: GraphicalNote, pitch: Pitch, grace: boolean, graceScalingFactor: number): void;
+    private reactOnKeyInstructionChange();
+}

+ 72 - 0
dist/src/MusicalScore/Graphical/AccidentalCalculator.js

@@ -0,0 +1,72 @@
+"use strict";
+var pitch_1 = require("../../Common/DataObjects/pitch");
+var KeyInstruction_1 = require("../VoiceData/Instructions/KeyInstruction");
+var Dictionary_1 = require("typescript-collections/dist/lib/Dictionary");
+var AccidentalCalculator = (function () {
+    function AccidentalCalculator(symbolFactory) {
+        this.keySignatureNoteAlterationsDict = new Dictionary_1.default();
+        this.currentAlterationsComparedToKeyInstructionDict = [];
+        this.currentInMeasureNoteAlterationsDict = new Dictionary_1.default();
+        this.symbolFactory = symbolFactory;
+    }
+    Object.defineProperty(AccidentalCalculator.prototype, "ActiveKeyInstruction", {
+        get: function () {
+            return this.activeKeyInstruction;
+        },
+        set: function (value) {
+            this.activeKeyInstruction = value;
+            this.reactOnKeyInstructionChange();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    AccidentalCalculator.prototype.doCalculationsAtEndOfMeasure = function () {
+        this.currentInMeasureNoteAlterationsDict.clear();
+        for (var _i = 0, _a = this.keySignatureNoteAlterationsDict.keys(); _i < _a.length; _i++) {
+            var key = _a[_i];
+            this.currentInMeasureNoteAlterationsDict.setValue(key, this.keySignatureNoteAlterationsDict.getValue(key));
+        }
+    };
+    AccidentalCalculator.prototype.checkAccidental = function (graphicalNote, pitch, grace, graceScalingFactor) {
+        if (pitch === undefined) {
+            return;
+        }
+        var pitchKey = pitch.FundamentalNote + pitch.Octave * 12;
+        var pitchKeyGivenInMeasureDict = this.currentInMeasureNoteAlterationsDict.containsKey(pitchKey);
+        if ((pitchKeyGivenInMeasureDict && this.currentInMeasureNoteAlterationsDict.getValue(pitchKey) !== pitch.Accidental)
+            || (!pitchKeyGivenInMeasureDict && pitch.Accidental !== pitch_1.AccidentalEnum.NONE)) {
+            if (this.currentAlterationsComparedToKeyInstructionDict.indexOf(pitchKey) === -1) {
+                this.currentAlterationsComparedToKeyInstructionDict.push(pitchKey);
+            }
+            this.currentInMeasureNoteAlterationsDict.setValue(pitchKey, pitch.Accidental);
+            this.symbolFactory.addGraphicalAccidental(graphicalNote, pitch, grace, graceScalingFactor);
+        }
+        else if (this.currentAlterationsComparedToKeyInstructionDict.indexOf(pitchKey) !== -1
+            && ((pitchKeyGivenInMeasureDict && this.currentInMeasureNoteAlterationsDict.getValue(pitchKey) !== pitch.Accidental)
+                || (!pitchKeyGivenInMeasureDict && pitch.Accidental === pitch_1.AccidentalEnum.NONE))) {
+            delete this.currentAlterationsComparedToKeyInstructionDict[pitchKey];
+            this.currentInMeasureNoteAlterationsDict.setValue(pitchKey, pitch.Accidental);
+            this.symbolFactory.addGraphicalAccidental(graphicalNote, pitch, grace, graceScalingFactor);
+        }
+    };
+    AccidentalCalculator.prototype.reactOnKeyInstructionChange = function () {
+        var noteEnums = KeyInstruction_1.KeyInstruction.getNoteEnumList(this.activeKeyInstruction);
+        var keyAccidentalType;
+        if (this.activeKeyInstruction.Key > 0) {
+            keyAccidentalType = pitch_1.AccidentalEnum.SHARP;
+        }
+        else {
+            keyAccidentalType = pitch_1.AccidentalEnum.FLAT;
+        }
+        this.keySignatureNoteAlterationsDict.clear();
+        this.currentAlterationsComparedToKeyInstructionDict.length = 0;
+        for (var octave = -9; octave < 9; octave++) {
+            for (var i = 0; i < noteEnums.length; i++) {
+                this.keySignatureNoteAlterationsDict.setValue(noteEnums[i] + octave * 12, keyAccidentalType);
+            }
+        }
+        this.doCalculationsAtEndOfMeasure();
+    };
+    return AccidentalCalculator;
+}());
+exports.AccidentalCalculator = AccidentalCalculator;

+ 76 - 0
dist/src/MusicalScore/Graphical/BoundingBox.d.ts

@@ -0,0 +1,76 @@
+import { PointF2D } from "../../Common/DataObjects/PointF2D";
+import { SizeF2D } from "../../Common/DataObjects/SizeF2D";
+import { RectangleF2D } from "../../Common/DataObjects/RectangleF2D";
+export declare class BoundingBox {
+    protected isSymbol: boolean;
+    protected relativePositionHasBeenSet: boolean;
+    protected xBordersHaveBeenSet: boolean;
+    protected yBordersHaveBeenSet: boolean;
+    protected absolutePosition: PointF2D;
+    protected relativePosition: PointF2D;
+    protected size: SizeF2D;
+    protected marginSize: SizeF2D;
+    protected upperLeftCorner: PointF2D;
+    protected upperLeftMarginCorner: PointF2D;
+    protected borderLeft: number;
+    protected borderRight: number;
+    protected borderTop: number;
+    protected borderBottom: number;
+    protected borderMarginLeft: number;
+    protected borderMarginRight: number;
+    protected borderMarginTop: number;
+    protected borderMarginBottom: number;
+    protected boundingRectangle: RectangleF2D;
+    protected boundingMarginRectangle: RectangleF2D;
+    protected childElements: BoundingBox[];
+    protected parent: BoundingBox;
+    protected dataObject: Object;
+    constructor(dataObject?: Object, parent?: BoundingBox);
+    RelativePositionHasBeenSet: boolean;
+    XBordersHaveBeenSet: boolean;
+    YBordersHaveBeenSet: boolean;
+    AbsolutePosition: PointF2D;
+    RelativePosition: PointF2D;
+    Size: SizeF2D;
+    MarginSize: SizeF2D;
+    UpperLeftCorner: PointF2D;
+    UpperLeftMarginCorner: PointF2D;
+    BorderLeft: number;
+    BorderRight: number;
+    BorderTop: number;
+    BorderBottom: number;
+    BorderMarginLeft: number;
+    BorderMarginRight: number;
+    BorderMarginTop: number;
+    BorderMarginBottom: number;
+    BoundingRectangle: RectangleF2D;
+    BoundingMarginRectangle: RectangleF2D;
+    ChildElements: BoundingBox[];
+    Parent: BoundingBox;
+    DataObject: Object;
+    setAbsolutePositionFromParent(): void;
+    calculateAbsolutePositionsRecursiveWithoutTopelement(): void;
+    calculateAbsolutePositionsRecursive(x: number, y: number): void;
+    calculateBoundingBox(): void;
+    calculateTopBottomBorders(): void;
+    computeNonOverlappingPositionWithMargin(placementPsi: BoundingBox, direction: ColDirEnum, position: PointF2D): void;
+    collisionDetection(psi: BoundingBox): boolean;
+    liesInsideBorders(psi: BoundingBox): boolean;
+    pointLiesInsideBorders(position: PointF2D): boolean;
+    marginCollisionDetection(psi: BoundingBox): boolean;
+    liesInsideMargins(psi: BoundingBox): boolean;
+    pointLiesInsideMargins(position: PointF2D): boolean;
+    computeNonOverlappingPosition(placementPsi: BoundingBox, direction: ColDirEnum, position: PointF2D): void;
+    getClickedObjectOfType<T>(clickPosition: PointF2D): T;
+    getObjectsInRegion<T>(region: BoundingBox, liesInside?: boolean): T[];
+    protected calculateRectangle(): void;
+    protected calculateMarginRectangle(): void;
+    private calculateMarginPositionAlongDirection(toBePlaced, direction);
+    private calculatePositionAlongDirection(toBePlaced, direction);
+}
+export declare enum ColDirEnum {
+    Left = 0,
+    Right = 1,
+    Up = 2,
+    Down = 3,
+}

+ 595 - 0
dist/src/MusicalScore/Graphical/BoundingBox.js

@@ -0,0 +1,595 @@
+"use strict";
+var Exceptions_1 = require("../Exceptions");
+var PointF2D_1 = require("../../Common/DataObjects/PointF2D");
+var SizeF2D_1 = require("../../Common/DataObjects/SizeF2D");
+var RectangleF2D_1 = require("../../Common/DataObjects/RectangleF2D");
+var BoundingBox = (function () {
+    function BoundingBox(dataObject, parent) {
+        if (dataObject === void 0) { dataObject = undefined; }
+        if (parent === void 0) { parent = undefined; }
+        this.isSymbol = false;
+        this.relativePositionHasBeenSet = false;
+        this.xBordersHaveBeenSet = false;
+        this.yBordersHaveBeenSet = false;
+        this.absolutePosition = new PointF2D_1.PointF2D();
+        this.relativePosition = new PointF2D_1.PointF2D();
+        this.size = new SizeF2D_1.SizeF2D();
+        this.borderLeft = 0;
+        this.borderRight = 0;
+        this.borderTop = 0;
+        this.borderBottom = 0;
+        this.borderMarginLeft = 0;
+        this.borderMarginRight = 0;
+        this.borderMarginTop = 0;
+        this.borderMarginBottom = 0;
+        this.childElements = [];
+        this.parent = parent;
+        this.dataObject = dataObject;
+        this.xBordersHaveBeenSet = false;
+        this.yBordersHaveBeenSet = false;
+    }
+    Object.defineProperty(BoundingBox.prototype, "RelativePositionHasBeenSet", {
+        get: function () {
+            return this.relativePositionHasBeenSet;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "XBordersHaveBeenSet", {
+        get: function () {
+            return this.xBordersHaveBeenSet;
+        },
+        set: function (value) {
+            this.xBordersHaveBeenSet = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "YBordersHaveBeenSet", {
+        get: function () {
+            return this.yBordersHaveBeenSet;
+        },
+        set: function (value) {
+            this.yBordersHaveBeenSet = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "AbsolutePosition", {
+        get: function () {
+            return this.absolutePosition;
+        },
+        set: function (value) {
+            this.absolutePosition = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "RelativePosition", {
+        get: function () {
+            return this.relativePosition;
+        },
+        set: function (value) {
+            this.relativePosition = value;
+            this.relativePositionHasBeenSet = true;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "Size", {
+        get: function () {
+            return this.size;
+        },
+        set: function (value) {
+            this.size = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "MarginSize", {
+        get: function () {
+            return this.marginSize;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "UpperLeftCorner", {
+        get: function () {
+            return this.upperLeftCorner;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "UpperLeftMarginCorner", {
+        get: function () {
+            return this.upperLeftMarginCorner;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "BorderLeft", {
+        get: function () {
+            return this.borderLeft;
+        },
+        set: function (value) {
+            this.borderLeft = value;
+            this.calculateRectangle();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "BorderRight", {
+        get: function () {
+            return this.borderRight;
+        },
+        set: function (value) {
+            this.borderRight = value;
+            this.calculateRectangle();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "BorderTop", {
+        get: function () {
+            return this.borderTop;
+        },
+        set: function (value) {
+            this.borderTop = value;
+            this.calculateRectangle();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "BorderBottom", {
+        get: function () {
+            return this.borderBottom;
+        },
+        set: function (value) {
+            this.borderBottom = value;
+            this.calculateRectangle();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "BorderMarginLeft", {
+        get: function () {
+            return this.borderMarginLeft;
+        },
+        set: function (value) {
+            this.borderMarginLeft = value;
+            this.calculateMarginRectangle();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "BorderMarginRight", {
+        get: function () {
+            return this.borderMarginRight;
+        },
+        set: function (value) {
+            this.borderMarginRight = value;
+            this.calculateMarginRectangle();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "BorderMarginTop", {
+        get: function () {
+            return this.borderMarginTop;
+        },
+        set: function (value) {
+            this.borderMarginTop = value;
+            this.calculateMarginRectangle();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "BorderMarginBottom", {
+        get: function () {
+            return this.borderMarginBottom;
+        },
+        set: function (value) {
+            this.borderMarginBottom = value;
+            this.calculateMarginRectangle();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "BoundingRectangle", {
+        get: function () {
+            return this.boundingRectangle;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "BoundingMarginRectangle", {
+        get: function () {
+            return this.boundingMarginRectangle;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "ChildElements", {
+        get: function () {
+            return this.childElements;
+        },
+        set: function (value) {
+            this.childElements = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "Parent", {
+        get: function () {
+            return this.parent;
+        },
+        set: function (value) {
+            this.parent = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BoundingBox.prototype, "DataObject", {
+        get: function () {
+            return this.dataObject;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    BoundingBox.prototype.setAbsolutePositionFromParent = function () {
+        if (this.parent !== undefined) {
+            this.absolutePosition.x = this.parent.AbsolutePosition.x + this.relativePosition.x;
+            this.absolutePosition.y = this.parent.AbsolutePosition.y + this.relativePosition.y;
+        }
+        else {
+            this.absolutePosition = this.relativePosition;
+        }
+    };
+    BoundingBox.prototype.calculateAbsolutePositionsRecursiveWithoutTopelement = function () {
+        this.absolutePosition.x = 0.0;
+        this.absolutePosition.y = 0.0;
+        for (var idx = 0, len = this.ChildElements.length; idx < len; ++idx) {
+            var child = this.ChildElements[idx];
+            child.calculateAbsolutePositionsRecursive(this.absolutePosition.x, this.absolutePosition.y);
+        }
+    };
+    BoundingBox.prototype.calculateAbsolutePositionsRecursive = function (x, y) {
+        this.absolutePosition.x = this.relativePosition.x + x;
+        this.absolutePosition.y = this.relativePosition.y + y;
+        for (var idx = 0, len = this.ChildElements.length; idx < len; ++idx) {
+            var child = this.ChildElements[idx];
+            child.calculateAbsolutePositionsRecursive(this.absolutePosition.x, this.absolutePosition.y);
+        }
+    };
+    BoundingBox.prototype.calculateBoundingBox = function () {
+        if (this.childElements.length === 0) {
+            return;
+        }
+        for (var idx = 0, len = this.ChildElements.length; idx < len; ++idx) {
+            var childElement = this.ChildElements[idx];
+            childElement.calculateBoundingBox();
+        }
+        var minLeft = Number.MAX_VALUE;
+        var maxRight = Number.MIN_VALUE;
+        var minTop = Number.MAX_VALUE;
+        var maxBottom = Number.MIN_VALUE;
+        var minMarginLeft = Number.MAX_VALUE;
+        var maxMarginRight = Number.MIN_VALUE;
+        var minMarginTop = Number.MAX_VALUE;
+        var maxMarginBottom = Number.MIN_VALUE;
+        if (this.isSymbol) {
+            minLeft = this.borderLeft;
+            maxRight = this.borderRight;
+            minTop = this.borderTop;
+            maxBottom = this.borderBottom;
+            minMarginLeft = this.borderMarginLeft;
+            maxMarginRight = this.borderMarginRight;
+            minMarginTop = this.borderMarginTop;
+            maxMarginBottom = this.borderMarginBottom;
+        }
+        for (var idx = 0, len = this.ChildElements.length; idx < len; ++idx) {
+            var childElement = this.ChildElements[idx];
+            minLeft = Math.min(minLeft, childElement.relativePosition.x + childElement.borderLeft);
+            maxRight = Math.max(maxRight, childElement.relativePosition.x + childElement.borderRight);
+            minTop = Math.min(minTop, childElement.relativePosition.y + childElement.borderTop);
+            maxBottom = Math.max(maxBottom, childElement.relativePosition.y + childElement.borderBottom);
+            minMarginLeft = Math.min(minMarginLeft, childElement.relativePosition.x + childElement.borderMarginLeft);
+            maxMarginRight = Math.max(maxMarginRight, childElement.relativePosition.x + childElement.borderMarginRight);
+            minMarginTop = Math.min(minMarginTop, childElement.relativePosition.y + childElement.borderMarginTop);
+            maxMarginBottom = Math.max(maxMarginBottom, childElement.relativePosition.y + childElement.borderMarginBottom);
+        }
+        this.borderLeft = minLeft;
+        this.borderRight = maxRight;
+        this.borderTop = minTop;
+        this.borderBottom = maxBottom;
+        this.borderMarginLeft = minMarginLeft;
+        this.borderMarginRight = maxMarginRight;
+        this.borderMarginTop = minMarginTop;
+        this.borderMarginBottom = maxMarginBottom;
+        this.calculateRectangle();
+        this.calculateMarginRectangle();
+        this.xBordersHaveBeenSet = true;
+        this.yBordersHaveBeenSet = true;
+    };
+    BoundingBox.prototype.calculateTopBottomBorders = function () {
+        if (this.childElements.length === 0) {
+            return;
+        }
+        for (var idx = 0, len = this.ChildElements.length; idx < len; ++idx) {
+            var childElement = this.ChildElements[idx];
+            childElement.calculateTopBottomBorders();
+        }
+        var minTop = Number.MAX_VALUE;
+        var maxBottom = Number.MIN_VALUE;
+        var minMarginTop = Number.MAX_VALUE;
+        var maxMarginBottom = Number.MIN_VALUE;
+        if (this.yBordersHaveBeenSet) {
+            minTop = this.borderTop;
+            maxBottom = this.borderBottom;
+            minMarginTop = this.borderMarginTop;
+            maxMarginBottom = this.borderMarginBottom;
+        }
+        for (var idx = 0, len = this.ChildElements.length; idx < len; ++idx) {
+            var childElement = this.ChildElements[idx];
+            minTop = Math.min(minTop, childElement.relativePosition.y + childElement.borderTop);
+            maxBottom = Math.max(maxBottom, childElement.relativePosition.y + childElement.borderBottom);
+            minMarginTop = Math.min(minMarginTop, childElement.relativePosition.y + childElement.borderMarginTop);
+            maxMarginBottom = Math.max(maxMarginBottom, childElement.relativePosition.y + childElement.borderMarginBottom);
+        }
+        this.borderTop = minTop;
+        this.borderBottom = maxBottom;
+        this.borderMarginTop = minMarginTop;
+        this.borderMarginBottom = maxMarginBottom;
+        this.calculateRectangle();
+        this.calculateMarginRectangle();
+    };
+    BoundingBox.prototype.computeNonOverlappingPositionWithMargin = function (placementPsi, direction, position) {
+        this.RelativePosition = new PointF2D_1.PointF2D(position.x, position.y);
+        this.setAbsolutePositionFromParent();
+        var currentPosition = 0.0;
+        var hasBeenMoved = false;
+        do {
+            switch (direction) {
+                case ColDirEnum.Left:
+                case ColDirEnum.Right:
+                    currentPosition = this.relativePosition.x;
+                    placementPsi.calculateMarginPositionAlongDirection(this, direction);
+                    hasBeenMoved = Math.abs(currentPosition - this.relativePosition.x) > 0.001;
+                    break;
+                case ColDirEnum.Up:
+                case ColDirEnum.Down:
+                    currentPosition = this.relativePosition.y;
+                    placementPsi.calculateMarginPositionAlongDirection(this, direction);
+                    hasBeenMoved = Math.abs(currentPosition - this.relativePosition.y) > 0.001;
+                    break;
+                default:
+                    throw new Exceptions_1.ArgumentOutOfRangeException("direction");
+            }
+        } while (hasBeenMoved);
+    };
+    BoundingBox.prototype.collisionDetection = function (psi) {
+        var overlapWidth = Math.min(this.AbsolutePosition.x + this.borderRight, psi.absolutePosition.x + psi.borderRight)
+            - Math.max(this.AbsolutePosition.x + this.borderLeft, psi.absolutePosition.x + psi.borderLeft);
+        var overlapHeight = Math.min(this.AbsolutePosition.y + this.borderBottom, psi.absolutePosition.y + psi.borderBottom)
+            - Math.max(this.AbsolutePosition.y + this.borderTop, psi.absolutePosition.y + psi.borderTop);
+        if (overlapWidth > 0 && overlapHeight > 0) {
+            return true;
+        }
+        return false;
+    };
+    BoundingBox.prototype.liesInsideBorders = function (psi) {
+        var leftBorderInside = (this.AbsolutePosition.x + this.borderLeft) <= (psi.absolutePosition.x + psi.borderLeft)
+            && (psi.absolutePosition.x + psi.borderLeft) <= (this.AbsolutePosition.x + this.borderRight);
+        var rightBorderInside = (this.AbsolutePosition.x + this.borderLeft) <= (psi.absolutePosition.x + psi.borderRight)
+            && (psi.absolutePosition.x + psi.borderRight) <= (this.AbsolutePosition.x + this.borderRight);
+        if (leftBorderInside && rightBorderInside) {
+            var topBorderInside = (this.AbsolutePosition.y + this.borderTop) <= (psi.absolutePosition.y + psi.borderTop)
+                && (psi.absolutePosition.y + psi.borderTop) <= (this.AbsolutePosition.y + this.borderBottom);
+            var bottomBorderInside = (this.AbsolutePosition.y + this.borderTop) <= (psi.absolutePosition.y + psi.borderBottom)
+                && (psi.absolutePosition.y + psi.borderBottom) <= (this.AbsolutePosition.y + this.borderBottom);
+            if (topBorderInside && bottomBorderInside) {
+                return true;
+            }
+        }
+        return false;
+    };
+    BoundingBox.prototype.pointLiesInsideBorders = function (position) {
+        var xInside = (this.AbsolutePosition.x + this.borderLeft) <= position.x && position.x <= (this.AbsolutePosition.x + this.borderRight);
+        if (xInside) {
+            var yInside = (this.AbsolutePosition.y + this.borderTop) <= position.y && position.y <= (this.AbsolutePosition.y + this.borderBottom);
+            if (yInside) {
+                return true;
+            }
+        }
+        return false;
+    };
+    BoundingBox.prototype.marginCollisionDetection = function (psi) {
+        var overlapWidth = Math.min(this.AbsolutePosition.x + this.borderMarginRight, psi.absolutePosition.x + psi.borderMarginRight)
+            - Math.max(this.AbsolutePosition.x + this.borderMarginLeft, psi.absolutePosition.x + psi.borderMarginLeft);
+        var overlapHeight = Math.min(this.AbsolutePosition.y + this.borderMarginBottom, psi.absolutePosition.y + psi.borderMarginBottom)
+            - Math.max(this.AbsolutePosition.y + this.borderMarginTop, psi.absolutePosition.y + psi.borderMarginTop);
+        if (overlapWidth > 0 && overlapHeight > 0) {
+            return true;
+        }
+        return false;
+    };
+    BoundingBox.prototype.liesInsideMargins = function (psi) {
+        var leftMarginInside = (this.AbsolutePosition.x + this.borderMarginLeft) <= (psi.absolutePosition.x + psi.borderMarginLeft)
+            && (psi.absolutePosition.x + psi.borderMarginLeft) <= (this.AbsolutePosition.x + this.borderMarginRight);
+        var rightMarginInside = (this.AbsolutePosition.x + this.borderMarginLeft) <= (psi.absolutePosition.x + psi.borderMarginRight)
+            && (psi.absolutePosition.x + psi.borderMarginRight) <= (this.AbsolutePosition.x + this.borderMarginRight);
+        if (leftMarginInside && rightMarginInside) {
+            var topMarginInside = (this.AbsolutePosition.y + this.borderMarginTop) <= (psi.absolutePosition.y + psi.borderMarginTop)
+                && (psi.absolutePosition.y + psi.borderMarginTop) <= (this.AbsolutePosition.y + this.borderMarginBottom);
+            var bottomMarginInside = (this.AbsolutePosition.y + this.borderMarginTop) <= (psi.absolutePosition.y + psi.borderMarginBottom)
+                && (psi.absolutePosition.y + psi.borderMarginBottom) <= (this.AbsolutePosition.y + this.borderMarginBottom);
+            if (topMarginInside && bottomMarginInside) {
+                return true;
+            }
+        }
+        return false;
+    };
+    BoundingBox.prototype.pointLiesInsideMargins = function (position) {
+        var xInside = (this.AbsolutePosition.x + this.borderMarginLeft) <= position.x
+            && position.x <= (this.AbsolutePosition.x + this.borderMarginRight);
+        if (xInside) {
+            var yInside = (this.AbsolutePosition.y + this.borderMarginTop) <= position.y
+                && position.y <= (this.AbsolutePosition.y + this.borderMarginBottom);
+            if (yInside) {
+                return true;
+            }
+        }
+        return false;
+    };
+    BoundingBox.prototype.computeNonOverlappingPosition = function (placementPsi, direction, position) {
+        this.RelativePosition = new PointF2D_1.PointF2D(position.x, position.y);
+        this.setAbsolutePositionFromParent();
+        var currentPosition = 0.0;
+        var hasBeenMoved = false;
+        do {
+            switch (direction) {
+                case ColDirEnum.Left:
+                case ColDirEnum.Right:
+                    currentPosition = this.relativePosition.x;
+                    placementPsi.calculatePositionAlongDirection(this, direction);
+                    hasBeenMoved = Math.abs(currentPosition - this.relativePosition.x) > 0.0001;
+                    break;
+                case ColDirEnum.Up:
+                case ColDirEnum.Down:
+                    currentPosition = this.relativePosition.y;
+                    placementPsi.calculatePositionAlongDirection(this, direction);
+                    hasBeenMoved = Math.abs(currentPosition - this.relativePosition.y) > 0.0001;
+                    break;
+                default:
+                    throw new Exceptions_1.ArgumentOutOfRangeException("direction");
+            }
+        } while (hasBeenMoved);
+    };
+    BoundingBox.prototype.getClickedObjectOfType = function (clickPosition) {
+        var obj = this.dataObject;
+        if (this.pointLiesInsideBorders(clickPosition) && (obj !== undefined)) {
+            return obj;
+        }
+        for (var idx = 0, len = this.childElements.length; idx < len; ++idx) {
+            var psi = this.childElements[idx];
+            var innerObject = psi.getClickedObjectOfType(clickPosition);
+            if (innerObject !== undefined) {
+                return innerObject;
+            }
+        }
+        return undefined;
+    };
+    BoundingBox.prototype.getObjectsInRegion = function (region, liesInside) {
+        if (liesInside === void 0) { liesInside = true; }
+        if (this.dataObject !== undefined) {
+            if (liesInside) {
+                if (region.liesInsideBorders(this)) {
+                    return [this.dataObject];
+                }
+            }
+            else {
+                if (region.collisionDetection(this)) {
+                    return [this.dataObject];
+                }
+            }
+        }
+        var result = [];
+        for (var _i = 0, _a = this.childElements; _i < _a.length; _i++) {
+            var child = _a[_i];
+            result.concat(child.getObjectsInRegion(region, liesInside));
+        }
+        return result;
+        //return this.childElements.SelectMany(psi => psi.getObjectsInRegion<T>(region, liesInside));
+    };
+    BoundingBox.prototype.calculateRectangle = function () {
+        this.upperLeftCorner = new PointF2D_1.PointF2D(this.borderLeft, this.borderTop);
+        this.size = new SizeF2D_1.SizeF2D(this.borderRight - this.borderLeft, this.borderBottom - this.borderTop);
+        this.boundingRectangle = RectangleF2D_1.RectangleF2D.createFromLocationAndSize(this.upperLeftCorner, this.size);
+    };
+    BoundingBox.prototype.calculateMarginRectangle = function () {
+        this.upperLeftMarginCorner = new PointF2D_1.PointF2D(this.borderMarginLeft, this.borderMarginTop);
+        this.marginSize = new SizeF2D_1.SizeF2D(this.borderMarginRight - this.borderMarginLeft, this.borderMarginBottom - this.borderMarginTop);
+        this.boundingMarginRectangle = RectangleF2D_1.RectangleF2D.createFromLocationAndSize(this.upperLeftMarginCorner, this.marginSize);
+    };
+    BoundingBox.prototype.calculateMarginPositionAlongDirection = function (toBePlaced, direction) {
+        if (this === toBePlaced) {
+            return;
+        }
+        if (this.isSymbol && this.marginCollisionDetection(toBePlaced)) {
+            var shiftDistance = 0;
+            switch (direction) {
+                case ColDirEnum.Left:
+                    shiftDistance = (this.absolutePosition.x + this.borderMarginLeft) - (toBePlaced.absolutePosition.x + toBePlaced.borderMarginRight);
+                    toBePlaced.relativePosition.x += shiftDistance;
+                    toBePlaced.absolutePosition.x += shiftDistance;
+                    return;
+                case ColDirEnum.Right:
+                    shiftDistance = (this.absolutePosition.x + this.borderMarginRight) - (toBePlaced.absolutePosition.x + toBePlaced.borderMarginLeft);
+                    toBePlaced.relativePosition.x += shiftDistance;
+                    toBePlaced.absolutePosition.x += shiftDistance;
+                    return;
+                case ColDirEnum.Up:
+                    shiftDistance = (this.absolutePosition.y + this.borderMarginTop) - (toBePlaced.absolutePosition.y + toBePlaced.borderMarginBottom);
+                    toBePlaced.relativePosition.y += shiftDistance;
+                    toBePlaced.absolutePosition.y += shiftDistance;
+                    return;
+                case ColDirEnum.Down:
+                    shiftDistance = (this.absolutePosition.y + this.borderMarginBottom) - (toBePlaced.absolutePosition.y + toBePlaced.borderMarginTop);
+                    toBePlaced.relativePosition.y += shiftDistance;
+                    toBePlaced.absolutePosition.y += shiftDistance;
+                    return;
+                default:
+                    throw new Exceptions_1.ArgumentOutOfRangeException("direction");
+            }
+        }
+        for (var idx = 0, len = this.ChildElements.length; idx < len; ++idx) {
+            var childElement = this.ChildElements[idx];
+            childElement.calculateMarginPositionAlongDirection(toBePlaced, direction);
+        }
+    };
+    BoundingBox.prototype.calculatePositionAlongDirection = function (toBePlaced, direction) {
+        if (this === toBePlaced) {
+            return;
+        }
+        if (this.isSymbol && this.collisionDetection(toBePlaced)) {
+            var shiftDistance = void 0;
+            switch (direction) {
+                case ColDirEnum.Left:
+                    shiftDistance = (this.absolutePosition.x + this.borderLeft) - (toBePlaced.absolutePosition.x + toBePlaced.borderRight);
+                    toBePlaced.relativePosition.x += shiftDistance;
+                    toBePlaced.absolutePosition.x += shiftDistance;
+                    return;
+                case ColDirEnum.Right:
+                    shiftDistance = (this.absolutePosition.x + this.borderRight) - (toBePlaced.absolutePosition.x + toBePlaced.borderLeft);
+                    toBePlaced.relativePosition.x += shiftDistance;
+                    toBePlaced.absolutePosition.x += shiftDistance;
+                    return;
+                case ColDirEnum.Up:
+                    shiftDistance = (this.absolutePosition.y + this.borderTop) - (toBePlaced.absolutePosition.y + toBePlaced.borderBottom);
+                    toBePlaced.relativePosition.y += shiftDistance;
+                    toBePlaced.absolutePosition.y += shiftDistance;
+                    return;
+                case ColDirEnum.Down:
+                    shiftDistance = (this.absolutePosition.y + this.borderBottom) - (toBePlaced.absolutePosition.y + toBePlaced.borderTop);
+                    toBePlaced.relativePosition.y += shiftDistance;
+                    toBePlaced.absolutePosition.y += shiftDistance;
+                    return;
+                default:
+                    throw new Exceptions_1.ArgumentOutOfRangeException("direction");
+            }
+        }
+        for (var idx = 0, len = this.ChildElements.length; idx < len; ++idx) {
+            var childElement = this.ChildElements[idx];
+            childElement.calculatePositionAlongDirection(toBePlaced, direction);
+        }
+    };
+    return BoundingBox;
+}());
+exports.BoundingBox = BoundingBox;
+(function (ColDirEnum) {
+    ColDirEnum[ColDirEnum["Left"] = 0] = "Left";
+    ColDirEnum[ColDirEnum["Right"] = 1] = "Right";
+    ColDirEnum[ColDirEnum["Up"] = 2] = "Up";
+    ColDirEnum[ColDirEnum["Down"] = 3] = "Down";
+})(exports.ColDirEnum || (exports.ColDirEnum = {}));
+var ColDirEnum = exports.ColDirEnum;

+ 4 - 0
dist/src/MusicalScore/Graphical/Clickable.d.ts

@@ -0,0 +1,4 @@
+import { GraphicalObject } from "./GraphicalObject";
+export declare class Clickable extends GraphicalObject {
+    dataObject: Object;
+}

+ 15 - 0
dist/src/MusicalScore/Graphical/Clickable.js

@@ -0,0 +1,15 @@
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var GraphicalObject_1 = require("./GraphicalObject");
+var Clickable = (function (_super) {
+    __extends(Clickable, _super);
+    function Clickable() {
+        _super.apply(this, arguments);
+    }
+    return Clickable;
+}(GraphicalObject_1.GraphicalObject));
+exports.Clickable = Clickable;

+ 61 - 0
dist/src/MusicalScore/Graphical/DrawingEnums.d.ts

@@ -0,0 +1,61 @@
+export declare enum OutlineAndFillStyleEnum {
+    BaseWritingColor = 0,
+    FollowingCursor = 1,
+    AlternativeFollowingCursor = 2,
+    PlaybackCursor = 3,
+    Highlighted = 4,
+    ErrorUnderlay = 5,
+    Selected = 6,
+    SelectionSymbol = 7,
+    DebugColor1 = 8,
+    DebugColor2 = 9,
+    DebugColor3 = 10,
+    SplitScreenDivision = 11,
+    GreyTransparentOverlay = 12,
+    MarkedArea1 = 13,
+    MarkedArea2 = 14,
+    MarkedArea3 = 15,
+    MarkedArea4 = 16,
+    MarkedArea5 = 17,
+    MarkedArea6 = 18,
+    MarkedArea7 = 19,
+    MarkedArea8 = 20,
+    MarkedArea9 = 21,
+    MarkedArea10 = 22,
+    Comment1 = 23,
+    Comment2 = 24,
+    Comment3 = 25,
+    Comment4 = 26,
+    Comment5 = 27,
+    Comment6 = 28,
+    Comment7 = 29,
+    Comment8 = 30,
+    Comment9 = 31,
+    Comment10 = 32,
+}
+export declare enum StyleSets {
+    MarkedArea = 0,
+    Comment = 1,
+}
+export declare enum GraphicalLayers {
+    Background = 0,
+    Highlight = 1,
+    MeasureError = 2,
+    SelectionSymbol = 3,
+    Cursor = 4,
+    PSI_Debug = 5,
+    Notes = 6,
+    Comment = 7,
+    Debug_above = 8,
+}
+export declare enum NoteState {
+    Normal = 0,
+    Selected = 1,
+    Follow_Confirmed = 2,
+    QFeedback_NotFound = 3,
+    QFeedback_OK = 4,
+    QFeedback_Perfect = 5,
+    Debug1 = 6,
+    Debug2 = 7,
+    Debug3 = 8,
+}

+ 66 - 0
dist/src/MusicalScore/Graphical/DrawingEnums.js

@@ -0,0 +1,66 @@
+"use strict";
+(function (OutlineAndFillStyleEnum) {
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["BaseWritingColor"] = 0] = "BaseWritingColor";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["FollowingCursor"] = 1] = "FollowingCursor";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["AlternativeFollowingCursor"] = 2] = "AlternativeFollowingCursor";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["PlaybackCursor"] = 3] = "PlaybackCursor";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["Highlighted"] = 4] = "Highlighted";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["ErrorUnderlay"] = 5] = "ErrorUnderlay";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["Selected"] = 6] = "Selected";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["SelectionSymbol"] = 7] = "SelectionSymbol";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["DebugColor1"] = 8] = "DebugColor1";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["DebugColor2"] = 9] = "DebugColor2";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["DebugColor3"] = 10] = "DebugColor3";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["SplitScreenDivision"] = 11] = "SplitScreenDivision";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["GreyTransparentOverlay"] = 12] = "GreyTransparentOverlay";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["MarkedArea1"] = 13] = "MarkedArea1";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["MarkedArea2"] = 14] = "MarkedArea2";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["MarkedArea3"] = 15] = "MarkedArea3";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["MarkedArea4"] = 16] = "MarkedArea4";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["MarkedArea5"] = 17] = "MarkedArea5";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["MarkedArea6"] = 18] = "MarkedArea6";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["MarkedArea7"] = 19] = "MarkedArea7";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["MarkedArea8"] = 20] = "MarkedArea8";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["MarkedArea9"] = 21] = "MarkedArea9";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["MarkedArea10"] = 22] = "MarkedArea10";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["Comment1"] = 23] = "Comment1";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["Comment2"] = 24] = "Comment2";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["Comment3"] = 25] = "Comment3";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["Comment4"] = 26] = "Comment4";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["Comment5"] = 27] = "Comment5";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["Comment6"] = 28] = "Comment6";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["Comment7"] = 29] = "Comment7";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["Comment8"] = 30] = "Comment8";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["Comment9"] = 31] = "Comment9";
+    OutlineAndFillStyleEnum[OutlineAndFillStyleEnum["Comment10"] = 32] = "Comment10";
+})(exports.OutlineAndFillStyleEnum || (exports.OutlineAndFillStyleEnum = {}));
+var OutlineAndFillStyleEnum = exports.OutlineAndFillStyleEnum;
+(function (StyleSets) {
+    StyleSets[StyleSets["MarkedArea"] = 0] = "MarkedArea";
+    StyleSets[StyleSets["Comment"] = 1] = "Comment";
+})(exports.StyleSets || (exports.StyleSets = {}));
+var StyleSets = exports.StyleSets;
+(function (GraphicalLayers) {
+    GraphicalLayers[GraphicalLayers["Background"] = 0] = "Background";
+    GraphicalLayers[GraphicalLayers["Highlight"] = 1] = "Highlight";
+    GraphicalLayers[GraphicalLayers["MeasureError"] = 2] = "MeasureError";
+    GraphicalLayers[GraphicalLayers["SelectionSymbol"] = 3] = "SelectionSymbol";
+    GraphicalLayers[GraphicalLayers["Cursor"] = 4] = "Cursor";
+    GraphicalLayers[GraphicalLayers["PSI_Debug"] = 5] = "PSI_Debug";
+    GraphicalLayers[GraphicalLayers["Notes"] = 6] = "Notes";
+    GraphicalLayers[GraphicalLayers["Comment"] = 7] = "Comment";
+    GraphicalLayers[GraphicalLayers["Debug_above"] = 8] = "Debug_above";
+})(exports.GraphicalLayers || (exports.GraphicalLayers = {}));
+var GraphicalLayers = exports.GraphicalLayers;
+(function (NoteState) {
+    NoteState[NoteState["Normal"] = 0] = "Normal";
+    NoteState[NoteState["Selected"] = 1] = "Selected";
+    NoteState[NoteState["Follow_Confirmed"] = 2] = "Follow_Confirmed";
+    NoteState[NoteState["QFeedback_NotFound"] = 3] = "QFeedback_NotFound";
+    NoteState[NoteState["QFeedback_OK"] = 4] = "QFeedback_OK";
+    NoteState[NoteState["QFeedback_Perfect"] = 5] = "QFeedback_Perfect";
+    NoteState[NoteState["Debug1"] = 6] = "Debug1";
+    NoteState[NoteState["Debug2"] = 7] = "Debug2";
+    NoteState[NoteState["Debug3"] = 8] = "Debug3";
+})(exports.NoteState || (exports.NoteState = {}));
+var NoteState = exports.NoteState;

+ 24 - 0
dist/src/MusicalScore/Graphical/DrawingMode.d.ts

@@ -0,0 +1,24 @@
+export declare enum DrawingMode {
+    All = 0,
+    NoOverlays = 1,
+    Leadsheet = 2,
+}
+export declare enum MusicSymbolDrawingStyle {
+    Normal = 0,
+    Disabled = 1,
+    Selected = 2,
+    Clickable = 3,
+    PlaybackSymbols = 4,
+    FollowSymbols = 5,
+    QFeedbackNotFound = 6,
+    QFeedbackOk = 7,
+    QFeedbackPerfect = 8,
+    Debug1 = 9,
+    Debug2 = 10,
+    Debug3 = 11,
+}
+export declare enum PhonicScoreModes {
+    Following = 0,
+    Midi = 1,
+    Manual = 2,
+}

+ 28 - 0
dist/src/MusicalScore/Graphical/DrawingMode.js

@@ -0,0 +1,28 @@
+"use strict";
+(function (DrawingMode) {
+    DrawingMode[DrawingMode["All"] = 0] = "All";
+    DrawingMode[DrawingMode["NoOverlays"] = 1] = "NoOverlays";
+    DrawingMode[DrawingMode["Leadsheet"] = 2] = "Leadsheet";
+})(exports.DrawingMode || (exports.DrawingMode = {}));
+var DrawingMode = exports.DrawingMode;
+(function (MusicSymbolDrawingStyle) {
+    MusicSymbolDrawingStyle[MusicSymbolDrawingStyle["Normal"] = 0] = "Normal";
+    MusicSymbolDrawingStyle[MusicSymbolDrawingStyle["Disabled"] = 1] = "Disabled";
+    MusicSymbolDrawingStyle[MusicSymbolDrawingStyle["Selected"] = 2] = "Selected";
+    MusicSymbolDrawingStyle[MusicSymbolDrawingStyle["Clickable"] = 3] = "Clickable";
+    MusicSymbolDrawingStyle[MusicSymbolDrawingStyle["PlaybackSymbols"] = 4] = "PlaybackSymbols";
+    MusicSymbolDrawingStyle[MusicSymbolDrawingStyle["FollowSymbols"] = 5] = "FollowSymbols";
+    MusicSymbolDrawingStyle[MusicSymbolDrawingStyle["QFeedbackNotFound"] = 6] = "QFeedbackNotFound";
+    MusicSymbolDrawingStyle[MusicSymbolDrawingStyle["QFeedbackOk"] = 7] = "QFeedbackOk";
+    MusicSymbolDrawingStyle[MusicSymbolDrawingStyle["QFeedbackPerfect"] = 8] = "QFeedbackPerfect";
+    MusicSymbolDrawingStyle[MusicSymbolDrawingStyle["Debug1"] = 9] = "Debug1";
+    MusicSymbolDrawingStyle[MusicSymbolDrawingStyle["Debug2"] = 10] = "Debug2";
+    MusicSymbolDrawingStyle[MusicSymbolDrawingStyle["Debug3"] = 11] = "Debug3";
+})(exports.MusicSymbolDrawingStyle || (exports.MusicSymbolDrawingStyle = {}));
+var MusicSymbolDrawingStyle = exports.MusicSymbolDrawingStyle;
+(function (PhonicScoreModes) {
+    PhonicScoreModes[PhonicScoreModes["Following"] = 0] = "Following";
+    PhonicScoreModes[PhonicScoreModes["Midi"] = 1] = "Midi";
+    PhonicScoreModes[PhonicScoreModes["Manual"] = 2] = "Manual";
+})(exports.PhonicScoreModes || (exports.PhonicScoreModes = {}));
+var PhonicScoreModes = exports.PhonicScoreModes;

+ 14 - 0
dist/src/MusicalScore/Graphical/DrawingParameters.d.ts

@@ -0,0 +1,14 @@
+export declare class DrawingParameters {
+    drawHighlights: boolean;
+    drawErrors: boolean;
+    drawSelectionStartSymbol: boolean;
+    drawSelectionEndSymbol: boolean;
+    drawCursors: boolean;
+    drawActivitySymbols: boolean;
+    drawScrollIndicator: boolean;
+    drawComments: boolean;
+    drawMarkedAreas: boolean;
+    setForAllOn(): void;
+    setForThumbmail(): void;
+    setForLeadsheet(): void;
+}

+ 40 - 0
dist/src/MusicalScore/Graphical/DrawingParameters.js

@@ -0,0 +1,40 @@
+"use strict";
+var DrawingParameters = (function () {
+    function DrawingParameters() {
+    }
+    DrawingParameters.prototype.setForAllOn = function () {
+        this.drawHighlights = true;
+        this.drawErrors = true;
+        this.drawSelectionStartSymbol = true;
+        this.drawSelectionEndSymbol = true;
+        this.drawCursors = true;
+        this.drawActivitySymbols = true;
+        this.drawScrollIndicator = true;
+        this.drawComments = true;
+        this.drawMarkedAreas = true;
+    };
+    DrawingParameters.prototype.setForThumbmail = function () {
+        this.drawHighlights = false;
+        this.drawErrors = false;
+        this.drawSelectionStartSymbol = false;
+        this.drawSelectionStartSymbol = false;
+        this.drawCursors = false;
+        this.drawActivitySymbols = false;
+        this.drawScrollIndicator = false;
+        this.drawComments = true;
+        this.drawMarkedAreas = true;
+    };
+    DrawingParameters.prototype.setForLeadsheet = function () {
+        this.drawHighlights = false;
+        this.drawErrors = false;
+        this.drawSelectionStartSymbol = true;
+        this.drawSelectionEndSymbol = true;
+        this.drawCursors = true;
+        this.drawActivitySymbols = false;
+        this.drawScrollIndicator = true;
+        this.drawComments = true;
+        this.drawMarkedAreas = true;
+    };
+    return DrawingParameters;
+}());
+exports.DrawingParameters = DrawingParameters;

+ 279 - 0
dist/src/MusicalScore/Graphical/EngravingRules.d.ts

@@ -0,0 +1,279 @@
+import { PagePlacementEnum } from "./GraphicalMusicPage";
+export declare class EngravingRules {
+    private static rules;
+    private static unit;
+    private samplingUnit;
+    private staccatoShorteningFactor;
+    private sheetTitleHeight;
+    private sheetSubtitleHeight;
+    private sheetMinimumDistanceBetweenTitleAndSubtitle;
+    private sheetComposerHeight;
+    private sheetAuthorHeight;
+    private pagePlacementEnum;
+    private pageHeight;
+    private pageTopMargin;
+    private pageBottomMargin;
+    private pageLeftMargin;
+    private pageRightMargin;
+    private titleTopDistance;
+    private titleBottomDistance;
+    private systemDistance;
+    private systemLeftMargin;
+    private systemRightMargin;
+    private firstSystemMargin;
+    private systemLabelsRightMargin;
+    private systemComposerDistance;
+    private instrumentLabelTextHeight;
+    private minimumAllowedDistanceBetweenSystems;
+    private lastSystemMaxScalingFactor;
+    private staffDistance;
+    private betweenStaffDistance;
+    private staffHeight;
+    private betweenStaffLinesDistance;
+    private beamWidth;
+    private beamSpaceWidth;
+    private beamForwardLength;
+    private clefLeftMargin;
+    private clefRightMargin;
+    private betweenKeySymbolsDistance;
+    private keyRightMargin;
+    private rhythmRightMargin;
+    private inStaffClefScalingFactor;
+    private distanceBetweenNaturalAndSymbolWhenCancelling;
+    private noteHelperLinesOffset;
+    private measureLeftMargin;
+    private measureRightMargin;
+    private distanceBetweenLastInstructionAndRepetitionBarline;
+    private arpeggioDistance;
+    private idealStemLength;
+    private stemNoteHeadBorderYOffset;
+    private stemWidth;
+    private stemMargin;
+    private stemMinLength;
+    private stemMaxLength;
+    private beamSlopeMaxAngle;
+    private stemMinAllowedDistanceBetweenNoteHeadAndBeamLine;
+    private graceNoteScalingFactor;
+    private graceNoteXOffset;
+    private wedgeOpeningLength;
+    private wedgeMeasureEndOpeningLength;
+    private wedgeMeasureBeginOpeningLength;
+    private wedgePlacementAboveY;
+    private wedgePlacementBelowY;
+    private wedgeHorizontalMargin;
+    private wedgeVerticalMargin;
+    private distanceOffsetBetweenTwoHorizontallyCrossedWedges;
+    private wedgeMinLength;
+    private distanceBetweenAdjacentDynamics;
+    private tempoChangeMeasureValitidy;
+    private tempoContinousFactor;
+    private staccatoScalingFactor;
+    private betweenDotsDistance;
+    private ornamentAccidentalScalingFactor;
+    private chordSymbolTextHeight;
+    private fingeringLabelFontHeight;
+    private measureNumberLabelHeight;
+    private measureNumberLabelOffset;
+    private tupletNumberLabelHeight;
+    private tupletNumberYOffset;
+    private labelMarginBorderFactor;
+    private tupletVerticalLineLength;
+    private repetitionEndingLabelHeight;
+    private repetitionEndingLabelXOffset;
+    private repetitionEndingLabelYOffset;
+    private repetitionEndingLineYLowerOffset;
+    private repetitionEndingLineYUpperOffset;
+    private lyricsHeight;
+    private verticalBetweenLyricsDistance;
+    private betweenSyllabelMaximumDistance;
+    private minimumDistanceBetweenDashes;
+    private bezierCurveStepSize;
+    private tPower3;
+    private oneMinusTPower3;
+    private factorOne;
+    private factorTwo;
+    private tieGhostObjectWidth;
+    private tieYPositionOffsetFactor;
+    private minimumNeededXspaceForTieGhostObject;
+    private tieHeightMinimum;
+    private tieHeightMaximum;
+    private tieHeightInterpolationK;
+    private tieHeightInterpolationD;
+    private slurNoteHeadYOffset;
+    private slurStemXOffset;
+    private slurSlopeMaxAngle;
+    private slurTangentMinAngle;
+    private slurTangentMaxAngle;
+    private slursStartingAtSameStaffEntryYOffset;
+    private instantaniousTempoTextHeight;
+    private continuousDynamicTextHeight;
+    private moodTextHeight;
+    private unknownTextHeight;
+    private continuousTempoTextHeight;
+    private staffLineWidth;
+    private ledgerLineWidth;
+    private wedgeLineWidth;
+    private tupletLineWidth;
+    private lyricUnderscoreLineWidth;
+    private systemThinLineWidth;
+    private systemBoldLineWidth;
+    private systemRepetitionEndingLineWidth;
+    private systemDotWidth;
+    private distanceBetweenVerticalSystemLines;
+    private distanceBetweenDotAndLine;
+    private octaveShiftLineWidth;
+    private octaveShiftVerticalLineLength;
+    private graceLineWidth;
+    private minimumStaffLineDistance;
+    private minimumCrossedBeamDifferenceMargin;
+    private displacedNoteMargin;
+    private minNoteDistance;
+    private subMeasureXSpacingThreshold;
+    private measureDynamicsMaxScalingFactor;
+    private maxInstructionsConstValue;
+    private noteDistances;
+    private noteDistancesScalingFactors;
+    private durationDistanceDict;
+    private durationScalingDistanceDict;
+    constructor();
+    static Rules: EngravingRules;
+    SamplingUnit: number;
+    SheetTitleHeight: number;
+    SheetSubtitleHeight: number;
+    SheetMinimumDistanceBetweenTitleAndSubtitle: number;
+    SheetComposerHeight: number;
+    SheetAuthorHeight: number;
+    PagePlacement: PagePlacementEnum;
+    PageHeight: number;
+    PageTopMargin: number;
+    PageBottomMargin: number;
+    PageLeftMargin: number;
+    PageRightMargin: number;
+    TitleTopDistance: number;
+    TitleBottomDistance: number;
+    SystemComposerDistance: number;
+    InstrumentLabelTextHeight: number;
+    SystemDistance: number;
+    SystemLeftMargin: number;
+    SystemRightMargin: number;
+    FirstSystemMargin: number;
+    SystemLabelsRightMargin: number;
+    MinimumAllowedDistanceBetweenSystems: number;
+    LastSystemMaxScalingFactor: number;
+    StaffDistance: number;
+    BetweenStaffDistance: number;
+    StaffHeight: number;
+    BetweenStaffLinesDistance: number;
+    BeamWidth: number;
+    BeamSpaceWidth: number;
+    BeamForwardLength: number;
+    BetweenKeySymbolsDistance: number;
+    ClefLeftMargin: number;
+    ClefRightMargin: number;
+    KeyRightMargin: number;
+    RhythmRightMargin: number;
+    InStaffClefScalingFactor: number;
+    DistanceBetweenNaturalAndSymbolWhenCancelling: number;
+    NoteHelperLinesOffset: number;
+    MeasureLeftMargin: number;
+    MeasureRightMargin: number;
+    DistanceBetweenLastInstructionAndRepetitionBarline: number;
+    ArpeggioDistance: number;
+    StaccatoShorteningFactor: number;
+    IdealStemLength: number;
+    StemNoteHeadBorderYOffset: number;
+    StemWidth: number;
+    StemMargin: number;
+    StemMinLength: number;
+    StemMaxLength: number;
+    BeamSlopeMaxAngle: number;
+    StemMinAllowedDistanceBetweenNoteHeadAndBeamLine: number;
+    GraceNoteScalingFactor: number;
+    GraceNoteXOffset: number;
+    WedgeOpeningLength: number;
+    WedgeMeasureEndOpeningLength: number;
+    WedgeMeasureBeginOpeningLength: number;
+    WedgePlacementAboveY: number;
+    WedgePlacementBelowY: number;
+    WedgeHorizontalMargin: number;
+    WedgeVerticalMargin: number;
+    DistanceOffsetBetweenTwoHorizontallyCrossedWedges: number;
+    WedgeMinLength: number;
+    DistanceBetweenAdjacentDynamics: number;
+    TempoChangeMeasureValitidy: number;
+    TempoContinousFactor: number;
+    StaccatoScalingFactor: number;
+    BetweenDotsDistance: number;
+    OrnamentAccidentalScalingFactor: number;
+    ChordSymbolTextHeight: number;
+    FingeringLabelFontHeight: number;
+    MeasureNumberLabelHeight: number;
+    MeasureNumberLabelOffset: number;
+    TupletNumberLabelHeight: number;
+    TupletNumberYOffset: number;
+    LabelMarginBorderFactor: number;
+    TupletVerticalLineLength: number;
+    RepetitionEndingLabelHeight: number;
+    RepetitionEndingLabelXOffset: number;
+    RepetitionEndingLabelYOffset: number;
+    RepetitionEndingLineYLowerOffset: number;
+    RepetitionEndingLineYUpperOffset: number;
+    LyricsHeight: number;
+    VerticalBetweenLyricsDistance: number;
+    BetweenSyllabelMaximumDistance: number;
+    MinimumDistanceBetweenDashes: number;
+    BezierCurveStepSize: number;
+    TPow3: number[];
+    OneMinusTPow3: number[];
+    BezierFactorOne: number[];
+    BezierFactorTwo: number[];
+    TieGhostObjectWidth: number;
+    TieYPositionOffsetFactor: number;
+    MinimumNeededXspaceForTieGhostObject: number;
+    TieHeightMinimum: number;
+    TieHeightMaximum: number;
+    TieHeightInterpolationK: number;
+    TieHeightInterpolationD: number;
+    SlurNoteHeadYOffset: number;
+    SlurStemXOffset: number;
+    SlurSlopeMaxAngle: number;
+    SlurTangentMinAngle: number;
+    SlurTangentMaxAngle: number;
+    SlursStartingAtSameStaffEntryYOffset: number;
+    InstantaniousTempoTextHeight: number;
+    ContinuousDynamicTextHeight: number;
+    MoodTextHeight: number;
+    ContinuousTempoTextHeight: number;
+    UnknownTextHeight: number;
+    StaffLineWidth: number;
+    LedgerLineWidth: number;
+    WedgeLineWidth: number;
+    TupletLineWidth: number;
+    LyricUnderscoreLineWidth: number;
+    SystemThinLineWidth: number;
+    SystemBoldLineWidth: number;
+    SystemRepetitionEndingLineWidth: number;
+    SystemDotWidth: number;
+    DistanceBetweenVerticalSystemLines: number;
+    DistanceBetweenDotAndLine: number;
+    OctaveShiftLineWidth: number;
+    OctaveShiftVerticalLineLength: number;
+    GraceLineWidth: number;
+    MinimumStaffLineDistance: number;
+    MinimumCrossedBeamDifferenceMargin: number;
+    DisplacedNoteMargin: number;
+    MinNoteDistance: number;
+    SubMeasureXSpacingThreshold: number;
+    MeasureDynamicsMaxScalingFactor: number;
+    MaxInstructionsConstValue: number;
+    NoteDistances: number[];
+    NoteDistancesScalingFactors: number[];
+    DurationDistanceDict: {
+        [_: number]: number;
+    };
+    DurationScalingDistanceDict: {
+        [_: number]: number;
+    };
+    private populateDictionaries();
+    private calculateCurveParametersArrays();
+}

+ 1524 - 0
dist/src/MusicalScore/Graphical/EngravingRules.js

@@ -0,0 +1,1524 @@
+"use strict";
+var GraphicalMusicPage_1 = require("./GraphicalMusicPage");
+//import {MusicSymbol} from "./MusicSymbol";
+var logging_1 = require("../../Common/logging");
+var EngravingRules = (function () {
+    function EngravingRules() {
+        this.noteDistances = [1.0, 1.0, 1.3, 1.6, 2.0, 2.5, 3.0, 4.0];
+        this.noteDistancesScalingFactors = [1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0];
+        this.durationDistanceDict = {};
+        this.durationScalingDistanceDict = {};
+        this.samplingUnit = EngravingRules.unit * 3;
+        this.sheetTitleHeight = 4.0;
+        this.sheetSubtitleHeight = 2.0;
+        this.sheetMinimumDistanceBetweenTitleAndSubtitle = 1.0;
+        this.sheetComposerHeight = 2.0;
+        this.sheetAuthorHeight = 2.0;
+        this.pagePlacementEnum = GraphicalMusicPage_1.PagePlacementEnum.Down;
+        this.pageHeight = 100001.0;
+        this.pageTopMargin = 5.0;
+        this.pageBottomMargin = 5.0;
+        this.pageLeftMargin = 5.0;
+        this.pageRightMargin = 5.0;
+        this.titleTopDistance = 9.0;
+        this.titleBottomDistance = 1.0;
+        this.staffDistance = 7.0;
+        this.betweenStaffDistance = 5.0;
+        this.staffHeight = 4.0;
+        this.betweenStaffLinesDistance = EngravingRules.unit;
+        this.systemDistance = 10.0;
+        this.systemLeftMargin = 0.0;
+        this.systemRightMargin = 0.0;
+        this.firstSystemMargin = 15.0;
+        this.systemLabelsRightMargin = 2.0;
+        this.systemComposerDistance = 2.0;
+        this.instrumentLabelTextHeight = 2;
+        this.minimumAllowedDistanceBetweenSystems = 3.0;
+        this.lastSystemMaxScalingFactor = 1.4;
+        this.beamWidth = EngravingRules.unit / 2.0;
+        this.beamSpaceWidth = EngravingRules.unit / 3.0;
+        this.beamForwardLength = 1.25 * EngravingRules.unit;
+        this.clefLeftMargin = 0.5;
+        this.clefRightMargin = 0.75;
+        this.betweenKeySymbolsDistance = 0.2;
+        this.keyRightMargin = 0.75;
+        this.rhythmRightMargin = 1.25;
+        this.inStaffClefScalingFactor = 0.8;
+        this.distanceBetweenNaturalAndSymbolWhenCancelling = 0.4;
+        this.noteHelperLinesOffset = 0.25;
+        this.measureLeftMargin = 0.7;
+        this.measureRightMargin = 0.0;
+        this.distanceBetweenLastInstructionAndRepetitionBarline = 1.0;
+        this.arpeggioDistance = 0.6;
+        this.staccatoShorteningFactor = 2;
+        this.idealStemLength = 3.0;
+        this.stemNoteHeadBorderYOffset = 0.2;
+        this.stemWidth = 0.13;
+        this.stemMargin = 0.2;
+        this.stemMinLength = 2.5;
+        this.stemMaxLength = 4.5;
+        this.beamSlopeMaxAngle = 10.0;
+        this.stemMinAllowedDistanceBetweenNoteHeadAndBeamLine = 1.0;
+        this.graceNoteScalingFactor = 0.6;
+        this.graceNoteXOffset = 0.2;
+        this.wedgeOpeningLength = 1.2;
+        this.wedgeMeasureEndOpeningLength = 0.75;
+        this.wedgeMeasureBeginOpeningLength = 0.75;
+        this.wedgePlacementAboveY = -1.5;
+        this.wedgePlacementBelowY = 1.5;
+        this.wedgeHorizontalMargin = 0.6;
+        this.wedgeVerticalMargin = 0.5;
+        this.distanceOffsetBetweenTwoHorizontallyCrossedWedges = 0.3;
+        this.wedgeMinLength = 2.0;
+        this.distanceBetweenAdjacentDynamics = 0.75;
+        this.tempoChangeMeasureValitidy = 4;
+        this.tempoContinousFactor = 0.7;
+        this.staccatoScalingFactor = 0.8;
+        this.betweenDotsDistance = 0.8;
+        this.ornamentAccidentalScalingFactor = 0.65;
+        this.chordSymbolTextHeight = 2.0;
+        this.fingeringLabelFontHeight = 1.7;
+        this.measureNumberLabelHeight = 1.5 * EngravingRules.unit;
+        this.measureNumberLabelOffset = 2;
+        this.tupletNumberLabelHeight = 1.5 * EngravingRules.unit;
+        this.tupletNumberYOffset = 0.5;
+        this.labelMarginBorderFactor = 0.1;
+        this.tupletVerticalLineLength = 0.5;
+        this.bezierCurveStepSize = 1000;
+        this.calculateCurveParametersArrays();
+        this.tieGhostObjectWidth = 0.75;
+        this.tieYPositionOffsetFactor = 0.3;
+        this.minimumNeededXspaceForTieGhostObject = 1.0;
+        this.tieHeightMinimum = 0.28;
+        this.tieHeightMaximum = 1.2;
+        this.tieHeightInterpolationK = 0.0288;
+        this.tieHeightInterpolationD = 0.136;
+        this.slurNoteHeadYOffset = 0.5;
+        this.slurStemXOffset = 0.3;
+        this.slurSlopeMaxAngle = 15.0;
+        this.slurTangentMinAngle = 30.0;
+        this.slurTangentMaxAngle = 80.0;
+        this.slursStartingAtSameStaffEntryYOffset = 0.8;
+        this.repetitionEndingLabelHeight = 2.0;
+        this.repetitionEndingLabelXOffset = 0.5;
+        this.repetitionEndingLabelYOffset = 0.3;
+        this.repetitionEndingLineYLowerOffset = 0.5;
+        this.repetitionEndingLineYUpperOffset = 0.3;
+        this.lyricsHeight = 2.0;
+        this.verticalBetweenLyricsDistance = 0.5;
+        this.betweenSyllabelMaximumDistance = 10.0;
+        this.minimumDistanceBetweenDashes = 5.0;
+        this.instantaniousTempoTextHeight = 2.3;
+        this.continuousDynamicTextHeight = 2.3;
+        this.moodTextHeight = 2.3;
+        this.unknownTextHeight = 2.0;
+        this.continuousTempoTextHeight = 2.3;
+        this.staffLineWidth = 0.12;
+        this.ledgerLineWidth = 0.12;
+        this.wedgeLineWidth = 0.12;
+        this.tupletLineWidth = 0.12;
+        this.lyricUnderscoreLineWidth = 0.12;
+        this.systemThinLineWidth = 0.12;
+        this.systemBoldLineWidth = EngravingRules.unit / 2.0;
+        this.systemRepetitionEndingLineWidth = 0.12;
+        this.systemDotWidth = EngravingRules.unit / 5.0;
+        this.distanceBetweenVerticalSystemLines = 0.35;
+        this.distanceBetweenDotAndLine = 0.7;
+        this.octaveShiftLineWidth = 0.12;
+        this.octaveShiftVerticalLineLength = EngravingRules.unit;
+        this.graceLineWidth = this.staffLineWidth * this.GraceNoteScalingFactor;
+        this.minimumStaffLineDistance = 1.0;
+        this.minimumCrossedBeamDifferenceMargin = 0.0001;
+        this.displacedNoteMargin = 0.1;
+        this.minNoteDistance = 2.0;
+        this.subMeasureXSpacingThreshold = 35;
+        this.measureDynamicsMaxScalingFactor = 2.5;
+        this.populateDictionaries();
+        try {
+            this.maxInstructionsConstValue = this.ClefLeftMargin + this.ClefRightMargin + this.KeyRightMargin + this.RhythmRightMargin + 11;
+        }
+        catch (ex) {
+            logging_1.Logging.log("EngravingRules()", ex);
+        }
+    }
+    Object.defineProperty(EngravingRules, "Rules", {
+        get: function () {
+            return EngravingRules.rules !== undefined ? EngravingRules.rules : (EngravingRules.rules = new EngravingRules());
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SamplingUnit", {
+        get: function () {
+            return this.samplingUnit;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SheetTitleHeight", {
+        get: function () {
+            return this.sheetTitleHeight;
+        },
+        set: function (value) {
+            this.sheetTitleHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SheetSubtitleHeight", {
+        get: function () {
+            return this.sheetSubtitleHeight;
+        },
+        set: function (value) {
+            this.sheetSubtitleHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SheetMinimumDistanceBetweenTitleAndSubtitle", {
+        get: function () {
+            return this.sheetMinimumDistanceBetweenTitleAndSubtitle;
+        },
+        set: function (value) {
+            this.sheetMinimumDistanceBetweenTitleAndSubtitle = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SheetComposerHeight", {
+        get: function () {
+            return this.sheetComposerHeight;
+        },
+        set: function (value) {
+            this.sheetComposerHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SheetAuthorHeight", {
+        get: function () {
+            return this.sheetAuthorHeight;
+        },
+        set: function (value) {
+            this.sheetAuthorHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "PagePlacement", {
+        get: function () {
+            return this.pagePlacementEnum;
+        },
+        set: function (value) {
+            this.pagePlacementEnum = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "PageHeight", {
+        get: function () {
+            return this.pageHeight;
+        },
+        set: function (value) {
+            this.pageHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "PageTopMargin", {
+        get: function () {
+            return this.pageTopMargin;
+        },
+        set: function (value) {
+            this.pageTopMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "PageBottomMargin", {
+        get: function () {
+            return this.pageBottomMargin;
+        },
+        set: function (value) {
+            this.pageBottomMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "PageLeftMargin", {
+        get: function () {
+            return this.pageLeftMargin;
+        },
+        set: function (value) {
+            this.pageLeftMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "PageRightMargin", {
+        get: function () {
+            return this.pageRightMargin;
+        },
+        set: function (value) {
+            this.pageRightMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TitleTopDistance", {
+        get: function () {
+            return this.titleTopDistance;
+        },
+        set: function (value) {
+            this.titleTopDistance = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TitleBottomDistance", {
+        get: function () {
+            return this.titleBottomDistance;
+        },
+        set: function (value) {
+            this.titleBottomDistance = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SystemComposerDistance", {
+        get: function () {
+            return this.systemComposerDistance;
+        },
+        set: function (value) {
+            this.systemComposerDistance = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "InstrumentLabelTextHeight", {
+        get: function () {
+            return this.instrumentLabelTextHeight;
+        },
+        set: function (value) {
+            this.instrumentLabelTextHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SystemDistance", {
+        get: function () {
+            return this.systemDistance;
+        },
+        set: function (value) {
+            this.systemDistance = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SystemLeftMargin", {
+        get: function () {
+            return this.systemLeftMargin;
+        },
+        set: function (value) {
+            this.systemLeftMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SystemRightMargin", {
+        get: function () {
+            return this.systemRightMargin;
+        },
+        set: function (value) {
+            this.systemRightMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "FirstSystemMargin", {
+        get: function () {
+            return this.firstSystemMargin;
+        },
+        set: function (value) {
+            this.firstSystemMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SystemLabelsRightMargin", {
+        get: function () {
+            return this.systemLabelsRightMargin;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "MinimumAllowedDistanceBetweenSystems", {
+        get: function () {
+            return this.minimumAllowedDistanceBetweenSystems;
+        },
+        set: function (value) {
+            this.minimumAllowedDistanceBetweenSystems = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "LastSystemMaxScalingFactor", {
+        get: function () {
+            return this.lastSystemMaxScalingFactor;
+        },
+        set: function (value) {
+            this.lastSystemMaxScalingFactor = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "StaffDistance", {
+        get: function () {
+            return this.staffDistance;
+        },
+        set: function (value) {
+            this.staffDistance = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "BetweenStaffDistance", {
+        get: function () {
+            return this.betweenStaffDistance;
+        },
+        set: function (value) {
+            this.betweenStaffDistance = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "StaffHeight", {
+        get: function () {
+            return this.staffHeight;
+        },
+        set: function (value) {
+            this.staffHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "BetweenStaffLinesDistance", {
+        get: function () {
+            return this.betweenStaffLinesDistance;
+        },
+        set: function (value) {
+            this.betweenStaffLinesDistance = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "BeamWidth", {
+        get: function () {
+            return this.beamWidth;
+        },
+        set: function (value) {
+            this.beamWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "BeamSpaceWidth", {
+        get: function () {
+            return this.beamSpaceWidth;
+        },
+        set: function (value) {
+            this.beamSpaceWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "BeamForwardLength", {
+        get: function () {
+            return this.beamForwardLength;
+        },
+        set: function (value) {
+            this.beamForwardLength = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "BetweenKeySymbolsDistance", {
+        get: function () {
+            return this.betweenKeySymbolsDistance;
+        },
+        set: function (value) {
+            this.betweenKeySymbolsDistance = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "ClefLeftMargin", {
+        get: function () {
+            return this.clefLeftMargin;
+        },
+        set: function (value) {
+            this.clefLeftMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "ClefRightMargin", {
+        get: function () {
+            return this.clefRightMargin;
+        },
+        set: function (value) {
+            this.clefRightMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "KeyRightMargin", {
+        get: function () {
+            return this.keyRightMargin;
+        },
+        set: function (value) {
+            this.keyRightMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "RhythmRightMargin", {
+        get: function () {
+            return this.rhythmRightMargin;
+        },
+        set: function (value) {
+            this.rhythmRightMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "InStaffClefScalingFactor", {
+        get: function () {
+            return this.inStaffClefScalingFactor;
+        },
+        set: function (value) {
+            this.inStaffClefScalingFactor = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "DistanceBetweenNaturalAndSymbolWhenCancelling", {
+        get: function () {
+            return this.distanceBetweenNaturalAndSymbolWhenCancelling;
+        },
+        set: function (value) {
+            this.distanceBetweenNaturalAndSymbolWhenCancelling = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "NoteHelperLinesOffset", {
+        get: function () {
+            return this.noteHelperLinesOffset;
+        },
+        set: function (value) {
+            this.noteHelperLinesOffset = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "MeasureLeftMargin", {
+        get: function () {
+            return this.measureLeftMargin;
+        },
+        set: function (value) {
+            this.measureLeftMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "MeasureRightMargin", {
+        get: function () {
+            return this.measureRightMargin;
+        },
+        set: function (value) {
+            this.measureRightMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "DistanceBetweenLastInstructionAndRepetitionBarline", {
+        get: function () {
+            return this.distanceBetweenLastInstructionAndRepetitionBarline;
+        },
+        set: function (value) {
+            this.distanceBetweenLastInstructionAndRepetitionBarline = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "ArpeggioDistance", {
+        get: function () {
+            return this.arpeggioDistance;
+        },
+        set: function (value) {
+            this.arpeggioDistance = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "StaccatoShorteningFactor", {
+        get: function () {
+            return this.staccatoShorteningFactor;
+        },
+        set: function (value) {
+            this.staccatoShorteningFactor = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "IdealStemLength", {
+        get: function () {
+            return this.idealStemLength;
+        },
+        set: function (value) {
+            this.idealStemLength = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "StemNoteHeadBorderYOffset", {
+        get: function () {
+            return this.stemNoteHeadBorderYOffset;
+        },
+        set: function (value) {
+            this.stemNoteHeadBorderYOffset = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "StemWidth", {
+        get: function () {
+            return this.stemWidth;
+        },
+        set: function (value) {
+            this.stemWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "StemMargin", {
+        get: function () {
+            return this.stemMargin;
+        },
+        set: function (value) {
+            this.stemMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "StemMinLength", {
+        get: function () {
+            return this.stemMinLength;
+        },
+        set: function (value) {
+            this.stemMinLength = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "StemMaxLength", {
+        get: function () {
+            return this.stemMaxLength;
+        },
+        set: function (value) {
+            this.stemMaxLength = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "BeamSlopeMaxAngle", {
+        get: function () {
+            return this.beamSlopeMaxAngle;
+        },
+        set: function (value) {
+            this.beamSlopeMaxAngle = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "StemMinAllowedDistanceBetweenNoteHeadAndBeamLine", {
+        get: function () {
+            return this.stemMinAllowedDistanceBetweenNoteHeadAndBeamLine;
+        },
+        set: function (value) {
+            this.stemMinAllowedDistanceBetweenNoteHeadAndBeamLine = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "GraceNoteScalingFactor", {
+        get: function () {
+            return this.graceNoteScalingFactor;
+        },
+        set: function (value) {
+            this.graceNoteScalingFactor = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "GraceNoteXOffset", {
+        get: function () {
+            return this.graceNoteXOffset;
+        },
+        set: function (value) {
+            this.graceNoteXOffset = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "WedgeOpeningLength", {
+        get: function () {
+            return this.wedgeOpeningLength;
+        },
+        set: function (value) {
+            this.wedgeOpeningLength = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "WedgeMeasureEndOpeningLength", {
+        get: function () {
+            return this.wedgeMeasureEndOpeningLength;
+        },
+        set: function (value) {
+            this.wedgeMeasureEndOpeningLength = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "WedgeMeasureBeginOpeningLength", {
+        get: function () {
+            return this.wedgeMeasureBeginOpeningLength;
+        },
+        set: function (value) {
+            this.wedgeMeasureBeginOpeningLength = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "WedgePlacementAboveY", {
+        get: function () {
+            return this.wedgePlacementAboveY;
+        },
+        set: function (value) {
+            this.wedgePlacementAboveY = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "WedgePlacementBelowY", {
+        get: function () {
+            return this.wedgePlacementBelowY;
+        },
+        set: function (value) {
+            this.wedgePlacementBelowY = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "WedgeHorizontalMargin", {
+        get: function () {
+            return this.wedgeHorizontalMargin;
+        },
+        set: function (value) {
+            this.wedgeHorizontalMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "WedgeVerticalMargin", {
+        get: function () {
+            return this.wedgeVerticalMargin;
+        },
+        set: function (value) {
+            this.wedgeVerticalMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "DistanceOffsetBetweenTwoHorizontallyCrossedWedges", {
+        get: function () {
+            return this.distanceOffsetBetweenTwoHorizontallyCrossedWedges;
+        },
+        set: function (value) {
+            this.distanceOffsetBetweenTwoHorizontallyCrossedWedges = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "WedgeMinLength", {
+        get: function () {
+            return this.wedgeMinLength;
+        },
+        set: function (value) {
+            this.wedgeMinLength = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "DistanceBetweenAdjacentDynamics", {
+        get: function () {
+            return this.distanceBetweenAdjacentDynamics;
+        },
+        set: function (value) {
+            this.distanceBetweenAdjacentDynamics = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TempoChangeMeasureValitidy", {
+        get: function () {
+            return this.tempoChangeMeasureValitidy;
+        },
+        set: function (value) {
+            this.tempoChangeMeasureValitidy = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TempoContinousFactor", {
+        get: function () {
+            return this.tempoContinousFactor;
+        },
+        set: function (value) {
+            this.tempoContinousFactor = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "StaccatoScalingFactor", {
+        get: function () {
+            return this.staccatoScalingFactor;
+        },
+        set: function (value) {
+            this.staccatoScalingFactor = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "BetweenDotsDistance", {
+        get: function () {
+            return this.betweenDotsDistance;
+        },
+        set: function (value) {
+            this.betweenDotsDistance = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "OrnamentAccidentalScalingFactor", {
+        get: function () {
+            return this.ornamentAccidentalScalingFactor;
+        },
+        set: function (value) {
+            this.ornamentAccidentalScalingFactor = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "ChordSymbolTextHeight", {
+        get: function () {
+            return this.chordSymbolTextHeight;
+        },
+        set: function (value) {
+            this.chordSymbolTextHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "FingeringLabelFontHeight", {
+        get: function () {
+            return this.fingeringLabelFontHeight;
+        },
+        set: function (value) {
+            this.fingeringLabelFontHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "MeasureNumberLabelHeight", {
+        get: function () {
+            return this.measureNumberLabelHeight;
+        },
+        set: function (value) {
+            this.measureNumberLabelHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "MeasureNumberLabelOffset", {
+        get: function () {
+            return this.measureNumberLabelOffset;
+        },
+        set: function (value) {
+            this.measureNumberLabelOffset = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TupletNumberLabelHeight", {
+        get: function () {
+            return this.tupletNumberLabelHeight;
+        },
+        set: function (value) {
+            this.tupletNumberLabelHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TupletNumberYOffset", {
+        get: function () {
+            return this.tupletNumberYOffset;
+        },
+        set: function (value) {
+            this.tupletNumberYOffset = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "LabelMarginBorderFactor", {
+        get: function () {
+            return this.labelMarginBorderFactor;
+        },
+        set: function (value) {
+            this.labelMarginBorderFactor = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TupletVerticalLineLength", {
+        get: function () {
+            return this.tupletVerticalLineLength;
+        },
+        set: function (value) {
+            this.tupletVerticalLineLength = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "RepetitionEndingLabelHeight", {
+        get: function () {
+            return this.repetitionEndingLabelHeight;
+        },
+        set: function (value) {
+            this.repetitionEndingLabelHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "RepetitionEndingLabelXOffset", {
+        get: function () {
+            return this.repetitionEndingLabelXOffset;
+        },
+        set: function (value) {
+            this.repetitionEndingLabelXOffset = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "RepetitionEndingLabelYOffset", {
+        get: function () {
+            return this.repetitionEndingLabelYOffset;
+        },
+        set: function (value) {
+            this.repetitionEndingLabelYOffset = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "RepetitionEndingLineYLowerOffset", {
+        get: function () {
+            return this.repetitionEndingLineYLowerOffset;
+        },
+        set: function (value) {
+            this.repetitionEndingLineYLowerOffset = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "RepetitionEndingLineYUpperOffset", {
+        get: function () {
+            return this.repetitionEndingLineYUpperOffset;
+        },
+        set: function (value) {
+            this.repetitionEndingLineYUpperOffset = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "LyricsHeight", {
+        get: function () {
+            return this.lyricsHeight;
+        },
+        set: function (value) {
+            this.lyricsHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "VerticalBetweenLyricsDistance", {
+        get: function () {
+            return this.verticalBetweenLyricsDistance;
+        },
+        set: function (value) {
+            this.verticalBetweenLyricsDistance = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "BetweenSyllabelMaximumDistance", {
+        get: function () {
+            return this.betweenSyllabelMaximumDistance;
+        },
+        set: function (value) {
+            this.betweenSyllabelMaximumDistance = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "MinimumDistanceBetweenDashes", {
+        get: function () {
+            return this.minimumDistanceBetweenDashes;
+        },
+        set: function (value) {
+            this.minimumDistanceBetweenDashes = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "BezierCurveStepSize", {
+        get: function () {
+            return this.bezierCurveStepSize;
+        },
+        set: function (value) {
+            this.bezierCurveStepSize = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TPow3", {
+        get: function () {
+            return this.tPower3;
+        },
+        set: function (value) {
+            this.tPower3 = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "OneMinusTPow3", {
+        get: function () {
+            return this.oneMinusTPower3;
+        },
+        set: function (value) {
+            this.oneMinusTPower3 = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "BezierFactorOne", {
+        get: function () {
+            return this.factorOne;
+        },
+        set: function (value) {
+            this.factorOne = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "BezierFactorTwo", {
+        get: function () {
+            return this.factorTwo;
+        },
+        set: function (value) {
+            this.factorTwo = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TieGhostObjectWidth", {
+        get: function () {
+            return this.tieGhostObjectWidth;
+        },
+        set: function (value) {
+            this.tieGhostObjectWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TieYPositionOffsetFactor", {
+        get: function () {
+            return this.tieYPositionOffsetFactor;
+        },
+        set: function (value) {
+            this.tieYPositionOffsetFactor = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "MinimumNeededXspaceForTieGhostObject", {
+        get: function () {
+            return this.minimumNeededXspaceForTieGhostObject;
+        },
+        set: function (value) {
+            this.minimumNeededXspaceForTieGhostObject = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TieHeightMinimum", {
+        get: function () {
+            return this.tieHeightMinimum;
+        },
+        set: function (value) {
+            this.tieHeightMinimum = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TieHeightMaximum", {
+        get: function () {
+            return this.tieHeightMaximum;
+        },
+        set: function (value) {
+            this.tieHeightMaximum = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TieHeightInterpolationK", {
+        get: function () {
+            return this.tieHeightInterpolationK;
+        },
+        set: function (value) {
+            this.tieHeightInterpolationK = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TieHeightInterpolationD", {
+        get: function () {
+            return this.tieHeightInterpolationD;
+        },
+        set: function (value) {
+            this.tieHeightInterpolationD = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SlurNoteHeadYOffset", {
+        get: function () {
+            return this.slurNoteHeadYOffset;
+        },
+        set: function (value) {
+            this.slurNoteHeadYOffset = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SlurStemXOffset", {
+        get: function () {
+            return this.slurStemXOffset;
+        },
+        set: function (value) {
+            this.slurStemXOffset = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SlurSlopeMaxAngle", {
+        get: function () {
+            return this.slurSlopeMaxAngle;
+        },
+        set: function (value) {
+            this.slurSlopeMaxAngle = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SlurTangentMinAngle", {
+        get: function () {
+            return this.slurTangentMinAngle;
+        },
+        set: function (value) {
+            this.slurTangentMinAngle = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SlurTangentMaxAngle", {
+        get: function () {
+            return this.slurTangentMaxAngle;
+        },
+        set: function (value) {
+            this.slurTangentMaxAngle = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SlursStartingAtSameStaffEntryYOffset", {
+        get: function () {
+            return this.slursStartingAtSameStaffEntryYOffset;
+        },
+        set: function (value) {
+            this.slursStartingAtSameStaffEntryYOffset = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "InstantaniousTempoTextHeight", {
+        get: function () {
+            return this.instantaniousTempoTextHeight;
+        },
+        set: function (value) {
+            this.instantaniousTempoTextHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "ContinuousDynamicTextHeight", {
+        get: function () {
+            return this.continuousDynamicTextHeight;
+        },
+        set: function (value) {
+            this.continuousDynamicTextHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "MoodTextHeight", {
+        get: function () {
+            return this.moodTextHeight;
+        },
+        set: function (value) {
+            this.moodTextHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "ContinuousTempoTextHeight", {
+        get: function () {
+            return this.continuousTempoTextHeight;
+        },
+        set: function (value) {
+            this.continuousTempoTextHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "UnknownTextHeight", {
+        get: function () {
+            return this.unknownTextHeight;
+        },
+        set: function (value) {
+            this.unknownTextHeight = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "StaffLineWidth", {
+        get: function () {
+            return this.staffLineWidth;
+        },
+        set: function (value) {
+            this.staffLineWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "LedgerLineWidth", {
+        get: function () {
+            return this.ledgerLineWidth;
+        },
+        set: function (value) {
+            this.ledgerLineWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "WedgeLineWidth", {
+        get: function () {
+            return this.wedgeLineWidth;
+        },
+        set: function (value) {
+            this.wedgeLineWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "TupletLineWidth", {
+        get: function () {
+            return this.tupletLineWidth;
+        },
+        set: function (value) {
+            this.tupletLineWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "LyricUnderscoreLineWidth", {
+        get: function () {
+            return this.lyricUnderscoreLineWidth;
+        },
+        set: function (value) {
+            this.lyricUnderscoreLineWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SystemThinLineWidth", {
+        get: function () {
+            return this.systemThinLineWidth;
+        },
+        set: function (value) {
+            this.systemThinLineWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SystemBoldLineWidth", {
+        get: function () {
+            return this.systemBoldLineWidth;
+        },
+        set: function (value) {
+            this.systemBoldLineWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SystemRepetitionEndingLineWidth", {
+        get: function () {
+            return this.systemRepetitionEndingLineWidth;
+        },
+        set: function (value) {
+            this.systemRepetitionEndingLineWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SystemDotWidth", {
+        get: function () {
+            return this.systemDotWidth;
+        },
+        set: function (value) {
+            this.systemDotWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "DistanceBetweenVerticalSystemLines", {
+        get: function () {
+            return this.distanceBetweenVerticalSystemLines;
+        },
+        set: function (value) {
+            this.distanceBetweenVerticalSystemLines = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "DistanceBetweenDotAndLine", {
+        get: function () {
+            return this.distanceBetweenDotAndLine;
+        },
+        set: function (value) {
+            this.distanceBetweenDotAndLine = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "OctaveShiftLineWidth", {
+        get: function () {
+            return this.octaveShiftLineWidth;
+        },
+        set: function (value) {
+            this.octaveShiftLineWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "OctaveShiftVerticalLineLength", {
+        get: function () {
+            return this.octaveShiftVerticalLineLength;
+        },
+        set: function (value) {
+            this.octaveShiftVerticalLineLength = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "GraceLineWidth", {
+        get: function () {
+            return this.graceLineWidth;
+        },
+        set: function (value) {
+            this.graceLineWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "MinimumStaffLineDistance", {
+        get: function () {
+            return this.minimumStaffLineDistance;
+        },
+        set: function (value) {
+            this.minimumStaffLineDistance = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "MinimumCrossedBeamDifferenceMargin", {
+        get: function () {
+            return this.minimumCrossedBeamDifferenceMargin;
+        },
+        set: function (value) {
+            this.minimumCrossedBeamDifferenceMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "DisplacedNoteMargin", {
+        get: function () {
+            return this.displacedNoteMargin;
+        },
+        set: function (value) {
+            this.displacedNoteMargin = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "MinNoteDistance", {
+        get: function () {
+            return this.minNoteDistance;
+        },
+        set: function (value) {
+            this.minNoteDistance = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "SubMeasureXSpacingThreshold", {
+        get: function () {
+            return this.subMeasureXSpacingThreshold;
+        },
+        set: function (value) {
+            this.subMeasureXSpacingThreshold = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "MeasureDynamicsMaxScalingFactor", {
+        get: function () {
+            return this.measureDynamicsMaxScalingFactor;
+        },
+        set: function (value) {
+            this.measureDynamicsMaxScalingFactor = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "MaxInstructionsConstValue", {
+        get: function () {
+            return this.maxInstructionsConstValue;
+        },
+        set: function (value) {
+            this.maxInstructionsConstValue = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "NoteDistances", {
+        get: function () {
+            return this.noteDistances;
+        },
+        set: function (value) {
+            this.noteDistances = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "NoteDistancesScalingFactors", {
+        get: function () {
+            return this.noteDistancesScalingFactors;
+        },
+        set: function (value) {
+            this.noteDistancesScalingFactors = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "DurationDistanceDict", {
+        get: function () {
+            return this.durationDistanceDict;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(EngravingRules.prototype, "DurationScalingDistanceDict", {
+        get: function () {
+            return this.durationScalingDistanceDict;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    EngravingRules.prototype.populateDictionaries = function () {
+        for (var i = 0; i < this.noteDistances.length; i++) {
+            switch (i) {
+                case 0:
+                    this.durationDistanceDict[0.015625] = this.noteDistances[i];
+                    this.durationScalingDistanceDict[0.015625] = this.noteDistancesScalingFactors[i];
+                    break;
+                case 1:
+                    this.durationDistanceDict[0.03125] = this.noteDistances[i];
+                    this.durationScalingDistanceDict[0.03125] = this.noteDistancesScalingFactors[i];
+                    break;
+                case 2:
+                    this.durationDistanceDict[0.0625] = this.noteDistances[i];
+                    this.durationScalingDistanceDict[0.0625] = this.noteDistancesScalingFactors[i];
+                    break;
+                case 3:
+                    this.durationDistanceDict[0.125] = this.noteDistances[i];
+                    this.durationScalingDistanceDict[0.125] = this.noteDistancesScalingFactors[i];
+                    break;
+                case 4:
+                    this.durationDistanceDict[0.25] = this.noteDistances[i];
+                    this.durationScalingDistanceDict[0.25] = this.noteDistancesScalingFactors[i];
+                    break;
+                case 5:
+                    this.durationDistanceDict[0.5] = this.noteDistances[i];
+                    this.durationScalingDistanceDict[0.5] = this.noteDistancesScalingFactors[i];
+                    break;
+                case 6:
+                    this.durationDistanceDict[1.0] = this.noteDistances[i];
+                    this.durationScalingDistanceDict[1.0] = this.noteDistancesScalingFactors[i];
+                    break;
+                case 7:
+                    this.durationDistanceDict[2.0] = this.noteDistances[i];
+                    this.durationScalingDistanceDict[2.0] = this.noteDistancesScalingFactors[i];
+                    break;
+                default:
+            }
+        }
+    };
+    EngravingRules.prototype.calculateCurveParametersArrays = function () {
+        this.tPower3 = new Array(this.bezierCurveStepSize);
+        this.oneMinusTPower3 = new Array(this.bezierCurveStepSize);
+        this.factorOne = new Array(this.bezierCurveStepSize);
+        this.factorTwo = new Array(this.bezierCurveStepSize);
+        for (var i = 0; i < this.bezierCurveStepSize; i++) {
+            var t = i / this.bezierCurveStepSize;
+            this.tPower3[i] = Math.pow(t, 3);
+            this.oneMinusTPower3[i] = Math.pow((1 - t), 3);
+            this.factorOne[i] = 3 * Math.pow((1 - t), 2) * t;
+            this.factorTwo[i] = 3 * (1 - t) * Math.pow(t, 2);
+        }
+    };
+    EngravingRules.unit = 1.0;
+    return EngravingRules;
+}());
+exports.EngravingRules = EngravingRules;

+ 12 - 0
dist/src/MusicalScore/Graphical/GraphicalChordSymbolContainer.d.ts

@@ -0,0 +1,12 @@
+import { GraphicalLabel } from "./GraphicalLabel";
+import { ChordSymbolContainer } from "../VoiceData/ChordSymbolContainer";
+import { BoundingBox } from "./BoundingBox";
+import { GraphicalObject } from "./GraphicalObject";
+export declare class GraphicalChordSymbolContainer extends GraphicalObject {
+    private chordSymbolContainer;
+    private graphicalLabel;
+    constructor(chordSymbolContainer: ChordSymbolContainer, parent: BoundingBox, textHeight: number, transposeHalftones: number);
+    GetChordSymbolContainer: ChordSymbolContainer;
+    GetGraphicalLabel: GraphicalLabel;
+    private calculateLabel(textHeight, transposeHalftones);
+}

+ 44 - 0
dist/src/MusicalScore/Graphical/GraphicalChordSymbolContainer.js

@@ -0,0 +1,44 @@
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var TextAlignment_1 = require("../../Common/Enums/TextAlignment");
+var Label_1 = require("../Label");
+var GraphicalLabel_1 = require("./GraphicalLabel");
+var ChordSymbolContainer_1 = require("../VoiceData/ChordSymbolContainer");
+var BoundingBox_1 = require("./BoundingBox");
+var GraphicalObject_1 = require("./GraphicalObject");
+var PointF2D_1 = require("../../Common/DataObjects/PointF2D");
+var GraphicalChordSymbolContainer = (function (_super) {
+    __extends(GraphicalChordSymbolContainer, _super);
+    function GraphicalChordSymbolContainer(chordSymbolContainer, parent, textHeight, transposeHalftones) {
+        _super.call(this);
+        this.chordSymbolContainer = chordSymbolContainer;
+        this.boundingBox = new BoundingBox_1.BoundingBox(this, parent);
+        this.calculateLabel(textHeight, transposeHalftones);
+    }
+    Object.defineProperty(GraphicalChordSymbolContainer.prototype, "GetChordSymbolContainer", {
+        get: function () {
+            return this.chordSymbolContainer;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalChordSymbolContainer.prototype, "GetGraphicalLabel", {
+        get: function () {
+            return this.graphicalLabel;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    GraphicalChordSymbolContainer.prototype.calculateLabel = function (textHeight, transposeHalftones) {
+        var text = ChordSymbolContainer_1.ChordSymbolContainer.calculateChordText(this.chordSymbolContainer, transposeHalftones);
+        this.graphicalLabel = new GraphicalLabel_1.GraphicalLabel(new Label_1.Label(text), textHeight, TextAlignment_1.TextAlignment.CenterBottom, this.boundingBox);
+        this.graphicalLabel.PositionAndShape.RelativePosition = new PointF2D_1.PointF2D(0.0, 0.0);
+        this.boundingBox.ChildElements.push(this.graphicalLabel.PositionAndShape);
+    };
+    return GraphicalChordSymbolContainer;
+}(GraphicalObject_1.GraphicalObject));
+exports.GraphicalChordSymbolContainer = GraphicalChordSymbolContainer;

+ 6 - 0
dist/src/MusicalScore/Graphical/GraphicalComment.d.ts

@@ -0,0 +1,6 @@
+import { GraphicalLabel } from "./GraphicalLabel";
+export declare class GraphicalComment {
+    constructor(label: GraphicalLabel, settingsLabel: GraphicalLabel);
+    label: GraphicalLabel;
+    settings: GraphicalLabel;
+}

+ 9 - 0
dist/src/MusicalScore/Graphical/GraphicalComment.js

@@ -0,0 +1,9 @@
+"use strict";
+var GraphicalComment = (function () {
+    function GraphicalComment(label, settingsLabel) {
+        this.label = label;
+        this.settings = settingsLabel;
+    }
+    return GraphicalComment;
+}());
+exports.GraphicalComment = GraphicalComment;

+ 10 - 0
dist/src/MusicalScore/Graphical/GraphicalLabel.d.ts

@@ -0,0 +1,10 @@
+import { Label } from "../Label";
+import { TextAlignment } from "../../Common/Enums/TextAlignment";
+import { Clickable } from "./Clickable";
+import { BoundingBox } from "./BoundingBox";
+export declare class GraphicalLabel extends Clickable {
+    private label;
+    constructor(label: Label, textHeight: number, alignment: TextAlignment, parent?: BoundingBox);
+    Label: Label;
+    setLabelPositionAndShapeBorders(): void;
+}

+ 102 - 0
dist/src/MusicalScore/Graphical/GraphicalLabel.js

@@ -0,0 +1,102 @@
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var TextAlignment_1 = require("../../Common/Enums/TextAlignment");
+var Clickable_1 = require("./Clickable");
+var BoundingBox_1 = require("./BoundingBox");
+var EngravingRules_1 = require("./EngravingRules");
+var MusicSheetCalculator_1 = require("./MusicSheetCalculator");
+var GraphicalLabel = (function (_super) {
+    __extends(GraphicalLabel, _super);
+    function GraphicalLabel(label, textHeight, alignment, parent) {
+        if (parent === void 0) { parent = undefined; }
+        _super.call(this);
+        this.label = label;
+        this.boundingBox = new BoundingBox_1.BoundingBox(this, parent);
+        this.label.fontHeight = textHeight;
+        this.label.textAlignment = alignment;
+    }
+    Object.defineProperty(GraphicalLabel.prototype, "Label", {
+        get: function () {
+            return this.label;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    GraphicalLabel.prototype.setLabelPositionAndShapeBorders = function () {
+        if (this.Label.text.trim() === "") {
+            return;
+        }
+        var labelMarginBorderFactor = EngravingRules_1.EngravingRules.Rules.LabelMarginBorderFactor;
+        var widthToHeightRatio = MusicSheetCalculator_1.MusicSheetCalculator.TextMeasurer.computeTextWidthToHeightRatio(this.Label.text, this.Label.font, this.Label.fontStyle);
+        var height = this.Label.fontHeight;
+        var width = height * widthToHeightRatio;
+        var psi = this.PositionAndShape;
+        switch (this.Label.textAlignment) {
+            case TextAlignment_1.TextAlignment.CenterBottom:
+                psi.BorderTop = -height;
+                psi.BorderLeft = -width / 2;
+                psi.BorderBottom = 0;
+                psi.BorderRight = width / 2;
+                break;
+            case TextAlignment_1.TextAlignment.CenterCenter:
+                psi.BorderTop = -height / 2;
+                psi.BorderLeft = -width / 2;
+                psi.BorderBottom = height / 2;
+                psi.BorderRight = width / 2;
+                break;
+            case TextAlignment_1.TextAlignment.CenterTop:
+                psi.BorderTop = 0;
+                psi.BorderLeft = -width / 2;
+                psi.BorderBottom = height;
+                psi.BorderRight = width / 2;
+                break;
+            case TextAlignment_1.TextAlignment.LeftBottom:
+                psi.BorderTop = -height;
+                psi.BorderLeft = 0;
+                psi.BorderBottom = 0;
+                psi.BorderRight = width;
+                break;
+            case TextAlignment_1.TextAlignment.LeftCenter:
+                psi.BorderTop = -height / 2;
+                psi.BorderLeft = 0;
+                psi.BorderBottom = height / 2;
+                psi.BorderRight = width;
+                break;
+            case TextAlignment_1.TextAlignment.LeftTop:
+                psi.BorderTop = 0;
+                psi.BorderLeft = 0;
+                psi.BorderBottom = height;
+                psi.BorderRight = width;
+                break;
+            case TextAlignment_1.TextAlignment.RightBottom:
+                psi.BorderTop = -height;
+                psi.BorderLeft = -width;
+                psi.BorderBottom = 0;
+                psi.BorderRight = 0;
+                break;
+            case TextAlignment_1.TextAlignment.RightCenter:
+                psi.BorderTop = -height / 2;
+                psi.BorderLeft = -width;
+                psi.BorderBottom = height / 2;
+                psi.BorderRight = 0;
+                break;
+            case TextAlignment_1.TextAlignment.RightTop:
+                psi.BorderTop = 0;
+                psi.BorderLeft = -width;
+                psi.BorderBottom = height;
+                psi.BorderRight = 0;
+                break;
+            default:
+        }
+        psi.BorderMarginTop = psi.BorderTop - height * labelMarginBorderFactor;
+        psi.BorderMarginLeft = psi.BorderLeft - height * labelMarginBorderFactor;
+        psi.BorderMarginBottom = psi.BorderBottom + height * labelMarginBorderFactor;
+        psi.BorderMarginRight = psi.BorderRight + height * labelMarginBorderFactor;
+    };
+    return GraphicalLabel;
+}(Clickable_1.Clickable));
+exports.GraphicalLabel = GraphicalLabel;

+ 12 - 0
dist/src/MusicalScore/Graphical/GraphicalLine.d.ts

@@ -0,0 +1,12 @@
+import { OutlineAndFillStyleEnum } from "./DrawingEnums";
+import { PointF2D } from "../../Common/DataObjects/PointF2D";
+export declare class GraphicalLine {
+    constructor(start: PointF2D, end: PointF2D, width?: number, styleEnum?: OutlineAndFillStyleEnum);
+    styleId: number;
+    private start;
+    private end;
+    private width;
+    Start: PointF2D;
+    End: PointF2D;
+    Width: number;
+}

+ 44 - 0
dist/src/MusicalScore/Graphical/GraphicalLine.js

@@ -0,0 +1,44 @@
+"use strict";
+var DrawingEnums_1 = require("./DrawingEnums");
+var GraphicalLine = (function () {
+    function GraphicalLine(start, end, width, styleEnum) {
+        if (width === void 0) { width = 0; }
+        if (styleEnum === void 0) { styleEnum = DrawingEnums_1.OutlineAndFillStyleEnum.BaseWritingColor; }
+        this.start = start;
+        this.end = end;
+        this.width = width;
+        this.styleId = styleEnum;
+    }
+    Object.defineProperty(GraphicalLine.prototype, "Start", {
+        get: function () {
+            return this.start;
+        },
+        set: function (value) {
+            this.start = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalLine.prototype, "End", {
+        get: function () {
+            return this.end;
+        },
+        set: function (value) {
+            this.end = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalLine.prototype, "Width", {
+        get: function () {
+            return this.width;
+        },
+        set: function (value) {
+            this.width = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    return GraphicalLine;
+}());
+exports.GraphicalLine = GraphicalLine;

+ 15 - 0
dist/src/MusicalScore/Graphical/GraphicalLyricEntry.d.ts

@@ -0,0 +1,15 @@
+import { LyricsEntry } from "../VoiceData/Lyrics/LyricsEntry";
+import { GraphicalLyricWord } from "./GraphicalLyricWord";
+import { GraphicalLabel } from "./GraphicalLabel";
+import { GraphicalStaffEntry } from "./GraphicalStaffEntry";
+export declare class GraphicalLyricEntry {
+    private lyricsEntry;
+    private graphicalLyricWord;
+    private graphicalLabel;
+    private graphicalStaffEntry;
+    constructor(lyricsEntry: LyricsEntry, graphicalStaffEntry: GraphicalStaffEntry, lyricsHeight: number, staffHeight: number);
+    GetLyricsEntry: LyricsEntry;
+    ParentLyricWord: GraphicalLyricWord;
+    GraphicalLabel: GraphicalLabel;
+    StaffEntryParent: GraphicalStaffEntry;
+}

+ 52 - 0
dist/src/MusicalScore/Graphical/GraphicalLyricEntry.js

@@ -0,0 +1,52 @@
+"use strict";
+var GraphicalLabel_1 = require("./GraphicalLabel");
+var Label_1 = require("../Label");
+var TextAlignment_1 = require("../../Common/Enums/TextAlignment");
+var PointF2D_1 = require("../../Common/DataObjects/PointF2D");
+var GraphicalLyricEntry = (function () {
+    function GraphicalLyricEntry(lyricsEntry, graphicalStaffEntry, lyricsHeight, staffHeight) {
+        this.lyricsEntry = lyricsEntry;
+        this.graphicalStaffEntry = graphicalStaffEntry;
+        this.graphicalLabel = new GraphicalLabel_1.GraphicalLabel(new Label_1.Label(lyricsEntry.Text), lyricsHeight, TextAlignment_1.TextAlignment.CenterBottom, graphicalStaffEntry.PositionAndShape);
+        this.graphicalLabel.PositionAndShape.RelativePosition = new PointF2D_1.PointF2D(0.0, staffHeight);
+    }
+    Object.defineProperty(GraphicalLyricEntry.prototype, "GetLyricsEntry", {
+        get: function () {
+            return this.lyricsEntry;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalLyricEntry.prototype, "ParentLyricWord", {
+        get: function () {
+            return this.graphicalLyricWord;
+        },
+        set: function (value) {
+            this.graphicalLyricWord = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalLyricEntry.prototype, "GraphicalLabel", {
+        get: function () {
+            return this.graphicalLabel;
+        },
+        set: function (value) {
+            this.graphicalLabel = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalLyricEntry.prototype, "StaffEntryParent", {
+        get: function () {
+            return this.graphicalStaffEntry;
+        },
+        set: function (value) {
+            this.graphicalStaffEntry = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    return GraphicalLyricEntry;
+}());
+exports.GraphicalLyricEntry = GraphicalLyricEntry;

+ 11 - 0
dist/src/MusicalScore/Graphical/GraphicalLyricWord.d.ts

@@ -0,0 +1,11 @@
+import { LyricWord } from "../VoiceData/Lyrics/LyricsWord";
+import { GraphicalLyricEntry } from "./GraphicalLyricEntry";
+export declare class GraphicalLyricWord {
+    private lyricWord;
+    private graphicalLyricsEntries;
+    constructor(lyricWord: LyricWord);
+    GetLyricWord: LyricWord;
+    GraphicalLyricsEntries: GraphicalLyricEntry[];
+    isFilled(): boolean;
+    private initialize();
+}

+ 40 - 0
dist/src/MusicalScore/Graphical/GraphicalLyricWord.js

@@ -0,0 +1,40 @@
+"use strict";
+var GraphicalLyricWord = (function () {
+    function GraphicalLyricWord(lyricWord) {
+        this.graphicalLyricsEntries = [];
+        this.lyricWord = lyricWord;
+        this.initialize();
+    }
+    Object.defineProperty(GraphicalLyricWord.prototype, "GetLyricWord", {
+        get: function () {
+            return this.lyricWord;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalLyricWord.prototype, "GraphicalLyricsEntries", {
+        get: function () {
+            return this.graphicalLyricsEntries;
+        },
+        set: function (value) {
+            this.graphicalLyricsEntries = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    GraphicalLyricWord.prototype.isFilled = function () {
+        for (var i = 0; i < this.graphicalLyricsEntries.length; i++) {
+            if (this.graphicalLyricsEntries[i] === undefined) {
+                return false;
+            }
+        }
+        return true;
+    };
+    GraphicalLyricWord.prototype.initialize = function () {
+        for (var i = 0; i < this.lyricWord.Syllables.length; i++) {
+            this.graphicalLyricsEntries.push(undefined);
+        }
+    };
+    return GraphicalLyricWord;
+}());
+exports.GraphicalLyricWord = GraphicalLyricWord;

+ 9 - 0
dist/src/MusicalScore/Graphical/GraphicalMarkedArea.d.ts

@@ -0,0 +1,9 @@
+import { GraphicalLabel } from "./GraphicalLabel";
+import { GraphicalRectangle } from "./GraphicalRectangle";
+export declare class GraphicalMarkedArea {
+    constructor(systemRectangle: GraphicalRectangle, labelRectangle?: GraphicalRectangle, label?: GraphicalLabel, settingsLabel?: GraphicalLabel);
+    systemRectangle: GraphicalRectangle;
+    labelRectangle: GraphicalRectangle;
+    label: GraphicalLabel;
+    settings: GraphicalLabel;
+}

+ 14 - 0
dist/src/MusicalScore/Graphical/GraphicalMarkedArea.js

@@ -0,0 +1,14 @@
+"use strict";
+var GraphicalMarkedArea = (function () {
+    function GraphicalMarkedArea(systemRectangle, labelRectangle, label, settingsLabel) {
+        if (labelRectangle === void 0) { labelRectangle = undefined; }
+        if (label === void 0) { label = undefined; }
+        if (settingsLabel === void 0) { settingsLabel = undefined; }
+        this.systemRectangle = systemRectangle;
+        this.labelRectangle = labelRectangle;
+        this.label = label;
+        this.settings = settingsLabel;
+    }
+    return GraphicalMarkedArea;
+}());
+exports.GraphicalMarkedArea = GraphicalMarkedArea;

+ 21 - 0
dist/src/MusicalScore/Graphical/GraphicalMusicPage.d.ts

@@ -0,0 +1,21 @@
+import { GraphicalObject } from "./GraphicalObject";
+import { GraphicalLabel } from "./GraphicalLabel";
+import { MusicSystem } from "./MusicSystem";
+import { EngravingRules } from "./EngravingRules";
+import { PointF2D } from "../../Common/DataObjects/PointF2D";
+import { GraphicalMusicSheet } from "./GraphicalMusicSheet";
+export declare class GraphicalMusicPage extends GraphicalObject {
+    private musicSystems;
+    private labels;
+    private parent;
+    constructor(parent: GraphicalMusicSheet);
+    MusicSystems: MusicSystem[];
+    Labels: GraphicalLabel[];
+    Parent: GraphicalMusicSheet;
+    setMusicPageAbsolutePosition(pageIndex: number, rules: EngravingRules): PointF2D;
+}
+export declare enum PagePlacementEnum {
+    Down = 0,
+    Right = 1,
+    RightDown = 2,
+}

+ 83 - 0
dist/src/MusicalScore/Graphical/GraphicalMusicPage.js

@@ -0,0 +1,83 @@
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var BoundingBox_1 = require("./BoundingBox");
+var GraphicalObject_1 = require("./GraphicalObject");
+var PointF2D_1 = require("../../Common/DataObjects/PointF2D");
+var GraphicalMusicPage = (function (_super) {
+    __extends(GraphicalMusicPage, _super);
+    function GraphicalMusicPage(parent) {
+        _super.call(this);
+        this.musicSystems = [];
+        this.labels = [];
+        this.parent = parent;
+        this.boundingBox = new BoundingBox_1.BoundingBox(this, undefined);
+    }
+    Object.defineProperty(GraphicalMusicPage.prototype, "MusicSystems", {
+        get: function () {
+            return this.musicSystems;
+        },
+        set: function (value) {
+            this.musicSystems = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicPage.prototype, "Labels", {
+        get: function () {
+            return this.labels;
+        },
+        set: function (value) {
+            this.labels = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicPage.prototype, "Parent", {
+        get: function () {
+            return this.parent;
+        },
+        set: function (value) {
+            this.parent = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    GraphicalMusicPage.prototype.setMusicPageAbsolutePosition = function (pageIndex, rules) {
+        if (rules.PagePlacement === PagePlacementEnum.Down) {
+            return new PointF2D_1.PointF2D(0.0, pageIndex * rules.PageHeight);
+        }
+        else if (rules.PagePlacement === PagePlacementEnum.Right) {
+            return new PointF2D_1.PointF2D(pageIndex * this.parent.ParentMusicSheet.pageWidth, 0.0);
+        }
+        else {
+            if (pageIndex % 2 === 0) {
+                if (pageIndex === 0) {
+                    return new PointF2D_1.PointF2D(0.0, pageIndex * rules.PageHeight);
+                }
+                else {
+                    return new PointF2D_1.PointF2D(0.0, (pageIndex - 1) * rules.PageHeight);
+                }
+            }
+            else {
+                if (pageIndex === 1) {
+                    return new PointF2D_1.PointF2D(this.parent.ParentMusicSheet.pageWidth, (pageIndex - 1) * rules.PageHeight);
+                }
+                else {
+                    return new PointF2D_1.PointF2D(this.parent.ParentMusicSheet.pageWidth, (pageIndex - 2) * rules.PageHeight);
+                }
+            }
+        }
+    };
+    return GraphicalMusicPage;
+}(GraphicalObject_1.GraphicalObject));
+exports.GraphicalMusicPage = GraphicalMusicPage;
+(function (PagePlacementEnum) {
+    PagePlacementEnum[PagePlacementEnum["Down"] = 0] = "Down";
+    PagePlacementEnum[PagePlacementEnum["Right"] = 1] = "Right";
+    PagePlacementEnum[PagePlacementEnum["RightDown"] = 2] = "RightDown";
+})(exports.PagePlacementEnum || (exports.PagePlacementEnum = {}));
+var PagePlacementEnum = exports.PagePlacementEnum;

+ 100 - 0
dist/src/MusicalScore/Graphical/GraphicalMusicSheet.d.ts

@@ -0,0 +1,100 @@
+import { MusicSheet } from "../MusicSheet";
+import { SourceMeasure } from "../VoiceData/SourceMeasure";
+import { StaffMeasure } from "./StaffMeasure";
+import { GraphicalMusicPage } from "./GraphicalMusicPage";
+import { VerticalGraphicalStaffEntryContainer } from "./VerticalGraphicalStaffEntryContainer";
+import { GraphicalLabel } from "./GraphicalLabel";
+import { GraphicalLine } from "./GraphicalLine";
+import { MusicSystem } from "./MusicSystem";
+import { GraphicalStaffEntry } from "./GraphicalStaffEntry";
+import { SourceStaffEntry } from "../VoiceData/SourceStaffEntry";
+import { PointF2D } from "../../Common/DataObjects/PointF2D";
+import { ClefInstruction } from "../VoiceData/Instructions/ClefInstruction";
+import { KeyInstruction } from "../VoiceData/Instructions/KeyInstruction";
+import { Fraction } from "../../Common/DataObjects/fraction";
+import { GraphicalNote } from "./GraphicalNote";
+import { Note } from "../VoiceData/Note";
+import { MusicSheetCalculator } from "./MusicSheetCalculator";
+import Dictionary from "typescript-collections/dist/lib/Dictionary";
+import { SelectionStartSymbol } from "./SelectionStartSymbol";
+import { SelectionEndSymbol } from "./SelectionEndSymbol";
+import { OutlineAndFillStyleEnum } from "./DrawingEnums";
+export declare class GraphicalMusicSheet {
+    constructor(musicSheet: MusicSheet, calculator: MusicSheetCalculator);
+    sourceToGraphicalMeasureLinks: Dictionary<SourceMeasure, StaffMeasure[]>;
+    private musicSheet;
+    private calculator;
+    private musicPages;
+    private measureList;
+    private verticalGraphicalStaffEntryContainers;
+    private title;
+    private subtitle;
+    private composer;
+    private lyricist;
+    private cursors;
+    private selectionStartSymbol;
+    private selectionEndSymbol;
+    private minAllowedSystemWidth;
+    private numberOfStaves;
+    private leadSheet;
+    ParentMusicSheet: MusicSheet;
+    GetCalculator: MusicSheetCalculator;
+    MusicPages: GraphicalMusicPage[];
+    MeasureList: StaffMeasure[][];
+    VerticalGraphicalStaffEntryContainers: VerticalGraphicalStaffEntryContainer[];
+    Title: GraphicalLabel;
+    Subtitle: GraphicalLabel;
+    Composer: GraphicalLabel;
+    Lyricist: GraphicalLabel;
+    Cursors: GraphicalLine[];
+    SelectionStartSymbol: SelectionStartSymbol;
+    SelectionEndSymbol: SelectionEndSymbol;
+    MinAllowedSystemWidth: number;
+    NumberOfStaves: number;
+    LeadSheet: boolean;
+    static transformRelativeToAbsolutePosition(graphicalMusicSheet: GraphicalMusicSheet): void;
+    Initialize(): void;
+    reCalculate(): void;
+    prepare(): void;
+    EnforceRedrawOfMusicSystems(): void;
+    getClickedObject<T>(positionOnMusicSheet: PointF2D): T;
+    findGraphicalStaffEntryFromMeasureList(staffIndex: number, measureIndex: number, sourceStaffEntry: SourceStaffEntry): GraphicalStaffEntry;
+    findNextGraphicalStaffEntry(staffIndex: number, measureIndex: number, graphicalStaffEntry: GraphicalStaffEntry): GraphicalStaffEntry;
+    getFirstVisibleMeasuresListFromIndeces(start: number, end: number): StaffMeasure[];
+    orderMeasuresByStaffLine(measures: StaffMeasure[]): StaffMeasure[][];
+    initializeActiveClefs(): ClefInstruction[];
+    GetMainKey(): KeyInstruction;
+    getOrCreateVerticalContainer(timestamp: Fraction): VerticalGraphicalStaffEntryContainer;
+    GetVerticalContainerFromTimestamp(timestamp: Fraction, startIndex?: number): VerticalGraphicalStaffEntryContainer;
+    GetInterpolatedIndexInVerticalContainers(musicTimestamp: Fraction): number;
+    getVisibleStavesIndecesFromSourceMeasure(visibleMeasures: StaffMeasure[]): number[];
+    getGraphicalMeasureFromSourceMeasureAndIndex(sourceMeasure: SourceMeasure, index: number): StaffMeasure;
+    getMeasureIndex(graphicalMeasure: StaffMeasure, measureIndex: number, inListIndex: number): boolean;
+    GetNearesNote(clickPosition: PointF2D, maxClickDist: PointF2D): GraphicalNote;
+    GetClickableLabel(clickPosition: PointF2D): GraphicalLabel;
+    GetNearestStaffEntry(clickPosition: PointF2D): GraphicalStaffEntry;
+    GetPossibleCommentAnchor(clickPosition: PointF2D): SourceStaffEntry;
+    getClickedObjectOfType<T>(positionOnMusicSheet: PointF2D): T;
+    tryGetTimestampFromPosition(positionOnMusicSheet: PointF2D): Fraction;
+    tryGetClickableLabel(positionOnMusicSheet: PointF2D): GraphicalLabel;
+    tryGetTimeStampFromPosition(positionOnMusicSheet: PointF2D): Fraction;
+    getStaffEntry(index: number): GraphicalStaffEntry;
+    GetPreviousVisibleContainerIndex(index: number): number;
+    GetNextVisibleContainerIndex(index: number): number;
+    findClosestLeftStaffEntry(fractionalIndex: number, searchOnlyVisibleEntries: boolean): GraphicalStaffEntry;
+    findClosestRightStaffEntry(fractionalIndex: number, returnOnlyVisibleEntries: boolean): GraphicalStaffEntry;
+    calculateCursorLineAtTimestamp(musicTimestamp: Fraction, styleEnum: OutlineAndFillStyleEnum): GraphicalLine;
+    calculateXPositionFromTimestamp(timeStamp: Fraction): [number, MusicSystem];
+    GetNumberOfVisibleInstruments(): number;
+    GetNumberOfFollowedInstruments(): number;
+    GetGraphicalFromSourceMeasure(sourceMeasure: SourceMeasure): StaffMeasure[];
+    GetGraphicalFromSourceStaffEntry(sourceStaffEntry: SourceStaffEntry): GraphicalStaffEntry;
+    GetGraphicalNoteFromSourceNote(note: Note, containingGse: GraphicalStaffEntry): GraphicalNote;
+    private CalculateDistance(pt1, pt2);
+    private getLongestStaffEntryDuration(index);
+}
+export declare class SystemImageProperties {
+    positionInPixels: PointF2D;
+    systemImageId: number;
+    system: MusicSystem;
+}

+ 812 - 0
dist/src/MusicalScore/Graphical/GraphicalMusicSheet.js

@@ -0,0 +1,812 @@
+"use strict";
+var VerticalGraphicalStaffEntryContainer_1 = require("./VerticalGraphicalStaffEntryContainer");
+var GraphicalLine_1 = require("./GraphicalLine");
+var PointF2D_1 = require("../../Common/DataObjects/PointF2D");
+var ClefInstruction_1 = require("../VoiceData/Instructions/ClefInstruction");
+var KeyInstruction_1 = require("../VoiceData/Instructions/KeyInstruction");
+var fraction_1 = require("../../Common/DataObjects/fraction");
+var BoundingBox_1 = require("./BoundingBox");
+var logging_1 = require("../../Common/logging");
+var Dictionary_1 = require("typescript-collections/dist/lib/Dictionary");
+var collectionUtil_1 = require("../../Util/collectionUtil");
+var GraphicalMusicSheet = (function () {
+    function GraphicalMusicSheet(musicSheet, calculator) {
+        this.musicPages = [];
+        this.measureList = [];
+        this.verticalGraphicalStaffEntryContainers = [];
+        this.cursors = [];
+        this.leadSheet = false;
+        this.musicSheet = musicSheet;
+        this.numberOfStaves = this.musicSheet.Staves.length;
+        this.calculator = calculator;
+        this.sourceToGraphicalMeasureLinks = new Dictionary_1.default();
+        this.calculator.initialize(this);
+    }
+    Object.defineProperty(GraphicalMusicSheet.prototype, "ParentMusicSheet", {
+        get: function () {
+            return this.musicSheet;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicSheet.prototype, "GetCalculator", {
+        get: function () {
+            return this.calculator;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicSheet.prototype, "MusicPages", {
+        get: function () {
+            return this.musicPages;
+        },
+        set: function (value) {
+            this.musicPages = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicSheet.prototype, "MeasureList", {
+        //public get FontInfo(): FontInfo {
+        //    return this.fontInfo;
+        //}
+        get: function () {
+            return this.measureList;
+        },
+        set: function (value) {
+            this.measureList = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicSheet.prototype, "VerticalGraphicalStaffEntryContainers", {
+        get: function () {
+            return this.verticalGraphicalStaffEntryContainers;
+        },
+        set: function (value) {
+            this.verticalGraphicalStaffEntryContainers = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicSheet.prototype, "Title", {
+        get: function () {
+            return this.title;
+        },
+        set: function (value) {
+            this.title = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicSheet.prototype, "Subtitle", {
+        get: function () {
+            return this.subtitle;
+        },
+        set: function (value) {
+            this.subtitle = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicSheet.prototype, "Composer", {
+        get: function () {
+            return this.composer;
+        },
+        set: function (value) {
+            this.composer = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicSheet.prototype, "Lyricist", {
+        get: function () {
+            return this.lyricist;
+        },
+        set: function (value) {
+            this.lyricist = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicSheet.prototype, "Cursors", {
+        get: function () {
+            return this.cursors;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicSheet.prototype, "SelectionStartSymbol", {
+        get: function () {
+            return this.selectionStartSymbol;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicSheet.prototype, "SelectionEndSymbol", {
+        get: function () {
+            return this.selectionEndSymbol;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicSheet.prototype, "MinAllowedSystemWidth", {
+        get: function () {
+            return this.minAllowedSystemWidth;
+        },
+        set: function (value) {
+            this.minAllowedSystemWidth = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicSheet.prototype, "NumberOfStaves", {
+        // public get SystemImages(): Dictionary<MusicSystem, SystemImageProperties> {
+        //     return this.systemImages;
+        // }
+        get: function () {
+            return this.numberOfStaves;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalMusicSheet.prototype, "LeadSheet", {
+        get: function () {
+            return this.leadSheet;
+        },
+        set: function (value) {
+            this.leadSheet = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    GraphicalMusicSheet.transformRelativeToAbsolutePosition = function (graphicalMusicSheet) {
+        for (var i = 0; i < graphicalMusicSheet.MusicPages.length; i++) {
+            var pageAbsolute = graphicalMusicSheet.MusicPages[i].setMusicPageAbsolutePosition(i, graphicalMusicSheet.ParentMusicSheet.rules);
+            var page = graphicalMusicSheet.MusicPages[i];
+            page.PositionAndShape.calculateAbsolutePositionsRecursive(pageAbsolute.x, pageAbsolute.y);
+        }
+    };
+    GraphicalMusicSheet.prototype.Initialize = function () {
+        this.verticalGraphicalStaffEntryContainers = [];
+        this.musicPages = [];
+        this.measureList = [];
+    };
+    GraphicalMusicSheet.prototype.reCalculate = function () {
+        this.calculator.calculate();
+    };
+    GraphicalMusicSheet.prototype.prepare = function () {
+        this.calculator.prepareGraphicalMusicSheet();
+    };
+    GraphicalMusicSheet.prototype.EnforceRedrawOfMusicSystems = function () {
+        for (var idx = 0, len = this.musicPages.length; idx < len; ++idx) {
+            var graphicalMusicPage = this.musicPages[idx];
+            for (var idx2 = 0, len2 = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
+                var musicSystem = graphicalMusicPage.MusicSystems[idx2];
+                musicSystem.needsToBeRedrawn = true;
+            }
+        }
+    };
+    GraphicalMusicSheet.prototype.getClickedObject = function (positionOnMusicSheet) {
+        for (var idx = 0, len = this.MusicPages.length; idx < len; ++idx) {
+            var graphicalMusicPage = this.MusicPages[idx];
+            return graphicalMusicPage.PositionAndShape.getClickedObjectOfType(positionOnMusicSheet);
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.findGraphicalStaffEntryFromMeasureList = function (staffIndex, measureIndex, sourceStaffEntry) {
+        for (var i = measureIndex; i < this.measureList.length; i++) {
+            var graphicalMeasure = this.measureList[i][staffIndex];
+            for (var idx = 0, len = graphicalMeasure.staffEntries.length; idx < len; ++idx) {
+                var graphicalStaffEntry = graphicalMeasure.staffEntries[idx];
+                if (graphicalStaffEntry.sourceStaffEntry === sourceStaffEntry) {
+                    return graphicalStaffEntry;
+                }
+            }
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.findNextGraphicalStaffEntry = function (staffIndex, measureIndex, graphicalStaffEntry) {
+        var graphicalMeasure = graphicalStaffEntry.parentMeasure;
+        var graphicalStaffEntryIndex = graphicalMeasure.staffEntries.indexOf(graphicalStaffEntry);
+        if (graphicalStaffEntryIndex < graphicalMeasure.staffEntries.length - 1) {
+            return graphicalMeasure.staffEntries[graphicalStaffEntryIndex + 1];
+        }
+        else if (measureIndex < this.measureList.length - 1) {
+            var nextMeasure = this.measureList[measureIndex + 1][staffIndex];
+            if (nextMeasure.staffEntries.length > 0) {
+                return nextMeasure.staffEntries[0];
+            }
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.getFirstVisibleMeasuresListFromIndeces = function (start, end) {
+        var graphicalMeasures = [];
+        var numberOfStaves = this.measureList[0].length;
+        for (var i = start; i <= end; i++) {
+            for (var j = 0; j < numberOfStaves; j++) {
+                if (this.measureList[i][j].isVisible()) {
+                    graphicalMeasures.push(this.measureList[i][j]);
+                    break;
+                }
+            }
+        }
+        return graphicalMeasures;
+    };
+    GraphicalMusicSheet.prototype.orderMeasuresByStaffLine = function (measures) {
+        var orderedMeasures = [];
+        var mList = [];
+        orderedMeasures.push(mList);
+        for (var i = 0; i < measures.length; i++) {
+            if (i === 0) {
+                mList.push(measures[0]);
+            }
+            else {
+                if (measures[i].ParentStaffLine === measures[i - 1].ParentStaffLine) {
+                    mList.push(measures[i]);
+                }
+                else {
+                    if (orderedMeasures.indexOf(mList) === -1) {
+                        orderedMeasures.push(mList);
+                    }
+                    mList = [];
+                    orderedMeasures.push(mList);
+                    mList.push(measures[i]);
+                }
+            }
+        }
+        return orderedMeasures;
+    };
+    GraphicalMusicSheet.prototype.initializeActiveClefs = function () {
+        var activeClefs = [];
+        var firstSourceMeasure = this.musicSheet.getFirstSourceMeasure();
+        if (firstSourceMeasure !== undefined) {
+            for (var i = 0; i < firstSourceMeasure.CompleteNumberOfStaves; i++) {
+                var clef = new ClefInstruction_1.ClefInstruction();
+                if (firstSourceMeasure.FirstInstructionsStaffEntries[i] !== undefined) {
+                    for (var idx = 0, len = firstSourceMeasure.FirstInstructionsStaffEntries[i].Instructions.length; idx < len; ++idx) {
+                        var abstractNotationInstruction = firstSourceMeasure.FirstInstructionsStaffEntries[i].Instructions[idx];
+                        if (abstractNotationInstruction instanceof ClefInstruction_1.ClefInstruction) {
+                            clef = abstractNotationInstruction;
+                        }
+                    }
+                }
+                activeClefs.push(clef);
+            }
+        }
+        return activeClefs;
+    };
+    GraphicalMusicSheet.prototype.GetMainKey = function () {
+        var firstSourceMeasure = this.musicSheet.getFirstSourceMeasure();
+        if (firstSourceMeasure !== undefined) {
+            for (var i = 0; i < firstSourceMeasure.CompleteNumberOfStaves; i++) {
+                for (var idx = 0, len = firstSourceMeasure.FirstInstructionsStaffEntries[i].Instructions.length; idx < len; ++idx) {
+                    var abstractNotationInstruction = firstSourceMeasure.FirstInstructionsStaffEntries[i].Instructions[idx];
+                    if (abstractNotationInstruction instanceof KeyInstruction_1.KeyInstruction) {
+                        return abstractNotationInstruction;
+                    }
+                }
+            }
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.getOrCreateVerticalContainer = function (timestamp) {
+        if (this.verticalGraphicalStaffEntryContainers.length === 0 ||
+            timestamp > collectionUtil_1.CollectionUtil.getLastElement(this.verticalGraphicalStaffEntryContainers).AbsoluteTimestamp) {
+            var verticalGraphicalStaffEntryContainer = new VerticalGraphicalStaffEntryContainer_1.VerticalGraphicalStaffEntryContainer(this.numberOfStaves, timestamp);
+            this.verticalGraphicalStaffEntryContainers.push(verticalGraphicalStaffEntryContainer);
+            return verticalGraphicalStaffEntryContainer;
+        }
+        var i;
+        for (; i >= 0; i--) {
+            if (this.verticalGraphicalStaffEntryContainers[i].AbsoluteTimestamp < timestamp) {
+                var verticalGraphicalStaffEntryContainer = new VerticalGraphicalStaffEntryContainer_1.VerticalGraphicalStaffEntryContainer(this.numberOfStaves, timestamp);
+                this.verticalGraphicalStaffEntryContainers.splice(i + 1, 0, verticalGraphicalStaffEntryContainer);
+                return verticalGraphicalStaffEntryContainer;
+            }
+            if (this.verticalGraphicalStaffEntryContainers[i].AbsoluteTimestamp === timestamp) {
+                return this.verticalGraphicalStaffEntryContainers[i];
+            }
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.GetVerticalContainerFromTimestamp = function (timestamp, startIndex) {
+        if (startIndex === void 0) { startIndex = 0; }
+        var index = collectionUtil_1.CollectionUtil.binarySearch(this.verticalGraphicalStaffEntryContainers, new VerticalGraphicalStaffEntryContainer_1.VerticalGraphicalStaffEntryContainer(0, timestamp), VerticalGraphicalStaffEntryContainer_1.VerticalGraphicalStaffEntryContainer.compareByTimestamp, startIndex, this.verticalGraphicalStaffEntryContainers.length - startIndex);
+        if (index >= 0) {
+            return this.verticalGraphicalStaffEntryContainers[index];
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.GetInterpolatedIndexInVerticalContainers = function (musicTimestamp) {
+        var containers = this.verticalGraphicalStaffEntryContainers;
+        var leftIndex = 0;
+        var rightIndex = containers.length - 1;
+        var foundIndex;
+        var leftTS = undefined;
+        var rightTS = undefined;
+        if (musicTimestamp <= containers[containers.length - 1].AbsoluteTimestamp) {
+            while (rightIndex - leftIndex > 1) {
+                var middleIndex = (rightIndex + leftIndex) / 2;
+                if (containers[leftIndex].AbsoluteTimestamp === musicTimestamp) {
+                    rightIndex = leftIndex;
+                    break;
+                }
+                else if (containers[rightIndex].AbsoluteTimestamp === musicTimestamp) {
+                    leftIndex = rightIndex;
+                    break;
+                }
+                else if (containers[middleIndex].AbsoluteTimestamp === musicTimestamp) {
+                    return this.verticalGraphicalStaffEntryContainers.indexOf(containers[middleIndex]);
+                }
+                else if (containers[middleIndex].AbsoluteTimestamp > musicTimestamp) {
+                    rightIndex = middleIndex;
+                }
+                else {
+                    leftIndex = middleIndex;
+                }
+            }
+            if (leftIndex === rightIndex) {
+                return this.verticalGraphicalStaffEntryContainers.indexOf(containers[leftIndex]);
+            }
+            leftTS = containers[leftIndex].AbsoluteTimestamp;
+            rightTS = containers[rightIndex].AbsoluteTimestamp;
+        }
+        else {
+            leftTS = containers[containers.length - 1].AbsoluteTimestamp;
+            rightTS = fraction_1.Fraction.plus(this.getLongestStaffEntryDuration(containers.length - 1), leftTS);
+            rightIndex = containers.length;
+        }
+        var diff = rightTS.RealValue - leftTS.RealValue;
+        var diffTS = rightTS.RealValue - musicTimestamp.RealValue;
+        foundIndex = rightIndex - (diffTS / diff);
+        return Math.min(foundIndex, this.verticalGraphicalStaffEntryContainers.length);
+    };
+    GraphicalMusicSheet.prototype.getVisibleStavesIndecesFromSourceMeasure = function (visibleMeasures) {
+        var visibleInstruments = [];
+        var visibleStavesIndeces = [];
+        for (var idx = 0, len = visibleMeasures.length; idx < len; ++idx) {
+            var graphicalMeasure = visibleMeasures[idx];
+            var instrument = graphicalMeasure.ParentStaff.ParentInstrument;
+            if (visibleInstruments.indexOf(instrument) === -1) {
+                visibleInstruments.push(instrument);
+            }
+        }
+        for (var idx = 0, len = visibleInstruments.length; idx < len; ++idx) {
+            var instrument = visibleInstruments[idx];
+            var index = this.musicSheet.getGlobalStaffIndexOfFirstStaff(instrument);
+            for (var j = 0; j < instrument.Staves.length; j++) {
+                visibleStavesIndeces.push(index + j);
+            }
+        }
+        return visibleStavesIndeces;
+    };
+    GraphicalMusicSheet.prototype.getGraphicalMeasureFromSourceMeasureAndIndex = function (sourceMeasure, index) {
+        for (var i = 0; i < this.measureList.length; i++) {
+            if (this.measureList[i][0].parentSourceMeasure === sourceMeasure) {
+                return this.measureList[i][index];
+            }
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.getMeasureIndex = function (graphicalMeasure, measureIndex, inListIndex) {
+        measureIndex = 0;
+        inListIndex = 0;
+        for (; measureIndex < this.measureList.length; measureIndex++) {
+            for (var idx = 0, len = this.measureList[measureIndex].length; idx < len; ++idx) {
+                var measure = this.measureList[measureIndex][idx];
+                if (measure === graphicalMeasure) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    };
+    GraphicalMusicSheet.prototype.GetNearesNote = function (clickPosition, maxClickDist) {
+        var initialSearchArea = 10;
+        var foundNotes = [];
+        var region = new BoundingBox_1.BoundingBox();
+        region.BorderLeft = clickPosition.x - initialSearchArea;
+        region.BorderTop = clickPosition.y - initialSearchArea;
+        region.BorderRight = clickPosition.x + initialSearchArea;
+        region.BorderBottom = clickPosition.y + initialSearchArea;
+        region.AbsolutePosition = new PointF2D_1.PointF2D(0, 0);
+        for (var idx = 0, len = this.MusicPages.length; idx < len; ++idx) {
+            var graphicalMusicPage = this.MusicPages[idx];
+            var entries = graphicalMusicPage.PositionAndShape.getObjectsInRegion(region);
+            //let entriesArr: GraphicalNote[] = __as__<GraphicalNote[]>(entries, GraphicalNote[]) ? ? entries;
+            if (entries === undefined) {
+                continue;
+            }
+            else {
+                for (var idx2 = 0, len2 = entries.length; idx2 < len2; ++idx2) {
+                    var note = entries[idx2];
+                    if (Math.abs(note.PositionAndShape.AbsolutePosition.x - clickPosition.x) < maxClickDist.x
+                        && Math.abs(note.PositionAndShape.AbsolutePosition.y - clickPosition.y) < maxClickDist.y) {
+                        foundNotes.push(note);
+                    }
+                }
+            }
+        }
+        var closest = undefined;
+        for (var idx = 0, len = foundNotes.length; idx < len; ++idx) {
+            var note = foundNotes[idx];
+            if (closest === undefined) {
+                closest = note;
+            }
+            else {
+                if (note.parentStaffEntry.relInMeasureTimestamp === undefined) {
+                    continue;
+                }
+                var deltaNew = this.CalculateDistance(note.PositionAndShape.AbsolutePosition, clickPosition);
+                var deltaOld = this.CalculateDistance(closest.PositionAndShape.AbsolutePosition, clickPosition);
+                if (deltaNew < deltaOld) {
+                    closest = note;
+                }
+            }
+        }
+        if (closest !== undefined) {
+            return closest;
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.GetClickableLabel = function (clickPosition) {
+        var initialSearchAreaX = 4;
+        var initialSearchAreaY = 4;
+        var region = new BoundingBox_1.BoundingBox();
+        region.BorderLeft = clickPosition.x - initialSearchAreaX;
+        region.BorderTop = clickPosition.y - initialSearchAreaY;
+        region.BorderRight = clickPosition.x + initialSearchAreaX;
+        region.BorderBottom = clickPosition.y + initialSearchAreaY;
+        region.AbsolutePosition = new PointF2D_1.PointF2D(0, 0);
+        for (var idx = 0, len = this.MusicPages.length; idx < len; ++idx) {
+            var graphicalMusicPage = this.MusicPages[idx];
+            var entries = graphicalMusicPage.PositionAndShape.getObjectsInRegion(region);
+            if (entries.length !== 1) {
+                continue;
+            }
+            else {
+                for (var idx2 = 0, len2 = entries.length; idx2 < len2; ++idx2) {
+                    var clickedLabel = entries[idx2];
+                    return clickedLabel;
+                }
+            }
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.GetNearestStaffEntry = function (clickPosition) {
+        var initialSearchArea = 10;
+        var foundEntries = [];
+        var region = new BoundingBox_1.BoundingBox(undefined);
+        region.BorderLeft = clickPosition.x - initialSearchArea;
+        region.BorderTop = clickPosition.y - initialSearchArea;
+        region.BorderRight = clickPosition.x + initialSearchArea;
+        region.BorderBottom = clickPosition.y + initialSearchArea;
+        region.AbsolutePosition = new PointF2D_1.PointF2D(0, 0);
+        for (var idx = 0, len = this.MusicPages.length; idx < len; ++idx) {
+            var graphicalMusicPage = this.MusicPages[idx];
+            var entries = graphicalMusicPage.PositionAndShape.getObjectsInRegion(region, false);
+            if (entries === undefined || entries.length === 0) {
+                continue;
+            }
+            else {
+                for (var idx2 = 0, len2 = entries.length; idx2 < len2; ++idx2) {
+                    var gse = entries[idx2];
+                    foundEntries.push(gse);
+                }
+            }
+        }
+        var closest = undefined;
+        for (var idx = 0, len = foundEntries.length; idx < len; ++idx) {
+            var gse = foundEntries[idx];
+            if (closest === undefined) {
+                closest = gse;
+            }
+            else {
+                if (gse.relInMeasureTimestamp === undefined) {
+                    continue;
+                }
+                var deltaNew = this.CalculateDistance(gse.PositionAndShape.AbsolutePosition, clickPosition);
+                var deltaOld = this.CalculateDistance(closest.PositionAndShape.AbsolutePosition, clickPosition);
+                if (deltaNew < deltaOld) {
+                    closest = gse;
+                }
+            }
+        }
+        if (closest !== undefined) {
+            return closest;
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.GetPossibleCommentAnchor = function (clickPosition) {
+        var entry = this.GetNearestStaffEntry(clickPosition);
+        if (entry === undefined) {
+            return undefined;
+        }
+        return entry.sourceStaffEntry;
+    };
+    GraphicalMusicSheet.prototype.getClickedObjectOfType = function (positionOnMusicSheet) {
+        for (var idx = 0, len = this.musicPages.length; idx < len; ++idx) {
+            var page = this.musicPages[idx];
+            var o = page.PositionAndShape.getClickedObjectOfType(positionOnMusicSheet);
+            if (o !== undefined) {
+                return o;
+            }
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.tryGetTimestampFromPosition = function (positionOnMusicSheet) {
+        var entry = this.getClickedObjectOfType(positionOnMusicSheet);
+        if (entry === undefined) {
+            return undefined;
+        }
+        return entry.getAbsoluteTimestamp();
+    };
+    GraphicalMusicSheet.prototype.tryGetClickableLabel = function (positionOnMusicSheet) {
+        try {
+            return this.GetClickableLabel(positionOnMusicSheet);
+        }
+        catch (ex) {
+            logging_1.Logging.log("GraphicalMusicSheet.tryGetClickableObject", "positionOnMusicSheet: " + positionOnMusicSheet, ex);
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.tryGetTimeStampFromPosition = function (positionOnMusicSheet) {
+        try {
+            var entry = this.GetNearestStaffEntry(positionOnMusicSheet);
+            if (entry === undefined) {
+                return undefined;
+            }
+            return entry.getAbsoluteTimestamp();
+        }
+        catch (ex) {
+            logging_1.Logging.log("GraphicalMusicSheet.tryGetTimeStampFromPosition", "positionOnMusicSheet: " + positionOnMusicSheet, ex);
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.getStaffEntry = function (index) {
+        var container = this.VerticalGraphicalStaffEntryContainers[index];
+        var staffEntry = undefined;
+        try {
+            for (var idx = 0, len = container.StaffEntries.length; idx < len; ++idx) {
+                var entry = container.StaffEntries[idx];
+                if (entry === undefined || !entry.sourceStaffEntry.ParentStaff.ParentInstrument.Visible) {
+                    continue;
+                }
+                if (staffEntry === undefined) {
+                    staffEntry = entry;
+                }
+                else if (entry.PositionAndShape !== undefined && staffEntry.PositionAndShape !== undefined) {
+                    if (staffEntry.PositionAndShape.RelativePosition.x > entry.PositionAndShape.RelativePosition.x) {
+                        staffEntry = entry;
+                    }
+                }
+            }
+        }
+        catch (ex) {
+            logging_1.Logging.log("GraphicalMusicSheet.getStaffEntry", ex);
+        }
+        return staffEntry;
+    };
+    GraphicalMusicSheet.prototype.GetPreviousVisibleContainerIndex = function (index) {
+        for (var i = index - 1; i >= 0; i--) {
+            var entries = this.verticalGraphicalStaffEntryContainers[i].StaffEntries;
+            for (var idx = 0, len = entries.length; idx < len; ++idx) {
+                var entry = entries[idx];
+                if (entry !== undefined && entry.sourceStaffEntry.ParentStaff.ParentInstrument.Visible) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    };
+    GraphicalMusicSheet.prototype.GetNextVisibleContainerIndex = function (index) {
+        for (var i = index + 1; i < this.verticalGraphicalStaffEntryContainers.length; ++i) {
+            var entries = this.verticalGraphicalStaffEntryContainers[i].StaffEntries;
+            for (var idx = 0, len = entries.length; idx < len; ++idx) {
+                var entry = entries[idx];
+                if (entry !== undefined && entry.sourceStaffEntry.ParentStaff.ParentInstrument.Visible) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    };
+    GraphicalMusicSheet.prototype.findClosestLeftStaffEntry = function (fractionalIndex, searchOnlyVisibleEntries) {
+        var foundEntry = undefined;
+        var leftIndex = Math.floor(fractionalIndex);
+        leftIndex = Math.min(this.VerticalGraphicalStaffEntryContainers.length - 1, leftIndex);
+        for (var i = leftIndex; i >= 0; i--) {
+            foundEntry = this.getStaffEntry(i);
+            if (foundEntry !== undefined) {
+                if (searchOnlyVisibleEntries) {
+                    if (foundEntry.sourceStaffEntry.ParentStaff.ParentInstrument.Visible) {
+                        return foundEntry;
+                    }
+                }
+                else {
+                    return foundEntry;
+                }
+            }
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.findClosestRightStaffEntry = function (fractionalIndex, returnOnlyVisibleEntries) {
+        var foundEntry = undefined;
+        var rightIndex = Math.max(0, Math.ceil(fractionalIndex));
+        for (var i = rightIndex; i < this.VerticalGraphicalStaffEntryContainers.length; i++) {
+            foundEntry = this.getStaffEntry(i);
+            if (foundEntry !== undefined) {
+                if (returnOnlyVisibleEntries) {
+                    if (foundEntry.sourceStaffEntry.ParentStaff.ParentInstrument.Visible) {
+                        return foundEntry;
+                    }
+                }
+                else {
+                    return foundEntry;
+                }
+            }
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.calculateCursorLineAtTimestamp = function (musicTimestamp, styleEnum) {
+        var result = this.calculateXPositionFromTimestamp(musicTimestamp);
+        var xPos = result[0];
+        var correspondingMusicSystem = result[1];
+        if (correspondingMusicSystem === undefined || correspondingMusicSystem.StaffLines.length === 0) {
+            return undefined;
+        }
+        var yCoordinate = correspondingMusicSystem.PositionAndShape.AbsolutePosition.y;
+        var height = collectionUtil_1.CollectionUtil.last(correspondingMusicSystem.StaffLines).PositionAndShape.RelativePosition.y + 4;
+        return new GraphicalLine_1.GraphicalLine(new PointF2D_1.PointF2D(xPos, yCoordinate), new PointF2D_1.PointF2D(xPos, yCoordinate + height), 3, styleEnum);
+    };
+    GraphicalMusicSheet.prototype.calculateXPositionFromTimestamp = function (timeStamp) {
+        var currentMusicSystem = undefined;
+        var fractionalIndex = this.GetInterpolatedIndexInVerticalContainers(timeStamp);
+        var previousStaffEntry = this.findClosestLeftStaffEntry(fractionalIndex, true);
+        var nextStaffEntry = this.findClosestRightStaffEntry(fractionalIndex, true);
+        var currentTimeStamp = timeStamp.RealValue;
+        if (previousStaffEntry === undefined && nextStaffEntry === undefined) {
+            return [0, undefined];
+        }
+        var previousStaffEntryMusicSystem = undefined;
+        if (previousStaffEntry !== undefined) {
+            previousStaffEntryMusicSystem = previousStaffEntry.parentMeasure.ParentStaffLine.ParentMusicSystem;
+        }
+        else {
+            previousStaffEntryMusicSystem = nextStaffEntry.parentMeasure.ParentStaffLine.ParentMusicSystem;
+        }
+        var nextStaffEntryMusicSystem = undefined;
+        if (nextStaffEntry !== undefined) {
+            nextStaffEntryMusicSystem = nextStaffEntry.parentMeasure.ParentStaffLine.ParentMusicSystem;
+        }
+        else {
+            nextStaffEntryMusicSystem = previousStaffEntry.parentMeasure.ParentStaffLine.ParentMusicSystem;
+        }
+        if (previousStaffEntryMusicSystem === nextStaffEntryMusicSystem) {
+            currentMusicSystem = previousStaffEntryMusicSystem;
+            var fraction = void 0;
+            var previousStaffEntryPositionX = void 0;
+            var nextStaffEntryPositionX = void 0;
+            if (previousStaffEntry === undefined) {
+                previousStaffEntryPositionX = nextStaffEntryPositionX = nextStaffEntry.PositionAndShape.AbsolutePosition.x;
+                fraction = 0;
+            }
+            else if (nextStaffEntry === undefined) {
+                previousStaffEntryPositionX = previousStaffEntry.PositionAndShape.AbsolutePosition.x;
+                nextStaffEntryPositionX = currentMusicSystem.GetRightBorderAbsoluteXPosition();
+                var sm = previousStaffEntry.parentMeasure.parentSourceMeasure;
+                fraction = (currentTimeStamp - previousStaffEntry.getAbsoluteTimestamp().RealValue) / (fraction_1.Fraction.plus(sm.AbsoluteTimestamp, sm.Duration).RealValue - previousStaffEntry.getAbsoluteTimestamp().RealValue);
+            }
+            else {
+                previousStaffEntryPositionX = previousStaffEntry.PositionAndShape.AbsolutePosition.x;
+                nextStaffEntryPositionX = nextStaffEntry.PositionAndShape.AbsolutePosition.x;
+                if (previousStaffEntry === nextStaffEntry) {
+                    fraction = 0;
+                }
+                else {
+                    fraction = (currentTimeStamp - previousStaffEntry.getAbsoluteTimestamp().RealValue) /
+                        (nextStaffEntry.getAbsoluteTimestamp().RealValue - previousStaffEntry.getAbsoluteTimestamp().RealValue);
+                }
+            }
+            fraction = Math.min(1, Math.max(0, fraction));
+            var interpolatedXPosition = previousStaffEntryPositionX + fraction * (nextStaffEntryPositionX - previousStaffEntryPositionX);
+            return [interpolatedXPosition, currentMusicSystem];
+        }
+        else {
+            var nextSystemLeftBorderTimeStamp = nextStaffEntry.parentMeasure.parentSourceMeasure.AbsoluteTimestamp.RealValue;
+            var fraction = void 0;
+            var interpolatedXPosition = void 0;
+            if (currentTimeStamp < nextSystemLeftBorderTimeStamp) {
+                currentMusicSystem = previousStaffEntryMusicSystem;
+                var previousStaffEntryPositionX = previousStaffEntry.PositionAndShape.AbsolutePosition.x;
+                var previousSystemRightBorderX = currentMusicSystem.GetRightBorderAbsoluteXPosition();
+                fraction = (currentTimeStamp - previousStaffEntry.getAbsoluteTimestamp().RealValue) /
+                    (nextSystemLeftBorderTimeStamp - previousStaffEntry.getAbsoluteTimestamp().RealValue);
+                fraction = Math.min(1, Math.max(0, fraction));
+                interpolatedXPosition = previousStaffEntryPositionX + fraction * (previousSystemRightBorderX - previousStaffEntryPositionX);
+            }
+            else {
+                currentMusicSystem = nextStaffEntryMusicSystem;
+                var nextStaffEntryPositionX = nextStaffEntry.PositionAndShape.AbsolutePosition.x;
+                var nextSystemLeftBorderX = currentMusicSystem.GetLeftBorderAbsoluteXPosition();
+                fraction = (currentTimeStamp - nextSystemLeftBorderTimeStamp) /
+                    (nextStaffEntry.getAbsoluteTimestamp().RealValue - nextSystemLeftBorderTimeStamp);
+                fraction = Math.min(1, Math.max(0, fraction));
+                interpolatedXPosition = nextSystemLeftBorderX + fraction * (nextStaffEntryPositionX - nextSystemLeftBorderX);
+            }
+            return [interpolatedXPosition, currentMusicSystem];
+        }
+    };
+    GraphicalMusicSheet.prototype.GetNumberOfVisibleInstruments = function () {
+        var visibleInstrumentCount = 0;
+        for (var idx = 0, len = this.musicSheet.Instruments.length; idx < len; ++idx) {
+            var instrument = this.musicSheet.Instruments[idx];
+            if (instrument.Visible === true) {
+                visibleInstrumentCount++;
+            }
+        }
+        return visibleInstrumentCount;
+    };
+    GraphicalMusicSheet.prototype.GetNumberOfFollowedInstruments = function () {
+        var followedInstrumentCount = 0;
+        for (var idx = 0, len = this.musicSheet.Instruments.length; idx < len; ++idx) {
+            var instrument = this.musicSheet.Instruments[idx];
+            if (instrument.Following === true) {
+                followedInstrumentCount++;
+            }
+        }
+        return followedInstrumentCount;
+    };
+    GraphicalMusicSheet.prototype.GetGraphicalFromSourceMeasure = function (sourceMeasure) {
+        return this.sourceToGraphicalMeasureLinks.getValue(sourceMeasure);
+    };
+    GraphicalMusicSheet.prototype.GetGraphicalFromSourceStaffEntry = function (sourceStaffEntry) {
+        var graphicalMeasure = this.GetGraphicalFromSourceMeasure(sourceStaffEntry.VerticalContainerParent.ParentMeasure)[sourceStaffEntry.ParentStaff.idInMusicSheet];
+        return graphicalMeasure.findGraphicalStaffEntryFromTimestamp(sourceStaffEntry.Timestamp);
+    };
+    GraphicalMusicSheet.prototype.GetGraphicalNoteFromSourceNote = function (note, containingGse) {
+        for (var idx = 0, len = containingGse.notes.length; idx < len; ++idx) {
+            var graphicalNotes = containingGse.notes[idx];
+            for (var idx2 = 0, len2 = graphicalNotes.length; idx2 < len2; ++idx2) {
+                var graphicalNote = graphicalNotes[idx2];
+                if (graphicalNote.sourceNote === note) {
+                    return graphicalNote;
+                }
+            }
+        }
+        return undefined;
+    };
+    GraphicalMusicSheet.prototype.CalculateDistance = function (pt1, pt2) {
+        var deltaX = pt1.x - pt2.x;
+        var deltaY = pt1.y - pt2.y;
+        return (deltaX * deltaX) + (deltaY * deltaY);
+    };
+    GraphicalMusicSheet.prototype.getLongestStaffEntryDuration = function (index) {
+        var maxLength = new fraction_1.Fraction(0, 1);
+        for (var idx = 0, len = this.verticalGraphicalStaffEntryContainers[index].StaffEntries.length; idx < len; ++idx) {
+            var graphicalStaffEntry = this.verticalGraphicalStaffEntryContainers[index].StaffEntries[idx];
+            if (graphicalStaffEntry === undefined) {
+                continue;
+            }
+            for (var idx2 = 0, len2 = graphicalStaffEntry.notes.length; idx2 < len2; ++idx2) {
+                var graphicalNotes = graphicalStaffEntry.notes[idx2];
+                for (var idx3 = 0, len3 = graphicalNotes.length; idx3 < len3; ++idx3) {
+                    var note = graphicalNotes[idx3];
+                    if (note.graphicalNoteLength > maxLength) {
+                        maxLength = note.graphicalNoteLength;
+                    }
+                }
+            }
+        }
+        return maxLength;
+    };
+    return GraphicalMusicSheet;
+}());
+exports.GraphicalMusicSheet = GraphicalMusicSheet;
+var SystemImageProperties = (function () {
+    function SystemImageProperties() {
+    }
+    return SystemImageProperties;
+}());
+exports.SystemImageProperties = SystemImageProperties;

+ 16 - 0
dist/src/MusicalScore/Graphical/GraphicalNote.d.ts

@@ -0,0 +1,16 @@
+import { Note } from "../VoiceData/Note";
+import { Fraction } from "../../Common/DataObjects/fraction";
+import { KeyInstruction } from "../VoiceData/Instructions/KeyInstruction";
+import { ClefInstruction } from "../VoiceData/Instructions/ClefInstruction";
+import { OctaveEnum } from "../VoiceData/Expressions/ContinuousExpressions/octaveShift";
+import { Pitch } from "../../Common/DataObjects/pitch";
+import { GraphicalStaffEntry } from "./GraphicalStaffEntry";
+import { GraphicalObject } from "./GraphicalObject";
+export declare class GraphicalNote extends GraphicalObject {
+    constructor(note: Note, parent: GraphicalStaffEntry);
+    sourceNote: Note;
+    graphicalNoteLength: Fraction;
+    parentStaffEntry: GraphicalStaffEntry;
+    ParentList: GraphicalNote[];
+    Transpose(keyInstruction: KeyInstruction, activeClef: ClefInstruction, halfTones: number, octaveEnum: OctaveEnum): Pitch;
+}

+ 40 - 0
dist/src/MusicalScore/Graphical/GraphicalNote.js

@@ -0,0 +1,40 @@
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var GraphicalObject_1 = require("./GraphicalObject");
+var MusicSheetCalculator_1 = require("./MusicSheetCalculator");
+var BoundingBox_1 = require("./BoundingBox");
+var GraphicalNote = (function (_super) {
+    __extends(GraphicalNote, _super);
+    function GraphicalNote(note, parent) {
+        _super.call(this);
+        this.sourceNote = note;
+        this.parentStaffEntry = parent;
+        this.PositionAndShape = new BoundingBox_1.BoundingBox(this, parent.PositionAndShape);
+    }
+    Object.defineProperty(GraphicalNote.prototype, "ParentList", {
+        get: function () {
+            for (var idx = 0, len = this.parentStaffEntry.notes.length; idx < len; ++idx) {
+                var graphicalNotes = this.parentStaffEntry.notes[idx];
+                if (graphicalNotes.indexOf(this) !== -1) {
+                    return graphicalNotes;
+                }
+            }
+            return undefined;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    GraphicalNote.prototype.Transpose = function (keyInstruction, activeClef, halfTones, octaveEnum) {
+        var transposedPitch = this.sourceNote.Pitch;
+        if (MusicSheetCalculator_1.MusicSheetCalculator.transposeCalculator !== undefined) {
+            transposedPitch = MusicSheetCalculator_1.MusicSheetCalculator.transposeCalculator.transposePitch(this.sourceNote.Pitch, keyInstruction, halfTones);
+        }
+        return transposedPitch;
+    };
+    return GraphicalNote;
+}(GraphicalObject_1.GraphicalObject));
+exports.GraphicalNote = GraphicalNote;

+ 5 - 0
dist/src/MusicalScore/Graphical/GraphicalObject.d.ts

@@ -0,0 +1,5 @@
+import { BoundingBox } from "./BoundingBox";
+export declare class GraphicalObject {
+    protected boundingBox: BoundingBox;
+    PositionAndShape: BoundingBox;
+}

+ 17 - 0
dist/src/MusicalScore/Graphical/GraphicalObject.js

@@ -0,0 +1,17 @@
+"use strict";
+var GraphicalObject = (function () {
+    function GraphicalObject() {
+    }
+    Object.defineProperty(GraphicalObject.prototype, "PositionAndShape", {
+        get: function () {
+            return this.boundingBox;
+        },
+        set: function (value) {
+            this.boundingBox = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    return GraphicalObject;
+}());
+exports.GraphicalObject = GraphicalObject;

+ 16 - 0
dist/src/MusicalScore/Graphical/GraphicalOctaveShift.d.ts

@@ -0,0 +1,16 @@
+import { GraphicalObject } from "./GraphicalObject";
+import { OctaveShift } from "../VoiceData/Expressions/ContinuousExpressions/octaveShift";
+import { BoundingBox } from "./BoundingBox";
+import { MusicSymbol } from "./MusicSymbol";
+import { PointF2D } from "../../Common/DataObjects/PointF2D";
+export declare class GraphicalOctaveShift extends GraphicalObject {
+    constructor(octaveShift: OctaveShift, parent: BoundingBox);
+    getOctaveShift: OctaveShift;
+    octaveSymbol: MusicSymbol;
+    dashesStart: PointF2D;
+    dashesEnd: PointF2D;
+    endsOnDifferentStaffLine: boolean;
+    isFirstPart: boolean;
+    isSecondPart: boolean;
+    private setSymbol();
+}

+ 42 - 0
dist/src/MusicalScore/Graphical/GraphicalOctaveShift.js

@@ -0,0 +1,42 @@
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var GraphicalObject_1 = require("./GraphicalObject");
+var octaveShift_1 = require("../VoiceData/Expressions/ContinuousExpressions/octaveShift");
+var BoundingBox_1 = require("./BoundingBox");
+var MusicSymbol_1 = require("./MusicSymbol");
+var Exceptions_1 = require("../Exceptions");
+var GraphicalOctaveShift = (function (_super) {
+    __extends(GraphicalOctaveShift, _super);
+    function GraphicalOctaveShift(octaveShift, parent) {
+        _super.call(this);
+        this.getOctaveShift = octaveShift;
+        this.setSymbol();
+        // ToDo: set the size again due to the given symbol...
+        //this.PositionAndShape = new BoundingBox(parent, this.octaveSymbol, this);
+        this.PositionAndShape = new BoundingBox_1.BoundingBox(this, parent);
+    }
+    GraphicalOctaveShift.prototype.setSymbol = function () {
+        switch (this.getOctaveShift.Type) {
+            case octaveShift_1.OctaveEnum.VA8:
+                this.octaveSymbol = MusicSymbol_1.MusicSymbol.VA8;
+                break;
+            case octaveShift_1.OctaveEnum.VB8:
+                this.octaveSymbol = MusicSymbol_1.MusicSymbol.VB8;
+                break;
+            case octaveShift_1.OctaveEnum.MA15:
+                this.octaveSymbol = MusicSymbol_1.MusicSymbol.MA15;
+                break;
+            case octaveShift_1.OctaveEnum.MB15:
+                this.octaveSymbol = MusicSymbol_1.MusicSymbol.MB15;
+                break;
+            default:
+                throw new Exceptions_1.ArgumentOutOfRangeException("");
+        }
+    };
+    return GraphicalOctaveShift;
+}(GraphicalObject_1.GraphicalObject));
+exports.GraphicalOctaveShift = GraphicalOctaveShift;

+ 8 - 0
dist/src/MusicalScore/Graphical/GraphicalRectangle.d.ts

@@ -0,0 +1,8 @@
+import { OutlineAndFillStyleEnum } from "./DrawingEnums";
+import { BoundingBox } from "./BoundingBox";
+import { PointF2D } from "../../Common/DataObjects/PointF2D";
+import { GraphicalObject } from "./GraphicalObject";
+export declare class GraphicalRectangle extends GraphicalObject {
+    constructor(upperLeftPoint: PointF2D, lowerRightPoint: PointF2D, parent: BoundingBox, style: OutlineAndFillStyleEnum);
+    style: OutlineAndFillStyleEnum;
+}

+ 21 - 0
dist/src/MusicalScore/Graphical/GraphicalRectangle.js

@@ -0,0 +1,21 @@
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var BoundingBox_1 = require("./BoundingBox");
+var GraphicalObject_1 = require("./GraphicalObject");
+var GraphicalRectangle = (function (_super) {
+    __extends(GraphicalRectangle, _super);
+    function GraphicalRectangle(upperLeftPoint, lowerRightPoint, parent, style) {
+        _super.call(this);
+        this.boundingBox = new BoundingBox_1.BoundingBox(parent);
+        this.boundingBox.RelativePosition = upperLeftPoint;
+        this.boundingBox.BorderRight = lowerRightPoint.x - upperLeftPoint.x;
+        this.boundingBox.BorderBottom = lowerRightPoint.y - upperLeftPoint.y;
+        this.style = style;
+    }
+    return GraphicalRectangle;
+}(GraphicalObject_1.GraphicalObject));
+exports.GraphicalRectangle = GraphicalRectangle;

+ 50 - 0
dist/src/MusicalScore/Graphical/GraphicalStaffEntry.d.ts

@@ -0,0 +1,50 @@
+import { SourceStaffEntry } from "../VoiceData/SourceStaffEntry";
+import { Fraction } from "../../Common/DataObjects/fraction";
+import { VerticalGraphicalStaffEntryContainer } from "./VerticalGraphicalStaffEntryContainer";
+import { Note } from "../VoiceData/Note";
+import { Slur } from "../VoiceData/Expressions/ContinuousExpressions/Slur";
+import { Voice } from "../VoiceData/Voice";
+import { VoiceEntry } from "../VoiceData/VoiceEntry";
+import { GraphicalTie } from "./GraphicalTie";
+import { GraphicalObject } from "./GraphicalObject";
+import { StaffMeasure } from "./StaffMeasure";
+import { GraphicalNote } from "./GraphicalNote";
+import { GraphicalChordSymbolContainer } from "./GraphicalChordSymbolContainer";
+import { GraphicalLyricEntry } from "./GraphicalLyricEntry";
+import { AbstractGraphicalInstruction } from "./AbstractGraphicalInstruction";
+import { GraphicalStaffEntryLink } from "./GraphicalStaffEntryLink";
+export declare abstract class GraphicalStaffEntry extends GraphicalObject {
+    constructor(parentMeasure: StaffMeasure, sourceStaffEntry?: SourceStaffEntry, staffEntryParent?: GraphicalStaffEntry);
+    graphicalChordContainer: GraphicalChordSymbolContainer;
+    graphicalLink: GraphicalStaffEntryLink;
+    relInMeasureTimestamp: Fraction;
+    sourceStaffEntry: SourceStaffEntry;
+    parentMeasure: StaffMeasure;
+    notes: GraphicalNote[][];
+    graceStaffEntriesBefore: GraphicalStaffEntry[];
+    graceStaffEntriesAfter: GraphicalStaffEntry[];
+    staffEntryParent: GraphicalStaffEntry;
+    parentVerticalContainer: VerticalGraphicalStaffEntryContainer;
+    private graphicalInstructions;
+    private graphicalTies;
+    private lyricsEntries;
+    GraphicalInstructions: AbstractGraphicalInstruction[];
+    GraphicalTies: GraphicalTie[];
+    LyricsEntries: GraphicalLyricEntry[];
+    getAbsoluteTimestamp(): Fraction;
+    findEndTieGraphicalNoteFromNote(tieNote: Note): GraphicalNote;
+    findEndTieGraphicalNoteFromNoteWithStartingSlur(tieNote: Note, slur: Slur): GraphicalNote;
+    findEndTieGraphicalNoteFromNoteWithEndingSlur(tieNote: Note): GraphicalNote;
+    findGraphicalNoteFromGraceNote(graceNote: Note): GraphicalNote;
+    findGraphicalNoteFromNote(baseNote: Note): GraphicalNote;
+    getGraphicalNoteDurationFromVoice(voice: Voice): Fraction;
+    findLinkedNotes(notLinkedNotes: GraphicalNote[]): void;
+    findVoiceEntryGraphicalNotes(voiceEntry: VoiceEntry): GraphicalNote[];
+    isVoiceEntryPartOfLinkedVoiceEntry(voiceEntry: VoiceEntry): boolean;
+    getMainVoice(): Voice;
+    findStaffEntryMinNoteLength(): Fraction;
+    findStaffEntryMaxNoteLength(): Fraction;
+    findOrCreateGraphicalNotesListFromVoiceEntry(voiceEntry: VoiceEntry): GraphicalNote[];
+    findOrCreateGraphicalNotesListFromGraphicalNote(graphicalNote: GraphicalNote): GraphicalNote[];
+    addGraphicalNoteToListAtCorrectYPosition(graphicalNotes: GraphicalNote[], graphicalNote: GraphicalNote): void;
+}

+ 273 - 0
dist/src/MusicalScore/Graphical/GraphicalStaffEntry.js

@@ -0,0 +1,273 @@
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var BoundingBox_1 = require("./BoundingBox");
+var fraction_1 = require("../../Common/DataObjects/fraction");
+var LinkedVoice_1 = require("../VoiceData/LinkedVoice");
+var GraphicalObject_1 = require("./GraphicalObject");
+var collectionUtil_1 = require("../../Util/collectionUtil");
+var GraphicalStaffEntry = (function (_super) {
+    __extends(GraphicalStaffEntry, _super);
+    function GraphicalStaffEntry(parentMeasure, sourceStaffEntry, staffEntryParent) {
+        if (sourceStaffEntry === void 0) { sourceStaffEntry = undefined; }
+        if (staffEntryParent === void 0) { staffEntryParent = undefined; }
+        _super.call(this);
+        this.graphicalInstructions = [];
+        this.graphicalTies = [];
+        this.lyricsEntries = [];
+        this.parentMeasure = parentMeasure;
+        this.notes = [];
+        this.graceStaffEntriesBefore = [];
+        this.graceStaffEntriesAfter = [];
+        this.sourceStaffEntry = sourceStaffEntry;
+        if (staffEntryParent !== undefined) {
+            this.staffEntryParent = staffEntryParent;
+            this.parentVerticalContainer = staffEntryParent.parentVerticalContainer;
+            this.PositionAndShape = new BoundingBox_1.BoundingBox(this, staffEntryParent.PositionAndShape);
+        }
+        else {
+            this.PositionAndShape = new BoundingBox_1.BoundingBox(this, parentMeasure.PositionAndShape);
+        }
+        if (sourceStaffEntry !== undefined) {
+            this.relInMeasureTimestamp = sourceStaffEntry.Timestamp;
+        }
+    }
+    Object.defineProperty(GraphicalStaffEntry.prototype, "GraphicalInstructions", {
+        get: function () {
+            return this.graphicalInstructions;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalStaffEntry.prototype, "GraphicalTies", {
+        get: function () {
+            return this.graphicalTies;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalStaffEntry.prototype, "LyricsEntries", {
+        get: function () {
+            return this.lyricsEntries;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    GraphicalStaffEntry.prototype.getAbsoluteTimestamp = function () {
+        var result = fraction_1.Fraction.createFromFraction(this.parentMeasure.parentSourceMeasure.AbsoluteTimestamp);
+        if (this.relInMeasureTimestamp !== undefined) {
+            result.Add(this.relInMeasureTimestamp);
+        }
+        return result;
+    };
+    GraphicalStaffEntry.prototype.findEndTieGraphicalNoteFromNote = function (tieNote) {
+        for (var idx = 0, len = this.notes.length; idx < len; ++idx) {
+            var graphicalNotes = this.notes[idx];
+            for (var idx2 = 0, len2 = graphicalNotes.length; idx2 < len2; ++idx2) {
+                var graphicalNote = graphicalNotes[idx2];
+                var note = graphicalNote.sourceNote;
+                if (note.Pitch !== undefined && note.Pitch.FundamentalNote === tieNote.Pitch.FundamentalNote
+                    && note.Pitch.Octave === tieNote.Pitch.Octave && note.getAbsoluteTimestamp() === tieNote.getAbsoluteTimestamp()) {
+                    return graphicalNote;
+                }
+            }
+        }
+        return undefined;
+    };
+    GraphicalStaffEntry.prototype.findEndTieGraphicalNoteFromNoteWithStartingSlur = function (tieNote, slur) {
+        for (var idx = 0, len = this.notes.length; idx < len; ++idx) {
+            var graphicalNotes = this.notes[idx];
+            for (var idx2 = 0, len2 = graphicalNotes.length; idx2 < len2; ++idx2) {
+                var graphicalNote = graphicalNotes[idx2];
+                var note = graphicalNote.sourceNote;
+                if (note.NoteTie !== undefined && note.NoteSlurs.indexOf(slur) !== -1) {
+                    return graphicalNote;
+                }
+            }
+        }
+        return undefined;
+    };
+    GraphicalStaffEntry.prototype.findEndTieGraphicalNoteFromNoteWithEndingSlur = function (tieNote) {
+        for (var idx = 0, len = this.notes.length; idx < len; ++idx) {
+            var graphicalNotes = this.notes[idx];
+            for (var idx2 = 0, len2 = graphicalNotes.length; idx2 < len2; ++idx2) {
+                var graphicalNote = graphicalNotes[idx2];
+                var note = graphicalNote.sourceNote;
+                if (note.Pitch !== undefined && note.Pitch.FundamentalNote === tieNote.Pitch.FundamentalNote
+                    && note.Pitch.Octave === tieNote.Pitch.Octave && this.getAbsoluteTimestamp() === tieNote.getAbsoluteTimestamp()) {
+                    return graphicalNote;
+                }
+            }
+        }
+        return undefined;
+    };
+    GraphicalStaffEntry.prototype.findGraphicalNoteFromGraceNote = function (graceNote) {
+        for (var idx = 0, len = this.notes.length; idx < len; ++idx) {
+            var graphicalNotes = this.notes[idx];
+            for (var idx2 = 0, len2 = graphicalNotes.length; idx2 < len2; ++idx2) {
+                var graphicalNote = graphicalNotes[idx2];
+                if (graphicalNote.sourceNote === graceNote) {
+                    return graphicalNote;
+                }
+            }
+        }
+        return undefined;
+    };
+    GraphicalStaffEntry.prototype.findGraphicalNoteFromNote = function (baseNote) {
+        for (var idx = 0, len = this.notes.length; idx < len; ++idx) {
+            var graphicalNotes = this.notes[idx];
+            for (var idx2 = 0, len2 = graphicalNotes.length; idx2 < len2; ++idx2) {
+                var graphicalNote = graphicalNotes[idx2];
+                if (graphicalNote.sourceNote === baseNote && this.getAbsoluteTimestamp() === baseNote.getAbsoluteTimestamp()) {
+                    return graphicalNote;
+                }
+            }
+        }
+        return undefined;
+    };
+    GraphicalStaffEntry.prototype.getGraphicalNoteDurationFromVoice = function (voice) {
+        for (var idx = 0, len = this.notes.length; idx < len; ++idx) {
+            var graphicalNotes = this.notes[idx];
+            if (graphicalNotes[0].sourceNote.ParentVoiceEntry.ParentVoice === voice) {
+                return graphicalNotes[0].graphicalNoteLength;
+            }
+        }
+        return new fraction_1.Fraction(0, 1);
+    };
+    GraphicalStaffEntry.prototype.findLinkedNotes = function (notLinkedNotes) {
+        if (this.sourceStaffEntry !== undefined && this.sourceStaffEntry.Link !== undefined) {
+            for (var idx = 0, len = this.notes.length; idx < len; ++idx) {
+                var graphicalNotes = this.notes[idx];
+                for (var idx2 = 0, len2 = graphicalNotes.length; idx2 < len2; ++idx2) {
+                    var graphicalNote = graphicalNotes[idx2];
+                    if (graphicalNote.parentStaffEntry === this) {
+                        notLinkedNotes.push(graphicalNote);
+                    }
+                }
+            }
+        }
+    };
+    GraphicalStaffEntry.prototype.findVoiceEntryGraphicalNotes = function (voiceEntry) {
+        for (var idx = 0, len = this.notes.length; idx < len; ++idx) {
+            var graphicalNotes = this.notes[idx];
+            for (var idx2 = 0, len2 = graphicalNotes.length; idx2 < len2; ++idx2) {
+                var graphicalNote = graphicalNotes[idx2];
+                if (graphicalNote.sourceNote.ParentVoiceEntry === voiceEntry) {
+                    return graphicalNotes;
+                }
+            }
+        }
+        return undefined;
+    };
+    GraphicalStaffEntry.prototype.isVoiceEntryPartOfLinkedVoiceEntry = function (voiceEntry) {
+        if (this.sourceStaffEntry.Link !== undefined) {
+            for (var idx = 0, len = this.sourceStaffEntry.Link.LinkStaffEntries.length; idx < len; ++idx) {
+                var sEntry = this.sourceStaffEntry.Link.LinkStaffEntries[idx];
+                if (sEntry.VoiceEntries.indexOf(voiceEntry) !== -1 && sEntry !== this.sourceStaffEntry) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    };
+    GraphicalStaffEntry.prototype.getMainVoice = function () {
+        for (var idx = 0, len = this.sourceStaffEntry.VoiceEntries.length; idx < len; ++idx) {
+            var voiceEntry = this.sourceStaffEntry.VoiceEntries[idx];
+            if (!(voiceEntry.ParentVoice instanceof LinkedVoice_1.LinkedVoice)) {
+                return voiceEntry.ParentVoice;
+            }
+        }
+        return this.notes[0][0].sourceNote.ParentVoiceEntry.ParentVoice;
+    };
+    GraphicalStaffEntry.prototype.findStaffEntryMinNoteLength = function () {
+        var minLength = new fraction_1.Fraction(Number.MAX_VALUE, 1);
+        for (var idx = 0, len = this.notes.length; idx < len; ++idx) {
+            var graphicalNotes = this.notes[idx];
+            for (var idx2 = 0, len2 = graphicalNotes.length; idx2 < len2; ++idx2) {
+                var graphicalNote = graphicalNotes[idx2];
+                var calNoteLen = graphicalNote.graphicalNoteLength;
+                if (calNoteLen < minLength && calNoteLen.Numerator > 0) {
+                    minLength = calNoteLen;
+                }
+            }
+        }
+        return minLength;
+    };
+    GraphicalStaffEntry.prototype.findStaffEntryMaxNoteLength = function () {
+        var maxLength = new fraction_1.Fraction(0, 1);
+        for (var idx = 0, len = this.notes.length; idx < len; ++idx) {
+            var graphicalNotes = this.notes[idx];
+            for (var idx2 = 0, len2 = graphicalNotes.length; idx2 < len2; ++idx2) {
+                var graphicalNote = graphicalNotes[idx2];
+                var calNoteLen = graphicalNote.graphicalNoteLength;
+                if (calNoteLen > maxLength && calNoteLen.Numerator > 0) {
+                    maxLength = calNoteLen;
+                }
+            }
+        }
+        return maxLength;
+    };
+    GraphicalStaffEntry.prototype.findOrCreateGraphicalNotesListFromVoiceEntry = function (voiceEntry) {
+        var graphicalNotes;
+        if (this.notes.length === 0) {
+            graphicalNotes = [];
+            this.notes.push(graphicalNotes);
+        }
+        else {
+            for (var i = 0; i < this.notes.length; i++) {
+                if (this.notes[i][0].sourceNote.ParentVoiceEntry.ParentVoice === voiceEntry.ParentVoice) {
+                    return this.notes[i];
+                }
+            }
+            graphicalNotes = [];
+            this.notes.push(graphicalNotes);
+        }
+        return graphicalNotes;
+    };
+    GraphicalStaffEntry.prototype.findOrCreateGraphicalNotesListFromGraphicalNote = function (graphicalNote) {
+        var graphicalNotes;
+        var tieStartSourceStaffEntry = graphicalNote.sourceNote.ParentStaffEntry;
+        if (this.sourceStaffEntry !== tieStartSourceStaffEntry) {
+            graphicalNotes = this.findOrCreateGraphicalNotesListFromVoiceEntry(graphicalNote.sourceNote.ParentVoiceEntry);
+        }
+        else {
+            if (this.notes.length === 0) {
+                graphicalNotes = [];
+                this.notes.push(graphicalNotes);
+            }
+            else {
+                for (var i = 0; i < this.notes.length; i++) {
+                    if (this.notes[i][0].sourceNote.ParentVoiceEntry.ParentVoice === graphicalNote.sourceNote.ParentVoiceEntry.ParentVoice) {
+                        return this.notes[i];
+                    }
+                }
+                graphicalNotes = [];
+                this.notes.push(graphicalNotes);
+            }
+        }
+        return graphicalNotes;
+    };
+    GraphicalStaffEntry.prototype.addGraphicalNoteToListAtCorrectYPosition = function (graphicalNotes, graphicalNote) {
+        if (graphicalNotes.length === 0 ||
+            graphicalNote.PositionAndShape.RelativePosition.y < collectionUtil_1.CollectionUtil.last(graphicalNotes).PositionAndShape.RelativePosition.Y) {
+            graphicalNotes.push(graphicalNote);
+        }
+        else {
+            for (var i = graphicalNotes.length - 1; i >= 0; i--) {
+                if (graphicalNotes[i].PositionAndShape.RelativePosition.y > graphicalNote.PositionAndShape.RelativePosition.y) {
+                    graphicalNotes.splice(i + 1, 0, graphicalNote);
+                    break;
+                }
+                if (i === 0) {
+                    graphicalNotes.splice(0, 0, graphicalNote);
+                    break;
+                }
+            }
+        }
+    };
+    return GraphicalStaffEntry;
+}(GraphicalObject_1.GraphicalObject));
+exports.GraphicalStaffEntry = GraphicalStaffEntry;

+ 13 - 0
dist/src/MusicalScore/Graphical/GraphicalStaffEntryLink.d.ts

@@ -0,0 +1,13 @@
+import { StaffEntryLink } from "../VoiceData/StaffEntryLink";
+import { GraphicalStaffEntry } from "./GraphicalStaffEntry";
+import { GraphicalNote } from "./GraphicalNote";
+export declare class GraphicalStaffEntryLink {
+    private staffEntryLink;
+    private graphicalLinkedStaffEntries;
+    constructor(staffEntryLink: StaffEntryLink);
+    GetStaffEntryLink: StaffEntryLink;
+    GraphicalLinkedStaffEntries: GraphicalStaffEntry[];
+    isFilled(): boolean;
+    getLinkedStaffEntriesGraphicalNotes(graphicalStaffEntry: GraphicalStaffEntry): GraphicalNote[];
+    private initialize();
+}

+ 60 - 0
dist/src/MusicalScore/Graphical/GraphicalStaffEntryLink.js

@@ -0,0 +1,60 @@
+"use strict";
+var GraphicalStaffEntryLink = (function () {
+    function GraphicalStaffEntryLink(staffEntryLink) {
+        this.graphicalLinkedStaffEntries = [];
+        this.staffEntryLink = staffEntryLink;
+        this.initialize();
+    }
+    Object.defineProperty(GraphicalStaffEntryLink.prototype, "GetStaffEntryLink", {
+        get: function () {
+            return this.staffEntryLink;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalStaffEntryLink.prototype, "GraphicalLinkedStaffEntries", {
+        get: function () {
+            return this.graphicalLinkedStaffEntries;
+        },
+        set: function (value) {
+            this.graphicalLinkedStaffEntries = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    GraphicalStaffEntryLink.prototype.isFilled = function () {
+        for (var i = 0; i < this.graphicalLinkedStaffEntries.length; i++) {
+            if (this.graphicalLinkedStaffEntries[i] === undefined) {
+                return false;
+            }
+        }
+        return true;
+    };
+    GraphicalStaffEntryLink.prototype.getLinkedStaffEntriesGraphicalNotes = function (graphicalStaffEntry) {
+        if (this.graphicalLinkedStaffEntries.indexOf(graphicalStaffEntry) !== -1) {
+            var notes = [];
+            for (var idx = 0, len = this.graphicalLinkedStaffEntries.length; idx < len; ++idx) {
+                var graphicalLinkedStaffEntry = this.graphicalLinkedStaffEntries[idx];
+                for (var idx2 = 0, len2 = graphicalLinkedStaffEntry.notes.length; idx2 < len2; ++idx2) {
+                    var graphicalNotes = graphicalLinkedStaffEntry.notes[idx2];
+                    for (var idx3 = 0, len3 = graphicalNotes.length; idx3 < len3; ++idx3) {
+                        var graphicalNote = graphicalNotes[idx3];
+                        if (graphicalNote.sourceNote.ParentStaffEntry.Link !== undefined
+                            && graphicalNote.sourceNote.ParentVoiceEntry === this.staffEntryLink.GetVoiceEntry) {
+                            notes.push(graphicalNote);
+                        }
+                    }
+                }
+            }
+            return notes;
+        }
+        return undefined;
+    };
+    GraphicalStaffEntryLink.prototype.initialize = function () {
+        for (var idx = 0, len = this.staffEntryLink.LinkStaffEntries.length; idx < len; ++idx) {
+            this.graphicalLinkedStaffEntries.push(undefined);
+        }
+    };
+    return GraphicalStaffEntryLink;
+}());
+exports.GraphicalStaffEntryLink = GraphicalStaffEntryLink;

+ 11 - 0
dist/src/MusicalScore/Graphical/GraphicalTie.d.ts

@@ -0,0 +1,11 @@
+import { Tie } from "../VoiceData/Tie";
+import { GraphicalNote } from "./GraphicalNote";
+export declare class GraphicalTie {
+    private tie;
+    private startNote;
+    private endNote;
+    constructor(tie: Tie, start?: GraphicalNote, end?: GraphicalNote);
+    GetTie: Tie;
+    StartNote: GraphicalNote;
+    EndNote: GraphicalNote;
+}

+ 39 - 0
dist/src/MusicalScore/Graphical/GraphicalTie.js

@@ -0,0 +1,39 @@
+"use strict";
+var GraphicalTie = (function () {
+    function GraphicalTie(tie, start, end) {
+        if (start === void 0) { start = undefined; }
+        if (end === void 0) { end = undefined; }
+        this.tie = tie;
+        this.startNote = start;
+        this.endNote = end;
+    }
+    Object.defineProperty(GraphicalTie.prototype, "GetTie", {
+        get: function () {
+            return this.tie;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalTie.prototype, "StartNote", {
+        get: function () {
+            return this.startNote;
+        },
+        set: function (value) {
+            this.startNote = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(GraphicalTie.prototype, "EndNote", {
+        get: function () {
+            return this.endNote;
+        },
+        set: function (value) {
+            this.endNote = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    return GraphicalTie;
+}());
+exports.GraphicalTie = GraphicalTie;

+ 137 - 0
dist/src/MusicalScore/Graphical/MusicSheetCalculator.d.ts

@@ -0,0 +1,137 @@
+import { GraphicalStaffEntry } from "./GraphicalStaffEntry";
+import { StaffLine } from "./StaffLine";
+import { GraphicalMusicSheet } from "./GraphicalMusicSheet";
+import { EngravingRules } from "./EngravingRules";
+import { Tie } from "../VoiceData/Tie";
+import { Fraction } from "../../Common/DataObjects/fraction";
+import { Note } from "../VoiceData/Note";
+import { StaffMeasure } from "./StaffMeasure";
+import { ClefInstruction } from "../VoiceData/Instructions/ClefInstruction";
+import { LyricWord } from "../VoiceData/Lyrics/LyricsWord";
+import { SourceMeasure } from "../VoiceData/SourceMeasure";
+import { GraphicalMusicPage } from "./GraphicalMusicPage";
+import { GraphicalNote } from "./GraphicalNote";
+import { Beam } from "../VoiceData/Beam";
+import { OctaveEnum } from "../VoiceData/Expressions/ContinuousExpressions/octaveShift";
+import { LyricsEntry } from "../VoiceData/Lyrics/LyricsEntry";
+import { VoiceEntry } from "../VoiceData/VoiceEntry";
+import { OrnamentContainer } from "../VoiceData/OrnamentContainer";
+import { ArticulationEnum } from "../VoiceData/VoiceEntry";
+import { Tuplet } from "../VoiceData/Tuplet";
+import { MusicSystem } from "./MusicSystem";
+import { GraphicalTie } from "./GraphicalTie";
+import { RepetitionInstruction } from "../VoiceData/Instructions/RepetitionInstruction";
+import { MultiExpression } from "../VoiceData/Expressions/multiExpression";
+import { StaffEntryLink } from "../VoiceData/StaffEntryLink";
+import { MultiTempoExpression } from "../VoiceData/Expressions/multiTempoExpression";
+import { Repetition } from "../MusicSource/Repetition";
+import { PointF2D } from "../../Common/DataObjects/PointF2D";
+import { SourceStaffEntry } from "../VoiceData/SourceStaffEntry";
+import { BoundingBox } from "./BoundingBox";
+import { IGraphicalSymbolFactory } from "../Interfaces/IGraphicalSymbolFactory";
+import { ITextMeasurer } from "../Interfaces/ITextMeasurer";
+import { ITransposeCalculator } from "../Interfaces/ITransposeCalculator";
+import { OctaveShiftParams } from "./OctaveShiftParams";
+import { AccidentalCalculator } from "./AccidentalCalculator";
+import Dictionary from "typescript-collections/dist/lib/Dictionary";
+export declare abstract class MusicSheetCalculator {
+    static transposeCalculator: ITransposeCalculator;
+    protected static textMeasurer: ITextMeasurer;
+    protected staffEntriesWithGraphicalTies: GraphicalStaffEntry[];
+    protected staffEntriesWithOrnaments: GraphicalStaffEntry[];
+    protected staffEntriesWithChordSymbols: GraphicalStaffEntry[];
+    protected staffLinesWithLyricWords: StaffLine[];
+    protected staffLinesWithGraphicalExpressions: StaffLine[];
+    protected graphicalMusicSheet: GraphicalMusicSheet;
+    protected rules: EngravingRules;
+    protected symbolFactory: IGraphicalSymbolFactory;
+    constructor(symbolFactory: IGraphicalSymbolFactory);
+    static TextMeasurer: ITextMeasurer;
+    protected leadSheet: boolean;
+    private static addTieToTieTimestampsDict(tieTimestampListDict, note);
+    private static setMeasuresMinStaffEntriesWidth(measures, minimumStaffEntriesWidth);
+    initialize(graphicalMusicSheet: GraphicalMusicSheet): void;
+    prepareGraphicalMusicSheet(): void;
+    calculate(): void;
+    calculateXLayout(graphicalMusicSheet: GraphicalMusicSheet, maxInstrNameLabelLength: number): void;
+    protected calculateMeasureXLayout(measures: StaffMeasure[]): number;
+    protected calculateSystemYLayout(): void;
+    protected initStaffMeasuresCreation(): void;
+    protected handleBeam(graphicalNote: GraphicalNote, beam: Beam, openBeams: Beam[]): void;
+    protected createGraphicalTieNote(beams: Beam[], activeClef: ClefInstruction, octaveShiftValue: OctaveEnum, graphicalStaffEntry: GraphicalStaffEntry, duration: Fraction, numberOfDots: number, openTie: Tie, isLastTieNote: boolean): void;
+    protected handleVoiceEntryLyrics(lyricsEntries: Dictionary<number, LyricsEntry>, voiceEntry: VoiceEntry, graphicalStaffEntry: GraphicalStaffEntry, openLyricWords: LyricWord[]): void;
+    protected handleVoiceEntryOrnaments(ornamentContainer: OrnamentContainer, voiceEntry: VoiceEntry, graphicalStaffEntry: GraphicalStaffEntry): void;
+    protected handleVoiceEntryArticulations(articulations: ArticulationEnum[], voiceEntry: VoiceEntry, graphicalStaffEntry: GraphicalStaffEntry): void;
+    protected handleTuplet(graphicalNote: GraphicalNote, tuplet: Tuplet, openTuplets: Tuplet[]): void;
+    protected layoutVoiceEntry(voiceEntry: VoiceEntry, graphicalNotes: GraphicalNote[], graphicalStaffEntry: GraphicalStaffEntry, hasPitchedNote: boolean, isGraceStaffEntry: boolean): void;
+    protected layoutStaffEntry(graphicalStaffEntry: GraphicalStaffEntry): void;
+    protected handleTie(tie: Tie, startGraphicalStaffEntry: GraphicalStaffEntry, staffIndex: number, measureIndex: number): void;
+    protected updateStaffLineBorders(staffLine: StaffLine): void;
+    protected calculateMeasureNumberPlacement(musicSystem: MusicSystem): void;
+    protected layoutGraphicalTie(tie: GraphicalTie, tieIsAtSystemBreak: boolean): void;
+    protected calculateSingleStaffLineLyricsPosition(staffLine: StaffLine, lyricVersesNumber: number[]): void;
+    protected calculateSingleOctaveShift(sourceMeasure: SourceMeasure, multiExpression: MultiExpression, measureIndex: number, staffIndex: number): void;
+    protected calculateWordRepetitionInstruction(repetitionInstruction: RepetitionInstruction, measureIndex: number): void;
+    protected calculateMoodAndUnknownExpression(multiExpression: MultiExpression, measureIndex: number, staffIndex: number): void;
+    protected clearRecreatedObjects(): void;
+    protected handleStaffEntryLink(graphicalStaffEntry: GraphicalStaffEntry, staffEntryLinks: StaffEntryLink[]): void;
+    protected calculateMusicSystems(): void;
+    protected updateSkyBottomLine(staffLine: StaffLine): void;
+    protected calculateSkyBottomLine(staffLine: StaffLine): void;
+    protected calculateMarkedAreas(): void;
+    protected calculateComments(): void;
+    protected optimizeStaffLineDynamicExpressionsPositions(): void;
+    protected calculateChordSymbols(): void;
+    protected layoutMeasureWithWholeRest(rest: GraphicalNote, gse: GraphicalStaffEntry, measure: StaffMeasure): void;
+    protected layoutBeams(staffEntry: GraphicalStaffEntry): void;
+    protected layoutArticulationMarks(articulations: ArticulationEnum[], voiceEntry: VoiceEntry, graphicalStaffEntry: GraphicalStaffEntry): void;
+    protected layoutOrnament(ornaments: OrnamentContainer, voiceEntry: VoiceEntry, graphicalStaffEntry: GraphicalStaffEntry): void;
+    protected calculateRestNotePlacementWithinGraphicalBeam(graphicalStaffEntry: GraphicalStaffEntry, restNote: GraphicalNote, previousNote: GraphicalNote, nextStaffEntry: GraphicalStaffEntry, nextNote: GraphicalNote): void;
+    protected calculateTupletNumbers(): void;
+    protected calculateSlurs(): void;
+    protected calculateDynamicExpressionsForSingleMultiExpression(multiExpression: MultiExpression, measureIndex: number, staffIndex: number): void;
+    protected calcGraphicalRepetitionEndingsRecursively(repetition: Repetition): void;
+    protected layoutSingleRepetitionEnding(start: StaffMeasure, end: StaffMeasure, numberText: string, offset: number, leftOpen: boolean, rightOpen: boolean): void;
+    protected calculateTempoExpressionsForSingleMultiTempoExpression(sourceMeasure: SourceMeasure, multiTempoExpression: MultiTempoExpression, measureIndex: number): void;
+    protected clearSystemsAndMeasures(): void;
+    protected handleVoiceEntry(voiceEntry: VoiceEntry, graphicalStaffEntry: GraphicalStaffEntry, accidentalCalculator: AccidentalCalculator, openLyricWords: LyricWord[], tieTimestampListDict: Dictionary<Tie, Fraction[]>, activeClef: ClefInstruction, openTuplets: Tuplet[], openBeams: Beam[], octaveShiftValue: OctaveEnum, grace?: boolean, linkedNotes?: Note[], sourceStaffEntry?: SourceStaffEntry): OctaveEnum;
+    protected handleVoiceEntryGraceNotes(graceEntries: VoiceEntry[], graphicalGraceEntries: GraphicalStaffEntry[], graphicalStaffEntry: GraphicalStaffEntry, accidentalCalculator: AccidentalCalculator, activeClef: ClefInstruction, octaveShiftValue: OctaveEnum, lyricWords: LyricWord[], tieTimestampListDict: Dictionary<Tie, Fraction[]>, tuplets: Tuplet[], beams: Beam[]): void;
+    protected handleOpenTies(measure: StaffMeasure, beams: Beam[], tieTimestampListDict: Dictionary<Tie, Fraction[]>, activeClef: ClefInstruction, octaveShiftParams: OctaveShiftParams): void;
+    protected resetYPositionForLeadSheet(psi: BoundingBox): void;
+    protected layoutVoiceEntries(graphicalStaffEntry: GraphicalStaffEntry): void;
+    protected maxInstrNameLabelLength(): number;
+    protected calculateSheetLabelBoundingBoxes(): void;
+    protected checkMeasuresForWholeRestNotes(): void;
+    protected optimizeRestNotePlacement(graphicalStaffEntry: GraphicalStaffEntry, measure: StaffMeasure): void;
+    protected getRelativePositionInStaffLineFromTimestamp(timestamp: Fraction, verticalIndex: number, staffLine: StaffLine, multiStaffInstrument: boolean, firstVisibleMeasureRelativeX?: number): PointF2D;
+    protected getRelativeXPositionFromTimestamp(timestamp: Fraction): number;
+    protected calculatePageLabels(page: GraphicalMusicPage): void;
+    protected createGraphicalTies(): void;
+    private createAccidentalCalculators();
+    private calculateVerticalContainersList();
+    private setIndecesToVerticalGraphicalContainers();
+    private createGraphicalMeasuresForSourceMeasure(sourceMeasure, accidentalCalculators, openLyricWords, tieTimestampListDictList, openOctaveShifts, activeClefs);
+    private createGraphicalMeasure(sourceMeasure, tieTimestampListDict, openTuplets, openBeams, accidentalCalculator, activeClefs, openOctaveShifts, openLyricWords, staffIndex, staffEntryLinks);
+    private checkVoiceEntriesForTechnicalInstructions(voiceEntry, graphicalStaffEntry);
+    private checkNoteForAccidental(graphicalNote, accidentalCalculator, activeClef, octaveEnum, grace?);
+    private createStaffEntryForTieNote(measure, absoluteTimestamp, openTie);
+    private updateSkyBottomLines();
+    private handleStaffEntries();
+    private calculateSkyBottomLines();
+    private calculateBeams();
+    private calculateStaffEntryArticulationMarks();
+    private calculateOrnaments();
+    private optimizeRestPlacement();
+    private calculateTwoRestNotesPlacementWithCollisionDetection(graphicalStaffEntry);
+    private calculateRestNotePlacementWithCollisionDetectionFromGraphicalNote(graphicalStaffEntry);
+    private calculateTieCurves();
+    private calculateLyricsPosition();
+    private calculateDynamicExpressions();
+    private calculateOctaveShifts();
+    private getFirstLeftNotNullStaffEntryFromContainer(horizontalIndex, verticalIndex, multiStaffInstrument);
+    private getFirstRightNotNullStaffEntryFromContainer(horizontalIndex, verticalIndex, multiStaffInstrument);
+    private calculateWordRepetitionInstructions();
+    private calculateRepetitionEndings();
+    private calculateTempoExpressions();
+    private calculateMoodAndUnknownExpressions();
+}

+ 1313 - 0
dist/src/MusicalScore/Graphical/MusicSheetCalculator.js

@@ -0,0 +1,1313 @@
+"use strict";
+var GraphicalMusicSheet_1 = require("./GraphicalMusicSheet");
+var fraction_1 = require("../../Common/DataObjects/fraction");
+var Note_1 = require("../VoiceData/Note");
+var ClefInstruction_1 = require("../VoiceData/Instructions/ClefInstruction");
+var octaveShift_1 = require("../VoiceData/Expressions/ContinuousExpressions/octaveShift");
+var VoiceEntry_1 = require("../VoiceData/VoiceEntry");
+var MusicSystemBuilder_1 = require("./MusicSystemBuilder");
+var PointF2D_1 = require("../../Common/DataObjects/PointF2D");
+var SourceStaffEntry_1 = require("../VoiceData/SourceStaffEntry");
+var GraphicalLabel_1 = require("./GraphicalLabel");
+var TextAlignment_1 = require("../../Common/Enums/TextAlignment");
+var KeyInstruction_1 = require("../VoiceData/Instructions/KeyInstruction");
+var ClefInstruction_2 = require("../VoiceData/Instructions/ClefInstruction");
+var LinkedVoice_1 = require("../VoiceData/LinkedVoice");
+var BoundingBox_1 = require("./BoundingBox");
+var OctaveShiftParams_1 = require("./OctaveShiftParams");
+var AccidentalCalculator_1 = require("./AccidentalCalculator");
+var ClefInstruction_3 = require("../VoiceData/Instructions/ClefInstruction");
+var logging_1 = require("../../Common/logging");
+var Dictionary_1 = require("typescript-collections/dist/lib/Dictionary");
+var collectionUtil_1 = require("../../Util/collectionUtil");
+var MusicSheetCalculator = (function () {
+    function MusicSheetCalculator(symbolFactory) {
+        this.staffEntriesWithGraphicalTies = [];
+        this.staffEntriesWithOrnaments = [];
+        this.staffEntriesWithChordSymbols = [];
+        this.staffLinesWithLyricWords = [];
+        this.staffLinesWithGraphicalExpressions = [];
+        this.symbolFactory = symbolFactory;
+    }
+    Object.defineProperty(MusicSheetCalculator, "TextMeasurer", {
+        get: function () {
+            return MusicSheetCalculator.textMeasurer;
+        },
+        set: function (value) {
+            MusicSheetCalculator.textMeasurer = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(MusicSheetCalculator.prototype, "leadSheet", {
+        get: function () {
+            return this.graphicalMusicSheet.LeadSheet;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    MusicSheetCalculator.addTieToTieTimestampsDict = function (tieTimestampListDict, note) {
+        note.NoteTie.initializeBoolList();
+        var tieTimestampList = [];
+        for (var m = 0; m < note.NoteTie.Fractions.length; m++) {
+            var musicTimestamp = void 0;
+            if (m === 0) {
+                musicTimestamp = fraction_1.Fraction.plus(note.calculateNoteLengthWithoutTie(), note.getAbsoluteTimestamp());
+            }
+            else {
+                musicTimestamp = fraction_1.Fraction.plus(tieTimestampList[m - 1], note.NoteTie.Fractions[m - 1]);
+            }
+            tieTimestampList.push(musicTimestamp);
+        }
+        tieTimestampListDict.setValue(note.NoteTie, tieTimestampList);
+    };
+    MusicSheetCalculator.setMeasuresMinStaffEntriesWidth = function (measures, minimumStaffEntriesWidth) {
+        for (var idx = 0, len = measures.length; idx < len; ++idx) {
+            var measure = measures[idx];
+            measure.minimumStaffEntriesWidth = minimumStaffEntriesWidth;
+        }
+    };
+    MusicSheetCalculator.prototype.initialize = function (graphicalMusicSheet) {
+        this.graphicalMusicSheet = graphicalMusicSheet;
+        this.rules = graphicalMusicSheet.ParentMusicSheet.rules;
+        this.prepareGraphicalMusicSheet();
+        this.calculate();
+    };
+    MusicSheetCalculator.prototype.prepareGraphicalMusicSheet = function () {
+        //this.graphicalMusicSheet.SystemImages.length = 0;
+        var musicSheet = this.graphicalMusicSheet.ParentMusicSheet;
+        this.staffEntriesWithGraphicalTies = [];
+        this.staffEntriesWithOrnaments = [];
+        this.staffEntriesWithChordSymbols = [];
+        this.staffLinesWithLyricWords = [];
+        this.staffLinesWithGraphicalExpressions = [];
+        this.graphicalMusicSheet.Initialize();
+        var measureList = this.graphicalMusicSheet.MeasureList;
+        var accidentalCalculators = this.createAccidentalCalculators();
+        var activeClefs = this.graphicalMusicSheet.initializeActiveClefs();
+        var lyricWords = [];
+        var completeNumberOfStaves = musicSheet.getCompleteNumberOfStaves();
+        var openOctaveShifts = [];
+        var tieTimestampListDictList = [];
+        for (var i = 0; i < completeNumberOfStaves; i++) {
+            var tieTimestampListDict = new Dictionary_1.default();
+            tieTimestampListDictList.push(tieTimestampListDict);
+            openOctaveShifts.push(undefined);
+        }
+        for (var idx = 0, len = musicSheet.SourceMeasures.length; idx < len; ++idx) {
+            var sourceMeasure = musicSheet.SourceMeasures[idx];
+            var graphicalMeasures = this.createGraphicalMeasuresForSourceMeasure(sourceMeasure, accidentalCalculators, lyricWords, tieTimestampListDictList, openOctaveShifts, activeClefs);
+            measureList.push(graphicalMeasures);
+        }
+        this.handleStaffEntries();
+        this.calculateVerticalContainersList();
+        this.setIndecesToVerticalGraphicalContainers();
+    };
+    MusicSheetCalculator.prototype.calculate = function () {
+        this.clearSystemsAndMeasures();
+        this.clearRecreatedObjects();
+        this.createGraphicalTies();
+        this.calculateSheetLabelBoundingBoxes();
+        this.calculateXLayout(this.graphicalMusicSheet, this.maxInstrNameLabelLength());
+        this.graphicalMusicSheet.MusicPages.length = 0;
+        this.calculateMusicSystems();
+        this.graphicalMusicSheet.MusicPages[0].PositionAndShape.BorderMarginBottom += 9;
+        GraphicalMusicSheet_1.GraphicalMusicSheet.transformRelativeToAbsolutePosition(this.graphicalMusicSheet);
+    };
+    MusicSheetCalculator.prototype.calculateXLayout = function (graphicalMusicSheet, maxInstrNameLabelLength) {
+        var minLength = 0;
+        var maxInstructionsLength = this.rules.MaxInstructionsConstValue;
+        if (this.graphicalMusicSheet.MeasureList.length > 0) {
+            var measures = this.graphicalMusicSheet.MeasureList[0];
+            var minimumStaffEntriesWidth = this.calculateMeasureXLayout(measures);
+            MusicSheetCalculator.setMeasuresMinStaffEntriesWidth(measures, minimumStaffEntriesWidth);
+            minLength = minimumStaffEntriesWidth * 1.2 + maxInstrNameLabelLength + maxInstructionsLength;
+            for (var i = 1; i < this.graphicalMusicSheet.MeasureList.length; i++) {
+                measures = this.graphicalMusicSheet.MeasureList[i];
+                minimumStaffEntriesWidth = this.calculateMeasureXLayout(measures);
+                MusicSheetCalculator.setMeasuresMinStaffEntriesWidth(measures, minimumStaffEntriesWidth);
+                minLength = Math.max(minLength, minimumStaffEntriesWidth * 1.2 + maxInstructionsLength);
+            }
+        }
+        this.graphicalMusicSheet.MinAllowedSystemWidth = minLength;
+    };
+    MusicSheetCalculator.prototype.calculateMeasureXLayout = function (measures) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.calculateSystemYLayout = function () {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.initStaffMeasuresCreation = function () {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.handleBeam = function (graphicalNote, beam, openBeams) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.createGraphicalTieNote = function (beams, activeClef, octaveShiftValue, graphicalStaffEntry, duration, numberOfDots, openTie, isLastTieNote) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.handleVoiceEntryLyrics = function (lyricsEntries, voiceEntry, graphicalStaffEntry, openLyricWords) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.handleVoiceEntryOrnaments = function (ornamentContainer, voiceEntry, graphicalStaffEntry) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.handleVoiceEntryArticulations = function (articulations, voiceEntry, graphicalStaffEntry) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.handleTuplet = function (graphicalNote, tuplet, openTuplets) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.layoutVoiceEntry = function (voiceEntry, graphicalNotes, graphicalStaffEntry, hasPitchedNote, isGraceStaffEntry) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.layoutStaffEntry = function (graphicalStaffEntry) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.handleTie = function (tie, startGraphicalStaffEntry, staffIndex, measureIndex) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.updateStaffLineBorders = function (staffLine) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.calculateMeasureNumberPlacement = function (musicSystem) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.layoutGraphicalTie = function (tie, tieIsAtSystemBreak) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.calculateSingleStaffLineLyricsPosition = function (staffLine, lyricVersesNumber) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.calculateSingleOctaveShift = function (sourceMeasure, multiExpression, measureIndex, staffIndex) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.calculateWordRepetitionInstruction = function (repetitionInstruction, measureIndex) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.calculateMoodAndUnknownExpression = function (multiExpression, measureIndex, staffIndex) {
+        throw new Error("abstract, not implemented");
+    };
+    MusicSheetCalculator.prototype.clearRecreatedObjects = function () {
+        logging_1.Logging.log("clearRecreatedObjects not implemented");
+    };
+    MusicSheetCalculator.prototype.handleStaffEntryLink = function (graphicalStaffEntry, staffEntryLinks) {
+        logging_1.Logging.log("handleStaffEntryLink not implemented");
+    };
+    MusicSheetCalculator.prototype.calculateMusicSystems = function () {
+        if (this.graphicalMusicSheet.MeasureList === undefined) {
+            return;
+        }
+        var allMeasures = this.graphicalMusicSheet.MeasureList;
+        if (allMeasures === undefined) {
+            return;
+        }
+        var visibleMeasureList = [];
+        for (var idx = 0, len = allMeasures.length; idx < len; ++idx) {
+            var staffMeasures = allMeasures[idx];
+            var visibleStaffMeasures = [];
+            for (var idx2 = 0, len2 = staffMeasures.length; idx2 < len2; ++idx2) {
+                var staffMeasure = allMeasures[idx][idx2];
+                if (staffMeasure.isVisible()) {
+                    visibleStaffMeasures.push(staffMeasure);
+                }
+            }
+            visibleMeasureList.push(visibleStaffMeasures);
+        }
+        var numberOfStaffLines = 0;
+        for (var idx = 0, len = visibleMeasureList.length; idx < len; ++idx) {
+            var gmlist = visibleMeasureList[idx];
+            numberOfStaffLines = Math.max(gmlist.length, numberOfStaffLines);
+            break;
+        }
+        if (numberOfStaffLines === 0) {
+            return;
+        }
+        var musicSystemBuilder = new MusicSystemBuilder_1.MusicSystemBuilder();
+        musicSystemBuilder.initialize(this.graphicalMusicSheet, visibleMeasureList, numberOfStaffLines, this.symbolFactory);
+        musicSystemBuilder.buildMusicSystems();
+        this.checkMeasuresForWholeRestNotes();
+        if (!this.leadSheet) {
+            this.calculateBeams();
+            this.optimizeRestPlacement();
+            this.calculateStaffEntryArticulationMarks();
+            this.calculateTieCurves();
+        }
+        this.calculateSkyBottomLines();
+        this.calculateTupletNumbers();
+        for (var idx = 0, len = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
+            var graphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
+            for (var idx2 = 0, len2 = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
+                var musicSystem = graphicalMusicPage.MusicSystems[idx2];
+                this.calculateMeasureNumberPlacement(musicSystem);
+            }
+        }
+        if (!this.leadSheet) {
+            this.calculateSlurs();
+        }
+        if (!this.leadSheet) {
+            this.calculateOrnaments();
+        }
+        this.updateSkyBottomLines();
+        this.calculateChordSymbols();
+        if (!this.leadSheet) {
+            this.calculateDynamicExpressions();
+            this.optimizeStaffLineDynamicExpressionsPositions();
+            this.calculateMoodAndUnknownExpressions();
+            this.calculateOctaveShifts();
+            this.calculateWordRepetitionInstructions();
+        }
+        this.calculateRepetitionEndings();
+        if (!this.leadSheet) {
+            this.calculateTempoExpressions();
+        }
+        this.calculateLyricsPosition();
+        for (var idx = 0, len = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
+            var graphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
+            for (var idx2 = 0, len2 = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
+                var musicSystem = graphicalMusicPage.MusicSystems[idx2];
+                for (var idx3 = 0, len3 = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
+                    var staffLine = musicSystem.StaffLines[idx3];
+                    this.updateStaffLineBorders(staffLine);
+                }
+            }
+        }
+        this.calculateComments();
+        this.calculateSystemYLayout();
+        this.calculateMarkedAreas();
+        for (var idx = 0, len = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
+            var graphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
+            for (var idx2 = 0, len2 = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
+                var musicSystem = graphicalMusicPage.MusicSystems[idx2];
+                musicSystem.setMusicSystemLabelsYPosition();
+                if (!this.leadSheet) {
+                    musicSystem.setYPositionsToVerticalLineObjectsAndCreateLines(this.rules);
+                    musicSystem.createSystemLeftLine(this.rules.SystemThinLineWidth, this.rules.SystemLabelsRightMargin);
+                    musicSystem.createInstrumentBrackets(this.graphicalMusicSheet.ParentMusicSheet.Instruments, this.rules.StaffHeight);
+                    musicSystem.createGroupBrackets(this.graphicalMusicSheet.ParentMusicSheet.InstrumentalGroups, this.rules.StaffHeight, 0);
+                    musicSystem.alignBeginInstructions();
+                }
+                else if (musicSystem === musicSystem.Parent.MusicSystems[0]) {
+                    musicSystem.createSystemLeftLine(this.rules.SystemThinLineWidth, this.rules.SystemLabelsRightMargin);
+                }
+                musicSystem.calculateBorders(this.rules);
+            }
+            var distance = graphicalMusicPage.MusicSystems[0].PositionAndShape.BorderTop;
+            for (var idx2 = 0, len2 = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
+                var musicSystem = graphicalMusicPage.MusicSystems[idx2];
+                // let newPosition: PointF2D = new PointF2D(musicSystem.PositionAndShape.RelativePosition.x,
+                // musicSystem.PositionAndShape.RelativePosition.y - distance);
+                musicSystem.PositionAndShape.RelativePosition =
+                    new PointF2D_1.PointF2D(musicSystem.PositionAndShape.RelativePosition.x, musicSystem.PositionAndShape.RelativePosition.y - distance);
+            }
+            for (var idx2 = 0, len2 = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
+                var musicSystem = graphicalMusicPage.MusicSystems[idx2];
+                for (var idx3 = 0, len3 = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
+                    var staffLine = musicSystem.StaffLines[idx3];
+                    staffLine.addActivitySymbolClickArea();
+                }
+            }
+            if (graphicalMusicPage === this.graphicalMusicSheet.MusicPages[0]) {
+                this.calculatePageLabels(graphicalMusicPage);
+            }
+            graphicalMusicPage.PositionAndShape.calculateTopBottomBorders();
+        }
+    };
+    MusicSheetCalculator.prototype.updateSkyBottomLine = function (staffLine) {
+        logging_1.Logging.log("updateSkyBottomLine not implemented");
+    };
+    MusicSheetCalculator.prototype.calculateSkyBottomLine = function (staffLine) {
+        logging_1.Logging.log("calculateSkyBottomLine not implemented");
+    };
+    MusicSheetCalculator.prototype.calculateMarkedAreas = function () {
+        logging_1.Logging.log("calculateMarkedAreas not implemented");
+    };
+    MusicSheetCalculator.prototype.calculateComments = function () {
+        logging_1.Logging.log("calculateComments not implemented");
+    };
+    MusicSheetCalculator.prototype.optimizeStaffLineDynamicExpressionsPositions = function () {
+        return;
+    };
+    MusicSheetCalculator.prototype.calculateChordSymbols = function () {
+        return;
+    };
+    MusicSheetCalculator.prototype.layoutMeasureWithWholeRest = function (rest, gse, measure) {
+        return;
+    };
+    MusicSheetCalculator.prototype.layoutBeams = function (staffEntry) {
+        return;
+    };
+    MusicSheetCalculator.prototype.layoutArticulationMarks = function (articulations, voiceEntry, graphicalStaffEntry) {
+        return;
+    };
+    MusicSheetCalculator.prototype.layoutOrnament = function (ornaments, voiceEntry, graphicalStaffEntry) {
+        return;
+    };
+    MusicSheetCalculator.prototype.calculateRestNotePlacementWithinGraphicalBeam = function (graphicalStaffEntry, restNote, previousNote, nextStaffEntry, nextNote) {
+        return;
+    };
+    MusicSheetCalculator.prototype.calculateTupletNumbers = function () {
+        return;
+    };
+    MusicSheetCalculator.prototype.calculateSlurs = function () {
+        return;
+    };
+    MusicSheetCalculator.prototype.calculateDynamicExpressionsForSingleMultiExpression = function (multiExpression, measureIndex, staffIndex) {
+        return;
+    };
+    MusicSheetCalculator.prototype.calcGraphicalRepetitionEndingsRecursively = function (repetition) {
+        return;
+    };
+    MusicSheetCalculator.prototype.layoutSingleRepetitionEnding = function (start, end, numberText, offset, leftOpen, rightOpen) {
+        return;
+    };
+    MusicSheetCalculator.prototype.calculateTempoExpressionsForSingleMultiTempoExpression = function (sourceMeasure, multiTempoExpression, measureIndex) {
+        return;
+    };
+    MusicSheetCalculator.prototype.clearSystemsAndMeasures = function () {
+        for (var idx = 0, len = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
+            var graphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
+            for (var idx2 = 0, len2 = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
+                var musicSystem = graphicalMusicPage.MusicSystems[idx2];
+                for (var idx3 = 0, len3 = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
+                    var staffLine = musicSystem.StaffLines[idx3];
+                    for (var idx4 = 0, len4 = staffLine.Measures.length; idx4 < len4; ++idx4) {
+                        var graphicalMeasure = staffLine.Measures[idx4];
+                        if (graphicalMeasure.FirstInstructionStaffEntry !== undefined) {
+                            var index = graphicalMeasure.PositionAndShape.ChildElements.indexOf(graphicalMeasure.FirstInstructionStaffEntry.PositionAndShape);
+                            if (index > -1) {
+                                graphicalMeasure.PositionAndShape.ChildElements.splice(index, 1);
+                            }
+                            graphicalMeasure.FirstInstructionStaffEntry = undefined;
+                            graphicalMeasure.beginInstructionsWidth = 0.0;
+                        }
+                        if (graphicalMeasure.LastInstructionStaffEntry !== undefined) {
+                            var index = graphicalMeasure.PositionAndShape.ChildElements.indexOf(graphicalMeasure.LastInstructionStaffEntry.PositionAndShape);
+                            if (index > -1) {
+                                graphicalMeasure.PositionAndShape.ChildElements.splice(index, 1);
+                            }
+                            graphicalMeasure.LastInstructionStaffEntry = undefined;
+                            graphicalMeasure.endInstructionsWidth = 0.0;
+                        }
+                    }
+                    staffLine.Measures = [];
+                    staffLine.PositionAndShape.ChildElements = [];
+                }
+                musicSystem.StaffLines.length = 0;
+                musicSystem.PositionAndShape.ChildElements = [];
+            }
+            graphicalMusicPage.MusicSystems = [];
+            graphicalMusicPage.PositionAndShape.ChildElements = [];
+        }
+        this.graphicalMusicSheet.MusicPages = [];
+    };
+    MusicSheetCalculator.prototype.handleVoiceEntry = function (voiceEntry, graphicalStaffEntry, accidentalCalculator, openLyricWords, tieTimestampListDict, activeClef, openTuplets, openBeams, octaveShiftValue, grace, linkedNotes, sourceStaffEntry) {
+        if (grace === void 0) { grace = false; }
+        if (linkedNotes === void 0) { linkedNotes = undefined; }
+        if (sourceStaffEntry === void 0) { sourceStaffEntry = undefined; }
+        var graphicalNotes = graphicalStaffEntry.findOrCreateGraphicalNotesListFromVoiceEntry(voiceEntry);
+        for (var idx = 0, len = voiceEntry.Notes.length; idx < len; ++idx) {
+            var note = voiceEntry.Notes[idx];
+            if (sourceStaffEntry !== undefined && sourceStaffEntry.Link !== undefined && linkedNotes !== undefined && linkedNotes.indexOf(note) > -1) {
+                continue;
+            }
+            var graphicalNote = void 0;
+            var numberOfDots = note.calculateNumberOfNeededDots();
+            if (grace) {
+                graphicalNote = this.symbolFactory.createGraceNote(note, numberOfDots, graphicalStaffEntry, activeClef, octaveShiftValue);
+            }
+            else {
+                graphicalNote = this.symbolFactory.createNote(note, numberOfDots, graphicalStaffEntry, activeClef, octaveShiftValue);
+            }
+            if (note.NoteTie !== undefined) {
+                MusicSheetCalculator.addTieToTieTimestampsDict(tieTimestampListDict, note);
+            }
+            if (note.Pitch !== undefined) {
+                this.checkNoteForAccidental(graphicalNote, accidentalCalculator, activeClef, octaveShiftValue, grace);
+            }
+            this.resetYPositionForLeadSheet(graphicalNote.PositionAndShape);
+            graphicalStaffEntry.addGraphicalNoteToListAtCorrectYPosition(graphicalNotes, graphicalNote);
+            graphicalStaffEntry.PositionAndShape.ChildElements.push(graphicalNote.PositionAndShape);
+            graphicalNote.PositionAndShape.calculateBoundingBox();
+            if (!this.leadSheet) {
+                if (note.NoteBeam !== undefined) {
+                    this.handleBeam(graphicalNote, note.NoteBeam, openBeams);
+                }
+                if (note.NoteTuplet !== undefined) {
+                    this.handleTuplet(graphicalNote, note.NoteTuplet, openTuplets);
+                }
+            }
+        }
+        if (voiceEntry.Articulations.length > 0) {
+            this.handleVoiceEntryArticulations(voiceEntry.Articulations, voiceEntry, graphicalStaffEntry);
+        }
+        if (voiceEntry.TechnicalInstructions.length > 0) {
+            this.checkVoiceEntriesForTechnicalInstructions(voiceEntry, graphicalStaffEntry);
+        }
+        if (voiceEntry.LyricsEntries.size() > 0) {
+            this.handleVoiceEntryLyrics(voiceEntry.LyricsEntries, voiceEntry, graphicalStaffEntry, openLyricWords);
+        }
+        if (voiceEntry.OrnamentContainer !== undefined) {
+            this.handleVoiceEntryOrnaments(voiceEntry.OrnamentContainer, voiceEntry, graphicalStaffEntry);
+        }
+        return octaveShiftValue;
+    };
+    MusicSheetCalculator.prototype.handleVoiceEntryGraceNotes = function (graceEntries, graphicalGraceEntries, graphicalStaffEntry, accidentalCalculator, activeClef, octaveShiftValue, lyricWords, tieTimestampListDict, tuplets, beams) {
+        if (graceEntries !== undefined) {
+            for (var idx = 0, len = graceEntries.length; idx < len; ++idx) {
+                var graceVoiceEntry = graceEntries[idx];
+                var graceStaffEntry = this.symbolFactory.createGraceStaffEntry(graphicalStaffEntry, graphicalStaffEntry.parentMeasure);
+                graphicalGraceEntries.push(graceStaffEntry);
+                graphicalStaffEntry.PositionAndShape.ChildElements.push(graceStaffEntry.PositionAndShape);
+                this.handleVoiceEntry(graceVoiceEntry, graceStaffEntry, accidentalCalculator, lyricWords, tieTimestampListDict, activeClef, tuplets, beams, octaveShiftValue, true);
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.handleOpenTies = function (measure, beams, tieTimestampListDict, activeClef, octaveShiftParams) {
+        collectionUtil_1.CollectionUtil.removeDictElementIfTrue(tieTimestampListDict, function (openTie, tieTimestamps) {
+            // for (let m: number = tieTimestampListDict.size() - 1; m >= 0; m--) {
+            //     let keyValuePair: KeyValuePair<Tie, Fraction[]> = tieTimestampListDict.ElementAt(m);
+            //     let openTie: Tie = keyValuePair.Key;
+            //    let tieTimestamps: Fraction[] = keyValuePair.Value;
+            var absoluteTimestamp = undefined;
+            var k;
+            var removeTie = false;
+            for (; k < tieTimestamps.length; k++) {
+                if (!openTie.NoteHasBeenCreated[k]) {
+                    absoluteTimestamp = tieTimestamps[k];
+                    if (absoluteTimestamp >= fraction_1.Fraction.plus(measure.parentSourceMeasure.AbsoluteTimestamp, measure.parentSourceMeasure.Duration)) {
+                        continue;
+                    }
+                    var graphicalStaffEntry = undefined;
+                    if (absoluteTimestamp !== undefined) {
+                        for (var idx = 0, len = measure.staffEntries.length; idx < len; ++idx) {
+                            var gse = measure.staffEntries[idx];
+                            if (gse.getAbsoluteTimestamp() === absoluteTimestamp) {
+                                graphicalStaffEntry = gse;
+                                break;
+                            }
+                        }
+                        if (graphicalStaffEntry === undefined) {
+                            graphicalStaffEntry = this.createStaffEntryForTieNote(measure, absoluteTimestamp, openTie);
+                        }
+                    }
+                    if (graphicalStaffEntry !== undefined) {
+                        var octaveShiftValue = octaveShift_1.OctaveEnum.NONE;
+                        if (octaveShiftParams !== undefined) {
+                            if (graphicalStaffEntry.getAbsoluteTimestamp() >= octaveShiftParams.getAbsoluteStartTimestamp &&
+                                graphicalStaffEntry.getAbsoluteTimestamp() <= octaveShiftParams.getAbsoluteEndTimestamp) {
+                                octaveShiftValue = octaveShiftParams.getOpenOctaveShift.Type;
+                            }
+                        }
+                        var isLastTieNote = k === tieTimestamps.length - 1;
+                        var tieFraction = openTie.Fractions[k];
+                        var numberOfDots = openTie.Start.calculateNumberOfNeededDots();
+                        this.createGraphicalTieNote(beams, activeClef, octaveShiftValue, graphicalStaffEntry, tieFraction, numberOfDots, openTie, isLastTieNote);
+                        var tieStartNote = openTie.Start;
+                        if (isLastTieNote && tieStartNote.ParentVoiceEntry.Articulations.length === 1 &&
+                            tieStartNote.ParentVoiceEntry.Articulations[0] === VoiceEntry_1.ArticulationEnum.fermata) {
+                            this.symbolFactory.addFermataAtTiedEndNote(tieStartNote, graphicalStaffEntry);
+                        }
+                        openTie.NoteHasBeenCreated[k] = true;
+                        if (openTie.allGraphicalNotesHaveBeenCreated()) {
+                            removeTie = true;
+                        }
+                    }
+                }
+            }
+            return removeTie;
+        });
+    };
+    MusicSheetCalculator.prototype.resetYPositionForLeadSheet = function (psi) {
+        if (this.leadSheet) {
+            psi.RelativePosition = new PointF2D_1.PointF2D(psi.RelativePosition.x, 0.0);
+        }
+    };
+    MusicSheetCalculator.prototype.layoutVoiceEntries = function (graphicalStaffEntry) {
+        graphicalStaffEntry.PositionAndShape.RelativePosition = new PointF2D_1.PointF2D(0.0, 0.0);
+        var isGraceStaffEntry = graphicalStaffEntry.staffEntryParent !== undefined;
+        if (!this.leadSheet) {
+            var graphicalStaffEntryNotes = graphicalStaffEntry.notes;
+            for (var idx4 = 0, len4 = graphicalStaffEntryNotes.length; idx4 < len4; ++idx4) {
+                var graphicalNotes = graphicalStaffEntryNotes[idx4];
+                if (graphicalNotes.length === 0) {
+                    continue;
+                }
+                var voiceEntry = graphicalNotes[0].sourceNote.ParentVoiceEntry;
+                var hasPitchedNote = graphicalNotes[0].sourceNote.Pitch !== undefined;
+                this.layoutVoiceEntry(voiceEntry, graphicalNotes, graphicalStaffEntry, hasPitchedNote, isGraceStaffEntry);
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.maxInstrNameLabelLength = function () {
+        var maxLabelLength = 0.0;
+        for (var _i = 0, _a = this.graphicalMusicSheet.ParentMusicSheet.Instruments; _i < _a.length; _i++) {
+            var instrument = _a[_i];
+            if (instrument.Voices.length > 0 && instrument.Voices[0].Visible) {
+                var graphicalLabel = new GraphicalLabel_1.GraphicalLabel(instrument.NameLabel, this.rules.InstrumentLabelTextHeight, TextAlignment_1.TextAlignment.LeftCenter);
+                graphicalLabel.setLabelPositionAndShapeBorders();
+                maxLabelLength = Math.max(maxLabelLength, graphicalLabel.PositionAndShape.MarginSize.width);
+            }
+        }
+        return maxLabelLength;
+    };
+    MusicSheetCalculator.prototype.calculateSheetLabelBoundingBoxes = function () {
+        var musicSheet = this.graphicalMusicSheet.ParentMusicSheet;
+        if (musicSheet.Title !== undefined) {
+            var title = new GraphicalLabel_1.GraphicalLabel(musicSheet.Title, this.rules.SheetTitleHeight, TextAlignment_1.TextAlignment.CenterBottom);
+            this.graphicalMusicSheet.Title = title;
+            title.setLabelPositionAndShapeBorders();
+        }
+        if (musicSheet.Subtitle !== undefined) {
+            var subtitle = new GraphicalLabel_1.GraphicalLabel(musicSheet.Subtitle, this.rules.SheetSubtitleHeight, TextAlignment_1.TextAlignment.CenterCenter);
+            this.graphicalMusicSheet.Subtitle = subtitle;
+            subtitle.setLabelPositionAndShapeBorders();
+        }
+        if (musicSheet.Composer !== undefined) {
+            var composer = new GraphicalLabel_1.GraphicalLabel(musicSheet.Composer, this.rules.SheetComposerHeight, TextAlignment_1.TextAlignment.RightCenter);
+            this.graphicalMusicSheet.Composer = composer;
+            composer.setLabelPositionAndShapeBorders();
+        }
+        if (musicSheet.Lyricist !== undefined) {
+            var lyricist = new GraphicalLabel_1.GraphicalLabel(musicSheet.Lyricist, this.rules.SheetAuthorHeight, TextAlignment_1.TextAlignment.LeftCenter);
+            this.graphicalMusicSheet.Lyricist = lyricist;
+            lyricist.setLabelPositionAndShapeBorders();
+        }
+    };
+    MusicSheetCalculator.prototype.checkMeasuresForWholeRestNotes = function () {
+        for (var idx = 0, len = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
+            var musicPage = this.graphicalMusicSheet.MusicPages[idx];
+            for (var idx2 = 0, len2 = musicPage.MusicSystems.length; idx2 < len2; ++idx2) {
+                var musicSystem = musicPage.MusicSystems[idx2];
+                for (var idx3 = 0, len3 = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
+                    var staffLine = musicSystem.StaffLines[idx3];
+                    for (var idx4 = 0, len4 = staffLine.Measures.length; idx4 < len4; ++idx4) {
+                        var measure = staffLine.Measures[idx4];
+                        if (measure.staffEntries.length === 1) {
+                            var gse = measure.staffEntries[0];
+                            if (gse.notes.length > 0 && gse.notes[0].length > 0) {
+                                var graphicalNote = gse.notes[0][0];
+                                if (graphicalNote.sourceNote.Pitch === undefined && (new fraction_1.Fraction(1, 2)).lt(graphicalNote.sourceNote.Length)) {
+                                    this.layoutMeasureWithWholeRest(graphicalNote, gse, measure);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.optimizeRestNotePlacement = function (graphicalStaffEntry, measure) {
+        if (graphicalStaffEntry.notes.length === 0) {
+            return;
+        }
+        var voice1Notes = graphicalStaffEntry.notes[0];
+        if (voice1Notes.length === 0) {
+            return;
+        }
+        var voice1Note1 = voice1Notes[0];
+        var voice1Note1IsRest = voice1Note1.sourceNote.Pitch === undefined;
+        if (graphicalStaffEntry.notes.length === 2) {
+            var voice2Note1IsRest = false;
+            var voice2Notes = graphicalStaffEntry.notes[1];
+            if (voice2Notes.length > 0) {
+                var voice2Note1 = voice1Notes[0];
+                voice2Note1IsRest = voice2Note1.sourceNote.Pitch === undefined;
+            }
+            if (voice1Note1IsRest && voice2Note1IsRest) {
+                this.calculateTwoRestNotesPlacementWithCollisionDetection(graphicalStaffEntry);
+            }
+            else if (voice1Note1IsRest || voice2Note1IsRest) {
+                this.calculateRestNotePlacementWithCollisionDetectionFromGraphicalNote(graphicalStaffEntry);
+            }
+        }
+        else if (voice1Note1IsRest && graphicalStaffEntry !== measure.staffEntries[0] &&
+            graphicalStaffEntry !== measure.staffEntries[measure.staffEntries.length - 1]) {
+            var staffEntryIndex = measure.staffEntries.indexOf(graphicalStaffEntry);
+            var previousStaffEntry = measure.staffEntries[staffEntryIndex - 1];
+            var nextStaffEntry = measure.staffEntries[staffEntryIndex + 1];
+            if (previousStaffEntry.notes.length === 1) {
+                var previousNote = previousStaffEntry.notes[0][0];
+                if (previousNote.sourceNote.NoteBeam !== undefined && nextStaffEntry.notes.length === 1) {
+                    var nextNote = nextStaffEntry.notes[0][0];
+                    if (nextNote.sourceNote.NoteBeam !== undefined && previousNote.sourceNote.NoteBeam === nextNote.sourceNote.NoteBeam) {
+                        this.calculateRestNotePlacementWithinGraphicalBeam(graphicalStaffEntry, voice1Note1, previousNote, nextStaffEntry, nextNote);
+                        graphicalStaffEntry.PositionAndShape.calculateBoundingBox();
+                    }
+                }
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.getRelativePositionInStaffLineFromTimestamp = function (timestamp, verticalIndex, staffLine, multiStaffInstrument, firstVisibleMeasureRelativeX) {
+        if (firstVisibleMeasureRelativeX === void 0) { firstVisibleMeasureRelativeX = 0.0; }
+        var relative = new PointF2D_1.PointF2D();
+        var leftStaffEntry = undefined;
+        var rightStaffEntry = undefined;
+        var numEntries = this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers.length;
+        var index = this.graphicalMusicSheet.GetInterpolatedIndexInVerticalContainers(timestamp);
+        var leftIndex = Math.min(Math.floor(index), numEntries - 1);
+        var rightIndex = Math.min(Math.ceil(index), numEntries - 1);
+        if (leftIndex < 0 || verticalIndex < 0) {
+            return relative;
+        }
+        leftStaffEntry = this.getFirstLeftNotNullStaffEntryFromContainer(leftIndex, verticalIndex, multiStaffInstrument);
+        rightStaffEntry = this.getFirstRightNotNullStaffEntryFromContainer(rightIndex, verticalIndex, multiStaffInstrument);
+        if (leftStaffEntry !== undefined && rightStaffEntry !== undefined) {
+            var measureRelativeX = leftStaffEntry.parentMeasure.PositionAndShape.RelativePosition.x;
+            if (firstVisibleMeasureRelativeX > 0) {
+                measureRelativeX = firstVisibleMeasureRelativeX;
+            }
+            var leftX = leftStaffEntry.PositionAndShape.RelativePosition.x + measureRelativeX;
+            var rightX = rightStaffEntry.PositionAndShape.RelativePosition.x + rightStaffEntry.parentMeasure.PositionAndShape.RelativePosition.x;
+            if (firstVisibleMeasureRelativeX > 0) {
+                rightX = rightStaffEntry.PositionAndShape.RelativePosition.x + measureRelativeX;
+            }
+            var timestampQuotient = 0.0;
+            if (leftStaffEntry !== rightStaffEntry) {
+                var leftTimestamp = leftStaffEntry.getAbsoluteTimestamp();
+                var rightTimestamp = rightStaffEntry.getAbsoluteTimestamp();
+                var leftDifference = fraction_1.Fraction.minus(timestamp, leftTimestamp);
+                timestampQuotient = leftDifference.RealValue / fraction_1.Fraction.minus(rightTimestamp, leftTimestamp).RealValue;
+            }
+            if (leftStaffEntry.parentMeasure.ParentStaffLine !== rightStaffEntry.parentMeasure.ParentStaffLine) {
+                if (leftStaffEntry.parentMeasure.ParentStaffLine === staffLine) {
+                    rightX = staffLine.PositionAndShape.Size.width;
+                }
+                else {
+                    leftX = staffLine.PositionAndShape.RelativePosition.x;
+                }
+            }
+            relative = new PointF2D_1.PointF2D(leftX + (rightX - leftX) * timestampQuotient, 0.0);
+        }
+        return relative;
+    };
+    MusicSheetCalculator.prototype.getRelativeXPositionFromTimestamp = function (timestamp) {
+        var numEntries = this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers.length;
+        var index = this.graphicalMusicSheet.GetInterpolatedIndexInVerticalContainers(timestamp);
+        var discreteIndex = Math.max(0, Math.min(Math.round(index), numEntries - 1));
+        var gse = this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[discreteIndex].getFirstNonNullStaffEntry();
+        var posX = gse.PositionAndShape.RelativePosition.x + gse.parentMeasure.PositionAndShape.RelativePosition.x;
+        return posX;
+    };
+    MusicSheetCalculator.prototype.calculatePageLabels = function (page) {
+        var relative = new PointF2D_1.PointF2D();
+        var firstSystemAbsoluteTopMargin = 10;
+        if (page.MusicSystems.length > 0) {
+            var firstMusicSystem = page.MusicSystems[0];
+            firstSystemAbsoluteTopMargin = firstMusicSystem.PositionAndShape.RelativePosition.y + firstMusicSystem.PositionAndShape.BorderTop;
+        }
+        if (this.graphicalMusicSheet.Title !== undefined) {
+            var title = this.graphicalMusicSheet.Title;
+            title.PositionAndShape.Parent = page.PositionAndShape;
+            page.PositionAndShape.ChildElements.push(title.PositionAndShape);
+            relative.x = this.graphicalMusicSheet.ParentMusicSheet.pageWidth / 2;
+            relative.y = this.rules.TitleTopDistance + this.rules.SheetTitleHeight;
+            title.PositionAndShape.RelativePosition = relative;
+            page.Labels.push(title);
+        }
+        if (this.graphicalMusicSheet.Subtitle !== undefined) {
+            var subtitle = this.graphicalMusicSheet.Subtitle;
+            subtitle.PositionAndShape.Parent = page.PositionAndShape;
+            page.PositionAndShape.ChildElements.push(subtitle.PositionAndShape);
+            relative.x = this.graphicalMusicSheet.ParentMusicSheet.pageWidth / 2;
+            relative.y = this.rules.TitleTopDistance + this.rules.SheetTitleHeight + this.rules.SheetMinimumDistanceBetweenTitleAndSubtitle;
+            subtitle.PositionAndShape.RelativePosition = relative;
+            page.Labels.push(subtitle);
+        }
+        if (this.graphicalMusicSheet.Composer !== undefined) {
+            var composer = this.graphicalMusicSheet.Composer;
+            composer.PositionAndShape.Parent = page.PositionAndShape;
+            page.PositionAndShape.ChildElements.push(composer.PositionAndShape);
+            composer.setLabelPositionAndShapeBorders();
+            relative.x = this.graphicalMusicSheet.ParentMusicSheet.pageWidth - this.rules.PageRightMargin;
+            relative.y = firstSystemAbsoluteTopMargin - this.rules.SystemComposerDistance;
+            composer.PositionAndShape.RelativePosition = relative;
+            page.Labels.push(composer);
+        }
+        if (this.graphicalMusicSheet.Lyricist !== undefined) {
+            var lyricist = this.graphicalMusicSheet.Lyricist;
+            lyricist.PositionAndShape.Parent = page.PositionAndShape;
+            page.PositionAndShape.ChildElements.push(lyricist.PositionAndShape);
+            lyricist.setLabelPositionAndShapeBorders();
+            relative.x = this.rules.PageLeftMargin;
+            relative.y = firstSystemAbsoluteTopMargin - this.rules.SystemComposerDistance;
+            lyricist.PositionAndShape.RelativePosition = relative;
+            page.Labels.push(lyricist);
+        }
+    };
+    MusicSheetCalculator.prototype.createGraphicalTies = function () {
+        for (var measureIndex = 0; measureIndex < this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length; measureIndex++) {
+            var sourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures[measureIndex];
+            for (var staffIndex = 0; staffIndex < sourceMeasure.CompleteNumberOfStaves; staffIndex++) {
+                for (var j = 0; j < sourceMeasure.VerticalSourceStaffEntryContainers.length; j++) {
+                    var sourceStaffEntry = sourceMeasure.VerticalSourceStaffEntryContainers[j].StaffEntries[staffIndex];
+                    if (sourceStaffEntry !== undefined) {
+                        var startStaffEntry = this.graphicalMusicSheet.findGraphicalStaffEntryFromMeasureList(staffIndex, measureIndex, sourceStaffEntry);
+                        for (var idx = 0, len = sourceStaffEntry.VoiceEntries.length; idx < len; ++idx) {
+                            var voiceEntry = sourceStaffEntry.VoiceEntries[idx];
+                            for (var idx2 = 0, len2 = voiceEntry.Notes.length; idx2 < len2; ++idx2) {
+                                var note = voiceEntry.Notes[idx2];
+                                if (note.NoteTie !== undefined) {
+                                    var tie = note.NoteTie;
+                                    this.handleTie(tie, startStaffEntry, staffIndex, measureIndex);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.createAccidentalCalculators = function () {
+        var accidentalCalculators = [];
+        var firstSourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.getFirstSourceMeasure();
+        if (firstSourceMeasure !== undefined) {
+            for (var i = 0; i < firstSourceMeasure.CompleteNumberOfStaves; i++) {
+                var accidentalCalculator = new AccidentalCalculator_1.AccidentalCalculator(this.symbolFactory);
+                accidentalCalculators.push(accidentalCalculator);
+                if (firstSourceMeasure.FirstInstructionsStaffEntries[i] !== undefined) {
+                    for (var idx = 0, len = firstSourceMeasure.FirstInstructionsStaffEntries[i].Instructions.length; idx < len; ++idx) {
+                        var abstractNotationInstruction = firstSourceMeasure.FirstInstructionsStaffEntries[i].Instructions[idx];
+                        if (abstractNotationInstruction instanceof KeyInstruction_1.KeyInstruction) {
+                            var keyInstruction = abstractNotationInstruction;
+                            accidentalCalculator.ActiveKeyInstruction = keyInstruction;
+                        }
+                    }
+                }
+            }
+        }
+        return accidentalCalculators;
+    };
+    MusicSheetCalculator.prototype.calculateVerticalContainersList = function () {
+        var numberOfEntries = this.graphicalMusicSheet.MeasureList[0].length;
+        for (var i = 0; i < this.graphicalMusicSheet.MeasureList.length; i++) {
+            for (var j = 0; j < numberOfEntries; j++) {
+                var measure = this.graphicalMusicSheet.MeasureList[i][j];
+                for (var idx = 0, len = measure.staffEntries.length; idx < len; ++idx) {
+                    var graphicalStaffEntry = measure.staffEntries[idx];
+                    var verticalContainer = this.graphicalMusicSheet.getOrCreateVerticalContainer(graphicalStaffEntry.getAbsoluteTimestamp());
+                    if (verticalContainer !== undefined) {
+                        verticalContainer.StaffEntries[j] = graphicalStaffEntry;
+                        graphicalStaffEntry.parentVerticalContainer = verticalContainer;
+                    }
+                    else {
+                        ;
+                    }
+                }
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.setIndecesToVerticalGraphicalContainers = function () {
+        for (var i = 0; i < this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers.length; i++) {
+            this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[i].Index = i;
+        }
+    };
+    MusicSheetCalculator.prototype.createGraphicalMeasuresForSourceMeasure = function (sourceMeasure, accidentalCalculators, openLyricWords, tieTimestampListDictList, openOctaveShifts, activeClefs) {
+        this.initStaffMeasuresCreation();
+        var verticalMeasureList = [];
+        var openBeams = [];
+        var openTuplets = [];
+        var staffEntryLinks = [];
+        for (var staffIndex = 0; staffIndex < sourceMeasure.CompleteNumberOfStaves; staffIndex++) {
+            var measure = this.createGraphicalMeasure(sourceMeasure, tieTimestampListDictList[staffIndex], openTuplets, openBeams, accidentalCalculators[staffIndex], activeClefs, openOctaveShifts, openLyricWords, staffIndex, staffEntryLinks);
+            verticalMeasureList.push(measure);
+        }
+        this.graphicalMusicSheet.sourceToGraphicalMeasureLinks.setValue(sourceMeasure, verticalMeasureList);
+        return verticalMeasureList;
+    };
+    MusicSheetCalculator.prototype.createGraphicalMeasure = function (sourceMeasure, tieTimestampListDict, openTuplets, openBeams, accidentalCalculator, activeClefs, openOctaveShifts, openLyricWords, staffIndex, staffEntryLinks) {
+        var staff = this.graphicalMusicSheet.ParentMusicSheet.getStaffFromIndex(staffIndex);
+        var measure = this.symbolFactory.createStaffMeasure(sourceMeasure, staff);
+        measure.hasError = sourceMeasure.getErrorInMeasure(staffIndex);
+        if (sourceMeasure.FirstInstructionsStaffEntries[staffIndex] !== undefined) {
+            for (var idx = 0, len = sourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions.length; idx < len; ++idx) {
+                var instruction = sourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions[idx];
+                if (instruction instanceof KeyInstruction_1.KeyInstruction) {
+                    var key = KeyInstruction_1.KeyInstruction.copy(instruction);
+                    if (this.graphicalMusicSheet.ParentMusicSheet.Transpose !== 0 &&
+                        measure.ParentStaff.ParentInstrument.MidiInstrumentId !== ClefInstruction_3.MidiInstrument.Percussion &&
+                        MusicSheetCalculator.transposeCalculator !== undefined) {
+                        MusicSheetCalculator.transposeCalculator.transposeKey(key, this.graphicalMusicSheet.ParentMusicSheet.Transpose);
+                    }
+                    accidentalCalculator.ActiveKeyInstruction = key;
+                }
+            }
+        }
+        for (var idx = 0, len = sourceMeasure.StaffLinkedExpressions[staffIndex].length; idx < len; ++idx) {
+            var multiExpression = sourceMeasure.StaffLinkedExpressions[staffIndex][idx];
+            if (multiExpression.OctaveShiftStart !== undefined) {
+                var openOctaveShift = multiExpression.OctaveShiftStart;
+                openOctaveShifts[staffIndex] = new OctaveShiftParams_1.OctaveShiftParams(openOctaveShift, multiExpression.AbsoluteTimestamp, openOctaveShift.ParentEndMultiExpression.AbsoluteTimestamp);
+            }
+        }
+        for (var entryIndex = 0; entryIndex < sourceMeasure.VerticalSourceStaffEntryContainers.length; entryIndex++) {
+            var sourceStaffEntry = sourceMeasure.VerticalSourceStaffEntryContainers[entryIndex].StaffEntries[staffIndex];
+            if (sourceStaffEntry !== undefined) {
+                for (var idx = 0, len = sourceStaffEntry.Instructions.length; idx < len; ++idx) {
+                    var abstractNotationInstruction = sourceStaffEntry.Instructions[idx];
+                    if (abstractNotationInstruction instanceof ClefInstruction_1.ClefInstruction) {
+                        activeClefs[staffIndex] = abstractNotationInstruction;
+                    }
+                }
+                var graphicalStaffEntry = this.symbolFactory.createStaffEntry(sourceStaffEntry, measure);
+                if (measure.staffEntries.length > entryIndex) {
+                    measure.addGraphicalStaffEntryAtTimestamp(graphicalStaffEntry);
+                }
+                else {
+                    measure.addGraphicalStaffEntry(graphicalStaffEntry);
+                }
+                var linkedNotes = [];
+                if (sourceStaffEntry.Link !== undefined) {
+                    sourceStaffEntry.findLinkedNotes(linkedNotes);
+                    this.handleStaffEntryLink(graphicalStaffEntry, staffEntryLinks);
+                }
+                var octaveShiftValue = octaveShift_1.OctaveEnum.NONE;
+                if (openOctaveShifts[staffIndex] !== undefined) {
+                    var octaveShiftParams = openOctaveShifts[staffIndex];
+                    if (sourceStaffEntry.AbsoluteTimestamp >= octaveShiftParams.getAbsoluteStartTimestamp &&
+                        sourceStaffEntry.AbsoluteTimestamp <= octaveShiftParams.getAbsoluteEndTimestamp) {
+                        octaveShiftValue = octaveShiftParams.getOpenOctaveShift.Type;
+                    }
+                }
+                for (var idx = 0, len = sourceStaffEntry.VoiceEntries.length; idx < len; ++idx) {
+                    var voiceEntry = sourceStaffEntry.VoiceEntries[idx];
+                    this.handleVoiceEntryGraceNotes(voiceEntry.graceVoiceEntriesBefore, graphicalStaffEntry.graceStaffEntriesBefore, graphicalStaffEntry, accidentalCalculator, activeClefs[staffIndex], octaveShiftValue, openLyricWords, tieTimestampListDict, openTuplets, openBeams);
+                    octaveShiftValue = this.handleVoiceEntry(voiceEntry, graphicalStaffEntry, accidentalCalculator, openLyricWords, tieTimestampListDict, activeClefs[staffIndex], openTuplets, openBeams, octaveShiftValue, false, linkedNotes, sourceStaffEntry);
+                    this.handleVoiceEntryGraceNotes(voiceEntry.graceVoiceEntriesAfter, graphicalStaffEntry.graceStaffEntriesAfter, graphicalStaffEntry, accidentalCalculator, activeClefs[staffIndex], octaveShiftValue, openLyricWords, tieTimestampListDict, openTuplets, openBeams);
+                }
+                if (sourceStaffEntry.Instructions.length > 0) {
+                    var clefInstruction = sourceStaffEntry.Instructions[0];
+                    this.symbolFactory.createInStaffClef(graphicalStaffEntry, clefInstruction);
+                }
+                if (sourceStaffEntry.ChordContainer !== undefined) {
+                    sourceStaffEntry.ParentStaff.ParentInstrument.HasChordSymbols = true;
+                    this.symbolFactory.createChordSymbol(sourceStaffEntry, graphicalStaffEntry, this.graphicalMusicSheet.ParentMusicSheet.Transpose);
+                }
+            }
+        }
+        if (tieTimestampListDict.size() > 0) {
+            this.handleOpenTies(measure, openBeams, tieTimestampListDict, activeClefs[staffIndex], openOctaveShifts[staffIndex]);
+        }
+        accidentalCalculator.doCalculationsAtEndOfMeasure();
+        if (sourceMeasure.LastInstructionsStaffEntries[staffIndex] !== undefined) {
+            var lastStaffEntry = sourceMeasure.LastInstructionsStaffEntries[staffIndex];
+            for (var idx = 0, len = lastStaffEntry.Instructions.length; idx < len; ++idx) {
+                var abstractNotationInstruction = lastStaffEntry.Instructions[idx];
+                if (abstractNotationInstruction instanceof ClefInstruction_1.ClefInstruction) {
+                    activeClefs[staffIndex] = abstractNotationInstruction;
+                }
+            }
+        }
+        for (var idx = 0, len = sourceMeasure.StaffLinkedExpressions[staffIndex].length; idx < len; ++idx) {
+            var multiExpression = sourceMeasure.StaffLinkedExpressions[staffIndex][idx];
+            if (multiExpression.OctaveShiftEnd !== undefined && openOctaveShifts[staffIndex] !== undefined &&
+                multiExpression.OctaveShiftEnd === openOctaveShifts[staffIndex].getOpenOctaveShift) {
+                openOctaveShifts[staffIndex] = undefined;
+            }
+        }
+        if (measure.staffEntries.length === 0) {
+            var sourceStaffEntry = new SourceStaffEntry_1.SourceStaffEntry(undefined, staff);
+            var note = new Note_1.Note(undefined, sourceStaffEntry, fraction_1.Fraction.createFromFraction(sourceMeasure.Duration), undefined);
+            var graphicalStaffEntry = this.symbolFactory.createStaffEntry(sourceStaffEntry, measure);
+            measure.addGraphicalStaffEntry(graphicalStaffEntry);
+            graphicalStaffEntry.relInMeasureTimestamp = new fraction_1.Fraction(0, 1);
+            var graphicalNotes = [];
+            graphicalStaffEntry.notes.push(graphicalNotes);
+            var numberOfDots = note.calculateNumberOfNeededDots();
+            var graphicalNote = this.symbolFactory.createNote(note, numberOfDots, graphicalStaffEntry, new ClefInstruction_1.ClefInstruction(ClefInstruction_2.ClefEnum.G, 0, 2), octaveShift_1.OctaveEnum.NONE);
+            graphicalNotes.push(graphicalNote);
+            graphicalStaffEntry.PositionAndShape.ChildElements.push(graphicalNote.PositionAndShape);
+        }
+        return measure;
+    };
+    MusicSheetCalculator.prototype.checkVoiceEntriesForTechnicalInstructions = function (voiceEntry, graphicalStaffEntry) {
+        for (var idx = 0, len = voiceEntry.TechnicalInstructions.length; idx < len; ++idx) {
+            var technicalInstruction = voiceEntry.TechnicalInstructions[idx];
+            this.symbolFactory.createGraphicalTechnicalInstruction(technicalInstruction, graphicalStaffEntry);
+        }
+    };
+    MusicSheetCalculator.prototype.checkNoteForAccidental = function (graphicalNote, accidentalCalculator, activeClef, octaveEnum, grace) {
+        if (grace === void 0) { grace = false; }
+        var pitch = graphicalNote.sourceNote.Pitch;
+        var transpose = this.graphicalMusicSheet.ParentMusicSheet.Transpose;
+        if (transpose !== 0 && graphicalNote.sourceNote.ParentStaffEntry.ParentStaff.ParentInstrument.MidiInstrumentId !== ClefInstruction_3.MidiInstrument.Percussion) {
+            pitch = graphicalNote.Transpose(accidentalCalculator.ActiveKeyInstruction, activeClef, transpose, octaveEnum);
+            if (graphicalNote.sourceNote.NoteTie !== undefined) {
+                graphicalNote.sourceNote.NoteTie.BaseNoteYPosition = graphicalNote.PositionAndShape.RelativePosition.y;
+            }
+        }
+        graphicalNote.sourceNote.halfTone = pitch.getHalfTone();
+        var scalingFactor = 1.0;
+        if (grace) {
+            scalingFactor = this.rules.GraceNoteScalingFactor;
+        }
+        accidentalCalculator.checkAccidental(graphicalNote, pitch, grace, scalingFactor);
+    };
+    // needed to disable linter, as it doesn't recognize the existing usage of this method.
+    // ToDo: check if a newer version doesn't have the problem.
+    /* tslint:disable:no-unused-variable */
+    MusicSheetCalculator.prototype.createStaffEntryForTieNote = function (measure, absoluteTimestamp, openTie) {
+        /* tslint:enable:no-unused-variable */
+        var graphicalStaffEntry;
+        graphicalStaffEntry = this.symbolFactory.createStaffEntry(openTie.Start.ParentStaffEntry, measure);
+        graphicalStaffEntry.relInMeasureTimestamp = fraction_1.Fraction.minus(absoluteTimestamp, measure.parentSourceMeasure.AbsoluteTimestamp);
+        this.resetYPositionForLeadSheet(graphicalStaffEntry.PositionAndShape);
+        measure.addGraphicalStaffEntry(graphicalStaffEntry);
+        return graphicalStaffEntry;
+    };
+    MusicSheetCalculator.prototype.updateSkyBottomLines = function () {
+        for (var idx = 0, len = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
+            var graphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
+            for (var idx2 = 0, len2 = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
+                var musicSystem = graphicalMusicPage.MusicSystems[idx2];
+                for (var idx3 = 0, len3 = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
+                    var staffLine = musicSystem.StaffLines[idx3];
+                    this.updateSkyBottomLine(staffLine);
+                }
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.handleStaffEntries = function () {
+        for (var idx = 0, len = this.graphicalMusicSheet.MeasureList.length; idx < len; ++idx) {
+            var measures = this.graphicalMusicSheet.MeasureList[idx];
+            for (var idx2 = 0, len2 = measures.length; idx2 < len2; ++idx2) {
+                var measure = measures[idx2];
+                for (var idx3 = 0, len3 = measure.staffEntries.length; idx3 < len3; ++idx3) {
+                    var graphicalStaffEntry = measure.staffEntries[idx3];
+                    if (graphicalStaffEntry.parentMeasure !== undefined && graphicalStaffEntry.notes.length > 0 && graphicalStaffEntry.notes[0].length > 0) {
+                        this.layoutVoiceEntries(graphicalStaffEntry);
+                        this.layoutStaffEntry(graphicalStaffEntry);
+                    }
+                }
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.calculateSkyBottomLines = function () {
+        for (var idx = 0, len = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
+            var graphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
+            for (var idx2 = 0, len2 = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
+                var musicSystem = graphicalMusicPage.MusicSystems[idx2];
+                for (var idx3 = 0, len3 = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
+                    var staffLine = musicSystem.StaffLines[idx3];
+                    this.calculateSkyBottomLine(staffLine);
+                }
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.calculateBeams = function () {
+        for (var idx = 0, len = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
+            var musicPage = this.graphicalMusicSheet.MusicPages[idx];
+            for (var idx2 = 0, len2 = musicPage.MusicSystems.length; idx2 < len2; ++idx2) {
+                var musicSystem = musicPage.MusicSystems[idx2];
+                for (var idx3 = 0, len3 = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
+                    var staffLine = musicSystem.StaffLines[idx3];
+                    for (var idx4 = 0, len4 = staffLine.Measures.length; idx4 < len4; ++idx4) {
+                        var measure = staffLine.Measures[idx4];
+                        for (var idx5 = 0, len5 = measure.staffEntries.length; idx5 < len5; ++idx5) {
+                            var staffEntry = measure.staffEntries[idx5];
+                            this.layoutBeams(staffEntry);
+                        }
+                    }
+                }
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.calculateStaffEntryArticulationMarks = function () {
+        for (var idx = 0, len = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
+            var page = this.graphicalMusicSheet.MusicPages[idx];
+            for (var idx2 = 0, len2 = page.MusicSystems.length; idx2 < len2; ++idx2) {
+                var system = page.MusicSystems[idx2];
+                for (var idx3 = 0, len3 = system.StaffLines.length; idx3 < len3; ++idx3) {
+                    var line = system.StaffLines[idx3];
+                    for (var idx4 = 0, len4 = line.Measures.length; idx4 < len4; ++idx4) {
+                        var measure = line.Measures[idx4];
+                        for (var idx5 = 0, len5 = measure.staffEntries.length; idx5 < len5; ++idx5) {
+                            var graphicalStaffEntry = measure.staffEntries[idx5];
+                            for (var idx6 = 0, len6 = graphicalStaffEntry.sourceStaffEntry.VoiceEntries.length; idx6 < len6; ++idx6) {
+                                var voiceEntry = graphicalStaffEntry.sourceStaffEntry.VoiceEntries[idx6];
+                                if (voiceEntry.Articulations.length > 0) {
+                                    this.layoutArticulationMarks(voiceEntry.Articulations, voiceEntry, graphicalStaffEntry);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.calculateOrnaments = function () {
+        for (var idx = 0, len = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
+            var page = this.graphicalMusicSheet.MusicPages[idx];
+            for (var idx2 = 0, len2 = page.MusicSystems.length; idx2 < len2; ++idx2) {
+                var system = page.MusicSystems[idx2];
+                for (var idx3 = 0, len3 = system.StaffLines.length; idx3 < len3; ++idx3) {
+                    var line = system.StaffLines[idx3];
+                    for (var idx4 = 0, len4 = line.Measures.length; idx4 < len4; ++idx4) {
+                        var measure = line.Measures[idx4];
+                        for (var idx5 = 0, len5 = measure.staffEntries.length; idx5 < len5; ++idx5) {
+                            var graphicalStaffEntry = measure.staffEntries[idx5];
+                            for (var idx6 = 0, len6 = graphicalStaffEntry.sourceStaffEntry.VoiceEntries.length; idx6 < len6; ++idx6) {
+                                var voiceEntry = graphicalStaffEntry.sourceStaffEntry.VoiceEntries[idx6];
+                                if (voiceEntry.OrnamentContainer !== undefined) {
+                                    if (voiceEntry.hasTie() && graphicalStaffEntry.relInMeasureTimestamp !== voiceEntry.Timestamp) {
+                                        continue;
+                                    }
+                                    this.layoutOrnament(voiceEntry.OrnamentContainer, voiceEntry, graphicalStaffEntry);
+                                    if (!(this.staffEntriesWithOrnaments.indexOf(graphicalStaffEntry) !== -1)) {
+                                        this.staffEntriesWithOrnaments.push(graphicalStaffEntry);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.optimizeRestPlacement = function () {
+        for (var idx = 0, len = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
+            var page = this.graphicalMusicSheet.MusicPages[idx];
+            for (var idx2 = 0, len2 = page.MusicSystems.length; idx2 < len2; ++idx2) {
+                var system = page.MusicSystems[idx2];
+                for (var idx3 = 0, len3 = system.StaffLines.length; idx3 < len3; ++idx3) {
+                    var line = system.StaffLines[idx3];
+                    for (var idx4 = 0, len4 = line.Measures.length; idx4 < len4; ++idx4) {
+                        var measure = line.Measures[idx4];
+                        for (var idx5 = 0, len5 = measure.staffEntries.length; idx5 < len5; ++idx5) {
+                            var graphicalStaffEntry = measure.staffEntries[idx5];
+                            this.optimizeRestNotePlacement(graphicalStaffEntry, measure);
+                        }
+                    }
+                }
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.calculateTwoRestNotesPlacementWithCollisionDetection = function (graphicalStaffEntry) {
+        var firstRestNote = graphicalStaffEntry.notes[0][0];
+        var secondRestNote = graphicalStaffEntry.notes[1][0];
+        secondRestNote.PositionAndShape.RelativePosition = new PointF2D_1.PointF2D(0.0, 2.5);
+        graphicalStaffEntry.PositionAndShape.calculateAbsolutePositionsRecursiveWithoutTopelement();
+        firstRestNote.PositionAndShape.computeNonOverlappingPositionWithMargin(graphicalStaffEntry.PositionAndShape, BoundingBox_1.ColDirEnum.Up, new PointF2D_1.PointF2D(0.0, secondRestNote.PositionAndShape.RelativePosition.y));
+        var relative = firstRestNote.PositionAndShape.RelativePosition;
+        relative.y -= 1.0;
+        firstRestNote.PositionAndShape.RelativePosition = relative;
+        graphicalStaffEntry.PositionAndShape.calculateBoundingBox();
+    };
+    MusicSheetCalculator.prototype.calculateRestNotePlacementWithCollisionDetectionFromGraphicalNote = function (graphicalStaffEntry) {
+        var restNote;
+        var graphicalNotes;
+        if (graphicalStaffEntry.notes[0][0].sourceNote.Pitch === undefined) {
+            restNote = graphicalStaffEntry.notes[0][0];
+            graphicalNotes = graphicalStaffEntry.notes[1];
+        }
+        else {
+            graphicalNotes = graphicalStaffEntry.notes[0];
+            restNote = graphicalStaffEntry.notes[1][0];
+        }
+        var collision = false;
+        graphicalStaffEntry.PositionAndShape.calculateAbsolutePositionsRecursiveWithoutTopelement();
+        for (var idx = 0, len = graphicalNotes.length; idx < len; ++idx) {
+            var graphicalNote = graphicalNotes[idx];
+            if (restNote.PositionAndShape.marginCollisionDetection(graphicalNote.PositionAndShape)) {
+                collision = true;
+                break;
+            }
+        }
+        if (collision) {
+            if (restNote.sourceNote.ParentVoiceEntry.ParentVoice instanceof LinkedVoice_1.LinkedVoice) {
+                var bottomBorder = graphicalNotes[0].PositionAndShape.BorderMarginBottom + graphicalNotes[0].PositionAndShape.RelativePosition.y;
+                restNote.PositionAndShape.RelativePosition = new PointF2D_1.PointF2D(0.0, bottomBorder - restNote.PositionAndShape.BorderMarginTop + 0.5);
+            }
+            else {
+                var last = graphicalNotes[graphicalNotes.length - 1];
+                var topBorder = last.PositionAndShape.BorderMarginTop + last.PositionAndShape.RelativePosition.y;
+                if (graphicalNotes[0].sourceNote.ParentVoiceEntry.ParentVoice instanceof LinkedVoice_1.LinkedVoice) {
+                    restNote.PositionAndShape.RelativePosition = new PointF2D_1.PointF2D(0.0, topBorder - restNote.PositionAndShape.BorderMarginBottom - 0.5);
+                }
+                else {
+                    var bottomBorder = graphicalNotes[0].PositionAndShape.BorderMarginBottom + graphicalNotes[0].PositionAndShape.RelativePosition.y;
+                    if (bottomBorder < 2.0) {
+                        restNote.PositionAndShape.RelativePosition = new PointF2D_1.PointF2D(0.0, bottomBorder - restNote.PositionAndShape.BorderMarginTop + 0.5);
+                    }
+                    else {
+                        restNote.PositionAndShape.RelativePosition = new PointF2D_1.PointF2D(0.0, topBorder - restNote.PositionAndShape.BorderMarginBottom - 0.0);
+                    }
+                }
+            }
+        }
+        graphicalStaffEntry.PositionAndShape.calculateBoundingBox();
+    };
+    MusicSheetCalculator.prototype.calculateTieCurves = function () {
+        for (var idx = 0, len = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
+            var graphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
+            for (var idx2 = 0, len2 = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
+                var musicSystem = graphicalMusicPage.MusicSystems[idx2];
+                for (var idx3 = 0, len3 = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
+                    var staffLine = musicSystem.StaffLines[idx3];
+                    for (var idx4 = 0, len5 = staffLine.Measures.length; idx4 < len5; ++idx4) {
+                        var measure = staffLine.Measures[idx4];
+                        for (var idx6 = 0, len6 = measure.staffEntries.length; idx6 < len6; ++idx6) {
+                            var staffEntry = measure.staffEntries[idx6];
+                            var graphicalTies = staffEntry.GraphicalTies;
+                            for (var idx7 = 0, len7 = graphicalTies.length; idx7 < len7; ++idx7) {
+                                var graphicalTie = graphicalTies[idx7];
+                                if (graphicalTie.StartNote !== undefined && graphicalTie.StartNote.parentStaffEntry === staffEntry) {
+                                    var tieIsAtSystemBreak = (graphicalTie.StartNote.parentStaffEntry.parentMeasure.ParentStaffLine !==
+                                        graphicalTie.EndNote.parentStaffEntry.parentMeasure.ParentStaffLine);
+                                    this.layoutGraphicalTie(graphicalTie, tieIsAtSystemBreak);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    };
+    // Commented because unused:
+    //private calculateFingering(): void {
+    //    for (let idx: number = 0, len: number = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
+    //        let graphicalMusicPage: GraphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
+    //        for (let idx2: number = 0, len2: number = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
+    //            let musicSystem: MusicSystem = graphicalMusicPage.MusicSystems[idx2];
+    //            for (let idx3: number = 0, len3: number = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
+    //                let staffLine: StaffLine = musicSystem.StaffLines[idx3];
+    //                let skyBottomLineCalculator: SkyBottomLineCalculator = new SkyBottomLineCalculator(this.rules);
+    //                for (let idx4: number = 0, len4: number = staffLine.Measures.length; idx4 < len4; ++idx4) {
+    //                    let measure: StaffMeasure = staffLine.Measures[idx4];
+    //                    let measureRelativePosition: PointF2D = measure.PositionAndShape.RelativePosition;
+    //                    for (let idx5: number = 0, len5: number = measure.staffEntries.length; idx5 < len5; ++idx5) {
+    //                        let staffEntry: GraphicalStaffEntry = measure.staffEntries[idx5];
+    //                        let hasTechnicalInstruction: boolean = false;
+    //                        for (let idx6: number = 0, len6: number = staffEntry.sourceStaffEntry.VoiceEntries.length; idx6 < len6; ++idx6) {
+    //                            let ve: VoiceEntry = staffEntry.sourceStaffEntry.VoiceEntries[idx6];
+    //                            if (ve.TechnicalInstructions.length > 0) {
+    //                                hasTechnicalInstruction = true;
+    //                                break;
+    //                            }
+    //                        }
+    //                        if (hasTechnicalInstruction) {
+    //                            this.layoutFingering(staffLine, skyBottomLineCalculator, staffEntry, measureRelativePosition);
+    //                        }
+    //                    }
+    //                }
+    //            }
+    //        }
+    //    }
+    //}
+    MusicSheetCalculator.prototype.calculateLyricsPosition = function () {
+        for (var idx = 0, len = this.graphicalMusicSheet.ParentMusicSheet.Instruments.length; idx < len; ++idx) {
+            var instrument = this.graphicalMusicSheet.ParentMusicSheet.Instruments[idx];
+            if (instrument.HasLyrics && instrument.LyricVersesNumbers.length > 0) {
+                instrument.LyricVersesNumbers.sort();
+            }
+        }
+        for (var idx = 0, len = this.graphicalMusicSheet.MusicPages.length; idx < len; ++idx) {
+            var graphicalMusicPage = this.graphicalMusicSheet.MusicPages[idx];
+            for (var idx2 = 0, len2 = graphicalMusicPage.MusicSystems.length; idx2 < len2; ++idx2) {
+                var musicSystem = graphicalMusicPage.MusicSystems[idx2];
+                for (var idx3 = 0, len3 = musicSystem.StaffLines.length; idx3 < len3; ++idx3) {
+                    var staffLine = musicSystem.StaffLines[idx3];
+                    this.calculateSingleStaffLineLyricsPosition(staffLine, staffLine.ParentStaff.ParentInstrument.LyricVersesNumbers);
+                }
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.calculateDynamicExpressions = function () {
+        for (var i = 0; i < this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length; i++) {
+            var sourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures[i];
+            for (var j = 0; j < sourceMeasure.StaffLinkedExpressions.length; j++) {
+                if (this.graphicalMusicSheet.MeasureList[i][j].ParentStaff.ParentInstrument.Visible) {
+                    for (var k = 0; k < sourceMeasure.StaffLinkedExpressions[j].length; k++) {
+                        if (sourceMeasure.StaffLinkedExpressions[j][k].InstantaniousDynamic !== undefined ||
+                            (sourceMeasure.StaffLinkedExpressions[j][k].StartingContinuousDynamic !== undefined &&
+                                sourceMeasure.StaffLinkedExpressions[j][k].StartingContinuousDynamic.StartMultiExpression ===
+                                    sourceMeasure.StaffLinkedExpressions[j][k] && sourceMeasure.StaffLinkedExpressions[j][k].UnknownList.length === 0)) {
+                            this.calculateDynamicExpressionsForSingleMultiExpression(sourceMeasure.StaffLinkedExpressions[j][k], i, j);
+                        }
+                    }
+                }
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.calculateOctaveShifts = function () {
+        for (var i = 0; i < this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length; i++) {
+            var sourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures[i];
+            for (var j = 0; j < sourceMeasure.StaffLinkedExpressions.length; j++) {
+                if (this.graphicalMusicSheet.MeasureList[i][j].ParentStaff.ParentInstrument.Visible) {
+                    for (var k = 0; k < sourceMeasure.StaffLinkedExpressions[j].length; k++) {
+                        if ((sourceMeasure.StaffLinkedExpressions[j][k].OctaveShiftStart !== undefined)) {
+                            this.calculateSingleOctaveShift(sourceMeasure, sourceMeasure.StaffLinkedExpressions[j][k], i, j);
+                        }
+                    }
+                }
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.getFirstLeftNotNullStaffEntryFromContainer = function (horizontalIndex, verticalIndex, multiStaffInstrument) {
+        if (this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[horizontalIndex].StaffEntries[verticalIndex] !== undefined) {
+            return this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[horizontalIndex].StaffEntries[verticalIndex];
+        }
+        for (var i = horizontalIndex - 1; i >= 0; i--) {
+            if (this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[i].StaffEntries[verticalIndex] !== undefined) {
+                return this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[i].StaffEntries[verticalIndex];
+            }
+        }
+        return undefined;
+    };
+    MusicSheetCalculator.prototype.getFirstRightNotNullStaffEntryFromContainer = function (horizontalIndex, verticalIndex, multiStaffInstrument) {
+        if (this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[horizontalIndex].StaffEntries[verticalIndex] !== undefined) {
+            return this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[horizontalIndex].StaffEntries[verticalIndex];
+        }
+        for (var i = horizontalIndex + 1; i < this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers.length; i++) {
+            if (this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[i].StaffEntries[verticalIndex] !== undefined) {
+                return this.graphicalMusicSheet.VerticalGraphicalStaffEntryContainers[i].StaffEntries[verticalIndex];
+            }
+        }
+        return undefined;
+    };
+    MusicSheetCalculator.prototype.calculateWordRepetitionInstructions = function () {
+        for (var i = 0; i < this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length; i++) {
+            var sourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures[i];
+            for (var idx = 0, len = sourceMeasure.FirstRepetitionInstructions.length; idx < len; ++idx) {
+                var instruction = sourceMeasure.FirstRepetitionInstructions[idx];
+                this.calculateWordRepetitionInstruction(instruction, i);
+            }
+            for (var idx = 0, len = sourceMeasure.LastRepetitionInstructions.length; idx < len; ++idx) {
+                var instruction = sourceMeasure.LastRepetitionInstructions[idx];
+                this.calculateWordRepetitionInstruction(instruction, i);
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.calculateRepetitionEndings = function () {
+        var musicsheet = this.graphicalMusicSheet.ParentMusicSheet;
+        for (var idx = 0, len = musicsheet.Repetitions.length; idx < len; ++idx) {
+            var partListEntry = musicsheet.Repetitions[idx];
+            this.calcGraphicalRepetitionEndingsRecursively(partListEntry);
+        }
+    };
+    MusicSheetCalculator.prototype.calculateTempoExpressions = function () {
+        for (var i = 0; i < this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length; i++) {
+            var sourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures[i];
+            for (var j = 0; j < sourceMeasure.TempoExpressions.length; j++) {
+                this.calculateTempoExpressionsForSingleMultiTempoExpression(sourceMeasure, sourceMeasure.TempoExpressions[j], i);
+            }
+        }
+    };
+    MusicSheetCalculator.prototype.calculateMoodAndUnknownExpressions = function () {
+        for (var i = 0; i < this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length; i++) {
+            var sourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures[i];
+            for (var j = 0; j < sourceMeasure.StaffLinkedExpressions.length; j++) {
+                if (this.graphicalMusicSheet.MeasureList[i][j].ParentStaff.ParentInstrument.Visible) {
+                    for (var k = 0; k < sourceMeasure.StaffLinkedExpressions[j].length; k++) {
+                        if ((sourceMeasure.StaffLinkedExpressions[j][k].MoodList.length > 0) ||
+                            (sourceMeasure.StaffLinkedExpressions[j][k].UnknownList.length > 0)) {
+                            this.calculateMoodAndUnknownExpression(sourceMeasure.StaffLinkedExpressions[j][k], i, j);
+                        }
+                    }
+                }
+            }
+        }
+    };
+    return MusicSheetCalculator;
+}());
+exports.MusicSheetCalculator = MusicSheetCalculator;

+ 70 - 0
dist/src/MusicalScore/Graphical/MusicSheetDrawer.d.ts

@@ -0,0 +1,70 @@
+import { EngravingRules } from "./EngravingRules";
+import { ITextMeasurer } from "../Interfaces/ITextMeasurer";
+import { GraphicalMusicSheet } from "./GraphicalMusicSheet";
+import { BoundingBox } from "./BoundingBox";
+import { DrawingParameters } from "./DrawingParameters";
+import { GraphicalLine } from "./GraphicalLine";
+import { RectangleF2D } from "../../Common/DataObjects/RectangleF2D";
+import { PointF2D } from "../../Common/DataObjects/PointF2D";
+import { GraphicalRectangle } from "./GraphicalRectangle";
+import { GraphicalLabel } from "./GraphicalLabel";
+import { SelectionStartSymbol } from "./SelectionStartSymbol";
+import { SelectionEndSymbol } from "./SelectionEndSymbol";
+import { MusicSystem } from "./MusicSystem";
+import { StaffMeasure } from "./StaffMeasure";
+import { StaffLine } from "./StaffLine";
+import { SystemLine } from "./SystemLine";
+import { MusicSymbol } from "./MusicSymbol";
+import { MusicSymbolDrawingStyle, PhonicScoreModes } from "./DrawingMode";
+import { GraphicalOctaveShift } from "./GraphicalOctaveShift";
+import { GraphicalObject } from "./GraphicalObject";
+export declare abstract class MusicSheetDrawer {
+    drawingParameters: DrawingParameters;
+    splitScreenLineColor: number;
+    midiPlaybackAvailable: boolean;
+    protected rules: EngravingRules;
+    protected graphicalMusicSheet: GraphicalMusicSheet;
+    protected textMeasurer: ITextMeasurer;
+    private phonicScoreMode;
+    constructor(textMeasurer: ITextMeasurer, isPreviewImageDrawer?: boolean);
+    Mode: PhonicScoreModes;
+    drawSheet(graphicalMusicSheet: GraphicalMusicSheet): void;
+    drawLineAsHorizontalRectangle(line: GraphicalLine, layer: number): void;
+    drawLineAsVerticalRectangle(line: GraphicalLine, layer: number): void;
+    drawLineAsHorizontalRectangleWithOffset(line: GraphicalLine, offset: PointF2D, layer: number): void;
+    drawLineAsVerticalRectangleWithOffset(line: GraphicalLine, offset: PointF2D, layer: number): void;
+    drawRectangle(rect: GraphicalRectangle, layer: number): void;
+    calculatePixelDistance(unitDistance: number): number;
+    drawLabel(graphicalLabel: GraphicalLabel, layer: number): void;
+    protected applyScreenTransformation(point: PointF2D): PointF2D;
+    protected applyScreenTransformations(points: PointF2D[]): PointF2D[];
+    protected applyScreenTransformationForRect(rectangle: RectangleF2D): RectangleF2D;
+    protected drawSplitScreenLine(): void;
+    protected renderRectangle(rectangle: RectangleF2D, layer: number, styleId: number): void;
+    protected drawScrollIndicator(): void;
+    protected drawSelectionStartSymbol(symbol: SelectionStartSymbol): void;
+    protected drawSelectionEndSymbol(symbol: SelectionEndSymbol): void;
+    protected renderLabel(graphicalLabel: GraphicalLabel, layer: number, bitmapWidth: number, bitmapHeight: number, heightInPixel: number, screenPosition: PointF2D): void;
+    protected renderSystemToScreen(system: MusicSystem, systemBoundingBoxInPixels: RectangleF2D, absBoundingRectWithMargin: RectangleF2D): void;
+    protected drawMeasure(measure: StaffMeasure): void;
+    protected drawSkyLine(staffLine: StaffLine): void;
+    protected drawBottomLine(staffLine: StaffLine): void;
+    protected drawInstrumentBracket(bracket: GraphicalObject, system: MusicSystem): void;
+    protected drawGroupBracket(bracket: GraphicalObject, system: MusicSystem): void;
+    protected isVisible(psi: BoundingBox): boolean;
+    protected drawMusicSystem(system: MusicSystem): void;
+    protected getSytemBoundingBoxInPixels(absBoundingRectWithMargin: RectangleF2D): RectangleF2D;
+    protected getSystemAbsBoundingRect(system: MusicSystem): RectangleF2D;
+    protected drawMusicSystemComponents(musicSystem: MusicSystem, systemBoundingBoxInPixels: RectangleF2D, absBoundingRectWithMargin: RectangleF2D): void;
+    protected activateSystemRendering(systemId: number, absBoundingRect: RectangleF2D, systemBoundingBoxInPixels: RectangleF2D, createNewImage: boolean): boolean;
+    protected drawSystemLineObject(systemLine: SystemLine): void;
+    protected drawStaffLine(staffLine: StaffLine): void;
+    protected drawOctaveShift(staffLine: StaffLine, graphicalOctaveShift: GraphicalOctaveShift): void;
+    protected drawStaffLines(staffLine: StaffLine): void;
+    protected drawSymbol(symbol: MusicSymbol, symbolStyle: MusicSymbolDrawingStyle, position: PointF2D, scalingFactor?: number, layer?: number): void;
+    protected leadSheet: boolean;
+    private drawPage(page);
+    private drawMarkedAreas(system);
+    private drawComment(system);
+    private drawStaffLineSymbols(staffLine);
+}

+ 438 - 0
dist/src/MusicalScore/Graphical/MusicSheetDrawer.js

@@ -0,0 +1,438 @@
+"use strict";
+var BoundingBox_1 = require("./BoundingBox");
+var DrawingEnums_1 = require("./DrawingEnums");
+var DrawingParameters_1 = require("./DrawingParameters");
+var GraphicalLine_1 = require("./GraphicalLine");
+var RectangleF2D_1 = require("../../Common/DataObjects/RectangleF2D");
+var PointF2D_1 = require("../../Common/DataObjects/PointF2D");
+var TextAlignment_1 = require("../../Common/Enums/TextAlignment");
+var Exceptions_1 = require("../Exceptions");
+var MusicSymbol_1 = require("./MusicSymbol");
+var DrawingMode_1 = require("./DrawingMode");
+var MusicSheetDrawer = (function () {
+    function MusicSheetDrawer(textMeasurer, isPreviewImageDrawer) {
+        if (isPreviewImageDrawer === void 0) { isPreviewImageDrawer = false; }
+        this.drawingParameters = new DrawingParameters_1.DrawingParameters();
+        this.phonicScoreMode = DrawingMode_1.PhonicScoreModes.Manual;
+        this.textMeasurer = textMeasurer;
+        this.splitScreenLineColor = -1;
+        if (isPreviewImageDrawer) {
+            this.drawingParameters.setForThumbmail();
+        }
+        else {
+            this.drawingParameters.setForAllOn();
+        }
+    }
+    Object.defineProperty(MusicSheetDrawer.prototype, "Mode", {
+        set: function (value) {
+            this.phonicScoreMode = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    MusicSheetDrawer.prototype.drawSheet = function (graphicalMusicSheet) {
+        this.graphicalMusicSheet = graphicalMusicSheet;
+        this.rules = graphicalMusicSheet.ParentMusicSheet.Rules;
+        this.drawSplitScreenLine();
+        if (this.drawingParameters.drawCursors) {
+            for (var _i = 0, _a = graphicalMusicSheet.Cursors; _i < _a.length; _i++) {
+                var line = _a[_i];
+                var psi = new BoundingBox_1.BoundingBox(line);
+                psi.AbsolutePosition = line.Start;
+                psi.BorderBottom = line.End.y - line.Start.y;
+                psi.BorderRight = line.Width / 2.0;
+                psi.BorderLeft = -line.Width / 2.0;
+                if (this.isVisible(psi)) {
+                    this.drawLineAsVerticalRectangle(line, DrawingEnums_1.GraphicalLayers.Cursor);
+                }
+            }
+        }
+        if (this.drawingParameters.drawScrollIndicator) {
+            this.drawScrollIndicator();
+        }
+        for (var _b = 0, _c = this.graphicalMusicSheet.MusicPages; _b < _c.length; _b++) {
+            var page = _c[_b];
+            this.drawPage(page);
+        }
+    };
+    MusicSheetDrawer.prototype.drawLineAsHorizontalRectangle = function (line, layer) {
+        var rectangle = new RectangleF2D_1.RectangleF2D(line.Start.x, line.End.y - line.Width / 2, line.End.x - line.Start.x, line.Width);
+        rectangle = this.applyScreenTransformationForRect(rectangle);
+        this.renderRectangle(rectangle, layer, line.styleId);
+    };
+    MusicSheetDrawer.prototype.drawLineAsVerticalRectangle = function (line, layer) {
+        var lineStart = line.Start;
+        var lineWidth = line.Width;
+        var rectangle = new RectangleF2D_1.RectangleF2D(lineStart.x - lineWidth / 2, lineStart.y, lineWidth, line.End.y - lineStart.y);
+        rectangle = this.applyScreenTransformationForRect(rectangle);
+        this.renderRectangle(rectangle, layer, line.styleId);
+    };
+    MusicSheetDrawer.prototype.drawLineAsHorizontalRectangleWithOffset = function (line, offset, layer) {
+        var start = new PointF2D_1.PointF2D(line.Start.x + offset.x, line.Start.y + offset.y);
+        var end = new PointF2D_1.PointF2D(line.End.x + offset.x, line.End.y + offset.y);
+        var width = line.Width;
+        var rectangle = new RectangleF2D_1.RectangleF2D(start.x, end.y - width / 2, end.x - start.x, width);
+        rectangle = this.applyScreenTransformationForRect(rectangle);
+        this.renderRectangle(rectangle, layer, line.styleId);
+    };
+    MusicSheetDrawer.prototype.drawLineAsVerticalRectangleWithOffset = function (line, offset, layer) {
+        var start = new PointF2D_1.PointF2D(line.Start.x + offset.x, line.Start.y + offset.y);
+        var end = new PointF2D_1.PointF2D(line.End.x + offset.x, line.End.y + offset.y);
+        var width = line.Width;
+        var rectangle = new RectangleF2D_1.RectangleF2D(start.x, start.y, width, end.y - start.y);
+        rectangle = this.applyScreenTransformationForRect(rectangle);
+        this.renderRectangle(rectangle, layer, line.styleId);
+    };
+    MusicSheetDrawer.prototype.drawRectangle = function (rect, layer) {
+        var psi = rect.PositionAndShape;
+        var rectangle = new RectangleF2D_1.RectangleF2D(psi.AbsolutePosition.x, psi.AbsolutePosition.y, psi.BorderRight, psi.BorderBottom);
+        rectangle = this.applyScreenTransformationForRect(rectangle);
+        this.renderRectangle(rectangle, layer, rect.style);
+    };
+    MusicSheetDrawer.prototype.calculatePixelDistance = function (unitDistance) {
+        throw new Error("not implemented");
+    };
+    MusicSheetDrawer.prototype.drawLabel = function (graphicalLabel, layer) {
+        if (!this.isVisible(graphicalLabel.PositionAndShape)) {
+            return;
+        }
+        var label = graphicalLabel.Label;
+        if (label.text.trim() === "") {
+            return;
+        }
+        var screenPosition = this.applyScreenTransformation(graphicalLabel.PositionAndShape.AbsolutePosition);
+        var heightInPixel = this.calculatePixelDistance(label.fontHeight);
+        var widthInPixel = heightInPixel * this.textMeasurer.computeTextWidthToHeightRatio(label.text, label.font, label.fontStyle);
+        var bitmapWidth = Math.ceil(widthInPixel);
+        var bitmapHeight = Math.ceil(heightInPixel * 1.2);
+        switch (label.textAlignment) {
+            case TextAlignment_1.TextAlignment.LeftTop:
+                break;
+            case TextAlignment_1.TextAlignment.LeftCenter:
+                screenPosition.y -= bitmapHeight / 2;
+                break;
+            case TextAlignment_1.TextAlignment.LeftBottom:
+                screenPosition.y -= bitmapHeight;
+                break;
+            case TextAlignment_1.TextAlignment.CenterTop:
+                screenPosition.x -= bitmapWidth / 2;
+                break;
+            case TextAlignment_1.TextAlignment.CenterCenter:
+                screenPosition.x -= bitmapWidth / 2;
+                screenPosition.y -= bitmapHeight / 2;
+                break;
+            case TextAlignment_1.TextAlignment.CenterBottom:
+                screenPosition.x -= bitmapWidth / 2;
+                screenPosition.y -= bitmapHeight;
+                break;
+            case TextAlignment_1.TextAlignment.RightTop:
+                screenPosition.x -= bitmapWidth;
+                break;
+            case TextAlignment_1.TextAlignment.RightCenter:
+                screenPosition.x -= bitmapWidth;
+                screenPosition.y -= bitmapHeight / 2;
+                break;
+            case TextAlignment_1.TextAlignment.RightBottom:
+                screenPosition.x -= bitmapWidth;
+                screenPosition.y -= bitmapHeight;
+                break;
+            default:
+                throw new Exceptions_1.ArgumentOutOfRangeException("");
+        }
+        this.renderLabel(graphicalLabel, layer, bitmapWidth, bitmapHeight, heightInPixel, screenPosition);
+    };
+    MusicSheetDrawer.prototype.applyScreenTransformation = function (point) {
+        throw new Error("not implemented");
+    };
+    MusicSheetDrawer.prototype.applyScreenTransformations = function (points) {
+        var transformedPoints = [];
+        for (var _i = 0, points_1 = points; _i < points_1.length; _i++) {
+            var point = points_1[_i];
+            transformedPoints.push(this.applyScreenTransformation(point));
+        }
+        return transformedPoints;
+    };
+    MusicSheetDrawer.prototype.applyScreenTransformationForRect = function (rectangle) {
+        throw new Error("not implemented");
+    };
+    MusicSheetDrawer.prototype.drawSplitScreenLine = function () {
+        // empty
+    };
+    MusicSheetDrawer.prototype.renderRectangle = function (rectangle, layer, styleId) {
+        throw new Error("not implemented");
+    };
+    MusicSheetDrawer.prototype.drawScrollIndicator = function () {
+        // empty
+    };
+    MusicSheetDrawer.prototype.drawSelectionStartSymbol = function (symbol) {
+        // empty
+    };
+    MusicSheetDrawer.prototype.drawSelectionEndSymbol = function (symbol) {
+        // empty
+    };
+    MusicSheetDrawer.prototype.renderLabel = function (graphicalLabel, layer, bitmapWidth, bitmapHeight, heightInPixel, screenPosition) {
+        throw new Error("not implemented");
+    };
+    MusicSheetDrawer.prototype.renderSystemToScreen = function (system, systemBoundingBoxInPixels, absBoundingRectWithMargin) {
+        // empty
+    };
+    MusicSheetDrawer.prototype.drawMeasure = function (measure) {
+        throw new Error("not implemented");
+    };
+    MusicSheetDrawer.prototype.drawSkyLine = function (staffLine) {
+        // empty
+    };
+    MusicSheetDrawer.prototype.drawBottomLine = function (staffLine) {
+        // empty
+    };
+    MusicSheetDrawer.prototype.drawInstrumentBracket = function (bracket, system) {
+        // empty
+    };
+    MusicSheetDrawer.prototype.drawGroupBracket = function (bracket, system) {
+        // empty
+    };
+    MusicSheetDrawer.prototype.isVisible = function (psi) {
+        return true;
+    };
+    MusicSheetDrawer.prototype.drawMusicSystem = function (system) {
+        var absBoundingRectWithMargin = this.getSystemAbsBoundingRect(system);
+        var systemBoundingBoxInPixels = this.getSytemBoundingBoxInPixels(absBoundingRectWithMargin);
+        this.drawMusicSystemComponents(system, systemBoundingBoxInPixels, absBoundingRectWithMargin);
+    };
+    MusicSheetDrawer.prototype.getSytemBoundingBoxInPixels = function (absBoundingRectWithMargin) {
+        var systemBoundingBoxInPixels = this.applyScreenTransformationForRect(absBoundingRectWithMargin);
+        systemBoundingBoxInPixels.x = Math.round(systemBoundingBoxInPixels.x);
+        systemBoundingBoxInPixels.y = Math.round(systemBoundingBoxInPixels.y);
+        return systemBoundingBoxInPixels;
+    };
+    MusicSheetDrawer.prototype.getSystemAbsBoundingRect = function (system) {
+        var relBoundingRect = system.PositionAndShape.BoundingRectangle;
+        var absBoundingRectWithMargin = new RectangleF2D_1.RectangleF2D(system.PositionAndShape.AbsolutePosition.x + system.PositionAndShape.BorderLeft - 1, system.PositionAndShape.AbsolutePosition.y + system.PositionAndShape.BorderTop - 1, (relBoundingRect.width + 6), (relBoundingRect.height + 2));
+        return absBoundingRectWithMargin;
+    };
+    MusicSheetDrawer.prototype.drawMusicSystemComponents = function (musicSystem, systemBoundingBoxInPixels, absBoundingRectWithMargin) {
+        var selectStartSymb = this.graphicalMusicSheet.SelectionStartSymbol;
+        var selectEndSymb = this.graphicalMusicSheet.SelectionEndSymbol;
+        if (this.drawingParameters.drawSelectionStartSymbol) {
+            if (selectStartSymb !== undefined && this.isVisible(selectStartSymb.PositionAndShape)) {
+                this.drawSelectionStartSymbol(selectStartSymb);
+            }
+        }
+        if (this.drawingParameters.drawSelectionEndSymbol) {
+            if (selectEndSymb !== undefined && this.isVisible(selectEndSymb.PositionAndShape)) {
+                this.drawSelectionEndSymbol(selectEndSymb);
+            }
+        }
+        for (var _i = 0, _a = musicSystem.StaffLines; _i < _a.length; _i++) {
+            var staffLine = _a[_i];
+            this.drawStaffLine(staffLine);
+        }
+        for (var _b = 0, _c = musicSystem.SystemLines; _b < _c.length; _b++) {
+            var systemLine = _c[_b];
+            this.drawSystemLineObject(systemLine);
+        }
+        if (musicSystem === musicSystem.Parent.MusicSystems[0] && musicSystem.Parent === musicSystem.Parent.Parent.MusicPages[0]) {
+            for (var _d = 0, _e = musicSystem.Labels; _d < _e.length; _d++) {
+                var label = _e[_d];
+                this.drawLabel(label, DrawingEnums_1.GraphicalLayers.Notes);
+            }
+        }
+        for (var _f = 0, _g = musicSystem.InstrumentBrackets; _f < _g.length; _f++) {
+            var bracket = _g[_f];
+            this.drawInstrumentBracket(bracket, musicSystem);
+        }
+        for (var _h = 0, _j = musicSystem.GroupBrackets; _h < _j.length; _h++) {
+            var bracket = _j[_h];
+            this.drawGroupBracket(bracket, musicSystem);
+        }
+        if (!this.leadSheet) {
+            for (var _k = 0, _l = musicSystem.MeasureNumberLabels; _k < _l.length; _k++) {
+                var measureNumberLabel = _l[_k];
+                this.drawLabel(measureNumberLabel, DrawingEnums_1.GraphicalLayers.Notes);
+            }
+        }
+        for (var _m = 0, _o = musicSystem.StaffLines; _m < _o.length; _m++) {
+            var staffLine = _o[_m];
+            this.drawStaffLineSymbols(staffLine);
+        }
+        if (this.drawingParameters.drawMarkedAreas) {
+            this.drawMarkedAreas(musicSystem);
+        }
+        if (this.drawingParameters.drawComments) {
+            this.drawComment(musicSystem);
+        }
+    };
+    MusicSheetDrawer.prototype.activateSystemRendering = function (systemId, absBoundingRect, systemBoundingBoxInPixels, createNewImage) {
+        return true;
+    };
+    MusicSheetDrawer.prototype.drawSystemLineObject = function (systemLine) {
+        // empty
+    };
+    MusicSheetDrawer.prototype.drawStaffLine = function (staffLine) {
+        for (var _i = 0, _a = staffLine.Measures; _i < _a.length; _i++) {
+            var measure = _a[_i];
+            this.drawMeasure(measure);
+        }
+    };
+    // protected drawSlur(slur: GraphicalSlur, abs: PointF2D): void {
+    //
+    // }
+    MusicSheetDrawer.prototype.drawOctaveShift = function (staffLine, graphicalOctaveShift) {
+        this.drawSymbol(graphicalOctaveShift.octaveSymbol, DrawingMode_1.MusicSymbolDrawingStyle.Normal, graphicalOctaveShift.PositionAndShape.AbsolutePosition);
+        var absolutePos = staffLine.PositionAndShape.AbsolutePosition;
+        if (graphicalOctaveShift.dashesStart.x < graphicalOctaveShift.dashesEnd.x) {
+            var horizontalLine = new GraphicalLine_1.GraphicalLine(graphicalOctaveShift.dashesStart, graphicalOctaveShift.dashesEnd, this.rules.OctaveShiftLineWidth);
+            this.drawLineAsHorizontalRectangleWithOffset(horizontalLine, absolutePos, DrawingEnums_1.GraphicalLayers.Notes);
+        }
+        if (!graphicalOctaveShift.endsOnDifferentStaffLine || graphicalOctaveShift.isSecondPart) {
+            var verticalLine = void 0;
+            var dashEnd = graphicalOctaveShift.dashesEnd;
+            var octShiftVertLineLength = this.rules.OctaveShiftVerticalLineLength;
+            var octShiftLineWidth = this.rules.OctaveShiftLineWidth;
+            if (graphicalOctaveShift.octaveSymbol === MusicSymbol_1.MusicSymbol.VA8 || graphicalOctaveShift.octaveSymbol === MusicSymbol_1.MusicSymbol.MA15) {
+                verticalLine = new GraphicalLine_1.GraphicalLine(dashEnd, new PointF2D_1.PointF2D(dashEnd.x, dashEnd.y + octShiftVertLineLength), octShiftLineWidth);
+            }
+            else {
+                verticalLine = new GraphicalLine_1.GraphicalLine(new PointF2D_1.PointF2D(dashEnd.x, dashEnd.y - octShiftVertLineLength), dashEnd, octShiftLineWidth);
+            }
+            this.drawLineAsVerticalRectangleWithOffset(verticalLine, absolutePos, DrawingEnums_1.GraphicalLayers.Notes);
+        }
+    };
+    MusicSheetDrawer.prototype.drawStaffLines = function (staffLine) {
+        if (staffLine.StaffLines !== undefined) {
+            var position = staffLine.PositionAndShape.AbsolutePosition;
+            for (var i = 0; i < 5; i++) {
+                this.drawLineAsHorizontalRectangleWithOffset(staffLine.StaffLines[i], position, DrawingEnums_1.GraphicalLayers.Notes);
+            }
+        }
+    };
+    // protected drawEnding(ending: GraphicalRepetitionEnding, absolutePosition: PointF2D): void {
+    //     if (undefined !== ending.Left)
+    //         drawLineAsVerticalRectangle(ending.Left, absolutePosition, <number>GraphicalLayers.Notes);
+    //     this.drawLineAsHorizontalRectangle(ending.Top, absolutePosition, <number>GraphicalLayers.Notes);
+    //     if (undefined !== ending.Right)
+    //         drawLineAsVerticalRectangle(ending.Right, absolutePosition, <number>GraphicalLayers.Notes);
+    //     this.drawLabel(ending.Label, <number>GraphicalLayers.Notes);
+    // }
+    // protected drawInstantaniousDynamic(expression: GraphicalInstantaniousDynamicExpression): void {
+    //     expression.ExpressionSymbols.forEach(function (expressionSymbol) {
+    //         let position: PointF2D = expressionSymbol.PositionAndShape.AbsolutePosition;
+    //         let symbol: MusicSymbol = expressionSymbol.GetSymbol;
+    //         drawSymbol(symbol, MusicSymbolDrawingStyle.Normal, position);
+    //     });
+    // }
+    // protected drawContinuousDynamic(expression: GraphicalContinuousDynamicExpression,
+    //     absolute: PointF2D): void {
+    //     throw new Error("not implemented");
+    // }
+    MusicSheetDrawer.prototype.drawSymbol = function (symbol, symbolStyle, position, scalingFactor, layer) {
+        if (scalingFactor === void 0) { scalingFactor = 1; }
+        if (layer === void 0) { layer = DrawingEnums_1.GraphicalLayers.Notes; }
+        //empty
+    };
+    Object.defineProperty(MusicSheetDrawer.prototype, "leadSheet", {
+        get: function () {
+            return this.graphicalMusicSheet.LeadSheet;
+        },
+        set: function (value) {
+            this.graphicalMusicSheet.LeadSheet = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    MusicSheetDrawer.prototype.drawPage = function (page) {
+        if (!this.isVisible(page.PositionAndShape)) {
+            return;
+        }
+        for (var _i = 0, _a = page.MusicSystems; _i < _a.length; _i++) {
+            var system = _a[_i];
+            if (this.isVisible(system.PositionAndShape)) {
+                this.drawMusicSystem(system);
+            }
+        }
+        if (page === page.Parent.MusicPages[0]) {
+            for (var _b = 0, _c = page.Labels; _b < _c.length; _b++) {
+                var label = _c[_b];
+                this.drawLabel(label, DrawingEnums_1.GraphicalLayers.Notes);
+            }
+        }
+    };
+    MusicSheetDrawer.prototype.drawMarkedAreas = function (system) {
+        for (var _i = 0, _a = system.GraphicalMarkedAreas; _i < _a.length; _i++) {
+            var markedArea = _a[_i];
+            if (markedArea !== undefined) {
+                if (markedArea.systemRectangle !== undefined) {
+                    this.drawRectangle(markedArea.systemRectangle, DrawingEnums_1.GraphicalLayers.Background);
+                }
+                if (markedArea.settings !== undefined) {
+                    this.drawLabel(markedArea.settings, DrawingEnums_1.GraphicalLayers.Comment);
+                }
+                if (markedArea.labelRectangle !== undefined) {
+                    this.drawRectangle(markedArea.labelRectangle, DrawingEnums_1.GraphicalLayers.Background);
+                }
+                if (markedArea.label !== undefined) {
+                    this.drawLabel(markedArea.label, DrawingEnums_1.GraphicalLayers.Comment);
+                }
+            }
+        }
+    };
+    MusicSheetDrawer.prototype.drawComment = function (system) {
+        for (var _i = 0, _a = system.GraphicalComments; _i < _a.length; _i++) {
+            var comment = _a[_i];
+            if (comment !== undefined) {
+                if (comment.settings !== undefined) {
+                    this.drawLabel(comment.settings, DrawingEnums_1.GraphicalLayers.Comment);
+                }
+                if (comment.label !== undefined) {
+                    this.drawLabel(comment.label, DrawingEnums_1.GraphicalLayers.Comment);
+                }
+            }
+        }
+    };
+    MusicSheetDrawer.prototype.drawStaffLineSymbols = function (staffLine) {
+        var parentInst = staffLine.ParentStaff.ParentInstrument;
+        var absX = staffLine.PositionAndShape.AbsolutePosition.x;
+        var absY = staffLine.PositionAndShape.AbsolutePosition.y + 2;
+        var borderRight = staffLine.PositionAndShape.BorderRight;
+        if (parentInst.highlight && this.drawingParameters.drawHighlights) {
+            this.drawLineAsHorizontalRectangle(new GraphicalLine_1.GraphicalLine(new PointF2D_1.PointF2D(absX, absY), new PointF2D_1.PointF2D(absX + borderRight, absY), 4, DrawingEnums_1.OutlineAndFillStyleEnum.Highlighted), DrawingEnums_1.GraphicalLayers.Highlight);
+        }
+        var style = DrawingMode_1.MusicSymbolDrawingStyle.Disabled;
+        var symbol = MusicSymbol_1.MusicSymbol.PLAY;
+        var drawSymbols = this.drawingParameters.drawActivitySymbols;
+        switch (this.phonicScoreMode) {
+            case DrawingMode_1.PhonicScoreModes.Midi:
+                symbol = MusicSymbol_1.MusicSymbol.PLAY;
+                if (this.midiPlaybackAvailable && staffLine.ParentStaff.audible) {
+                    style = DrawingMode_1.MusicSymbolDrawingStyle.PlaybackSymbols;
+                }
+                break;
+            case DrawingMode_1.PhonicScoreModes.Following:
+                symbol = MusicSymbol_1.MusicSymbol.MIC;
+                if (staffLine.ParentStaff.following) {
+                    style = DrawingMode_1.MusicSymbolDrawingStyle.FollowSymbols;
+                }
+                break;
+            default:
+                drawSymbols = false;
+                break;
+        }
+        if (drawSymbols) {
+            var p = new PointF2D_1.PointF2D(absX + borderRight + 2, absY);
+            this.drawSymbol(symbol, style, p);
+        }
+        if (this.drawingParameters.drawErrors) {
+            for (var _i = 0, _a = staffLine.Measures; _i < _a.length; _i++) {
+                var measure = _a[_i];
+                var measurePSI = measure.PositionAndShape;
+                var absXPSI = measurePSI.AbsolutePosition.x;
+                var absYPSI = measurePSI.AbsolutePosition.y + 2;
+                if (measure.hasError && this.graphicalMusicSheet.ParentMusicSheet.DrawErroneousMeasures) {
+                    this.drawLineAsHorizontalRectangle(new GraphicalLine_1.GraphicalLine(new PointF2D_1.PointF2D(absXPSI, absYPSI), new PointF2D_1.PointF2D(absXPSI + measurePSI.BorderRight, absYPSI), 4, DrawingEnums_1.OutlineAndFillStyleEnum.ErrorUnderlay), DrawingEnums_1.GraphicalLayers.MeasureError);
+                }
+            }
+        }
+    };
+    return MusicSheetDrawer;
+}());
+exports.MusicSheetDrawer = MusicSheetDrawer;

+ 87 - 0
dist/src/MusicalScore/Graphical/MusicSymbol.d.ts

@@ -0,0 +1,87 @@
+export declare enum MusicSymbol {
+    Unused_first_Symbol = 0,
+    BLACK_HEAD = 1,
+    UPWARDS_TAIL = 2,
+    DOWNWARDS_TAIL = 3,
+    UPWARDS_DOUBLE_TAIL = 4,
+    DOWNWARDS_DOUBLE_TAIL = 5,
+    UPWARDS_TRIPLE_TAIL = 6,
+    DOWNWARDS_TRIPLE_TAIL = 7,
+    UPWARDS_QUAD_TAIL = 8,
+    DOWNWARDS_QUAD_TAIL = 9,
+    ROUND_HEAD = 10,
+    WHITE_HEAD = 11,
+    G_CLEF = 12,
+    F_CLEF = 13,
+    C_CLEF = 14,
+    BREVE = 15,
+    BREVE_REST = 16,
+    COMMON_TIME = 17,
+    CUT_TIME = 18,
+    WHOLE_REST = 19,
+    HALF_REST = 20,
+    QUARTER_REST = 21,
+    EIGHTH_REST = 22,
+    SIXTEENTH_REST = 23,
+    THIRTYSECOND_REST = 24,
+    SIXTYFOURTH_REST = 25,
+    FLAT = 26,
+    SHARP = 27,
+    NATURAL = 28,
+    DOUBLE_FLAT = 29,
+    DOUBLE_SHARP = 30,
+    ZERO = 31,
+    ONE = 32,
+    TWO = 33,
+    THREE = 34,
+    FOUR = 35,
+    FIVE = 36,
+    SIX = 37,
+    SEVEN = 38,
+    EIGHT = 39,
+    NINE = 40,
+    DOT = 41,
+    FERMATA = 42,
+    INVERTED_FERMATA = 43,
+    SPICCATO = 44,
+    TENUTO = 45,
+    MARCATO = 46,
+    MARCATISSIMO = 47,
+    INVERTED_MARCATISSIMO = 48,
+    P = 49,
+    F = 50,
+    S = 51,
+    Z = 52,
+    M = 53,
+    R = 54,
+    SEGNO = 55,
+    CODA = 56,
+    DRUM_CLEF = 57,
+    G_CLEF_SUB8 = 58,
+    G_CLEF_SUPER8 = 59,
+    G_CLEF_SUB15 = 60,
+    G_CLEF_SUPER15 = 61,
+    F_CLEF_SUB8 = 62,
+    F_CLEF_SUPER8 = 63,
+    F_CLEF_SUB15 = 64,
+    F_CLEF_SUPER15 = 65,
+    DOWN_BOW = 66,
+    MORDENT = 67,
+    INVERTED_MORDENT = 68,
+    TURN = 69,
+    INVERTED_TURN = 70,
+    LEFTHAND_PIZZICATO = 71,
+    RELEASE_PED = 72,
+    ENGAGE_PED = 73,
+    VA8 = 74,
+    VB8 = 75,
+    TRILL = 76,
+    MA15 = 77,
+    MB15 = 78,
+    HIGH = 79,
+    PLAY = 80,
+    MIC = 81,
+    SNAP_PIZZICATO = 82,
+    NATURAL_HARMONIC = 83,
+    EditPen = 84,
+}

+ 89 - 0
dist/src/MusicalScore/Graphical/MusicSymbol.js

@@ -0,0 +1,89 @@
+"use strict";
+(function (MusicSymbol) {
+    MusicSymbol[MusicSymbol["Unused_first_Symbol"] = 0] = "Unused_first_Symbol";
+    MusicSymbol[MusicSymbol["BLACK_HEAD"] = 1] = "BLACK_HEAD";
+    MusicSymbol[MusicSymbol["UPWARDS_TAIL"] = 2] = "UPWARDS_TAIL";
+    MusicSymbol[MusicSymbol["DOWNWARDS_TAIL"] = 3] = "DOWNWARDS_TAIL";
+    MusicSymbol[MusicSymbol["UPWARDS_DOUBLE_TAIL"] = 4] = "UPWARDS_DOUBLE_TAIL";
+    MusicSymbol[MusicSymbol["DOWNWARDS_DOUBLE_TAIL"] = 5] = "DOWNWARDS_DOUBLE_TAIL";
+    MusicSymbol[MusicSymbol["UPWARDS_TRIPLE_TAIL"] = 6] = "UPWARDS_TRIPLE_TAIL";
+    MusicSymbol[MusicSymbol["DOWNWARDS_TRIPLE_TAIL"] = 7] = "DOWNWARDS_TRIPLE_TAIL";
+    MusicSymbol[MusicSymbol["UPWARDS_QUAD_TAIL"] = 8] = "UPWARDS_QUAD_TAIL";
+    MusicSymbol[MusicSymbol["DOWNWARDS_QUAD_TAIL"] = 9] = "DOWNWARDS_QUAD_TAIL";
+    MusicSymbol[MusicSymbol["ROUND_HEAD"] = 10] = "ROUND_HEAD";
+    MusicSymbol[MusicSymbol["WHITE_HEAD"] = 11] = "WHITE_HEAD";
+    MusicSymbol[MusicSymbol["G_CLEF"] = 12] = "G_CLEF";
+    MusicSymbol[MusicSymbol["F_CLEF"] = 13] = "F_CLEF";
+    MusicSymbol[MusicSymbol["C_CLEF"] = 14] = "C_CLEF";
+    MusicSymbol[MusicSymbol["BREVE"] = 15] = "BREVE";
+    MusicSymbol[MusicSymbol["BREVE_REST"] = 16] = "BREVE_REST";
+    MusicSymbol[MusicSymbol["COMMON_TIME"] = 17] = "COMMON_TIME";
+    MusicSymbol[MusicSymbol["CUT_TIME"] = 18] = "CUT_TIME";
+    MusicSymbol[MusicSymbol["WHOLE_REST"] = 19] = "WHOLE_REST";
+    MusicSymbol[MusicSymbol["HALF_REST"] = 20] = "HALF_REST";
+    MusicSymbol[MusicSymbol["QUARTER_REST"] = 21] = "QUARTER_REST";
+    MusicSymbol[MusicSymbol["EIGHTH_REST"] = 22] = "EIGHTH_REST";
+    MusicSymbol[MusicSymbol["SIXTEENTH_REST"] = 23] = "SIXTEENTH_REST";
+    MusicSymbol[MusicSymbol["THIRTYSECOND_REST"] = 24] = "THIRTYSECOND_REST";
+    MusicSymbol[MusicSymbol["SIXTYFOURTH_REST"] = 25] = "SIXTYFOURTH_REST";
+    MusicSymbol[MusicSymbol["FLAT"] = 26] = "FLAT";
+    MusicSymbol[MusicSymbol["SHARP"] = 27] = "SHARP";
+    MusicSymbol[MusicSymbol["NATURAL"] = 28] = "NATURAL";
+    MusicSymbol[MusicSymbol["DOUBLE_FLAT"] = 29] = "DOUBLE_FLAT";
+    MusicSymbol[MusicSymbol["DOUBLE_SHARP"] = 30] = "DOUBLE_SHARP";
+    MusicSymbol[MusicSymbol["ZERO"] = 31] = "ZERO";
+    MusicSymbol[MusicSymbol["ONE"] = 32] = "ONE";
+    MusicSymbol[MusicSymbol["TWO"] = 33] = "TWO";
+    MusicSymbol[MusicSymbol["THREE"] = 34] = "THREE";
+    MusicSymbol[MusicSymbol["FOUR"] = 35] = "FOUR";
+    MusicSymbol[MusicSymbol["FIVE"] = 36] = "FIVE";
+    MusicSymbol[MusicSymbol["SIX"] = 37] = "SIX";
+    MusicSymbol[MusicSymbol["SEVEN"] = 38] = "SEVEN";
+    MusicSymbol[MusicSymbol["EIGHT"] = 39] = "EIGHT";
+    MusicSymbol[MusicSymbol["NINE"] = 40] = "NINE";
+    MusicSymbol[MusicSymbol["DOT"] = 41] = "DOT";
+    MusicSymbol[MusicSymbol["FERMATA"] = 42] = "FERMATA";
+    MusicSymbol[MusicSymbol["INVERTED_FERMATA"] = 43] = "INVERTED_FERMATA";
+    MusicSymbol[MusicSymbol["SPICCATO"] = 44] = "SPICCATO";
+    MusicSymbol[MusicSymbol["TENUTO"] = 45] = "TENUTO";
+    MusicSymbol[MusicSymbol["MARCATO"] = 46] = "MARCATO";
+    MusicSymbol[MusicSymbol["MARCATISSIMO"] = 47] = "MARCATISSIMO";
+    MusicSymbol[MusicSymbol["INVERTED_MARCATISSIMO"] = 48] = "INVERTED_MARCATISSIMO";
+    MusicSymbol[MusicSymbol["P"] = 49] = "P";
+    MusicSymbol[MusicSymbol["F"] = 50] = "F";
+    MusicSymbol[MusicSymbol["S"] = 51] = "S";
+    MusicSymbol[MusicSymbol["Z"] = 52] = "Z";
+    MusicSymbol[MusicSymbol["M"] = 53] = "M";
+    MusicSymbol[MusicSymbol["R"] = 54] = "R";
+    MusicSymbol[MusicSymbol["SEGNO"] = 55] = "SEGNO";
+    MusicSymbol[MusicSymbol["CODA"] = 56] = "CODA";
+    MusicSymbol[MusicSymbol["DRUM_CLEF"] = 57] = "DRUM_CLEF";
+    MusicSymbol[MusicSymbol["G_CLEF_SUB8"] = 58] = "G_CLEF_SUB8";
+    MusicSymbol[MusicSymbol["G_CLEF_SUPER8"] = 59] = "G_CLEF_SUPER8";
+    MusicSymbol[MusicSymbol["G_CLEF_SUB15"] = 60] = "G_CLEF_SUB15";
+    MusicSymbol[MusicSymbol["G_CLEF_SUPER15"] = 61] = "G_CLEF_SUPER15";
+    MusicSymbol[MusicSymbol["F_CLEF_SUB8"] = 62] = "F_CLEF_SUB8";
+    MusicSymbol[MusicSymbol["F_CLEF_SUPER8"] = 63] = "F_CLEF_SUPER8";
+    MusicSymbol[MusicSymbol["F_CLEF_SUB15"] = 64] = "F_CLEF_SUB15";
+    MusicSymbol[MusicSymbol["F_CLEF_SUPER15"] = 65] = "F_CLEF_SUPER15";
+    MusicSymbol[MusicSymbol["DOWN_BOW"] = 66] = "DOWN_BOW";
+    MusicSymbol[MusicSymbol["MORDENT"] = 67] = "MORDENT";
+    MusicSymbol[MusicSymbol["INVERTED_MORDENT"] = 68] = "INVERTED_MORDENT";
+    MusicSymbol[MusicSymbol["TURN"] = 69] = "TURN";
+    MusicSymbol[MusicSymbol["INVERTED_TURN"] = 70] = "INVERTED_TURN";
+    MusicSymbol[MusicSymbol["LEFTHAND_PIZZICATO"] = 71] = "LEFTHAND_PIZZICATO";
+    MusicSymbol[MusicSymbol["RELEASE_PED"] = 72] = "RELEASE_PED";
+    MusicSymbol[MusicSymbol["ENGAGE_PED"] = 73] = "ENGAGE_PED";
+    MusicSymbol[MusicSymbol["VA8"] = 74] = "VA8";
+    MusicSymbol[MusicSymbol["VB8"] = 75] = "VB8";
+    MusicSymbol[MusicSymbol["TRILL"] = 76] = "TRILL";
+    MusicSymbol[MusicSymbol["MA15"] = 77] = "MA15";
+    MusicSymbol[MusicSymbol["MB15"] = 78] = "MB15";
+    MusicSymbol[MusicSymbol["HIGH"] = 79] = "HIGH";
+    MusicSymbol[MusicSymbol["PLAY"] = 80] = "PLAY";
+    MusicSymbol[MusicSymbol["MIC"] = 81] = "MIC";
+    MusicSymbol[MusicSymbol["SNAP_PIZZICATO"] = 82] = "SNAP_PIZZICATO";
+    MusicSymbol[MusicSymbol["NATURAL_HARMONIC"] = 83] = "NATURAL_HARMONIC";
+    MusicSymbol[MusicSymbol["EditPen"] = 84] = "EditPen";
+})(exports.MusicSymbol || (exports.MusicSymbol = {}));
+var MusicSymbol = exports.MusicSymbol;

+ 95 - 0
dist/src/MusicalScore/Graphical/MusicSystem.d.ts

@@ -0,0 +1,95 @@
+import { StaffLine } from "./StaffLine";
+import { Instrument } from "../Instrument";
+import { Fraction } from "../../Common/DataObjects/fraction";
+import { InstrumentalGroup } from "../InstrumentalGroup";
+import { GraphicalMusicPage } from "./GraphicalMusicPage";
+import { GraphicalLabel } from "./GraphicalLabel";
+import { StaffMeasure } from "./StaffMeasure";
+import { GraphicalObject } from "./GraphicalObject";
+import { EngravingRules } from "./EngravingRules";
+import { PointF2D } from "../../Common/DataObjects/PointF2D";
+import { SystemLinesEnum } from "./SystemLinesEnum";
+import Dictionary from "typescript-collections/dist/lib/Dictionary";
+import { GraphicalComment } from "./GraphicalComment";
+import { GraphicalMarkedArea } from "./GraphicalMarkedArea";
+import { SystemLine } from "./SystemLine";
+import { SystemLinePosition } from "./SystemLinePosition";
+export declare abstract class MusicSystem extends GraphicalObject {
+    needsToBeRedrawn: boolean;
+    protected parent: GraphicalMusicPage;
+    protected id: number;
+    protected staffLines: StaffLine[];
+    protected graphicalMeasures: StaffMeasure[][];
+    protected labels: Dictionary<GraphicalLabel, Instrument>;
+    protected measureNumberLabels: GraphicalLabel[];
+    protected maxLabelLength: number;
+    protected objectsToRedraw: [Object[], Object][];
+    protected instrumentBrackets: GraphicalObject[];
+    protected groupBrackets: GraphicalObject[];
+    protected graphicalMarkedAreas: GraphicalMarkedArea[];
+    protected graphicalComments: GraphicalComment[];
+    protected systemLines: SystemLine[];
+    protected rules: EngravingRules;
+    constructor(parent: GraphicalMusicPage, id: number);
+    Parent: GraphicalMusicPage;
+    StaffLines: StaffLine[];
+    GraphicalMeasures: StaffMeasure[][];
+    MeasureNumberLabels: GraphicalLabel[];
+    Labels: GraphicalLabel[];
+    ObjectsToRedraw: [Object[], Object][];
+    InstrumentBrackets: GraphicalObject[];
+    GroupBrackets: GraphicalObject[];
+    GraphicalMarkedAreas: GraphicalMarkedArea[];
+    GraphicalComments: GraphicalComment[];
+    SystemLines: SystemLine[];
+    Id: number;
+    /**
+     * This method creates the left vertical Line connecting all staves of the MusicSystem.
+     * @param lineWidth
+     * @param systemLabelsRightMargin
+     */
+    createSystemLeftLine(lineWidth: number, systemLabelsRightMargin: number): void;
+    /**
+     * This method creates the vertical Lines after the End of all StaffLine's Measures
+     * @param xPosition
+     * @param lineWidth
+     * @param lineType
+     * @param linePosition indicates if the line belongs to start or end of measure
+     * @param measureIndex the measure index within the staffline
+     * @param measure
+     */
+    createVerticalLineForMeasure(xPosition: number, lineWidth: number, lineType: SystemLinesEnum, linePosition: SystemLinePosition, measureIndex: number, measure: StaffMeasure): void;
+    setYPositionsToVerticalLineObjectsAndCreateLines(rules: EngravingRules): void;
+    calculateBorders(rules: EngravingRules): void;
+    alignBeginInstructions(): void;
+    GetLeftBorderAbsoluteXPosition(): number;
+    GetRightBorderAbsoluteXPosition(): number;
+    AddStaffMeasures(graphicalMeasures: StaffMeasure[]): void;
+    GetSystemsFirstTimeStamp(): Fraction;
+    GetSystemsLastTimeStamp(): Fraction;
+    createInstrumentBrackets(instruments: Instrument[], staffHeight: number): void;
+    createGroupBrackets(instrumentGroups: InstrumentalGroup[], staffHeight: number, recursionDepth: number): void;
+    createMusicSystemLabel(instrumentLabelTextHeight: number, systemLabelsRightMargin: number, labelMarginBorderFactor: number): void;
+    setMusicSystemLabelsYPosition(): void;
+    checkStaffEntriesForStaffEntryLink(): boolean;
+    getBottomStaffLine(topStaffLine: StaffLine): StaffLine;
+    /**
+     * Here the system line is generated, which acts as the container of graphical lines and dots that will be finally rendered.
+     * It holds al the logical parameters of the system line.
+     * @param xPosition The x position within the system
+     * @param lineWidth The total x width
+     * @param lineType The line type enum
+     * @param linePosition indicates if the line belongs to start or end of measure
+     * @param musicSystem
+     * @param topMeasure
+     * @param bottomMeasure
+     */
+    protected createSystemLine(xPosition: number, lineWidth: number, lineType: SystemLinesEnum, linePosition: SystemLinePosition, musicSystem: MusicSystem, topMeasure: StaffMeasure, bottomMeasure?: StaffMeasure): SystemLine;
+    protected createLinesForSystemLine(systemLine: SystemLine): void;
+    protected calcInstrumentsBracketsWidth(): number;
+    protected createInstrumentBracket(rightUpper: PointF2D, rightLower: PointF2D): void;
+    protected createGroupBracket(rightUpper: PointF2D, rightLower: PointF2D, staffHeight: number, recursionDepth: number): void;
+    private findFirstVisibleInstrumentInInstrumentalGroup(instrumentalGroup);
+    private findLastVisibleInstrumentInInstrumentalGroup(instrumentalGroup);
+    private updateMusicSystemStaffLineXPosition(systemLabelsRightMargin);
+}

+ 420 - 0
dist/src/MusicalScore/Graphical/MusicSystem.js

@@ -0,0 +1,420 @@
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var Instrument_1 = require("../Instrument");
+var BoundingBox_1 = require("./BoundingBox");
+var fraction_1 = require("../../Common/DataObjects/fraction");
+var TextAlignment_1 = require("../../Common/Enums/TextAlignment");
+var GraphicalLabel_1 = require("./GraphicalLabel");
+var GraphicalObject_1 = require("./GraphicalObject");
+var PointF2D_1 = require("../../Common/DataObjects/PointF2D");
+var SystemLinesEnum_1 = require("./SystemLinesEnum");
+var Dictionary_1 = require("typescript-collections/dist/lib/Dictionary");
+var collectionUtil_1 = require("../../Util/collectionUtil");
+var SystemLinePosition_1 = require("./SystemLinePosition");
+var MusicSystem = (function (_super) {
+    __extends(MusicSystem, _super);
+    function MusicSystem(parent, id) {
+        _super.call(this);
+        this.needsToBeRedrawn = true;
+        this.staffLines = [];
+        this.graphicalMeasures = [];
+        this.labels = new Dictionary_1.default();
+        this.measureNumberLabels = [];
+        this.objectsToRedraw = [];
+        this.instrumentBrackets = [];
+        this.groupBrackets = [];
+        this.graphicalMarkedAreas = [];
+        this.graphicalComments = [];
+        this.systemLines = [];
+        this.parent = parent;
+        this.id = id;
+        this.boundingBox = new BoundingBox_1.BoundingBox(this, parent.PositionAndShape);
+        this.maxLabelLength = 0.0;
+        this.rules = this.parent.Parent.ParentMusicSheet.Rules;
+    }
+    Object.defineProperty(MusicSystem.prototype, "Parent", {
+        get: function () {
+            return this.parent;
+        },
+        set: function (value) {
+            this.parent = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(MusicSystem.prototype, "StaffLines", {
+        get: function () {
+            return this.staffLines;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(MusicSystem.prototype, "GraphicalMeasures", {
+        get: function () {
+            return this.graphicalMeasures;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(MusicSystem.prototype, "MeasureNumberLabels", {
+        get: function () {
+            return this.measureNumberLabels;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(MusicSystem.prototype, "Labels", {
+        get: function () {
+            return this.labels.keys();
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(MusicSystem.prototype, "ObjectsToRedraw", {
+        get: function () {
+            return this.objectsToRedraw;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(MusicSystem.prototype, "InstrumentBrackets", {
+        get: function () {
+            return this.instrumentBrackets;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(MusicSystem.prototype, "GroupBrackets", {
+        get: function () {
+            return this.groupBrackets;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(MusicSystem.prototype, "GraphicalMarkedAreas", {
+        get: function () {
+            return this.graphicalMarkedAreas;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(MusicSystem.prototype, "GraphicalComments", {
+        get: function () {
+            return this.graphicalComments;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(MusicSystem.prototype, "SystemLines", {
+        get: function () {
+            return this.systemLines;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(MusicSystem.prototype, "Id", {
+        get: function () {
+            return this.id;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    /**
+     * This method creates the left vertical Line connecting all staves of the MusicSystem.
+     * @param lineWidth
+     * @param systemLabelsRightMargin
+     */
+    MusicSystem.prototype.createSystemLeftLine = function (lineWidth, systemLabelsRightMargin) {
+        var xPosition = -lineWidth / 2;
+        if (this === this.parent.MusicSystems[0] && this.parent === this.parent.Parent.MusicPages[0]) {
+            xPosition = this.maxLabelLength + systemLabelsRightMargin - lineWidth / 2;
+        }
+        var top = this.staffLines[0].Measures[0];
+        var bottom = undefined;
+        if (this.staffLines.length > 1) {
+            bottom = this.staffLines[this.staffLines.length - 1].Measures[0];
+        }
+        var leftSystemLine = this.createSystemLine(xPosition, lineWidth, SystemLinesEnum_1.SystemLinesEnum.SingleThin, SystemLinePosition_1.SystemLinePosition.MeasureBegin, this, top, bottom);
+        this.SystemLines.push(leftSystemLine);
+        this.boundingBox.ChildElements.push(leftSystemLine.PositionAndShape);
+        leftSystemLine.PositionAndShape.RelativePosition = new PointF2D_1.PointF2D(xPosition, 0);
+        leftSystemLine.PositionAndShape.BorderLeft = 0;
+        leftSystemLine.PositionAndShape.BorderRight = lineWidth;
+        leftSystemLine.PositionAndShape.BorderTop = 0;
+        leftSystemLine.PositionAndShape.BorderBottom = this.boundingBox.Size.height;
+        this.createLinesForSystemLine(leftSystemLine);
+    };
+    /**
+     * This method creates the vertical Lines after the End of all StaffLine's Measures
+     * @param xPosition
+     * @param lineWidth
+     * @param lineType
+     * @param linePosition indicates if the line belongs to start or end of measure
+     * @param measureIndex the measure index within the staffline
+     * @param measure
+     */
+    MusicSystem.prototype.createVerticalLineForMeasure = function (xPosition, lineWidth, lineType, linePosition, measureIndex, measure) {
+        var staffLine = measure.ParentStaffLine;
+        var staffLineRelative = new PointF2D_1.PointF2D(staffLine.PositionAndShape.RelativePosition.x, staffLine.PositionAndShape.RelativePosition.y);
+        var staves = staffLine.ParentStaff.ParentInstrument.Staves;
+        if (staffLine.ParentStaff === staves[0]) {
+            var bottomMeasure = undefined;
+            if (staves.length > 1) {
+                bottomMeasure = this.getBottomStaffLine(staffLine).Measures[measureIndex];
+            }
+            var singleVerticalLineAfterMeasure = this.createSystemLine(xPosition, lineWidth, lineType, linePosition, this, measure, bottomMeasure);
+            var systemXPosition = staffLineRelative.x + xPosition;
+            singleVerticalLineAfterMeasure.PositionAndShape.RelativePosition = new PointF2D_1.PointF2D(systemXPosition, 0);
+            singleVerticalLineAfterMeasure.PositionAndShape.BorderLeft = 0;
+            singleVerticalLineAfterMeasure.PositionAndShape.BorderRight = lineWidth;
+            this.SystemLines.push(singleVerticalLineAfterMeasure);
+            this.boundingBox.ChildElements.push(singleVerticalLineAfterMeasure.PositionAndShape);
+        }
+    };
+    MusicSystem.prototype.setYPositionsToVerticalLineObjectsAndCreateLines = function (rules) {
+        // empty
+    };
+    MusicSystem.prototype.calculateBorders = function (rules) {
+        // empty
+    };
+    MusicSystem.prototype.alignBeginInstructions = function () {
+        // empty
+    };
+    MusicSystem.prototype.GetLeftBorderAbsoluteXPosition = function () {
+        return this.StaffLines[0].PositionAndShape.AbsolutePosition.x + this.StaffLines[0].Measures[0].beginInstructionsWidth;
+    };
+    MusicSystem.prototype.GetRightBorderAbsoluteXPosition = function () {
+        return this.StaffLines[0].PositionAndShape.AbsolutePosition.x + this.StaffLines[0].StaffLines[0].End.x;
+    };
+    MusicSystem.prototype.AddStaffMeasures = function (graphicalMeasures) {
+        for (var idx = 0, len = graphicalMeasures.length; idx < len; ++idx) {
+            var graphicalMeasure = graphicalMeasures[idx];
+            graphicalMeasure.parentMusicSystem = this;
+        }
+        this.graphicalMeasures.push(graphicalMeasures);
+    };
+    MusicSystem.prototype.GetSystemsFirstTimeStamp = function () {
+        return this.graphicalMeasures[0][0].parentSourceMeasure.AbsoluteTimestamp;
+    };
+    MusicSystem.prototype.GetSystemsLastTimeStamp = function () {
+        var m = this.graphicalMeasures[this.graphicalMeasures.length - 1][0].parentSourceMeasure;
+        return fraction_1.Fraction.plus(m.AbsoluteTimestamp, m.Duration);
+    };
+    MusicSystem.prototype.createInstrumentBrackets = function (instruments, staffHeight) {
+        for (var idx = 0, len = instruments.length; idx < len; ++idx) {
+            var instrument = instruments[idx];
+            if (instrument.Staves.length > 1) {
+                var firstStaffLine = undefined, lastStaffLine = undefined;
+                for (var idx2 = 0, len2 = this.staffLines.length; idx2 < len2; ++idx2) {
+                    var staffLine = this.staffLines[idx2];
+                    if (staffLine.ParentStaff === instrument.Staves[0]) {
+                        firstStaffLine = staffLine;
+                    }
+                    if (staffLine.ParentStaff === instrument.Staves[instrument.Staves.length - 1]) {
+                        lastStaffLine = staffLine;
+                    }
+                }
+                if (firstStaffLine !== undefined && lastStaffLine !== undefined) {
+                    var rightUpper = new PointF2D_1.PointF2D(firstStaffLine.PositionAndShape.RelativePosition.x, firstStaffLine.PositionAndShape.RelativePosition.y);
+                    var rightLower = new PointF2D_1.PointF2D(lastStaffLine.PositionAndShape.RelativePosition.x, lastStaffLine.PositionAndShape.RelativePosition.y + staffHeight);
+                    this.createInstrumentBracket(rightUpper, rightLower);
+                }
+            }
+        }
+    };
+    MusicSystem.prototype.createGroupBrackets = function (instrumentGroups, staffHeight, recursionDepth) {
+        for (var idx = 0, len = instrumentGroups.length; idx < len; ++idx) {
+            var instrumentGroup = instrumentGroups[idx];
+            if (instrumentGroup.InstrumentalGroups.length < 1) {
+                continue;
+            }
+            var instrument1 = this.findFirstVisibleInstrumentInInstrumentalGroup(instrumentGroup);
+            var instrument2 = this.findLastVisibleInstrumentInInstrumentalGroup(instrumentGroup);
+            if (instrument1 === undefined || instrument2 === undefined) {
+                continue;
+            }
+            var firstStaffLine = undefined, lastStaffLine = undefined;
+            for (var idx2 = 0, len2 = this.staffLines.length; idx2 < len2; ++idx2) {
+                var staffLine = this.staffLines[idx2];
+                if (staffLine.ParentStaff === instrument1.Staves[0]) {
+                    firstStaffLine = staffLine;
+                }
+                if (staffLine.ParentStaff === collectionUtil_1.CollectionUtil.last(instrument2.Staves)) {
+                    lastStaffLine = staffLine;
+                }
+            }
+            if (firstStaffLine !== undefined && lastStaffLine !== undefined) {
+                var rightUpper = new PointF2D_1.PointF2D(firstStaffLine.PositionAndShape.RelativePosition.x, firstStaffLine.PositionAndShape.RelativePosition.y);
+                var rightLower = new PointF2D_1.PointF2D(lastStaffLine.PositionAndShape.RelativePosition.x, lastStaffLine.PositionAndShape.RelativePosition.y + staffHeight);
+                this.createGroupBracket(rightUpper, rightLower, staffHeight, recursionDepth);
+            }
+            if (instrumentGroup.InstrumentalGroups.length < 1) {
+                continue;
+            }
+            this.createGroupBrackets(instrumentGroup.InstrumentalGroups, staffHeight, recursionDepth + 1);
+        }
+    };
+    MusicSystem.prototype.createMusicSystemLabel = function (instrumentLabelTextHeight, systemLabelsRightMargin, labelMarginBorderFactor) {
+        if (this.parent === this.parent.Parent.MusicPages[0] && this === this.parent.MusicSystems[0]) {
+            var instruments = this.parent.Parent.ParentMusicSheet.getVisibleInstruments();
+            for (var idx = 0, len = instruments.length; idx < len; ++idx) {
+                var instrument = instruments[idx];
+                var graphicalLabel = new GraphicalLabel_1.GraphicalLabel(instrument.NameLabel, instrumentLabelTextHeight, TextAlignment_1.TextAlignment.LeftCenter, this.boundingBox);
+                graphicalLabel.setLabelPositionAndShapeBorders();
+                this.labels.setValue(graphicalLabel, instrument);
+                this.boundingBox.ChildElements.push(graphicalLabel.PositionAndShape);
+                graphicalLabel.PositionAndShape.RelativePosition = new PointF2D_1.PointF2D(0.0, 0.0);
+            }
+            this.maxLabelLength = 0.0;
+            var labels = this.labels.keys();
+            for (var idx = 0, len = labels.length; idx < len; ++idx) {
+                var label = labels[idx];
+                if (label.PositionAndShape.Size.width > this.maxLabelLength) {
+                    this.maxLabelLength = label.PositionAndShape.Size.width;
+                }
+            }
+            this.updateMusicSystemStaffLineXPosition(systemLabelsRightMargin);
+        }
+    };
+    MusicSystem.prototype.setMusicSystemLabelsYPosition = function () {
+        var _this = this;
+        if (this.parent === this.parent.Parent.MusicPages[0] && this === this.parent.MusicSystems[0]) {
+            this.labels.forEach(function (key, value) {
+                var ypositionSum = 0;
+                var staffCounter = 0;
+                for (var i = 0; i < _this.staffLines.length; i++) {
+                    if (_this.staffLines[i].ParentStaff.ParentInstrument === value) {
+                        for (var j = i; j < _this.staffLines.length; j++) {
+                            var staffLine = _this.staffLines[j];
+                            if (staffLine.ParentStaff.ParentInstrument !== value) {
+                                break;
+                            }
+                            ypositionSum += staffLine.PositionAndShape.RelativePosition.y;
+                            staffCounter++;
+                        }
+                        break;
+                    }
+                }
+                if (staffCounter > 0) {
+                    key.PositionAndShape.RelativePosition = new PointF2D_1.PointF2D(0.0, ypositionSum / staffCounter + 2.0);
+                }
+            });
+        }
+    };
+    MusicSystem.prototype.checkStaffEntriesForStaffEntryLink = function () {
+        var first = false;
+        var second = false;
+        for (var i = 0; i < this.staffLines.length - 1; i++) {
+            for (var idx = 0, len = this.staffLines[i].Measures.length; idx < len; ++idx) {
+                var measure = this.staffLines[i].Measures[idx];
+                for (var idx2 = 0, len2 = measure.staffEntries.length; idx2 < len2; ++idx2) {
+                    var staffEntry = measure.staffEntries[idx2];
+                    if (staffEntry.sourceStaffEntry.Link !== undefined) {
+                        first = true;
+                    }
+                }
+            }
+            for (var idx = 0, len = this.staffLines[i + 1].Measures.length; idx < len; ++idx) {
+                var measure = this.staffLines[i + 1].Measures[idx];
+                for (var idx2 = 0, len2 = measure.staffEntries.length; idx2 < len2; ++idx2) {
+                    var staffEntry = measure.staffEntries[idx2];
+                    if (staffEntry.sourceStaffEntry.Link !== undefined) {
+                        second = true;
+                    }
+                }
+            }
+        }
+        if (first && second) {
+            return true;
+        }
+        return false;
+    };
+    MusicSystem.prototype.getBottomStaffLine = function (topStaffLine) {
+        var staves = topStaffLine.ParentStaff.ParentInstrument.Staves;
+        var last = staves[staves.length - 1];
+        for (var _i = 0, _a = topStaffLine.ParentMusicSystem.staffLines; _i < _a.length; _i++) {
+            var line = _a[_i];
+            if (line.ParentStaff === last) {
+                return line;
+            }
+        }
+        return undefined;
+    };
+    /**
+     * Here the system line is generated, which acts as the container of graphical lines and dots that will be finally rendered.
+     * It holds al the logical parameters of the system line.
+     * @param xPosition The x position within the system
+     * @param lineWidth The total x width
+     * @param lineType The line type enum
+     * @param linePosition indicates if the line belongs to start or end of measure
+     * @param musicSystem
+     * @param topMeasure
+     * @param bottomMeasure
+     */
+    MusicSystem.prototype.createSystemLine = function (xPosition, lineWidth, lineType, linePosition, musicSystem, topMeasure, bottomMeasure) {
+        if (bottomMeasure === void 0) { bottomMeasure = undefined; }
+        throw new Error("not implemented");
+    };
+    /// <summary>
+    /// This method creates all the graphical lines and dots needed to render a system line (e.g. bold-thin-dots..).
+    /// </summary>
+    /// <param name="psSystemLine"></param>
+    MusicSystem.prototype.createLinesForSystemLine = function (systemLine) {
+        //Empty
+    };
+    MusicSystem.prototype.calcInstrumentsBracketsWidth = function () {
+        throw new Error("not implemented");
+    };
+    MusicSystem.prototype.createInstrumentBracket = function (rightUpper, rightLower) {
+        throw new Error("not implemented");
+    };
+    MusicSystem.prototype.createGroupBracket = function (rightUpper, rightLower, staffHeight, recursionDepth) {
+        throw new Error("not implemented");
+    };
+    MusicSystem.prototype.findFirstVisibleInstrumentInInstrumentalGroup = function (instrumentalGroup) {
+        for (var idx = 0, len = instrumentalGroup.InstrumentalGroups.length; idx < len; ++idx) {
+            var groupOrInstrument = instrumentalGroup.InstrumentalGroups[idx];
+            if (groupOrInstrument instanceof Instrument_1.Instrument) {
+                if (groupOrInstrument.Visible === true) {
+                    return groupOrInstrument;
+                }
+                continue;
+            }
+            return this.findFirstVisibleInstrumentInInstrumentalGroup(groupOrInstrument);
+        }
+        return undefined;
+    };
+    MusicSystem.prototype.findLastVisibleInstrumentInInstrumentalGroup = function (instrumentalGroup) {
+        var groupOrInstrument;
+        for (var i = instrumentalGroup.InstrumentalGroups.length - 1; i >= 0; i--) {
+            groupOrInstrument = instrumentalGroup.InstrumentalGroups[i];
+            if (groupOrInstrument instanceof Instrument_1.Instrument) {
+                if (groupOrInstrument.Visible === true) {
+                    return groupOrInstrument;
+                }
+                continue;
+            }
+            return this.findLastVisibleInstrumentInInstrumentalGroup(groupOrInstrument);
+        }
+        return undefined;
+    };
+    MusicSystem.prototype.updateMusicSystemStaffLineXPosition = function (systemLabelsRightMargin) {
+        for (var idx = 0, len = this.StaffLines.length; idx < len; ++idx) {
+            var staffLine = this.StaffLines[idx];
+            var relative = staffLine.PositionAndShape.RelativePosition;
+            relative.x = this.maxLabelLength + systemLabelsRightMargin;
+            staffLine.PositionAndShape.RelativePosition = relative;
+            staffLine.PositionAndShape.BorderRight = this.boundingBox.Size.width - this.maxLabelLength - systemLabelsRightMargin;
+            for (var i = 0; i < staffLine.StaffLines.length; i++) {
+                var lineEnd = new PointF2D_1.PointF2D(staffLine.PositionAndShape.Size.width, staffLine.StaffLines[i].End.y);
+                staffLine.StaffLines[i].End = lineEnd;
+            }
+        }
+    };
+    return MusicSystem;
+}(GraphicalObject_1.GraphicalObject));
+exports.MusicSystem = MusicSystem;

+ 71 - 0
dist/src/MusicalScore/Graphical/MusicSystemBuilder.d.ts

@@ -0,0 +1,71 @@
+import { StaffMeasure } from "./StaffMeasure";
+import { MusicSystem } from "./MusicSystem";
+import { SystemLinesEnum } from "./SystemLinesEnum";
+import { GraphicalMusicSheet } from "./GraphicalMusicSheet";
+import { IGraphicalSymbolFactory } from "../Interfaces/IGraphicalSymbolFactory";
+export declare class MusicSystemBuilder {
+    private measureList;
+    private graphicalMusicSheet;
+    private currentMusicPage;
+    private currentPageHeight;
+    private currentSystemParams;
+    private numberOfVisibleStaffLines;
+    private rules;
+    private measureListIndex;
+    private visibleStaffIndices;
+    private activeRhythm;
+    private activeKeys;
+    private activeClefs;
+    private globalSystemIndex;
+    private leadSheet;
+    private symbolFactory;
+    initialize(graphicalMusicSheet: GraphicalMusicSheet, measureList: StaffMeasure[][], numberOfStaffLines: number, symbolFactory: IGraphicalSymbolFactory): void;
+    buildMusicSystems(): void;
+    private setMeasureWidth(staffMeasures, width, beginInstrWidth, endInstrWidth);
+    private finalizeCurrentAndCreateNewSystem(measures, isPartEndingSystem?);
+    private adaptRepetitionLineWithIfNeeded();
+    private addMeasureToSystem(staffMeasures, measureStartLine, measureEndLine, totalMeasureWidth, currentMeasureBeginInstructionsWidth, currentVarWidth, currentMeasureEndInstructionsWidth);
+    private createMusicPage();
+    private initMusicSystem();
+    private getFullPageSystemWidth();
+    private layoutSystemStaves();
+    private addStaffLineToMusicSystem(musicSystem, relativeYPosition, staff);
+    private initializeActiveInstructions(measureList);
+    private transposeKeyInstruction(keyInstruction, graphicalMeasure);
+    private addBeginInstructions(measures, isSystemFirstMeasure, isFirstSourceMeasure);
+    private addEndInstructions(measures);
+    private AddInstructionsAtMeasureBegin(firstEntry, measure, visibleStaffIdx, isFirstSourceMeasure, isSystemStartMeasure);
+    private addInstructionsAtMeasureEnd(lastEntry, measure);
+    private updateActiveClefs(measure, staffMeasures);
+    private checkAndCreateExtraInstructionMeasure(measures);
+    private addExtraInstructionMeasure(visStaffIdx, keyInstruction, rhythmInstruction);
+    private addStaveMeasuresToSystem(staffMeasures);
+    private getMeasureStartLine();
+    private getMeasureEndLine();
+    private getLineWidth(measure, systemLineEnum, isSystemStartMeasure);
+    private previousMeasureEndsLineRepetition();
+    private thisMeasureBeginsLineRepetition();
+    private nextMeasureBeginsLineRepetition();
+    private thisMeasureEndsLineRepetition();
+    private nextMeasureBeginsWordRepetition();
+    private thisMeasureEndsWordRepetition();
+    private nextMeasureHasKeyInstructionChange();
+    private getNextMeasureKeyInstruction();
+    private calculateXScalingFactor(systemFixWidth, systemVarWidth);
+    private stretchMusicSystem(isPartEndingSystem);
+    private decreaseMusicSystemBorders();
+}
+export declare class SystemBuildParameters {
+    currentSystem: MusicSystem;
+    systemMeasures: MeasureBuildParameters[];
+    systemMeasureIndex: number;
+    currentWidth: number;
+    currentSystemFixWidth: number;
+    currentSystemVarWidth: number;
+    maxLabelLength: number;
+    IsSystemStartMeasure(): boolean;
+}
+export declare class MeasureBuildParameters {
+    beginLine: SystemLinesEnum;
+    endLine: SystemLinesEnum;
+}

+ 725 - 0
dist/src/MusicalScore/Graphical/MusicSystemBuilder.js

@@ -0,0 +1,725 @@
+"use strict";
+var GraphicalMusicPage_1 = require("./GraphicalMusicPage");
+var RhythmInstruction_1 = require("../VoiceData/Instructions/RhythmInstruction");
+var KeyInstruction_1 = require("../VoiceData/Instructions/KeyInstruction");
+var ClefInstruction_1 = require("../VoiceData/Instructions/ClefInstruction");
+var PointF2D_1 = require("../../Common/DataObjects/PointF2D");
+var GraphicalLine_1 = require("./GraphicalLine");
+var SystemLinesEnum_1 = require("./SystemLinesEnum");
+var MusicSheetCalculator_1 = require("./MusicSheetCalculator");
+var ClefInstruction_2 = require("../VoiceData/Instructions/ClefInstruction");
+var collectionUtil_1 = require("../../Util/collectionUtil");
+var SystemLinePosition_1 = require("./SystemLinePosition");
+var MusicSystemBuilder = (function () {
+    function MusicSystemBuilder() {
+        this.globalSystemIndex = 0;
+        this.leadSheet = false;
+    }
+    MusicSystemBuilder.prototype.initialize = function (graphicalMusicSheet, measureList, numberOfStaffLines, symbolFactory) {
+        this.leadSheet = graphicalMusicSheet.LeadSheet;
+        this.graphicalMusicSheet = graphicalMusicSheet;
+        this.rules = this.graphicalMusicSheet.ParentMusicSheet.rules;
+        this.measureList = measureList;
+        this.symbolFactory = symbolFactory;
+        this.currentMusicPage = this.createMusicPage();
+        this.currentPageHeight = 0.0;
+        this.numberOfVisibleStaffLines = numberOfStaffLines;
+        this.activeRhythm = new Array(this.numberOfVisibleStaffLines);
+        this.activeKeys = new Array(this.numberOfVisibleStaffLines);
+        this.activeClefs = new Array(this.numberOfVisibleStaffLines);
+        this.initializeActiveInstructions(this.measureList[0]);
+    };
+    MusicSystemBuilder.prototype.buildMusicSystems = function () {
+        var previousMeasureEndsSystem = false;
+        var systemMaxWidth = this.getFullPageSystemWidth();
+        this.measureListIndex = 0;
+        this.currentSystemParams = new SystemBuildParameters();
+        this.currentSystemParams.currentSystem = this.initMusicSystem();
+        this.layoutSystemStaves();
+        this.currentSystemParams.currentSystem.createMusicSystemLabel(this.rules.InstrumentLabelTextHeight, this.rules.SystemLabelsRightMargin, this.rules.LabelMarginBorderFactor);
+        this.currentPageHeight += this.currentSystemParams.currentSystem.PositionAndShape.RelativePosition.y;
+        var numberOfMeasures = 0;
+        for (var idx = 0, len = this.measureList.length; idx < len; ++idx) {
+            if (this.measureList[idx].length > 0) {
+                numberOfMeasures++;
+            }
+        }
+        while (this.measureListIndex < numberOfMeasures) {
+            var staffMeasures = this.measureList[this.measureListIndex];
+            for (var idx = 0, len = staffMeasures.length; idx < len; ++idx) {
+                staffMeasures[idx].resetLayout();
+            }
+            var sourceMeasure = staffMeasures[0].parentSourceMeasure;
+            var sourceMeasureEndsSystem = sourceMeasure.BreakSystemAfter;
+            var isSystemStartMeasure = this.currentSystemParams.IsSystemStartMeasure();
+            var isFirstSourceMeasure = sourceMeasure === this.graphicalMusicSheet.ParentMusicSheet.getFirstSourceMeasure();
+            var currentMeasureBeginInstructionsWidth = this.rules.MeasureLeftMargin;
+            var currentMeasureEndInstructionsWidth = 0;
+            var measureStartLine = this.getMeasureStartLine();
+            currentMeasureBeginInstructionsWidth += this.getLineWidth(staffMeasures[0], measureStartLine, isSystemStartMeasure);
+            if (!this.leadSheet) {
+                currentMeasureBeginInstructionsWidth += this.addBeginInstructions(staffMeasures, isSystemStartMeasure, isFirstSourceMeasure);
+                currentMeasureEndInstructionsWidth += this.addEndInstructions(staffMeasures);
+            }
+            var currentMeasureVarWidth = 0;
+            for (var i = 0; i < this.numberOfVisibleStaffLines; i++) {
+                currentMeasureVarWidth = Math.max(currentMeasureVarWidth, staffMeasures[i].minimumStaffEntriesWidth);
+            }
+            var measureEndLine = this.getMeasureEndLine();
+            currentMeasureEndInstructionsWidth += this.getLineWidth(staffMeasures[0], measureEndLine, isSystemStartMeasure);
+            var nextMeasureBeginInstructionWidth = this.rules.MeasureLeftMargin;
+            if (this.measureListIndex + 1 < this.measureList.length) {
+                var nextStaffMeasures = this.measureList[this.measureListIndex + 1];
+                var nextSourceMeasure = nextStaffMeasures[0].parentSourceMeasure;
+                if (nextSourceMeasure.hasBeginInstructions()) {
+                    nextMeasureBeginInstructionWidth += this.addBeginInstructions(nextStaffMeasures, false, false);
+                }
+            }
+            var totalMeasureWidth = currentMeasureBeginInstructionsWidth + currentMeasureEndInstructionsWidth + currentMeasureVarWidth;
+            var measureFitsInSystem = this.currentSystemParams.currentWidth + totalMeasureWidth + nextMeasureBeginInstructionWidth < systemMaxWidth;
+            if (isSystemStartMeasure || measureFitsInSystem) {
+                this.addMeasureToSystem(staffMeasures, measureStartLine, measureEndLine, totalMeasureWidth, currentMeasureBeginInstructionsWidth, currentMeasureVarWidth, currentMeasureEndInstructionsWidth);
+                this.updateActiveClefs(sourceMeasure, staffMeasures);
+                this.measureListIndex++;
+            }
+            else {
+                this.finalizeCurrentAndCreateNewSystem(staffMeasures, previousMeasureEndsSystem);
+            }
+            previousMeasureEndsSystem = sourceMeasureEndsSystem;
+        }
+        this.finalizeCurrentAndCreateNewSystem(this.measureList[this.measureList.length - 1], true);
+    };
+    MusicSystemBuilder.prototype.setMeasureWidth = function (staffMeasures, width, beginInstrWidth, endInstrWidth) {
+        for (var idx = 0, len = staffMeasures.length; idx < len; ++idx) {
+            var measure = staffMeasures[idx];
+            measure.setWidth(width);
+            if (beginInstrWidth > 0) {
+                measure.beginInstructionsWidth = beginInstrWidth;
+            }
+            if (endInstrWidth > 0) {
+                measure.endInstructionsWidth = endInstrWidth;
+            }
+        }
+    };
+    MusicSystemBuilder.prototype.finalizeCurrentAndCreateNewSystem = function (measures, isPartEndingSystem) {
+        if (isPartEndingSystem === void 0) { isPartEndingSystem = false; }
+        this.adaptRepetitionLineWithIfNeeded();
+        if (!isPartEndingSystem) {
+            this.checkAndCreateExtraInstructionMeasure(measures);
+        }
+        this.stretchMusicSystem(isPartEndingSystem);
+        if (this.currentPageHeight + this.currentSystemParams.currentSystem.PositionAndShape.Size.height + this.rules.SystemDistance <= this.rules.PageHeight) {
+            this.currentPageHeight += this.currentSystemParams.currentSystem.PositionAndShape.Size.height + this.rules.SystemDistance;
+            if (this.currentPageHeight + this.currentSystemParams.currentSystem.PositionAndShape.Size.height
+                + this.rules.SystemDistance >= this.rules.PageHeight) {
+                this.currentMusicPage = this.createMusicPage();
+                this.currentPageHeight = this.rules.PageTopMargin + this.rules.TitleTopDistance;
+            }
+        }
+        else {
+            this.currentMusicPage = this.createMusicPage();
+            this.currentPageHeight = this.rules.PageTopMargin + this.rules.TitleTopDistance;
+        }
+        this.currentSystemParams = new SystemBuildParameters();
+        if (this.measureListIndex < this.measureList.length) {
+            this.currentSystemParams.currentSystem = this.initMusicSystem();
+            this.layoutSystemStaves();
+        }
+    };
+    MusicSystemBuilder.prototype.adaptRepetitionLineWithIfNeeded = function () {
+        var systemMeasures = this.currentSystemParams.systemMeasures;
+        if (systemMeasures.length >= 1) {
+            var measures = this.currentSystemParams.currentSystem.GraphicalMeasures[this.currentSystemParams.currentSystem.GraphicalMeasures.length - 1];
+            var measureParams = systemMeasures[systemMeasures.length - 1];
+            var diff = 0.0;
+            if (measureParams.endLine === SystemLinesEnum_1.SystemLinesEnum.DotsBoldBoldDots) {
+                measureParams.endLine = SystemLinesEnum_1.SystemLinesEnum.DotsThinBold;
+                diff = measures[0].getLineWidth(SystemLinesEnum_1.SystemLinesEnum.DotsBoldBoldDots) / 2 - measures[0].getLineWidth(SystemLinesEnum_1.SystemLinesEnum.DotsThinBold);
+            }
+            this.currentSystemParams.currentSystemFixWidth -= diff;
+            for (var idx = 0, len = measures.length; idx < len; ++idx) {
+                var measure = measures[idx];
+                measure.endInstructionsWidth -= diff;
+            }
+        }
+    };
+    MusicSystemBuilder.prototype.addMeasureToSystem = function (staffMeasures, measureStartLine, measureEndLine, totalMeasureWidth, currentMeasureBeginInstructionsWidth, currentVarWidth, currentMeasureEndInstructionsWidth) {
+        this.currentSystemParams.systemMeasures.push({ beginLine: measureStartLine, endLine: measureEndLine });
+        this.setMeasureWidth(staffMeasures, totalMeasureWidth, currentMeasureBeginInstructionsWidth, currentMeasureEndInstructionsWidth);
+        this.addStaveMeasuresToSystem(staffMeasures);
+        this.currentSystemParams.currentWidth += totalMeasureWidth;
+        this.currentSystemParams.currentSystemFixWidth += currentMeasureBeginInstructionsWidth + currentMeasureEndInstructionsWidth;
+        this.currentSystemParams.currentSystemVarWidth += currentVarWidth;
+        this.currentSystemParams.systemMeasureIndex++;
+    };
+    MusicSystemBuilder.prototype.createMusicPage = function () {
+        var page = new GraphicalMusicPage_1.GraphicalMusicPage(this.graphicalMusicSheet);
+        this.graphicalMusicSheet.MusicPages.push(page);
+        page.PositionAndShape.BorderLeft = 0.0;
+        page.PositionAndShape.BorderRight = this.graphicalMusicSheet.ParentMusicSheet.pageWidth;
+        page.PositionAndShape.BorderTop = 0.0;
+        page.PositionAndShape.BorderBottom = this.rules.PageHeight;
+        page.PositionAndShape.RelativePosition = new PointF2D_1.PointF2D(0.0, 0.0);
+        return page;
+    };
+    MusicSystemBuilder.prototype.initMusicSystem = function () {
+        var musicSystem = this.symbolFactory.createMusicSystem(this.currentMusicPage, this.globalSystemIndex++);
+        this.currentMusicPage.MusicSystems.push(musicSystem);
+        var boundingBox = musicSystem.PositionAndShape;
+        this.currentMusicPage.PositionAndShape.ChildElements.push(boundingBox);
+        return musicSystem;
+    };
+    MusicSystemBuilder.prototype.getFullPageSystemWidth = function () {
+        return this.currentMusicPage.PositionAndShape.Size.width - this.rules.PageLeftMargin
+            - this.rules.PageRightMargin - this.rules.SystemLeftMargin - this.rules.SystemRightMargin;
+    };
+    MusicSystemBuilder.prototype.layoutSystemStaves = function () {
+        var systemWidth = this.getFullPageSystemWidth();
+        var musicSystem = this.currentSystemParams.currentSystem;
+        var boundingBox = musicSystem.PositionAndShape;
+        boundingBox.BorderLeft = 0.0;
+        boundingBox.BorderRight = systemWidth;
+        boundingBox.BorderTop = 0.0;
+        var staffList = [];
+        var instruments = this.graphicalMusicSheet.ParentMusicSheet.Instruments;
+        for (var idx = 0, len = instruments.length; idx < len; ++idx) {
+            var instrument = instruments[idx];
+            if (instrument.Voices.length === 0 || !instrument.Visible) {
+                continue;
+            }
+            for (var idx2 = 0, len2 = instrument.Staves.length; idx2 < len2; ++idx2) {
+                var staff = instrument.Staves[idx2];
+                staffList.push(staff);
+            }
+        }
+        var multiLyrics = false;
+        if (this.leadSheet) {
+            for (var idx = 0, len = staffList.length; idx < len; ++idx) {
+                var staff = staffList[idx];
+                if (staff.ParentInstrument.LyricVersesNumbers.length > 1) {
+                    multiLyrics = true;
+                    break;
+                }
+            }
+        }
+        var yOffsetSum = 0;
+        for (var i = 0; i < staffList.length; i++) {
+            this.addStaffLineToMusicSystem(musicSystem, yOffsetSum, staffList[i]);
+            yOffsetSum += this.rules.StaffHeight;
+            if (i + 1 < staffList.length) {
+                var yOffset = 0;
+                if (this.leadSheet && !multiLyrics) {
+                    yOffset = 2.5;
+                }
+                else {
+                    if (staffList[i].ParentInstrument === staffList[i + 1].ParentInstrument) {
+                        yOffset = this.rules.BetweenStaffDistance;
+                    }
+                    else {
+                        yOffset = this.rules.StaffDistance;
+                    }
+                }
+                yOffsetSum += yOffset;
+            }
+        }
+        boundingBox.BorderBottom = yOffsetSum;
+    };
+    MusicSystemBuilder.prototype.addStaffLineToMusicSystem = function (musicSystem, relativeYPosition, staff) {
+        if (musicSystem !== undefined) {
+            var staffLine = this.symbolFactory.createStaffLine(musicSystem, staff);
+            musicSystem.StaffLines.push(staffLine);
+            var boundingBox = staffLine.PositionAndShape;
+            musicSystem.PositionAndShape.ChildElements.push(boundingBox);
+            var relativePosition = new PointF2D_1.PointF2D();
+            if (musicSystem.Parent.MusicSystems[0] === musicSystem && musicSystem.Parent === musicSystem.Parent.Parent.MusicPages[0]) {
+                relativePosition.x = this.rules.FirstSystemMargin;
+            }
+            else {
+                relativePosition.x = 0.0;
+            }
+            relativePosition.y = relativeYPosition;
+            boundingBox.RelativePosition = relativePosition;
+            if (musicSystem.Parent.MusicSystems[0] === musicSystem && musicSystem.Parent === musicSystem.Parent.Parent.MusicPages[0]) {
+                boundingBox.BorderRight = musicSystem.PositionAndShape.Size.width - this.rules.FirstSystemMargin;
+            }
+            else {
+                boundingBox.BorderRight = musicSystem.PositionAndShape.Size.width;
+            }
+            boundingBox.BorderLeft = 0.0;
+            boundingBox.BorderTop = 0.0;
+            boundingBox.BorderBottom = this.rules.StaffHeight;
+            for (var i = 0; i < 5; i++) {
+                var start = new PointF2D_1.PointF2D();
+                start.x = 0.0;
+                start.y = i * this.rules.StaffHeight / 4;
+                var end = new PointF2D_1.PointF2D();
+                end.x = staffLine.PositionAndShape.Size.width;
+                end.y = i * this.rules.StaffHeight / 4;
+                if (this.leadSheet) {
+                    start.y = end.y = 0;
+                }
+                staffLine.StaffLines[i] = new GraphicalLine_1.GraphicalLine(start, end, this.rules.StaffLineWidth);
+            }
+        }
+    };
+    MusicSystemBuilder.prototype.initializeActiveInstructions = function (measureList) {
+        var firstSourceMeasure = this.graphicalMusicSheet.ParentMusicSheet.getFirstSourceMeasure();
+        if (firstSourceMeasure !== undefined) {
+            this.visibleStaffIndices = this.graphicalMusicSheet.getVisibleStavesIndecesFromSourceMeasure(measureList);
+            for (var i = 0, len = this.visibleStaffIndices.length; i < len; i++) {
+                var staffIndex = this.visibleStaffIndices[i];
+                var graphicalMeasure = this.graphicalMusicSheet.getGraphicalMeasureFromSourceMeasureAndIndex(firstSourceMeasure, staffIndex);
+                this.activeClefs[i] = firstSourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions[0];
+                var keyInstruction = KeyInstruction_1.KeyInstruction.copy(firstSourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions[1]);
+                keyInstruction = this.transposeKeyInstruction(keyInstruction, graphicalMeasure);
+                this.activeKeys[i] = keyInstruction;
+                this.activeRhythm[i] = firstSourceMeasure.FirstInstructionsStaffEntries[staffIndex].Instructions[2];
+            }
+        }
+    };
+    MusicSystemBuilder.prototype.transposeKeyInstruction = function (keyInstruction, graphicalMeasure) {
+        if (this.graphicalMusicSheet.ParentMusicSheet.Transpose !== 0
+            && graphicalMeasure.ParentStaff.ParentInstrument.MidiInstrumentId !== ClefInstruction_2.MidiInstrument.Percussion
+            && MusicSheetCalculator_1.MusicSheetCalculator.transposeCalculator !== undefined) {
+            MusicSheetCalculator_1.MusicSheetCalculator.transposeCalculator.transposeKey(keyInstruction, this.graphicalMusicSheet.ParentMusicSheet.Transpose);
+        }
+        return keyInstruction;
+    };
+    MusicSystemBuilder.prototype.addBeginInstructions = function (measures, isSystemFirstMeasure, isFirstSourceMeasure) {
+        var measureCount = measures.length;
+        if (measureCount === 0) {
+            return 0;
+        }
+        var totalBeginInstructionLengthX = 0.0;
+        var sourceMeasure = measures[0].parentSourceMeasure;
+        for (var idx = 0; idx < measureCount; ++idx) {
+            var measure = measures[idx];
+            var staffIndex = this.visibleStaffIndices[idx];
+            var beginInstructionsStaffEntry = sourceMeasure.FirstInstructionsStaffEntries[staffIndex];
+            var beginInstructionLengthX = this.AddInstructionsAtMeasureBegin(beginInstructionsStaffEntry, measure, idx, isFirstSourceMeasure, isSystemFirstMeasure);
+            totalBeginInstructionLengthX = Math.max(totalBeginInstructionLengthX, beginInstructionLengthX);
+        }
+        return totalBeginInstructionLengthX;
+    };
+    MusicSystemBuilder.prototype.addEndInstructions = function (measures) {
+        var measureCount = measures.length;
+        if (measureCount === 0) {
+            return 0;
+        }
+        var totalEndInstructionLengthX = 0.5;
+        var sourceMeasure = measures[0].parentSourceMeasure;
+        for (var idx = 0; idx < measureCount; idx++) {
+            var measure = measures[idx];
+            var staffIndex = this.visibleStaffIndices[idx];
+            var endInstructionsStaffEntry = sourceMeasure.LastInstructionsStaffEntries[staffIndex];
+            var endInstructionLengthX = this.addInstructionsAtMeasureEnd(endInstructionsStaffEntry, measure);
+            totalEndInstructionLengthX = Math.max(totalEndInstructionLengthX, endInstructionLengthX);
+        }
+        return totalEndInstructionLengthX;
+    };
+    MusicSystemBuilder.prototype.AddInstructionsAtMeasureBegin = function (firstEntry, measure, visibleStaffIdx, isFirstSourceMeasure, isSystemStartMeasure) {
+        var instructionsLengthX = 0;
+        var currentClef = undefined;
+        var currentKey = undefined;
+        var currentRhythm = undefined;
+        if (firstEntry !== undefined) {
+            for (var idx = 0, len = firstEntry.Instructions.length; idx < len; ++idx) {
+                var abstractNotationInstruction = firstEntry.Instructions[idx];
+                if (abstractNotationInstruction instanceof ClefInstruction_1.ClefInstruction) {
+                    currentClef = abstractNotationInstruction;
+                }
+                else if (abstractNotationInstruction instanceof KeyInstruction_1.KeyInstruction) {
+                    currentKey = abstractNotationInstruction;
+                }
+                else if (abstractNotationInstruction instanceof RhythmInstruction_1.RhythmInstruction) {
+                    currentRhythm = abstractNotationInstruction;
+                }
+            }
+        }
+        if (isSystemStartMeasure) {
+            if (currentClef === undefined) {
+                currentClef = this.activeClefs[visibleStaffIdx];
+            }
+            if (currentKey === undefined) {
+                currentKey = this.activeKeys[visibleStaffIdx];
+            }
+            if (isFirstSourceMeasure && currentRhythm === undefined) {
+                currentRhythm = this.activeRhythm[visibleStaffIdx];
+            }
+        }
+        var clefAdded = false;
+        var keyAdded = false;
+        var rhythmAdded = false;
+        if (currentClef !== undefined) {
+            measure.addClefAtBegin(currentClef);
+            clefAdded = true;
+        }
+        else {
+            currentClef = this.activeClefs[visibleStaffIdx];
+        }
+        if (currentKey !== undefined) {
+            currentKey = this.transposeKeyInstruction(currentKey, measure);
+            var previousKey = isSystemStartMeasure ? undefined : this.activeKeys[visibleStaffIdx];
+            measure.addKeyAtBegin(currentKey, previousKey, currentClef);
+            keyAdded = true;
+        }
+        if (currentRhythm !== undefined) {
+            measure.addRhythmAtBegin(currentRhythm);
+            rhythmAdded = true;
+        }
+        if (clefAdded || keyAdded || rhythmAdded) {
+            instructionsLengthX += measure.beginInstructionsWidth;
+            if (rhythmAdded) {
+                instructionsLengthX += this.rules.RhythmRightMargin;
+            }
+        }
+        return instructionsLengthX;
+    };
+    MusicSystemBuilder.prototype.addInstructionsAtMeasureEnd = function (lastEntry, measure) {
+        if (lastEntry === undefined || lastEntry.Instructions === undefined || lastEntry.Instructions.length === 0) {
+            return 0;
+        }
+        for (var idx = 0, len = lastEntry.Instructions.length; idx < len; ++idx) {
+            var abstractNotationInstruction = lastEntry.Instructions[idx];
+            if (abstractNotationInstruction instanceof ClefInstruction_1.ClefInstruction) {
+                var activeClef = abstractNotationInstruction;
+                measure.addClefAtEnd(activeClef);
+            }
+        }
+        return this.rules.MeasureRightMargin + measure.endInstructionsWidth;
+    };
+    MusicSystemBuilder.prototype.updateActiveClefs = function (measure, staffMeasures) {
+        for (var visStaffIdx = 0, len = staffMeasures.length; visStaffIdx < len; visStaffIdx++) {
+            var staffIndex = this.visibleStaffIndices[visStaffIdx];
+            var firstEntry = measure.FirstInstructionsStaffEntries[staffIndex];
+            if (firstEntry !== undefined) {
+                for (var idx = 0, len2 = firstEntry.Instructions.length; idx < len2; ++idx) {
+                    var abstractNotationInstruction = firstEntry.Instructions[idx];
+                    if (abstractNotationInstruction instanceof ClefInstruction_1.ClefInstruction) {
+                        this.activeClefs[visStaffIdx] = abstractNotationInstruction;
+                    }
+                    else if (abstractNotationInstruction instanceof KeyInstruction_1.KeyInstruction) {
+                        this.activeKeys[visStaffIdx] = abstractNotationInstruction;
+                    }
+                    else if (abstractNotationInstruction instanceof RhythmInstruction_1.RhythmInstruction) {
+                        this.activeRhythm[visStaffIdx] = abstractNotationInstruction;
+                    }
+                }
+            }
+            var entries = measure.getEntriesPerStaff(staffIndex);
+            for (var idx = 0, len2 = entries.length; idx < len2; ++idx) {
+                var staffEntry = entries[idx];
+                if (staffEntry.Instructions !== undefined) {
+                    for (var idx2 = 0, len3 = staffEntry.Instructions.length; idx2 < len3; ++idx2) {
+                        var abstractNotationInstruction = staffEntry.Instructions[idx2];
+                        if (abstractNotationInstruction instanceof ClefInstruction_1.ClefInstruction) {
+                            this.activeClefs[visStaffIdx] = abstractNotationInstruction;
+                        }
+                    }
+                }
+            }
+            var lastEntry = measure.LastInstructionsStaffEntries[staffIndex];
+            if (lastEntry !== undefined) {
+                var instructions = lastEntry.Instructions;
+                for (var idx = 0, len3 = instructions.length; idx < len3; ++idx) {
+                    var abstractNotationInstruction = instructions[idx];
+                    if (abstractNotationInstruction instanceof ClefInstruction_1.ClefInstruction) {
+                        this.activeClefs[visStaffIdx] = abstractNotationInstruction;
+                    }
+                }
+            }
+        }
+    };
+    MusicSystemBuilder.prototype.checkAndCreateExtraInstructionMeasure = function (measures) {
+        var firstStaffEntries = measures[0].parentSourceMeasure.FirstInstructionsStaffEntries;
+        var visibleInstructionEntries = [];
+        for (var idx = 0, len = measures.length; idx < len; ++idx) {
+            var measure = measures[idx];
+            visibleInstructionEntries.push(firstStaffEntries[measure.ParentStaff.idInMusicSheet]);
+        }
+        var maxMeasureWidth = 0;
+        for (var visStaffIdx = 0, len = visibleInstructionEntries.length; visStaffIdx < len; ++visStaffIdx) {
+            var sse = visibleInstructionEntries[visStaffIdx];
+            if (sse === undefined) {
+                continue;
+            }
+            var instructions = sse.Instructions;
+            var keyInstruction = undefined;
+            var rhythmInstruction = undefined;
+            for (var idx2 = 0, len2 = instructions.length; idx2 < len2; ++idx2) {
+                var instruction = instructions[idx2];
+                if (instruction instanceof KeyInstruction_1.KeyInstruction && instruction.Key !== this.activeKeys[visStaffIdx].Key) {
+                    keyInstruction = instruction;
+                }
+                if (instruction instanceof RhythmInstruction_1.RhythmInstruction && instruction !== this.activeRhythm[visStaffIdx]) {
+                    rhythmInstruction = instruction;
+                }
+            }
+            if (keyInstruction !== undefined || rhythmInstruction !== undefined) {
+                var measureWidth = this.addExtraInstructionMeasure(visStaffIdx, keyInstruction, rhythmInstruction);
+                maxMeasureWidth = Math.max(maxMeasureWidth, measureWidth);
+            }
+        }
+        if (maxMeasureWidth > 0) {
+            this.currentSystemParams.systemMeasures.push({
+                beginLine: SystemLinesEnum_1.SystemLinesEnum.None,
+                endLine: SystemLinesEnum_1.SystemLinesEnum.None,
+            });
+            this.currentSystemParams.currentWidth += maxMeasureWidth;
+            this.currentSystemParams.currentSystemFixWidth += maxMeasureWidth;
+        }
+    };
+    MusicSystemBuilder.prototype.addExtraInstructionMeasure = function (visStaffIdx, keyInstruction, rhythmInstruction) {
+        var currentSystem = this.currentSystemParams.currentSystem;
+        var measures = [];
+        var measure = this.symbolFactory.createExtraStaffMeasure(currentSystem.StaffLines[visStaffIdx]);
+        measures.push(measure);
+        if (keyInstruction !== undefined) {
+            measure.addKeyAtBegin(keyInstruction, this.activeKeys[visStaffIdx], this.activeClefs[visStaffIdx]);
+        }
+        if (rhythmInstruction !== undefined) {
+            measure.addRhythmAtBegin(rhythmInstruction);
+        }
+        measure.PositionAndShape.BorderLeft = 0.0;
+        measure.PositionAndShape.BorderTop = 0.0;
+        measure.PositionAndShape.BorderBottom = this.rules.StaffHeight;
+        var width = this.rules.MeasureLeftMargin + measure.beginInstructionsWidth + this.rules.MeasureRightMargin;
+        measure.PositionAndShape.BorderRight = width;
+        currentSystem.StaffLines[visStaffIdx].Measures.push(measure);
+        measure.ParentStaffLine = currentSystem.StaffLines[visStaffIdx];
+        currentSystem.StaffLines[visStaffIdx].PositionAndShape.ChildElements.push(measure.PositionAndShape);
+        return width;
+    };
+    MusicSystemBuilder.prototype.addStaveMeasuresToSystem = function (staffMeasures) {
+        if (staffMeasures[0] !== undefined) {
+            var gmeasures = [];
+            for (var i = 0; i < staffMeasures.length; i++) {
+                gmeasures.push(staffMeasures[i]);
+            }
+            var currentSystem = this.currentSystemParams.currentSystem;
+            for (var visStaffIdx = 0; visStaffIdx < this.numberOfVisibleStaffLines; visStaffIdx++) {
+                var measure = gmeasures[visStaffIdx];
+                currentSystem.StaffLines[visStaffIdx].Measures.push(measure);
+                measure.ParentStaffLine = currentSystem.StaffLines[visStaffIdx];
+                currentSystem.StaffLines[visStaffIdx].PositionAndShape.ChildElements.push(measure.PositionAndShape);
+            }
+            currentSystem.AddStaffMeasures(gmeasures);
+        }
+    };
+    MusicSystemBuilder.prototype.getMeasureStartLine = function () {
+        var thisMeasureBeginsLineRep = this.thisMeasureBeginsLineRepetition();
+        if (thisMeasureBeginsLineRep) {
+            var isSystemStartMeasure = this.currentSystemParams.IsSystemStartMeasure();
+            var isGlobalFirstMeasure = this.measureListIndex === 0;
+            if (this.previousMeasureEndsLineRepetition() && !isSystemStartMeasure) {
+                return SystemLinesEnum_1.SystemLinesEnum.DotsBoldBoldDots;
+            }
+            if (!isGlobalFirstMeasure) {
+                return SystemLinesEnum_1.SystemLinesEnum.BoldThinDots;
+            }
+        }
+        return SystemLinesEnum_1.SystemLinesEnum.None;
+    };
+    MusicSystemBuilder.prototype.getMeasureEndLine = function () {
+        if (this.nextMeasureBeginsLineRepetition() && this.thisMeasureEndsLineRepetition()) {
+            return SystemLinesEnum_1.SystemLinesEnum.DotsBoldBoldDots;
+        }
+        if (this.thisMeasureEndsLineRepetition()) {
+            return SystemLinesEnum_1.SystemLinesEnum.DotsThinBold;
+        }
+        if (this.measureListIndex === this.measureList.length - 1 || this.measureList[this.measureListIndex][0].parentSourceMeasure.endsPiece) {
+            return SystemLinesEnum_1.SystemLinesEnum.ThinBold;
+        }
+        if (this.nextMeasureHasKeyInstructionChange() || this.thisMeasureEndsWordRepetition() || this.nextMeasureBeginsWordRepetition()) {
+            return SystemLinesEnum_1.SystemLinesEnum.DoubleThin;
+        }
+        return SystemLinesEnum_1.SystemLinesEnum.SingleThin;
+    };
+    MusicSystemBuilder.prototype.getLineWidth = function (measure, systemLineEnum, isSystemStartMeasure) {
+        var width = measure.getLineWidth(systemLineEnum);
+        if (systemLineEnum === SystemLinesEnum_1.SystemLinesEnum.DotsBoldBoldDots) {
+            width /= 2;
+        }
+        if (isSystemStartMeasure && systemLineEnum === SystemLinesEnum_1.SystemLinesEnum.BoldThinDots) {
+            width += this.rules.DistanceBetweenLastInstructionAndRepetitionBarline;
+        }
+        return width;
+    };
+    MusicSystemBuilder.prototype.previousMeasureEndsLineRepetition = function () {
+        if (this.measureListIndex === 0) {
+            return false;
+        }
+        for (var idx = 0, len = this.measureList[this.measureListIndex - 1].length; idx < len; ++idx) {
+            var measure = this.measureList[this.measureListIndex - 1][idx];
+            if (measure.endsWithLineRepetition()) {
+                return true;
+            }
+        }
+        return false;
+    };
+    MusicSystemBuilder.prototype.thisMeasureBeginsLineRepetition = function () {
+        for (var idx = 0, len = this.measureList[this.measureListIndex].length; idx < len; ++idx) {
+            var measure = this.measureList[this.measureListIndex][idx];
+            if (measure.beginsWithLineRepetition()) {
+                return true;
+            }
+        }
+        return false;
+    };
+    MusicSystemBuilder.prototype.nextMeasureBeginsLineRepetition = function () {
+        var nextMeasureIndex = this.measureListIndex + 1;
+        if (nextMeasureIndex >= this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length) {
+            return false;
+        }
+        for (var idx = 0, len = this.measureList[nextMeasureIndex].length; idx < len; ++idx) {
+            var measure = this.measureList[nextMeasureIndex][idx];
+            if (measure.beginsWithLineRepetition()) {
+                return true;
+            }
+        }
+        return false;
+    };
+    MusicSystemBuilder.prototype.thisMeasureEndsLineRepetition = function () {
+        for (var idx = 0, len = this.measureList[this.measureListIndex].length; idx < len; ++idx) {
+            var measure = this.measureList[this.measureListIndex][idx];
+            if (measure.endsWithLineRepetition()) {
+                return true;
+            }
+        }
+        return false;
+    };
+    MusicSystemBuilder.prototype.nextMeasureBeginsWordRepetition = function () {
+        var nextMeasureIndex = this.measureListIndex + 1;
+        if (nextMeasureIndex >= this.graphicalMusicSheet.ParentMusicSheet.SourceMeasures.length) {
+            return false;
+        }
+        for (var idx = 0, len = this.measureList[nextMeasureIndex].length; idx < len; ++idx) {
+            var measure = this.measureList[nextMeasureIndex][idx];
+            if (measure.beginsWithWordRepetition()) {
+                return true;
+            }
+        }
+        return false;
+    };
+    MusicSystemBuilder.prototype.thisMeasureEndsWordRepetition = function () {
+        for (var idx = 0, len = this.measureList[this.measureListIndex].length; idx < len; ++idx) {
+            var measure = this.measureList[this.measureListIndex][idx];
+            if (measure.endsWithWordRepetition()) {
+                return true;
+            }
+        }
+        return false;
+    };
+    MusicSystemBuilder.prototype.nextMeasureHasKeyInstructionChange = function () {
+        return this.getNextMeasureKeyInstruction() !== undefined;
+    };
+    MusicSystemBuilder.prototype.getNextMeasureKeyInstruction = function () {
+        if (this.measureListIndex < this.measureList.length - 1) {
+            for (var visIndex = 0; visIndex < this.measureList[this.measureListIndex].length; visIndex++) {
+                var sourceMeasure = this.measureList[this.measureListIndex + 1][visIndex].parentSourceMeasure;
+                if (sourceMeasure === undefined) {
+                    return undefined;
+                }
+                return sourceMeasure.getKeyInstruction(this.visibleStaffIndices[visIndex]);
+            }
+        }
+        return undefined;
+    };
+    MusicSystemBuilder.prototype.calculateXScalingFactor = function (systemFixWidth, systemVarWidth) {
+        if (Math.abs(systemVarWidth - 0) < 0.00001 || Math.abs(systemFixWidth - 0) < 0.00001) {
+            return 1.0;
+        }
+        var systemEndX;
+        var currentSystem = this.currentSystemParams.currentSystem;
+        systemEndX = currentSystem.StaffLines[0].PositionAndShape.Size.width;
+        var scalingFactor = (systemEndX - systemFixWidth) / systemVarWidth;
+        return scalingFactor;
+    };
+    MusicSystemBuilder.prototype.stretchMusicSystem = function (isPartEndingSystem) {
+        var scalingFactor = this.calculateXScalingFactor(this.currentSystemParams.currentSystemFixWidth, this.currentSystemParams.currentSystemVarWidth);
+        if (isPartEndingSystem) {
+            scalingFactor = Math.min(scalingFactor, this.rules.LastSystemMaxScalingFactor);
+        }
+        var currentSystem = this.currentSystemParams.currentSystem;
+        for (var visStaffIdx = 0, len = currentSystem.StaffLines.length; visStaffIdx < len; ++visStaffIdx) {
+            var staffLine = currentSystem.StaffLines[visStaffIdx];
+            var currentXPosition = 0.0;
+            for (var measureIndex = 0; measureIndex < staffLine.Measures.length; measureIndex++) {
+                var measure = staffLine.Measures[measureIndex];
+                measure.setPositionInStaffline(currentXPosition);
+                measure.setWidth(measure.beginInstructionsWidth + measure.minimumStaffEntriesWidth * scalingFactor + measure.endInstructionsWidth);
+                if (measureIndex < this.currentSystemParams.systemMeasures.length) {
+                    var startLine = this.currentSystemParams.systemMeasures[measureIndex].beginLine;
+                    var lineWidth = measure.getLineWidth(SystemLinesEnum_1.SystemLinesEnum.BoldThinDots);
+                    switch (startLine) {
+                        case SystemLinesEnum_1.SystemLinesEnum.BoldThinDots:
+                            var xPosition = currentXPosition;
+                            if (measureIndex === 0) {
+                                xPosition = currentXPosition + measure.beginInstructionsWidth - lineWidth;
+                            }
+                            currentSystem.createVerticalLineForMeasure(xPosition, lineWidth, startLine, SystemLinePosition_1.SystemLinePosition.MeasureBegin, measureIndex, measure);
+                            break;
+                        default:
+                    }
+                }
+                measure.staffEntriesScaleFactor = scalingFactor;
+                measure.layoutSymbols();
+                var nextMeasureHasRepStartLine = measureIndex + 1 < this.currentSystemParams.systemMeasures.length
+                    && this.currentSystemParams.systemMeasures[measureIndex + 1].beginLine === SystemLinesEnum_1.SystemLinesEnum.BoldThinDots;
+                if (!nextMeasureHasRepStartLine) {
+                    var endLine = SystemLinesEnum_1.SystemLinesEnum.SingleThin;
+                    if (measureIndex < this.currentSystemParams.systemMeasures.length) {
+                        endLine = this.currentSystemParams.systemMeasures[measureIndex].endLine;
+                    }
+                    var lineWidth = measure.getLineWidth(endLine);
+                    var xPos = measure.PositionAndShape.RelativePosition.x + measure.PositionAndShape.BorderRight - lineWidth;
+                    if (endLine === SystemLinesEnum_1.SystemLinesEnum.DotsBoldBoldDots) {
+                        xPos -= lineWidth / 2;
+                    }
+                    currentSystem.createVerticalLineForMeasure(xPos, lineWidth, endLine, SystemLinePosition_1.SystemLinePosition.MeasureEnd, measureIndex, measure);
+                }
+                currentXPosition = measure.PositionAndShape.RelativePosition.x + measure.PositionAndShape.BorderRight;
+            }
+        }
+        if (isPartEndingSystem) {
+            this.decreaseMusicSystemBorders();
+        }
+    };
+    MusicSystemBuilder.prototype.decreaseMusicSystemBorders = function () {
+        var currentSystem = this.currentSystemParams.currentSystem;
+        var bb = collectionUtil_1.CollectionUtil.last(currentSystem.StaffLines[0].Measures).PositionAndShape;
+        var width = bb.RelativePosition.x + bb.Size.width;
+        for (var idx = 0, len = currentSystem.StaffLines.length; idx < len; ++idx) {
+            var staffLine = currentSystem.StaffLines[idx];
+            staffLine.PositionAndShape.BorderRight = width;
+            for (var idx2 = 0, len2 = staffLine.StaffLines.length; idx2 < len2; ++idx2) {
+                var graphicalLine = staffLine.StaffLines[idx2];
+                graphicalLine.End = new PointF2D_1.PointF2D(width, graphicalLine.End.y);
+            }
+        }
+        currentSystem.PositionAndShape.BorderRight = width + this.currentSystemParams.maxLabelLength + this.rules.SystemLabelsRightMargin;
+    };
+    return MusicSystemBuilder;
+}());
+exports.MusicSystemBuilder = MusicSystemBuilder;
+var SystemBuildParameters = (function () {
+    function SystemBuildParameters() {
+        this.systemMeasures = [];
+        this.systemMeasureIndex = 0;
+        this.currentWidth = 0;
+        this.currentSystemFixWidth = 0;
+        this.currentSystemVarWidth = 0;
+        this.maxLabelLength = 0;
+    }
+    SystemBuildParameters.prototype.IsSystemStartMeasure = function () {
+        return this.systemMeasureIndex === 0;
+    };
+    return SystemBuildParameters;
+}());
+exports.SystemBuildParameters = SystemBuildParameters;
+var MeasureBuildParameters = (function () {
+    function MeasureBuildParameters() {
+    }
+    return MeasureBuildParameters;
+}());
+exports.MeasureBuildParameters = MeasureBuildParameters;

+ 8 - 0
dist/src/MusicalScore/Graphical/OctaveShiftParams.d.ts

@@ -0,0 +1,8 @@
+import { Fraction } from "../../Common/DataObjects/fraction";
+import { OctaveShift } from "../VoiceData/Expressions/ContinuousExpressions/octaveShift";
+export declare class OctaveShiftParams {
+    constructor(openOctaveShift: OctaveShift, absoluteStartTimestamp: Fraction, absoluteEndTimestamp: Fraction);
+    getOpenOctaveShift: OctaveShift;
+    getAbsoluteStartTimestamp: Fraction;
+    getAbsoluteEndTimestamp: Fraction;
+}

+ 10 - 0
dist/src/MusicalScore/Graphical/OctaveShiftParams.js

@@ -0,0 +1,10 @@
+"use strict";
+var OctaveShiftParams = (function () {
+    function OctaveShiftParams(openOctaveShift, absoluteStartTimestamp, absoluteEndTimestamp) {
+        this.getOpenOctaveShift = openOctaveShift;
+        this.getAbsoluteStartTimestamp = absoluteStartTimestamp;
+        this.getAbsoluteEndTimestamp = absoluteEndTimestamp;
+    }
+    return OctaveShiftParams;
+}());
+exports.OctaveShiftParams = OctaveShiftParams;

+ 10 - 0
dist/src/MusicalScore/Graphical/SelectionEndSymbol.d.ts

@@ -0,0 +1,10 @@
+import { GraphicalObject } from "./GraphicalObject";
+import { MusicSystem } from "./MusicSystem";
+import { PointF2D } from "../../Common/DataObjects/PointF2D";
+import { GraphicalLine } from "./GraphicalLine";
+export declare class SelectionEndSymbol extends GraphicalObject {
+    constructor(system: MusicSystem, xPosition: number);
+    verticalLine: GraphicalLine;
+    arrows: PointF2D[][];
+    arrowlines: PointF2D[][];
+}

+ 65 - 0
dist/src/MusicalScore/Graphical/SelectionEndSymbol.js

@@ -0,0 +1,65 @@
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var GraphicalObject_1 = require("./GraphicalObject");
+var DrawingEnums_1 = require("./DrawingEnums");
+var PointF2D_1 = require("../../Common/DataObjects/PointF2D");
+var BoundingBox_1 = require("./BoundingBox");
+var GraphicalLine_1 = require("./GraphicalLine");
+var collectionUtil_1 = require("../../Util/collectionUtil");
+var SelectionEndSymbol = (function (_super) {
+    __extends(SelectionEndSymbol, _super);
+    function SelectionEndSymbol(system, xPosition) {
+        _super.call(this);
+        var xCoordinate = xPosition;
+        var yCoordinate = system.PositionAndShape.AbsolutePosition.y;
+        var lineThickness = 0.4;
+        var height = collectionUtil_1.CollectionUtil.last(system.StaffLines).PositionAndShape.RelativePosition.y + 4;
+        this.verticalLine = new GraphicalLine_1.GraphicalLine(new PointF2D_1.PointF2D(xCoordinate, yCoordinate), new PointF2D_1.PointF2D(xCoordinate, yCoordinate + height), lineThickness, DrawingEnums_1.OutlineAndFillStyleEnum.SelectionSymbol);
+        for (var idx = 0, len = system.StaffLines.length; idx < len; ++idx) {
+            var staffLine = system.StaffLines[idx];
+            var anchor = new PointF2D_1.PointF2D(xCoordinate, yCoordinate + staffLine.PositionAndShape.RelativePosition.y);
+            var arrowPoints = new Array(3);
+            anchor.y -= .2;
+            arrowPoints[0].x = anchor.x - 3;
+            arrowPoints[0].y = anchor.y + 1.2;
+            arrowPoints[1].x = anchor.x - 2;
+            arrowPoints[1].y = anchor.y + 0.4;
+            arrowPoints[2].x = anchor.x - 2;
+            arrowPoints[2].y = anchor.y + 2;
+            this.arrows.push(arrowPoints);
+            var linePoints = new Array(8);
+            var arrowThickness = .8;
+            anchor.x -= .1;
+            anchor.y += .3;
+            var hilfsVar = .2;
+            linePoints[0].x = anchor.x - 2;
+            linePoints[0].y = anchor.y + 1.5 - hilfsVar;
+            linePoints[1].x = anchor.x - 1;
+            linePoints[1].y = anchor.y + 1.5 - hilfsVar;
+            linePoints[2].x = anchor.x - 1;
+            linePoints[2].y = anchor.y + 2.5;
+            linePoints[3].x = anchor.x - 2;
+            linePoints[3].y = anchor.y + 2.5;
+            linePoints[4].x = linePoints[0].x;
+            linePoints[4].y = linePoints[0].y - arrowThickness;
+            linePoints[5].x = linePoints[4].x + arrowThickness + 1;
+            linePoints[5].y = linePoints[4].y;
+            linePoints[6].x = linePoints[5].x;
+            linePoints[6].y = linePoints[3].y + arrowThickness;
+            linePoints[7].x = linePoints[3].x;
+            linePoints[7].y = linePoints[6].y;
+            this.arrowlines.push(linePoints);
+        }
+        this.boundingBox = new BoundingBox_1.BoundingBox(this);
+        this.boundingBox.AbsolutePosition = new PointF2D_1.PointF2D(xCoordinate, yCoordinate);
+        this.boundingBox.BorderLeft = -lineThickness;
+        this.boundingBox.BorderRight = 4;
+        this.boundingBox.BorderBottom = height;
+    }
+    return SelectionEndSymbol;
+}(GraphicalObject_1.GraphicalObject));
+exports.SelectionEndSymbol = SelectionEndSymbol;

+ 9 - 0
dist/src/MusicalScore/Graphical/SelectionStartSymbol.d.ts

@@ -0,0 +1,9 @@
+import { PointF2D } from "../../Common/DataObjects/PointF2D";
+import { GraphicalLine } from "./GraphicalLine";
+import { MusicSystem } from "./MusicSystem";
+import { GraphicalObject } from "./GraphicalObject";
+export declare class SelectionStartSymbol extends GraphicalObject {
+    constructor(system: MusicSystem, xPosition: number);
+    verticalLine: GraphicalLine;
+    arrows: PointF2D[][];
+}

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor