Ver código fonte

Merge branch 'release/0.0.1-alpha.0'

Sebastian Haas 9 anos atrás
pai
commit
1127e56b27
100 arquivos alterados com 9787 adições e 139 exclusões
  1. 33 0
      .editorconfig
  2. 4 4
      .gitignore
  3. 10 4
      .travis.yml
  4. 4 0
      AUTHORS
  5. 85 76
      Gruntfile.js
  6. 1 1
      LICENSE
  7. 6 34
      README.md
  8. 0 20
      build.js
  9. 10 0
      dist/src/Common/DataObjects/MusicSheetErrors.d.ts
  10. 25 0
      dist/src/Common/DataObjects/MusicSheetErrors.js
  11. 8 0
      dist/src/Common/DataObjects/PointF2D.d.ts
  12. 26 0
      dist/src/Common/DataObjects/PointF2D.js
  13. 12 0
      dist/src/Common/DataObjects/RectangleF2D.d.ts
  14. 34 0
      dist/src/Common/DataObjects/RectangleF2D.js
  15. 5 0
      dist/src/Common/DataObjects/SizeF2D.d.ts
  16. 11 0
      dist/src/Common/DataObjects/SizeF2D.js
  17. 30 0
      dist/src/Common/DataObjects/fraction.d.ts
  18. 191 0
      dist/src/Common/DataObjects/fraction.js
  19. 19 0
      dist/src/Common/DataObjects/osmdColor.d.ts
  20. 100 0
      dist/src/Common/DataObjects/osmdColor.js
  21. 64 0
      dist/src/Common/DataObjects/pitch.d.ts
  22. 267 0
      dist/src/Common/DataObjects/pitch.js
  23. 7 0
      dist/src/Common/Enums/FontStyles.d.ts
  24. 9 0
      dist/src/Common/Enums/FontStyles.js
  25. 4 0
      dist/src/Common/Enums/Fonts.d.ts
  26. 6 0
      dist/src/Common/Enums/Fonts.js
  27. 11 0
      dist/src/Common/Enums/TextAlignment.d.ts
  28. 13 0
      dist/src/Common/Enums/TextAlignment.js
  29. 2 0
      dist/src/Common/FileIO/Mxl.d.ts
  30. 44 0
      dist/src/Common/FileIO/Mxl.js
  31. 15 0
      dist/src/Common/FileIO/Xml.d.ts
  32. 60 0
      dist/src/Common/FileIO/Xml.js
  33. 7 0
      dist/src/Common/logging.d.ts
  34. 24 0
      dist/src/Common/logging.js
  35. 16 0
      dist/src/MusicSheetAPI.d.ts
  36. 67 0
      dist/src/MusicSheetAPI.js
  37. 22 0
      dist/src/MusicalScore/Calculation/MeasureSizeCalculator.d.ts
  38. 176 0
      dist/src/MusicalScore/Calculation/MeasureSizeCalculator.js
  39. 15 0
      dist/src/MusicalScore/Exceptions.d.ts
  40. 27 0
      dist/src/MusicalScore/Exceptions.js
  41. 7 0
      dist/src/MusicalScore/Graphical/AbstractGraphicalInstruction.d.ts
  42. 26 0
      dist/src/MusicalScore/Graphical/AbstractGraphicalInstruction.js
  43. 16 0
      dist/src/MusicalScore/Graphical/AccidentalCalculator.d.ts
  44. 72 0
      dist/src/MusicalScore/Graphical/AccidentalCalculator.js
  45. 76 0
      dist/src/MusicalScore/Graphical/BoundingBox.d.ts
  46. 595 0
      dist/src/MusicalScore/Graphical/BoundingBox.js
  47. 4 0
      dist/src/MusicalScore/Graphical/Clickable.d.ts
  48. 15 0
      dist/src/MusicalScore/Graphical/Clickable.js
  49. 61 0
      dist/src/MusicalScore/Graphical/DrawingEnums.d.ts
  50. 66 0
      dist/src/MusicalScore/Graphical/DrawingEnums.js
  51. 24 0
      dist/src/MusicalScore/Graphical/DrawingMode.d.ts
  52. 28 0
      dist/src/MusicalScore/Graphical/DrawingMode.js
  53. 14 0
      dist/src/MusicalScore/Graphical/DrawingParameters.d.ts
  54. 40 0
      dist/src/MusicalScore/Graphical/DrawingParameters.js
  55. 279 0
      dist/src/MusicalScore/Graphical/EngravingRules.d.ts
  56. 1524 0
      dist/src/MusicalScore/Graphical/EngravingRules.js
  57. 12 0
      dist/src/MusicalScore/Graphical/GraphicalChordSymbolContainer.d.ts
  58. 44 0
      dist/src/MusicalScore/Graphical/GraphicalChordSymbolContainer.js
  59. 6 0
      dist/src/MusicalScore/Graphical/GraphicalComment.d.ts
  60. 9 0
      dist/src/MusicalScore/Graphical/GraphicalComment.js
  61. 10 0
      dist/src/MusicalScore/Graphical/GraphicalLabel.d.ts
  62. 102 0
      dist/src/MusicalScore/Graphical/GraphicalLabel.js
  63. 12 0
      dist/src/MusicalScore/Graphical/GraphicalLine.d.ts
  64. 44 0
      dist/src/MusicalScore/Graphical/GraphicalLine.js
  65. 15 0
      dist/src/MusicalScore/Graphical/GraphicalLyricEntry.d.ts
  66. 52 0
      dist/src/MusicalScore/Graphical/GraphicalLyricEntry.js
  67. 11 0
      dist/src/MusicalScore/Graphical/GraphicalLyricWord.d.ts
  68. 40 0
      dist/src/MusicalScore/Graphical/GraphicalLyricWord.js
  69. 9 0
      dist/src/MusicalScore/Graphical/GraphicalMarkedArea.d.ts
  70. 14 0
      dist/src/MusicalScore/Graphical/GraphicalMarkedArea.js
  71. 21 0
      dist/src/MusicalScore/Graphical/GraphicalMusicPage.d.ts
  72. 83 0
      dist/src/MusicalScore/Graphical/GraphicalMusicPage.js
  73. 100 0
      dist/src/MusicalScore/Graphical/GraphicalMusicSheet.d.ts
  74. 812 0
      dist/src/MusicalScore/Graphical/GraphicalMusicSheet.js
  75. 16 0
      dist/src/MusicalScore/Graphical/GraphicalNote.d.ts
  76. 40 0
      dist/src/MusicalScore/Graphical/GraphicalNote.js
  77. 5 0
      dist/src/MusicalScore/Graphical/GraphicalObject.d.ts
  78. 17 0
      dist/src/MusicalScore/Graphical/GraphicalObject.js
  79. 16 0
      dist/src/MusicalScore/Graphical/GraphicalOctaveShift.d.ts
  80. 42 0
      dist/src/MusicalScore/Graphical/GraphicalOctaveShift.js
  81. 8 0
      dist/src/MusicalScore/Graphical/GraphicalRectangle.d.ts
  82. 21 0
      dist/src/MusicalScore/Graphical/GraphicalRectangle.js
  83. 50 0
      dist/src/MusicalScore/Graphical/GraphicalStaffEntry.d.ts
  84. 273 0
      dist/src/MusicalScore/Graphical/GraphicalStaffEntry.js
  85. 13 0
      dist/src/MusicalScore/Graphical/GraphicalStaffEntryLink.d.ts
  86. 60 0
      dist/src/MusicalScore/Graphical/GraphicalStaffEntryLink.js
  87. 11 0
      dist/src/MusicalScore/Graphical/GraphicalTie.d.ts
  88. 39 0
      dist/src/MusicalScore/Graphical/GraphicalTie.js
  89. 137 0
      dist/src/MusicalScore/Graphical/MusicSheetCalculator.d.ts
  90. 1313 0
      dist/src/MusicalScore/Graphical/MusicSheetCalculator.js
  91. 70 0
      dist/src/MusicalScore/Graphical/MusicSheetDrawer.d.ts
  92. 438 0
      dist/src/MusicalScore/Graphical/MusicSheetDrawer.js
  93. 87 0
      dist/src/MusicalScore/Graphical/MusicSymbol.d.ts
  94. 89 0
      dist/src/MusicalScore/Graphical/MusicSymbol.js
  95. 95 0
      dist/src/MusicalScore/Graphical/MusicSystem.d.ts
  96. 420 0
      dist/src/MusicalScore/Graphical/MusicSystem.js
  97. 71 0
      dist/src/MusicalScore/Graphical/MusicSystemBuilder.d.ts
  98. 725 0
      dist/src/MusicalScore/Graphical/MusicSystemBuilder.js
  99. 8 0
      dist/src/MusicalScore/Graphical/OctaveShiftParams.d.ts
  100. 10 0
      dist/src/MusicalScore/Graphical/OctaveShiftParams.js

