// This is a generated file. Do not edit. var Space_Separator = /[u1680u2000-u200Au202Fu205Fu3000]/; var ID_Start = /[xAAxB5xBAxC0-xD6xD8-xF6xF8-u02C1u02C6-u02D1u02E0-u02E4u02ECu02EEu0370-u0374u0376u0377u037A-u037Du037Fu0386u0388-u038Au038Cu038E-u03A1u03A3-u03F5u03F7-u0481u048A-u052Fu0531-u0556u0559u0561-u0587u05D0-u05EAu05F0-u05F2u0620-u064Au066Eu066Fu0671-u06D3u06D5u06E5u06E6u06EEu06EFu06FA-u06FCu06FFu0710u0712-u072Fu074D-u07A5u07B1u07CA-u07EAu07F4u07F5u07FAu0800-u0815u081Au0824u0828u0840-u0858u0860-u086Au08A0-u08B4u08B6-u08BDu0904-u0939u093Du0950u0958-u0961u0971-u0980u0985-u098Cu098Fu0990u0993-u09A8u09AA-u09B0u09B2u09B6-u09B9u09BDu09CEu09DCu09DDu09DF-u09E1u09F0u09F1u09FCu0A05-u0A0Au0A0Fu0A10u0A13-u0A28u0A2A-u0A30u0A32u0A33u0A35u0A36u0A38u0A39u0A59-u0A5Cu0A5Eu0A72-u0A74u0A85-u0A8Du0A8F-u0A91u0A93-u0AA8u0AAA-u0AB0u0AB2u0AB3u0AB5-u0AB9u0ABDu0AD0u0AE0u0AE1u0AF9u0B05-u0B0Cu0B0Fu0B10u0B13-u0B28u0B2A-u0B30u0B32u0B33u0B35-u0B39u0B3Du0B5Cu0B5Du0B5F-u0B61u0B71u0B83u0B85-u0B8Au0B8E-u0B90u0B92-u0B95u0B99u0B9Au0B9Cu0B9Eu0B9Fu0BA3u0BA4u0BA8-u0BAAu0BAE-u0BB9u0BD0u0C05-u0C0Cu0C0E-u0C10u0C12-u0C28u0C2A-u0C39u0C3Du0C58-u0C5Au0C60u0C61u0C80u0C85-u0C8Cu0C8E-u0C90u0C92-u0CA8u0CAA-u0CB3u0CB5-u0CB9u0CBDu0CDEu0CE0u0CE1u0CF1u0CF2u0D05-u0D0Cu0D0E-u0D10u0D12-u0D3Au0D3Du0D4Eu0D54-u0D56u0D5F-u0D61u0D7A-u0D7Fu0D85-u0D96u0D9A-u0DB1u0DB3-u0DBBu0DBDu0DC0-u0DC6u0E01-u0E30u0E32u0E33u0E40-u0E46u0E81u0E82u0E84u0E87u0E88u0E8Au0E8Du0E94-u0E97u0E99-u0E9Fu0EA1-u0EA3u0EA5u0EA7u0EAAu0EABu0EAD-u0EB0u0EB2u0EB3u0EBDu0EC0-u0EC4u0EC6u0EDC-u0EDFu0F00u0F40-u0F47u0F49-u0F6Cu0F88-u0F8Cu1000-u102Au103Fu1050-u1055u105A-u105Du1061u1065u1066u106E-u1070u1075-u1081u108Eu10A0-u10C5u10C7u10CDu10D0-u10FAu10FC-u1248u124A-u124Du1250-u1256u1258u125A-u125Du1260-u1288u128A-u128Du1290-u12B0u12B2-u12B5u12B8-u12BEu12C0u12C2-u12C5u12C8-u12D6u12D8-u1310u1312-u1315u1318-u135Au1380-u138Fu13A0-u13F5u13F8-u13FDu1401-u166Cu166F-u167Fu1681-u169Au16A0-u16EAu16EE-u16F8u1700-u170Cu170E-u1711u1720-u1731u1740-u1751u1760-u176Cu176E-u1770u1780-u17B3u17D7u17DCu1820-u1877u1880-u1884u1887-u18A8u18AAu18B0-u18F5u1900-u191Eu1950-u196Du1970-u1974u1980-u19ABu19B0-u19C9u1A00-u1A16u1A20-u1A54u1AA7u1B05-u1B33u1B45-u1B4Bu1B83-u1BA0u1BAEu1BAFu1BBA-u1BE5u1C00-u1C23u1C4D-u1C4Fu1C5A-u1C7Du1C80-u1C88u1CE9-u1CECu1CEE-u1CF1u1CF5u1CF6u1D00-u1DBFu1E00-u1F15u1F18-u1F1Du1F20-u1F45u1F48-u1F4Du1F50-u1F57u1F59u1F5Bu1F5Du1F5F-u1F7Du1F80-u1FB4u1FB6-u1FBCu1FBEu1FC2-u1FC4u1FC6-u1FCCu1FD0-u1FD3u1FD6-u1FDBu1FE0-u1FECu1FF2-u1FF4u1FF6-u1FFCu2071u207Fu2090-u209Cu2102u2107u210A-u2113u2115u2119-u211Du2124u2126u2128u212A-u212Du212F-u2139u213C-u213Fu2145-u2149u214Eu2160-u2188u2C00-u2C2Eu2C30-u2C5Eu2C60-u2CE4u2CEB-u2CEEu2CF2u2CF3u2D00-u2D25u2D27u2D2Du2D30-u2D67u2D6Fu2D80-u2D96u2DA0-u2DA6u2DA8-u2DAEu2DB0-u2DB6u2DB8-u2DBEu2DC0-u2DC6u2DC8-u2DCEu2DD0-u2DD6u2DD8-u2DDEu2E2Fu3005-u3007u3021-u3029u3031-u3035u3038-u303Cu3041-u3096u309D-u309Fu30A1-u30FAu30FC-u30FFu3105-u312Eu3131-u318Eu31A0-u31BAu31F0-u31FFu3400-u4DB5u4E00-u9FEAuA000-uA48CuA4D0-uA4FDuA500-uA60CuA610-uA61FuA62AuA62BuA640-uA66EuA67F-uA69DuA6A0-uA6EFuA717-uA71FuA722-uA788uA78B-uA7AEuA7B0-uA7B7uA7F7-uA801uA803-uA805uA807-uA80AuA80C-uA822uA840-uA873uA882-uA8B3uA8F2-uA8F7uA8FBuA8FDuA90A-uA925uA930-uA946uA960-uA97CuA984-uA9B2uA9CFuA9E0-uA9E4uA9E6-uA9EFuA9FA-uA9FEuAA00-uAA28uAA40-uAA42uAA44-uAA4BuAA60-uAA76uAA7AuAA7E-uAAAFuAAB1uAAB5uAAB6uAAB9-uAABDuAAC0uAAC2uAADB-uAADDuAAE0-uAAEAuAAF2-uAAF4uAB01-uAB06uAB09-uAB0EuAB11-uAB16uAB20-uAB26uAB28-uAB2EuAB30-uAB5AuAB5C-uAB65uAB70-uABE2uAC00-uD7A3uD7B0-uD7C6uD7CB-uD7FBuF900-uFA6DuFA70-uFAD9uFB00-uFB06uFB13-uFB17uFB1DuFB1F-uFB28uFB2A-uFB36uFB38-uFB3CuFB3EuFB40uFB41uFB43uFB44uFB46-uFBB1uFBD3-uFD3DuFD50-uFD8FuFD92-uFDC7uFDF0-uFDFBuFE70-uFE74uFE76-uFEFCuFF21-uFF3AuFF41-uFF5AuFF66-uFFBEuFFC2-uFFC7uFFCA-uFFCFuFFD2-uFFD7uFFDA-uFFDC]|uD800|uD801|uD802|uD803|uD804|uD805|uD806|uD807|uD808|uD809|[uD80CuD81C-uD820uD840-uD868uD86A-uD86CuD86F-uD872uD874-uD879]|uD80D|uD811|uD81A|uD81B|uD821|uD822|uD82C|uD82F|uD835|uD83A|uD83B|uD869|uD86D|uD86E|uD873|uD87A|uD87E/; var ID_Continue = /[xAAxB5xBAxC0-xD6xD8-xF6xF8-u02C1u02C6-u02D1u02E0-u02E4u02ECu02EEu0300-u0374u0376u0377u037A-u037Du037Fu0386u0388-u038Au038Cu038E-u03A1u03A3-u03F5u03F7-u0481u0483-u0487u048A-u052Fu0531-u0556u0559u0561-u0587u0591-u05BDu05BFu05C1u05C2u05C4u05C5u05C7u05D0-u05EAu05F0-u05F2u0610-u061Au0620-u0669u066E-u06D3u06D5-u06DCu06DF-u06E8u06EA-u06FCu06FFu0710-u074Au074D-u07B1u07C0-u07F5u07FAu0800-u082Du0840-u085Bu0860-u086Au08A0-u08B4u08B6-u08BDu08D4-u08E1u08E3-u0963u0966-u096Fu0971-u0983u0985-u098Cu098Fu0990u0993-u09A8u09AA-u09B0u09B2u09B6-u09B9u09BC-u09C4u09C7u09C8u09CB-u09CEu09D7u09DCu09DDu09DF-u09E3u09E6-u09F1u09FCu0A01-u0A03u0A05-u0A0Au0A0Fu0A10u0A13-u0A28u0A2A-u0A30u0A32u0A33u0A35u0A36u0A38u0A39u0A3Cu0A3E-u0A42u0A47u0A48u0A4B-u0A4Du0A51u0A59-u0A5Cu0A5Eu0A66-u0A75u0A81-u0A83u0A85-u0A8Du0A8F-u0A91u0A93-u0AA8u0AAA-u0AB0u0AB2u0AB3u0AB5-u0AB9u0ABC-u0AC5u0AC7-u0AC9u0ACB-u0ACDu0AD0u0AE0-u0AE3u0AE6-u0AEFu0AF9-u0AFFu0B01-u0B03u0B05-u0B0Cu0B0Fu0B10u0B13-u0B28u0B2A-u0B30u0B32u0B33u0B35-u0B39u0B3C-u0B44u0B47u0B48u0B4B-u0B4Du0B56u0B57u0B5Cu0B5Du0B5F-u0B63u0B66-u0B6Fu0B71u0B82u0B83u0B85-u0B8Au0B8E-u0B90u0B92-u0B95u0B99u0B9Au0B9Cu0B9Eu0B9Fu0BA3u0BA4u0BA8-u0BAAu0BAE-u0BB9u0BBE-u0BC2u0BC6-u0BC8u0BCA-u0BCDu0BD0u0BD7u0BE6-u0BEFu0C00-u0C03u0C05-u0C0Cu0C0E-u0C10u0C12-u0C28u0C2A-u0C39u0C3D-u0C44u0C46-u0C48u0C4A-u0C4Du0C55u0C56u0C58-u0C5Au0C60-u0C63u0C66-u0C6Fu0C80-u0C83u0C85-u0C8Cu0C8E-u0C90u0C92-u0CA8u0CAA-u0CB3u0CB5-u0CB9u0CBC-u0CC4u0CC6-u0CC8u0CCA-u0CCDu0CD5u0CD6u0CDEu0CE0-u0CE3u0CE6-u0CEFu0CF1u0CF2u0D00-u0D03u0D05-u0D0Cu0D0E-u0D10u0D12-u0D44u0D46-u0D48u0D4A-u0D4Eu0D54-u0D57u0D5F-u0D63u0D66-u0D6Fu0D7A-u0D7Fu0D82u0D83u0D85-u0D96u0D9A-u0DB1u0DB3-u0DBBu0DBDu0DC0-u0DC6u0DCAu0DCF-u0DD4u0DD6u0DD8-u0DDFu0DE6-u0DEFu0DF2u0DF3u0E01-u0E3Au0E40-u0E4Eu0E50-u0E59u0E81u0E82u0E84u0E87u0E88u0E8Au0E8Du0E94-u0E97u0E99-u0E9Fu0EA1-u0EA3u0EA5u0EA7u0EAAu0EABu0EAD-u0EB9u0EBB-u0EBDu0EC0-u0EC4u0EC6u0EC8-u0ECDu0ED0-u0ED9u0EDC-u0EDFu0F00u0F18u0F19u0F20-u0F29u0F35u0F37u0F39u0F3E-u0F47u0F49-u0F6Cu0F71-u0F84u0F86-u0F97u0F99-u0FBCu0FC6u1000-u1049u1050-u109Du10A0-u10C5u10C7u10CDu10D0-u10FAu10FC-u1248u124A-u124Du1250-u1256u1258u125A-u125Du1260-u1288u128A-u128Du1290-u12B0u12B2-u12B5u12B8-u12BEu12C0u12C2-u12C5u12C8-u12D6u12D8-u1310u1312-u1315u1318-u135Au135D-u135Fu1380-u138Fu13A0-u13F5u13F8-u13FDu1401-u166Cu166F-u167Fu1681-u169Au16A0-u16EAu16EE-u16F8u1700-u170Cu170E-u1714u1720-u1734u1740-u1753u1760-u176Cu176E-u1770u1772u1773u1780-u17D3u17D7u17DCu17DDu17E0-u17E9u180B-u180Du1810-u1819u1820-u1877u1880-u18AAu18B0-u18F5u1900-u191Eu1920-u192Bu1930-u193Bu1946-u196Du1970-u1974u1980-u19ABu19B0-u19C9u19D0-u19D9u1A00-u1A1Bu1A20-u1A5Eu1A60-u1A7Cu1A7F-u1A89u1A90-u1A99u1AA7u1AB0-u1ABDu1B00-u1B4Bu1B50-u1B59u1B6B-u1B73u1B80-u1BF3u1C00-u1C37u1C40-u1C49u1C4D-u1C7Du1C80-u1C88u1CD0-u1CD2u1CD4-u1CF9u1D00-u1DF9u1DFB-u1F15u1F18-u1F1Du1F20-u1F45u1F48-u1F4Du1F50-u1F57u1F59u1F5Bu1F5Du1F5F-u1F7Du1F80-u1FB4u1FB6-u1FBCu1FBEu1FC2-u1FC4u1FC6-u1FCCu1FD0-u1FD3u1FD6-u1FDBu1FE0-u1FECu1FF2-u1FF4u1FF6-u1FFCu203Fu2040u2054u2071u207Fu2090-u209Cu20D0-u20DCu20E1u20E5-u20F0u2102u2107u210A-u2113u2115u2119-u211Du2124u2126u2128u212A-u212Du212F-u2139u213C-u213Fu2145-u2149u214Eu2160-u2188u2C00-u2C2Eu2C30-u2C5Eu2C60-u2CE4u2CEB-u2CF3u2D00-u2D25u2D27u2D2Du2D30-u2D67u2D6Fu2D7F-u2D96u2DA0-u2DA6u2DA8-u2DAEu2DB0-u2DB6u2DB8-u2DBEu2DC0-u2DC6u2DC8-u2DCEu2DD0-u2DD6u2DD8-u2DDEu2DE0-u2DFFu2E2Fu3005-u3007u3021-u302Fu3031-u3035u3038-u303Cu3041-u3096u3099u309Au309D-u309Fu30A1-u30FAu30FC-u30FFu3105-u312Eu3131-u318Eu31A0-u31BAu31F0-u31FFu3400-u4DB5u4E00-u9FEAuA000-uA48CuA4D0-uA4FDuA500-uA60CuA610-uA62BuA640-uA66FuA674-uA67DuA67F-uA6F1uA717-uA71FuA722-uA788uA78B-uA7AEuA7B0-uA7B7uA7F7-uA827uA840-uA873uA880-uA8C5uA8D0-uA8D9uA8E0-uA8F7uA8FBuA8FDuA900-uA92DuA930-uA953uA960-uA97CuA980-uA9C0uA9CF-uA9D9uA9E0-uA9FEuAA00-uAA36uAA40-uAA4DuAA50-uAA59uAA60-uAA76uAA7A-uAAC2uAADB-uAADDuAAE0-uAAEFuAAF2-uAAF6uAB01-uAB06uAB09-uAB0EuAB11-uAB16uAB20-uAB26uAB28-uAB2EuAB30-uAB5AuAB5C-uAB65uAB70-uABEAuABECuABEDuABF0-uABF9uAC00-uD7A3uD7B0-uD7C6uD7CB-uD7FBuF900-uFA6DuFA70-uFAD9uFB00-uFB06uFB13-uFB17uFB1D-uFB28uFB2A-uFB36uFB38-uFB3CuFB3EuFB40uFB41uFB43uFB44uFB46-uFBB1uFBD3-uFD3DuFD50-uFD8FuFD92-uFDC7uFDF0-uFDFBuFE00-uFE0FuFE20-uFE2FuFE33uFE34uFE4D-uFE4FuFE70-uFE74uFE76-uFEFCuFF10-uFF19uFF21-uFF3AuFF3FuFF41-uFF5AuFF66-uFFBEuFFC2-uFFC7uFFCA-uFFCFuFFD2-uFFD7uFFDA-uFFDC]|uD800|uD801|uD802|uD803|uD804|uD805|uD806|uD807|uD808|uD809|[uD80CuD81C-uD820uD840-uD868uD86A-uD86CuD86F-uD872uD874-uD879]|uD80D|uD811|uD81A|uD81B|uD821|uD822|uD82C|uD82F|uD834|uD835|uD836|uD838|uD83A|uD83B|uD869|uD86D|uD86E|uD873|uD87A|uD87E|uDB40/;

