text: /*
   *	MySQL Mode for CodeMirror 2 by MySQL-Tools
   *	@author James Thorne (partydroid)
   *	@link 	http://github.com/partydroid/MySQL-Tools
   * 	@link 	http://mysqltools.org
   *	@version 02/Jan/2012
   */
  CodeMirror.defineMode("mysql", function (config) {
    var indentUnit = config.indentUnit;
    var curPunc;
  
    function wordRegexp(words) {
      return new RegExp("^(?:" + words.join("|") + ")$", "i");
    }
    var ops = wordRegexp([
      "str",
      "lang",
      "langmatches",
      "datatype",
      "bound",
      "sameterm",
      "isiri",
      "isuri",
      "isblank",
      "isliteral",
      "union",
      "a",
    ]);
    var keywords = wordRegexp([
      "ACCESSIBLE",
      "ALTER",
      "AS",
      "BEFORE",
      "BINARY",
      "BY",
      "CASE",
      "CHARACTER",
      "COLUMN",
      "CONTINUE",
      "CROSS",
      "CURRENT_TIMESTAMP",
      "DATABASE",
      "DAY_MICROSECOND",
      "DEC",
      "DEFAULT",
      "DESC",
      "DISTINCT",
      "DOUBLE",
      "EACH",
      "ENCLOSED",
      "EXIT",
      "FETCH",
      "FLOAT8",
      "FOREIGN",
      "GRANT",
      "HIGH_PRIORITY",
      "HOUR_SECOND",
      "IN",
      "INNER",
      "INSERT",
      "INT2",
      "INT8",
      "INTO",
      "JOIN",
      "KILL",
      "LEFT",
      "LINEAR",
      "LOCALTIME",
      "LONG",
      "LOOP",
      "MATCH",
      "MEDIUMTEXT",
      "MINUTE_SECOND",
      "NATURAL",
      "NULL",
      "OPTIMIZE",
      "OR",
      "OUTER",
      "PRIMARY",
      "RANGE",
      "READ_WRITE",
      "REGEXP",
      "REPEAT",
      "RESTRICT",
      "RIGHT",
      "SCHEMAS",
      "SENSITIVE",
      "SHOW",
      "SPECIFIC",
      "SQLSTATE",
      "SQL_CALC_FOUND_ROWS",
      "STARTING",
      "TERMINATED",
      "TINYINT",
      "TRAILING",
      "UNDO",
      "UNLOCK",
      "USAGE",
      "UTC_DATE",
      "VALUES",
      "VARCHARACTER",
      "WHERE",
      "WRITE",
      "ZEROFILL",
      "ALL",
      "AND",
      "ASENSITIVE",
      "BIGINT",
      "BOTH",
      "CASCADE",
      "CHAR",
      "COLLATE",
      "CONSTRAINT",
      "CREATE",
      "CURRENT_TIME",
      "CURSOR",
      "DAY_HOUR",
      "DAY_SECOND",
      "DECLARE",
      "DELETE",
      "DETERMINISTIC",
      "DIV",
      "DUAL",
      "ELSEIF",
      "EXISTS",
      "FALSE",
      "FLOAT4",
      "FORCE",
      "FULLTEXT",
      "HAVING",
      "HOUR_MINUTE",
      "IGNORE",
      "INFILE",
      "INSENSITIVE",
      "INT1",
      "INT4",
      "INTERVAL",
      "ITERATE",
      "KEYS",
      "LEAVE",
      "LIMIT",
      "LOAD",
      "LOCK",
      "LONGTEXT",
      "MASTER_SSL_VERIFY_SERVER_CERT",
      "MEDIUMINT",
      "MINUTE_MICROSECOND",
      "MODIFIES",
      "NO_WRITE_TO_BINLOG",
      "ON",
      "OPTIONALLY",
      "OUT",
      "PRECISION",
      "PURGE",
      "READS",
      "REFERENCES",
      "RENAME",
      "REQUIRE",
      "REVOKE",
      "SCHEMA",
      "SELECT",
      "SET",
      "SPATIAL",
      "SQLEXCEPTION",
      "SQL_BIG_RESULT",
      "SSL",
      "TABLE",
      "TINYBLOB",
      "TO",
      "TRUE",
      "UNIQUE",
      "UPDATE",
      "USING",
      "UTC_TIMESTAMP",
      "VARCHAR",
      "WHEN",
      "WITH",
      "YEAR_MONTH",
      "ADD",
      "ANALYZE",
      "ASC",
      "BETWEEN",
      "BLOB",
      "CALL",
      "CHANGE",
      "CHECK",
      "CONDITION",
      "CONVERT",
      "CURRENT_DATE",
      "CURRENT_USER",
      "DATABASES",
      "DAY_MINUTE",
      "DECIMAL",
      "DELAYED",
      "DESCRIBE",
      "DISTINCTROW",
      "DROP",
      "ELSE",
      "ESCAPED",
      "EXPLAIN",
      "FLOAT",
      "FOR",
      "FROM",
      "GROUP",
      "HOUR_MICROSECOND",
      "IF",
      "INDEX",
      "INOUT",
      "INT",
      "INT3",
      "INTEGER",
      "IS",
      "KEY",
      "LEADING",
      "LIKE",
      "LINES",
      "LOCALTIMESTAMP",
      "LONGBLOB",
      "LOW_PRIORITY",
      "MEDIUMBLOB",
      "MIDDLEINT",
      "MOD",
      "NOT",
      "NUMERIC",
      "OPTION",
      "ORDER",
      "OUTFILE",
      "PROCEDURE",
      "READ",
      "REAL",
      "RELEASE",
      "REPLACE",
      "RETURN",
      "RLIKE",
      "SECOND_MICROSECOND",
      "SEPARATOR",
      "SMALLINT",
      "SQL",
      "SQLWARNING",
      "SQL_SMALL_RESULT",
      "STRAIGHT_JOIN",
      "THEN",
      "TINYTEXT",
      "TRIGGER",
      "UNION",
      "UNSIGNED",
      "USE",
      "UTC_TIME",
      "VARBINARY",
      "VARYING",
      "WHILE",
      "XOR",
      "FULL",
      "COLUMNS",
      "MIN",
      "MAX",
      "STDEV",
      "COUNT",
    ]);
    var operatorChars = /[*+\-<>=&|]/;
  
    function tokenBase(stream, state) {
      var ch = stream.next();
      curPunc = null;
      if (ch == "$" || ch == "?") {
        stream.match(/^[\w\d]*/);
        return "variable-2";
      } else if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) {
        stream.match(/^[^\s\u00a0>]*>?/);
        return "atom";
      } else if (ch == '"' || ch == "'") {
        state.tokenize = tokenLiteral(ch);
        return state.tokenize(stream, state);
      } else if (ch == "`") {
        state.tokenize = tokenOpLiteral(ch);
        return state.tokenize(stream, state);
      } else if (/[{}\(\),\.;\[\]]/.test(ch)) {
        curPunc = ch;
        return null;
      } else if (ch == "-") {
        ch2 = stream.next();
        if (ch2 == "-") {
          stream.skipToEnd();
          return "comment";
        }
      } else if (operatorChars.test(ch)) {
        stream.eatWhile(operatorChars);
        return null;
      } else if (ch == ":") {
        stream.eatWhile(/[\w\d\._\-]/);
        return "atom";
      } else {
        stream.eatWhile(/[_\w\d]/);
        if (stream.eat(":")) {
          stream.eatWhile(/[\w\d_\-]/);
          return "atom";
        }
        var word = stream.current(),
          type;
        if (ops.test(word)) return null;
        else if (keywords.test(word)) return "keyword";
        else return "variable";
      }
    }
  
    function tokenLiteral(quote) {
      return function (stream, state) {
        var escaped = false,
          ch;
        while ((ch = stream.next()) != null) {
          if (ch == quote && !escaped) {
            state.tokenize = tokenBase;
            break;
          }
          escaped = !escaped && ch == "\\";
        }
        return "string";
      };
    }
  
    function tokenOpLiteral(quote) {
      return function (stream, state) {
        var escaped = false,
          ch;
        while ((ch = stream.next()) != null) {
          if (ch == quote && !escaped) {
            state.tokenize = tokenBase;
            break;
          }
          escaped = !escaped && ch == "\\";
        }
        return "variable-2";
      };
    }
  
    function pushContext(state, type, col) {
      state.context = {
        prev: state.context,
        indent: state.indent,
        col: col,
        type: type,
      };
    }
    function popContext(state) {
      state.indent = state.context.indent;
      state.context = state.context.prev;
    }
  
    return {
      startState: function (base) {
        return { tokenize: tokenBase, context: null, indent: 0, col: 0 };
      },
  
      token: function (stream, state) {
        if (stream.sol()) {
          if (state.context && state.context.align == null)
            state.context.align = false;
          state.indent = stream.indentation();
        }
        if (stream.eatSpace()) return null;
        var style = state.tokenize(stream, state);
  
        if (
          style != "comment" &&
          state.context &&
          state.context.align == null &&
          state.context.type != "pattern"
        ) {
          state.context.align = true;
        }
  
        if (curPunc == "(") pushContext(state, ")", stream.column());
        else if (curPunc == "[") pushContext(state, "]", stream.column());
        else if (curPunc == "{") pushContext(state, "}", stream.column());
        else if (/[\]\}\)]/.test(curPunc)) {
          while (state.context && state.context.type == "pattern")
            popContext(state);
          if (state.context && curPunc == state.context.type) popContext(state);
        } else if (
          curPunc == "." &&
          state.context &&
          state.context.type == "pattern"
        )
          popContext(state);
        else if (/atom|string|variable/.test(style) && state.context) {
          if (/[\}\]]/.test(state.context.type))
            pushContext(state, "pattern", stream.column());
          else if (state.context.type == "pattern" && !state.context.align) {
            state.context.align = true;
            state.context.col = stream.column();
          }
        }
  
        return style;
      },
  
      indent: function (state, textAfter) {
        var firstChar = textAfter && textAfter.charAt(0);
        var context = state.context;
        if (/[\]\}]/.test(firstChar))
          while (context && context.type == "pattern") context = context.prev;
  
        var closing = context && firstChar == context.type;
        if (!context) return 0;
        else if (context.type == "pattern") return context.col;
        else if (context.align) return context.col + (closing ? 0 : 1);
        else return context.indent + (closing ? 0 : indentUnit);
      },
    };
  });
  
  CodeMirror.defineMIME("text/x-mysql", "mysql");
  