(function (e) {
  if (typeof exports == 'object' && typeof module == 'object') e(require('../../lib/codemirror'));
  else if (typeof define == 'function' && define.amd) define(['../../lib/codemirror'], e);
  else e(CodeMirror);
})(function (e) {
  'use strict';
  e.defineMode('javascript', function (t, n) {
    function h(e) {
      var t = false,
        n,
        r = false;
      while ((n = e.next()) != null) {
        if (!t) {
          if (n == '/' && !r) return;
          if (n == '[') r = true;
          else if (r && n == ']') r = false;
        }
        t = !t && n == '\\';
      }
    }
    function v(e, t, n) {
      p = e;
      d = n;
      return t;
    }
    function m(e, t) {
      var n = e.next();
      if (n == '"' || n == "'") {
        t.tokenize = g(n);
        return t.tokenize(e, t);
      } else if (n == '.' && e.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
        return v('number', 'number');
      } else if (n == '.' && e.match('..')) {
        return v('spread', 'meta');
      } else if (/[\[\]{}\(\),;\:\.]/.test(n)) {
        return v(n);
      } else if (n == '=' && e.eat('>')) {
        return v('=>', 'operator');
      } else if (n == '0' && e.eat(/x/i)) {
        e.eatWhile(/[\da-f]/i);
        return v('number', 'number');
      } else if (/\d/.test(n)) {
        e.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
        return v('number', 'number');
      } else if (n == '/') {
        if (e.eat('*')) {
          t.tokenize = y;
          return y(e, t);
        } else if (e.eat('/')) {
          e.skipToEnd();
          return v('comment', 'comment');
        } else if (t.lastType == 'operator' || t.lastType == 'keyword c' || t.lastType == 'sof' || /^[\[{}\(,;:]$/.test(t.lastType)) {
          h(e);
          e.eatWhile(/[gimy]/);
          return v('regexp', 'string-2');
        } else {
          e.eatWhile(l);
          return v('operator', 'operator', e.current());
        }
      } else if (n == '`') {
        t.tokenize = b;
        return b(e, t);
      } else if (n == '#') {
        e.skipToEnd();
        return v('error', 'error');
      } else if (l.test(n)) {
        e.eatWhile(l);
        return v('operator', 'operator', e.current());
      } else if (a.test(n)) {
        e.eatWhile(a);
        var r = e.current(),
          i = f.propertyIsEnumerable(r) && f[r];
        return i && t.lastType != '.' ? v(i.type, i.style, r) : v('variable', 'variable', r);
      }
    }
    function g(e) {
      return function (t, n) {
        var r = false,
          i;
        if (s && t.peek() == '@' && t.match(c)) {
          n.tokenize = m;
          return v('jsonld-keyword', 'meta');
        }
        while ((i = t.next()) != null) {
          if (i == e && !r) break;
          r = !r && i == '\\';
        }
        if (!r) n.tokenize = m;
        return v('string', 'string');
      };
    }
    function y(e, t) {
      var n = false,
        r;
      while ((r = e.next())) {
        if (r == '/' && n) {
          t.tokenize = m;
          break;
        }
        n = r == '*';
      }
      return v('comment', 'comment');
    }
    function b(e, t) {
      var n = false,
        r;
      while ((r = e.next()) != null) {
        if (!n && (r == '`' || (r == '$' && e.eat('{')))) {
          t.tokenize = m;
          break;
        }
        n = !n && r == '\\';
      }
      return v('quasi', 'string-2', e.current());
    }
    function E(e, t) {
      if (t.fatArrowAt) t.fatArrowAt = null;
      var n = e.string.indexOf('=>', e.start);
      if (n < 0) return;
      var r = 0,
        i = false;
      for (var s = n - 1; s >= 0; --s) {
        var o = e.string.charAt(s);
        var u = w.indexOf(o);
        if (u >= 0 && u < 3) {
          if (!r) {
            ++s;
            break;
          }
          if (--r == 0) break;
        } else if (u >= 3 && u < 6) {
          ++r;
        } else if (a.test(o)) {
          i = true;
        } else if (/["'\/]/.test(o)) {
          return;
        } else if (i && !r) {
          ++s;
          break;
        }
      }
      if (i && !r) t.fatArrowAt = s;
    }
    function x(e, t, n, r, i, s) {
      this.indented = e;
      this.column = t;
      this.type = n;
      this.prev = i;
      this.info = s;
      if (r != null) this.align = r;
    }
    function T(e, t) {
      for (var n = e.localVars; n; n = n.next) if (n.name == t) return true;
      for (var r = e.context; r; r = r.prev) {
        for (var n = r.vars; n; n = n.next) if (n.name == t) return true;
      }
    }
    function N(e, t, n, r, i) {
      var s = e.cc;
      C.state = e;
      C.stream = i;
      ((C.marked = null), (C.cc = s));
      C.style = t;
      if (!e.lexical.hasOwnProperty('align')) e.lexical.align = true;
      while (true) {
        var u = s.length ? s.pop() : o ? j : B;
        if (u(n, r)) {
          while (s.length && s[s.length - 1].lex) s.pop()();
          if (C.marked) return C.marked;
          if (n == 'variable' && T(e, r)) return 'variable-2';
          return t;
        }
      }
    }
    function k() {
      for (var e = arguments.length - 1; e >= 0; e--) C.cc.push(arguments[e]);
    }
    function L() {
      k.apply(null, arguments);
      return true;
    }
    function A(e) {
      function t(t) {
        for (var n = t; n; n = n.next) if (n.name == e) return true;
        return false;
      }
      var r = C.state;
      if (r.context) {
        C.marked = 'def';
        if (t(r.localVars)) return;
        r.localVars = { name: e, next: r.localVars };
      } else {
        if (t(r.globalVars)) return;
        if (n.globalVars) r.globalVars = { name: e, next: r.globalVars };
      }
    }
    function M() {
      C.state.context = { prev: C.state.context, vars: C.state.localVars };
      C.state.localVars = O;
    }
    function _() {
      C.state.localVars = C.state.context.vars;
      C.state.context = C.state.context.prev;
    }
    function D(e, t) {
      var n = function () {
        var n = C.state,
          r = n.indented;
        if (n.lexical.type == 'stat') r = n.lexical.indented;
        else for (var i = n.lexical; i && i.type == ')' && i.align; i = i.prev) r = i.indented;
        n.lexical = new x(r, C.stream.column(), e, null, n.lexical, t);
      };
      n.lex = true;
      return n;
    }
    function P() {
      var e = C.state;
      if (e.lexical.prev) {
        if (e.lexical.type == ')') e.indented = e.lexical.indented;
        e.lexical = e.lexical.prev;
      }
    }
    function H(e) {
      function t(n) {
        if (n == e) return L();
        else if (e == ';') return k();
        else return L(t);
      }
      return t;
    }
    function B(e, t) {
      if (e == 'var') return L(D('vardef', t.length), it, H(';'), P);
      if (e == 'keyword a') return L(D('form'), j, B, P);
      if (e == 'keyword b') return L(D('form'), B, P);
      if (e == '{') return L(D('}'), tt, P);
      if (e == ';') return L();
      if (e == 'if') {
        if (C.state.lexical.info == 'else' && C.state.cc[C.state.cc.length - 1] == P) C.state.cc.pop()();
        return L(D('form'), j, B, P, ft);
      }
      if (e == 'function') return L(vt);
      if (e == 'for') return L(D('form'), lt, B, P);
      if (e == 'variable') return L(D('stat'), J);
      if (e == 'switch') return L(D('form'), j, D('}', 'switch'), H('{'), tt, P, P);
      if (e == 'case') return L(j, H(':'));
      if (e == 'default') return L(H(':'));
      if (e == 'catch') return L(D('form'), M, H('('), mt, H(')'), B, P, _);
      if (e == 'module') return L(D('form'), M, Et, _, P);
      if (e == 'class') return L(D('form'), gt, P);
      if (e == 'export') return L(D('form'), St, P);
      if (e == 'import') return L(D('form'), xt, P);
      return k(D('stat'), j, H(';'), P);
    }
    function j(e) {
      return I(e, false);
    }
    function F(e) {
      return I(e, true);
    }
    function I(e, t) {
      if (C.state.fatArrowAt == C.stream.start) {
        var n = t ? $ : V;
        if (e == '(') return L(M, D(')'), Z(st, ')'), P, H('=>'), n, _);
        else if (e == 'variable') return k(M, st, H('=>'), n, _);
      }
      var r = t ? z : U;
      if (S.hasOwnProperty(e)) return L(r);
      if (e == 'function') return L(vt, r);
      if (e == 'keyword c') return L(t ? R : q);
      if (e == '(') return L(D(')'), q, Lt, H(')'), P, r);
      if (e == 'operator' || e == 'spread') return L(t ? F : j);
      if (e == '[') return L(D(']'), Ct, P, r);
      if (e == '{') return et(Q, '}', null, r);
      if (e == 'quasi') {
        return k(W, r);
      }
      return L();
    }
    function q(e) {
      if (e.match(/[;\}\)\],]/)) return k();
      return k(j);
    }
    function R(e) {
      if (e.match(/[;\}\)\],]/)) return k();
      return k(F);
    }
    function U(e, t) {
      if (e == ',') return L(j);
      return z(e, t, false);
    }
    function z(e, t, n) {
      var r = n == false ? U : z;
      var i = n == false ? j : F;
      if (e == '=>') return L(M, n ? $ : V, _);
      if (e == 'operator') {
        if (/\+\+|--/.test(t)) return L(r);
        if (t == '?') return L(j, H(':'), i);
        return L(i);
      }
      if (e == 'quasi') {
        return k(W, r);
      }
      if (e == ';') return;
      if (e == '(') return et(F, ')', 'call', r);
      if (e == '.') return L(K, r);
      if (e == '[') return L(D(']'), q, H(']'), P, r);
    }
    function W(e, t) {
      if (e != 'quasi') return k();
      if (t.slice(t.length - 2) != '${') return L(W);
      return L(j, X);
    }
    function X(e) {
      if (e == '}') {
        C.marked = 'string-2';
        C.state.tokenize = b;
        return L(W);
      }
    }
    function V(e) {
      E(C.stream, C.state);
      return k(e == '{' ? B : j);
    }
    function $(e) {
      E(C.stream, C.state);
      return k(e == '{' ? B : F);
    }
    function J(e) {
      if (e == ':') return L(P, B);
      return k(U, H(';'), P);
    }
    function K(e) {
      if (e == 'variable') {
        C.marked = 'property';
        return L();
      }
    }
    function Q(e, t) {
      if (e == 'variable' || C.style == 'keyword') {
        C.marked = 'property';
        if (t == 'get' || t == 'set') return L(G);
        return L(Y);
      } else if (e == 'number' || e == 'string') {
        C.marked = s ? 'property' : C.style + ' property';
        return L(Y);
      } else if (e == 'jsonld-keyword') {
        return L(Y);
      } else if (e == '[') {
        return L(j, H(']'), Y);
      }
    }
    function G(e) {
      if (e != 'variable') return k(Y);
      C.marked = 'property';
      return L(vt);
    }
    function Y(e) {
      if (e == ':') return L(F);
      if (e == '(') return k(vt);
    }
    function Z(e, t) {
      function n(r) {
        if (r == ',') {
          var i = C.state.lexical;
          if (i.info == 'call') i.pos = (i.pos || 0) + 1;
          return L(e, n);
        }
        if (r == t) return L();
        return L(H(t));
      }
      return function (r) {
        if (r == t) return L();
        return k(e, n);
      };
    }
    function et(e, t, n) {
      for (var r = 3; r < arguments.length; r++) C.cc.push(arguments[r]);
      return L(D(t, n), Z(e, t), P);
    }
    function tt(e) {
      if (e == '}') return L();
      return k(B, tt);
    }
    function nt(e) {
      if (u && e == ':') return L(rt);
    }
    function rt(e) {
      if (e == 'variable') {
        C.marked = 'variable-3';
        return L();
      }
    }
    function it() {
      return k(st, nt, ut, at);
    }
    function st(e, t) {
      if (e == 'variable') {
        A(t);
        return L();
      }
      if (e == '[') return et(st, ']');
      if (e == '{') return et(ot, '}');
    }
    function ot(e, t) {
      if (e == 'variable' && !C.stream.match(/^\s*:/, false)) {
        A(t);
        return L(ut);
      }
      if (e == 'variable') C.marked = 'property';
      return L(H(':'), st, ut);
    }
    function ut(e, t) {
      if (t == '=') return L(F);
    }
    function at(e) {
      if (e == ',') return L(it);
    }
    function ft(e, t) {
      if (e == 'keyword b' && t == 'else') return L(D('form', 'else'), B, P);
    }
    function lt(e) {
      if (e == '(') return L(D(')'), ct, H(')'), P);
    }
    function ct(e) {
      if (e == 'var') return L(it, H(';'), pt);
      if (e == ';') return L(pt);
      if (e == 'variable') return L(ht);
      return k(j, H(';'), pt);
    }
    function ht(e, t) {
      if (t == 'in' || t == 'of') {
        C.marked = 'keyword';
        return L(j);
      }
      return L(U, pt);
    }
    function pt(e, t) {
      if (e == ';') return L(dt);
      if (t == 'in' || t == 'of') {
        C.marked = 'keyword';
        return L(j);
      }
      return k(j, H(';'), dt);
    }
    function dt(e) {
      if (e != ')') L(j);
    }
    function vt(e, t) {
      if (t == '*') {
        C.marked = 'keyword';
        return L(vt);
      }
      if (e == 'variable') {
        A(t);
        return L(vt);
      }
      if (e == '(') return L(M, D(')'), Z(mt, ')'), P, B, _);
    }
    function mt(e) {
      if (e == 'spread') return L(mt);
      return k(st, nt);
    }
    function gt(e, t) {
      if (e == 'variable') {
        A(t);
        return L(yt);
      }
    }
    function yt(e, t) {
      if (t == 'extends') return L(j, yt);
      if (e == '{') return L(D('}'), bt, P);
    }
    function bt(e, t) {
      if (e == 'variable' || C.style == 'keyword') {
        C.marked = 'property';
        if (t == 'get' || t == 'set') return L(wt, vt, bt);
        return L(vt, bt);
      }
      if (t == '*') {
        C.marked = 'keyword';
        return L(bt);
      }
      if (e == ';') return L(bt);
      if (e == '}') return L();
    }
    function wt(e) {
      if (e != 'variable') return k();
      C.marked = 'property';
      return L();
    }
    function Et(e, t) {
      if (e == 'string') return L(B);
      if (e == 'variable') {
        A(t);
        return L(Nt);
      }
    }
    function St(e, t) {
      if (t == '*') {
        C.marked = 'keyword';
        return L(Nt, H(';'));
      }
      if (t == 'default') {
        C.marked = 'keyword';
        return L(j, H(';'));
      }
      return k(B);
    }
    function xt(e) {
      if (e == 'string') return L();
      return k(Tt, Nt);
    }
    function Tt(e, t) {
      if (e == '{') return et(Tt, '}');
      if (e == 'variable') A(t);
      return L();
    }
    function Nt(e, t) {
      if (t == 'from') {
        C.marked = 'keyword';
        return L(j);
      }
    }
    function Ct(e) {
      if (e == ']') return L();
      return k(F, kt);
    }
    function kt(e) {
      if (e == 'for') return k(Lt, H(']'));
      if (e == ',') return L(Z(R, ']'));
      return k(Z(F, ']'));
    }
    function Lt(e) {
      if (e == 'for') return L(lt, Lt);
      if (e == 'if') return L(j, Lt);
    }
    var r = t.indentUnit;
    var i = n.statementIndent;
    var s = n.jsonld;
    var o = n.json || s;
    var u = n.typescript;
    var a = n.wordCharacters || /[\w$\xa1-\uffff]/;
    var f = (function () {
      function e(e) {
        return { type: e, style: 'keyword' };
      }
      var t = e('keyword a'),
        n = e('keyword b'),
        r = e('keyword c');
      var i = e('operator'),
        s = { type: 'atom', style: 'atom' };
      var o = {
        if: e('if'),
        while: t,
        with: t,
        else: n,
        do: n,
        try: n,
        finally: n,
        return: r,
        break: r,
        continue: r,
        new: r,
        delete: r,
        throw: r,
        debugger: r,
        var: e('var'),
        const: e('var'),
        let: e('var'),
        function: e('function'),
        catch: e('catch'),
        for: e('for'),
        switch: e('switch'),
        case: e('case'),
        default: e('default'),
        in: i,
        typeof: i,
        instanceof: i,
        true: s,
        false: s,
        null: s,
        undefined: s,
        NaN: s,
        Infinity: s,
        this: e('this'),
        module: e('module'),
        class: e('class'),
        super: e('atom'),
        yield: r,
        export: e('export'),
        import: e('import'),
        extends: r,
      };
      if (u) {
        var a = { type: 'variable', style: 'variable-3' };
        var f = { interface: e('interface'), extends: e('extends'), constructor: e('constructor'), public: e('public'), private: e('private'), protected: e('protected'), static: e('static'), string: a, number: a, bool: a, any: a };
        for (var l in f) {
          o[l] = f[l];
        }
      }
      return o;
    })();
    var l = /[+\-*&%=<>!?|~^]/;
    var c = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
    var p, d;
    var w = '([{}])';
    var S = { atom: true, number: true, variable: true, string: true, regexp: true, this: true, 'jsonld-keyword': true };
    var C = { state: null, column: null, marked: null, cc: null };
    var O = { name: 'this', next: { name: 'arguments' } };
    P.lex = true;
    return {
      startState: function (e) {
        var t = { tokenize: m, lastType: 'sof', cc: [], lexical: new x((e || 0) - r, 0, 'block', false), localVars: n.localVars, context: n.localVars && { vars: n.localVars }, indented: 0 };
        if (n.globalVars && typeof n.globalVars == 'object') t.globalVars = n.globalVars;
        return t;
      },
      token: function (e, t) {
        if (e.sol()) {
          if (!t.lexical.hasOwnProperty('align')) t.lexical.align = false;
          t.indented = e.indentation();
          E(e, t);
        }
        if (t.tokenize != y && e.eatSpace()) return null;
        var n = t.tokenize(e, t);
        if (p == 'comment') return n;
        t.lastType = p == 'operator' && (d == '++' || d == '--') ? 'incdec' : p;
        return N(t, n, p, d, e);
      },
      indent: function (t, s) {
        if (t.tokenize == y) return e.Pass;
        if (t.tokenize != m) return 0;
        var o = s && s.charAt(0),
          u = t.lexical;
        if (!/^\s*else\b/.test(s))
          for (var a = t.cc.length - 1; a >= 0; --a) {
            var f = t.cc[a];
            if (f == P) u = u.prev;
            else if (f != ft) break;
          }
        if (u.type == 'stat' && o == '}') u = u.prev;
        if (i && u.type == ')' && u.prev.type == 'stat') u = u.prev;
        var l = u.type,
          c = o == l;
        if (l == 'vardef') return u.indented + (t.lastType == 'operator' || t.lastType == ',' ? u.info + 1 : 0);
        else if (l == 'form' && o == '{') return u.indented;
        else if (l == 'form') return u.indented + r;
        else if (l == 'stat') return u.indented + (t.lastType == 'operator' || t.lastType == ',' ? i || r : 0);
        else if (u.info == 'switch' && !c && n.doubleIndentSwitch != false) return u.indented + (/^(?:case|default)\b/.test(s) ? r : 2 * r);
        else if (u.align) return u.column + (c ? 0 : 1);
        else return u.indented + (c ? 0 : r);
      },
      electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
      blockCommentStart: o ? null : '/*',
      blockCommentEnd: o ? null : '*/',
      lineComment: o ? null : '//',
      fold: 'brace',
      helperType: o ? 'json' : 'javascript',
      jsonldMode: s,
      jsonMode: o,
    };
  });
  e.registerHelper('wordChars', 'javascript', /[\w$]/);
  e.defineMIME('text/javascript', 'javascript');
  e.defineMIME('text/ecmascript', 'javascript');
  e.defineMIME('application/javascript', 'javascript');
  e.defineMIME('application/x-javascript', 'javascript');
  e.defineMIME('application/ecmascript', 'javascript');
  e.defineMIME('application/json', { name: 'javascript', json: true });
  e.defineMIME('application/x-json', { name: 'javascript', json: true });
  e.defineMIME('application/ld+json', { name: 'javascript', jsonld: true });
  e.defineMIME('text/typescript', { name: 'javascript', typescript: true });
  e.defineMIME('application/typescript', { name: 'javascript', typescript: true });
});