var unicode = {

Space_Separator: Space_Separator,
ID_Start: ID_Start,
ID_Continue: ID_Continue

};

var util = {

isSpaceSeparator (c) {
    return unicode.Space_Separator.test(c)
},

isIdStartChar (c) {
    return (
        (c >= 'a' && c <= 'z') ||
    (c >= 'A' && c <= 'Z') ||
    (c === '$') || (c === '_') ||
    unicode.ID_Start.test(c)
    )
},

isIdContinueChar (c) {
    return (
        (c >= 'a' && c <= 'z') ||
    (c >= 'A' && c <= 'Z') ||
    (c >= '0' && c <= '9') ||
    (c === '$') || (c === '_') ||
    (c === '\u200C') || (c === '\u200D') ||
    unicode.ID_Continue.test(c)
    )
},

isDigit (c) {
    return /[0-9]/.test(c)
},

isHexDigit (c) {
    return /[0-9A-Fa-f]/.test(c)
},

};

let source; let parseState; let stack; let pos; let line; let column; let token; let key; let root;

var parse = function parse (text, reviver) {

source = String(text);
parseState = 'start';
stack = [];
pos = 0;
line = 1;
column = 0;
token = undefined;
key = undefined;
root = undefined;

do {
    token = lex();

    // This code is unreachable.
    // if (!parseStates[parseState]) {
    //     throw invalidParseState()
    // }

    parseStates[parseState]();
} while (token.type !== 'eof')

if (typeof reviver === 'function') {
    return internalize({'': root}, '', reviver)
}

return root

};

