text: // Generated by CoffeeScript 1.7.1
  var $, BOM, CLOSING_TAG, COMMENT, HEREDOC, HEREGEX, JSTOKEN, OPENING_TAG, PRAGMA, ParseTreeBranchNode, ParseTreeLeafNode, Parser, REGEX, SIMPLESTR, TAG_ATTRIBUTES, TRAILING_SPACES, WHITESPACE, compact, count, last, repeat, starts, throwSyntaxError, _ref;
  
  _ref = require('./helpers'), count = _ref.count, starts = _ref.starts, compact = _ref.compact, last = _ref.last, repeat = _ref.repeat, throwSyntaxError = _ref.throwSyntaxError;
  
  $ = require('./symbols');
  
  ParseTreeLeafNode = function(type, value) {
    if (value == null) {
      value = null;
    }
    return {
      type: type,
      value: value
    };
  };
  
  ParseTreeBranchNode = function(type, value, children) {
    if (value == null) {
      value = null;
    }
    if (children == null) {
      children = [];
    }
    return {
      type: type,
      value: value,
      children: children
    };
  };
  
  module.exports = Parser = (function() {
    function Parser() {}
  
    Parser.prototype.parse = function(code, opts) {
      var consumed, i, message, _ref1, _ref2;
      this.opts = opts != null ? opts : {};
      this.parseTree = ParseTreeBranchNode(this.opts.root || $.ROOT);
      this.activeStates = [this.parseTree];
      this.chunkLine = 0;
      this.chunkColumn = 0;
      this.cjsxPragmaChecked = false;
      code = this.clean(code);
      i = 0;
      while ((this.chunk = code.slice(i))) {
        if (this.activeStates.length === 0) {
          break;
        }
        consumed = ((_ref1 = this.currentState()) !== $.CJSX_EL && _ref1 !== $.CJSX_ATTRIBUTES ? this.csComment() || this.csHeredoc() || this.csString() || this.csRegex() || this.jsEscaped() : void 0) || this.cjsxStart() || this.cjsxAttribute() || this.cjsxEscape() || this.cjsxUnescape() || this.cjsxEnd() || this.cjsxText() || this.coffeescriptCode();
        _ref2 = this.getLineAndColumnFromChunk(consumed), this.chunkLine = _ref2[0], this.chunkColumn = _ref2[1];
        i += consumed;
      }
      if ((this.activeBranchNode() != null) && this.activeBranchNode() !== this.parseTree) {
        message = "Unexpected end of input: unclosed " + (this.currentState());
        throwSyntaxError(message, {
          first_line: this.chunkLine,
          first_column: this.chunkColumn
        });
      }
      this.remainder = code.slice(i);
      if (!this.opts.recursive) {
        if (this.remainder.length) {
          throwSyntaxError("Unexpected return from root state", {
            first_line: this.chunkLine,
            first_column: this.chunkColumn
          });
        }
      }
      return this.parseTree;
    };
  
    Parser.prototype.csComment = function() {
      var comment, here, match, pragmaMatch, prefix;
      if (!(match = this.chunk.match(COMMENT))) {
        return 0;
      }
      comment = match[0], here = match[1];
      if (!this.cjsxPragmaChecked) {
        this.cjsxPragmaChecked = true;
        if (pragmaMatch = comment.match(PRAGMA)) {
          if (pragmaMatch && pragmaMatch[1] && pragmaMatch[1].length) {
            prefix = pragmaMatch[1];
          } else {
            prefix = 'React.DOM';
          }
          this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_PRAGMA, prefix));
          return comment.length;
        }
      }
      this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_COMMENT, comment));
      return comment.length;
    };
  
    Parser.prototype.csHeredoc = function() {
      var heredoc, match;
      if (!(match = HEREDOC.exec(this.chunk))) {
        return 0;
      }
      heredoc = match[0];
      this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_HEREDOC, heredoc));
      return heredoc.length;
    };
  
    Parser.prototype.csString = function() {
      var quote, string;
      switch (quote = this.chunk.charAt(0)) {
        case "'":
          string = SIMPLESTR.exec(this.chunk)[0];
          break;
        case '"':
          string = this.balancedString(this.chunk, '"');
      }
      if (!string) {
        return 0;
      }
      this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_STRING, string));
      return string.length;
    };
  
    Parser.prototype.csRegex = function() {
      var flags, length, match, regex, _ref1;
      if (this.chunk.charAt(0) !== '/') {
        return 0;
      }
      if (length = this.csHeregex()) {
        return length;
      }
      if (!(match = REGEX.exec(this.chunk))) {
        return 0;
      }
      _ref1 = match, match = _ref1[0], regex = _ref1[1], flags = _ref1[2];
      if (regex.indexOf("\n") > -1) {
        return 0;
      }
      if (regex === '//') {
        return 0;
      }
      this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_REGEX, match));
      return match.length;
    };
  
    Parser.prototype.csHeregex = function() {
      var body, flags, heregex, match;
      if (!(match = HEREGEX.exec(this.chunk))) {
        return 0;
      }
      heregex = match[0], body = match[1], flags = match[2];
      this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS_HEREGEX, heregex));
      return heregex.length;
    };
  
    Parser.prototype.jsEscaped = function() {
      var match, script;
      if (!(this.chunk.charAt(0) === '`' && (match = JSTOKEN.exec(this.chunk)))) {
        return 0;
      }
      script = match[0];
      this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.JS_ESC, script));
      return script.length;
    };
  
    Parser.prototype.cjsxStart = function() {
      var attributesText, input, match, selfClosing, tagName;
      if (!(match = OPENING_TAG.exec(this.chunk))) {
        return 0;
      }
      input = match[0], tagName = match[1], attributesText = match[2], selfClosing = match[3];
      if (!(selfClosing || this.chunk.indexOf("</" + tagName + ">", input.length) > -1)) {
        return 0;
      }
      this.pushActiveBranchNode(ParseTreeBranchNode($.CJSX_EL, tagName));
      this.pushActiveBranchNode(ParseTreeBranchNode($.CJSX_ATTRIBUTES));
      return 1 + tagName.length;
    };
  
    Parser.prototype.cjsxAttribute = function() {
      var attrName, bareVal, cjsxEscVal, doubleQuotedVal, input, match, singleQuotedVal, spreadAttr, whitespace;
      if (this.currentState() !== $.CJSX_ATTRIBUTES) {
        return 0;
      }
      if (this.chunk.charAt(0) === '/') {
        if (this.chunk.charAt(1) === '>') {
          this.popActiveBranchNode();
          this.popActiveBranchNode();
          return 2;
        } else {
          throwSyntaxError("/ without immediately following > in CJSX tag " + (this.peekActiveState(2).value), {
            first_line: this.chunkLine,
            first_column: this.chunkColumn
          });
        }
      }
      if (this.chunk.charAt(0) === '>') {
        this.popActiveBranchNode();
        return 1;
      }
      if (!(match = TAG_ATTRIBUTES.exec(this.chunk))) {
        return 0;
      }
      input = match[0], attrName = match[1], doubleQuotedVal = match[2], singleQuotedVal = match[3], cjsxEscVal = match[4], bareVal = match[5], spreadAttr = match[6], whitespace = match[7];
      if (attrName) {
        if (doubleQuotedVal != null) {
          this.addLeafNodeToActiveBranch(ParseTreeBranchNode($.CJSX_ATTR_PAIR, null, [ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""), ParseTreeLeafNode($.CJSX_ATTR_VAL, "\"" + doubleQuotedVal + "\"")]));
          return input.length;
        } else if (singleQuotedVal != null) {
          this.addLeafNodeToActiveBranch(ParseTreeBranchNode($.CJSX_ATTR_PAIR, null, [ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""), ParseTreeLeafNode($.CJSX_ATTR_VAL, "'" + singleQuotedVal + "'")]));
          return input.length;
        } else if (cjsxEscVal) {
          this.pushActiveBranchNode(ParseTreeBranchNode($.CJSX_ATTR_PAIR));
          this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""));
          return input.indexOf('{');
        } else if (bareVal) {
          this.addLeafNodeToActiveBranch(ParseTreeBranchNode($.CJSX_ATTR_PAIR, null, [ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""), ParseTreeLeafNode($.CJSX_ATTR_VAL, bareVal)]));
          return input.length;
        } else {
          this.addLeafNodeToActiveBranch(ParseTreeBranchNode($.CJSX_ATTR_PAIR, null, [ParseTreeLeafNode($.CJSX_ATTR_KEY, "\"" + attrName + "\""), ParseTreeLeafNode($.CJSX_ATTR_VAL, 'true')]));
          return input.length;
        }
      } else if (spreadAttr) {
        this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_ATTR_SPREAD, spreadAttr));
        return input.length;
      } else if (whitespace != null) {
        this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_WHITESPACE, whitespace));
        return input.length;
      } else {
        return throwSyntaxError("Invalid attribute " + input + " in CJSX tag " + (this.peekActiveState(2).value), {
          first_line: this.chunkLine,
          first_column: this.chunkColumn
        });
      }
    };
  
    Parser.prototype.cjsxEscape = function() {
      var _ref1;
      if (!(this.chunk.charAt(0) === '{' && ((_ref1 = this.currentState()) === $.CJSX_EL || _ref1 === $.CJSX_ATTR_PAIR))) {
        return 0;
      }
      this.pushActiveBranchNode(ParseTreeBranchNode($.CJSX_ESC));
      this.activeBranchNode().stack = 1;
      return 1;
    };
  
    Parser.prototype.cjsxUnescape = function() {
      var _ref1;
      if (!(this.currentState() === $.CJSX_ESC && this.chunk.charAt(0) === '}')) {
        return 0;
      }
      if (this.activeBranchNode().stack === 0) {
        this.popActiveBranchNode();
        if ((_ref1 = this.currentState()) === $.CJSX_ATTR_PAIR) {
          this.popActiveBranchNode();
        }
        return 1;
      } else {
        return 0;
      }
    };
  
    Parser.prototype.cjsxEnd = function() {
      var input, match, tagName;
      if (this.currentState() !== $.CJSX_EL) {
        return 0;
      }
      if (!(match = CLOSING_TAG.exec(this.chunk))) {
        return 0;
      }
      input = match[0], tagName = match[1];
      if (tagName !== this.activeBranchNode().value) {
        throwSyntaxError("opening CJSX tag " + (this.activeBranchNode().value) + " doesn't match closing CJSX tag " + tagName, {
          first_line: this.chunkLine,
          first_column: this.chunkColumn
        });
      }
      this.popActiveBranchNode();
      return input.length;
    };
  
    Parser.prototype.cjsxText = function() {
      if (this.currentState() !== $.CJSX_EL) {
        return 0;
      }
      if (this.newestNode().type !== $.CJSX_TEXT) {
        this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CJSX_TEXT, ''));
      }
      this.newestNode().value += this.chunk.charAt(0);
      return 1;
    };
  
    Parser.prototype.coffeescriptCode = function() {
      if (this.currentState() === $.CJSX_ESC) {
        if (this.chunk.charAt(0) === '{') {
          this.activeBranchNode().stack++;
        } else if (this.chunk.charAt(0) === '}') {
          this.activeBranchNode().stack--;
          if (this.activeBranchNode().stack === 0) {
            return 0;
          }
        }
      }
      if (this.newestNode().type !== $.CS) {
        this.addLeafNodeToActiveBranch(ParseTreeLeafNode($.CS, ''));
      }
      this.newestNode().value += this.chunk.charAt(0);
      return 1;
    };
  
    Parser.prototype.activeBranchNode = function() {
      return last(this.activeStates);
    };
  
    Parser.prototype.peekActiveState = function(depth) {
      if (depth == null) {
        depth = 1;
      }
      return this.activeStates.slice(-depth)[0];
    };
  
    Parser.prototype.currentState = function() {
      return this.activeBranchNode().type;
    };
  
    Parser.prototype.newestNode = function() {
      return last(this.activeBranchNode().children) || this.activeBranchNode();
    };
  
    Parser.prototype.pushActiveBranchNode = function(node) {
      this.activeBranchNode().children.push(node);
      return this.activeStates.push(node);
    };
  
    Parser.prototype.popActiveBranchNode = function() {
      return this.activeStates.pop();
    };
  
    Parser.prototype.addLeafNodeToActiveBranch = function(node) {
      return this.activeBranchNode().children.push(node);
    };
  
    Parser.prototype.clean = function(code) {
      if (code.charCodeAt(0) === BOM) {
        code = code.slice(1);
      }
      code = code.replace(/\r/g, '');
      return code;
    };
  
    Parser.prototype.getLineAndColumnFromChunk = function(offset) {
      var column, lineCount, lines, string;
      if (offset === 0) {
        return [this.chunkLine, this.chunkColumn];
      }
      if (offset >= this.chunk.length) {
        string = this.chunk;
      } else {
        string = this.chunk.slice(0, +(offset - 1) + 1 || 9e9);
      }
      lineCount = count(string, '\n');
      column = this.chunkColumn;
      if (lineCount > 0) {
        lines = string.split('\n');
        column = last(lines).length;
      } else {
        column += string.length;
      }
      return [this.chunkLine + lineCount, column];
    };
  
    Parser.prototype.balancedString = function(str, end) {
      var continueCount, i, letter, match, prev, stack, _i, _ref1;
      continueCount = 0;
      stack = [end];
      for (i = _i = 1, _ref1 = str.length; 1 <= _ref1 ? _i < _ref1 : _i > _ref1; i = 1 <= _ref1 ? ++_i : --_i) {
        if (continueCount) {
          --continueCount;
          continue;
        }
        switch (letter = str.charAt(i)) {
          case '\\':
            ++continueCount;
            continue;
          case end:
            stack.pop();
            if (!stack.length) {
              return str.slice(0, +i + 1 || 9e9);
            }
            end = stack[stack.length - 1];
            continue;
        }
        if (end === '}' && (letter === '"' || letter === "'")) {
          stack.push(end = letter);
        } else if (end === '}' && letter === '/' && (match = HEREGEX.exec(str.slice(i)) || REGEX.exec(str.slice(i)))) {
          continueCount += match[0].length - 1;
        } else if (end === '}' && letter === '{') {
          stack.push(end = '}');
        } else if (end === '"' && prev === '#' && letter === '{') {
          stack.push(end = '}');
        }
        prev = letter;
      }
      return this.error("missing " + (stack.pop()) + ", starting");
    };
  
    return Parser;
  
  })();
  
  OPENING_TAG = /^<(@?[-A-Za-z0-9_\.]+)((?:(?:(?:\s+[\w-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:{[\s\S]*?})|[^>\s]+)))|\s+[\w-]+|\s+\{\.\.\.\s*?[^\s{}]+?\s*?\})?)*?\s*)(\/?)>/;
  
  CLOSING_TAG = /^<\/(@?[-A-Za-z0-9_\.]+)[^>]*>/;
  
  TAG_ATTRIBUTES = /(?:([-A-Za-z0-9_]+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|(?:{((?:\\.|[\s\S])*)})|([^>\s]+)))?)|(?:\{\.\.\.(\s*?[^\s{}]+?\s*?)\})|([\s\n]+)/;
  
  PRAGMA = /^\s*#\s*@cjsx\s+(\S*)/i;
  
  BOM = 65279;
  
  WHITESPACE = /^[^\n\S]+/;
  
  COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/;
  
  TRAILING_SPACES = /\s+$/;
  
  HEREDOC = /^("""|''')((?:\\[\s\S]|[^\\])*?)(?:\n[^\n\S]*)?\1/;
  
  SIMPLESTR = /^'[^\\']*(?:\\[\s\S][^\\']*)*'/;
  
  JSTOKEN = /^`[^\\`]*(?:\\.[^\\`]*)*`/;
  
  REGEX = /^(\/(?![\s=])[^[\/\n\\]*(?:(?:\\[\s\S]|\[[^\]\n\\]*(?:\\[\s\S][^\]\n\\]*)*])[^[\/\n\\]*)*\/)([imgy]{0,4})(?!\w)/;
  
  HEREGEX = /^\/{3}((?:\\?[\s\S])+?)\/{3}([imgy]{0,4})(?!\w)/;
  