+ 33 - 0
.editorconfig

@@ -0,0 +1,33 @@
+# EditorConfig is awesome: http://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+end_of_line = lf
+insert_final_newline = true
+
+# Matches multiple files with brace expansion notation
+# Set default charset
+[*.{js,py,ts}]
+charset = utf-8
+
+# 4 space indentation
+[*.py,ts]
+indent_style = space
+indent_size = 4
+
+# Tab indentation (no size specified)
+[Makefile]
+indent_style = tab
+
+# Indentation override for all JS under lib directory
+[lib/**.js]
+indent_style = space
+indent_size = 2
+
+# Matches the exact files either package.json or .travis.yml
+[{package.json,.travis.yml}]
+indent_style = space
+indent_size = 2

+ 4 - 4
.gitignore

@@ -1,6 +1,3 @@
-# Distribution
-dist
-
 # Build
 # Build
 build
 build
 
 
@@ -31,7 +28,9 @@ build/Release
 
 
 # Dependency directory
 # Dependency directory
 # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
 # https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
-node_modules
+node_modules/*
+!node_modules/karma-musicxml2js-preprocessor/
+
 
 
 # Optional npm cache directory
 # Optional npm cache directory
 .npm
 .npm
@@ -50,3 +49,4 @@ typings
 .vscode/
 .vscode/
 .idea/encodings.xml
 .idea/encodings.xml
 *.md
 *.md
+node_modules/

+ 10 - 4
.travis.yml

@@ -1,11 +1,17 @@
 sudo: false
 sudo: false
 language: node_js
 language: node_js
 node_js:
 node_js:
-  - "5"
-before_script:
-  - npm install
-  - npm start
+- '5'
 notifications:
 notifications:
   email: false
   email: false
   slack:
   slack:
     secure: ZLC7oJ5BcdVfLX+R7Bg6NUaFrrOG5heX9t8lpCZAWtHG4Uag/z5hCAtr/pfdaoEZ4AFJ7SS0yubE3EltwoXdx/zeGlF7gV5JxjDtDyNpkqFa38XTSorP/0FYjaahecFnxUYG2oNQWTcnyeE6BMak+RQ4+ciLC1dQrzC84FNE4R28tV5SVwgM+O1JAFg67Z2Xu497tNuLG6aptyRAov6G0mo9e1oLW4apuiV4CnV+p2nMYbLEyHT5TJiQ8/c7ar7jM7Ia8bL6WGHGjOmEmy71DyWWQXBlE+RSS8uBRlF7BvGX7/fleCUa4jE5ieP+IKCENfa+9+SCE6i8YEAc8Wyfqdl/f5A7NqPDNYxWxU1w8iSM4/FJn6hJKJ3vnogAdQUlPtNYssMio2U06bkvtZ+hu961f6qcGaR10fcX8EHi1UwFDHQ+9uha+9U5vF/+EQHXAG5WGSKrpbH3CFypdJ8g3U1eW5qJn76W9Um4COSj26KI+pBTD9gZwaZCmDas0g2bECIClUKK4y1utsYf/KiJcJaIOEE+QvFNyhuXwdAmTFi8OZ784yrbXmpQZqol2ckgfvWNQZnwqY8h3A8RDhXxvbv6UbNOfE8p/BgJCRaSZAkaqU7b9+D0kSaNIWVPbPad3+Plgkg/gvyC07l8GR5+9tMysz669VQXUs2vzIMIzfA=
     secure: ZLC7oJ5BcdVfLX+R7Bg6NUaFrrOG5heX9t8lpCZAWtHG4Uag/z5hCAtr/pfdaoEZ4AFJ7SS0yubE3EltwoXdx/zeGlF7gV5JxjDtDyNpkqFa38XTSorP/0FYjaahecFnxUYG2oNQWTcnyeE6BMak+RQ4+ciLC1dQrzC84FNE4R28tV5SVwgM+O1JAFg67Z2Xu497tNuLG6aptyRAov6G0mo9e1oLW4apuiV4CnV+p2nMYbLEyHT5TJiQ8/c7ar7jM7Ia8bL6WGHGjOmEmy71DyWWQXBlE+RSS8uBRlF7BvGX7/fleCUa4jE5ieP+IKCENfa+9+SCE6i8YEAc8Wyfqdl/f5A7NqPDNYxWxU1w8iSM4/FJn6hJKJ3vnogAdQUlPtNYssMio2U06bkvtZ+hu961f6qcGaR10fcX8EHi1UwFDHQ+9uha+9U5vF/+EQHXAG5WGSKrpbH3CFypdJ8g3U1eW5qJn76W9Um4COSj26KI+pBTD9gZwaZCmDas0g2bECIClUKK4y1utsYf/KiJcJaIOEE+QvFNyhuXwdAmTFi8OZ784yrbXmpQZqol2ckgfvWNQZnwqY8h3A8RDhXxvbv6UbNOfE8p/BgJCRaSZAkaqU7b9+D0kSaNIWVPbPad3+Plgkg/gvyC07l8GR5+9tMysz669VQXUs2vzIMIzfA=
+deploy:
+  provider: npm
+  email: sebastian@haas.tech
+  api_key:
+    secure: eXeFmjyHP0PRxcydQIqORVobbKY5YT4SAjDsfp70fB0SlFt1brEwPW6Im5cjr32Zky7gSvVqs++mxyultyjxTHT7q3KYXbSsY6CHyRcV0FeFFB8tS0m5HX/bbCcz94//vCuKXPSajn/jcxQUUvsykhwe0abJt+5D8Nl2h4LOQW/5/ItOPvOjVKAaud4I1gVyYJPGFpYvuyRBswYt+JBCoMtRF/nr4qF0Q3PWiifiNpovIm80Zx4yNaALWjf7zJf9GmePBebTboPykXMHEw2ROC805Gao4iX+a9psc340z2LWaWz9Qugb0pa3zL7d2TY0WJLlqXpnZHMWXn+rlDazT5ysrp3mCLdEiDFkVTSbRioBx5QCmDPcWQW9NHxP3XheUBf+cv+1LUUMvYp6tEU9yQWrAl6sk0h8uEi0YSNE27nucXAZyDaavzwIlM//r7oQBpaKXE6NQc0pf2Dsv6fSwwZCokW8YuH42gtr6KTj5hoisaVo/nYRCzdL3iL69sPY6Kgjq47kknobEEgq9jitAEYsedaSADc/s8hzd4gidtfAMj8aTP1ZjDhDMMquUTx+Ksht4dStOZ72ULOIUew8r/j51QPvXVdwJS8bPjz7BEbUqLZxTLRqAUD0HzM7vaM+ynd83mrVruWurm624H2uZm57/yJvpaVnjKEbnLiBG8E=
+  on:
+    tags: true
+    branch: master
+    repo: opensheetmusicdisplay/opensheetmusicdisplay

+ 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)

+ 85 - 76
Gruntfile.js

@@ -1,14 +1,27 @@
+/*global module*/
 module.exports = function (grunt) {
 module.exports = function (grunt) {
     'use strict';
     'use strict';
-    /*var BANNER = '**\n' +
-        ' * Open Sheet Music Display library <%= pkg.version %> built on <%= grunt.template.today("yyyy-mm-dd") %>.\n' +
+    // The banner on top of the build
+    var banner = '/**\n' +
+        ' * Open Sheet Music Display <%= pkg.version %> built on <%= grunt.template.today("yyyy-mm-dd") %>.\n' +
         ' * Copyright (c) 2016 PhonicScore\n' +
         ' * Copyright (c) 2016 PhonicScore\n' +
         ' *\n' +
         ' *\n' +
         ' * https://github.com/opensheetmusicdisplay/opensheetmusicdisplay\n' +
         ' * https://github.com/opensheetmusicdisplay/opensheetmusicdisplay\n' +
-        ' *\n';
-    */
+        ' */\n',
+        typings = [
+            'typings/index.d.ts',
+            // Additional manual typings:
+            'external/vexflow/vexflow.d.ts'
+            // 'typings/fft.d.ts'
+        ],
+    // Paths
+        src = ['src/**/*.ts'],
+        test = ['test/**/*.ts'];
+
+    // Grunt configuration following:
     grunt.initConfig({
     grunt.initConfig({
         pkg: grunt.file.readJSON('package.json'),
         pkg: grunt.file.readJSON('package.json'),
+        banner: '',
         // Build output directories
         // Build output directories
         outputDir: {
         outputDir: {
             build: 'build',
             build: 'build',
@@ -17,87 +30,74 @@ module.exports = function (grunt) {
         // Browserify
         // Browserify
         browserify: {
         browserify: {
             dist: {
             dist: {
-                src: [
-                    'typings/browser.d.ts',
-                    'typings/vexflow.d.ts',
-                    'src/**/*.ts'
-                ],
-                dest: '<%= outputDir.build %>/osmd.js'
+                src: [].concat(typings, src),
+                dest: '<%= outputDir.build %>/osmd.js',
+                options: {
+                    banner: "<%= banner %>"
+                }
+            },
+            debugDemo: {
+                src: [].concat(typings, src),
+                dest: '<%= outputDir.build %>/osmd-demo.js',
+                options: {
+                    banner: "<%= banner %>",
+                    browserifyOptions: {
+                        debug: true
+                    }
+                }
             },
             },
             debug: {
             debug: {
-                src: [
-                    'typings/browser.d.ts', 'typings/vexflow.d.ts',
-                    'src/**/*.ts', 'test/**/*.ts'
-                ],
+                src: [].concat(typings, src, test),
                 dest: '<%= outputDir.build %>/osmd-debug.js',
                 dest: '<%= outputDir.build %>/osmd-debug.js',
                 options: {
                 options: {
+                    banner: "<%= banner %>",
                     browserifyOptions: {
                     browserifyOptions: {
                         debug: true
                         debug: true
                     }
                     }
                 }
                 }
             },
             },
             options: {
             options: {
-                plugin: ['tsify'],
-                browserifyOptions: {
-                  standalone: 'MeasureSizeCalculator'
-                }
+                plugin: ['tsify']
             }
             }
         },
         },
         // Uglify
         // Uglify
-        /*uglify: {
-          options: {
-            compress: {
-              drop_console: true
-            }
-          },
-          my_target: {
-            files: {
-              'build/osmd.js': ['src/input.js']
+        uglify: {
+            options: {
+                compress: {
+                    drop_console: true
+                },
+                banner: banner,
+                mangle: true,
+                mangleProperties: true,
+                preserveComments: 'all'
+            },
+            bundle: {
+                files: {
+                    'build/osmd.min.js': ['build/osmd.js']
+                }
             }
             }
-          }
-        },*/
-        // Settings for tests
+        },
+        // Karma setup
         karma: {
         karma: {
             // For continuous integration
             // For continuous integration
             ci: {
             ci: {
                 configFile: 'karma.conf.js',
                 configFile: 'karma.conf.js',
                 options: {
                 options: {
-                    browsers: ['PhantomJS'],
-                    files: [
-                        '<%= browserify.debug.dest %>'
-                    ]
+                    browsers: ['PhantomJS']
                 }
                 }
             },
             },
             debugWithFirefox: {
             debugWithFirefox: {
                 configFile: 'karma.conf.js',
                 configFile: 'karma.conf.js',
                 options: {
                 options: {
                     singleRun: false,
                     singleRun: false,
-                    browsers: ['Firefox'],
-                    files: [
-                        '<%= browserify.debug.dest %>', {
-                            pattern: 'src/**/*.ts',
-                            included: false
-                        }, {
-                            pattern: 'test/**/*.ts',
-                            included: false
-                        }
-                    ]
+                    browsers: ['Firefox']
                 }
                 }
             },
             },
             debugWithChrome: {
             debugWithChrome: {
                 configFile: 'karma.conf.js',
                 configFile: 'karma.conf.js',
                 options: {
                 options: {
                     singleRun: false,
                     singleRun: false,
-                    browsers: ['Chrome'],
-                    files: [
-                        '<%= browserify.debug.dest %>', {
-                            pattern: 'src/**/*.ts',
-                            included: false
-                        }, {
-                            pattern: 'test/**/*.ts',
-                            included: false
-                        }
-                    ]
+                    browsers: ['Chrome']
                 }
                 }
             }
             }
         },
         },
@@ -107,21 +107,21 @@ module.exports = function (grunt) {
                 configuration: 'tslint.json'
                 configuration: 'tslint.json'
             },
             },
             all: {
             all: {
-                src: ['<%= browserify.dist.src %>', '<%= browserify.debug.src %>']
+                src: [].concat(src, test)
             }
             }
         },
         },
-        // TypeScript type definitions
+        // JsHint setup
+        jshint: {
+            all: [
+                'Gruntfile.js', 'karma.conf.js',
+                'submodules/**/*.json', 'submodules/**/*.js'
+            ]
+        },
+        // TypeScript Type Definitions
         typings: {
         typings: {
             install: {}
             install: {}
         },
         },
-        docco: {
-            src: ['src/**/*.ts'],
-            options: {
-                layout: 'linear',
-                output: 'build/docs'
-            }
-        },
-        // Settings for clean task
+        // Cleaning task setup
         clean: {
         clean: {
             options: {
             options: {
                 force: true
                 force: true
@@ -130,28 +130,37 @@ module.exports = function (grunt) {
                 src: [
                 src: [
                     '<%= outputDir.build %>',
                     '<%= outputDir.build %>',
                     '<%= outputDir.dist %>',
                     '<%= outputDir.dist %>',
-                    '.tscache'
+                    'node_modules',
+                    'typings',
+                    '.tscache',
+                    'src/**/*.js', 'test/**/*.js'
                 ]
                 ]
             }
             }
         }
         }
     });
     });
 
 
     // Load Npm tasks
     // Load Npm tasks
-    grunt.loadNpmTasks('grunt-browserify');
-    grunt.loadNpmTasks('grunt-contrib-clean');
-    grunt.loadNpmTasks('grunt-contrib-watch');
-    //grunt.loadNpmTasks('grunt-jscs');
     grunt.loadNpmTasks('grunt-karma');
     grunt.loadNpmTasks('grunt-karma');
     grunt.loadNpmTasks('grunt-tslint');
     grunt.loadNpmTasks('grunt-tslint');
     grunt.loadNpmTasks('grunt-typings');
     grunt.loadNpmTasks('grunt-typings');
+    grunt.loadNpmTasks('grunt-browserify');
+    grunt.loadNpmTasks('grunt-contrib-clean');
+    grunt.loadNpmTasks('grunt-contrib-watch');
+    grunt.loadNpmTasks('grunt-contrib-jshint');
+    grunt.loadNpmTasks('grunt-contrib-uglify');
 
 
     // Register tasks
     // Register tasks
-    grunt.registerTask('default', [ /*'tslint',*/ 'browserify', 'karma:ci']);
-    //grunt.registerTask('lint', ['tslint', 'jscs']);
-    grunt.registerTask('test', ['browserify:debug', 'karma:ci']);
-    //grunt.registerTask('test debug Firefox', ['browserify:debug', 'karma:debugWithFirefox']);
-    //grunt.registerTask('test debug Chrome', ['browserify:debug', 'karma:debugWithChrome']);
+    grunt.registerTask('all',     ['typings', 'default']);
+    grunt.registerTask('start',   ['typings']);
+    grunt.registerTask('default', ['browserify', 'lint', 'karma:ci', 'uglify']);
+    grunt.registerTask('npmtest', ['typings', 'test']);
+    grunt.registerTask('test',    ['browserify:debug', 'lint', 'karma:ci']);
+    grunt.registerTask('fasttest', ['browserify:debug', 'karma:ci']);
     grunt.registerTask('rebuild', ['clean', 'default']);
     grunt.registerTask('rebuild', ['clean', 'default']);
-    grunt.registerTask('publish', ['clean', 'browserify:dist']);
-    grunt.registerTask('all', ['typings', 'default']);
+    grunt.registerTask('publish', ['clean', 'typings', 'browserify:dist', 'uglify:bundle']);
+    grunt.registerTask('lint',    ['jshint', 'tslint']);
+
+    // Fix these in the future:
+    // grunt.registerTask('test debug Firefox', ['browserify:debug', 'karma:debugWithFirefox']);
+    // grunt.registerTask('test debug Chrome', ['browserify:debug', 'karma:debugWithChrome']);
 };
 };

+ 1 - 1
LICENSE

@@ -1,6 +1,6 @@
 The MIT License (MIT)
 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
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 of this software and associated documentation files (the "Software"), to deal

+ 6 - 34
README.md

@@ -1,39 +1,11 @@
-<h1 align="center">
+<p align="center">
   <img alt="OSMD logo" src="http://opensheetmusicdisplay.org/wp-content/uploads/2015/03/OSMD_3_icon.png" width="200"/>
   <img alt="OSMD logo" src="http://opensheetmusicdisplay.org/wp-content/uploads/2015/03/OSMD_3_icon.png" width="200"/>
-</h1>
+</p>
+
+# Open Sheet Music Display
 
 
 [![Build Status](https://travis-ci.org/opensheetmusicdisplay/opensheetmusicdisplay.svg?branch=master)](https://travis-ci.org/opensheetmusicdisplay/opensheetmusicdisplay)
 [![Build Status](https://travis-ci.org/opensheetmusicdisplay/opensheetmusicdisplay.svg?branch=master)](https://travis-ci.org/opensheetmusicdisplay/opensheetmusicdisplay)
-&nbsp;
 [![Dependency Status](https://david-dm.org/opensheetmusicdisplay/opensheetmusicdisplay.png)](https://david-dm.org/opensheetmusicdisplay/opensheetmusicdisplay)
 [![Dependency Status](https://david-dm.org/opensheetmusicdisplay/opensheetmusicdisplay.png)](https://david-dm.org/opensheetmusicdisplay/opensheetmusicdisplay)
 
 
-Display sheet music ([MusicXML](http://www.musicxml.com) files) in the browser.
-
-Using the [VexFlow](https://github.com/0xfe/vexflow) music notation rendering API.
-
-Written in [TypeScript](https://www.typescriptlang.org) and released under [MIT license](#license).
-
-See [opensheetmusicdisplay.org](http://opensheetmusicdisplay.org) for further information.
-
-
-# Build
-```bash
-$ git clone https://github.com/opensheetmusicdisplay/opensheetmusicdisplay.git
-$ npm install
-$ npm install -g grunt-cli
-$ grunt
-```
-
-# Install
-
-# Usage
-
-# <a name="license"></a>License
-The MIT License (MIT)
-
-Copyright &copy; 2016 PhonicScore GmbH
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+* Website: [opensheetmusicdisplay.org](http://opensheetmusicdisplay.org)
+* How to build: [wiki/Build-Instructions](https://github.com/opensheetmusicdisplay/opensheetmusicdisplay/wiki/Build-Instructions)

+ 0 - 20
build.js

@@ -1,20 +0,0 @@
-#!/usr/bin/env node
-
-var fs = require("fs");
-var path = require("path");
-var browserify = require("browserify");
-var args = require('minimist')(process.argv.slice(2));
-
-var b = browserify({ debug: args.debug || false });
-
-var path_to_vexflow = args.path || path.join(__dirname, "node_modules/vexflow/releases/");
-
-console.log("Path to vexflow: " + path_to_vexflow);
-
-if (args["include-vexflow"]) {
-	b.add(path.join(path_to_vexflow, 'vexflow-debug.js'));
-}
-
-b.add('./src/file1.js');
-
-b.bundle().pipe(fs.createWriteStream("osmd.js"));

+ 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;

Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff