vibe-editor 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +51 -0
  3. package/package.json +56 -0
  4. package/src/fonts/bravura/FONTLOG.txt +243 -0
  5. package/src/fonts/bravura/OFL-FAQ.txt +369 -0
  6. package/src/fonts/bravura/OFL.txt +94 -0
  7. package/src/fonts/bravura/bravura-text.md +153 -0
  8. package/src/fonts/bravura/bravura_metadata.json +34718 -0
  9. package/src/fonts/bravura/eot/Bravura.eot +0 -0
  10. package/src/fonts/bravura/eot/BravuraText.eot +0 -0
  11. package/src/fonts/bravura/otf/Bravura.otf +0 -0
  12. package/src/fonts/bravura/otf/BravuraText.otf +0 -0
  13. package/src/fonts/bravura/svg/Bravura.svg +3517 -0
  14. package/src/fonts/bravura/svg/BravuraText.svg +18879 -0
  15. package/src/fonts/bravura/woff/Bravura.woff +0 -0
  16. package/src/fonts/bravura/woff/BravuraText.woff +0 -0
  17. package/src/fonts/colaborate/ColabBol-webfont.eot +0 -0
  18. package/src/fonts/colaborate/ColabBol-webfont.svg +976 -0
  19. package/src/fonts/colaborate/ColabBol-webfont.ttf +0 -0
  20. package/src/fonts/colaborate/ColabBol-webfont.woff +0 -0
  21. package/src/fonts/colaborate/ColabLig-webfont.eot +0 -0
  22. package/src/fonts/colaborate/ColabLig-webfont.svg +976 -0
  23. package/src/fonts/colaborate/ColabLig-webfont.ttf +0 -0
  24. package/src/fonts/colaborate/ColabLig-webfont.woff +0 -0
  25. package/src/fonts/colaborate/ColabMed-webfont.eot +0 -0
  26. package/src/fonts/colaborate/ColabMed-webfont.svg +976 -0
  27. package/src/fonts/colaborate/ColabMed-webfont.ttf +0 -0
  28. package/src/fonts/colaborate/ColabMed-webfont.woff +0 -0
  29. package/src/fonts/colaborate/ColabReg-webfont.eot +0 -0
  30. package/src/fonts/colaborate/ColabReg-webfont.svg +976 -0
  31. package/src/fonts/colaborate/ColabReg-webfont.ttf +0 -0
  32. package/src/fonts/colaborate/ColabReg-webfont.woff +0 -0
  33. package/src/fonts/colaborate/ColabThi-webfont.eot +0 -0
  34. package/src/fonts/colaborate/ColabThi-webfont.svg +970 -0
  35. package/src/fonts/colaborate/ColabThi-webfont.ttf +0 -0
  36. package/src/fonts/colaborate/ColabThi-webfont.woff +0 -0
  37. package/src/images/GUI/.DS_Store +0 -0
  38. package/src/images/GUI/backward-fast-solid.svg +1 -0
  39. package/src/images/GUI/bars-solid.svg +1 -0
  40. package/src/images/GUI/caret-left-solid.svg +1 -0
  41. package/src/images/GUI/caret-right-solid.svg +1 -0
  42. package/src/images/GUI/edit-solid.svg +1 -0
  43. package/src/images/GUI/pause-solid.svg +1 -0
  44. package/src/images/GUI/play-solid.svg +1 -0
  45. package/src/images/GUI/triplet.svg +21 -0
  46. package/src/images/GUI/zoomin.svg +1 -0
  47. package/src/images/GUI/zoomout.svg +1 -0
  48. package/src/images/bravura_notes/.DS_Store +0 -0
  49. package/src/images/bravura_notes/16th.svg +1 -0
  50. package/src/images/bravura_notes/32th.svg +1 -0
  51. package/src/images/bravura_notes/alterDDown.svg +1 -0
  52. package/src/images/bravura_notes/alterDUp.svg +1 -0
  53. package/src/images/bravura_notes/alterDown.svg +1 -0
  54. package/src/images/bravura_notes/alterNeutral.svg +1 -0
  55. package/src/images/bravura_notes/alterUp.svg +1 -0
  56. package/src/images/bravura_notes/beams.svg +1 -0
  57. package/src/images/bravura_notes/eigth.svg +1 -0
  58. package/src/images/bravura_notes/full.svg +1 -0
  59. package/src/images/bravura_notes/half.svg +1 -0
  60. package/src/images/bravura_notes/oneDot.svg +1 -0
  61. package/src/images/bravura_notes/pauseNote.svg +1 -0
  62. package/src/images/bravura_notes/quarter.svg +1 -0
  63. package/src/images/bravura_notes/tie.svg +1 -0
  64. package/src/images/bravura_notes/twoDot.svg +1 -0
  65. package/src/scripts/js/.DS_Store +0 -0
  66. package/src/scripts/js/Core.js +887 -0
  67. package/src/scripts/js/MusicPlayer.js +572 -0
  68. package/src/scripts/js/MusicProcessor.js +652 -0
  69. package/src/scripts/js/VerovioScoreEditor.js +183 -0
  70. package/src/scripts/js/assets/mei_template.js +161 -0
  71. package/src/scripts/js/constants.js +20 -0
  72. package/src/scripts/js/datastructures/MeasureMatrix.js +235 -0
  73. package/src/scripts/js/datastructures/ScoreGraph.js +432 -0
  74. package/src/scripts/js/datastructures/ScoreNode.js +78 -0
  75. package/src/scripts/js/entry.js +4 -0
  76. package/src/scripts/js/gui/Annotations.js +456 -0
  77. package/src/scripts/js/gui/Cursor.js +203 -0
  78. package/src/scripts/js/gui/CustomAnnotationDrawer.js +114 -0
  79. package/src/scripts/js/gui/CustomAnnotationShapeDrawer.js +114 -0
  80. package/src/scripts/js/gui/HarmonyLabel.js +104 -0
  81. package/src/scripts/js/gui/Label.js +2 -0
  82. package/src/scripts/js/gui/PhantomElement.js +132 -0
  83. package/src/scripts/js/gui/ScoreManipulator.js +156 -0
  84. package/src/scripts/js/gui/Tabbar.js +675 -0
  85. package/src/scripts/js/gui/TempoLabel.js +60 -0
  86. package/src/scripts/js/gui/Toolbar copy.js +614 -0
  87. package/src/scripts/js/gui/Toolbar.js +618 -0
  88. package/src/scripts/js/handlers/AnnotationChangeHandler.js +567 -0
  89. package/src/scripts/js/handlers/AnnotationDragHandler.js +113 -0
  90. package/src/scripts/js/handlers/AnnotationLineHandler.js +113 -0
  91. package/src/scripts/js/handlers/ArticulationHandler.js +20 -0
  92. package/src/scripts/js/handlers/ClickModeHandler.js +265 -0
  93. package/src/scripts/js/handlers/CustomAnnotationShapeDrawer.js +131 -0
  94. package/src/scripts/js/handlers/CustomToolbarHandler.js +297 -0
  95. package/src/scripts/js/handlers/DeleteHandler.js +102 -0
  96. package/src/scripts/js/handlers/GlobalKeyboardHandler.js +367 -0
  97. package/src/scripts/js/handlers/Handler.js +2 -0
  98. package/src/scripts/js/handlers/HarmonyHandler.js +282 -0
  99. package/src/scripts/js/handlers/InsertModeHandler copy.js +423 -0
  100. package/src/scripts/js/handlers/InsertModeHandler.js +380 -0
  101. package/src/scripts/js/handlers/InsertModeHandler_deprecated.js +424 -0
  102. package/src/scripts/js/handlers/KeyModeHandler copy.js +407 -0
  103. package/src/scripts/js/handlers/KeyModeHandler.js +456 -0
  104. package/src/scripts/js/handlers/KeyModeHandler_deprecated.js +411 -0
  105. package/src/scripts/js/handlers/LabelHandler.js +461 -0
  106. package/src/scripts/js/handlers/ModHandler.js +311 -0
  107. package/src/scripts/js/handlers/NoteDragHandler copy.js +148 -0
  108. package/src/scripts/js/handlers/NoteDragHandler.js +97 -0
  109. package/src/scripts/js/handlers/NoteDragHandler_deprecated.js +150 -0
  110. package/src/scripts/js/handlers/PhantomElementHandler.js +168 -0
  111. package/src/scripts/js/handlers/ScoreManipulatorHandler.js +135 -0
  112. package/src/scripts/js/handlers/SelectionHandler.js +218 -0
  113. package/src/scripts/js/handlers/SideBarHandler.js +499 -0
  114. package/src/scripts/js/handlers/TooltipHandler.js +132 -0
  115. package/src/scripts/js/handlers/WindowHandler.js +257 -0
  116. package/src/scripts/js/utils/DOMCreator.js +174 -0
  117. package/src/scripts/js/utils/MEIConverter.js +64 -0
  118. package/src/scripts/js/utils/MEIOperations.js +2112 -0
  119. package/src/scripts/js/utils/Mouse2MEI.js +735 -0
  120. package/src/scripts/js/utils/Mouse2SVG.js +737 -0
  121. package/src/scripts/js/utils/SVGEditor.js +352 -0
  122. package/src/scripts/js/utils/SVGFiller.js +245 -0
  123. package/src/scripts/js/utils/Types.js +2 -0
  124. package/src/scripts/js/utils/VerovioWrapper copy.js +156 -0
  125. package/src/scripts/js/utils/VerovioWrapper.js +165 -0
  126. package/src/scripts/js/utils/VerovioWrapperLocal.js +156 -0
  127. package/src/scripts/js/utils/convenienceQueries.js +37 -0
  128. package/src/scripts/js/utils/coordinates.js +54 -0
  129. package/src/scripts/js/utils/firefoxBBoxes.js +143 -0
  130. package/src/scripts/js/utils/mappings.js +332 -0
  131. package/src/scripts/js/utils/random.js +45 -0
  132. package/src/styles/VerovioScoreEditor.css +694 -0