function internalize (holder, name, reviver) {

const value = holder[name];
if (value != null && typeof value === 'object') {
    for (const key in value) {
        const replacement = internalize(value, key, reviver);
        if (replacement === undefined) {
            delete value[key];
        } else {
            value[key] = replacement;
        }
    }
}

return reviver.call(holder, name, value)

}

let lexState; let buffer; let doubleQuote; let sign; let c;

function lex () {

lexState = 'default';
buffer = '';
doubleQuote = false;
sign = 1;

for (;;) {
    c = peek();

    // This code is unreachable.
    // if (!lexStates[lexState]) {
    //     throw invalidLexState(lexState)
    // }

    const token = lexStates[lexState]();
    if (token) {
        return token
    }
}

}

function peek () {

if (source[pos]) {
    return String.fromCodePoint(source.codePointAt(pos))
}

}

function read () {

const c = peek();

if (c === '\n') {
    line++;
    column = 0;
} else if (c) {
    column += c.length;
} else {
    column++;
}

if (c) {
    pos += c.length;
}

return c

}

const lexStates = {

default () {
    switch (c) {
    case '\t':
    case '\v':
    case '\f':
    case ' ':
    case '\u00A0':
    case '\uFEFF':
    case '\n':
    case '\r':
    case '\u2028':
    case '\u2029':
        read();
        return

    case '/':
        read();
        lexState = 'comment';
        return

    case undefined:
        read();
        return newToken('eof')
    }

    if (util.isSpaceSeparator(c)) {
        read();
        return
    }

    // This code is unreachable.
    // if (!lexStates[parseState]) {
    //     throw invalidLexState(parseState)
    // }

    return lexStates[parseState]()
},

comment () {
    switch (c) {
    case '*':
        read();
        lexState = 'multiLineComment';
        return

    case '/':
        read();
        lexState = 'singleLineComment';
        return
    }

    throw invalidChar(read())
},

multiLineComment () {
    switch (c) {
    case '*':
        read();
        lexState = 'multiLineCommentAsterisk';
        return

    case undefined:
        throw invalidChar(read())
    }

    read();
},

multiLineCommentAsterisk () {
    switch (c) {
    case '*':
        read();
        return

    case '/':
        read();
        lexState = 'default';
        return

    case undefined:
        throw invalidChar(read())
    }

    read();
    lexState = 'multiLineComment';
},

singleLineComment () {
    switch (c) {
    case '\n':
    case '\r':
    case '\u2028':
    case '\u2029':
        read();
        lexState = 'default';
        return

    case undefined:
        read();
        return newToken('eof')
    }

    read();
},

value () {
    switch (c) {
    case '{':
    case '[':
        return newToken('punctuator', read())

    case 'n':
        read();
        literal('ull');
        return newToken('null', null)

    case 't':
        read();
        literal('rue');
        return newToken('boolean', true)

    case 'f':
        read();
        literal('alse');
        return newToken('boolean', false)

    case '-':
    case '+':
        if (read() === '-') {
            sign = -1;
        }

        lexState = 'sign';
        return

    case '.':
        buffer = read();
        lexState = 'decimalPointLeading';
        return

    case '0':
        buffer = read();
        lexState = 'zero';
        return

    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
        buffer = read();
        lexState = 'decimalInteger';
        return

    case 'I':
        read();
        literal('nfinity');
        return newToken('numeric', Infinity)

    case 'N':
        read();
        literal('aN');
        return newToken('numeric', NaN)

    case '"':
    case "'":
        doubleQuote = (read() === '"');
        buffer = '';
        lexState = 'string';
        return
    }

    throw invalidChar(read())
},

identifierNameStartEscape () {
    if (c !== 'u') {
        throw invalidChar(read())
    }

    read();
    const u = unicodeEscape();
    switch (u) {
    case '$':
    case '_':
        break

    default:
        if (!util.isIdStartChar(u)) {
            throw invalidIdentifier()
        }

        break
    }

    buffer += u;
    lexState = 'identifierName';
},

identifierName () {
    switch (c) {
    case '$':
    case '_':
    case '\u200C':
    case '\u200D':
        buffer += read();
        return

    case '\\':
        read();
        lexState = 'identifierNameEscape';
        return
    }

    if (util.isIdContinueChar(c)) {
        buffer += read();
        return
    }

    return newToken('identifier', buffer)
},

identifierNameEscape () {
    if (c !== 'u') {
        throw invalidChar(read())
    }

    read();
    const u = unicodeEscape();
    switch (u) {
    case '$':
    case '_':
    case '\u200C':
    case '\u200D':
        break

    default:
        if (!util.isIdContinueChar(u)) {
            throw invalidIdentifier()
        }

        break
    }

    buffer += u;
    lexState = 'identifierName';
},

sign () {
    switch (c) {
    case '.':
        buffer = read();
        lexState = 'decimalPointLeading';
        return

    case '0':
        buffer = read();
        lexState = 'zero';
        return

    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
        buffer = read();
        lexState = 'decimalInteger';
        return

    case 'I':
        read();
        literal('nfinity');
        return newToken('numeric', sign * Infinity)

    case 'N':
        read();
        literal('aN');
        return newToken('numeric', NaN)
    }

    throw invalidChar(read())
},

zero () {
    switch (c) {
    case '.':
        buffer += read();
        lexState = 'decimalPoint';
        return

    case 'e':
    case 'E':
        buffer += read();
        lexState = 'decimalExponent';
        return

    case 'x':
    case 'X':
        buffer += read();
        lexState = 'hexadecimal';
        return
    }

    return newToken('numeric', sign * 0)
},

decimalInteger () {
    switch (c) {
    case '.':
        buffer += read();
        lexState = 'decimalPoint';
        return

    case 'e':
    case 'E':
        buffer += read();
        lexState = 'decimalExponent';
        return
    }

    if (util.isDigit(c)) {
        buffer += read();
        return
    }

    return newToken('numeric', sign * Number(buffer))
},

decimalPointLeading () {
    if (util.isDigit(c)) {
        buffer += read();
        lexState = 'decimalFraction';
        return
    }

    throw invalidChar(read())
},

decimalPoint () {
    switch (c) {
    case 'e':
    case 'E':
        buffer += read();
        lexState = 'decimalExponent';
        return
    }

    if (util.isDigit(c)) {
        buffer += read();
        lexState = 'decimalFraction';
        return
    }

    return newToken('numeric', sign * Number(buffer))
},

decimalFraction () {
    switch (c) {
    case 'e':
    case 'E':
        buffer += read();
        lexState = 'decimalExponent';
        return
    }

    if (util.isDigit(c)) {
        buffer += read();
        return
    }

    return newToken('numeric', sign * Number(buffer))
},

decimalExponent () {
    switch (c) {
    case '+':
    case '-':
        buffer += read();
        lexState = 'decimalExponentSign';
        return
    }

    if (util.isDigit(c)) {
        buffer += read();
        lexState = 'decimalExponentInteger';
        return
    }

    throw invalidChar(read())
},

decimalExponentSign () {
    if (util.isDigit(c)) {
        buffer += read();
        lexState = 'decimalExponentInteger';
        return
    }

    throw invalidChar(read())
},

decimalExponentInteger () {
    if (util.isDigit(c)) {
        buffer += read();
        return
    }

    return newToken('numeric', sign * Number(buffer))
},

hexadecimal () {
    if (util.isHexDigit(c)) {
        buffer += read();
        lexState = 'hexadecimalInteger';
        return
    }

    throw invalidChar(read())
},

hexadecimalInteger () {
    if (util.isHexDigit(c)) {
        buffer += read();
        return
    }

    return newToken('numeric', sign * Number(buffer))
},

string () {
    switch (c) {
    case '\\':
        read();
        buffer += escape();
        return

    case '"':
        if (doubleQuote) {
            read();
            return newToken('string', buffer)
        }

        buffer += read();
        return

    case "'":
        if (!doubleQuote) {
            read();
            return newToken('string', buffer)
        }

        buffer += read();
        return

    case '\n':
    case '\r':
        throw invalidChar(read())

    case '\u2028':
    case '\u2029':
        separatorChar(c);
        break

    case undefined:
        throw invalidChar(read())
    }

    buffer += read();
},

start () {
    switch (c) {
    case '{':
    case '[':
        return newToken('punctuator', read())

    // This code is unreachable since the default lexState handles eof.
    // case undefined:
    //     return newToken('eof')
    }

    lexState = 'value';
},

beforePropertyName () {
    switch (c) {
    case '$':
    case '_':
        buffer = read();
        lexState = 'identifierName';
        return

    case '\\':
        read();
        lexState = 'identifierNameStartEscape';
        return

    case '}':
        return newToken('punctuator', read())

    case '"':
    case "'":
        doubleQuote = (read() === '"');
        lexState = 'string';
        return
    }

    if (util.isIdStartChar(c)) {
        buffer += read();
        lexState = 'identifierName';
        return
    }

    throw invalidChar(read())
},

afterPropertyName () {
    if (c === ':') {
        return newToken('punctuator', read())
    }

    throw invalidChar(read())
},

beforePropertyValue () {
    lexState = 'value';
},

afterPropertyValue () {
    switch (c) {
    case ',':
    case '}':
        return newToken('punctuator', read())
    }

    throw invalidChar(read())
},

beforeArrayValue () {
    if (c === ']') {
        return newToken('punctuator', read())
    }

    lexState = 'value';
},

afterArrayValue () {
    switch (c) {
    case ',':
    case ']':
        return newToken('punctuator', read())
    }

    throw invalidChar(read())
},

end () {
    // This code is unreachable since it's handled by the default lexState.
    // if (c === undefined) {
    //     read()
    //     return newToken('eof')
    // }

    throw invalidChar(read())
},

};

