ace.define("ace/mode/latex_highlight_rules", ["require", "exports", "module", "ace/lib/oop", "ace/mode/text_highlight_rules"], function (require, exports, module) {
  "use strict";

  var oop = require("../lib/oop");

  var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

  var LatexHighlightRules = function LatexHighlightRules() {
    this.$rules = {
      "start": [{
        token: "comment",
        regex: "%.*$"
      }, {
        token: ["keyword", "lparen", "variable.parameter", "rparen", "lparen", "storage.type", "rparen"],
        regex: "(\\\\(?:documentclass|usepackage|input))(?:(\\[)([^\\]]*)(\\]))?({)([^}]*)(})"
      }, {
        token: ["keyword", "lparen", "variable.parameter", "rparen"],
        regex: "(\\\\(?:label|v?ref|cite(?:[^{]*)))(?:({)([^}]*)(}))?"
      }, {
        token: ["storage.type", "lparen", "variable.parameter", "rparen"],
        regex: "(\\\\begin)({)(verbatim)(})",
        next: "verbatim"
      }, {
        token: ["storage.type", "lparen", "variable.parameter", "rparen"],
        regex: "(\\\\begin)({)(lstlisting)(})",
        next: "lstlisting"
      }, {
        token: ["storage.type", "lparen", "variable.parameter", "rparen"],
        regex: "(\\\\(?:begin|end))({)([\\w*]*)(})"
      }, {
        token: "storage.type",
        regex: /\\verb\b\*?/,
        next: [{
          token: ["keyword.operator", "string", "keyword.operator"],
          regex: "(.)(.*?)(\\1|$)|",
          next: "start"
        }]
      }, {
        token: "storage.type",
        regex: "\\\\[a-zA-Z]+"
      }, {
        token: "lparen",
        regex: "[[({]"
      }, {
        token: "rparen",
        regex: "[\\])}]"
      }, {
        token: "constant.character.escape",
        regex: "\\\\[^a-zA-Z]?"
      }, {
        token: "string",
        regex: "\\${1,2}",
        next: "equation"
      }],
      "equation": [{
        token: "comment",
        regex: "%.*$"
      }, {
        token: "string",
        regex: "\\${1,2}",
        next: "start"
      }, {
        token: "constant.character.escape",
        regex: "\\\\(?:[^a-zA-Z]|[a-zA-Z]+)"
      }, {
        token: "error",
        regex: "^\\s*$",
        next: "start"
      }, {
        defaultToken: "string"
      }],
      "verbatim": [{
        token: ["storage.type", "lparen", "variable.parameter", "rparen"],
        regex: "(\\\\end)({)(verbatim)(})",
        next: "start"
      }, {
        defaultToken: "text"
      }],
      "lstlisting": [{
        token: ["storage.type", "lparen", "variable.parameter", "rparen"],
        regex: "(\\\\end)({)(lstlisting)(})",
        next: "start"
      }, {
        defaultToken: "text"
      }]
    };
    this.normalizeRules();
  };

  oop.inherits(LatexHighlightRules, TextHighlightRules);
  exports.LatexHighlightRules = LatexHighlightRules;
});
ace.define("ace/mode/folding/latex", ["require", "exports", "module", "ace/lib/oop", "ace/mode/folding/fold_mode", "ace/range", "ace/token_iterator"], function (require, exports, module) {
  "use strict";

  var oop = require("../../lib/oop");

  var BaseFoldMode = require("./fold_mode").FoldMode;

  var Range = require("../../range").Range;

  var TokenIterator = require("../../token_iterator").TokenIterator;

  var keywordLevels = {
    "\\subparagraph": 1,
    "\\paragraph": 2,
    "\\subsubsubsection": 3,
    "\\subsubsection": 4,
    "\\subsection": 5,
    "\\section": 6,
    "\\chapter": 7,
    "\\part": 8,
    "\\begin": 9,
    "\\end": 10
  };

  var FoldMode = exports.FoldMode = function () {};

  oop.inherits(FoldMode, BaseFoldMode);
  (function () {
    this.foldingStartMarker = /^\s*\\(begin)|\s*\\(part|chapter|(?:sub)*(?:section|paragraph))\b|{\s*$/;
    this.foldingStopMarker = /^\s*\\(end)\b|^\s*}/;

    this.getFoldWidgetRange = function (session, foldStyle, row) {
      var line = session.doc.getLine(row);
      var match = this.foldingStartMarker.exec(line);

      if (match) {
        if (match[1]) return this.latexBlock(session, row, match[0].length - 1);
        if (match[2]) return this.latexSection(session, row, match[0].length - 1);
        return this.openingBracketBlock(session, "{", row, match.index);
      }

      var match = this.foldingStopMarker.exec(line);

      if (match) {
        if (match[1]) return this.latexBlock(session, row, match[0].length - 1);
        return this.closingBracketBlock(session, "}", row, match.index + match[0].length);
      }
    };

    this.latexBlock = function (session, row, column, returnRange) {
      var keywords = {
        "\\begin": 1,
        "\\end": -1
      };
      var stream = new TokenIterator(session, row, column);
      var token = stream.getCurrentToken();
      if (!token || !(token.type == "storage.type" || token.type == "constant.character.escape")) return;
      var val = token.value;
      var dir = keywords[val];

      var getType = function getType() {
        var token = stream.stepForward();
        var type = token.type == "lparen" ? stream.stepForward().value : "";

        if (dir === -1) {
          stream.stepBackward();
          if (type) stream.stepBackward();
        }

        return type;
      };

      var stack = [getType()];
      var startColumn = dir === -1 ? stream.getCurrentTokenColumn() : session.getLine(row).length;
      var startRow = row;
      stream.step = dir === -1 ? stream.stepBackward : stream.stepForward;

      while (token = stream.step()) {
        if (!token || !(token.type == "storage.type" || token.type == "constant.character.escape")) continue;
        var level = keywords[token.value];
        if (!level) continue;
        var type = getType();
        if (level === dir) stack.unshift(type);else if (stack.shift() !== type || !stack.length) break;
      }

      if (stack.length) return;

      if (dir == 1) {
        stream.stepBackward();
        stream.stepBackward();
      }

      if (returnRange) return stream.getCurrentTokenRange();
      var row = stream.getCurrentTokenRow();
      if (dir === -1) return new Range(row, session.getLine(row).length, startRow, startColumn);else return new Range(startRow, startColumn, row, stream.getCurrentTokenColumn());
    };

    this.latexSection = function (session, row, column) {
      var stream = new TokenIterator(session, row, column);
      var token = stream.getCurrentToken();
      if (!token || token.type != "storage.type") return;
      var startLevel = keywordLevels[token.value] || 0;
      var stackDepth = 0;
      var endRow = row;

      while (token = stream.stepForward()) {
        if (token.type !== "storage.type") continue;
        var level = keywordLevels[token.value] || 0;

        if (level >= 9) {
          if (!stackDepth) endRow = stream.getCurrentTokenRow() - 1;
          stackDepth += level == 9 ? 1 : -1;
          if (stackDepth < 0) break;
        } else if (level >= startLevel) break;
      }

      if (!stackDepth) endRow = stream.getCurrentTokenRow() - 1;

      while (endRow > row && !/\S/.test(session.getLine(endRow))) {
        endRow--;
      }

      return new Range(row, session.getLine(row).length, endRow, session.getLine(endRow).length);
    };
  }).call(FoldMode.prototype);
});
ace.define("ace/mode/latex", ["require", "exports", "module", "ace/lib/oop", "ace/mode/text", "ace/mode/latex_highlight_rules", "ace/mode/behaviour/cstyle", "ace/mode/folding/latex"], function (require, exports, module) {
  "use strict";

  var oop = require("../lib/oop");

  var TextMode = require("./text").Mode;

  var LatexHighlightRules = require("./latex_highlight_rules").LatexHighlightRules;

  var CstyleBehaviour = require("./behaviour/cstyle").CstyleBehaviour;

  var LatexFoldMode = require("./folding/latex").FoldMode;

  var Mode = function Mode() {
    this.HighlightRules = LatexHighlightRules;
    this.foldingRules = new LatexFoldMode();
    this.$behaviour = new CstyleBehaviour({
      braces: true
    });
  };

  oop.inherits(Mode, TextMode);
  (function () {
    this.type = "text";
    this.lineCommentStart = "%";
    this.$id = "ace/mode/latex";

    this.getMatching = function (session, row, column) {
      if (row == undefined) row = session.selection.lead;

      if (typeof row == "object") {
        column = row.column;
        row = row.row;
      }

      var startToken = session.getTokenAt(row, column);
      if (!startToken) return;

      if (startToken.value == "\\begin" || startToken.value == "\\end") {
        return this.foldingRules.latexBlock(session, row, column, true);
      }
    };
  }).call(Mode.prototype);
  exports.Mode = Mode;
});

(function () {
  ace.require(["ace/mode/latex"], function (m) {
    if (typeof module == "object" && typeof exports == "object" && module) {
      module.exports = m;
    }
  });
})();