text: /**
   * Copyright (c) 2011 Jeremy Ashkenas
   *
   * Permission is hereby granted, free of charge, to any person
   * obtaining a copy of this software and associated documentation
   * files (the "Software"), to deal in the Software without
   * restriction, including without limitation the rights to use,
   * copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the
   * Software is furnished to do so, subject to the following
   * conditions:
   *
   * The above copyright notice and this permission notice shall be
   * included in all copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
   * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
   * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
   * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   * OTHER DEALINGS IN THE SOFTWARE.
   */
  
  define(function (require, exports, module) {
    // Generated by CoffeeScript 1.2.1-pre
  
    var BALANCED_PAIRS,
      EXPRESSION_CLOSE,
      EXPRESSION_END,
      EXPRESSION_START,
      IMPLICIT_BLOCK,
      IMPLICIT_CALL,
      IMPLICIT_END,
      IMPLICIT_FUNC,
      IMPLICIT_UNSPACED_CALL,
      INVERSES,
      LINEBREAKS,
      SINGLE_CLOSERS,
      SINGLE_LINERS,
      left,
      rite,
      _i,
      _len,
      _ref,
      __indexOf =
        [].indexOf ||
        function (item) {
          for (var i = 0, l = this.length; i < l; i++) {
            if (i in this && this[i] === item) return i;
          }
          return -1;
        },
      __slice = [].slice;
  
    exports.Rewriter = (function () {
      Rewriter.name = "Rewriter";
  
      function Rewriter() {}
  
      Rewriter.prototype.rewrite = function (tokens) {
        this.tokens = tokens;
        this.removeLeadingNewlines();
        this.removeMidExpressionNewlines();
        this.closeOpenCalls();
        this.closeOpenIndexes();
        this.addImplicitIndentation();
        this.tagPostfixConditionals();
        this.addImplicitBraces();
        this.addImplicitParentheses();
        return this.tokens;
      };
  
      Rewriter.prototype.scanTokens = function (block) {
        var i, token, tokens;
        tokens = this.tokens;
        i = 0;
        while ((token = tokens[i])) {
          i += block.call(this, token, i, tokens);
        }
        return true;
      };
  
      Rewriter.prototype.detectEnd = function (i, condition, action) {
        var levels, token, tokens, _ref, _ref1;
        tokens = this.tokens;
        levels = 0;
        while ((token = tokens[i])) {
          if (levels === 0 && condition.call(this, token, i)) {
            return action.call(this, token, i);
          }
          if (!token || levels < 0) return action.call(this, token, i - 1);
          if (((_ref = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0)) {
            levels += 1;
          } else if (
            ((_ref1 = token[0]), __indexOf.call(EXPRESSION_END, _ref1) >= 0)
          ) {
            levels -= 1;
          }
          i += 1;
        }
        return i - 1;
      };
  
      Rewriter.prototype.removeLeadingNewlines = function () {
        var i, tag, _i, _len, _ref;
        _ref = this.tokens;
        for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {
          tag = _ref[i][0];
          if (tag !== "TERMINATOR") break;
        }
        if (i) return this.tokens.splice(0, i);
      };
  
      Rewriter.prototype.removeMidExpressionNewlines = function () {
        return this.scanTokens(function (token, i, tokens) {
          var _ref;
          if (
            !(
              token[0] === "TERMINATOR" &&
              ((_ref = this.tag(i + 1)),
              __indexOf.call(EXPRESSION_CLOSE, _ref) >= 0)
            )
          ) {
            return 1;
          }
          tokens.splice(i, 1);
          return 0;
        });
      };
  
      Rewriter.prototype.closeOpenCalls = function () {
        var action, condition;
        condition = function (token, i) {
          var _ref;
          return (
            (_ref = token[0]) === ")" ||
            _ref === "CALL_END" ||
            (token[0] === "OUTDENT" && this.tag(i - 1) === ")")
          );
        };
        action = function (token, i) {
          return (this.tokens[token[0] === "OUTDENT" ? i - 1 : i][0] =
            "CALL_END");
        };
        return this.scanTokens(function (token, i) {
          if (token[0] === "CALL_START") this.detectEnd(i + 1, condition, action);
          return 1;
        });
      };
  
      Rewriter.prototype.closeOpenIndexes = function () {
        var action, condition;
        condition = function (token, i) {
          var _ref;
          return (_ref = token[0]) === "]" || _ref === "INDEX_END";
        };
        action = function (token, i) {
          return (token[0] = "INDEX_END");
        };
        return this.scanTokens(function (token, i) {
          if (token[0] === "INDEX_START")
            this.detectEnd(i + 1, condition, action);
          return 1;
        });
      };
  
      Rewriter.prototype.addImplicitBraces = function () {
        var action, condition, sameLine, stack, start, startIndent, startsLine;
        stack = [];
        start = null;
        startsLine = null;
        sameLine = true;
        startIndent = 0;
        condition = function (token, i) {
          var one, tag, three, two, _ref, _ref1;
          (_ref = this.tokens.slice(i + 1, i + 3 + 1 || 9e9)),
            (one = _ref[0]),
            (two = _ref[1]),
            (three = _ref[2]);
          if ("HERECOMMENT" === (one != null ? one[0] : void 0)) return false;
          tag = token[0];
          if (__indexOf.call(LINEBREAKS, tag) >= 0) sameLine = false;
          return (
            ((tag === "TERMINATOR" ||
              tag === "OUTDENT" ||
              (__indexOf.call(IMPLICIT_END, tag) >= 0 && sameLine)) &&
              ((!startsLine && this.tag(i - 1) !== ",") ||
                !(
                  (two != null ? two[0] : void 0) === ":" ||
                  ((one != null ? one[0] : void 0) === "@" &&
                    (three != null ? three[0] : void 0) === ":")
                ))) ||
            (tag === "," &&
              one &&
              (_ref1 = one[0]) !== "IDENTIFIER" &&
              _ref1 !== "NUMBER" &&
              _ref1 !== "STRING" &&
              _ref1 !== "@" &&
              _ref1 !== "TERMINATOR" &&
              _ref1 !== "OUTDENT")
          );
        };
        action = function (token, i) {
          var tok;
          tok = this.generate("}", "}", token[2]);
          return this.tokens.splice(i, 0, tok);
        };
        return this.scanTokens(function (token, i, tokens) {
          var ago, idx, prevTag, tag, tok, value, _ref, _ref1;
          if (
            ((_ref = tag = token[0]), __indexOf.call(EXPRESSION_START, _ref) >= 0)
          ) {
            stack.push([
              tag === "INDENT" && this.tag(i - 1) === "{" ? "{" : tag,
              i,
            ]);
            return 1;
          }
          if (__indexOf.call(EXPRESSION_END, tag) >= 0) {
            start = stack.pop();
            return 1;
          }
          if (
            !(
              tag === ":" &&
              ((ago = this.tag(i - 2)) === ":" ||
                ((_ref1 = stack[stack.length - 1]) != null
                  ? _ref1[0]
                  : void 0) !== "{")
            )
          ) {
            return 1;
          }
          sameLine = true;
          stack.push(["{"]);
          idx = ago === "@" ? i - 2 : i - 1;
          while (this.tag(idx - 2) === "HERECOMMENT") {
            idx -= 2;
          }
          prevTag = this.tag(idx - 1);
          startsLine = !prevTag || __indexOf.call(LINEBREAKS, prevTag) >= 0;
          value = new String("{");
          value.generated = true;
          tok = this.generate("{", value, token[2]);
          tokens.splice(idx, 0, tok);
          this.detectEnd(i + 2, condition, action);
          return 2;
        });
      };
  
      Rewriter.prototype.addImplicitParentheses = function () {
        var action, condition, noCall, seenControl, seenSingle;
        noCall = seenSingle = seenControl = false;
        condition = function (token, i) {
          var post, tag, _ref, _ref1;
          tag = token[0];
          if (!seenSingle && token.fromThen) return true;
          if (
            tag === "IF" ||
            tag === "ELSE" ||
            tag === "CATCH" ||
            tag === "->" ||
            tag === "=>" ||
            tag === "CLASS"
          ) {
            seenSingle = true;
          }
          if (
            tag === "IF" ||
            tag === "ELSE" ||
            tag === "SWITCH" ||
            tag === "TRY" ||
            tag === "="
          ) {
            seenControl = true;
          }
          if (
            (tag === "." || tag === "?." || tag === "::") &&
            this.tag(i - 1) === "OUTDENT"
          ) {
            return true;
          }
          return (
            !token.generated &&
            this.tag(i - 1) !== "," &&
            (__indexOf.call(IMPLICIT_END, tag) >= 0 ||
              (tag === "INDENT" && !seenControl)) &&
            (tag !== "INDENT" ||
              ((_ref = this.tag(i - 2)) !== "CLASS" &&
                _ref !== "EXTENDS" &&
                ((_ref1 = this.tag(i - 1)),
                __indexOf.call(IMPLICIT_BLOCK, _ref1) < 0) &&
                !(
                  (post = this.tokens[i + 1]) &&
                  post.generated &&
                  post[0] === "{"
                )))
          );
        };
        action = function (token, i) {
          return this.tokens.splice(
            i,
            0,
            this.generate("CALL_END", ")", token[2])
          );
        };
        return this.scanTokens(function (token, i, tokens) {
          var callObject, current, next, prev, tag, _ref, _ref1, _ref2;
          tag = token[0];
          if (
            tag === "CLASS" ||
            tag === "IF" ||
            tag === "FOR" ||
            tag === "WHILE"
          ) {
            noCall = true;
          }
          (_ref = tokens.slice(i - 1, i + 1 + 1 || 9e9)),
            (prev = _ref[0]),
            (current = _ref[1]),
            (next = _ref[2]);
          callObject =
            !noCall &&
            tag === "INDENT" &&
            next &&
            next.generated &&
            next[0] === "{" &&
            prev &&
            ((_ref1 = prev[0]), __indexOf.call(IMPLICIT_FUNC, _ref1) >= 0);
          seenSingle = false;
          seenControl = false;
          if (__indexOf.call(LINEBREAKS, tag) >= 0) noCall = false;
          if (prev && !prev.spaced && tag === "?") token.call = true;
          if (token.fromThen) return 1;
          if (
            !(
              callObject ||
              ((prev != null ? prev.spaced : void 0) &&
                (prev.call ||
                  ((_ref2 = prev[0]),
                  __indexOf.call(IMPLICIT_FUNC, _ref2) >= 0)) &&
                (__indexOf.call(IMPLICIT_CALL, tag) >= 0 ||
                  (!(token.spaced || token.newLine) &&
                    __indexOf.call(IMPLICIT_UNSPACED_CALL, tag) >= 0)))
            )
          ) {
            return 1;
          }
          tokens.splice(i, 0, this.generate("CALL_START", "(", token[2]));
          this.detectEnd(i + 1, condition, action);
          if (prev[0] === "?") prev[0] = "FUNC_EXIST";
          return 2;
        });
      };
  
      Rewriter.prototype.addImplicitIndentation = function () {
        var action, condition, indent, outdent, starter;
        starter = indent = outdent = null;
        condition = function (token, i) {
          var _ref;
          return (
            token[1] !== ";" &&
            ((_ref = token[0]), __indexOf.call(SINGLE_CLOSERS, _ref) >= 0) &&
            !(token[0] === "ELSE" && starter !== "IF" && starter !== "THEN")
          );
        };
        action = function (token, i) {
          return this.tokens.splice(
            this.tag(i - 1) === "," ? i - 1 : i,
            0,
            outdent
          );
        };
        return this.scanTokens(function (token, i, tokens) {
          var tag, _ref, _ref1;
          tag = token[0];
          if (tag === "TERMINATOR" && this.tag(i + 1) === "THEN") {
            tokens.splice(i, 1);
            return 0;
          }
          if (tag === "ELSE" && this.tag(i - 1) !== "OUTDENT") {
            tokens.splice.apply(
              tokens,
              [i, 0].concat(__slice.call(this.indentation(token)))
            );
            return 2;
          }
          if (
            tag === "CATCH" &&
            ((_ref = this.tag(i + 2)) === "OUTDENT" ||
              _ref === "TERMINATOR" ||
              _ref === "FINALLY")
          ) {
            tokens.splice.apply(
              tokens,
              [i + 2, 0].concat(__slice.call(this.indentation(token)))
            );
            return 4;
          }
          if (
            __indexOf.call(SINGLE_LINERS, tag) >= 0 &&
            this.tag(i + 1) !== "INDENT" &&
            !(tag === "ELSE" && this.tag(i + 1) === "IF")
          ) {
            starter = tag;
            (_ref1 = this.indentation(token, true)),
              (indent = _ref1[0]),
              (outdent = _ref1[1]);
            if (starter === "THEN") indent.fromThen = true;
            tokens.splice(i + 1, 0, indent);
            this.detectEnd(i + 2, condition, action);
            if (tag === "THEN") tokens.splice(i, 1);
            return 1;
          }
          return 1;
        });
      };
  
      Rewriter.prototype.tagPostfixConditionals = function () {
        var action, condition, original;
        original = null;
        condition = function (token, i) {
          var _ref;
          return (_ref = token[0]) === "TERMINATOR" || _ref === "INDENT";
        };
        action = function (token, i) {
          if (token[0] !== "INDENT" || (token.generated && !token.fromThen)) {
            return (original[0] = "POST_" + original[0]);
          }
        };
        return this.scanTokens(function (token, i) {
          if (token[0] !== "IF") return 1;
          original = token;
          this.detectEnd(i + 1, condition, action);
          return 1;
        });
      };
  
      Rewriter.prototype.indentation = function (token, implicit) {
        var indent, outdent;
        if (implicit == null) implicit = false;
        indent = ["INDENT", 2, token[2]];
        outdent = ["OUTDENT", 2, token[2]];
        if (implicit) indent.generated = outdent.generated = true;
        return [indent, outdent];
      };
  
      Rewriter.prototype.generate = function (tag, value, line) {
        var tok;
        tok = [tag, value, line];
        tok.generated = true;
        return tok;
      };
  
      Rewriter.prototype.tag = function (i) {
        var _ref;
        return (_ref = this.tokens[i]) != null ? _ref[0] : void 0;
      };
  
      return Rewriter;
    })();
  
    BALANCED_PAIRS = [
      ["(", ")"],
      ["[", "]"],
      ["{", "}"],
      ["INDENT", "OUTDENT"],
      ["CALL_START", "CALL_END"],
      ["PARAM_START", "PARAM_END"],
      ["INDEX_START", "INDEX_END"],
    ];
  
    exports.INVERSES = INVERSES = {};
  
    EXPRESSION_START = [];
  
    EXPRESSION_END = [];
  
    for (_i = 0, _len = BALANCED_PAIRS.length; _i < _len; _i++) {
      (_ref = BALANCED_PAIRS[_i]), (left = _ref[0]), (rite = _ref[1]);
      EXPRESSION_START.push((INVERSES[rite] = left));
      EXPRESSION_END.push((INVERSES[left] = rite));
    }
  
    EXPRESSION_CLOSE = ["CATCH", "WHEN", "ELSE", "FINALLY"].concat(
      EXPRESSION_END
    );
  
    IMPLICIT_FUNC = [
      "IDENTIFIER",
      "SUPER",
      ")",
      "CALL_END",
      "]",
      "INDEX_END",
      "@",
      "THIS",
    ];
  
    IMPLICIT_CALL = [
      "IDENTIFIER",
      "NUMBER",
      "STRING",
      "JS",
      "REGEX",
      "NEW",
      "PARAM_START",
      "CLASS",
      "IF",
      "TRY",
      "SWITCH",
      "THIS",
      "BOOL",
      "UNARY",
      "SUPER",
      "@",
      "->",
      "=>",
      "[",
      "(",
      "{",
      "--",
      "++",
    ];
  
    IMPLICIT_UNSPACED_CALL = ["+", "-"];
  
    IMPLICIT_BLOCK = ["->", "=>", "{", "[", ","];
  
    IMPLICIT_END = [
      "POST_IF",
      "FOR",
      "WHILE",
      "UNTIL",
      "WHEN",
      "BY",
      "LOOP",
      "TERMINATOR",
    ];
  
    SINGLE_LINERS = ["ELSE", "->", "=>", "TRY", "FINALLY", "THEN"];
  
    SINGLE_CLOSERS = [
      "TERMINATOR",
      "CATCH",
      "FINALLY",
      "ELSE",
      "OUTDENT",
      "LEADING_WHEN",
    ];
  
    LINEBREAKS = ["TERMINATOR", "INDENT", "OUTDENT"];
  });
  