function newToken (type, value) {

return {
    type,
    value,
    line,
    column,
}

}

function literal (s) {

for (const c of s) {
    const p = peek();

    if (p !== c) {
        throw invalidChar(read())
    }

    read();
}

}

function escape () {

const c = peek();
switch (c) {
case 'b':
    read();
    return '\b'

case 'f':
    read();
    return '\f'

case 'n':
    read();
    return '\n'

case 'r':
    read();
    return '\r'

case 't':
    read();
    return '\t'

case 'v':
    read();
    return '\v'

case '0':
    read();
    if (util.isDigit(peek())) {
        throw invalidChar(read())
    }

    return '\0'

case 'x':
    read();
    return hexEscape()

case 'u':
    read();
    return unicodeEscape()

case '\n':
case '\u2028':
case '\u2029':
    read();
    return ''

case '\r':
    read();
    if (peek() === '\n') {
        read();
    }

    return ''

case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
    throw invalidChar(read())

case undefined:
    throw invalidChar(read())
}

return read()

}

function hexEscape () {

let buffer = '';
let c = peek();

if (!util.isHexDigit(c)) {
    throw invalidChar(read())
}

buffer += read();

c = peek();
if (!util.isHexDigit(c)) {
    throw invalidChar(read())
}

buffer += read();

return String.fromCodePoint(parseInt(buffer, 16))

}