@@ -0,0 +1,735 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Mouse2SVG = void 0;
4
+ const constants_1 = require("../constants");
5
+ const random_1 = require("./random");
6
+ const mappings_1 = require("./mappings");
7
+ const MeasureMatrix_1 = require("../datastructures/MeasureMatrix");
8
+ const meiOperation = require("../utils/MEIOperations");
9
+ const coordinates = require("./coordinates");
10
+ const cq = require("./convenienceQueries");
11
+ class Mouse2SVG {
12
+ constructor() {
13
+ this.lastSystemMouseEnter = null;
14
+ this.lastStaffMouseEnter = null;
15
+ this.lastMeasureMouseEnter = null;
16
+ this.lastLayerMouseEnter = null;
17
+ this.noteNewDur = "4";
18
+ this.noteBBoxes = new Array();
19
+ this.staffLineBBoxes = new Array();
20
+ this.measureMatrix = new MeasureMatrix_1.default();
21
+ //this.setMouseEnterElementListeners();
22
+ //this.findBBoxes();
23
+ }
24
+ /**
25
+ * Set Flags for current focused measure, staff, system and layer when mouse moves.
26
+ * @returns
27
+ */
28
+ setMouseEnterElementListeners() {
29
+ var that = this;
30
+ var mouseEventName = "mouseover";
31
+ var enteredFlag = "lastEntered";
32
+ var activeContainerFlag = "activeContainer";
33
+ this.container.addEventListener("mouseenter", function (e) {
34
+ Array.from(document.getElementsByClassName("vse-container")).forEach(ac => {
35
+ if (ac === that.container) {
36
+ if (!that.container.classList.contains(activeContainerFlag)) {
37
+ that.container.classList.add(activeContainerFlag);
38
+ }
39
+ }
40
+ else {
41
+ ac.classList.remove(activeContainerFlag);
42
+ }
43
+ });
44
+ });
45
+ this.container.addEventListener("mouseleave", function (e) {
46
+ Array.from(document.getElementsByClassName("vse-container")).forEach(ac => {
47
+ if (ac === that.container) {
48
+ ac.classList.remove(activeContainerFlag);
49
+ }
50
+ });
51
+ });
52
+ this.interactionOverlay.querySelectorAll(".system").forEach(sy => {
53
+ sy.addEventListener(mouseEventName, function (e) {
54
+ e.preventDefault();
55
+ var target = e.target;
56
+ that.lastSystemMouseEnter = target.closest(".system");
57
+ if (!that.lastSystemMouseEnter.classList.contains(enteredFlag)) {
58
+ cq.getInteractOverlay(that.containerId).querySelectorAll(".system").forEach(s => {
59
+ s.classList.remove(enteredFlag);
60
+ });
61
+ that.lastSystemMouseEnter.classList.add(enteredFlag);
62
+ }
63
+ });
64
+ });
65
+ this.interactionOverlay.querySelectorAll(".staff").forEach(staff => {
66
+ staff.addEventListener(mouseEventName, function (e) {
67
+ var _a;
68
+ e.preventDefault();
69
+ var target = e.target;
70
+ that.lastStaffMouseEnter = target.closest(".staff");
71
+ (_a = that.lastStaffMouseEnter) === null || _a === void 0 ? void 0 : _a.dispatchEvent(new Event("currStaffChanged"));
72
+ if (!that.lastStaffMouseEnter.classList.contains(enteredFlag)) {
73
+ cq.getInteractOverlay(that.containerId).querySelectorAll(".staff").forEach(s => {
74
+ s.classList.remove(enteredFlag);
75
+ that.getElementinVrvSVG(s.getAttribute("refId")).classList.remove(enteredFlag);
76
+ });
77
+ that.container.querySelectorAll(".onChord").forEach(oc => oc.classList.remove("onChord")); // reset onChord, so that only chords in the same staff are set
78
+ that.lastStaffMouseEnter.classList.add(enteredFlag);
79
+ that.getElementinVrvSVG(that.lastStaffMouseEnter.getAttribute("refId")).classList.add(enteredFlag);
80
+ }
81
+ });
82
+ });
83
+ this.interactionOverlay.querySelectorAll(".measure").forEach(measure => {
84
+ measure.addEventListener(mouseEventName, function (e) {
85
+ e.preventDefault();
86
+ var target = e.target;
87
+ that.lastMeasureMouseEnter = target.closest(".measure");
88
+ if (!that.lastMeasureMouseEnter.classList.contains(enteredFlag)) {
89
+ cq.getInteractOverlay(that.containerId).querySelectorAll(".measure").forEach(m => {
90
+ m.classList.remove(enteredFlag);
91
+ });
92
+ that.lastMeasureMouseEnter.classList.add(enteredFlag);
93
+ //that.vrvSVG.querySelector("#"+that.lastMeasureMouseEnter.id).classList.add(enteredFlag)
94
+ }
95
+ });
96
+ });
97
+ this.interactionOverlay.querySelectorAll(".layer").forEach(layer => {
98
+ layer.addEventListener(mouseEventName, function (e) {
99
+ e.preventDefault();
100
+ var target = e.target;
101
+ that.lastLayerMouseEnter = target.closest(".layer");
102
+ if (!that.lastLayerMouseEnter.classList.contains(enteredFlag)) {
103
+ cq.getInteractOverlay(that.containerId).querySelectorAll(".layer").forEach(l => {
104
+ l.classList.remove(enteredFlag);
105
+ });
106
+ that.lastLayerMouseEnter.classList.add(enteredFlag);
107
+ }
108
+ });
109
+ });
110
+ return this;
111
+ }
112
+ setMouseEnterElements(refElement) {
113
+ var _a, _b, _c, _d, _e, _f, _g;
114
+ this.lastSystemMouseEnter = this.getElementInInteractOverlay((_a = refElement.closest(".system")) === null || _a === void 0 ? void 0 : _a.id);
115
+ this.lastMeasureMouseEnter = this.getElementInInteractOverlay((_b = refElement.closest(".measure")) === null || _b === void 0 ? void 0 : _b.id) || this.getElementInInteractOverlay((_c = refElement.querySelector(".measure")) === null || _c === void 0 ? void 0 : _c.id);
116
+ this.lastStaffMouseEnter = this.getElementInInteractOverlay((_d = refElement.closest(".staff")) === null || _d === void 0 ? void 0 : _d.id) || this.getElementInInteractOverlay((_e = refElement.querySelector(".staff")) === null || _e === void 0 ? void 0 : _e.id);
117
+ this.lastLayerMouseEnter = this.getElementInInteractOverlay((_f = refElement.closest(".layer")) === null || _f === void 0 ? void 0 : _f.id) || this.getElementInInteractOverlay((_g = refElement.querySelector(".layer")) === null || _g === void 0 ? void 0 : _g.id);
118
+ //this.update()
119
+ }
120
+ getMouseEnterElementByName(name) {
121
+ let e;
122
+ switch (name) {
123
+ case "system":
124
+ e = this.lastSystemMouseEnter;
125
+ break;
126
+ case "staff":
127
+ e = this.lastStaffMouseEnter;
128
+ break;
129
+ case "measure":
130
+ e = this.lastMeasureMouseEnter;
131
+ break;
132
+ case "layer":
133
+ e = this.lastLayerMouseEnter;
134
+ break;
135
+ default:
136
+ e = null;
137
+ }
138
+ return e;
139
+ }
140
+ findBBoxes() {
141
+ var notes = this.vrvSVG.querySelectorAll(".note, .rest, .mRest, .notehead");
142
+ var root = this.vrvSVG;
143
+ Array.from(notes).forEach(element => {
144
+ var interactionElement = this.interactionOverlay.querySelector("[refId=" + element.id + "]");
145
+ if (interactionElement === null)
146
+ return;
147
+ var relpt = coordinates.getDOMMatrixCoordinates(interactionElement, this.interactionOverlay);
148
+ let bb = {
149
+ id: element.id,
150
+ parentStaff: element.closest(".staff"),
151
+ parentLayer: element.closest(".layer"),
152
+ parentMeasure: element.closest(".measure"),
153
+ x: relpt.right,
154
+ y: relpt.y
155
+ };
156
+ this.noteBBoxes.push(bb);
157
+ });
158
+ // this.measureMatrix.populateFromSVG(document.querySelector(c._vrvSVGID_WITH_IDSELECTOR_));
159
+ this.measureMatrix.populateFromMEI(this.currentMEI);
160
+ var staves = cq.getVrvSVG(this.containerId).querySelectorAll(constants_1.constants._STAFF_WITH_CLASSSELECTOR_);
161
+ Array.from(staves).forEach(element => {
162
+ let g = cq.getVrvSVG(this.containerId).querySelectorAll("#" + element.id + " > path");
163
+ let staff = element;
164
+ let idxStaff = parseInt(element.getAttribute("n")) - 1;
165
+ let closestMeasure = element.closest(".measure");
166
+ let idxParentMeasure = parseInt(closestMeasure.getAttribute("n")) - 1;
167
+ let clefShape = this.measureMatrix.get(idxParentMeasure, idxStaff).clef;
168
+ Array.from(g).forEach((staffLine, idx) => {
169
+ if (staffLine.id === "") {
170
+ staffLine.id = random_1.uuidv4();
171
+ }
172
+ staffLine.classList.add("staffLine");
173
+ staffLine.classList.add("Clef" + clefShape);
174
+ var map = null;
175
+ switch (clefShape) {
176
+ case "G":
177
+ map = mappings_1.idxNoteMapGClef;
178
+ break;
179
+ case "F":
180
+ map = mappings_1.idxNoteMapFClef;
181
+ break;
182
+ case "C":
183
+ map = mappings_1.idxNoteMapCClef;
184
+ break;
185
+ default:
186
+ console.error("No Clef found");
187
+ break;
188
+ }
189
+ staffLine.classList.add(map.get(idx * 2));
190
+ staffLine.classList.add("Clef" + clefShape);
191
+ //var interactionElement = this.interactionOverlay.querySelector("[refId=" + staffLine.id +"]")
192
+ var relpt = coordinates.getDOMMatrixCoordinates(staffLine, staffLine.closest("svg")); //this.vrvSVG)
193
+ let bb = {
194
+ id: staffLine.parentElement.id,
195
+ y: relpt.y,
196
+ staffIdx: idx * 2,
197
+ classList: staffLine.classList
198
+ };
199
+ this.staffLineBBoxes.push(bb);
200
+ });
201
+ });
202
+ }
203
+ /**
204
+ * Create Phantom Lines to detect clicks above and under the system
205
+ */
206
+ createPhantomLines(upperStaffBound, lowerStaffBound) {
207
+ this.phantomStaffLinesAbove = new Array();
208
+ this.phantomStaffLinesBelow = new Array();
209
+ var diffY = Math.abs(this.staffLineBBoxes[0].y - this.staffLineBBoxes[1].y);
210
+ //Above System
211
+ for (var i = 0; i < 9; i++) {
212
+ if (i === 0) {
213
+ this.phantomStaffLinesAbove.push({ y: this.staffLineBBoxes[upperStaffBound].y - diffY });
214
+ }
215
+ else {
216
+ this.phantomStaffLinesAbove.push({ y: this.phantomStaffLinesAbove[i - 1].y - diffY });
217
+ }
218
+ }
219
+ //Below System
220
+ for (var i = 0; i < 12; i++) {
221
+ if (i === 0) {
222
+ this.phantomStaffLinesBelow.push({ y: this.staffLineBBoxes[lowerStaffBound].y + diffY });
223
+ }
224
+ else {
225
+ this.phantomStaffLinesBelow.push({ y: this.phantomStaffLinesBelow[i - 1].y + diffY });
226
+ }
227
+ }
228
+ }
229
+ /**
230
+ * Define New Note at coordinates
231
+ * 1. Check if left of Note
232
+ * 2. Check position between staves
233
+ * 3. update
234
+ *
235
+ * @param x page Coordinate
236
+ * @param y page Coordinate
237
+ */
238
+ defineNote(x, y, options) {
239
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
240
+ let staffIsEmpty = true;
241
+ let isLeftOfNote;
242
+ //let isRightOfNote: Boolean
243
+ let currentNearestNote = null;
244
+ let diffNote = null;
245
+ let leftRightPos;
246
+ let allIDs = Array.from(this.vrvSVG.querySelectorAll(".staff")).map(s => s.getAttribute("id"));
247
+ if (this.lastStaffMouseEnter === null) {
248
+ return;
249
+ }
250
+ let staffIdx = allIDs.indexOf((_a = this.lastStaffMouseEnter) === null || _a === void 0 ? void 0 : _a.getAttribute("refId"));
251
+ let upperStaffBound = staffIdx * 5 + 0;
252
+ let lowerStaffBound = staffIdx * 5 + 4;
253
+ let aboveSystem = (y < ((_b = this.staffLineBBoxes[upperStaffBound]) === null || _b === void 0 ? void 0 : _b.y)) ? true : false;
254
+ let belowSystem = (y > ((_c = this.staffLineBBoxes[lowerStaffBound]) === null || _c === void 0 ? void 0 : _c.y)) ? true : false;
255
+ let isInSystem = !aboveSystem && !belowSystem;
256
+ //this will cause that the duration of the chord will not be applied on inserted note
257
+ let isRestChord = false;
258
+ if (options.targetChord != undefined) {
259
+ isRestChord = options.targetChord.classList.contains("rest");
260
+ }
261
+ options.targetChord = isRestChord ? undefined : options.targetChord;
262
+ (_e = this.getElementinVrvSVG((_d = this.lastStaffMouseEnter) === null || _d === void 0 ? void 0 : _d.getAttribute("refId"))) === null || _e === void 0 ? void 0 : _e.querySelectorAll(".layer").forEach(l => {
263
+ if (l.hasChildNodes()) {
264
+ staffIsEmpty = false;
265
+ }
266
+ });
267
+ var currentStaffClef;
268
+ for (const [key, value] of (_g = this.getElementinVrvSVG((_f = this.lastStaffMouseEnter) === null || _f === void 0 ? void 0 : _f.getAttribute("refId"))) === null || _g === void 0 ? void 0 : _g.querySelector(".staffLine").classList.entries()) {
269
+ if (value.indexOf("Clef") !== -1) {
270
+ currentStaffClef = value;
271
+ break;
272
+ }
273
+ }
274
+ // Define relative position for click insert
275
+ // position should also consider right border of bounding box. Position should be
276
+ if (!staffIsEmpty) {
277
+ let nbb = [];
278
+ this.noteBBoxes.forEach(bb => {
279
+ var _a;
280
+ if (bb.parentStaff.id === ((_a = this.lastStaffMouseEnter) === null || _a === void 0 ? void 0 : _a.getAttribute("refId"))) {
281
+ nbb.push(bb);
282
+ }
283
+ });
284
+ nbb.forEach(bb => {
285
+ let zerocrossing = x - bb.x;
286
+ let tempDiff = Math.sqrt(Math.abs(x - bb.x) ** 2 + Math.abs(y - bb.y) ** 2);
287
+ if ((diffNote === null || Math.abs(tempDiff) < Math.abs(diffNote))) {
288
+ diffNote = tempDiff;
289
+ currentNearestNote = bb;
290
+ isLeftOfNote = zerocrossing <= 0 ? true : false;
291
+ }
292
+ });
293
+ leftRightPos = isLeftOfNote ? "left" : "right";
294
+ }
295
+ if (isRestChord) {
296
+ leftRightPos = "left";
297
+ }
298
+ let currentNearestStaffLine = null;
299
+ let currentNearestLineIdx = null;
300
+ let isOverStaff;
301
+ //let isUnderStaff: Boolean;
302
+ let diffStaff = null;
303
+ let pname;
304
+ let oct;
305
+ let noteDefinition = new Array();
306
+ let nextPitchIdx;
307
+ if (!isInSystem) { //Phantom Line Stuff
308
+ this.phantomLines = new Array();
309
+ let currentNearestY;
310
+ this.createPhantomLines(upperStaffBound, lowerStaffBound);
311
+ let lineArr = aboveSystem ? this.phantomStaffLinesAbove : this.phantomStaffLinesBelow;
312
+ let aboveMap;
313
+ let belowMap;
314
+ switch (currentStaffClef) {
315
+ case "ClefG":
316
+ aboveMap = mappings_1.idxNotePhantomMapAboveG;
317
+ belowMap = mappings_1.idxNotePhantomMapBelowG;
318
+ break;
319
+ case "ClefF":
320
+ aboveMap = mappings_1.idxNotePhantomMapAboveF;
321
+ belowMap = mappings_1.idxNotePhantomMapBelowF;
322
+ break;
323
+ case "ClefC":
324
+ aboveMap = mappings_1.idxNotePhantomMapAboveC;
325
+ belowMap = mappings_1.idxNotePhantomMapBelowC;
326
+ break;
327
+ default:
328
+ console.log("NO CLEF FOUND");
329
+ }
330
+ let map = aboveSystem ? aboveMap : belowMap;
331
+ let mappingidx = 0;
332
+ lineArr.forEach((line, idx) => {
333
+ let tempDiff = y - line.y;
334
+ mappingidx++;
335
+ if (diffStaff === null || Math.abs(tempDiff) < Math.abs(diffStaff)) {
336
+ this.phantomLines.push(line.y);
337
+ //if(idx%2 !== 0){return} // take only Elements which are actually lines! (every second one)
338
+ currentNearestY = line.y;
339
+ diffStaff = tempDiff;
340
+ currentNearestLineIdx = idx + mappingidx;
341
+ isOverStaff = tempDiff <= 0 ? true : false;
342
+ }
343
+ });
344
+ // prepare center coordinate (Y) for snapping
345
+ let lineDist = Math.abs(lineArr[0].y - lineArr[1].y);
346
+ this.lineDist = lineDist / 2;
347
+ lineDist = isOverStaff ? -lineDist : lineDist;
348
+ if (Math.abs(currentNearestY - y) < Math.abs(lineDist / 2 + currentNearestY - y)) { // line pos < middleline pos
349
+ this.newNoteY = currentNearestY;
350
+ nextPitchIdx = currentNearestLineIdx;
351
+ }
352
+ else {
353
+ if (aboveSystem) {
354
+ nextPitchIdx = isOverStaff ? currentNearestLineIdx + 1 : currentNearestLineIdx - 1;
355
+ }
356
+ else {
357
+ nextPitchIdx = isOverStaff ? currentNearestLineIdx - 1 : currentNearestLineIdx + 1;
358
+ }
359
+ this.newNoteY = currentNearestY + lineDist / 2;
360
+ }
361
+ if (map.get(nextPitchIdx) == undefined) {
362
+ return;
363
+ } // cursor is outside of score
364
+ pname = map.get(nextPitchIdx).charAt(0);
365
+ oct = map.get(nextPitchIdx).charAt(1);
366
+ }
367
+ else {
368
+ // Decide if Staffline is given or not
369
+ this.phantomLines = undefined;
370
+ if (options.staffLineId == undefined) {
371
+ let sbb = [];
372
+ this.staffLineBBoxes.forEach(bb => { var _a; if (bb.id === ((_a = this.lastStaffMouseEnter) === null || _a === void 0 ? void 0 : _a.getAttribute("refId")))
373
+ sbb.push(bb); });
374
+ sbb.forEach(bb => {
375
+ let tempDiff = y - bb.y;
376
+ if (diffStaff === null || Math.abs(tempDiff) < Math.abs(diffStaff)) {
377
+ diffStaff = tempDiff;
378
+ currentNearestStaffLine = bb;
379
+ isOverStaff = tempDiff <= 0 ? true : false;
380
+ //isUnderStaff = tempDiff > 0 ? true : false;
381
+ }
382
+ });
383
+ // prepare center coordinate (Y) for snapping
384
+ if (sbb[0] == undefined || sbb[1] == undefined) {
385
+ return;
386
+ }
387
+ let lineDist = Math.abs(sbb[0].y - sbb[1].y);
388
+ this.lineDist = lineDist / 2;
389
+ lineDist = isOverStaff ? -lineDist : lineDist;
390
+ if (Math.abs(currentNearestStaffLine.y - y) < Math.abs(lineDist / 2 + currentNearestStaffLine.y - y)) { // line pos < middleline pos
391
+ this.newNoteY = currentNearestStaffLine.y; // on line
392
+ nextPitchIdx = currentNearestStaffLine.staffIdx;
393
+ }
394
+ else {
395
+ this.newNoteY = currentNearestStaffLine.y + lineDist / 2; // between lines
396
+ nextPitchIdx = isOverStaff ? currentNearestStaffLine.staffIdx - 1 : currentNearestStaffLine.staffIdx + 1;
397
+ }
398
+ let map = null;
399
+ if (currentNearestStaffLine.classList.contains("ClefG")) {
400
+ map = mappings_1.idxNoteMapGClef;
401
+ }
402
+ else if (currentNearestStaffLine.classList.contains("ClefF")) {
403
+ map = mappings_1.idxNoteMapFClef;
404
+ }
405
+ else if (currentNearestStaffLine.classList.contains("ClefC")) {
406
+ map = mappings_1.idxNoteMapCClef;
407
+ }
408
+ else {
409
+ throw new Error("No Note to Clef Mapping found");
410
+ }
411
+ if (map.get(nextPitchIdx) == undefined) {
412
+ return;
413
+ }
414
+ pname = map.get(nextPitchIdx).charAt(0);
415
+ oct = map.get(nextPitchIdx).charAt(1);
416
+ }
417
+ else {
418
+ let pitch;
419
+ try {
420
+ pitch = cq.getInteractOverlay(this.containerId).querySelector("#" + options.staffLineId).getAttribute("class").split(" ");
421
+ }
422
+ catch (_k) {
423
+ return;
424
+ }
425
+ let p = pitch.filter(function (obj) {
426
+ let isPname = obj.charAt(0) === obj.charAt(0).toLowerCase(); // noch regexe?
427
+ let isOct = !isNaN(parseInt(obj.charAt(1)));
428
+ let length = obj.length === 2;
429
+ return isPname && isOct && length;
430
+ });
431
+ pname = p[0].charAt(0);
432
+ oct = p[0].charAt(1);
433
+ this.newNoteY = this.staffLineBBoxes.filter(function (bb) {
434
+ return bb.classList === cq.getInteractOverlay(this.containerId).querySelector("#" + options.staffLineId).classList;
435
+ })[0].y; // assert that length is 1 (all classlists are unique for )
436
+ }
437
+ }
438
+ //get relevant staffinfo
439
+ //var closestStaff = this.currentMEI.getElementById(currentNearestNote.id).closest("staff")
440
+ var closestStaff = this.currentMEI.getElementById((_h = this.lastStaffMouseEnter) === null || _h === void 0 ? void 0 : _h.getAttribute("refId"));
441
+ var closestMeasure = closestStaff.closest("measure");
442
+ var closestStaffIdx = parseInt(closestStaff.getAttribute("n")) - 1;
443
+ var closestMeasureIdx = parseInt(closestMeasure.getAttribute("n")) - 1;
444
+ var nearestNoteId = (currentNearestNote !== null) ? currentNearestNote.id : null;
445
+ if (nearestNoteId !== null) { // ensure note id to be in new note
446
+ nearestNoteId = this.vrvSVG.querySelector("#" + nearestNoteId).classList.contains("notehead") ? this.vrvSVG.querySelector("#" + nearestNoteId).closest(".note").id : nearestNoteId;
447
+ }
448
+ var keysig = this.measureMatrix.get(closestMeasureIdx, closestStaffIdx).keysig;
449
+ var accid;
450
+ if (this.container.querySelector(".alterBtn.selected") !== null) {
451
+ accid = mappings_1.modButtonToAccid.get(this.container.querySelector(".alterBtn.selected").id);
452
+ }
453
+ else if (keysig != undefined) {
454
+ accid = mappings_1.keysigToNotes.get(keysig);
455
+ accid = accid.filter((s) => { return s === pname; });
456
+ if (accid.length === 1) {
457
+ accid = keysig.charAt(1);
458
+ }
459
+ }
460
+ var newNote = {
461
+ id: random_1.uuidv4(),
462
+ pname: pname,
463
+ dur: this.getDurationNewNote(),
464
+ dots: this.getDotsNewNote(),
465
+ oct: oct,
466
+ keysig: keysig,
467
+ accid: accid,
468
+ nearestNoteId: nearestNoteId,
469
+ relPosX: leftRightPos,
470
+ staffId: (_j = this.lastStaffMouseEnter) === null || _j === void 0 ? void 0 : _j.getAttribute("refId"),
471
+ chordElement: options.targetChord,
472
+ rest: this.container.querySelector("#pauseNote").classList.contains("selected")
473
+ };
474
+ this.newNote = newNote;
475
+ }
476
+ /**
477
+ * Find Score Element nearest to given Position (e.g. Mouse)
478
+ * @param posX should be already transformed DOMPoint
479
+ * @param posY should be already transformed DOMPoint
480
+ * @param checkStaff check if vertical distance in the staff should be considered
481
+ * (for example: should be false, when check position for Annotations, should be true when placing notes in different staves)
482
+ * @param orientation only consider elements which are left or right of given coordinates
483
+ * @returns
484
+ */
485
+ findScoreTarget(posX, posY, checkStaff = true, orientation = { left: true, right: true }) {
486
+ var notes = this.getNoteBBoxes();
487
+ var nextNote;
488
+ var tempDist = Math.pow(10, 10);
489
+ var i = 0;
490
+ notes.forEach(n => {
491
+ var _a, _b, _c, _d;
492
+ var x;
493
+ var y;
494
+ if (((_a = this.getElementinVrvSVG(n.id)) === null || _a === void 0 ? void 0 : _a.closest(".chord")) && navigator.userAgent.toLowerCase().indexOf("firefox") > -1) { // special rule for firefox browsers
495
+ x = (_b = this.getElementinVrvSVG(n.id)) === null || _b === void 0 ? void 0 : _b.closest(".chord").getBoundingClientRect().x;
496
+ y = (_c = this.getElementinVrvSVG(n.id)) === null || _c === void 0 ? void 0 : _c.closest(".chord").getBoundingClientRect().y;
497
+ }
498
+ else {
499
+ x = n.x;
500
+ y = n.y;
501
+ }
502
+ //filter for left and right elements
503
+ if (!this.vrvSVG.querySelector("#" + n.id).classList.contains("mRest")) { //mRest are excluded from this rule
504
+ if (orientation.left === false) {
505
+ if (x < posX)
506
+ return; //exclude left elements
507
+ }
508
+ else if (orientation.right === false) {
509
+ if (x > posX)
510
+ return; // exclude right elements
511
+ }
512
+ }
513
+ var dist = Math.abs(x - posX);
514
+ var staffCondition = n.parentStaff === this.getElementinVrvSVG((_d = this.lastStaffMouseEnter) === null || _d === void 0 ? void 0 : _d.getAttribute("refId"));
515
+ if (checkStaff === false) {
516
+ staffCondition = true;
517
+ dist = Math.sqrt(Math.abs(x - posX) ** 2 + Math.abs(y - posY) ** 2);
518
+ }
519
+ if (dist < tempDist && staffCondition) { // define next note in staff bounds
520
+ tempDist = dist;
521
+ nextNote = n;
522
+ }
523
+ // var l = {x: x, posX: posX, dist: dist, tempDist: tempDist, nextNote: nextNote.id}
524
+ // console.log(i, l)
525
+ // i++
526
+ });
527
+ return nextNote;
528
+ }
529
+ ///// GETTER/ SETTER ///////
530
+ getLastMouseEnter() {
531
+ return { layer: this.lastLayerMouseEnter, staff: this.lastStaffMouseEnter, measure: this.lastMeasureMouseEnter, system: this.lastSystemMouseEnter };
532
+ }
533
+ getNewNote() {
534
+ return this.newNote;
535
+ }
536
+ getNewNoteY() {
537
+ return this.newNoteY;
538
+ }
539
+ getPhantomLines() {
540
+ return this.phantomLines;
541
+ }
542
+ getNoteBBoxes() {
543
+ return this.noteBBoxes;
544
+ }
545
+ getStaffLineBBoxes() {
546
+ return this.staffLineBBoxes;
547
+ }
548
+ setPnameNewNote(name) {
549
+ this.notePname = name;
550
+ }
551
+ setDurationNewNote(dur) {
552
+ this.noteNewDur = dur.toString();
553
+ }
554
+ /**
555
+ * Change note, chord or rest to given duration
556
+ * @param dur
557
+ * @returns
558
+ */
559
+ setMarkedNoteDurations(dur) {
560
+ var retVal = false;
561
+ var markedElements = this.vrvSVG.querySelectorAll(".note.marked, .rest.marked");
562
+ markedElements.forEach(m => {
563
+ var currMeiClone = this.currentMEI.cloneNode(true);
564
+ var meiElement = this.currentMEI.getElementById(m.id);
565
+ var oldMeiElement = meiElement.cloneNode(true);
566
+ var newMeiElement;
567
+ if (meiElement.closest("chord") !== null) {
568
+ oldMeiElement = meiElement.closest("chord").cloneNode(true);
569
+ meiElement.closest("chord").setAttribute("dur", dur.toString());
570
+ newMeiElement = meiElement.closest("chord");
571
+ }
572
+ else {
573
+ oldMeiElement = meiElement.cloneNode(true);
574
+ meiElement.setAttribute("dur", dur.toString());
575
+ newMeiElement = meiElement;
576
+ }
577
+ oldMeiElement.replaceWith(newMeiElement);
578
+ this.currentMEI = meiOperation.fillWithRests(newMeiElement, oldMeiElement, this.currentMEI);
579
+ //if(this.currentMEI.querySelectorAll(".changed").length === 0){
580
+ var additionalElements = Array.from(newMeiElement.closest("layer").querySelectorAll("*[dur]"));
581
+ additionalElements = additionalElements.filter((v, i) => i > additionalElements.indexOf(newMeiElement));
582
+ //this.currentMEI = meiOperation.changeDuration(this.currentMEI, "reduce", additionalElements)
583
+ //additionalElements.unshift(oldMeiElement) // we need this information to determine the new duration of an element that has to be shortened
584
+ this.currentMEI = meiOperation.changeDuration(this.currentMEI, additionalElements, newMeiElement); //this.currentMEI = meiOperation.changeDuration(this.currentMEI, additionalElements)
585
+ //}
586
+ this.currentMEI.querySelectorAll(".changed").forEach(c => c.classList.remove("changed"));
587
+ //check if following events (notes, chords, rests) should be replaced
588
+ if (meiOperation.elementIsOverfilling(meiElement, currMeiClone)) {
589
+ this.currentMEI = currMeiClone;
590
+ }
591
+ else {
592
+ retVal = true;
593
+ }
594
+ });
595
+ return retVal;
596
+ }
597
+ /**
598
+ * Change number of dots for note, chord or rest
599
+ * @param dots
600
+ * @returns
601
+ */
602
+ setMarkedNoteDots(dots) {
603
+ var retVal = false;
604
+ var markedElements = this.vrvSVG.querySelectorAll(".note.marked, .rest.marked");
605
+ markedElements.forEach(m => {
606
+ var currMeiClone = this.currentMEI.cloneNode(true);
607
+ var meiElement = this.currentMEI.getElementById(m.id);
608
+ var oldMeiElement = meiElement.cloneNode(true);
609
+ var newMeiElement;
610
+ if (meiElement.closest("chord") !== null) {
611
+ oldMeiElement = meiElement.closest("chord").cloneNode(true);
612
+ meiElement.closest("chord").setAttribute("dots", dots.toString());
613
+ newMeiElement = meiElement.closest("chord");
614
+ }
615
+ else {
616
+ oldMeiElement = meiElement.cloneNode(true);
617
+ meiElement.setAttribute("dots", dots.toString());
618
+ newMeiElement = meiElement;
619
+ }
620
+ oldMeiElement.replaceWith(newMeiElement);
621
+ this.currentMEI = meiOperation.fillWithRests(newMeiElement, oldMeiElement, this.currentMEI);
622
+ //if(this.currentMEI.querySelectorAll(".changed").length === 0){
623
+ var additionalElements = Array.from(newMeiElement.closest("layer").querySelectorAll("*[dur]"));
624
+ additionalElements = additionalElements.filter((v, i) => i > additionalElements.indexOf(newMeiElement));
625
+ //this.currentMEI = meiOperation.changeDuration(this.currentMEI, "reduce", additionalElements)
626
+ //additionalElements.unshift(oldMeiElement) // we need this information to determine the new duration of an element that has to be shortened
627
+ this.currentMEI = meiOperation.changeDuration(this.currentMEI, additionalElements, newMeiElement, meiOperation.getAbsoluteRatio(newMeiElement) - meiOperation.getAbsoluteRatio(oldMeiElement)); //this.currentMEI = meiOperation.changeDuration(this.currentMEI, additionalElements)
628
+ //}
629
+ this.currentMEI.querySelectorAll(".changed").forEach(c => c.classList.remove("changed"));
630
+ if (meiOperation.elementIsOverfilling(meiElement, currMeiClone)) {
631
+ this.currentMEI = currMeiClone;
632
+ }
633
+ else {
634
+ retVal = true;
635
+ }
636
+ });
637
+ return retVal;
638
+ }
639
+ getElementinVrvSVG(id) {
640
+ if (id !== "" && id !== null) {
641
+ return this.vrvSVG.querySelector("#" + id);
642
+ }
643
+ return;
644
+ }
645
+ getElementInInteractOverlay(id) {
646
+ if (id !== "" && id !== null) {
647
+ return this.interactionOverlay.querySelector("#" + id);
648
+ }
649
+ return;
650
+ }
651
+ setDotsNewNote(dots) {
652
+ this.noteNewDots = dots.toString();
653
+ }
654
+ setCurrentMEI(xmlDoc) {
655
+ var _a;
656
+ this.currentMEI = xmlDoc;
657
+ if (((_a = this.noteBBoxes) === null || _a === void 0 ? void 0 : _a.length) === 0) {
658
+ this.findBBoxes();
659
+ }
660
+ return this;
661
+ }
662
+ setContainerId(id) {
663
+ this.containerId = id;
664
+ this.interactionOverlay = cq.getInteractOverlay(id);
665
+ this.vrvSVG = cq.getVrvSVG(id);
666
+ this.container = document.getElementById(id);
667
+ return this;
668
+ }
669
+ getCurrentMei() {
670
+ return this.currentMEI;
671
+ }
672
+ getMeasureMatrix() {
673
+ return this.measureMatrix;
674
+ }
675
+ getDurationNewNote() {
676
+ var dur;
677
+ var selEl = this.container.querySelector("#noteGroup .selected");
678
+ if (selEl === null) {
679
+ return "4";
680
+ }
681
+ switch (selEl.id) {
682
+ case "fullNote":
683
+ dur = 1;
684
+ break;
685
+ case "halfNote":
686
+ dur = 2;
687
+ break;
688
+ case "quarterNote":
689
+ dur = 4;
690
+ break;
691
+ case "eigthNote":
692
+ dur = 8;
693
+ break;
694
+ case "sixteenthNote":
695
+ dur = 16;
696
+ break;
697
+ case "thirtysecondNote":
698
+ dur = 32;
699
+ break;
700
+ }
701
+ return dur.toString(); //this.noteNewDur
702
+ }
703
+ getDotsNewNote() {
704
+ var dots;
705
+ var selEl = this.container.querySelector("#dotGroup .selected");
706
+ if (selEl === null) {
707
+ return "0";
708
+ }
709
+ switch (selEl.id) {
710
+ case "oneDot":
711
+ dots = "1";
712
+ break;
713
+ case "twoDot":
714
+ dots = "2";
715
+ break;
716
+ }
717
+ return dots;
718
+ }
719
+ getLineDist() {
720
+ return this.lineDist;
721
+ }
722
+ update() {
723
+ this.noteBBoxes.length = 0;
724
+ this.staffLineBBoxes.length = 0;
725
+ //this.updateOverlayCallback()
726
+ this.findBBoxes();
727
+ this.setMouseEnterElementListeners();
728
+ return this;
729
+ }
730
+ setUpdateOverlayCallback(updateOverlayCallback) {
731
+ this.updateOverlayCallback = updateOverlayCallback;
732
+ return this;
733
+ }
734
+ }
735
+ exports.Mouse2SVG = Mouse2SVG;