musicxml-io 0.8.2 → 0.9.1

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.
@@ -6,7 +6,7 @@ var _chunkOEX7NVZNjs = require('./chunk-OEX7NVZN.js');
6
6
 
7
7
 
8
8
 
9
- var _chunkBQKGH2LTjs = require('./chunk-BQKGH2LT.js');
9
+ var _chunkJRXV2ECWjs = require('./chunk-JRXV2ECW.js');
10
10
 
11
11
 
12
12
 
@@ -16,39 +16,168 @@ var _chunkBQKGH2LTjs = require('./chunk-BQKGH2LT.js');
16
16
  var _chunkEWLB5X64js = require('./chunk-EWLB5X64.js');
17
17
 
18
18
  // src/importers/musicxml.ts
19
- var _txml = require('txml/txml');
20
19
  var _entityMap = { amp: "&", lt: "<", gt: ">", quot: '"', apos: "'" };
21
20
  var _entityRegex = /&(?:(amp|lt|gt|quot|apos)|#(\d+)|#x([0-9a-fA-F]+));/g;
21
+ var INVALID_XML_CHARS_RE = /[\x00-\x08\x0B\x0C\x0E-\x1F\uFFFE\uFFFF]/g;
22
+ var INVALID_XML_CHARS_TEST = /[\x00-\x08\x0B\x0C\x0E-\x1F\uFFFE\uFFFF]/;
23
+ function decodeCharRef(match, codePoint) {
24
+ if (codePoint > 1114111 || codePoint >= 55296 && codePoint <= 57343) return match;
25
+ return String.fromCodePoint(codePoint);
26
+ }
22
27
  function decodeXmlEntities(s) {
23
28
  if (s.indexOf("&") === -1) return s;
24
- return s.replace(
29
+ const decoded = s.replace(
25
30
  _entityRegex,
26
- (_, named, dec, hex) => named ? _entityMap[named] : dec ? String.fromCharCode(parseInt(dec, 10)) : String.fromCharCode(parseInt(hex, 16))
31
+ (match, named, dec, hex) => named ? _entityMap[named] : decodeCharRef(match, parseInt(_nullishCoalesce(dec, () => ( hex)), dec ? 10 : 16))
27
32
  );
28
- }
29
- var INVALID_XML_CHARS_RE = /[\x00-\x08\x0B\x0C\x0E-\x1F\uFFFE\uFFFF]/g;
30
- function decodeTree(nodes) {
31
- for (let i = 0; i < nodes.length; i++) {
32
- const node = nodes[i];
33
- if (typeof node === "string") {
34
- let s = node;
35
- if (s.indexOf("&") !== -1) {
36
- s = decodeXmlEntities(s);
37
- }
38
- nodes[i] = s.replace(INVALID_XML_CHARS_RE, "");
33
+ return INVALID_XML_CHARS_TEST.test(decoded) ? decoded.replace(INVALID_XML_CHARS_RE, "") : decoded;
34
+ }
35
+ var EMPTY_ATTRS = Object.freeze({});
36
+ var GT = 62;
37
+ var SLASH = 47;
38
+ var BANG = 33;
39
+ var QUESTION = 63;
40
+ var EQUALS = 61;
41
+ var DQUOTE = 34;
42
+ var SQUOTE = 39;
43
+ var LBRACKET = 91;
44
+ var RBRACKET = 93;
45
+ function isXmlWhitespace(code) {
46
+ return code === 32 || code === 10 || code === 9 || code === 13;
47
+ }
48
+ function isWhitespaceOnly(s) {
49
+ for (let i = 0; i < s.length; i++) {
50
+ if (!isXmlWhitespace(s.charCodeAt(i))) return false;
51
+ }
52
+ return true;
53
+ }
54
+ function parseXml(xml) {
55
+ const root = [];
56
+ const stack = [];
57
+ let children = root;
58
+ const len = xml.length;
59
+ let pos = 0;
60
+ while (pos < len) {
61
+ const lt = xml.indexOf("<", pos);
62
+ if (lt === -1) break;
63
+ if (lt > pos) {
64
+ let text = xml.slice(pos, lt);
65
+ if (!isWhitespaceOnly(text)) {
66
+ text = decodeXmlEntities(text);
67
+ children.push(
68
+ INVALID_XML_CHARS_TEST.test(text) ? text.replace(INVALID_XML_CHARS_RE, "") : text
69
+ );
70
+ } else if (children.length === 0 && xml.charCodeAt(lt + 1) === SLASH) {
71
+ children.push(text);
72
+ }
73
+ }
74
+ const c = xml.charCodeAt(lt + 1);
75
+ if (c === SLASH) {
76
+ const gt = xml.indexOf(">", lt + 2);
77
+ if (gt === -1) break;
78
+ let end = gt;
79
+ while (end > lt + 2 && isXmlWhitespace(xml.charCodeAt(end - 1))) end--;
80
+ const name = xml.slice(lt + 2, end);
81
+ for (let i = stack.length - 1; i >= 0; i--) {
82
+ if (stack[i].tagName === name) {
83
+ stack.length = i;
84
+ break;
85
+ }
86
+ }
87
+ children = stack.length > 0 ? stack[stack.length - 1].children : root;
88
+ pos = gt + 1;
89
+ } else if (c === QUESTION) {
90
+ const end = xml.indexOf("?>", lt + 2);
91
+ pos = end === -1 ? len : end + 2;
92
+ } else if (c === BANG) {
93
+ if (xml.startsWith("<!--", lt)) {
94
+ const end = xml.indexOf("-->", lt + 4);
95
+ pos = end === -1 ? len : end + 3;
96
+ } else if (xml.startsWith("<![CDATA[", lt)) {
97
+ const end = xml.indexOf("]]>", lt + 9);
98
+ let text = xml.slice(lt + 9, end === -1 ? len : end);
99
+ if (INVALID_XML_CHARS_TEST.test(text)) text = text.replace(INVALID_XML_CHARS_RE, "");
100
+ children.push(text);
101
+ pos = end === -1 ? len : end + 3;
102
+ } else {
103
+ let i = lt + 2;
104
+ let depth = 0;
105
+ while (i < len) {
106
+ const ch = xml.charCodeAt(i);
107
+ if (ch === LBRACKET) depth++;
108
+ else if (ch === RBRACKET) depth--;
109
+ else if (ch === GT && depth <= 0) break;
110
+ i++;
111
+ }
112
+ pos = i + 1;
113
+ }
39
114
  } else {
40
- const attrs = node.attributes;
41
- for (const key in attrs) {
42
- const v = attrs[key];
43
- if (v.indexOf("&") !== -1) {
44
- attrs[key] = decodeXmlEntities(v);
115
+ let i = lt + 1;
116
+ while (i < len) {
117
+ const ch = xml.charCodeAt(i);
118
+ if (ch === GT || ch === SLASH || isXmlWhitespace(ch)) break;
119
+ i++;
120
+ }
121
+ const tagName = xml.slice(lt + 1, i);
122
+ let attributes = EMPTY_ATTRS;
123
+ let selfClosing = false;
124
+ while (i < len) {
125
+ let ch = xml.charCodeAt(i);
126
+ while (isXmlWhitespace(ch)) ch = xml.charCodeAt(++i);
127
+ if (ch === GT) {
128
+ i++;
129
+ break;
130
+ }
131
+ if (ch === SLASH) {
132
+ selfClosing = true;
133
+ i++;
134
+ continue;
135
+ }
136
+ const nameStart = i;
137
+ while (i < len) {
138
+ ch = xml.charCodeAt(i);
139
+ if (ch === EQUALS || ch === GT || ch === SLASH || isXmlWhitespace(ch)) break;
140
+ i++;
141
+ }
142
+ const attrName = xml.slice(nameStart, i);
143
+ while (isXmlWhitespace(xml.charCodeAt(i))) i++;
144
+ if (xml.charCodeAt(i) === EQUALS) {
145
+ i++;
146
+ while (isXmlWhitespace(xml.charCodeAt(i))) i++;
147
+ ch = xml.charCodeAt(i);
148
+ let value;
149
+ if (ch === DQUOTE || ch === SQUOTE) {
150
+ const valStart = ++i;
151
+ while (i < len && xml.charCodeAt(i) !== ch) i++;
152
+ value = xml.slice(valStart, i);
153
+ i++;
154
+ } else {
155
+ const valStart = i;
156
+ while (i < len) {
157
+ ch = xml.charCodeAt(i);
158
+ if (ch === GT || isXmlWhitespace(ch)) break;
159
+ i++;
160
+ }
161
+ value = xml.slice(valStart, i);
162
+ }
163
+ if (attributes === EMPTY_ATTRS) attributes = {};
164
+ attributes[attrName] = decodeXmlEntities(value);
165
+ } else if (attrName.length > 0) {
166
+ if (attributes === EMPTY_ATTRS) attributes = {};
167
+ attributes[attrName] = "";
45
168
  }
46
169
  }
47
- decodeTree(node.children);
170
+ const node = { tagName, attributes, children: [] };
171
+ children.push(node);
172
+ if (!selfClosing) {
173
+ stack.push(node);
174
+ children = node.children;
175
+ }
176
+ pos = i;
48
177
  }
49
178
  }
179
+ return root;
50
180
  }
51
- var TXML_OPTIONS = { noChildNodes: [] };
52
181
  function decodeXmlBytes(data) {
53
182
  if (data.length >= 2 && data[0] === 254 && data[1] === 255) {
54
183
  return new TextDecoder("utf-16be").decode(data);
@@ -56,6 +185,10 @@ function decodeXmlBytes(data) {
56
185
  if (data.length >= 2 && data[0] === 255 && data[1] === 254) {
57
186
  return new TextDecoder("utf-16le").decode(data);
58
187
  }
188
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(data)) {
189
+ const hasBom = data.length >= 3 && data[0] === 239 && data[1] === 187 && data[2] === 191;
190
+ return data.toString("utf8", hasBom ? 3 : 0);
191
+ }
59
192
  return new TextDecoder("utf-8").decode(data);
60
193
  }
61
194
  function parse(input) {
@@ -69,9 +202,10 @@ function parse(input) {
69
202
  } else {
70
203
  xmlString = input;
71
204
  }
72
- const cleanedXml = xmlString.replace(/<\?(?!xml\s)[^?]*\?>/g, "");
73
- const parsed = _txml.parse.call(void 0, cleanedXml, TXML_OPTIONS);
74
- decodeTree(parsed);
205
+ if (INVALID_XML_CHARS_TEST.test(xmlString)) {
206
+ xmlString = xmlString.replace(INVALID_XML_CHARS_RE, "");
207
+ }
208
+ const parsed = parseXml(xmlString);
75
209
  let scorePartwiseVersion;
76
210
  let scorePartwise;
77
211
  for (const el of parsed) {
@@ -155,7 +289,7 @@ function parseScorePartwise(elements) {
155
289
  const defaults = parseDefaults(elements);
156
290
  const credits = parseCredits(elements);
157
291
  return {
158
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
292
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
159
293
  metadata,
160
294
  partList,
161
295
  parts,
@@ -412,7 +546,7 @@ function parseSystemLayout(elements) {
412
546
  }
413
547
  function parseCredits(elements) {
414
548
  const credits = collectElements(elements, "credit", (content, attrs) => {
415
- const credit = { _id: attrs["id"] || _chunkBQKGH2LTjs.generateId.call(void 0, ) };
549
+ const credit = { _id: attrs["id"] || _chunkJRXV2ECWjs.generateId.call(void 0, ) };
416
550
  if (attrs["page"]) credit.page = parseInt(attrs["page"], 10);
417
551
  const types = collectElements(content, "credit-type", (c) => extractText(c));
418
552
  const words = collectElements(content, "credit-words", (c, a) => {
@@ -431,8 +565,21 @@ function parseCredits(elements) {
431
565
  if (a["xml:space"]) cw.xmlSpace = a["xml:space"];
432
566
  return cw;
433
567
  });
568
+ const images = collectElements(content, "credit-image", (_c, a) => {
569
+ const ci = { source: a["source"] || "", type: a["type"] || "" };
570
+ if (a["height"]) ci.height = parseFloat(a["height"]);
571
+ if (a["width"]) ci.width = parseFloat(a["width"]);
572
+ if (a["default-x"]) ci.defaultX = parseFloat(a["default-x"]);
573
+ if (a["default-y"]) ci.defaultY = parseFloat(a["default-y"]);
574
+ if (a["relative-x"]) ci.relativeX = parseFloat(a["relative-x"]);
575
+ if (a["relative-y"]) ci.relativeY = parseFloat(a["relative-y"]);
576
+ if (a["halign"]) ci.halign = a["halign"];
577
+ if (a["valign"]) ci.valign = a["valign"];
578
+ return ci;
579
+ });
434
580
  if (types.length > 0) credit.creditType = types;
435
581
  if (words.length > 0) credit.creditWords = words;
582
+ if (images.length > 0) credit.creditImage = images[0];
436
583
  return credit;
437
584
  });
438
585
  return credits.length > 0 ? credits : void 0;
@@ -456,7 +603,7 @@ function parsePartList(elements) {
456
603
  const attrs = el.attributes;
457
604
  const content = el.children;
458
605
  const partInfo = {
459
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
606
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
460
607
  type: "score-part",
461
608
  id: attrs["id"] || ""
462
609
  };
@@ -555,7 +702,7 @@ function parsePartList(elements) {
555
702
  const attrs = el.attributes;
556
703
  const content = el.children;
557
704
  const group = {
558
- _id: attrs["id"] || _chunkBQKGH2LTjs.generateId.call(void 0, ),
705
+ _id: attrs["id"] || _chunkJRXV2ECWjs.generateId.call(void 0, ),
559
706
  type: "part-group",
560
707
  groupType: attrs["type"] === "stop" ? "stop" : "start"
561
708
  };
@@ -592,7 +739,7 @@ function parseParts(elements) {
592
739
  const attrs = el.attributes;
593
740
  const content = el.children;
594
741
  const part = {
595
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
742
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
596
743
  id: attrs["id"] || "",
597
744
  measures: []
598
745
  };
@@ -611,7 +758,7 @@ function parseParts(elements) {
611
758
  }
612
759
  function parseMeasure(elements, attrs) {
613
760
  const measure = {
614
- _id: attrs["id"] || _chunkBQKGH2LTjs.generateId.call(void 0, ),
761
+ _id: attrs["id"] || _chunkJRXV2ECWjs.generateId.call(void 0, ),
615
762
  number: attrs["number"] || "0",
616
763
  // Keep as string per MusicXML spec (token type)
617
764
  entries: []
@@ -628,7 +775,7 @@ function parseMeasure(elements, attrs) {
628
775
  measure.attributes = parsedAttrs;
629
776
  } else {
630
777
  const attrEntry = {
631
- _id: el.attributes["id"] || _chunkBQKGH2LTjs.generateId.call(void 0, ),
778
+ _id: el.attributes["id"] || _chunkJRXV2ECWjs.generateId.call(void 0, ),
632
779
  type: "attributes",
633
780
  attributes: parsedAttrs
634
781
  };
@@ -656,7 +803,7 @@ function parseMeasure(elements, attrs) {
656
803
  } else if (el.tagName === "grouping") {
657
804
  const grpAttrs = el.attributes;
658
805
  const grouping = {
659
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
806
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
660
807
  type: "grouping",
661
808
  groupingType: grpAttrs["type"] || "start"
662
809
  };
@@ -710,7 +857,7 @@ function parsePrint(elements, attrs) {
710
857
  return print;
711
858
  }
712
859
  function parseAttributes(elements, xmlAttrs = {}) {
713
- const attrs = { _id: xmlAttrs["id"] || _chunkBQKGH2LTjs.generateId.call(void 0, ) };
860
+ const attrs = { _id: xmlAttrs["id"] || _chunkJRXV2ECWjs.generateId.call(void 0, ) };
714
861
  const divisions = getElementTextAsInt(elements, "divisions");
715
862
  if (divisions !== void 0) attrs.divisions = divisions;
716
863
  const staves = getElementTextAsInt(elements, "staves");
@@ -876,7 +1023,7 @@ function parseTranspose(elements) {
876
1023
  }
877
1024
  function parseNote(elements, attrs) {
878
1025
  const note = {
879
- _id: attrs["id"] || _chunkBQKGH2LTjs.generateId.call(void 0, ),
1026
+ _id: attrs["id"] || _chunkJRXV2ECWjs.generateId.call(void 0, ),
880
1027
  type: "note",
881
1028
  duration: 0
882
1029
  };
@@ -1627,14 +1774,14 @@ function parseLyric(elements, attrs) {
1627
1774
  }
1628
1775
  function parseBackup(elements) {
1629
1776
  return {
1630
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
1777
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
1631
1778
  type: "backup",
1632
1779
  duration: parseInt(getElementText(elements, "duration") || "0", 10)
1633
1780
  };
1634
1781
  }
1635
1782
  function parseForward(elements, attrs = {}) {
1636
1783
  const forward = {
1637
- _id: attrs["id"] || _chunkBQKGH2LTjs.generateId.call(void 0, ),
1784
+ _id: attrs["id"] || _chunkJRXV2ECWjs.generateId.call(void 0, ),
1638
1785
  type: "forward",
1639
1786
  duration: parseInt(getElementText(elements, "duration") || "0", 10)
1640
1787
  };
@@ -1646,7 +1793,7 @@ function parseForward(elements, attrs = {}) {
1646
1793
  }
1647
1794
  function parseDirection(elements, attrs) {
1648
1795
  const direction = {
1649
- _id: attrs["id"] || _chunkBQKGH2LTjs.generateId.call(void 0, ),
1796
+ _id: attrs["id"] || _chunkJRXV2ECWjs.generateId.call(void 0, ),
1650
1797
  type: "direction",
1651
1798
  directionTypes: []
1652
1799
  };
@@ -2071,7 +2218,7 @@ function parseDirectionTypes(elements) {
2071
2218
  }
2072
2219
  function parseBarline(elements, attrs) {
2073
2220
  const location = attrs["location"] || "right";
2074
- const barline = { _id: attrs["id"] || _chunkBQKGH2LTjs.generateId.call(void 0, ), location };
2221
+ const barline = { _id: attrs["id"] || _chunkJRXV2ECWjs.generateId.call(void 0, ), location };
2075
2222
  const barStyle = getElementText(elements, "bar-style");
2076
2223
  if (barStyle && isValidBarStyle(barStyle)) {
2077
2224
  barline.barStyle = barStyle;
@@ -2303,7 +2450,7 @@ function parseMeasureStyle(elements, attrs) {
2303
2450
  }
2304
2451
  function parseHarmony(elements, attrs) {
2305
2452
  const harmony = {
2306
- _id: attrs["id"] || _chunkBQKGH2LTjs.generateId.call(void 0, ),
2453
+ _id: attrs["id"] || _chunkJRXV2ECWjs.generateId.call(void 0, ),
2307
2454
  type: "harmony",
2308
2455
  root: { rootStep: "C" },
2309
2456
  kind: "major"
@@ -2443,7 +2590,7 @@ function parseHarmony(elements, attrs) {
2443
2590
  }
2444
2591
  function parseFiguredBass(elements, attrs) {
2445
2592
  const fb = {
2446
- _id: attrs["id"] || _chunkBQKGH2LTjs.generateId.call(void 0, ),
2593
+ _id: attrs["id"] || _chunkJRXV2ECWjs.generateId.call(void 0, ),
2447
2594
  type: "figured-bass",
2448
2595
  figures: []
2449
2596
  };
@@ -2492,7 +2639,7 @@ function parseFiguredBass(elements, attrs) {
2492
2639
  }
2493
2640
  function parseSound(elements, attrs) {
2494
2641
  const sound = {
2495
- _id: attrs["id"] || _chunkBQKGH2LTjs.generateId.call(void 0, ),
2642
+ _id: attrs["id"] || _chunkJRXV2ECWjs.generateId.call(void 0, ),
2496
2643
  type: "sound"
2497
2644
  };
2498
2645
  if (attrs["tempo"]) sound.tempo = parseFloat(attrs["tempo"]);
@@ -3533,7 +3680,7 @@ function buildScore(header, voiceTokensList, voiceIds, headerFieldOrder, inlineV
3533
3680
  const headerVoice = _optionalChain([header, 'access', _2 => _2.voices, 'optionalAccess', _3 => _3.find, 'call', _4 => _4((v) => v.id === voiceId)]) || header.voices && header.voices[voiceIndex];
3534
3681
  const voiceName = headerVoice ? headerVoice.name || `Voice ${voiceIndex + 1}` : voiceTokensList.length > 1 ? `Voice ${voiceIndex + 1}` : "Music";
3535
3682
  partListEntries.push({
3536
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
3683
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
3537
3684
  type: "score-part",
3538
3685
  id: partId,
3539
3686
  name: voiceName
@@ -3541,7 +3688,7 @@ function buildScore(header, voiceTokensList, voiceIds, headerFieldOrder, inlineV
3541
3688
  const voiceClef = headerVoice ? abcClefToMusicXml(headerVoice.clef) : void 0;
3542
3689
  const buildResult = buildMeasures(tokens, unitNote, keySignature, timeSignature, measureDuration, voiceClef);
3543
3690
  parts.push({
3544
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
3691
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
3545
3692
  id: partId,
3546
3693
  measures: buildResult.measures
3547
3694
  });
@@ -3594,7 +3741,7 @@ function buildScore(header, voiceTokensList, voiceIds, headerFieldOrder, inlineV
3594
3741
  encoding.encoder = encoderValues;
3595
3742
  }
3596
3743
  return {
3597
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
3744
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
3598
3745
  metadata: {
3599
3746
  movementTitle: header.title,
3600
3747
  creators: creators.length > 0 ? creators : void 0,
@@ -3620,7 +3767,7 @@ function parseTempoToDirection(tempoStr) {
3620
3767
  if (found) beatUnit = found;
3621
3768
  }
3622
3769
  return {
3623
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
3770
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
3624
3771
  type: "direction",
3625
3772
  directionTypes: [{ kind: "metronome", beatUnit, perMinute }],
3626
3773
  placement: "above",
@@ -3676,7 +3823,7 @@ function buildMeasures(tokens, unitNote, keySignature, timeSignature, measureDur
3676
3823
  if (dynDir) currentEntries.push(dynDir);
3677
3824
  } else if (item.kind === "decoration") {
3678
3825
  const decoDir = {
3679
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
3826
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
3680
3827
  type: "direction",
3681
3828
  directionTypes: [{ kind: "words", text: item.value }]
3682
3829
  };
@@ -3687,13 +3834,13 @@ function buildMeasures(tokens, unitNote, keySignature, timeSignature, measureDur
3687
3834
  }
3688
3835
  function finalizeMeasure(endBarType) {
3689
3836
  const measure = {
3690
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
3837
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
3691
3838
  number: String(measureNumber),
3692
3839
  entries: currentEntries
3693
3840
  };
3694
3841
  if (isFirstMeasure) {
3695
3842
  measure.attributes = {
3696
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
3843
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
3697
3844
  divisions: DIVISIONS,
3698
3845
  time: timeSignature,
3699
3846
  key: keySignature,
@@ -3703,7 +3850,7 @@ function buildMeasures(tokens, unitNote, keySignature, timeSignature, measureDur
3703
3850
  }
3704
3851
  if (pendingKeyChange) {
3705
3852
  if (!measure.attributes) {
3706
- measure.attributes = { _id: _chunkBQKGH2LTjs.generateId.call(void 0, ) };
3853
+ measure.attributes = { _id: _chunkJRXV2ECWjs.generateId.call(void 0, ) };
3707
3854
  }
3708
3855
  const kValue = pendingKeyChange.replace(/^K:\s*/, "");
3709
3856
  measure.attributes.key = parseKeySignature2(kValue);
@@ -3906,7 +4053,7 @@ function buildMeasures(tokens, unitNote, keySignature, timeSignature, measureDur
3906
4053
  const rightBl = _optionalChain([lastMeasure, 'access', _9 => _9.barlines, 'optionalAccess', _10 => _10.find, 'call', _11 => _11((b) => b.location === "right")]);
3907
4054
  if (rightBl) {
3908
4055
  const endingBarline2 = {
3909
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
4056
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
3910
4057
  location: "left",
3911
4058
  barStyle: rightBl.barStyle,
3912
4059
  repeat: rightBl.repeat,
@@ -3918,7 +4065,7 @@ function buildMeasures(tokens, unitNote, keySignature, timeSignature, measureDur
3918
4065
  }
3919
4066
  }
3920
4067
  const endingBarline = {
3921
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
4068
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
3922
4069
  location: "left",
3923
4070
  ending: {
3924
4071
  number: token.value,
@@ -4021,7 +4168,7 @@ function buildMeasures(tokens, unitNote, keySignature, timeSignature, measureDur
4021
4168
  case "overlay": {
4022
4169
  if (currentPosition > 0) {
4023
4170
  const backupEntry = {
4024
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
4171
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
4025
4172
  type: "backup",
4026
4173
  duration: currentPosition
4027
4174
  };
@@ -4035,7 +4182,7 @@ function buildMeasures(tokens, unitNote, keySignature, timeSignature, measureDur
4035
4182
  if (lMatch) {
4036
4183
  currentUnitNote = { num: parseInt(lMatch[1], 10), den: parseInt(lMatch[2], 10) };
4037
4184
  const inlineEntry = {
4038
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
4185
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
4039
4186
  type: "direction",
4040
4187
  directionTypes: [{ kind: "words", text: `[L:${lMatch[1]}/${lMatch[2]}]` }]
4041
4188
  };
@@ -4054,7 +4201,7 @@ function buildMeasures(tokens, unitNote, keySignature, timeSignature, measureDur
4054
4201
  if (currentEntries.length > 0) {
4055
4202
  const breakText = token.value === "\\\n" ? "__abc_line_cont__" : "__abc_line_break__";
4056
4203
  const lineBreakDir = {
4057
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
4204
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
4058
4205
  type: "direction",
4059
4206
  directionTypes: [{ kind: "words", text: breakText }]
4060
4207
  };
@@ -4158,7 +4305,7 @@ function createNoteEntry(token, unitNote, _hasTieStop, isGrace, tupletState) {
4158
4305
  }
4159
4306
  const { noteType, dots } = durationToNoteType(isGrace ? lengthToDuration(num, den, unitNote) : duration);
4160
4307
  const entry = {
4161
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
4308
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
4162
4309
  type: "note",
4163
4310
  pitch: token.pitch,
4164
4311
  duration,
@@ -4212,7 +4359,7 @@ function createRestEntry(token, unitNote, tupletState, measureDuration) {
4212
4359
  }
4213
4360
  const { noteType, dots } = durationToNoteType(duration);
4214
4361
  const entry = {
4215
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
4362
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
4216
4363
  type: "note",
4217
4364
  rest: isWholeMeasure ? { measure: true } : {},
4218
4365
  duration,
@@ -4227,7 +4374,7 @@ function createRestEntry(token, unitNote, tupletState, measureDuration) {
4227
4374
  }
4228
4375
  function createBarline(barType, location, endingNumber) {
4229
4376
  const barline = {
4230
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
4377
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
4231
4378
  location
4232
4379
  };
4233
4380
  switch (barType) {
@@ -4318,7 +4465,7 @@ function createHarmonyEntry(chordStr) {
4318
4465
  break;
4319
4466
  }
4320
4467
  const entry = {
4321
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
4468
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
4322
4469
  type: "harmony",
4323
4470
  root: { rootStep, rootAlter: rootAlter !== void 0 ? rootAlter : void 0 },
4324
4471
  kind
@@ -4337,7 +4484,7 @@ function createHarmonyEntry(chordStr) {
4337
4484
  function createDynamicsDirection(dynamic) {
4338
4485
  if (!DYNAMICS_VALUES.has(dynamic)) return null;
4339
4486
  return {
4340
- _id: _chunkBQKGH2LTjs.generateId.call(void 0, ),
4487
+ _id: _chunkJRXV2ECWjs.generateId.call(void 0, ),
4341
4488
  type: "direction",
4342
4489
  directionTypes: [{
4343
4490
  kind: "dynamics",
@@ -4366,13 +4513,13 @@ function serialize(score, options = {}) {
4366
4513
  const version = options.version || score.version || "4.0";
4367
4514
  const indent = _nullishCoalesce(options.indent, () => ( " "));
4368
4515
  if (options.validate) {
4369
- const result = _chunkBQKGH2LTjs.validate.call(void 0, score, options.validateOptions);
4516
+ const result = _chunkJRXV2ECWjs.validate.call(void 0, score, options.validateOptions);
4370
4517
  if (options.onValidation) {
4371
4518
  options.onValidation(result);
4372
4519
  }
4373
4520
  if (!result.valid && options.throwOnValidationError) {
4374
4521
  const errorMessages = result.errors.map((e) => `[${e.code}] ${e.message}`).join("\n");
4375
- throw new (0, _chunkBQKGH2LTjs.ValidationException)(result.errors, `Score validation failed:
4522
+ throw new (0, _chunkJRXV2ECWjs.ValidationException)(result.errors, `Score validation failed:
4376
4523
  ${errorMessages}`);
4377
4524
  }
4378
4525
  }
@@ -4644,6 +4791,19 @@ function serializeCredit(credit, indent, out) {
4644
4791
  out.push(`${indent}${indent}<credit-type>${escapeXml(ct)}</credit-type>`);
4645
4792
  }
4646
4793
  }
4794
+ if (credit.creditImage) {
4795
+ const ci = credit.creditImage;
4796
+ let attrs2 = ` source="${escapeXml(ci.source)}" type="${escapeXml(ci.type)}"`;
4797
+ if (ci.height !== void 0) attrs2 += ` height="${ci.height}"`;
4798
+ if (ci.width !== void 0) attrs2 += ` width="${ci.width}"`;
4799
+ if (ci.defaultX !== void 0) attrs2 += ` default-x="${ci.defaultX}"`;
4800
+ if (ci.defaultY !== void 0) attrs2 += ` default-y="${ci.defaultY}"`;
4801
+ if (ci.relativeX !== void 0) attrs2 += ` relative-x="${ci.relativeX}"`;
4802
+ if (ci.relativeY !== void 0) attrs2 += ` relative-y="${ci.relativeY}"`;
4803
+ if (ci.halign) attrs2 += ` halign="${escapeXml(ci.halign)}"`;
4804
+ if (ci.valign) attrs2 += ` valign="${escapeXml(ci.valign)}"`;
4805
+ out.push(`${indent}${indent}<credit-image${attrs2}/>`);
4806
+ }
4647
4807
  if (credit.creditWords) {
4648
4808
  for (const cw of credit.creditWords) {
4649
4809
  let attrs2 = "";