function unicodeEscape () {

let buffer = '';
let count = 4;

while (count-- > 0) {
    const c = peek();
    if (!util.isHexDigit(c)) {
        throw invalidChar(read())
    }

    buffer += read();
}

return String.fromCodePoint(parseInt(buffer, 16))

}

const parseStates = {

start () {
    if (token.type === 'eof') {
        throw invalidEOF()
    }

    push();
},

beforePropertyName () {
    switch (token.type) {
    case 'identifier':
    case 'string':
        key = token.value;
        parseState = 'afterPropertyName';
        return

    case 'punctuator':
        // This code is unreachable since it's handled by the lexState.
        // if (token.value !== '}') {
        //     throw invalidToken()
        // }

        pop();
        return

    case 'eof':
        throw invalidEOF()
    }

    // This code is unreachable since it's handled by the lexState.
    // throw invalidToken()
},

afterPropertyName () {
    // This code is unreachable since it's handled by the lexState.
    // if (token.type !== 'punctuator' || token.value !== ':') {
    //     throw invalidToken()
    // }

    if (token.type === 'eof') {
        throw invalidEOF()
    }

    parseState = 'beforePropertyValue';
},

beforePropertyValue () {
    if (token.type === 'eof') {
        throw invalidEOF()
    }

    push();
},

beforeArrayValue () {
    if (token.type === 'eof') {
        throw invalidEOF()
    }

    if (token.type === 'punctuator' && token.value === ']') {
        pop();
        return
    }

    push();
},

afterPropertyValue () {
    // This code is unreachable since it's handled by the lexState.
    // if (token.type !== 'punctuator') {
    //     throw invalidToken()
    // }

    if (token.type === 'eof') {
        throw invalidEOF()
    }

    switch (token.value) {
    case ',':
        parseState = 'beforePropertyName';
        return

    case '}':
        pop();
    }

    // This code is unreachable since it's handled by the lexState.
    // throw invalidToken()
},

afterArrayValue () {
    // This code is unreachable since it's handled by the lexState.
    // if (token.type !== 'punctuator') {
    //     throw invalidToken()
    // }

    if (token.type === 'eof') {
        throw invalidEOF()
    }

    switch (token.value) {
    case ',':
        parseState = 'beforeArrayValue';
        return

    case ']':
        pop();
    }

    // This code is unreachable since it's handled by the lexState.
    // throw invalidToken()
},

end () {
    // This code is unreachable since it's handled by the lexState.
    // if (token.type !== 'eof') {
    //     throw invalidToken()
    // }
},

};

