@coderline/alphatab 1.6.0-alpha.1430 → 1.6.0-alpha.1432

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * alphaTab v1.6.0-alpha.1430 (develop, build 1430)
2
+ * alphaTab v1.6.0-alpha.1432 (develop, build 1432)
3
3
  *
4
4
  * Copyright © 2025, Daniel Kuschny and Contributors, All rights reserved.
5
5
  *
@@ -1006,6 +1006,26 @@ class Bar {
1006
1006
  get isEmpty() {
1007
1007
  return this._isEmpty;
1008
1008
  }
1009
+ /**
1010
+ * Whether this bar has any changes applied which are not related to the voices in it.
1011
+ * (e.g. new key signatures)
1012
+ */
1013
+ get hasChanges() {
1014
+ if (this.index === 0) {
1015
+ return true;
1016
+ }
1017
+ const hasChangesToPrevious = this.keySignature !== this.previousBar.keySignature ||
1018
+ this.keySignatureType !== this.previousBar.keySignatureType ||
1019
+ this.clef !== this.previousBar.clef ||
1020
+ this.clefOttava !== this.previousBar.clefOttava;
1021
+ if (hasChangesToPrevious) {
1022
+ return true;
1023
+ }
1024
+ return (this.simileMark !== SimileMark.None ||
1025
+ this.sustainPedals.length > 0 ||
1026
+ this.barLineLeft !== BarLineStyle.Automatic ||
1027
+ this.barLineRight !== BarLineStyle.Automatic);
1028
+ }
1009
1029
  /**
1010
1030
  * Whether this bar is empty or has only rests.
1011
1031
  */
@@ -2619,6 +2639,33 @@ class MasterBar {
2619
2639
  */
2620
2640
  this.directions = null;
2621
2641
  }
2642
+ /**
2643
+ * Whether the masterbar is has any changes applied to it (e.g. tempo changes, time signature changes etc)
2644
+ * The first bar is always considered changed due to initial setup of values. It does not consider
2645
+ * elements like whether the tempo really changes to the previous bar.
2646
+ */
2647
+ get hasChanges() {
2648
+ if (this.index === 0) {
2649
+ return false;
2650
+ }
2651
+ const hasChangesToPrevious = this.timeSignatureCommon !== this.previousMasterBar.timeSignatureCommon ||
2652
+ this.timeSignatureNumerator !== this.previousMasterBar.timeSignatureNumerator ||
2653
+ this.timeSignatureDenominator !== this.previousMasterBar.timeSignatureDenominator ||
2654
+ this.tripletFeel !== this.previousMasterBar.tripletFeel;
2655
+ if (hasChangesToPrevious) {
2656
+ return true;
2657
+ }
2658
+ return (this.alternateEndings !== 0 ||
2659
+ this.isRepeatStart ||
2660
+ this.isRepeatEnd ||
2661
+ this.isFreeTime ||
2662
+ this.isSectionStart ||
2663
+ this.tempoAutomations.length > 0 ||
2664
+ this.syncPoints && this.syncPoints.length > 0 ||
2665
+ (this.fermata !== null && this.fermata.size > 0) ||
2666
+ (this.directions !== null && this.directions.size > 0) ||
2667
+ this.isAnacrusis);
2668
+ }
2622
2669
  /**
2623
2670
  * The key signature used on all bars.
2624
2671
  * @deprecated Use key signatures on bar level
@@ -3560,6 +3607,43 @@ class ModelUtils {
3560
3607
  }
3561
3608
  }
3562
3609
  }
3610
+ /**
3611
+ * Trims any empty bars at the end of the song.
3612
+ * @param score
3613
+ */
3614
+ static trimEmptyBarsAtEnd(score) {
3615
+ while (score.masterBars.length > 1) {
3616
+ const barIndex = score.masterBars.length - 1;
3617
+ const masterBar = score.masterBars[barIndex];
3618
+ if (masterBar.hasChanges) {
3619
+ return;
3620
+ }
3621
+ for (const track of score.tracks) {
3622
+ for (const staff of track.staves) {
3623
+ if (barIndex < staff.bars.length) {
3624
+ const bar = staff.bars[barIndex];
3625
+ if (!bar.isEmpty || bar.hasChanges) {
3626
+ // found a non-empty bar, stop whole cleanup
3627
+ return;
3628
+ }
3629
+ }
3630
+ }
3631
+ }
3632
+ // if we reach here, all found bars are empty, remove the bar
3633
+ for (const track of score.tracks) {
3634
+ for (const staff of track.staves) {
3635
+ if (barIndex < staff.bars.length) {
3636
+ const bar = staff.bars[barIndex];
3637
+ staff.bars.pop();
3638
+ // unlink
3639
+ bar.previousBar.nextBar = null;
3640
+ }
3641
+ }
3642
+ }
3643
+ score.masterBars.pop();
3644
+ masterBar.previousMasterBar.nextMasterBar = null;
3645
+ }
3646
+ }
3563
3647
  }
