Source: AlphaTab/AlphaTexStructure.js

/**
 * @class
 * @classdesc Encapsulates the overall AlphaTex object composed of string, int, bool attributes and an array of tracks
 */
class AlphaTexStructure {
    /**
     * Creates a new AlphaTexStructure
     */
    constructor() {
        this.attributesStr = new Map();
        this.attributesInt = new Map();
        this.attributesBool = new Set();
        this.tracks = [];
    }

    /**
     * Get string attribute
     * @param {String} attribute attribute of string to retrieve
     * @returns {String} The value for the asked attribute
     */
    getStr(attribute) {
        return this.attributesStr.get(attribute);
    }

    /**
     * Get int attribute
     * @param {String} attribute attribute of int to retrieve
     * @returns {number} The value for the asked attribute
     */
    getInt(attribute) { return this.attributesInt.get(attribute); }

    /**
     * Set string attribute
     * @param {String} attribute attribute of string to set
     * @param {String} value value of string to set
     */
    setStr(attribute, value) {
        this.attributesStr.set(attribute, value);
    }

    /**
     * Set int attribute
     * @param {String} attribute attribute of int to set
     * @param {number} value value of int to set
     */
    setInt(attribute, value) {
        this.attributesInt.set(attribute, value);
    }

    /**
     * Remove int attribute
     * @param {String} attribute attribute of int to remove
     */
    removeInt(attribute) { this.attributesInt.delete(attribute); }

    /**
     * Add bool attribute
     * @param {String} attribute attribute of bool to add
     */
    addBool(attribute) { this.attributesBool.add(attribute); }

    /**
     * Add track to list of tracks
     * @param {Object} newTrack Track object to add
     */
    addTrack(newTrack) {
        this.tracks.push(newTrack);
    }

    /**
     * Copies all values from source.tracks into this.tracks
     * @param {Object} source Source must have a list of tracks 
     */
    copyTracks(source) {
        source.tracks.forEach((item, index) => {
            this.addTrack(item);
        });
    }

    /**
     * Copies all string, int, and boolean attributes into this object
     * @param {Object} source Source must have attributesStr, attributesInt, attributesBool
     */
    copyAttributes(source) {
        source.attributesStr.forEach((value, key, map) => {
            this.setStr(key, value);
        });

        source.attributesInt.forEach((value, key, map) => {
            this.setInt(key, value);
        });

        source.attributesBool.forEach((value1, value2, set) => {
            this.addBool(value1);
        });
    }

    /**
     * Converts AlphaTexStructure to a pretty string
     * @returns {String} The pretty string representation of the AlphaTexStructure
     */
    toString() {
        let output = "";

        this.attributesStr.forEach((value, key, map) => {
            output += key;
            output += " : ";
            output += value;
            output += "\n";
        });

        this.attributesInt.forEach((value, key, map) => {
            output += key;
            output += " : ";
            output += value;
            output += "\n";
        });

        if (this.tracks.length > 0) {
            this.tracks.forEach((track, index) => {
                output += track.toString();
                output += "\n";
            });
        }

        return output;
    }

}

module.exports = AlphaTexStructure