function push () {

let value;

switch (token.type) {
case 'punctuator':
    switch (token.value) {
    case '{':
        value = {};
        break

    case '[':
        value = [];
        break
    }

    break

case 'null':
case 'boolean':
case 'numeric':
case 'string':
    value = token.value;
    break

// This code is unreachable.
// default:
//     throw invalidToken()
}

if (root === undefined) {
    root = value;
} else {
    const parent = stack[stack.length - 1];
    if (Array.isArray(parent)) {
        parent.push(value);
    } else {
        parent[key] = value;
    }
}

if (value !== null && typeof value === 'object') {
    stack.push(value);

    if (Array.isArray(value)) {
        parseState = 'beforeArrayValue';
    } else {
        parseState = 'beforePropertyName';
    }
} else {
    const current = stack[stack.length - 1];
    if (current == null) {
        parseState = 'end';
    } else if (Array.isArray(current)) {
        parseState = 'afterArrayValue';
    } else {
        parseState = 'afterPropertyValue';
    }
}

}

function pop () {

stack.pop();

const current = stack[stack.length - 1];
if (current == null) {
    parseState = 'end';
} else if (Array.isArray(current)) {
    parseState = 'afterArrayValue';
} else {
    parseState = 'afterPropertyValue';
}

}

// This code is unreachable. // function invalidParseState () { // return new Error(`JSON5: invalid parse state '${parseState}'`) // }