3564
3648
  ModelUtils.TuningLetters = new Set([
3565
3649
  0x43 /* C */, 0x44 /* D */, 0x45 /* E */, 0x46 /* F */, 0x47 /* G */, 0x41 /* A */, 0x42 /* B */, 0x63 /* c */,
@@ -8677,6 +8761,7 @@ class AlphaTexImporter extends ScoreImporter {
8677
8761
  this._slurs = new Map();
8678
8762
  this._articulationValueToIndex = new Map();
8679
8763
  this._accidentalMode = AlphaTexAccidentalMode.Explicit;
8764
+ this._syncPoints = [];
8680
8765
  this.logErrors = false;
8681
8766
  }
8682
8767
  get name() {
@@ -8717,10 +8802,16 @@ class AlphaTexImporter extends ScoreImporter {
8717
8802
  if (!anyMetaRead && !anyBarsRead) {
8718
8803
  throw new UnsupportedFormatError('No alphaTex data found');
8719
8804
  }
8805
+ if (this._sy === AlphaTexSymbols.Dot) {
8806
+ this._sy = this.newSy();
8807
+ this.syncPoints();
8808
+ }
8720
8809
  }
8721
8810
  ModelUtils.consolidate(this._score);
8722
8811
  this._score.finish(this.settings);
8812
+ ModelUtils.trimEmptyBarsAtEnd(this._score);
8723
8813
  this._score.rebuildRepeatGroups();
8814
+ this._score.applyFlatSyncPoints(this._syncPoints);
8724
8815
  for (const [track, lyrics] of this._lyrics) {
8725
8816
  this._score.tracks[track].applyLyrics(lyrics);
8726
8817
  }
@@ -8737,6 +8828,47 @@ class AlphaTexImporter extends ScoreImporter {
8737
8828
  throw e;
8738
8829
  }
8739
8830
  }
8831
+ syncPoints() {
8832
+ while (this._sy !== AlphaTexSymbols.Eof) {
8833
+ this.syncPoint();
8834
+ }
8835
+ }
8836
+ syncPoint() {
8837
+ // \sync BarIndex Occurence MillisecondOffset
8838
+ // \sync BarIndex Occurence MillisecondOffset RatioPosition
8839
+ if (this._sy !== AlphaTexSymbols.MetaCommand || this._syData !== 'sync') {
8840
+ this.error('syncPoint', AlphaTexSymbols.MetaCommand, true);
8841
+ }
8842
+ this._sy = this.newSy();
8843
+ if (this._sy !== AlphaTexSymbols.Number) {
8844
+ this.error('syncPointBarIndex', AlphaTexSymbols.Number, true);
8845
+ }
8846
+ const barIndex = this._syData;
8847
+ this._sy = this.newSy();
8848
+ if (this._sy !== AlphaTexSymbols.Number) {
8849
+ this.error('syncPointBarOccurence', AlphaTexSymbols.Number, true);
8850
+ }
8851
+ const barOccurence = this._syData;
8852
+ this._sy = this.newSy();
8853
+ if (this._sy !== AlphaTexSymbols.Number) {
8854
+ this.error('syncPointBarMillis', AlphaTexSymbols.Number, true);
8855
+ }
8856
+ const millisecondOffset = this._syData;
8857
+ this._allowFloat = true;
8858
+ this._sy = this.newSy();
8859
+ this._allowFloat = false;
8860
+ let barPosition = 0;
8861
+ if (this._sy === AlphaTexSymbols.Number) {
8862
+ barPosition = this._syData;
8863
+ this._sy = this.newSy();
8864
+ }
8865
+ this._syncPoints.push({
8866
+ barIndex,
8867
+ barOccurence,
8868
+ barPosition,
8869
+ millisecondOffset
8870
+ });
8871
+ }
8740
8872
  error(nonterm, expected, wrongSymbol = true) {
8741
8873
  let receivedSymbol;
8742
8874
  let showSyData = false;
@@ -33102,7 +33234,7 @@ class AlphaSynthWorkerSynthOutput {
33102
33234
  addSamples(samples) {
33103
33235
  this._worker.postMessage({
33104
33236
  cmd: 'alphaSynth.output.addSamples',
33105
- samples: samples
33237
+ samples: Environment.prepareForPostMessage(samples)
33106
33238
  });
33107
33239
  }
33108
33240
  play() {
@@ -33298,7 +33430,7 @@ class AlphaSynthWebWorker {
33298
33430
  onSoundFontLoadFailed(e) {
33299
33431
  this._main.postMessage({
33300
33432
  cmd: 'alphaSynth.soundFontLoadFailed',
33301
- error: this.serializeException(e)
33433
+ error: this.serializeException(Environment.prepareForPostMessage(e))
33302
33434
  });
33303
33435
  }
33304
33436
  serializeException(e) {
@@ -33329,7 +33461,7 @@ class AlphaSynthWebWorker {
33329
33461
  onMidiLoadFailed(e) {
33330
33462
  this._main.postMessage({
33331
33463
  cmd: 'alphaSynth.midiLoaded',
33332
- error: this.serializeException(e)
33464
+ error: this.serializeException(Environment.prepareForPostMessage(e))
33333
33465
  });
33334
33466
  }
33335
33467
  onReadyForPlayback() {
@@ -42454,6 +42586,18 @@ class FileLoadError extends AlphaTabError {
42454
42586
  * available importers
42455
42587
  */
42456
42588
  class ScoreLoader {
42589
+ /**
42590
+ * Loads the given alphaTex string.
42591
+ * @param tex The alphaTex string.
42592
+ * @param settings The settings to use for parsing.
42593
+ * @returns The parsed {@see Score}.
42594
+ */
42595
+ static loadAlphaTex(tex, settings) {
42596
+ const parser = new AlphaTexImporter();
42597
+ parser.logErrors = true;
42598
+ parser.initFromString(tex, settings ?? new Settings());
42599
+ return parser.readScore();
42600
+ }
42457
42601
  /**
42458
42602
  * Loads a score asynchronously from the given datasource
42459
42603
  * @param path the source path to load the binary file from
@@ -43304,7 +43448,7 @@ class AlphaSynthWebWorkerApi {
43304
43448
  this._midiEventsPlayedFilter = value;
43305
43449
  this._synth.postMessage({
43306
43450
  cmd: 'alphaSynth.setMidiEventsPlayedFilter',
43307
- value: value
43451
+ value: Environment.prepareForPostMessage(value)
43308
43452
  });
43309
43453
  }
43310
43454
  get playbackSpeed() {
@@ -43369,7 +43513,7 @@ class AlphaSynthWebWorkerApi {
43369
43513
  this._playbackRange = value;
43370
43514
  this._synth.postMessage({
43371
43515
  cmd: 'alphaSynth.setPlaybackRange',
43372
- value: value
43516
+ value: Environment.prepareForPostMessage(value)
43373
43517
  });
43374
43518
  }
43375
43519
  constructor(player, settings) {
@@ -43463,13 +43607,13 @@ class AlphaSynthWebWorkerApi {
43463
43607
  playOneTimeMidiFile(midi) {
43464
43608
  this._synth.postMessage({
43465
43609
  cmd: 'alphaSynth.playOneTimeMidiFile',
43466
- midi: JsonConverter.midiFileToJsObject(midi)
43610
+ midi: JsonConverter.midiFileToJsObject(Environment.prepareForPostMessage(midi))
43467
43611
  });
43468
43612
  }
43469
43613
  loadSoundFont(data, append) {
43470
43614
  this._synth.postMessage({
43471
43615
  cmd: 'alphaSynth.loadSoundFontBytes',
43472
- data: data,
43616
+ data: Environment.prepareForPostMessage(data),
43473
43617
  append: append
43474
43618
  });
43475
43619
  }
@@ -43481,13 +43625,13 @@ class AlphaSynthWebWorkerApi {
43481
43625
  loadMidiFile(midi) {
43482
43626
  this._synth.postMessage({
43483
43627
  cmd: 'alphaSynth.loadMidi',
43484
- midi: JsonConverter.midiFileToJsObject(midi)
43628
+ midi: JsonConverter.midiFileToJsObject(Environment.prepareForPostMessage(midi))
43485
43629
  });
43486
43630
  }
43487
43631
  applyTranspositionPitches(transpositionPitches) {
43488
43632
  this._synth.postMessage({
43489
43633
  cmd: 'alphaSynth.applyTranspositionPitches',
43490
- transpositionPitches: JSON.stringify(Array.from(transpositionPitches.entries()))
43634
+ transpositionPitches: JSON.stringify(Array.from(Environment.prepareForPostMessage(transpositionPitches).entries()))
43491
43635
  });
43492
43636
  }
43493
43637
  setChannelTranspositionPitch(channel, semitones) {
@@ -43659,7 +43803,7 @@ class AlphaTabWorkerScoreRenderer {
43659
43803
  });
43660
43804
  }
43661
43805
  serializeSettingsForWorker(settings) {
43662
- const jsObject = JsonConverter.settingsToJsObject(settings);
43806
+ const jsObject = JsonConverter.settingsToJsObject(Environment.prepareForPostMessage(settings));
43663
43807
  // cut out player settings, they are only needed on UI thread side
43664
43808
  jsObject.delete('player');
43665
43809
  return jsObject;
@@ -43717,11 +43861,11 @@ class AlphaTabWorkerScoreRenderer {
43717
43861
  }
43718
43862
  }
43719
43863
  renderScore(score, trackIndexes) {
43720
- const jsObject = score == null ? null : JsonConverter.scoreToJsObject(score);
43864
+ const jsObject = score == null ? null : JsonConverter.scoreToJsObject(Environment.prepareForPostMessage(score));
43721
43865
  this._worker.postMessage({
43722
43866
  cmd: 'alphaTab.renderScore',
43723
43867
  score: jsObject,
43724
- trackIndexes: trackIndexes,
43868
+ trackIndexes: Environment.prepareForPostMessage(trackIndexes),
43725
43869
  fontSizes: FontSizes.FontSizeLookupTables
43726
43870
  });
43727
43871
  }
@@ -43912,7 +44056,7 @@ class AlphaSynthAudioWorkletOutput extends AlphaSynthWebAudioOutputBase {
43912
44056
  addSamples(f) {
43913
44057
  this._worklet?.port.postMessage({
43914
44058
  cmd: AlphaSynthWorkerSynthOutput.CmdOutputAddSamples,
43915
- samples: f
44059
+ samples: Environment.prepareForPostMessage(f)
43916
44060
  });
43917
44061
  }
43918
44062
  resetSamples() {
@@ -61132,9 +61276,9 @@ class VersionInfo {
61132
61276
  print(`build date: ${VersionInfo.date}`);
61133
61277
  }
61134
61278
  }
61135
- VersionInfo.version = '1.6.0-alpha.1430';
61136
- VersionInfo.date = '2025-05-29T22:21:21.689Z';
61137
- VersionInfo.commit = '98a4c2bec8d71f2645008118d3b77fb40973e7fe';
61279
+ VersionInfo.version = '1.6.0-alpha.1432';
61280
+ VersionInfo.date = '2025-05-31T02:06:00.256Z';
61281
+ VersionInfo.commit = '91e41f1b2cf0b786a1ca2053f51cf3f370da4bc6';
61138
61282
 
61139
61283
  /**
61140
61284
  * A factory for custom layout engines.
@@ -61679,6 +61823,29 @@ class Environment {
61679
61823
  print(`Screen Size: ${window.screen.width}x${window.screen.height}`);
61680
61824
  }
61681
61825
  }
61826
+ /**
61827
+ * Prepares the given object to be sent to workers. Web Frameworks like Vue might
61828
+ * create proxy objects for all objects used. This code handles the necessary unwrapping.
61829
+ * @internal
61830
+ * @target web
61831
+ */
61832
+ static prepareForPostMessage(object) {
61833
+ if (!object) {
61834
+ return object;
61835
+ }
61836
+ // Vue toRaw:
61837
+ // https://github.com/vuejs/core/blob/e7381761cc7971c0d40ae0a0a72687a500fd8db3/packages/reactivity/src/reactive.ts#L378-L381
61838
+ if (typeof object === 'object') {
61839
+ const unwrapped = object.__v_raw;
61840
+ if (unwrapped) {
61841
+ return Environment.prepareForPostMessage(unwrapped);
61842
+ }
61843
+ }
61844
+ // Solidjs unwrap: the symbol required to access the raw object is unfortunately hidden and we cannot unwrap it without importing
61845
+ // import { unwrap } from "solid-js/store"
61846
+ // alternative for users is to replace this method during runtime.
61847
+ return object;
61848
+ }
61682
61849
  }
61683
61850
  Environment.StaffIdBeforeSlashAlways = 'before-slash-always';
61684
61851
  Environment.StaffIdBeforeScoreAlways = 'before-score-always';
@@ -61950,6 +62117,7 @@ class CoreSettings {
61950
62117
 
61951
62118
  const _barrel$7 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.defineProperty({
61952
62119
  __proto__: null,
62120
+ AlphaTexImporter,
61953
62121
  ScoreImporter,
61954
62122
  ScoreLoader,
61955
62123
  UnsupportedFormatError
@@ -3014,6 +3014,155 @@ declare enum AlphaTabSystemExclusiveEvents {
3014
3014
  Rest = 1
3015
3015
  }
3016
3016
 
3017
+ /**
3018
+ * This importer can parse alphaTex markup into a score structure.
3019
+ */
3020
+ declare class AlphaTexImporter extends ScoreImporter {
3021
+ private static readonly Eof;
3022
+ private _trackChannel;
3023
+ private _score;
3024
+ private _currentTrack;
3025
+ private _currentStaff;
3026
+ private _barIndex;
3027
+ private _voiceIndex;
3028
+ private _input;
3029
+ private _ch;
3030
+ private _curChPos;
3031
+ private _line;
3032
+ private _col;
3033
+ private _lastValidSpot;
3034
+ private _sy;
3035
+ private _syData;
3036
+ private _allowNegatives;
3037
+ private _allowFloat;
3038
+ private _allowTuning;
3039
+ private _currentDuration;
3040
+ private _currentDynamics;
3041
+ private _currentTuplet;
3042
+ private _lyrics;
3043
+ private _staffHasExplicitDisplayTransposition;
3044
+ private _staffHasExplicitTuning;
3045
+ private _staffTuningApplied;
3046
+ private _percussionArticulationNames;
3047
+ private _sustainPedalToBeat;
3048
+ private _slurs;
3049
+ private _articulationValueToIndex;
3050
+ private _accidentalMode;
3051
+ private _syncPoints;
3052
+ logErrors: boolean;
3053
+ get name(): string;
3054
+ initFromString(tex: string, settings: Settings): void;
3055
+ readScore(): Score;
3056
+ private syncPoints;
3057
+ private syncPoint;
3058
+ private error;
3059
+ private errorMessage;
3060
+ /**
3061
+ * Initializes the song with some required default values.
3062
+ * @returns
3063
+ */
3064
+ private createDefaultScore;
3065
+ private newTrack;
3066
+ /**
3067
+ * Converts a clef string into the clef value.
3068
+ * @param str the string to convert
3069
+ * @returns the clef value
3070
+ */
3071
+ private parseClefFromString;
3072
+ /**
3073
+ * Converts a clef tuning into the clef value.
3074
+ * @param i the tuning value to convert
3075
+ * @returns the clef value
3076
+ */
3077
+ private parseClefFromInt;
3078
+ private parseTripletFeelFromString;
3079
+ private parseTripletFeelFromInt;
3080
+ /**
3081
+ * Converts a keysignature string into the assocciated value.
3082
+ * @param str the string to convert
3083
+ * @returns the assocciated keysignature value
3084
+ */
3085
+ private parseKeySignature;
3086
+ private parseKeySignatureType;
3087
+ /**
3088
+ * Reads, saves, and returns the next character of the source stream.
3089
+ */
3090
+ private nextChar;
3091
+ /**
3092
+ * Saves the current position, line, and column.
3093
+ * All parsed data until this point is assumed to be valid.
3094
+ */
3095
+ private saveValidSpot;
3096
+ /**
3097
+ * Reads, saves, and returns the next terminal symbol.
3098
+ */
3099
+ private newSy;
3100
+ private readNumberOrName;
3101
+ /**
3102
+ * Checks if the given character is a valid letter for a name.
3103
+ * (no control characters, whitespaces, numbers or dots)
3104
+ */
3105
+ private static isNameLetter;
3106
+ private static isTerminal;
3107
+ private static isWhiteSpace;
3108
+ private isDigit;
3109
+ /**
3110
+ * Reads a string from the stream.
3111
+ * @returns the read string.
3112
+ */
3113
+ private readName;
3114
+ private metaData;
3115
+ headerFooterStyle(element: ScoreSubElement): void;
3116
+ private parseTrackNamePolicy;
3117
+ private parseTrackNameMode;
3118
+ private parseTrackNameOrientation;
3119
+ private handleStaffMeta;
3120
+ private handleAccidentalMode;
3121
+ private makeCurrentStaffPitched;
3122
+ /**
3123
+ * Encodes a given string to a shorthand text form without spaces or special characters
3124
+ */
3125
+ private static toArticulationId;
3126
+ private applyPercussionStaff;
3127
+ private chordProperties;
3128
+ private bars;
3129
+ private trackStaffMeta;
3130
+ private handleNewVoice;
3131
+ private beginStaff;
3132
+ private trackProperties;
3133
+ private staffProperties;
3134
+ private bar;
3135
+ private newBar;
3136
+ private beat;
3137
+ private beatDuration;
3138
+ private beatEffects;
3139
+ /**
3140
+ * Tries to apply a beat effect to the given beat.
3141
+ * @returns true if a effect could be applied, otherwise false
3142
+ */
3143
+ private applyBeatEffect;
3144
+ private parseBracketExtendMode;
3145
+ private parseFermataFromString;
3146
+ private parseClefOttavaFromString;
3147
+ private getChordId;
3148
+ private static applyTuplet;
3149
+ private isNoteText;
3150
+ private note;
3151
+ private noteEffects;
3152
+ private harmonicValue;
3153
+ private toFinger;
3154
+ private parseDuration;
3155
+ private parseBendStyle;
3156
+ private parseBendType;
3157
+ private barMeta;
3158
+ private parseBarLineStyle;
3159
+ private parseSimileMarkFromString;
3160
+ private handleDirections;
3161
+ private readTempoAutomation;
3162
+ private applyAlternateEnding;
3163
+ private parseWhammyType;
3164
+ }
3165
+
3017
3166
  /**
3018
3167
  * Automations are used to change the behaviour of a song.
3019
3168
  * @cloneable
@@ -3211,6 +3360,11 @@ declare class Bar {
3211
3360
  * Whether this bar is fully empty (not even having rests).
3212
3361
  */
3213
3362
  get isEmpty(): boolean;
3363
+ /**
3364
+ * Whether this bar has any changes applied which are not related to the voices in it.
3365
+ * (e.g. new key signatures)
3366
+ */
3367
+ get hasChanges(): boolean;
3214
3368
  /**
3215
3369
  * Whether this bar is empty or has only rests.
3216
3370
  */
@@ -6372,6 +6526,7 @@ export declare class Environment {
6372
6526
  * @partial
6373
6527
  */
6374
6528
  private static printPlatformInfo;
6529
+ /* Excluded from this release type: prepareForPostMessage */
6375
6530
  }
6376
6531
 
6377
6532
  export declare namespace exporter {
@@ -7669,7 +7824,8 @@ export declare namespace importer {
7669
7824
  export {
7670
7825
  ScoreImporter,
7671
7826
  ScoreLoader,
7672
- UnsupportedFormatError
7827
+ UnsupportedFormatError,
7828
+ AlphaTexImporter
7673
7829
  }
7674
7830
  }
7675
7831
 
@@ -8683,6 +8839,12 @@ declare class MasterBar {
8683
8839
  * @json_ignore
8684
8840
  */
8685
8841
  index: number;
8842
+ /**
8843
+ * Whether the masterbar is has any changes applied to it (e.g. tempo changes, time signature changes etc)
8844
+ * The first bar is always considered changed due to initial setup of values. It does not consider
8845
+ * elements like whether the tempo really changes to the previous bar.
8846
+ */
8847
+ get hasChanges(): boolean;
8686
8848
  /**
8687
8849
  * The key signature used on all bars.
8688
8850
  * @deprecated Use key signatures on bar level
@@ -12952,6 +13114,13 @@ declare abstract class ScoreLayout {
12952
13114
  * available importers
12953
13115
  */
12954
13116
  declare class ScoreLoader {
13117
+ /**
13118
+ * Loads the given alphaTex string.
13119
+ * @param tex The alphaTex string.
13120
+ * @param settings The settings to use for parsing.
13121
+ * @returns The parsed {@see Score}.
13122
+ */
13123
+ static loadAlphaTex(tex: string, settings?: Settings): Score;
12955
13124
  /**
12956
13125
  * Loads a score asynchronously from the given datasource
12957
13126
  * @param path the source path to load the binary file from