"var $m = { ROOT: this, ADAPTER: _$m_adapter, PLATFORM: 'ruby' };\nvar JS2 = $m;\n(function () {\n // CLASS HELPERS\n(function (undefined, $m) {\n\n var OO = function (klass, par) {\n this.klass = klass;\n this.par = par;\n\n this.members = {};\n this.staticMembers = {};\n this.children = [];\n this.included = [];\n\n if (this.par) this.par.OO.children.push(klass);\n };\n\n $m.PUSH_ROOT = function (r) {\n this.ROOTS = this.ROOTS || [];\n this.ROOTS.push(r);\n this.ROOT = r;\n };\n\n $m.POP_ROOT = function () {\n this.ROOTS = this.ROOTS || [];\n if (this.ROOTS.length) {\n this.ROOTS.pop();\n this.ROOT = this.ROOTS[this.ROOTS.length-1];\n }\n\n };\n\n OO.prototype = {\n forbiddenMembers: {\n 'prototype': undefined,\n 'OO': undefined\n },\n\n include: function(module) {\n this.included.push(module);\n var members = module.OO.members;\n for (var name in members) {\n if (members.hasOwnProperty(name)) {\n this.addMember(name, members[name]);\n }\n }\n\n var staticMembers = module.OO.staticMembers;\n for (var name in staticMembers) {\n if (staticMembers.hasOwnProperty(name)) {\n this.addStaticMember(name, staticMembers[name]);\n }\n }\n\n if (typeof staticMembers['included'] == 'function') {\n staticMembers['included'](this.klass);\n }\n },\n\n createNamespace: function(name) {\n var splitted = name.split('.');\n var klassName = splitted.pop();\n var root = $m.ROOT;\n\n while (splitted.length > 0) {\n var name = splitted.shift();\n if (!root[name]) root[name] = $m.Class.extend({});\n root = root[name];\n }\n\n return [ root, klassName ];\n },\n\n makeSuper: function(newMethod, oldMethod) {\n if (!oldMethod) return newMethod;\n\n return function() {\n this.$super = oldMethod;\n return newMethod.apply(this, arguments);\n };\n },\n\n addMember: function(name, member) {\n if (this.forbiddenMembers.hasOwnProperty(name)) return;\n\n var proto = this.klass.prototype;\n if (typeof proto[name] == 'function' && !(proto[name] instanceof RegExp)) {\n member = this.makeSuper(member, proto[name]);\n }\n\n proto[name] = member;\n this.members[name] = member;\n },\n\n addStaticMember: function(name, member) {\n if (this.forbiddenMembers.hasOwnProperty(name)) return;\n\n if (typeof this.klass[name] == 'function') {\n if (!this.klass.hasOwnProperty(name)) {\n member = this.makeSuper(member, this.klass[name]);\n }\n }\n\n this.klass[name] = member;\n this.staticMembers[name] = member;\n }\n };\n\n $m.Class = function() { this.initialize.apply(this, arguments); };\n $m.Class.OO = new OO($m.Class);\n $m.Class.prototype = {\n initialize: function () {},\n oo: $m.Class.OO\n };\n\n var namedClasses = {};\n $m.getClass = function(name) {\n return namedClasses[name];\n };\n\n var noInit = false;\n $m.Class.extend = function(name, klassDef) {\n var klass = function() { if (!noInit) this.initialize.apply(this, arguments); };\n klass.OO = new OO(klass, this);\n\n if (typeof name != 'string') {\n klassDef = name;\n } else {\n namedClasses[name] = klass;\n var namespace = this.OO.createNamespace(name);\n namespace[0][namespace[1]] = klass;\n }\n\n // create instance of this as prototype for new this\n noInit = true;\n var proto = new this();\n noInit = false;\n\n klass.prototype = proto;\n var oo = klass.OO;\n proto.OO = oo;\n\n for (var name in this) {\n oo.addStaticMember(name, this[name]);\n }\n\n if (typeof klassDef == 'function') {\n klassDef(klass, oo);\n } else {\n for (var name in klassDef) {\n oo.addMember(name, klassDef[name]);\n }\n }\n\n return klass;\n };\n\n $m.Module = $m.Class;\n\n var assert = {\n 'eq': function(expected, actual) { if (expected != actual) $m.outs(\"Expected \"+expected+\", but got \"+actual+\".\") },\n 'isFalse': function(val) { if (val) $m.outs(\"Expected false, but got \"+JSON.stringify(val)+\".\") },\n 'isTrue': function(val) { if (!val) $m.outs(\"Expected true, but got \" +val+\".\") }\n };\n\n $m.test = function(message, callback) {\n if (!callback) callback = message;\n callback(assert);\n };\n\n function addListener(type, listener) {\n var events = this.__$events || (this.__$events = {});\n this.emit('newListener', type, listener);\n if (!events[type]) events[type] = [];\n events[type].push(listener);\n }\n\n $m.out = function () {\n for (var i=0,arg=null,_list_0=arguments,_len_0=_list_0.length;(arg=_list_0[i])||i<_len_0;i++){\n $m.ADAPTER.out(arg);\n if (i < arguments.length-1) {\n $m.ADAPTER.out(',');\n }\n }\n };\n\n $m.outs = function () {\n for (var _i_0=0,arg=null,_list_0=arguments,_len_0=_list_0.length;(arg=_list_0[_i_0])||_i_0<_len_0;_i_0++){\n $m.ADAPTER.outs(arg);\n }\n };\n\n return $m;\n})(undefined, $m);\n\n\n$m.Module.extend(\"EventEmitter\", function(KLASS, OO){\n \n var MAX_LISTENERS = 10;\n var isArray = Array.isArray;\n \n\n OO.addMember(\"emit\", function(){\n var type = arguments[0];\n // If there is no 'error' event listener then throw.\n if (type === 'error') {\n if (!this._events || !this._events.error ||\n (isArray(this._events.error) && !this._events.error.length))\n {\n if (arguments[1] instanceof Error) {\n throw arguments[1]; // Unhandled 'error' event\n } else {\n throw new Error(\"Uncaught, unspecified 'error' event.\");\n }\n return false;\n }\n }\n\n if (!this._events) return false;\n var handler = this._events[type];\n if (!handler) return false;\n\n if (typeof handler == 'function') {\n switch (arguments.length) {\n // fast cases\n case 1:\n handler.call(this);\n break;\n case 2:\n handler.call(this, arguments[1]);\n break;\n case 3:\n handler.call(this, arguments[1], arguments[2]);\n break;\n // slower\n default:\n var l = arguments.length;\n var args = new Array(l - 1);\n for (var i = 1; i < l; i++) args[i - 1] = arguments[i];\n handler.apply(this, args);\n }\n return true;\n\n } else if (isArray(handler)) {\n var l = arguments.length;\n var args = new Array(l - 1);\n for (var i = 1; i < l; i++) args[i - 1] = arguments[i];\n\n var listeners = handler.slice();\n for (var i = 0, l = listeners.length; i < l; i++) {\n listeners[i].apply(this, args);\n }\n return true;\n\n } else {\n return false;\n }\n\n }); \n\n OO.addMember(\"addListener\", function(type, listener){\n if ('function' !== typeof listener) {\n throw new Error('addListener only takes instances of Function');\n }\n\n if (!this._events) this._events = {};\n\n // To avoid recursion in the case that type == \"newListeners\"! Before\n // adding it to the listeners, first emit \"newListeners\".\n this.emit('newListener', type, typeof listener.listener === 'function' ?\n listener.listener : listener);\n\n if (!this._events[type]) {\n // Optimize the case of one listener. Don't need the extra array object.\n this._events[type] = listener;\n } else if (isArray(this._events[type])) {\n\n // If we've already got an array, just append.\n this._events[type].push(listener);\n\n } else {\n // Adding the second element, need to change to array.\n this._events[type] = [this._events[type], listener];\n\n }\n\n // Check for listener leak\n if (isArray(this._events[type]) && !this._events[type].warned) {\n var m;\n if (MAX_LISTENERS !== undefined) {\n m = MAX_LISTENERS;\n } else {\n m = defaultMaxListeners;\n }\n\n if (m && m > 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n console.trace();\n }\n }\n\n return this;\n });\n\n OO.addMember(\"on\", function(type, listener){\n this.addListener(type, listener);\n });\n\n OO.addMember(\"once\", function(type, listener){\n if ('function' !== typeof listener) {\n throw new Error('.once only takes instances of Function');\n }\n\n function g() {\n self.removeListener(type, g);\n listener.apply(this, arguments);\n };\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n });\n\n OO.addMember(\"removeListener\", function(type, listener){\n if ('function' !== typeof listener) {\n throw new Error('removeListener only takes instances of Function');\n }\n\n // does not use listeners(), so no side effect of creating _events[type]\n if (!this._events || !this._events[type]) return this;\n\n var list = this._events[type];\n\n if (isArray(list)) {\n var position = -1;\n for (var i = 0, length = list.length; i < length; i++) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener))\n {\n position = i;\n break;\n }\n }\n\n if (position < 0) return this;\n list.splice(position, 1);\n if (list.length == 0)\n delete this._events[type];\n } else if (list === listener ||\n (list.listener && list.listener === listener))\n {\n delete this._events[type];\n }\n\n return this;\n });\n\n OO.addMember(\"removeAllListeners\", function(type){\n if (arguments.length === 0) {\n this._events = {};\n return this;\n }\n\n // does not use listeners(), so no side effect of creating _events[type]\n if (type && this._events && this._events[type]) this._events[type] = null;\n return this;\n });\n\n OO.addMember(\"listeners\", function(type){\n if (!this._events) this._events = {};\n if (!this._events[type]) this._events[type] = [];\n if (!isArray(this._events[type])) {\n this._events[type] = [this._events[type]];\n }\n return this._events[type];\n });\n});\n\n$m.EventEmitter = $m.ROOT.EventEmitter;\n\n\n var IDENT = \"[\\\\$\\\\w]+\";\nvar TOKENS = [\n [ \"SPACE\", \"\\\\s+\" ],\n [ \"RETURN\", \"=>\", 'ReturnParser' ],\n\n [ \"STATIC\", \"static\\\\b\" ],\n [ \"MODULE\", \"module\\\\b\", 'ModuleParser' ],\n\n [ \"EXPORT\", \"export\\\\s+class\\\\b\", 'ClassParser' ],\n [ \"PUBLIC\", \"public\\\\s+class\\\\b\", 'ClassParser' ],\n\n [ \"CLASS\", \"class\\\\b\", 'ClassParser' ],\n [ \"FUNCTION\", \"function\\\\b\" ],\n [ \"INCLUDE\", \"include\\\\b\" ],\n [ \"VAR\", \"var\\\\b\" ],\n [ \"PRIVATE\", \"private\\\\b\" ],\n [ \"EXTENDS\", \"extends\\\\b\" ],\n [ \"FOREACH\", \"foreach\\\\b\", 'ForeachParser' ],\n\n [ \"SHORTHAND_MAPPER\", \"#[\\\\w\\\\$]+\\\\s*(?:{|\\\\()\", 'ShorthandMapperParser' ],\n [ \"SHORTHAND_FUNCTION\", \"#(?:{|\\\\()\", 'ShorthandFunctionParser' ],\n [ \"ISTRING_START\", \"%{\", 'IStringParser' ],\n [ \"HEREDOC\", \"<<[A-Z][0-9A-Z]*\", 'HereDocParser' ],\n\n [ \"DSTRING\", \"\\\"(?:\\\\\\\\.|[^\\\"])*\\\"\" ],\n [ \"SSTRING\", \"\\'(?:\\\\\\\\.|[^\\'])*\\'\" ],\n\n [ \"SEMICOLON\", \";\" ],\n [ \"OPERATOR\", \"\\\\+|\\\\-|\\\\++\" ],\n [ \"EQUALS\", \"=\" ],\n\n [ \"COMMENT\", \"\\\\/\\\\/|\\\\/\\\\*\", \"CommentParser\" ],\n [ \"REGEX\", \"/\", 'RegexParser' ],\n\n [ \"LBRACE\", \"\\\\(\" ],\n [ \"RBRACE\", \"\\\\)\" ],\n [ \"LCURLY\", \"\\\\{\" ],\n [ \"RCURLY\", \"\\\\}\" ],\n\n [ \"IDENT\", IDENT ],\n [ \"WHATEVER\", \".\" ]\n];\n\nvar $c = $m.ROOT;\nvar TYPES = {};\nvar REGEXES = [];\nvar MAIN_REGEX = null;\nvar RTYPES = {};\n\nfor (var i=0,t=null,_list_0=TOKENS,_len_0=_list_0.length;(t=_list_0[i])||i<_len_0;i++){\n TYPES[t[0]] = i;\n RTYPES[i] = t[0];\n REGEXES.push(\"(\" + t[1] + \")\");\n}\n\nvar EXTRA_REGEX_STRINGS = {\n ARGS: \"\\\\(\\s*(?:\" + IDENT + \")?(?:\\\\s*,\\\\s*\" + IDENT + \")*\\s*\\\\)\",\n CLASSNAME: \"[\\\\$\\\\w\\\\.]+\"\n};\n\nvar MAIN_REGEX = new RegExp(\"^\" + REGEXES.join('|'));\n\n$m.Class.extend(\"Tokens\", function(KLASS, OO){\n OO.addMember(\"initialize\", function(str){\n this.orig = str;\n this.str = str;\n this.iterator = 0;\n this.consumed = 0;\n });\n\n OO.addMember(\"peek\", function(){\n if (this._peek) return this._peek;\n\n var m = this.str.match(MAIN_REGEX);\n if (!m) return null;\n\n for (var i=0,ele=null,_list_0=TOKENS,_len_0=_list_0.length;(ele=_list_0[i])||i<_len_0;i++){\n if (m[i+1]) return this._peek = [ i, m[i+1], ele[2] ];\n }\n });\n\n OO.addStaticMember(\"regex\", function(str){\n var regexStr = str.replace(/\\*\\*/g, \"\\\\s*\").replace(/\\s+/g, \"\\\\s+\").replace(/\\>\\</g, \">\\\\s*<\").replace(/\\<(\\w+)\\>/g, function($1,$2,$3){\n return \"(\" + (EXTRA_REGEX_STRINGS[$2] || TOKENS[TYPES[$2]][1]) + \")\";\n });\n\n return new RegExp(\"^\" + regexStr);\n });\n\n OO.addMember(\"consume\", function(n){\n this.str = this.str.substr(n, this.str.length-n);\n this._peek = null;\n this.consumed += n;\n });\n\n OO.addMember(\"length\", function(){\n return this.str.length;\n });\n\n OO.addMember(\"lookback\", function(n){\n var starting = this.consumed - 1;\n\n //$m.outs(JSON.stringify(this.orig.substr(starting-10, 10)));\n //$m.outs(JSON.stringify(this.orig.charAt(starting)));\n while (this.orig.charAt(starting).match(/\\s/)) {\n //$m.outs(\"back\");\n starting--;\n }\n\n //$m.outs(n + \"= \" + JSON.stringify(this.orig.substr(starting-n, n)));\n return this.orig.substr(starting-n+1, n);\n });\n\n OO.addMember(\"lookahead\", function(n){\n var starting = this.consumed;\n while (this.orig.charAt(starting).match(/\\s/)) starting++;\n return this.orig.substr(starting, n);\n });\n\n\n OO.addMember(\"any\", function(){\n return this.str.length > 0;\n });\n\n OO.addMember(\"match\", function(regex){\n return this.str.match(regex);\n });\n});\nvar Tokens = $c.Tokens;\n\n\n$m.parse = function (str) {\n var parser = new $c.RootParser();\n parser.parse(new $c.Tokens(str));\n return parser.toString();\n};\n\n$m.toJSON = function (str, options) {\n var parser = new $c.RootParser();\n parser.parse(new $c.Tokens(str));\n return parser.toJSON();\n};\n\n$m.pp = function (str, options) {\n var parser = new $c.RootParser();\n parser.parse(new $c.Tokens(str));\n return parser.pp();\n};\n\nvar OPTIONS = {};\n\n$m.Class.extend(\"RootParser\", function(KLASS, OO){\n OO.addMember(\"handlers\", {});\n\n OO.addMember(\"initialize\", function(){\n this.out = [];\n this.finished = false;\n });\n\n OO.addMember(\"parse\", function(tokens){\n var len = tokens.length();\n if (this.startParse(tokens) === false || this.parseTokens(tokens) === false || this.endParse(tokens) === false) return false\n return len != tokens.length();\n });\n\n // TODO: messy clean this process up\n OO.addMember(\"parseTokens\", function(tokens){\n var sanity = 100;\n var origLen = tokens.length();\n\n while (tokens.any()) {\n var token = tokens.peek();\n if (!token) break;\n\n // has a parser class associated with this token\n var handlerClass = this.getHandler(token) || token[2];\n if (handlerClass) {\n var handler = new $c[handlerClass];\n handler._TYPE = handlerClass;\n if (handler.parse(tokens) !== false) {\n this.out.push(handler);\n tokens.lastHandler = handler;\n } else {\n this.handleToken(token, tokens);\n }\n }\n\n // no parser class, use \"this\" to just consume it\n else {\n this.handleToken(token, tokens);\n }\n\n if (this.finished) break;\n\n if (origLen == tokens.length() && sanity-- == 0) {\n throw \"parse error\";\n } else {\n sanity = 100;\n }\n }\n });\n\n OO.addMember(\"startParse\", function(){ });\n OO.addMember(\"endParse\", function(){ });\n\n OO.addMember(\"handleToken\", function(token, tokens){\n this.out.push(token[1]);\n tokens.consume(token[1].length);\n });\n\n OO.addMember(\"toString\", function(){\n var ret = [];\n for (var i=0; i<this.out.length; i++) {\n var ele = this.out[i];\n ret.push(ele === undefined ? '' : ele.toString());\n }\n return ret.join(\"\");\n });\n\n OO.addMember(\"toJSON\", function(){\n return JSON.stringify(this.toStruct());\n });\n\n OO.addMember(\"pp\", function(space){\n space = space == null ? \" \" : space + \" \";\n\n var ret = [ space + (this._TYPE || 'NODE') ];\n var generic = [];\n for (var _i_0=0,ele=null,_list_0=this.out,_len_0=_list_0.length;(ele=_list_0[_i_0])||_i_0<_len_0;_i_0++){\n if (ele === undefined) {\n ret.push(space + \" UNDEFINED!\");\n continue;\n }\n\n if (ele.pp) {\n if (generic.length) {\n ret.push(space + \" TOKENS:\" + JSON.stringify(generic.join('')));\n generic = [];\n }\n ret.push(ele.pp(space));\n }\n\n else {\n generic.push(ele);\n }\n }\n\n if (generic.length) {\n ret.push(space + \" TOKENS:\" + JSON.stringify(generic.join('')));\n }\n\n return ret.join(\"\\n\");\n });\n\n OO.addMember(\"toStruct\", function(){\n var ret = [];\n for (var _i_0=0,ele=null,_list_0=this.out,_len_0=_list_0.length;(ele=_list_0[_i_0])||_i_0<_len_0;_i_0++){\n ret.push(ele.toStruct ? ele.toStruct() : ele);\n }\n return ret;\n });\n\n // intercepts parser class for special cases\n OO.addMember(\"getHandler\", function(token){\n return null;\n });\n\n OO.addMember(\"chop\", function(){\n this.out.pop();\n });\n});\n\nvar RootParser = $c.RootParser;\n\nRootParser.extend(\"ClassParser\", function(KLASS, OO){\n \n var REGEX = Tokens.regex(\"(?:<EXPORT>|<PUBLIC>|<CLASS>) <CLASSNAME><LCURLY>\");\n var EXTENDS = Tokens.regex(\"(?:<EXPORT>|<PUBLIC>|<CLASS>) <CLASSNAME><EXTENDS><CLASSNAME><LCURLY>\");\n \n\n OO.addMember(\"parse\", function(tokens){\n var m = tokens.match(REGEX) || tokens.match(EXTENDS);\n var name = m[4];\n var extending = m[6] || \"$m.Class\";\n\n tokens.consume(m[0].length-1);\n\n var content = new $c.ClassContentParser();\n content.parse(tokens);\n\n var isPublic = ($m.PLATFORM == 'node' && m[2] && m[2].indexOf('public') == 0) ? \"exports.\" + name + '=' + name + ';' : '';\n var isExports = ($m.PLATFORM == 'node' && m[1] && m[1].indexOf('export') == 0) ? \"module.exports=\" + name + ';' : '';\n\n this.out = [ extending, \".extend(\", JSON.stringify(name), \", function(KLASS, OO)\", content, \");\", isPublic, isExports ];\n });\n});\n\nRootParser.extend(\"ModuleParser\", function(KLASS, OO){\n \n var REGEX = Tokens.regex(\"<MODULE> <CLASSNAME><LCURLY>\");\n \n\n OO.addMember(\"parse\", function(tokens){\n var m = tokens.match(REGEX);\n if (!m) return false;\n var name = m[2];\n tokens.consume(m[0].length-1);\n\n var content = new $c.ClassContentParser();\n content.parse(tokens);\n\n this.out = [ \"$m.Module.extend(\", JSON.stringify(name), \", function(KLASS, OO)\", content, \");\" ];\n });\n});\n\nRootParser.extend(\"CurlyParser\", function(KLASS, OO){\n OO.addMember(\"_TYPE\", 'CurlyParser');\n\n OO.addMember(\"initialize\", function(chop){\n this.chop = chop;\n this.$super();\n });\n\n OO.addMember(\"handleToken\", function(token, tokens){\n if (this.curly === undefined) this.curly = 0;\n if (token[0] == TYPES.RCURLY) {\n this.curly--;\n } else if (token[0] == TYPES.LCURLY) {\n this.curly++;\n }\n\n this.$super(token, tokens);\n\n if (this.curly == 0) {\n this.finished = true;\n }\n });\n\n OO.addMember(\"endParse\", function(tokens){\n if (this.chop) {\n this.out.pop();\n this.out.shift();\n }\n });\n});\n\nvar CurlyParser = $c.CurlyParser;\n\nCurlyParser.extend(\"ClassContentParser\", function(KLASS, OO){\n OO.addMember(\"getHandler\", function(token){\n switch(token[0]) {\n case TYPES.STATIC: return \"StaticParser\";\n case TYPES.VAR: return \"MemberParser\";\n case TYPES.FUNCTION: return \"MethodParser\";\n case TYPES.PRIVATE: return \"PrivateParser\";\n case TYPES.INCLUDE: return \"IncludeParser\";\n }\n });\n});\n\nRootParser.extend(\"LineParser\", function(KLASS, OO){\n OO.addMember(\"handleToken\", function(token, tokens){\n this.$super(token, tokens);\n if (token[0] == TYPES.SEMICOLON) {\n this.finished = true;\n }\n });\n});\n\nCurlyParser.extend(\"PrivateParser\", function(KLASS, OO){\n \n var REGEX = Tokens.regex(\"<PRIVATE>\\\\s*\");\n \n\n OO.addMember(\"startParse\", function(tokens){\n var m = tokens.match(REGEX);\n tokens.consume(m[0].length);\n });\n\n OO.addMember(\"endParse\", function(tokens){\n this.out.pop();\n this.out.shift();\n });\n});\n\n\nRootParser.extend(\"IStringParser\", function(KLASS, OO){\n \n var BEGIN = Tokens.regex(\"<ISTRING_START>\");\n \n\n OO.addMember(\"parse\", function(tokens){\n var m = tokens.match(BEGIN);\n tokens.consume(m[0].length);\n this.out.push('\"');\n\n while (1) {\n var m = tokens.match(/^((?:\\\\.|.)*?)(#\\{|})/);\n var str = m[1];\n var len = m[0].length;\n str.replace(/\"/, '\\\\\"');\n\n if (m[2] == '\#{') {\n this.out.push(str+'\"+(');\n tokens.consume(len-1);\n this.parseMiddle(tokens);\n this.out.push(')+\"');\n }\n\n else if (m[2] == '}') {\n this.out.push(str);\n this.out.push('\"');\n tokens.consume(len);\n return;\n }\n }\n });\n\n OO.addMember(\"parseMiddle\", function(tokens){\n var parser = new $c.CurlyParser(true);\n parser.parse(tokens);\n this.out.push(parser);\n });\n});\n\nRootParser.extend(\"StaticParser\", function(KLASS, OO){\n \n var VAR_REGEX = Tokens.regex(\"(<STATIC>(\\\\s+))<VAR>\");\n var FUNCT_REGEX = Tokens.regex(\"(<STATIC>(\\\\s+))<FUNCTION>\");\n \n\n OO.addMember(\"parseTokens\", function(tokens){\n var varMatch = tokens.match(VAR_REGEX);\n if (varMatch) {\n tokens.consume(varMatch[1].length);\n var parser = new $c.MemberParser();\n parser.isStatic = true;\n parser.parse(tokens);\n this.out.push(parser);\n }\n\n else {\n var functMatch = tokens.match(FUNCT_REGEX);\n tokens.consume(functMatch[1].length);\n\n var parser = new $c.MethodParser();\n parser.isStatic = true;\n parser.parse(tokens);\n this.out.push(parser);\n }\n });\n});\n\nRootParser.extend(\"MemberParser\", function(KLASS, OO){\n \n var REGEX = Tokens.regex(\"var <IDENT>\\\\s*=\\\\s*?\");\n \n\n OO.addMember(\"parse\", function(tokens){\n var m = tokens.str.match(REGEX);\n this.name = m[1];\n tokens.consume(m[0].length);\n\n var parser = new $c.LineParser();\n parser.parse(tokens);\n parser.chop();\n var addMethod = this.isStatic ? 'addStaticMember' : 'addMember';\n\n this.out = [ \"OO.\" + addMethod + \"(\", JSON.stringify(this.name), \",\", parser, \");\" ];\n });\n});\n\nvar MemberParser = $m.MemberParser;\n\n\n\nRootParser.extend(\"IncludeParser\", function(KLASS, OO){\n \n var REGEX = Tokens.regex(\"<INCLUDE> <CLASSNAME><SEMICOLON>\");\n \n\n OO.addMember(\"parse\", function(tokens){\n var m = tokens.match(REGEX);\n tokens.consume(m[0].length);\n this.out = [ 'OO.include(', m[2], ');' ];\n });\n});\n\nRootParser.extend(\"HereDocParser\", function(KLASS, OO){\n \n var REGEX = Tokens.regex(\"<HEREDOC>\");\n \n\n OO.addMember(\"parse\", function(tokens){\n var beginning = tokens.match(/^<<(\\w+)(?::(\\w+))?\\s*([;\\)])*\\n/);\n var terminator = beginning[1];\n\n tokens.consume(beginning[0].length);\n\n var spacing = tokens.match(/^(\\s*)/);\n var regexSub = new RegExp(\"^\" + (spacing[0] || ''), \"mg\");\n\n var strMatch = tokens.match(new RegExp(\"^([\\\\s\\\\S]*?)\\\\n\\\\s*\" + terminator + \"\\\\b\"));\n var toParse = strMatch[1] || '';\n\n toParse = toParse.replace(regexSub, '');\n toParse = toParse.replace(/\\n/g, \"\\\\n\");\n\n // TODO handle options for interpolation\n var string = '\"' + toParse.replace(/\"/g, '\\\\\"') + '\"';\n tokens.consume(strMatch[0] ? strMatch[0].length : 0);\n\n // TODO put this in register\n if (beginning[2]) {\n this.out = [ '$m.JSML.process(', string, ')', beginning[3] || ';' ];\n } else {\n this.out = [ string, beginning[3] || ';' ];\n }\n });\n});\n\nRootParser.extend(\"MethodParser\", function(KLASS, OO){\n \n var REGEX = Tokens.regex(\"<FUNCTION> <IDENT><ARGS><SPACE>\");\n \n\n OO.addMember(\"parse\", function(tokens){\n var m = tokens.str.match(REGEX);\n tokens.consume(m[0].length);\n var name = m[2];\n var args = m[3];\n\n var body = new $c.CurlyParser();\n body.parse(tokens);\n body.out[0] = \"{var self=this;\";\n\n var addMethod = this.isStatic ? 'addStaticMember' : 'addMember';\n\n\n this.out = [ 'OO.' + addMethod + '(', JSON.stringify(name), ', function', args, body, ');' ];\n });\n});\n\nRootParser.extend(\"ReturnParser\", function(KLASS, OO){\n OO.addMember(\"parse\", function(tokens){\n tokens.consume(2);\n this.out = [ 'return ' ];\n });\n});\n\nRootParser.extend(\"ShorthandMapperParser\", function(KLASS, OO){\n \n var ARGS_REGEX = Tokens.regex(\"<ARGS>\\\\s*\");\n \n\n OO.addMember(\"parse\", function(tokens){\n tokens.consume(1);\n var nameMatch = tokens.match(/^([\\w\\$]+)\\s*/);\n tokens.consume(nameMatch[0].length);\n\n var method = nameMatch[1];\n\n var argsMatch = tokens.match(ARGS_REGEX);\n var args = null;\n\n if (argsMatch) {\n args = argsMatch[0];\n tokens.consume(argsMatch[0].length);\n } else {\n args = \"($1,$2,$3)\";\n }\n\n var body = new $c.ReturnableCurlyParser();\n body.parse(tokens);\n\n this.out = [ '.', method, '(function', args, body, ')' ];\n });\n});\n\nRootParser.extend(\"ShorthandFunctionParser\", function(KLASS, OO){\n \n var ARGS_REGEX = Tokens.regex(\"<ARGS>\\\\s*\");\n \n\n OO.addMember(\"parse\", function(tokens){\n tokens.consume(1);\n var argsMatch = tokens.match(ARGS_REGEX);\n var args = null;\n\n if (argsMatch) {\n args = argsMatch[0];\n tokens.consume(argsMatch[0].length);\n } else {\n args = \"($1,$2,$3)\";\n }\n\n var body = new $c.CurlyParser();\n body.parse(tokens);\n var semi = tokens.match(/^\\s*[,;\\)]/) ? '' : ';';\n\n this.out = [ 'function', args, body, semi ];\n });\n});\n\nRootParser.extend(\"CommentParser\", function(KLASS, OO){\n OO.addMember(\"parse\", function(tokens){\n var m = tokens.match(/^\\/\\/.*?\\n/);\n if (m) {\n tokens.consume(m[0].length);\n this.out = [ m[0] ];\n return;\n }\n\n var m2 = tokens.match(/^\\/\\*[\\s\\S]*?\\*\\//);\n if (m2) {\n tokens.consume(m2[0].length);\n this.out = [ m2[0] ];\n return;\n }\n\n return false;\n });\n});\n\nRootParser.extend(\"RegexParser\", function(KLASS, OO){\n \n var REGEX = /^\\/(\\\\.|[^\\/])+\\/[imgy]{0,4}/;\n var DIVIDE = /(\\}|\\)|\\+\\+|\\-\\-|[\\w\\$])$/;\n \n\n OO.addMember(\"parseTokens\", function(tokens){\n var back = tokens.lookback(2);\n\n if (back.match(DIVIDE)) {\n this._TYPE = 'DIVIDE';\n tokens.consume(1);\n this.out.push(\"/\");\n }\n\n else {\n var m = tokens.match(REGEX);\n if (m) {\n this.out.push(m[0]);\n tokens.consume(m[0].length);\n } else {\n return false;\n }\n }\n\n });\n\n});\n\nCurlyParser.extend(\"ReturnableCurlyParser\", function(KLASS, OO){\n OO.addMember(\"toString\", function(){\n var ret = this.$super();\n return ret.replace(/^{(\\s*)(return)?/, '{$1return ');\n });\n});\n\n\n\nCurlyParser.extend(\"ForeachParser\", function(KLASS, OO){\n OO.addMember(\"_TYPE\", 'Foreach');\n\n \n var REGEX = Tokens.regex(\"<FOREACH><LBRACE><VAR> <IDENT>(?:**:**<IDENT>)? in (.*?)**<RBRACE>**{\");\n \n\n OO.addMember(\"startParse\", function(tokens){\n var m = tokens.match(REGEX);\n namespace = tokens.iterator++;\n\n this.item = m[4];\n this.iterator = m[5] || \"_i_\" + namespace;\n this.list = m[6];\n\n // TODO ugly, revisit this later\n tokens.consume(m[0].length-1);\n var declare = [ this.iterator + \"=0\", this.item + \"=null\", \"_list_\" + namespace + \"=\" + this.list, \"_len_\" + namespace + \"=_list_\" + namespace + \".length\" ].join(',');\n\n var bool = \"(\" + this.item + \"=\" + \"_list_\" + namespace + \"[\" + this.iterator + \"])||\" + this.iterator + \"<_len_\" + namespace;\n\n this.out = [ \"for (var \", declare, \";\", bool, ';', this.iterator + \"++)\" ];\n });\n\n OO.addMember(\"endParse\", function(tokens){\n tokens.iterator--;\n });\n\n});\n\n\n$m.Class.extend(\"CLI\", function(KLASS, OO){\n \n var COMMANDS = {\n help: 'help',\n render: 'render',\n compile: 'compile',\n watch: 'watch'\n };\n \n\n OO.addMember(\"run\", function(args){\n var opts = this.parseOpts(args);\n var options = opts[0];\n var command = opts[1];\n var files = opts[2];\n });\n\n OO.addMember(\"parseOpts\", function(args){\n var files = [];\n var options = {};\n var command = null;\n\n var endedArgs = false;\n\n for (var i=0,arg=null,_list_0=args,_len_0=_list_0.length;(arg=_list_0[i])||i<_len_0;i++){\n if (endedArgs) {\n files.push(arg);\n }\n\n else if (COMMANDS[arg]) {\n command = arg;\n endedArgs = true;\n }\n\n else {\n var setting = arg.match(/^(\\w+)(?:=(.*))?$/);\n if (setting) options[setting[0]] = setting[1] || 'true';\n }\n }\n\n return [ options, command, files ];\n });\n});\n\n\n})();\n"