
class MEIBasic {
public:
    static bool IsAllowed(const std::string &element, const std::string &attr)
    {
        if (attr == "xml:id") return true;
        if (!MEIBasic::map.count(element)) return false;
        const std::vector<std::string> &attributes = MEIBasic::map.at(element);
        return (std::find(attributes.begin(), attributes.end(), attr) != attributes.end());
    }

    // clang-format off
    
    inline static std::map<std::string, std::vector<std::string>> map = {
        {"arpeg", {"label", "type", "order", "layer", "plist", "staff", "tstamp", "startid", "arrow", "arrow.shape", "arrow.size", "arrow.color", "arrow.fillcolor", "color", "enclose", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "lform", "lwidth", "lsegs", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "vo"}},
        {"beam", {"label", "type", "layer", "staff", "color", "cue"}},
        {"beatRpt", {"label", "type", "beatdef", "layer", "staff", "slash", "color", "expand", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "plist"}},
        {"breath", {"label", "type", "layer", "staff", "startid", "tstamp", "color", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "ho", "vo"}},
        {"bTrem", {"label", "type", "layer", "staff", "dots", "dur", "num", "form", "num.place", "num.visible", "unitdur"}},
        {"fermata", {"label", "type", "layer", "plist", "staff", "tstamp", "endid", "startid", "form", "shape", "color", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "place", "ho", "vo"}},
        {"fTrem", {"label", "type", "layer", "staff", "dots", "dur", "form", "unitdur"}},
        {"gliss", {"label", "type", "layer", "plist", "staff", "tstamp", "dur", "endid", "startid", "tstamp2", "color", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "vo", "startho", "endho", "startvo", "endvo", "lendsym", "lendsym.size", "lstartsym", "lstartsym.size", "lform", "lwidth", "lsegs"}},
        {"graceGrp", {"label", "type", "attach", "layer", "staff", "grace", "grace.time", "color"}},
        {"hairpin", {"label", "type", "form", "niente", "layer", "plist", "staff", "tstamp", "dur", "endid", "startid", "tstamp2", "opening", "closed", "opening.vertical", "angle.optimize", "color", "lform", "lwidth", "lsegs", "place", "ho", "vo", "startho", "endho", "startvo", "endvo", "val", "val2"}},
        {"halfmRpt", {"label", "type", "layer", "staff", "dur", "color", "expand", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "vo"}},
        {"harpPedal", {"label", "type", "c", "d", "e", "f", "g", "a", "b", "layer", "plist", "staff", "tstamp", "endid", "startid", "color", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "place", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "vo"}},
        {"lv", {"label", "type", "layer", "plist", "staff", "tstamp", "endid", "startid", "tstamp2", "color", "curvedir", "lform", "lwidth", "lsegs", "ho", "vo", "startho", "endho", "startvo", "endvo"}},
        {"measure", {"label", "type", "left", "right", "metcon", "n"}},
        {"mNum", {"label", "type", "xml:lang", "color", "place", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "vo"}},
        {"mRest", {"label", "type", "cue", "dur", "layer", "staff", "color", "cutout", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "ploc", "oloc", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "vo"}},
        {"mRpt", {"label", "type", "layer", "staff", "num", "color", "expand", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "num.place", "num.visible", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight"}},
        {"multiRest", {"label", "type", "layer", "staff", "num", "block", "color", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "num.place", "num.visible", "ploc", "oloc", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "width"}},
        {"multiRpt", {"label", "type", "layer", "staff", "num", "color", "expand", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight"}},
        {"octave", {"label", "type", "coll", "layer", "plist", "staff", "tstamp", "dur", "dis", "dis.place", "endid", "startid", "tstamp2", "color", "extender", "lendsym", "lendsym.size", "lstartsym", "lstartsym.size", "lform", "lwidth", "lsegs", "ho", "vo", "startho", "endho"}},
        {"pedal", {"label", "type", "dir", "func", "layer", "plist", "staff", "tstamp", "endid", "startid", "tstamp2", "form", "color", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "lendsym", "lendsym.size", "lstartsym", "lstartsym.size", "lform", "lwidth", "lsegs", "place", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "vo"}},
        {"reh", {"label", "type", "xml:lang", "staff", "startid", "tstamp", "color", "place", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "vo"}},
        {"repeatMark", {"label", "type", "xml:lang", "func", "layer", "plist", "staff", "tstamp", "dur", "endid", "startid", "tstamp2", "color", "extender", "lendsym", "lendsym.size", "lstartsym", "lstartsym.size", "lform", "lwidth", "lsegs", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "place", "ho", "vo", "startho", "endho"}},
        {"slur", {"label", "type", "layer", "plist", "staff", "tstamp", "dur", "endid", "startid", "tstamp2", "color", "curvedir", "lform", "lwidth", "lsegs", "ho", "vo", "startho", "endho", "startvo", "endvo"}},
        {"tie", {"label", "type", "layer", "plist", "staff", "tstamp", "endid", "startid", "tstamp2", "color", "curvedir", "lform", "lwidth", "lsegs", "ho", "vo", "startho", "endho", "startvo", "endvo"}},
        {"tuplet", {"label", "type", "dur", "num", "numbase", "layer", "staff", "endid", "startid", "bracket.place", "bracket.visible", "dur.visible", "num.format", "color", "num.place", "num.visible"}},
        {"mordent", {"label", "type", "form", "long", "layer", "plist", "staff", "tstamp", "endid", "startid", "accidupper", "accidlower", "accidupper.ges", "accidlower.ges", "color", "enclose", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "place", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "vo"}},
        {"trill", {"label", "type", "layer", "plist", "staff", "tstamp", "dur", "accidupper", "accidlower", "accidupper.ges", "accidlower.ges", "endid", "startid", "tstamp2", "color", "enclose", "extender", "lendsym", "lendsym.size", "lstartsym", "lstartsym.size", "lform", "lwidth", "lsegs", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "place", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "vo", "startho", "endho"}},
        {"turn", {"label", "type", "delayed", "form", "layer", "plist", "staff", "tstamp", "accidupper", "accidlower", "accidupper.ges", "accidlower.ges", "startid", "color", "enclose", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "place", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "vo"}},
        {"fing", {"label", "type", "layer", "plist", "staff", "tstamp", "dur", "endid", "startid", "tstamp2", "color", "extender", "lendsym", "lendsym.size", "lstartsym", "lstartsym.size", "lform", "lwidth", "lsegs", "place", "ho", "vo"}},
        {"fingGrp", {"label", "type", "form", "layer", "plist", "staff", "tstamp", "dur", "endid", "startid", "tstamp2"}},
        {"chordDef", {"label", "type", "tab.pos", "tab.strings", "tab.courses"}},
        {"chordMember", {"label", "type", "accid.ges", "pname", "oct", "tab.fing", "tab.fret", "tab.line", "tab.string", "tab.course"}},
        {"chordTable", {"label", "type"}},
        {"f", {"label", "type", "layer", "plist", "staff", "tstamp", "dur", "endid", "startid", "tstamp2", "color", "extender", "lendsym", "lendsym.size", "lstartsym", "lstartsym.size", "lform", "lwidth", "lsegs", "place", "ho", "vo"}},
        {"fb", {"label", "type"}},
        {"harm", {"label", "type", "chordref", "layer", "plist", "staff", "tstamp", "dur", "endid", "startid", "tstamp2", "rendgrid", "color", "extender", "lendsym", "lendsym.size", "lstartsym", "lstartsym.size", "lform", "lwidth", "lsegs", "place", "ho", "vo", "startho", "endho"}},
        {"availability", {"label", "type", "data"}},
        {"fileDesc", {"label", "type", "corresp"}},
        {"meiHead", {"label", "xml:lang", "type"}},
        {"pubStmt", {"label", "type"}},
        {"titleStmt", {"label", "type"}},
        {"refrain", {"label", "type", "xml:lang", "color", "place", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "vo", "voltasym"}},
        {"verse", {"label", "type", "color", "place", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "vo", "voltasym", "n"}},
        {"volta", {"label", "type", "xml:lang", "color", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "vo"}},
        {"instrDef", {"label", "n", "type", "midi.channel", "midi.duty", "midi.port", "midi.track", "midi.instrnum", "midi.instrname", "midi.pan", "midi.patchname", "midi.patchnum", "midi.volume", "azimuth", "elevation"}},
        {"persName", {"label", "type", "xml:lang", "nymref", "role", "enddate", "isodate", "notafter", "notbefore", "startdate"}},
        {"accid", {"label", "type", "accid.ges", "func", "accid", "layer", "plist", "staff", "tstamp", "color", "enclose", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "ho", "vo"}},
        {"arranger", {"label", "type", "xml:lang"}},
        {"artic", {"label", "type", "artic", "layer", "plist", "staff", "tstamp", "color", "enclose", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "place", "ho", "vo"}},
        {"body", {"label", "type"}},
        {"caesura", {"label", "type", "layer", "staff", "startid", "tstamp", "color", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "ho", "vo"}},
        {"chord", {"label", "type", "instr", "dots", "grace", "grace.time", "cue", "dur", "layer", "staff", "cluster", "color", "enclose", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "stem.dir", "stem.len", "stem.mod", "ho", "breaksec"}},
        {"clef", {"label", "type", "layer", "staff", "cautionary", "shape", "line", "oct", "dis", "dis.place", "color", "enclose", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "vo"}},
        {"clefGrp", {"label", "type", "layer", "staff"}},
        {"composer", {"label", "type", "xml:lang"}},
        {"date", {"label", "type", "calendar", "enddate", "isodate", "notafter", "notbefore", "startdate", "xml:lang"}},
        {"dir", {"label", "type", "xml:lang", "layer", "plist", "staff", "tstamp", "dur", "endid", "startid", "tstamp2", "color", "extender", "lendsym", "lendsym.size", "lstartsym", "lstartsym.size", "lform", "lwidth", "lsegs", "place", "ho", "vo", "startho", "endho"}},
        {"dynam", {"label", "type", "xml:lang", "layer", "plist", "staff", "tstamp", "dur", "endid", "startid", "tstamp2", "color", "extender", "lendsym", "lendsym.size", "lstartsym", "lstartsym.size", "lform", "lwidth", "lsegs", "place", "ho", "vo", "startho", "endho"}},
        {"ending", {"label", "type", "lendsym", "lendsym.size", "lstartsym", "lstartsym.size", "lform", "lwidth", "lsegs"}},
        {"label", {"label", "type", "xml:lang"}},
        {"labelAbbr", {"label", "type", "xml:lang"}},
        {"layer", {"label", "n", "type"}},
        {"lb", {"label", "type"}},
        {"lyricist", {"label", "type", "xml:lang"}},
        {"mdiv", {"label", "type", "attacca", "n"}},
        {"mei", {"meiversion"}},
        {"music", {"label", "type"}},
        {"note", {"label", "type", "oct.ges", "pname.ges", "instr", "vel", "tab.fing", "tab.fret", "tab.line", "tab.string", "tab.course", "dots", "cue", "dur", "layer", "staff", "grace", "grace.time", "pname", "oct", "color", "enclose", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "stem.dir", "stem.len", "stem.mod", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "breaksec"}},
        {"ornam", {"label", "type", "layer", "plist", "staff", "tstamp", "dur", "accidupper", "accidlower", "accidupper.ges", "accidlower.ges", "endid", "startid", "tstamp2", "color", "enclose", "place", "ho", "vo", "startho", "endho"}},
        {"pb", {"label", "type", "folium"}},
        {"pgFoot", {"label", "type", "func", "halign", "xml:lang"}},
        {"pgHead", {"label", "type", "func", "halign", "xml:lang"}},
        {"pubPlace", {"label", "type", "xml:lang"}},
        {"rend", {"color", "label", "type", "glyph.auth", "glyph.uri", "halign", "xml:lang", "altrend", "rend", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "valign", "xml:space", "rotation"}},
        {"respStmt", {"label", "type"}},
        {"rest", {"label", "type", "instr", "dots", "cue", "dur", "layer", "staff", "color", "enclose", "breaksec", "ploc", "oloc", "ho", "vo"}},
        {"sb", {"label", "type", "form", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight"}},
        {"score", {"label", "type"}},
        {"scoreDef", {"label", "type", "keysig", "meter.count", "meter.unit", "meter.sym"}},
        {"section", {"label", "type", "attacca", "restart"}},
        {"space", {"label", "type", "dots", "dur", "layer", "staff", "compressable", "cutout"}},
        {"staff", {"label", "n", "type"}},
        {"staffDef", {"label", "n", "type", "instr", "tab.strings", "tab.courses", "ppq", "tune.Hz", "tune.pname", "tune.temper", "lines", "clef.shape", "clef.line", "clef.dis", "clef.dis.place", "keysig", "meter.count", "meter.unit", "meter.sym", "trans.diat", "trans.semi", "lines.color", "lines.visible", "scale"}},
        {"staffGrp", {"label", "type", "bar.thru", "symbol", "instr"}},
        {"syl", {"label", "type", "xml:lang", "con", "wordpos", "place", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "vo", "halign"}},
        {"symbol", {"label", "type", "color", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "scale", "ho", "vo"}},
        {"tempo", {"label", "type", "xml:lang", "midi.bpm", "midi.mspb", "func", "layer", "plist", "staff", "tstamp", "mm", "mm.unit", "mm.dots", "endid", "startid", "tstamp2", "color", "extender", "lendsym", "lendsym.size", "lstartsym", "lstartsym.size", "lform", "lwidth", "lsegs", "place", "ho", "vo", "startho", "endho"}},
        {"title", {"label", "xml:lang", "n", "level", "type"}},
        {"barre", {"label", "type", "endid", "startid", "fret"}},
        {"course", {"label", "type", "accid", "pname", "oct"}},
        {"string", {"label", "type", "accid", "pname", "oct"}},
        {"tabDurSym", {"label", "type", "tab.fing", "tab.fret", "tab.line", "tab.string", "tab.course", "layer", "color", "glyph.auth", "glyph.uri", "glyph.name", "glyph.num", "place", "fontfam", "fontname", "fontsize", "fontstyle", "fontweight", "letterspacing", "lineheight", "ho", "vo"}},
        {"tabGrp", {"label", "type", "dots", "dur", "layer", "staff", "ho"}},
    };

    // clang-format on
};
