ethstats-server/web-app/.meteor/local/build/programs/server/packages/spacebars-compiler.js.map
2015-08-14 19:22:53 +02:00

1 line
46 KiB
Plaintext

{"version":3,"sources":["spacebars-compiler/templatetag.js","spacebars-compiler/optimizer.js","spacebars-compiler/codegen.js","spacebars-compiler/compiler.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,uB;;AAEA,iE;AACA,E;AACA,0C;AACA,E;AACA,2B;AACA,6B;AACA,8B;AACA,sC;AACA,gC;AACA,+B;AACA,gC;AACA,0B;AACA,kD;AACA,E;AACA,iE;AACA,E;AACA,yE;AACA,2E;AACA,oB;AACA,E;AACA,wE;AACA,sE;AACA,2E;AACA,uE;AACA,sC;AACA,E;AACA,qE;AACA,kB;AACA,E;AACA,qD;AACA,E;AACA,6E;AACA,yE;AACA,qD;AACA,mC;AACA,E;AACA,sE;AACA,sE;AACA,6B;;AAEA,4D;;AAEA,2D;AACA,+C;AACA,E;AACA,kD;AACA,wE;;AAEA,4C;AACA,oD;AACA,6C;AACA,E;;AAEA,yD;AACA,6D;AACA,mD;AACA,c;AACA,2B;AACA,0D;AACA,oD;AACA,sD;AACA,uD;AACA,gD;AACA,2D;AACA,2D;AACA,4D;AACA,E;;AAEA,Y;AACA,qB;AACA,sB;AACA,E;;AAEA,iE;AACA,qE;AACA,yE;AACA,6C;AACA,gD;AACA,gC;AACA,kC;AACA,qD;;AAEA,kC;AACA,gD;AACA,gB;;AAEA,8B;AACA,yC;AACA,4C;AACA,iB;AACA,kB;AACA,wB;AACA,8B;AACA,e;AACA,I;;AAEA,mC;AACA,0B;AACA,I;;AAEA,iD;AACA,qD;AACA,a;AACA,6B;AACA,wB;AACA,2D;AACA,yF;;AAEA,c;AACA,I;;AAEA,8B;AACA,sB;;AAEA,oE;AACA,a;AACA,mC;AACA,4D;AACA,2C;;AAEA,wB;AACA,iC;;AAEA,0D;AACA,0B;AACA,sD;AACA,iD;AACA,gB;AACA,iC;AACA,sC;AACA,S;;AAEA,+B;AACA,6B;AACA,S;;AAEA,iC;;AAEA,yB;AACA,wB;AACA,K;;AAEA,kB;AACA,4B;;AAEA,uB;AACA,qC;AACA,kB;AACA,6C;AACA,+B;AACA,uC;AACA,sD;AACA,2B;AACA,c;AACA,mD;AACA,4B;AACA,kC;AACA,6B;AACA,+B;AACA,kB;AACA,oI;AACA,W;AACA,gB;AACA,4B;AACA,S;AACA,O;;AAEA,+B;AACA,gB;AACA,c;AACA,K;;AAEA,oB;AACA,I;;AAEA,mD;AACA,sC;AACA,kD;AACA,iD;AACA,oC;AACA,0E;AACA,gB;AACA,qC;AACA,sB;AACA,Y;AACA,kB;AACA,K;AACA,I;;AAEA,0C;AACA,8C;AACA,sD;AACA,kB;AACA,6B;AACA,kE;AACA,+B;AACA,mD;AACA,I;;AAEA,kE;AACA,4D;AACA,kC;AACA,+B;AACA,e;AACA,qD;AACA,sC;AACA,mE;AACA,sC;AACA,gD;AACA,kC;AACA,oE;AACA,sB;AACA,0B;AACA,8B;AACA,mD;AACA,0C;AACA,c;AACA,iD;AACA,oC;AACA,O;AACA,Y;AACA,+D;AACA,K;AACA,I;;AAEA,W;;AAEA,8B;AACA,uB;AACA,I;;AAEA,kC;AACA,8B;AACA,I;;AAEA,uD;AACA,mC;AACA,0C;AACA,2C;AACA,+C;AACA,+C;AACA,2D;AACA,iD;AACA,qD;AACA,qD;AACA,uD;AACA,M;AACA,gC;;AAEA,4B;AACA,kB;;AAEA,gC;AACA,4C;AACA,iB;AACA,sC;AACA,0D;AACA,kC;AACA,sC;AACA,iB;AACA,gC;AACA,oC;AACA,qC;AACA,0B;AACA,2B;AACA,uB;AACA,+B;AACA,2B;AACA,uB;AACA,iC;AACA,+B;AACA,2C;AACA,U;AACA,2C;AACA,0B;AACA,kB;AACA,2B;AACA,kB;AACA,kB;AACA,8B;AACA,6B;AACA,gB;AACA,wC;AACA,4B;AACA,c;AACA,6B;AACA,gB;AACA,wC;AACA,2B;AACA,O;AACA,6B;AACA,gC;AACA,0B;AACA,c;AACA,uB;AACA,8E;AACA,O;AACA,4B;;AAEA,mC;AACA,0B;AACA,K;AACA,G;;AAEA,a;AACA,E;;AAEA,iF;AACA,4B;AACA,E;AACA,wE;AACA,wB;AACA,uC;AACA,6B;AACA,0C;AACA,yB;AACA,gB;AACA,E;;AAEA,0E;AACA,0E;AACA,+B;AACA,E;AACA,e;AACA,E;AACA,oE;AACA,E;AACA,sE;AACA,8D;AACA,E;AACA,2E;AACA,wC;AACA,E;AACA,yE;AACA,qE;AACA,gC;AACA,kC;AACA,qD;;AAEA,mD;AACA,kD;AACA,e;AACA,kB;;AAEA,qC;AACA,gB;;AAEA,gC;AACA,gB;;AAEA,6B;AACA,yC;;AAEA,mC;AACA,qD;;AAEA,yD;AACA,iD;AACA,+B;;AAEA,oC;AACA,2B;;AAEA,oE;AACA,uE;AACA,oE;AACA,gB;AACA,0C;;AAEA,wB;AACA,qC;AACA,0D;AACA,wC;AACA,gE;AACA,mE;AACA,wC;AACA,O;AACA,2B;AACA,qD;AACA,yC;AACA,0B;AACA,Q;AACA,qE;;AAEA,4C;AACA,yE;;AAEA,yD;AACA,qE;;AAEA,kC;AACA,mD;AACA,2E;;AAEA,8C;AACA,+D;;AAEA,4B;AACA,2C;AACA,K;;AAEA,wC;AACA,8C;AACA,qC;AACA,8B;AACA,yE;AACA,kC;AACA,O;AACA,Y;AACA,4B;AACA,uE;AACA,kC;AACA,K;AACA,G;;AAEA,6B;AACA,yB;AACA,+B;AACA,yB;;AAEA,gB;AACA,E;;AAEA,+C;AACA,qC;AACA,I;AACA,yE;AACA,kE;AACA,yE;AACA,2C;AACA,iB;AACA,mC;AACA,yD;AACA,6C;AACA,oD;AACA,sD;AACA,E;;AAEA,oE;AACA,mE;AACA,W;AACA,4C;;AAEA,+D;AACA,yB;AACA,2E;AACA,qE;AACA,wB;AACA,yH;AACA,K;AACA,G;;AAEA,gE;AACA,wD;AACA,2D;AACA,a;AACA,2C;AACA,2B;AACA,0B;AACA,oD;AACA,wD;AACA,sD;AACA,wD;AACA,0H;AACA,O;AACA,Y;AACA,qF;AACA,K;AACA,+D;AACA,qC;AACA,8N;AACA,K;AACA,iC;AACA,4L;AACA,K;AACA,G;;AAEA,E;;;;;;;;;;;;;;;;;;;AC/dA,yE;AACA,yB;;AAEA,iC;AACA,uC;AACA,E;;AAEA,mB;AACA,U;AACA,W;AACA,S;AACA,E;;AAEA,0E;AACA,yE;AACA,qE;AACA,0E;AACA,8E;AACA,E;AACA,yE;AACA,2E;AACA,sE;AACA,4E;AACA,qB;AACA,+C;AACA,wB;AACA,wC;AACA,6C;AACA,2C;AACA,2C;AACA,uC;AACA,0C;AACA,4C;AACA,4B;AACA,sC;AACA,gD;AACA,iC;AACA,4B;AACA,I;AACA,4B;AACA,8B;AACA,iC;AACA,yE;AACA,qB;AACA,8B;AACA,iD;AACA,uD;AACA,sE;AACA,8B;AACA,qC;AACA,2E;AACA,8E;AACA,wE;AACA,0B;AACA,8B;AACA,K;;AAEA,gC;AACA,6C;AACA,uD;AACA,iC;;AAEA,6D;AACA,+B;;AAEA,4B;AACA,I;AACA,qC;AACA,gB;AACA,wC;AACA,8D;AACA,6C;AACA,4E;AACA,mC;AACA,wB;AACA,oD;AACA,qC;AACA,O;AACA,K;AACA,4B;AACA,G;AACA,G;;AAEA,4C;AACA,iD;AACA,E;;AAEA,0B;AACA,kC;AACA,E;;AAEA,wD;AACA,qB;AACA,8C;AACA,4C;AACA,+C;AACA,mB;;AAEA,oE;AACA,uB;AACA,G;AACA,G;;AAEA,kE;AACA,+D;AACA,iD;AACA,uB;AACA,mB;AACA,wB;AACA,sB;AACA,sB;AACA,gC;AACA,kD;AACA,8C;AACA,0B;AACA,sD;AACA,oE;AACA,Y;AACA,mB;AACA,K;AACA,I;AACA,4B;AACA,gD;AACA,8C;AACA,wB;AACA,sD;AACA,gE;AACA,Y;AACA,iB;AACA,K;AACA,I;AACA,sC;AACA,2D;AACA,qE;AACA,I;AACA,qC;AACA,iB;AACA,G;AACA,G;;AAEA,qD;AACA,oD;AACA,0B;AACA,gC;AACA,oB;AACA,4C;AACA,0B;AACA,uC;AACA,4B;AACA,4B;AACA,gE;AACA,+D;AACA,mE;AACA,2D;AACA,yB;AACA,+C;AACA,0D;AACA,S;AACA,c;AACA,0B;AACA,O;AACA,K;AACA,kB;AACA,G;AACA,G;;AAEA,wE;AACA,kC;AACA,mD;AACA,yB;AACA,4B;AACA,yB;AACA,yD;AACA,kB;AACA,Y;AACA,iB;AACA,K;AACA,G;AACA,G;;AAEA,8C;AACA,6C;AACA,gD;AACA,+C;AACA,c;AACA,E;;;;;;;;;;;;;;;;;;;ACzLA,+D;AACA,mC;;AAEA,qE;AACA,kE;AACA,yC;AACA,yD;;AAEA,oE;AACA,mB;AACA,2B;AACA,2B;AACA,sB;AACA,E;;;AAGA,kE;AACA,oE;AACA,W;AACA,6B;AACA,+D;AACA,kE;AACA,qC;AACA,8C;AACA,wC;;AAEA,8D;AACA,kE;AACA,6C;AACA,kC;;AAEA,sE;AACA,E;;AAEA,8D;AACA,iD;AACA,E;AACA,qE;AACA,kE;AACA,mB;AACA,oD;AACA,oD;AACA,+C;AACA,E;;AAEA,wC;AACA,iB;AACA,oB;AACA,iE;AACA,sC;AACA,E;;AAEA,6B;AACA,sC;AACA,oB;AACA,wE;AACA,yD;AACA,qE;AACA,0D;AACA,kE;AACA,mB;AACA,Y;AACA,2D;AACA,4D;AACA,oC;AACA,mD;AACA,S;AACA,4E;AACA,mE;AACA,oD;AACA,qD;AACA,qE;AACA,oD;AACA,S;AACA,yC;AACA,wE;AACA,4B;;AAEA,uC;AACA,0D;AACA,oC;AACA,Y;AACA,wD;AACA,8E;;AAEA,qF;AACA,uC;AACA,8B;AACA,gF;AACA,gC;AACA,qE;;AAEA,oD;AACA,2E;AACA,iC;AACA,kD;AACA,qE;AACA,wC;AACA,0D;AACA,6E;;AAEA,kD;AACA,+B;AACA,4C;;AAEA,qC;AACA,4E;;AAEA,gB;AACA,wE;AACA,gC;AACA,iC;AACA,0E;AACA,qB;AACA,W;;AAEA,iE;AACA,6C;AACA,gE;AACA,qD;AACA,wE;;AAEA,uC;AACA,wB;AACA,sC;AACA,4B;AACA,4C;AACA,W;;AAEA,2B;AACA,oE;;AAEA,yE;AACA,sE;AACA,mE;AACA,oE;AACA,0E;AACA,0E;AACA,oE;AACA,yB;AACA,yB;AACA,6E;AACA,mC;AACA,W;;AAEA,sE;AACA,6D;AACA,wE;AACA,uE;AACA,mF;AACA,qC;AACA,W;;AAEA,kD;AACA,S;AACA,yC;AACA,yB;AACA,c;AACA,kE;AACA,qE;AACA,qE;AACA,O;AACA,K;AACA,I;;AAEA,+C;AACA,I;AACA,6D;AACA,sD;AACA,I;AACA,gE;AACA,I;AACA,a;AACA,I;AACA,qE;AACA,mE;AACA,oE;AACA,iC;AACA,sC;AACA,oD;AACA,uE;AACA,0E;AACA,4E;AACA,qC;AACA,gE;AACA,2B;AACA,oD;AACA,2D;AACA,0B;AACA,kE;AACA,iD;AACA,4C;AACA,K;;AAEA,wD;AACA,gC;AACA,yD;AACA,sC;AACA,kE;;AAEA,0B;AACA,6C;AACA,sE;AACA,K;;AAEA,gB;AACA,I;;AAEA,+D;AACA,mE;AACA,I;AACA,iE;AACA,4D;AACA,mC;AACA,oB;;AAEA,yB;AACA,0B;;AAEA,gB;AACA,sB;AACA,kB;AACA,kB;AACA,mB;AACA,gB;AACA,iD;AACA,Y;AACA,gB;AACA,2C;AACA,Y;AACA,Y;AACA,uB;AACA,yD;AACA,K;;AAEA,mB;AACA,I;;AAEA,wE;AACA,uE;AACA,qC;AACA,wD;AACA,oB;;AAEA,0C;AACA,iD;AACA,gD;;AAEA,qD;AACA,uD;AACA,I;;AAEA,oD;AACA,iB;AACA,2C;AACA,oB;;AAEA,0C;AACA,gC;;AAEA,0B;AACA,oC;AACA,8C;;AAEA,2B;AACA,gE;AACA,gC;AACA,iC;AACA,c;AACA,8B;AACA,4B;AACA,2B;AACA,O;AACA,O;;AAEA,sD;AACA,iB;AACA,0B;AACA,mE;AACA,K;;AAEA,gB;AACA,I;;AAEA,oC;AACA,8C;AACA,I;;AAEA,6C;AACA,oB;;AAEA,4B;;AAEA,wB;AACA,wB;AACA,kB;AACA,sC;AACA,2D;AACA,yB;AACA,mC;AACA,4B;AACA,gF;AACA,S;AACA,kD;AACA,uC;AACA,wD;AACA,Q;AACA,uE;AACA,2C;AACA,mD;AACA,mC;AACA,qC;AACA,4E;AACA,Y;AACA,8D;AACA,wB;AACA,oE;AACA,0D;AACA,K;;AAEA,0D;AACA,G;;AAEA,G;;;;;;;;;;;;;;;;;;;;AClUA,4C;;AAEA,qC;AACA,U;AACA,sD;;AAEA,c;AACA,E;;AAEA,uD;AACA,4C;AACA,kD;AACA,E;;AAEA,2E;AACA,4C;AACA,6B;AACA,6C;;AAEA,gE;AACA,0D;AACA,4D;AACA,kE;AACA,6D;AACA,yB;AACA,gC;AACA,kE;;AAEA,gD;AACA,K;;AAEA,wE;AACA,I;AACA,qC;AACA,+C;AACA,oD;;AAEA,2D;AACA,gF;AACA,I;AACA,+C;AACA,iC;AACA,mC;AACA,kC;;AAEA,2B;AACA,sE;AACA,sE;AACA,wD;AACA,uE;AACA,4E;AACA,iD;AACA,oE;AACA,K;AACA,kB;AACA,G;AACA,G;;AAEA,2D;AACA,sD;AACA,wB;AACA,mD;AACA,2C;;AAEA,uB;;AAEA,4D;AACA,6B;AACA,4E;AACA,0B;AACA,4C;AACA,G;;AAEA,8C;AACA,qD;AACA,qC;;AAEA,+B;AACA,6B;AACA,gC;AACA,G;AACA,oB;AACA,gC;AACA,iB;;AAEA,2C;;AAEA,c;AACA,E;;AAEA,+C;AACA,8D;AACA,kD;AACA,W;AACA,yB;AACA,sB;AACA,wB;AACA,iC;AACA,kC;AACA,iC;AACA,6B;AACA,+E;AACA,gC;AACA,sC;AACA,kB;AACA,U;AACA,2C;AACA,gB;AACA,G;AACA,E","file":"/packages/spacebars-compiler.js","sourcesContent":["SpacebarsCompiler = {};\n\n// A TemplateTag is the result of parsing a single `{{...}}` tag.\n//\n// The `.type` of a TemplateTag is one of:\n//\n// - `\"DOUBLE\"` - `{{foo}}`\n// - `\"TRIPLE\"` - `{{{foo}}}`\n// - `\"COMMENT\"` - `{{! foo}}`\n// - `\"BLOCKCOMMENT\" - `{{!-- foo--}}`\n// - `\"INCLUSION\"` - `{{> foo}}`\n// - `\"BLOCKOPEN\"` - `{{#foo}}`\n// - `\"BLOCKCLOSE\"` - `{{/foo}}`\n// - `\"ELSE\"` - `{{else}}`\n// - `\"ESCAPE\"` - `{{|`, `{{{|`, `{{{{|` and so on\n//\n// Besides `type`, the mandatory properties of a TemplateTag are:\n//\n// - `path` - An array of one or more strings. The path of `{{foo.bar}}`\n// is `[\"foo\", \"bar\"]`. Applies to DOUBLE, TRIPLE, INCLUSION, BLOCKOPEN,\n// and BLOCKCLOSE.\n//\n// - `args` - An array of zero or more argument specs. An argument spec\n// is a two or three element array, consisting of a type, value, and\n// optional keyword name. For example, the `args` of `{{foo \"bar\" x=3}}`\n// are `[[\"STRING\", \"bar\"], [\"NUMBER\", 3, \"x\"]]`. Applies to DOUBLE,\n// TRIPLE, INCLUSION, and BLOCKOPEN.\n//\n// - `value` - A string of the comment's text. Applies to COMMENT and\n// BLOCKCOMMENT.\n//\n// These additional are typically set during parsing:\n//\n// - `position` - The HTMLTools.TEMPLATE_TAG_POSITION specifying at what sort\n// of site the TemplateTag was encountered (e.g. at element level or as\n// part of an attribute value). Its absence implies\n// TEMPLATE_TAG_POSITION.ELEMENT.\n//\n// - `content` and `elseContent` - When a BLOCKOPEN tag's contents are\n// parsed, they are put here. `elseContent` will only be present if\n// an `{{else}}` was found.\n\nvar TEMPLATE_TAG_POSITION = HTMLTools.TEMPLATE_TAG_POSITION;\n\nTemplateTag = SpacebarsCompiler.TemplateTag = function () {\n HTMLTools.TemplateTag.apply(this, arguments);\n};\nTemplateTag.prototype = new HTMLTools.TemplateTag;\nTemplateTag.prototype.constructorName = 'SpacebarsCompiler.TemplateTag';\n\nvar makeStacheTagStartRegex = function (r) {\n return new RegExp(r.source + /(?![{>!#/])/.source,\n r.ignoreCase ? 'i' : '');\n};\n\n// \"starts\" regexes are used to see what type of template\n// tag the parser is looking at. They must match a non-empty\n// result, but not the interesting part of the tag.\nvar starts = {\n ESCAPE: /^\\{\\{(?=\\{*\\|)/,\n ELSE: makeStacheTagStartRegex(/^\\{\\{\\s*else(?=[\\s}])/i),\n DOUBLE: makeStacheTagStartRegex(/^\\{\\{\\s*(?!\\s)/),\n TRIPLE: makeStacheTagStartRegex(/^\\{\\{\\{\\s*(?!\\s)/),\n BLOCKCOMMENT: makeStacheTagStartRegex(/^\\{\\{\\s*!--/),\n COMMENT: makeStacheTagStartRegex(/^\\{\\{\\s*!/),\n INCLUSION: makeStacheTagStartRegex(/^\\{\\{\\s*>\\s*(?!\\s)/),\n BLOCKOPEN: makeStacheTagStartRegex(/^\\{\\{\\s*#\\s*(?!\\s)/),\n BLOCKCLOSE: makeStacheTagStartRegex(/^\\{\\{\\s*\\/\\s*(?!\\s)/)\n};\n\nvar ends = {\n DOUBLE: /^\\s*\\}\\}/,\n TRIPLE: /^\\s*\\}\\}\\}/\n};\n\n// Parse a tag from the provided scanner or string. If the input\n// doesn't start with `{{`, returns null. Otherwise, either succeeds\n// and returns a SpacebarsCompiler.TemplateTag, or throws an error (using\n// `scanner.fatal` if a scanner is provided).\nTemplateTag.parse = function (scannerOrString) {\n var scanner = scannerOrString;\n if (typeof scanner === 'string')\n scanner = new HTMLTools.Scanner(scannerOrString);\n\n if (! (scanner.peek() === '{' &&\n (scanner.rest()).slice(0, 2) === '{{'))\n return null;\n\n var run = function (regex) {\n // regex is assumed to start with `^`\n var result = regex.exec(scanner.rest());\n if (! result)\n return null;\n var ret = result[0];\n scanner.pos += ret.length;\n return ret;\n };\n\n var advance = function (amount) {\n scanner.pos += amount;\n };\n\n var scanIdentifier = function (isFirstInPath) {\n var id = BlazeTools.parseIdentifierName(scanner);\n if (! id)\n expected('IDENTIFIER');\n if (isFirstInPath &&\n (id === 'null' || id === 'true' || id === 'false'))\n scanner.fatal(\"Can't use null, true, or false, as an identifier at start of path\");\n\n return id;\n };\n\n var scanPath = function () {\n var segments = [];\n\n // handle initial `.`, `..`, `./`, `../`, `../..`, `../../`, etc\n var dots;\n if ((dots = run(/^[\\.\\/]+/))) {\n var ancestorStr = '.'; // eg `../../..` maps to `....`\n var endsWithSlash = /\\/$/.test(dots);\n\n if (endsWithSlash)\n dots = dots.slice(0, -1);\n\n _.each(dots.split('/'), function(dotClause, index) {\n if (index === 0) {\n if (dotClause !== '.' && dotClause !== '..')\n expected(\"`.`, `..`, `./` or `../`\");\n } else {\n if (dotClause !== '..')\n expected(\"`..` or `../`\");\n }\n\n if (dotClause === '..')\n ancestorStr += '.';\n });\n\n segments.push(ancestorStr);\n\n if (!endsWithSlash)\n return segments;\n }\n\n while (true) {\n // scan a path segment\n\n if (run(/^\\[/)) {\n var seg = run(/^[\\s\\S]*?\\]/);\n if (! seg)\n error(\"Unterminated path segment\");\n seg = seg.slice(0, -1);\n if (! seg && ! segments.length)\n error(\"Path can't start with empty string\");\n segments.push(seg);\n } else {\n var id = scanIdentifier(! segments.length);\n if (id === 'this') {\n if (! segments.length) {\n // initial `this`\n segments.push('.');\n } else {\n error(\"Can only use `this` at the beginning of a path.\\nInstead of `foo.this` or `../this`, just write `foo` or `..`.\");\n }\n } else {\n segments.push(id);\n }\n }\n\n var sep = run(/^[\\.\\/]/);\n if (! sep)\n break;\n }\n\n return segments;\n };\n\n // scan the keyword portion of a keyword argument\n // (the \"foo\" portion in \"foo=bar\").\n // Result is either the keyword matched, or null\n // if we're not at a keyword argument position.\n var scanArgKeyword = function () {\n var match = /^([^\\{\\}\\(\\)\\>#=\\s\"'\\[\\]]+)\\s*=\\s*/.exec(scanner.rest());\n if (match) {\n scanner.pos += match[0].length;\n return match[1];\n } else {\n return null;\n }\n };\n\n // scan an argument; succeeds or errors.\n // Result is an array of two or three items:\n // type , value, and (indicating a keyword argument)\n // keyword name.\n var scanArg = function () {\n var keyword = scanArgKeyword(); // null if not parsing a kwarg\n var value = scanArgValue();\n return keyword ? value.concat(keyword) : value;\n };\n\n // scan an argument value (for keyword or positional arguments);\n // succeeds or errors. Result is an array of type, value.\n var scanArgValue = function () {\n var startPos = scanner.pos;\n var result;\n if ((result = BlazeTools.parseNumber(scanner))) {\n return ['NUMBER', result.value];\n } else if ((result = BlazeTools.parseStringLiteral(scanner))) {\n return ['STRING', result.value];\n } else if (/^[\\.\\[]/.test(scanner.peek())) {\n return ['PATH', scanPath()];\n } else if ((result = BlazeTools.parseIdentifierName(scanner))) {\n var id = result;\n if (id === 'null') {\n return ['NULL', null];\n } else if (id === 'true' || id === 'false') {\n return ['BOOLEAN', id === 'true'];\n } else {\n scanner.pos = startPos; // unconsume `id`\n return ['PATH', scanPath()];\n }\n } else {\n expected('identifier, number, string, boolean, or null');\n }\n };\n\n var type;\n\n var error = function (msg) {\n scanner.fatal(msg);\n };\n\n var expected = function (what) {\n error('Expected ' + what);\n };\n\n // must do ESCAPE first, immediately followed by ELSE\n // order of others doesn't matter\n if (run(starts.ESCAPE)) type = 'ESCAPE';\n else if (run(starts.ELSE)) type = 'ELSE';\n else if (run(starts.DOUBLE)) type = 'DOUBLE';\n else if (run(starts.TRIPLE)) type = 'TRIPLE';\n else if (run(starts.BLOCKCOMMENT)) type = 'BLOCKCOMMENT';\n else if (run(starts.COMMENT)) type = 'COMMENT';\n else if (run(starts.INCLUSION)) type = 'INCLUSION';\n else if (run(starts.BLOCKOPEN)) type = 'BLOCKOPEN';\n else if (run(starts.BLOCKCLOSE)) type = 'BLOCKCLOSE';\n else\n error('Unknown stache tag');\n\n var tag = new TemplateTag;\n tag.type = type;\n\n if (type === 'BLOCKCOMMENT') {\n var result = run(/^[\\s\\S]*?--\\s*?\\}\\}/);\n if (! result)\n error(\"Unclosed block comment\");\n tag.value = result.slice(0, result.lastIndexOf('--'));\n } else if (type === 'COMMENT') {\n var result = run(/^[\\s\\S]*?\\}\\}/);\n if (! result)\n error(\"Unclosed comment\");\n tag.value = result.slice(0, -2);\n } else if (type === 'BLOCKCLOSE') {\n tag.path = scanPath();\n if (! run(ends.DOUBLE))\n expected('`}}`');\n } else if (type === 'ELSE') {\n if (! run(ends.DOUBLE))\n expected('`}}`');\n } else if (type === 'ESCAPE') {\n var result = run(/^\\{*\\|/);\n tag.value = '{{' + result.slice(0, -1);\n } else {\n // DOUBLE, TRIPLE, BLOCKOPEN, INCLUSION\n tag.path = scanPath();\n tag.args = [];\n var foundKwArg = false;\n while (true) {\n run(/^\\s*/);\n if (type === 'TRIPLE') {\n if (run(ends.TRIPLE))\n break;\n else if (scanner.peek() === '}')\n expected('`}}}`');\n } else {\n if (run(ends.DOUBLE))\n break;\n else if (scanner.peek() === '}')\n expected('`}}`');\n }\n var newArg = scanArg();\n if (newArg.length === 3) {\n foundKwArg = true;\n } else {\n if (foundKwArg)\n error(\"Can't have a non-keyword argument after a keyword argument\");\n }\n tag.args.push(newArg);\n\n if (run(/^(?=[\\s}])/) !== '')\n expected('space');\n }\n }\n\n return tag;\n};\n\n// Returns a SpacebarsCompiler.TemplateTag parsed from `scanner`, leaving scanner\n// at its original position.\n//\n// An error will still be thrown if there is not a valid template tag at\n// the current position.\nTemplateTag.peek = function (scanner) {\n var startPos = scanner.pos;\n var result = TemplateTag.parse(scanner);\n scanner.pos = startPos;\n return result;\n};\n\n// Like `TemplateTag.parse`, but in the case of blocks, parse the complete\n// `{{#foo}}...{{/foo}}` with `content` and possible `elseContent`, rather\n// than just the BLOCKOPEN tag.\n//\n// In addition:\n//\n// - Throws an error if `{{else}}` or `{{/foo}}` tag is encountered.\n//\n// - Returns `null` for a COMMENT. (This case is distinguishable from\n// parsing no tag by the fact that the scanner is advanced.)\n//\n// - Takes an HTMLTools.TEMPLATE_TAG_POSITION `position` and sets it as the\n// TemplateTag's `.position` property.\n//\n// - Validates the tag's well-formedness and legality at in its position.\nTemplateTag.parseCompleteTag = function (scannerOrString, position) {\n var scanner = scannerOrString;\n if (typeof scanner === 'string')\n scanner = new HTMLTools.Scanner(scannerOrString);\n\n var startPos = scanner.pos; // for error messages\n var result = TemplateTag.parse(scannerOrString);\n if (! result)\n return result;\n\n if (result.type === 'BLOCKCOMMENT')\n return null;\n\n if (result.type === 'COMMENT')\n return null;\n\n if (result.type === 'ELSE')\n scanner.fatal(\"Unexpected {{else}}\");\n\n if (result.type === 'BLOCKCLOSE')\n scanner.fatal(\"Unexpected closing template tag\");\n\n position = (position || TEMPLATE_TAG_POSITION.ELEMENT);\n if (position !== TEMPLATE_TAG_POSITION.ELEMENT)\n result.position = position;\n\n if (result.type === 'BLOCKOPEN') {\n // parse block contents\n\n // Construct a string version of `.path` for comparing start and\n // end tags. For example, `foo/[0]` was parsed into `[\"foo\", \"0\"]`\n // and now becomes `foo,0`. This form may also show up in error\n // messages.\n var blockName = result.path.join(',');\n\n var textMode = null;\n if (blockName === 'markdown' ||\n position === TEMPLATE_TAG_POSITION.IN_RAWTEXT) {\n textMode = HTML.TEXTMODE.STRING;\n } else if (position === TEMPLATE_TAG_POSITION.IN_RCDATA ||\n position === TEMPLATE_TAG_POSITION.IN_ATTRIBUTE) {\n textMode = HTML.TEXTMODE.RCDATA;\n }\n var parserOptions = {\n getTemplateTag: TemplateTag.parseCompleteTag,\n shouldStop: isAtBlockCloseOrElse,\n textMode: textMode\n };\n result.content = HTMLTools.parseFragment(scanner, parserOptions);\n\n if (scanner.rest().slice(0, 2) !== '{{')\n scanner.fatal(\"Expected {{else}} or block close for \" + blockName);\n\n var lastPos = scanner.pos; // save for error messages\n var tmplTag = TemplateTag.parse(scanner); // {{else}} or {{/foo}}\n\n if (tmplTag.type === 'ELSE') {\n // parse {{else}} and content up to close tag\n result.elseContent = HTMLTools.parseFragment(scanner, parserOptions);\n\n if (scanner.rest().slice(0, 2) !== '{{')\n scanner.fatal(\"Expected block close for \" + blockName);\n\n lastPos = scanner.pos;\n tmplTag = TemplateTag.parse(scanner);\n }\n\n if (tmplTag.type === 'BLOCKCLOSE') {\n var blockName2 = tmplTag.path.join(',');\n if (blockName !== blockName2) {\n scanner.pos = lastPos;\n scanner.fatal('Expected tag to close ' + blockName + ', found ' +\n blockName2);\n }\n } else {\n scanner.pos = lastPos;\n scanner.fatal('Expected tag to close ' + blockName + ', found ' +\n tmplTag.type);\n }\n }\n\n var finalPos = scanner.pos;\n scanner.pos = startPos;\n validateTag(result, scanner);\n scanner.pos = finalPos;\n\n return result;\n};\n\nvar isAtBlockCloseOrElse = function (scanner) {\n // Detect `{{else}}` or `{{/foo}}`.\n //\n // We do as much work ourselves before deferring to `TemplateTag.peek`,\n // for efficiency (we're called for every input token) and to be\n // less obtrusive, because `TemplateTag.peek` will throw an error if it\n // sees `{{` followed by a malformed tag.\n var rest, type;\n return (scanner.peek() === '{' &&\n (rest = scanner.rest()).slice(0, 2) === '{{' &&\n /^\\{\\{\\s*(\\/|else\\b)/.test(rest) &&\n (type = TemplateTag.peek(scanner).type) &&\n (type === 'BLOCKCLOSE' || type === 'ELSE'));\n};\n\n// Validate that `templateTag` is correctly formed and legal for its\n// HTML position. Use `scanner` to report errors. On success, does\n// nothing.\nvar validateTag = function (ttag, scanner) {\n\n if (ttag.type === 'INCLUSION' || ttag.type === 'BLOCKOPEN') {\n var args = ttag.args;\n if (args.length > 1 && args[0].length === 2 && args[0][0] !== 'PATH') {\n // we have a positional argument that is not a PATH followed by\n // other arguments\n scanner.fatal(\"First argument must be a function, to be called on the rest of the arguments; found \" + args[0][0]);\n }\n }\n\n var position = ttag.position || TEMPLATE_TAG_POSITION.ELEMENT;\n if (position === TEMPLATE_TAG_POSITION.IN_ATTRIBUTE) {\n if (ttag.type === 'DOUBLE' || ttag.type === 'ESCAPE') {\n return;\n } else if (ttag.type === 'BLOCKOPEN') {\n var path = ttag.path;\n var path0 = path[0];\n if (! (path.length === 1 && (path0 === 'if' ||\n path0 === 'unless' ||\n path0 === 'with' ||\n path0 === 'each'))) {\n scanner.fatal(\"Custom block helpers are not allowed in an HTML attribute, only built-in ones like #each and #if\");\n }\n } else {\n scanner.fatal(ttag.type + \" template tag is not allowed in an HTML attribute\");\n }\n } else if (position === TEMPLATE_TAG_POSITION.IN_START_TAG) {\n if (! (ttag.type === 'DOUBLE')) {\n scanner.fatal(\"Reactive HTML attributes must either have a constant name or consist of a single {{helper}} providing a dictionary of names and values. A template tag of type \" + ttag.type + \" is not allowed here.\");\n }\n if (scanner.peek() === '=') {\n scanner.fatal(\"Template tags are not allowed in attribute names, only in attribute values or in the form of a single {{helper}} that evaluates to a dictionary of name=value pairs.\");\n }\n }\n\n};\n","// Optimize parts of an HTMLjs tree into raw HTML strings when they don't\n// contain template tags.\n\nvar constant = function (value) {\n return function () { return value; };\n};\n\nvar OPTIMIZABLE = {\n NONE: 0,\n PARTS: 1,\n FULL: 2\n};\n\n// We can only turn content into an HTML string if it contains no template\n// tags and no \"tricky\" HTML tags. If we can optimize the entire content\n// into a string, we return OPTIMIZABLE.FULL. If the we are given an\n// unoptimizable node, we return OPTIMIZABLE.NONE. If we are given a tree\n// that contains an unoptimizable node somewhere, we return OPTIMIZABLE.PARTS.\n//\n// For example, we always create SVG elements programmatically, since SVG\n// doesn't have innerHTML. If we are given an SVG element, we return NONE.\n// However, if we are given a big tree that contains SVG somewhere, we\n// return PARTS so that the optimizer can descend into the tree and optimize\n// other parts of it.\nvar CanOptimizeVisitor = HTML.Visitor.extend();\nCanOptimizeVisitor.def({\n visitNull: constant(OPTIMIZABLE.FULL),\n visitPrimitive: constant(OPTIMIZABLE.FULL),\n visitComment: constant(OPTIMIZABLE.FULL),\n visitCharRef: constant(OPTIMIZABLE.FULL),\n visitRaw: constant(OPTIMIZABLE.FULL),\n visitObject: constant(OPTIMIZABLE.NONE),\n visitFunction: constant(OPTIMIZABLE.NONE),\n visitArray: function (x) {\n for (var i = 0; i < x.length; i++)\n if (this.visit(x[i]) !== OPTIMIZABLE.FULL)\n return OPTIMIZABLE.PARTS;\n return OPTIMIZABLE.FULL;\n },\n visitTag: function (tag) {\n var tagName = tag.tagName;\n if (tagName === 'textarea') {\n // optimizing into a TEXTAREA's RCDATA would require being a little\n // more clever.\n return OPTIMIZABLE.NONE;\n } else if (! (HTML.isKnownElement(tagName) &&\n ! HTML.isKnownSVGElement(tagName))) {\n // foreign elements like SVG can't be stringified for innerHTML.\n return OPTIMIZABLE.NONE;\n } else if (tagName === 'table') {\n // Avoid ever producing HTML containing `<table><tr>...`, because the\n // browser will insert a TBODY. If we just `createElement(\"table\")` and\n // `createElement(\"tr\")`, on the other hand, no TBODY is necessary\n // (assuming IE 8+).\n return OPTIMIZABLE.NONE;\n }\n\n var children = tag.children;\n for (var i = 0; i < children.length; i++)\n if (this.visit(children[i]) !== OPTIMIZABLE.FULL)\n return OPTIMIZABLE.PARTS;\n\n if (this.visitAttributes(tag.attrs) !== OPTIMIZABLE.FULL)\n return OPTIMIZABLE.PARTS;\n\n return OPTIMIZABLE.FULL;\n },\n visitAttributes: function (attrs) {\n if (attrs) {\n var isArray = HTML.isArray(attrs);\n for (var i = 0; i < (isArray ? attrs.length : 1); i++) {\n var a = (isArray ? attrs[i] : attrs);\n if ((typeof a !== 'object') || (a instanceof HTMLTools.TemplateTag))\n return OPTIMIZABLE.PARTS;\n for (var k in a)\n if (this.visit(a[k]) !== OPTIMIZABLE.FULL)\n return OPTIMIZABLE.PARTS;\n }\n }\n return OPTIMIZABLE.FULL;\n }\n});\n\nvar getOptimizability = function (content) {\n return (new CanOptimizeVisitor).visit(content);\n};\n\nvar toRaw = function (x) {\n return HTML.Raw(HTML.toHTML(x));\n};\n\nvar TreeTransformer = HTML.TransformingVisitor.extend();\nTreeTransformer.def({\n visitAttributes: function (attrs/*, ...*/) {\n // pass template tags through by default\n if (attrs instanceof HTMLTools.TemplateTag)\n return attrs;\n\n return HTML.TransformingVisitor.prototype.visitAttributes.apply(\n this, arguments);\n }\n});\n\n// Replace parts of the HTMLjs tree that have no template tags (or\n// tricky HTML tags) with HTML.Raw objects containing raw HTML.\nvar OptimizingVisitor = TreeTransformer.extend();\nOptimizingVisitor.def({\n visitNull: toRaw,\n visitPrimitive: toRaw,\n visitComment: toRaw,\n visitCharRef: toRaw,\n visitArray: function (array) {\n var optimizability = getOptimizability(array);\n if (optimizability === OPTIMIZABLE.FULL) {\n return toRaw(array);\n } else if (optimizability === OPTIMIZABLE.PARTS) {\n return TreeTransformer.prototype.visitArray.call(this, array);\n } else {\n return array;\n }\n },\n visitTag: function (tag) {\n var optimizability = getOptimizability(tag);\n if (optimizability === OPTIMIZABLE.FULL) {\n return toRaw(tag);\n } else if (optimizability === OPTIMIZABLE.PARTS) {\n return TreeTransformer.prototype.visitTag.call(this, tag);\n } else {\n return tag;\n }\n },\n visitChildren: function (children) {\n // don't optimize the children array into a Raw object!\n return TreeTransformer.prototype.visitArray.call(this, children);\n },\n visitAttributes: function (attrs) {\n return attrs;\n }\n});\n\n// Combine consecutive HTML.Raws. Remove empty ones.\nvar RawCompactingVisitor = TreeTransformer.extend();\nRawCompactingVisitor.def({\n visitArray: function (array) {\n var result = [];\n for (var i = 0; i < array.length; i++) {\n var item = array[i];\n if ((item instanceof HTML.Raw) &&\n ((! item.value) ||\n (result.length &&\n (result[result.length - 1] instanceof HTML.Raw)))) {\n // two cases: item is an empty Raw, or previous item is\n // a Raw as well. In the latter case, replace the previous\n // Raw with a longer one that includes the new Raw.\n if (item.value) {\n result[result.length - 1] = HTML.Raw(\n result[result.length - 1].value + item.value);\n }\n } else {\n result.push(item);\n }\n }\n return result;\n }\n});\n\n// Replace pointless Raws like `HTMl.Raw('foo')` that contain no special\n// characters with simple strings.\nvar RawReplacingVisitor = TreeTransformer.extend();\nRawReplacingVisitor.def({\n visitRaw: function (raw) {\n var html = raw.value;\n if (html.indexOf('&') < 0 && html.indexOf('<') < 0) {\n return html;\n } else {\n return raw;\n }\n }\n});\n\nSpacebarsCompiler.optimize = function (tree) {\n tree = (new OptimizingVisitor).visit(tree);\n tree = (new RawCompactingVisitor).visit(tree);\n tree = (new RawReplacingVisitor).visit(tree);\n return tree;\n};\n","// ============================================================\n// Code-generation of template tags\n\n// The `CodeGen` class currently has no instance state, but in theory\n// it could be useful to track per-function state, like whether we\n// need to emit `var self = this` or not.\nvar CodeGen = SpacebarsCompiler.CodeGen = function () {};\n\nvar builtInBlockHelpers = SpacebarsCompiler._builtInBlockHelpers = {\n 'if': 'Blaze.If',\n 'unless': 'Blaze.Unless',\n 'with': 'Spacebars.With',\n 'each': 'Blaze.Each'\n};\n\n\n// Mapping of \"macros\" which, when preceded by `Template.`, expand\n// to special code rather than following the lookup rules for dotted\n// symbols.\nvar builtInTemplateMacros = {\n // `view` is a local variable defined in the generated render\n // function for the template in which `Template.contentBlock` or\n // `Template.elseBlock` is invoked.\n 'contentBlock': 'view.templateContentBlock',\n 'elseBlock': 'view.templateElseBlock',\n\n // Confusingly, this makes `{{> Template.dynamic}}` an alias\n // for `{{> __dynamic}}`, where \"__dynamic\" is the template that\n // implements the dynamic template feature.\n 'dynamic': 'Template.__dynamic',\n\n 'subscriptionsReady': 'view.templateInstance().subscriptionsReady()'\n};\n\n// A \"reserved name\" can't be used as a <template> name. This\n// function is used by the template file scanner.\n//\n// Note that the runtime imposes additional restrictions, for example\n// banning the name \"body\" and names of built-in object properties\n// like \"toString\".\nSpacebarsCompiler.isReservedName = function (name) {\n return builtInBlockHelpers.hasOwnProperty(name) ||\n builtInTemplateMacros.hasOwnProperty(name);\n};\n\nvar makeObjectLiteral = function (obj) {\n var parts = [];\n for (var k in obj)\n parts.push(BlazeTools.toObjectLiteralKey(k) + ': ' + obj[k]);\n return '{' + parts.join(', ') + '}';\n};\n\n_.extend(CodeGen.prototype, {\n codeGenTemplateTag: function (tag) {\n var self = this;\n if (tag.position === HTMLTools.TEMPLATE_TAG_POSITION.IN_START_TAG) {\n // Special dynamic attributes: `<div {{attrs}}>...`\n // only `tag.type === 'DOUBLE'` allowed (by earlier validation)\n return BlazeTools.EmitCode('function () { return ' +\n self.codeGenMustache(tag.path, tag.args, 'attrMustache')\n + '; }');\n } else {\n if (tag.type === 'DOUBLE' || tag.type === 'TRIPLE') {\n var code = self.codeGenMustache(tag.path, tag.args);\n if (tag.type === 'TRIPLE') {\n code = 'Spacebars.makeRaw(' + code + ')';\n }\n if (tag.position !== HTMLTools.TEMPLATE_TAG_POSITION.IN_ATTRIBUTE) {\n // Reactive attributes are already wrapped in a function,\n // and there's no fine-grained reactivity.\n // Anywhere else, we need to create a View.\n code = 'Blaze.View(\"lookup:' + tag.path.join('.') + '\", ' +\n 'function () { return ' + code + '; })';\n }\n return BlazeTools.EmitCode(code);\n } else if (tag.type === 'INCLUSION' || tag.type === 'BLOCKOPEN') {\n var path = tag.path;\n\n if (tag.type === 'BLOCKOPEN' &&\n builtInBlockHelpers.hasOwnProperty(path[0])) {\n // if, unless, with, each.\n //\n // If someone tries to do `{{> if}}`, we don't\n // get here, but an error is thrown when we try to codegen the path.\n\n // Note: If we caught these errors earlier, while scanning, we'd be able to\n // provide nice line numbers.\n if (path.length > 1)\n throw new Error(\"Unexpected dotted path beginning with \" + path[0]);\n if (! tag.args.length)\n throw new Error(\"#\" + path[0] + \" requires an argument\");\n\n // `args` must exist (tag.args.length > 0)\n var dataCode = self.codeGenInclusionDataFunc(tag.args) || 'null';\n // `content` must exist\n var contentBlock = (('content' in tag) ?\n self.codeGenBlock(tag.content) : null);\n // `elseContent` may not exist\n var elseContentBlock = (('elseContent' in tag) ?\n self.codeGenBlock(tag.elseContent) : null);\n\n var callArgs = [dataCode, contentBlock];\n if (elseContentBlock)\n callArgs.push(elseContentBlock);\n\n return BlazeTools.EmitCode(\n builtInBlockHelpers[path[0]] + '(' + callArgs.join(', ') + ')');\n\n } else {\n var compCode = self.codeGenPath(path, {lookupTemplate: true});\n if (path.length > 1) {\n // capture reactivity\n compCode = 'function () { return Spacebars.call(' + compCode +\n '); }';\n }\n\n var dataCode = self.codeGenInclusionDataFunc(tag.args);\n var content = (('content' in tag) ?\n self.codeGenBlock(tag.content) : null);\n var elseContent = (('elseContent' in tag) ?\n self.codeGenBlock(tag.elseContent) : null);\n\n var includeArgs = [compCode];\n if (content) {\n includeArgs.push(content);\n if (elseContent)\n includeArgs.push(elseContent);\n }\n\n var includeCode =\n 'Spacebars.include(' + includeArgs.join(', ') + ')';\n\n // calling convention compat -- set the data context around the\n // entire inclusion, so that if the name of the inclusion is\n // a helper function, it gets the data context in `this`.\n // This makes for a pretty confusing calling convention --\n // In `{{#foo bar}}`, `foo` is evaluated in the context of `bar`\n // -- but it's what we shipped for 0.8.0. The rationale is that\n // `{{#foo bar}}` is sugar for `{{#with bar}}{{#foo}}...`.\n if (dataCode) {\n includeCode =\n 'Blaze._TemplateWith(' + dataCode + ', function () { return ' +\n includeCode + '; })';\n }\n\n // XXX BACK COMPAT - UI is the old name, Template is the new\n if ((path[0] === 'UI' || path[0] === 'Template') &&\n (path[1] === 'contentBlock' || path[1] === 'elseBlock')) {\n // Call contentBlock and elseBlock in the appropriate scope\n includeCode = 'Blaze._InOuterTemplateScope(view, function () { return '\n + includeCode + '; })';\n }\n\n return BlazeTools.EmitCode(includeCode);\n }\n } else if (tag.type === 'ESCAPE') {\n return tag.value;\n } else {\n // Can't get here; TemplateTag validation should catch any\n // inappropriate tag types that might come out of the parser.\n throw new Error(\"Unexpected template tag type: \" + tag.type);\n }\n }\n },\n\n // `path` is an array of at least one string.\n //\n // If `path.length > 1`, the generated code may be reactive\n // (i.e. it may invalidate the current computation).\n //\n // No code is generated to call the result if it's a function.\n //\n // Options:\n //\n // - lookupTemplate {Boolean} If true, generated code also looks in\n // the list of templates. (After helpers, before data context).\n // Used when generating code for `{{> foo}}` or `{{#foo}}`. Only\n // used for non-dotted paths.\n codeGenPath: function (path, opts) {\n if (builtInBlockHelpers.hasOwnProperty(path[0]))\n throw new Error(\"Can't use the built-in '\" + path[0] + \"' here\");\n // Let `{{#if Template.contentBlock}}` check whether this template was\n // invoked via inclusion or as a block helper, in addition to supporting\n // `{{> Template.contentBlock}}`.\n // XXX BACK COMPAT - UI is the old name, Template is the new\n if (path.length >= 2 &&\n (path[0] === 'UI' || path[0] === 'Template')\n && builtInTemplateMacros.hasOwnProperty(path[1])) {\n if (path.length > 2)\n throw new Error(\"Unexpected dotted path beginning with \" +\n path[0] + '.' + path[1]);\n return builtInTemplateMacros[path[1]];\n }\n\n var firstPathItem = BlazeTools.toJSLiteral(path[0]);\n var lookupMethod = 'lookup';\n if (opts && opts.lookupTemplate && path.length === 1)\n lookupMethod = 'lookupTemplate';\n var code = 'view.' + lookupMethod + '(' + firstPathItem + ')';\n\n if (path.length > 1) {\n code = 'Spacebars.dot(' + code + ', ' +\n _.map(path.slice(1), BlazeTools.toJSLiteral).join(', ') + ')';\n }\n\n return code;\n },\n\n // Generates code for an `[argType, argValue]` argument spec,\n // ignoring the third element (keyword argument name) if present.\n //\n // The resulting code may be reactive (in the case of a PATH of\n // more than one element) and is not wrapped in a closure.\n codeGenArgValue: function (arg) {\n var self = this;\n\n var argType = arg[0];\n var argValue = arg[1];\n\n var argCode;\n switch (argType) {\n case 'STRING':\n case 'NUMBER':\n case 'BOOLEAN':\n case 'NULL':\n argCode = BlazeTools.toJSLiteral(argValue);\n break;\n case 'PATH':\n argCode = self.codeGenPath(argValue);\n break;\n default:\n // can't get here\n throw new Error(\"Unexpected arg type: \" + argType);\n }\n\n return argCode;\n },\n\n // Generates a call to `Spacebars.fooMustache` on evaluated arguments.\n // The resulting code has no function literals and must be wrapped in\n // one for fine-grained reactivity.\n codeGenMustache: function (path, args, mustacheType) {\n var self = this;\n\n var nameCode = self.codeGenPath(path);\n var argCode = self.codeGenMustacheArgs(args);\n var mustache = (mustacheType || 'mustache');\n\n return 'Spacebars.' + mustache + '(' + nameCode +\n (argCode ? ', ' + argCode.join(', ') : '') + ')';\n },\n\n // returns: array of source strings, or null if no\n // args at all.\n codeGenMustacheArgs: function (tagArgs) {\n var self = this;\n\n var kwArgs = null; // source -> source\n var args = null; // [source]\n\n // tagArgs may be null\n _.each(tagArgs, function (arg) {\n var argCode = self.codeGenArgValue(arg);\n\n if (arg.length > 2) {\n // keyword argument (represented as [type, value, name])\n kwArgs = (kwArgs || {});\n kwArgs[arg[2]] = argCode;\n } else {\n // positional argument\n args = (args || []);\n args.push(argCode);\n }\n });\n\n // put kwArgs in options dictionary at end of args\n if (kwArgs) {\n args = (args || []);\n args.push('Spacebars.kw(' + makeObjectLiteral(kwArgs) + ')');\n }\n\n return args;\n },\n\n codeGenBlock: function (content) {\n return SpacebarsCompiler.codeGen(content);\n },\n\n codeGenInclusionDataFunc: function (args) {\n var self = this;\n\n var dataFuncCode = null;\n\n if (! args.length) {\n // e.g. `{{#foo}}`\n return null;\n } else if (args[0].length === 3) {\n // keyword arguments only, e.g. `{{> point x=1 y=2}}`\n var dataProps = {};\n _.each(args, function (arg) {\n var argKey = arg[2];\n dataProps[argKey] = 'Spacebars.call(' + self.codeGenArgValue(arg) + ')';\n });\n dataFuncCode = makeObjectLiteral(dataProps);\n } else if (args[0][0] !== 'PATH') {\n // literal first argument, e.g. `{{> foo \"blah\"}}`\n //\n // tag validation has confirmed, in this case, that there is only\n // one argument (`args.length === 1`)\n dataFuncCode = self.codeGenArgValue(args[0]);\n } else if (args.length === 1) {\n // one argument, must be a PATH\n dataFuncCode = 'Spacebars.call(' + self.codeGenPath(args[0][1]) + ')';\n } else {\n // Multiple positional arguments; treat them as a nested\n // \"data mustache\"\n dataFuncCode = self.codeGenMustache(args[0][1], args.slice(1),\n 'dataMustache');\n }\n\n return 'function () { return ' + dataFuncCode + '; }';\n }\n\n});\n","\nSpacebarsCompiler.parse = function (input) {\n\n var tree = HTMLTools.parseFragment(\n input,\n { getTemplateTag: TemplateTag.parseCompleteTag });\n\n return tree;\n};\n\nSpacebarsCompiler.compile = function (input, options) {\n var tree = SpacebarsCompiler.parse(input);\n return SpacebarsCompiler.codeGen(tree, options);\n};\n\nSpacebarsCompiler._TemplateTagReplacer = HTML.TransformingVisitor.extend();\nSpacebarsCompiler._TemplateTagReplacer.def({\n visitObject: function (x) {\n if (x instanceof HTMLTools.TemplateTag) {\n\n // Make sure all TemplateTags in attributes have the right\n // `.position` set on them. This is a bit of a hack\n // (we shouldn't be mutating that here), but it allows\n // cleaner codegen of \"synthetic\" attributes like TEXTAREA's\n // \"value\", where the template tags were originally not\n // in an attribute.\n if (this.inAttributeValue)\n x.position = HTMLTools.TEMPLATE_TAG_POSITION.IN_ATTRIBUTE;\n\n return this.codegen.codeGenTemplateTag(x);\n }\n\n return HTML.TransformingVisitor.prototype.visitObject.call(this, x);\n },\n visitAttributes: function (attrs) {\n if (attrs instanceof HTMLTools.TemplateTag)\n return this.codegen.codeGenTemplateTag(attrs);\n\n // call super (e.g. for case where `attrs` is an array)\n return HTML.TransformingVisitor.prototype.visitAttributes.call(this, attrs);\n },\n visitAttribute: function (name, value, tag) {\n this.inAttributeValue = true;\n var result = this.visit(value);\n this.inAttributeValue = false;\n\n if (result !== value) {\n // some template tags must have been replaced, because otherwise\n // we try to keep things `===` when transforming. Wrap the code\n // in a function as per the rules. You can't have\n // `{id: Blaze.View(...)}` as an attributes dict because the View\n // would be rendered more than once; you need to wrap it in a function\n // so that it's a different View each time.\n return BlazeTools.EmitCode(this.codegen.codeGenBlock(result));\n }\n return result;\n }\n});\n\nSpacebarsCompiler.codeGen = function (parseTree, options) {\n // is this a template, rather than a block passed to\n // a block helper, say\n var isTemplate = (options && options.isTemplate);\n var isBody = (options && options.isBody);\n\n var tree = parseTree;\n\n // The flags `isTemplate` and `isBody` are kind of a hack.\n if (isTemplate || isBody) {\n // optimizing fragments would require being smarter about whether we are\n // in a TEXTAREA, say.\n tree = SpacebarsCompiler.optimize(tree);\n }\n\n var codegen = new SpacebarsCompiler.CodeGen;\n tree = (new SpacebarsCompiler._TemplateTagReplacer(\n {codegen: codegen})).visit(tree);\n\n var code = '(function () { ';\n if (isTemplate || isBody) {\n code += 'var view = this; ';\n }\n code += 'return ';\n code += BlazeTools.toJS(tree);\n code += '; })';\n\n code = SpacebarsCompiler._beautify(code);\n\n return code;\n};\n\nSpacebarsCompiler._beautify = function (code) {\n if (Package.minifiers && Package.minifiers.UglifyJSMinify) {\n var result = Package.minifiers.UglifyJSMinify(\n code,\n { fromString: true,\n mangle: false,\n compress: false,\n output: { beautify: true,\n indent_level: 2,\n width: 80 } });\n var output = result.code;\n // Uglify interprets our expression as a statement and may add a semicolon.\n // Strip trailing semicolon.\n output = output.replace(/;$/, '');\n return output;\n } else {\n // don't actually beautify; no UglifyJS\n return code;\n }\n};\n"]}