// This code is unreachable. // function invalidLexState (state) { // return new Error(`JSON5: invalid lex state '${state}'`) // }

function invalidChar © {

if (c === undefined) {
    return syntaxError(`JSON5: invalid end of input at ${line}:${column}`)
}

return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`)

}

function invalidEOF () {

return syntaxError(`JSON5: invalid end of input at ${line}:${column}`)

}

// This code is unreachable. // function invalidToken () { // if (token.type === 'eof') { // return syntaxError(`JSON5: invalid end of input at ${line}:${column}`) // }

// const c = String.fromCodePoint(token.value.codePointAt(0)) // return syntaxError(`JSON5: invalid character '${formatChar©}' at ${line}:${column}`) // }

function invalidIdentifier () {

column -= 5;
return syntaxError(`JSON5: invalid identifier character at ${line}:${column}`)

}

function separatorChar © {

console.warn(`JSON5: '${formatChar(c)}' in strings is not valid ECMAScript; consider escaping`);

}

function formatChar © {

const replacements = {
    "'": "\\'",
    '"': '\\"',
    '\\': '\\\\',
    '\b': '\\b',
    '\f': '\\f',
    '\n': '\\n',
    '\r': '\\r',
    '\t': '\\t',
    '\v': '\\v',
    '\0': '\\0',
    '\u2028': '\\u2028',
    '\u2029': '\\u2029',
};

if (replacements[c]) {
    return replacements[c]
}

if (c < ' ') {
    const hexString = c.charCodeAt(0).toString(16);
    return '\\x' + ('00' + hexString).substring(hexString.length)
}

return c

}

function syntaxError (message) {

const err = new SyntaxError(message);
err.lineNumber = line;
err.columnNumber = column;
return err

}

var stringify = function stringify (value, replacer, space) {

const stack = [];
let indent = '';
let propertyList;
let replacerFunc;
let gap = '';
let quote;

if (
    replacer != null &&
    typeof replacer === 'object' &&
    !Array.isArray(replacer)
) {
    space = replacer.space;
    quote = replacer.quote;
    replacer = replacer.replacer;
}

if (typeof replacer === 'function') {
    replacerFunc = replacer;
} else if (Array.isArray(replacer)) {
    propertyList = [];
    for (const v of replacer) {
        let item;

        if (typeof v === 'string') {
            item = v;
        } else if (
            typeof v === 'number' ||
            v instanceof String ||
            v instanceof Number
        ) {
            item = String(v);
        }

        if (item !== undefined && propertyList.indexOf(item) < 0) {
            propertyList.push(item);
        }
    }
}

if (space instanceof Number) {
    space = Number(space);
} else if (space instanceof String) {
    space = String(space);
}

if (typeof space === 'number') {
    if (space > 0) {
        space = Math.min(10, Math.floor(space));
        gap = '          '.substr(0, space);
    }
} else if (typeof space === 'string') {
    gap = space.substr(0, 10);
}

return serializeProperty('', {'': value})

function serializeProperty (key, holder) {
    let value = holder[key];
    if (value != null) {
        if (typeof value.toJSON5 === 'function') {
            value = value.toJSON5(key);
        } else if (typeof value.toJSON === 'function') {
            value = value.toJSON(key);
        }
    }

    if (replacerFunc) {
        value = replacerFunc.call(holder, key, value);
    }

    if (value instanceof Number) {
        value = Number(value);
    } else if (value instanceof String) {
        value = String(value);
    } else if (value instanceof Boolean) {
        value = value.valueOf();
    }

    switch (value) {
    case null: return 'null'
    case true: return 'true'
    case false: return 'false'
    }

    if (typeof value === 'string') {
        return quoteString(value, false)
    }

    if (typeof value === 'number') {
        return String(value)
    }

    if (typeof value === 'object') {
        return Array.isArray(value) ? serializeArray(value) : serializeObject(value)
    }

    return undefined
}

function quoteString (value) {
    const quotes = {
        "'": 0.1,
        '"': 0.2,
    };

    const replacements = {
        "'": "\\'",
        '"': '\\"',
        '\\': '\\\\',
        '\b': '\\b',
        '\f': '\\f',
        '\n': '\\n',
        '\r': '\\r',
        '\t': '\\t',
        '\v': '\\v',
        '\0': '\\0',
        '\u2028': '\\u2028',
        '\u2029': '\\u2029',
    };

    let product = '';

    for (let i = 0; i < value.length; i++) {
        const c = value[i];
        switch (c) {
        case "'":
        case '"':
            quotes[c]++;
            product += c;
            continue

        case '\0':
            if (util.isDigit(value[i + 1])) {
                product += '\\x00';
                continue
            }
        }

        if (replacements[c]) {
            product += replacements[c];
            continue
        }

        if (c < ' ') {
            let hexString = c.charCodeAt(0).toString(16);
            product += '\\x' + ('00' + hexString).substring(hexString.length);
            continue
        }

        product += c;
    }

    const quoteChar = quote || Object.keys(quotes).reduce((a, b) => (quotes[a] < quotes[b]) ? a : b);

    product = product.replace(new RegExp(quoteChar, 'g'), replacements[quoteChar]);

    return quoteChar + product + quoteChar
}

function serializeObject (value) {
    if (stack.indexOf(value) >= 0) {
        throw TypeError('Converting circular structure to JSON5')
    }

    stack.push(value);

    let stepback = indent;
    indent = indent + gap;

    let keys = propertyList || Object.keys(value);
    let partial = [];
    for (const key of keys) {
        const propertyString = serializeProperty(key, value);
        if (propertyString !== undefined) {
            let member = serializeKey(key) + ':';
            if (gap !== '') {
                member += ' ';
            }
            member += propertyString;
            partial.push(member);
        }
    }

    let final;
    if (partial.length === 0) {
        final = '{}';
    } else {
        let properties;
        if (gap === '') {
            properties = partial.join(',');
            final = '{' + properties + '}';
        } else {
            let separator = ',\n' + indent;
            properties = partial.join(separator);
            final = '{\n' + indent + properties + ',\n' + stepback + '}';
        }
    }

    stack.pop();
    indent = stepback;
    return final
}

function serializeKey (key) {
    if (key.length === 0) {
        return quoteString(key, true)
    }

    const firstChar = String.fromCodePoint(key.codePointAt(0));
    if (!util.isIdStartChar(firstChar)) {
        return quoteString(key, true)
    }

    for (let i = firstChar.length; i < key.length; i++) {
        if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) {
            return quoteString(key, true)
        }
    }

    return key
}

function serializeArray (value) {
    if (stack.indexOf(value) >= 0) {
        throw TypeError('Converting circular structure to JSON5')
    }

    stack.push(value);

    let stepback = indent;
    indent = indent + gap;

    let partial = [];
    for (let i = 0; i < value.length; i++) {
        const propertyString = serializeProperty(String(i), value);
        partial.push((propertyString !== undefined) ? propertyString : 'null');
    }

    let final;
    if (partial.length === 0) {
        final = '[]';
    } else {
        if (gap === '') {
            let properties = partial.join(',');
            final = '[' + properties + ']';
        } else {
            let separator = ',\n' + indent;
            let properties = partial.join(separator);
            final = '[\n' + indent + properties + ',\n' + stepback + ']';
        }
    }

    stack.pop();
    indent = stepback;
    return final
}

};

const JSON5 = {

parse,
stringify,

};

var lib = JSON5;

export default lib;