NOBUG: Fixed file access permissions
[moodle.git] / lib / yuilib / 3.13.0 / handlebars-compiler / handlebars-compiler-debug.js
blobf195bd06f7459b6b03008e37eb7d5e60647d951d
1 /*
2 YUI 3.13.0 (build 508226d)
3 Copyright 2013 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
6 */
8 YUI.add('handlebars-compiler', function (Y, NAME) {
10 /*!
11 Handlebars.js - Copyright (C) 2011 Yehuda Katz
12 https://raw.github.com/wycats/handlebars.js/master/LICENSE
14 // This file contains code that will be inserted at the beginning of the
15 // handlebars-compiler module.
17 // This is necessary because the Y.Handlebars object is created in the
18 // handlebars-base module, but the native Handlebars code expects to use a local
19 // Handlebars reference.
20 var Handlebars = Y.Handlebars;
21 /* THIS FILE IS GENERATED BY A BUILD SCRIPT - DO NOT EDIT! */
23 /* Jison generated parser */
24 var handlebars = (function(){
25 var parser = {trace: function trace() { },
26 yy: {},
27 symbols_: {"error":2,"root":3,"program":4,"EOF":5,"simpleInverse":6,"statements":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"params":27,"hash":28,"dataName":29,"param":30,"STRING":31,"INTEGER":32,"BOOLEAN":33,"hashSegments":34,"hashSegment":35,"ID":36,"EQUALS":37,"DATA":38,"pathSegments":39,"SEP":40,"$accept":0,"$end":1},
28 terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",31:"STRING",32:"INTEGER",33:"BOOLEAN",36:"ID",37:"EQUALS",38:"DATA",40:"SEP"},
29 productions_: [0,[3,2],[4,2],[4,3],[4,2],[4,1],[4,1],[4,0],[7,1],[7,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[6,2],[17,3],[17,2],[17,2],[17,1],[17,1],[27,2],[27,1],[30,1],[30,1],[30,1],[30,1],[30,1],[28,1],[34,2],[34,1],[35,3],[35,3],[35,3],[35,3],[35,3],[26,1],[26,1],[26,1],[29,2],[21,1],[39,3],[39,1]],
30 performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
32 var $0 = $$.length - 1;
33 switch (yystate) {
34 case 1: return $$[$0-1];
35 break;
36 case 2: this.$ = new yy.ProgramNode([], $$[$0]);
37 break;
38 case 3: this.$ = new yy.ProgramNode($$[$0-2], $$[$0]);
39 break;
40 case 4: this.$ = new yy.ProgramNode($$[$0-1], []);
41 break;
42 case 5: this.$ = new yy.ProgramNode($$[$0]);
43 break;
44 case 6: this.$ = new yy.ProgramNode([], []);
45 break;
46 case 7: this.$ = new yy.ProgramNode([]);
47 break;
48 case 8: this.$ = [$$[$0]];
49 break;
50 case 9: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
51 break;
52 case 10: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0]);
53 break;
54 case 11: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0]);
55 break;
56 case 12: this.$ = $$[$0];
57 break;
58 case 13: this.$ = $$[$0];
59 break;
60 case 14: this.$ = new yy.ContentNode($$[$0]);
61 break;
62 case 15: this.$ = new yy.CommentNode($$[$0]);
63 break;
64 case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
65 break;
66 case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
67 break;
68 case 18: this.$ = $$[$0-1];
69 break;
70 case 19:
71     // Parsing out the '&' escape token at this level saves ~500 bytes after min due to the removal of one parser node.
72     this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], $$[$0-2][2] === '&');
74 break;
75 case 20: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true);
76 break;
77 case 21: this.$ = new yy.PartialNode($$[$0-1]);
78 break;
79 case 22: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1]);
80 break;
81 case 23:
82 break;
83 case 24: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]];
84 break;
85 case 25: this.$ = [[$$[$0-1]].concat($$[$0]), null];
86 break;
87 case 26: this.$ = [[$$[$0-1]], $$[$0]];
88 break;
89 case 27: this.$ = [[$$[$0]], null];
90 break;
91 case 28: this.$ = [[$$[$0]], null];
92 break;
93 case 29: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
94 break;
95 case 30: this.$ = [$$[$0]];
96 break;
97 case 31: this.$ = $$[$0];
98 break;
99 case 32: this.$ = new yy.StringNode($$[$0]);
100 break;
101 case 33: this.$ = new yy.IntegerNode($$[$0]);
102 break;
103 case 34: this.$ = new yy.BooleanNode($$[$0]);
104 break;
105 case 35: this.$ = $$[$0];
106 break;
107 case 36: this.$ = new yy.HashNode($$[$0]);
108 break;
109 case 37: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
110 break;
111 case 38: this.$ = [$$[$0]];
112 break;
113 case 39: this.$ = [$$[$0-2], $$[$0]];
114 break;
115 case 40: this.$ = [$$[$0-2], new yy.StringNode($$[$0])];
116 break;
117 case 41: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])];
118 break;
119 case 42: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])];
120 break;
121 case 43: this.$ = [$$[$0-2], $$[$0]];
122 break;
123 case 44: this.$ = new yy.PartialNameNode($$[$0]);
124 break;
125 case 45: this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0]));
126 break;
127 case 46: this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0]));
128 break;
129 case 47: this.$ = new yy.DataNode($$[$0]);
130 break;
131 case 48: this.$ = new yy.IdNode($$[$0]);
132 break;
133 case 49: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
134 break;
135 case 50: this.$ = [{part: $$[$0]}];
136 break;
139 table: [{3:1,4:2,5:[2,7],6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],22:[1,14],23:[1,15],25:[1,16]},{1:[3]},{5:[1,17]},{5:[2,6],7:18,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,6],22:[1,14],23:[1,15],25:[1,16]},{5:[2,5],6:20,8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,5],22:[1,14],23:[1,15],25:[1,16]},{17:23,18:[1,22],21:24,29:25,36:[1,28],38:[1,27],39:26},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],25:[2,8]},{4:29,6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,7],22:[1,14],23:[1,15],25:[1,16]},{4:30,6:3,7:4,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,5],20:[2,7],22:[1,14],23:[1,15],25:[1,16]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{17:31,21:24,29:25,36:[1,28],38:[1,27],39:26},{17:32,21:24,29:25,36:[1,28],38:[1,27],39:26},{17:33,21:24,29:25,36:[1,28],38:[1,27],39:26},{21:35,26:34,31:[1,36],32:[1,37],36:[1,28],39:26},{1:[2,1]},{5:[2,2],8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,2],22:[1,14],23:[1,15],25:[1,16]},{17:23,21:24,29:25,36:[1,28],38:[1,27],39:26},{5:[2,4],7:38,8:6,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,4],22:[1,14],23:[1,15],25:[1,16]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{5:[2,23],14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{18:[1,39]},{18:[2,27],21:44,24:[2,27],27:40,28:41,29:48,30:42,31:[1,45],32:[1,46],33:[1,47],34:43,35:49,36:[1,50],38:[1,27],39:26},{18:[2,28],24:[2,28]},{18:[2,48],24:[2,48],31:[2,48],32:[2,48],33:[2,48],36:[2,48],38:[2,48],40:[1,51]},{21:52,36:[1,28],39:26},{18:[2,50],24:[2,50],31:[2,50],32:[2,50],33:[2,50],36:[2,50],38:[2,50],40:[2,50]},{10:53,20:[1,54]},{10:55,20:[1,54]},{18:[1,56]},{18:[1,57]},{24:[1,58]},{18:[1,59],21:60,36:[1,28],39:26},{18:[2,44],36:[2,44]},{18:[2,45],36:[2,45]},{18:[2,46],36:[2,46]},{5:[2,3],8:21,9:7,11:8,12:9,13:10,14:[1,11],15:[1,12],16:[1,13],19:[1,19],20:[2,3],22:[1,14],23:[1,15],25:[1,16]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{18:[2,25],21:44,24:[2,25],28:61,29:48,30:62,31:[1,45],32:[1,46],33:[1,47],34:43,35:49,36:[1,50],38:[1,27],39:26},{18:[2,26],24:[2,26]},{18:[2,30],24:[2,30],31:[2,30],32:[2,30],33:[2,30],36:[2,30],38:[2,30]},{18:[2,36],24:[2,36],35:63,36:[1,64]},{18:[2,31],24:[2,31],31:[2,31],32:[2,31],33:[2,31],36:[2,31],38:[2,31]},{18:[2,32],24:[2,32],31:[2,32],32:[2,32],33:[2,32],36:[2,32],38:[2,32]},{18:[2,33],24:[2,33],31:[2,33],32:[2,33],33:[2,33],36:[2,33],38:[2,33]},{18:[2,34],24:[2,34],31:[2,34],32:[2,34],33:[2,34],36:[2,34],38:[2,34]},{18:[2,35],24:[2,35],31:[2,35],32:[2,35],33:[2,35],36:[2,35],38:[2,35]},{18:[2,38],24:[2,38],36:[2,38]},{18:[2,50],24:[2,50],31:[2,50],32:[2,50],33:[2,50],36:[2,50],37:[1,65],38:[2,50],40:[2,50]},{36:[1,66]},{18:[2,47],24:[2,47],31:[2,47],32:[2,47],33:[2,47],36:[2,47],38:[2,47]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{21:67,36:[1,28],39:26},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,68]},{18:[2,24],24:[2,24]},{18:[2,29],24:[2,29],31:[2,29],32:[2,29],33:[2,29],36:[2,29],38:[2,29]},{18:[2,37],24:[2,37],36:[2,37]},{37:[1,65]},{21:69,29:73,31:[1,70],32:[1,71],33:[1,72],36:[1,28],38:[1,27],39:26},{18:[2,49],24:[2,49],31:[2,49],32:[2,49],33:[2,49],36:[2,49],38:[2,49],40:[2,49]},{18:[1,74]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{18:[2,39],24:[2,39],36:[2,39]},{18:[2,40],24:[2,40],36:[2,40]},{18:[2,41],24:[2,41],36:[2,41]},{18:[2,42],24:[2,42],36:[2,42]},{18:[2,43],24:[2,43],36:[2,43]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]}],
140 defaultActions: {17:[2,1]},
141 parseError: function parseError(str, hash) {
142     throw new Error(str);
144 parse: function parse(input) {
145     var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
146     this.lexer.setInput(input);
147     this.lexer.yy = this.yy;
148     this.yy.lexer = this.lexer;
149     this.yy.parser = this;
150     if (typeof this.lexer.yylloc == "undefined")
151         this.lexer.yylloc = {};
152     var yyloc = this.lexer.yylloc;
153     lstack.push(yyloc);
154     var ranges = this.lexer.options && this.lexer.options.ranges;
155     if (typeof this.yy.parseError === "function")
156         this.parseError = this.yy.parseError;
157     function popStack(n) {
158         stack.length = stack.length - 2 * n;
159         vstack.length = vstack.length - n;
160         lstack.length = lstack.length - n;
161     }
162     function lex() {
163         var token;
164         token = self.lexer.lex() || 1;
165         if (typeof token !== "number") {
166             token = self.symbols_[token] || token;
167         }
168         return token;
169     }
170     var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
171     while (true) {
172         state = stack[stack.length - 1];
173         if (this.defaultActions[state]) {
174             action = this.defaultActions[state];
175         } else {
176             if (symbol === null || typeof symbol == "undefined") {
177                 symbol = lex();
178             }
179             action = table[state] && table[state][symbol];
180         }
181         if (typeof action === "undefined" || !action.length || !action[0]) {
182             var errStr = "";
183             if (!recovering) {
184                 expected = [];
185                 for (p in table[state])
186                     if (this.terminals_[p] && p > 2) {
187                         expected.push("'" + this.terminals_[p] + "'");
188                     }
189                 if (this.lexer.showPosition) {
190                     errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
191                 } else {
192                     errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
193                 }
194                 this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
195             }
196         }
197         if (action[0] instanceof Array && action.length > 1) {
198             throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
199         }
200         switch (action[0]) {
201         case 1:
202             stack.push(symbol);
203             vstack.push(this.lexer.yytext);
204             lstack.push(this.lexer.yylloc);
205             stack.push(action[1]);
206             symbol = null;
207             if (!preErrorSymbol) {
208                 yyleng = this.lexer.yyleng;
209                 yytext = this.lexer.yytext;
210                 yylineno = this.lexer.yylineno;
211                 yyloc = this.lexer.yylloc;
212                 if (recovering > 0)
213                     recovering--;
214             } else {
215                 symbol = preErrorSymbol;
216                 preErrorSymbol = null;
217             }
218             break;
219         case 2:
220             len = this.productions_[action[1]][1];
221             yyval.$ = vstack[vstack.length - len];
222             yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
223             if (ranges) {
224                 yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
225             }
226             r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
227             if (typeof r !== "undefined") {
228                 return r;
229             }
230             if (len) {
231                 stack = stack.slice(0, -1 * len * 2);
232                 vstack = vstack.slice(0, -1 * len);
233                 lstack = lstack.slice(0, -1 * len);
234             }
235             stack.push(this.productions_[action[1]][0]);
236             vstack.push(yyval.$);
237             lstack.push(yyval._$);
238             newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
239             stack.push(newState);
240             break;
241         case 3:
242             return true;
243         }
244     }
245     return true;
248 /* Jison generated lexer */
249 var lexer = (function(){
250 var lexer = ({EOF:1,
251 parseError:function parseError(str, hash) {
252         if (this.yy.parser) {
253             this.yy.parser.parseError(str, hash);
254         } else {
255             throw new Error(str);
256         }
257     },
258 setInput:function (input) {
259         this._input = input;
260         this._more = this._less = this.done = false;
261         this.yylineno = this.yyleng = 0;
262         this.yytext = this.matched = this.match = '';
263         this.conditionStack = ['INITIAL'];
264         this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
265         if (this.options.ranges) this.yylloc.range = [0,0];
266         this.offset = 0;
267         return this;
268     },
269 input:function () {
270         var ch = this._input[0];
271         this.yytext += ch;
272         this.yyleng++;
273         this.offset++;
274         this.match += ch;
275         this.matched += ch;
276         var lines = ch.match(/(?:\r\n?|\n).*/g);
277         if (lines) {
278             this.yylineno++;
279             this.yylloc.last_line++;
280         } else {
281             this.yylloc.last_column++;
282         }
283         if (this.options.ranges) this.yylloc.range[1]++;
285         this._input = this._input.slice(1);
286         return ch;
287     },
288 unput:function (ch) {
289         var len = ch.length;
290         var lines = ch.split(/(?:\r\n?|\n)/g);
292         this._input = ch + this._input;
293         this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
294         //this.yyleng -= len;
295         this.offset -= len;
296         var oldLines = this.match.split(/(?:\r\n?|\n)/g);
297         this.match = this.match.substr(0, this.match.length-1);
298         this.matched = this.matched.substr(0, this.matched.length-1);
300         if (lines.length-1) this.yylineno -= lines.length-1;
301         var r = this.yylloc.range;
303         this.yylloc = {first_line: this.yylloc.first_line,
304           last_line: this.yylineno+1,
305           first_column: this.yylloc.first_column,
306           last_column: lines ?
307               (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
308               this.yylloc.first_column - len
309           };
311         if (this.options.ranges) {
312             this.yylloc.range = [r[0], r[0] + this.yyleng - len];
313         }
314         return this;
315     },
316 more:function () {
317         this._more = true;
318         return this;
319     },
320 less:function (n) {
321         this.unput(this.match.slice(n));
322     },
323 pastInput:function () {
324         var past = this.matched.substr(0, this.matched.length - this.match.length);
325         return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
326     },
327 upcomingInput:function () {
328         var next = this.match;
329         if (next.length < 20) {
330             next += this._input.substr(0, 20-next.length);
331         }
332         return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
333     },
334 showPosition:function () {
335         var pre = this.pastInput();
336         var c = new Array(pre.length + 1).join("-");
337         return pre + this.upcomingInput() + "\n" + c+"^";
338     },
339 next:function () {
340         if (this.done) {
341             return this.EOF;
342         }
343         if (!this._input) this.done = true;
345         var token,
346             match,
347             tempMatch,
348             index,
349             col,
350             lines;
351         if (!this._more) {
352             this.yytext = '';
353             this.match = '';
354         }
355         var rules = this._currentRules();
356         for (var i=0;i < rules.length; i++) {
357             tempMatch = this._input.match(this.rules[rules[i]]);
358             if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
359                 match = tempMatch;
360                 index = i;
361                 if (!this.options.flex) break;
362             }
363         }
364         if (match) {
365             lines = match[0].match(/(?:\r\n?|\n).*/g);
366             if (lines) this.yylineno += lines.length;
367             this.yylloc = {first_line: this.yylloc.last_line,
368                            last_line: this.yylineno+1,
369                            first_column: this.yylloc.last_column,
370                            last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
371             this.yytext += match[0];
372             this.match += match[0];
373             this.matches = match;
374             this.yyleng = this.yytext.length;
375             if (this.options.ranges) {
376                 this.yylloc.range = [this.offset, this.offset += this.yyleng];
377             }
378             this._more = false;
379             this._input = this._input.slice(match[0].length);
380             this.matched += match[0];
381             token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
382             if (this.done && this._input) this.done = false;
383             if (token) return token;
384             else return;
385         }
386         if (this._input === "") {
387             return this.EOF;
388         } else {
389             return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
390                     {text: "", token: null, line: this.yylineno});
391         }
392     },
393 lex:function lex() {
394         var r = this.next();
395         if (typeof r !== 'undefined') {
396             return r;
397         } else {
398             return this.lex();
399         }
400     },
401 begin:function begin(condition) {
402         this.conditionStack.push(condition);
403     },
404 popState:function popState() {
405         return this.conditionStack.pop();
406     },
407 _currentRules:function _currentRules() {
408         return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
409     },
410 topState:function () {
411         return this.conditionStack[this.conditionStack.length-2];
412     },
413 pushState:function begin(condition) {
414         this.begin(condition);
415     }});
416 lexer.options = {};
417 lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
419 var YYSTATE=YY_START
420 switch($avoiding_name_collisions) {
421 case 0: yy_.yytext = "\\"; return 14;
422 break;
423 case 1:
424                                    if(yy_.yytext.slice(-1) !== "\\") this.begin("mu");
425                                    if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1), this.begin("emu");
426                                    if(yy_.yytext) return 14;
428 break;
429 case 2: return 14;
430 break;
431 case 3:
432                                    if(yy_.yytext.slice(-1) !== "\\") this.popState();
433                                    if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1);
434                                    return 14;
436 break;
437 case 4: yy_.yytext = yy_.yytext.substr(0, yy_.yyleng-4); this.popState(); return 15;
438 break;
439 case 5: return 25;
440 break;
441 case 6: return 16;
442 break;
443 case 7: return 20;
444 break;
445 case 8: return 19;
446 break;
447 case 9: return 19;
448 break;
449 case 10: return 23;
450 break;
451 case 11: return 22;
452 break;
453 case 12: this.popState(); this.begin('com');
454 break;
455 case 13: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15;
456 break;
457 case 14: return 22;
458 break;
459 case 15: return 37;
460 break;
461 case 16: return 36;
462 break;
463 case 17: return 36;
464 break;
465 case 18: return 40;
466 break;
467 case 19: /*ignore whitespace*/
468 break;
469 case 20: this.popState(); return 24;
470 break;
471 case 21: this.popState(); return 18;
472 break;
473 case 22: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 31;
474 break;
475 case 23: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\'/g,"'"); return 31;
476 break;
477 case 24: return 38;
478 break;
479 case 25: return 33;
480 break;
481 case 26: return 33;
482 break;
483 case 27: return 32;
484 break;
485 case 28: return 36;
486 break;
487 case 29: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 36;
488 break;
489 case 30: return 'INVALID';
490 break;
491 case 31: return 5;
492 break;
495 lexer.rules = [/^(?:\\\\(?=(\{\{)))/,/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[}\/ ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:-?[0-9]+(?=[}\s]))/,/^(?:[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
496 lexer.conditions = {"mu":{"rules":[5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31],"inclusive":false},"emu":{"rules":[3],"inclusive":false},"com":{"rules":[4],"inclusive":false},"INITIAL":{"rules":[0,1,2,31],"inclusive":true}};
497 return lexer;})()
498 parser.lexer = lexer;
499 function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
500 return new Parser;
501 })();
502 /* THIS FILE IS GENERATED BY A BUILD SCRIPT - DO NOT EDIT! */
504 Handlebars.Parser = handlebars;
506 Handlebars.parse = function(input) {
508   // Just return if an already-compile AST was passed in.
509   if(input.constructor === Handlebars.AST.ProgramNode) { return input; }
511   Handlebars.Parser.yy = Handlebars.AST;
512   return Handlebars.Parser.parse(input);
514 /* THIS FILE IS GENERATED BY A BUILD SCRIPT - DO NOT EDIT! */
516 Handlebars.AST = {};
518 Handlebars.AST.ProgramNode = function(statements, inverse) {
519   this.type = "program";
520   this.statements = statements;
521   if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
524 Handlebars.AST.MustacheNode = function(rawParams, hash, unescaped) {
525   this.type = "mustache";
526   this.escaped = !unescaped;
527   this.hash = hash;
529   var id = this.id = rawParams[0];
530   var params = this.params = rawParams.slice(1);
532   // a mustache is an eligible helper if:
533   // * its id is simple (a single part, not `this` or `..`)
534   var eligibleHelper = this.eligibleHelper = id.isSimple;
536   // a mustache is definitely a helper if:
537   // * it is an eligible helper, and
538   // * it has at least one parameter or hash segment
539   this.isHelper = eligibleHelper && (params.length || hash);
541   // if a mustache is an eligible helper but not a definite
542   // helper, it is ambiguous, and will be resolved in a later
543   // pass or at runtime.
546 Handlebars.AST.PartialNode = function(partialName, context) {
547   this.type         = "partial";
548   this.partialName  = partialName;
549   this.context      = context;
552 Handlebars.AST.BlockNode = function(mustache, program, inverse, close) {
553   var verifyMatch = function(open, close) {
554     if(open.original !== close.original) {
555       throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
556     }
557   };
559   verifyMatch(mustache.id, close);
560   this.type = "block";
561   this.mustache = mustache;
562   this.program  = program;
563   this.inverse  = inverse;
565   if (this.inverse && !this.program) {
566     this.isInverse = true;
567   }
570 Handlebars.AST.ContentNode = function(string) {
571   this.type = "content";
572   this.string = string;
575 Handlebars.AST.HashNode = function(pairs) {
576   this.type = "hash";
577   this.pairs = pairs;
580 Handlebars.AST.IdNode = function(parts) {
581   this.type = "ID";
583   var original = "",
584       dig = [],
585       depth = 0;
587   for(var i=0,l=parts.length; i<l; i++) {
588     var part = parts[i].part;
589     original += (parts[i].separator || '') + part;
591     if (part === ".." || part === "." || part === "this") {
592       if (dig.length > 0) { throw new Handlebars.Exception("Invalid path: " + original); }
593       else if (part === "..") { depth++; }
594       else { this.isScoped = true; }
595     }
596     else { dig.push(part); }
597   }
599   this.original = original;
600   this.parts    = dig;
601   this.string   = dig.join('.');
602   this.depth    = depth;
604   // an ID is simple if it only has one part, and that part is not
605   // `..` or `this`.
606   this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
608   this.stringModeValue = this.string;
611 Handlebars.AST.PartialNameNode = function(name) {
612   this.type = "PARTIAL_NAME";
613   this.name = name.original;
616 Handlebars.AST.DataNode = function(id) {
617   this.type = "DATA";
618   this.id = id;
621 Handlebars.AST.StringNode = function(string) {
622   this.type = "STRING";
623   this.original =
624     this.string =
625     this.stringModeValue = string;
628 Handlebars.AST.IntegerNode = function(integer) {
629   this.type = "INTEGER";
630   this.original =
631     this.integer = integer;
632   this.stringModeValue = Number(integer);
635 Handlebars.AST.BooleanNode = function(bool) {
636   this.type = "BOOLEAN";
637   this.bool = bool;
638   this.stringModeValue = bool === "true";
641 Handlebars.AST.CommentNode = function(comment) {
642   this.type = "comment";
643   this.comment = comment;
645 /* THIS FILE IS GENERATED BY A BUILD SCRIPT - DO NOT EDIT! */
647 /*jshint eqnull:true*/
648 var Compiler = Handlebars.Compiler = function() {};
649 var JavaScriptCompiler = Handlebars.JavaScriptCompiler = function() {};
651 // the foundHelper register will disambiguate helper lookup from finding a
652 // function in a context. This is necessary for mustache compatibility, which
653 // requires that context functions in blocks are evaluated by blockHelperMissing,
654 // and then proceed as if the resulting value was provided to blockHelperMissing.
656 Compiler.prototype = {
657   compiler: Compiler,
659   disassemble: function() {
660     var opcodes = this.opcodes, opcode, out = [], params, param;
662     for (var i=0, l=opcodes.length; i<l; i++) {
663       opcode = opcodes[i];
665       if (opcode.opcode === 'DECLARE') {
666         out.push("DECLARE " + opcode.name + "=" + opcode.value);
667       } else {
668         params = [];
669         for (var j=0; j<opcode.args.length; j++) {
670           param = opcode.args[j];
671           if (typeof param === "string") {
672             param = "\"" + param.replace("\n", "\\n") + "\"";
673           }
674           params.push(param);
675         }
676         out.push(opcode.opcode + " " + params.join(" "));
677       }
678     }
680     return out.join("\n");
681   },
682   equals: function(other) {
683     var len = this.opcodes.length;
684     if (other.opcodes.length !== len) {
685       return false;
686     }
688     for (var i = 0; i < len; i++) {
689       var opcode = this.opcodes[i],
690           otherOpcode = other.opcodes[i];
691       if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
692         return false;
693       }
694       for (var j = 0; j < opcode.args.length; j++) {
695         if (opcode.args[j] !== otherOpcode.args[j]) {
696           return false;
697         }
698       }
699     }
701     len = this.children.length;
702     if (other.children.length !== len) {
703       return false;
704     }
705     for (i = 0; i < len; i++) {
706       if (!this.children[i].equals(other.children[i])) {
707         return false;
708       }
709     }
711     return true;
712   },
714   guid: 0,
716   compile: function(program, options) {
717     this.children = [];
718     this.depths = {list: []};
719     this.options = options;
721     // These changes will propagate to the other compiler components
722     var knownHelpers = this.options.knownHelpers;
723     this.options.knownHelpers = {
724       'helperMissing': true,
725       'blockHelperMissing': true,
726       'each': true,
727       'if': true,
728       'unless': true,
729       'with': true,
730       'log': true
731     };
732     if (knownHelpers) {
733       for (var name in knownHelpers) {
734         this.options.knownHelpers[name] = knownHelpers[name];
735       }
736     }
738     return this.program(program);
739   },
741   accept: function(node) {
742     return this[node.type](node);
743   },
745   program: function(program) {
746     var statements = program.statements, statement;
747     this.opcodes = [];
749     for(var i=0, l=statements.length; i<l; i++) {
750       statement = statements[i];
751       this[statement.type](statement);
752     }
753     this.isSimple = l === 1;
755     this.depths.list = this.depths.list.sort(function(a, b) {
756       return a - b;
757     });
759     return this;
760   },
762   compileProgram: function(program) {
763     var result = new this.compiler().compile(program, this.options);
764     var guid = this.guid++, depth;
766     this.usePartial = this.usePartial || result.usePartial;
768     this.children[guid] = result;
770     for(var i=0, l=result.depths.list.length; i<l; i++) {
771       depth = result.depths.list[i];
773       if(depth < 2) { continue; }
774       else { this.addDepth(depth - 1); }
775     }
777     return guid;
778   },
780   block: function(block) {
781     var mustache = block.mustache,
782         program = block.program,
783         inverse = block.inverse;
785     if (program) {
786       program = this.compileProgram(program);
787     }
789     if (inverse) {
790       inverse = this.compileProgram(inverse);
791     }
793     var type = this.classifyMustache(mustache);
795     if (type === "helper") {
796       this.helperMustache(mustache, program, inverse);
797     } else if (type === "simple") {
798       this.simpleMustache(mustache);
800       // now that the simple mustache is resolved, we need to
801       // evaluate it by executing `blockHelperMissing`
802       this.opcode('pushProgram', program);
803       this.opcode('pushProgram', inverse);
804       this.opcode('emptyHash');
805       this.opcode('blockValue');
806     } else {
807       this.ambiguousMustache(mustache, program, inverse);
809       // now that the simple mustache is resolved, we need to
810       // evaluate it by executing `blockHelperMissing`
811       this.opcode('pushProgram', program);
812       this.opcode('pushProgram', inverse);
813       this.opcode('emptyHash');
814       this.opcode('ambiguousBlockValue');
815     }
817     this.opcode('append');
818   },
820   hash: function(hash) {
821     var pairs = hash.pairs, pair, val;
823     this.opcode('pushHash');
825     for(var i=0, l=pairs.length; i<l; i++) {
826       pair = pairs[i];
827       val  = pair[1];
829       if (this.options.stringParams) {
830         if(val.depth) {
831           this.addDepth(val.depth);
832         }
833         this.opcode('getContext', val.depth || 0);
834         this.opcode('pushStringParam', val.stringModeValue, val.type);
835       } else {
836         this.accept(val);
837       }
839       this.opcode('assignToHash', pair[0]);
840     }
841     this.opcode('popHash');
842   },
844   partial: function(partial) {
845     var partialName = partial.partialName;
846     this.usePartial = true;
848     if(partial.context) {
849       this.ID(partial.context);
850     } else {
851       this.opcode('push', 'depth0');
852     }
854     this.opcode('invokePartial', partialName.name);
855     this.opcode('append');
856   },
858   content: function(content) {
859     this.opcode('appendContent', content.string);
860   },
862   mustache: function(mustache) {
863     var options = this.options;
864     var type = this.classifyMustache(mustache);
866     if (type === "simple") {
867       this.simpleMustache(mustache);
868     } else if (type === "helper") {
869       this.helperMustache(mustache);
870     } else {
871       this.ambiguousMustache(mustache);
872     }
874     if(mustache.escaped && !options.noEscape) {
875       this.opcode('appendEscaped');
876     } else {
877       this.opcode('append');
878     }
879   },
881   ambiguousMustache: function(mustache, program, inverse) {
882     var id = mustache.id,
883         name = id.parts[0],
884         isBlock = program != null || inverse != null;
886     this.opcode('getContext', id.depth);
888     this.opcode('pushProgram', program);
889     this.opcode('pushProgram', inverse);
891     this.opcode('invokeAmbiguous', name, isBlock);
892   },
894   simpleMustache: function(mustache) {
895     var id = mustache.id;
897     if (id.type === 'DATA') {
898       this.DATA(id);
899     } else if (id.parts.length) {
900       this.ID(id);
901     } else {
902       // Simplified ID for `this`
903       this.addDepth(id.depth);
904       this.opcode('getContext', id.depth);
905       this.opcode('pushContext');
906     }
908     this.opcode('resolvePossibleLambda');
909   },
911   helperMustache: function(mustache, program, inverse) {
912     var params = this.setupFullMustacheParams(mustache, program, inverse),
913         name = mustache.id.parts[0];
915     if (this.options.knownHelpers[name]) {
916       this.opcode('invokeKnownHelper', params.length, name);
917     } else if (this.options.knownHelpersOnly) {
918       throw new Error("You specified knownHelpersOnly, but used the unknown helper " + name);
919     } else {
920       this.opcode('invokeHelper', params.length, name);
921     }
922   },
924   ID: function(id) {
925     this.addDepth(id.depth);
926     this.opcode('getContext', id.depth);
928     var name = id.parts[0];
929     if (!name) {
930       this.opcode('pushContext');
931     } else {
932       this.opcode('lookupOnContext', id.parts[0]);
933     }
935     for(var i=1, l=id.parts.length; i<l; i++) {
936       this.opcode('lookup', id.parts[i]);
937     }
938   },
940   DATA: function(data) {
941     this.options.data = true;
942     if (data.id.isScoped || data.id.depth) {
943       throw new Handlebars.Exception('Scoped data references are not supported: ' + data.original);
944     }
946     this.opcode('lookupData');
947     var parts = data.id.parts;
948     for(var i=0, l=parts.length; i<l; i++) {
949       this.opcode('lookup', parts[i]);
950     }
951   },
953   STRING: function(string) {
954     this.opcode('pushString', string.string);
955   },
957   INTEGER: function(integer) {
958     this.opcode('pushLiteral', integer.integer);
959   },
961   BOOLEAN: function(bool) {
962     this.opcode('pushLiteral', bool.bool);
963   },
965   comment: function() {},
967   // HELPERS
968   opcode: function(name) {
969     this.opcodes.push({ opcode: name, args: [].slice.call(arguments, 1) });
970   },
972   declare: function(name, value) {
973     this.opcodes.push({ opcode: 'DECLARE', name: name, value: value });
974   },
976   addDepth: function(depth) {
977     if(isNaN(depth)) { throw new Error("EWOT"); }
978     if(depth === 0) { return; }
980     if(!this.depths[depth]) {
981       this.depths[depth] = true;
982       this.depths.list.push(depth);
983     }
984   },
986   classifyMustache: function(mustache) {
987     var isHelper   = mustache.isHelper;
988     var isEligible = mustache.eligibleHelper;
989     var options    = this.options;
991     // if ambiguous, we can possibly resolve the ambiguity now
992     if (isEligible && !isHelper) {
993       var name = mustache.id.parts[0];
995       if (options.knownHelpers[name]) {
996         isHelper = true;
997       } else if (options.knownHelpersOnly) {
998         isEligible = false;
999       }
1000     }
1002     if (isHelper) { return "helper"; }
1003     else if (isEligible) { return "ambiguous"; }
1004     else { return "simple"; }
1005   },
1007   pushParams: function(params) {
1008     var i = params.length, param;
1010     while(i--) {
1011       param = params[i];
1013       if(this.options.stringParams) {
1014         if(param.depth) {
1015           this.addDepth(param.depth);
1016         }
1018         this.opcode('getContext', param.depth || 0);
1019         this.opcode('pushStringParam', param.stringModeValue, param.type);
1020       } else {
1021         this[param.type](param);
1022       }
1023     }
1024   },
1026   setupMustacheParams: function(mustache) {
1027     var params = mustache.params;
1028     this.pushParams(params);
1030     if(mustache.hash) {
1031       this.hash(mustache.hash);
1032     } else {
1033       this.opcode('emptyHash');
1034     }
1036     return params;
1037   },
1039   // this will replace setupMustacheParams when we're done
1040   setupFullMustacheParams: function(mustache, program, inverse) {
1041     var params = mustache.params;
1042     this.pushParams(params);
1044     this.opcode('pushProgram', program);
1045     this.opcode('pushProgram', inverse);
1047     if(mustache.hash) {
1048       this.hash(mustache.hash);
1049     } else {
1050       this.opcode('emptyHash');
1051     }
1053     return params;
1054   }
1057 var Literal = function(value) {
1058   this.value = value;
1061 JavaScriptCompiler.prototype = {
1062   // PUBLIC API: You can override these methods in a subclass to provide
1063   // alternative compiled forms for name lookup and buffering semantics
1064   nameLookup: function(parent, name /* , type*/) {
1065     if (/^[0-9]+$/.test(name)) {
1066       return parent + "[" + name + "]";
1067     } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
1068       return parent + "." + name;
1069     }
1070     else {
1071       return parent + "['" + name + "']";
1072     }
1073   },
1075   appendToBuffer: function(string) {
1076     if (this.environment.isSimple) {
1077       return "return " + string + ";";
1078     } else {
1079       return {
1080         appendToBuffer: true,
1081         content: string,
1082         toString: function() { return "buffer += " + string + ";"; }
1083       };
1084     }
1085   },
1087   initializeBuffer: function() {
1088     return this.quotedString("");
1089   },
1091   namespace: "Handlebars",
1092   // END PUBLIC API
1094   compile: function(environment, options, context, asObject) {
1095     this.environment = environment;
1096     this.options = options || {};
1098     Handlebars.log(Handlebars.logger.DEBUG, this.environment.disassemble() + "\n\n");
1100     this.name = this.environment.name;
1101     this.isChild = !!context;
1102     this.context = context || {
1103       programs: [],
1104       environments: [],
1105       aliases: { }
1106     };
1108     this.preamble();
1110     this.stackSlot = 0;
1111     this.stackVars = [];
1112     this.registers = { list: [] };
1113     this.compileStack = [];
1114     this.inlineStack = [];
1116     this.compileChildren(environment, options);
1118     var opcodes = environment.opcodes, opcode;
1120     this.i = 0;
1122     for(l=opcodes.length; this.i<l; this.i++) {
1123       opcode = opcodes[this.i];
1125       if(opcode.opcode === 'DECLARE') {
1126         this[opcode.name] = opcode.value;
1127       } else {
1128         this[opcode.opcode].apply(this, opcode.args);
1129       }
1130     }
1132     return this.createFunctionContext(asObject);
1133   },
1135   nextOpcode: function() {
1136     var opcodes = this.environment.opcodes;
1137     return opcodes[this.i + 1];
1138   },
1140   eat: function() {
1141     this.i = this.i + 1;
1142   },
1144   preamble: function() {
1145     var out = [];
1147     if (!this.isChild) {
1148       var namespace = this.namespace;
1150       var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
1151       if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
1152       if (this.options.data) { copies = copies + " data = data || {};"; }
1153       out.push(copies);
1154     } else {
1155       out.push('');
1156     }
1158     if (!this.environment.isSimple) {
1159       out.push(", buffer = " + this.initializeBuffer());
1160     } else {
1161       out.push("");
1162     }
1164     // track the last context pushed into place to allow skipping the
1165     // getContext opcode when it would be a noop
1166     this.lastContext = 0;
1167     this.source = out;
1168   },
1170   createFunctionContext: function(asObject) {
1171     var locals = this.stackVars.concat(this.registers.list);
1173     if(locals.length > 0) {
1174       this.source[1] = this.source[1] + ", " + locals.join(", ");
1175     }
1177     // Generate minimizer alias mappings
1178     if (!this.isChild) {
1179       for (var alias in this.context.aliases) {
1180         if (this.context.aliases.hasOwnProperty(alias)) {
1181           this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
1182         }
1183       }
1184     }
1186     if (this.source[1]) {
1187       this.source[1] = "var " + this.source[1].substring(2) + ";";
1188     }
1190     // Merge children
1191     if (!this.isChild) {
1192       this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
1193     }
1195     if (!this.environment.isSimple) {
1196       this.source.push("return buffer;");
1197     }
1199     var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
1201     for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
1202       params.push("depth" + this.environment.depths.list[i]);
1203     }
1205     // Perform a second pass over the output to merge content when possible
1206     var source = this.mergeSource();
1208     if (!this.isChild) {
1209       var revision = Handlebars.COMPILER_REVISION,
1210           versions = Handlebars.REVISION_CHANGES[revision];
1211       source = "this.compilerInfo = ["+revision+",'"+versions+"'];\n"+source;
1212     }
1214     if (asObject) {
1215       params.push(source);
1217       return Function.apply(this, params);
1218     } else {
1219       var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n  ' + source + '}';
1220       Handlebars.log(Handlebars.logger.DEBUG, functionSource + "\n\n");
1221       return functionSource;
1222     }
1223   },
1224   mergeSource: function() {
1225     // WARN: We are not handling the case where buffer is still populated as the source should
1226     // not have buffer append operations as their final action.
1227     var source = '',
1228         buffer;
1229     for (var i = 0, len = this.source.length; i < len; i++) {
1230       var line = this.source[i];
1231       if (line.appendToBuffer) {
1232         if (buffer) {
1233           buffer = buffer + '\n    + ' + line.content;
1234         } else {
1235           buffer = line.content;
1236         }
1237       } else {
1238         if (buffer) {
1239           source += 'buffer += ' + buffer + ';\n  ';
1240           buffer = undefined;
1241         }
1242         source += line + '\n  ';
1243       }
1244     }
1245     return source;
1246   },
1248   // [blockValue]
1249   //
1250   // On stack, before: hash, inverse, program, value
1251   // On stack, after: return value of blockHelperMissing
1252   //
1253   // The purpose of this opcode is to take a block of the form
1254   // `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
1255   // replace it on the stack with the result of properly
1256   // invoking blockHelperMissing.
1257   blockValue: function() {
1258     this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
1260     var params = ["depth0"];
1261     this.setupParams(0, params);
1263     this.replaceStack(function(current) {
1264       params.splice(1, 0, current);
1265       return "blockHelperMissing.call(" + params.join(", ") + ")";
1266     });
1267   },
1269   // [ambiguousBlockValue]
1270   //
1271   // On stack, before: hash, inverse, program, value
1272   // Compiler value, before: lastHelper=value of last found helper, if any
1273   // On stack, after, if no lastHelper: same as [blockValue]
1274   // On stack, after, if lastHelper: value
1275   ambiguousBlockValue: function() {
1276     this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
1278     var params = ["depth0"];
1279     this.setupParams(0, params);
1281     var current = this.topStack();
1282     params.splice(1, 0, current);
1284     // Use the options value generated from the invocation
1285     params[params.length-1] = 'options';
1287     this.source.push("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
1288   },
1290   // [appendContent]
1291   //
1292   // On stack, before: ...
1293   // On stack, after: ...
1294   //
1295   // Appends the string value of `content` to the current buffer
1296   appendContent: function(content) {
1297     this.source.push(this.appendToBuffer(this.quotedString(content)));
1298   },
1300   // [append]
1301   //
1302   // On stack, before: value, ...
1303   // On stack, after: ...
1304   //
1305   // Coerces `value` to a String and appends it to the current buffer.
1306   //
1307   // If `value` is truthy, or 0, it is coerced into a string and appended
1308   // Otherwise, the empty string is appended
1309   append: function() {
1310     // Force anything that is inlined onto the stack so we don't have duplication
1311     // when we examine local
1312     this.flushInline();
1313     var local = this.popStack();
1314     this.source.push("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
1315     if (this.environment.isSimple) {
1316       this.source.push("else { " + this.appendToBuffer("''") + " }");
1317     }
1318   },
1320   // [appendEscaped]
1321   //
1322   // On stack, before: value, ...
1323   // On stack, after: ...
1324   //
1325   // Escape `value` and append it to the buffer
1326   appendEscaped: function() {
1327     this.context.aliases.escapeExpression = 'this.escapeExpression';
1329     this.source.push(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
1330   },
1332   // [getContext]
1333   //
1334   // On stack, before: ...
1335   // On stack, after: ...
1336   // Compiler value, after: lastContext=depth
1337   //
1338   // Set the value of the `lastContext` compiler value to the depth
1339   getContext: function(depth) {
1340     if(this.lastContext !== depth) {
1341       this.lastContext = depth;
1342     }
1343   },
1345   // [lookupOnContext]
1346   //
1347   // On stack, before: ...
1348   // On stack, after: currentContext[name], ...
1349   //
1350   // Looks up the value of `name` on the current context and pushes
1351   // it onto the stack.
1352   lookupOnContext: function(name) {
1353     this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
1354   },
1356   // [pushContext]
1357   //
1358   // On stack, before: ...
1359   // On stack, after: currentContext, ...
1360   //
1361   // Pushes the value of the current context onto the stack.
1362   pushContext: function() {
1363     this.pushStackLiteral('depth' + this.lastContext);
1364   },
1366   // [resolvePossibleLambda]
1367   //
1368   // On stack, before: value, ...
1369   // On stack, after: resolved value, ...
1370   //
1371   // If the `value` is a lambda, replace it on the stack by
1372   // the return value of the lambda
1373   resolvePossibleLambda: function() {
1374     this.context.aliases.functionType = '"function"';
1376     this.replaceStack(function(current) {
1377       return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
1378     });
1379   },
1381   // [lookup]
1382   //
1383   // On stack, before: value, ...
1384   // On stack, after: value[name], ...
1385   //
1386   // Replace the value on the stack with the result of looking
1387   // up `name` on `value`
1388   lookup: function(name) {
1389     this.replaceStack(function(current) {
1390       return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
1391     });
1392   },
1394   // [lookupData]
1395   //
1396   // On stack, before: ...
1397   // On stack, after: data[id], ...
1398   //
1399   // Push the result of looking up `id` on the current data
1400   lookupData: function(id) {
1401     this.push('data');
1402   },
1404   // [pushStringParam]
1405   //
1406   // On stack, before: ...
1407   // On stack, after: string, currentContext, ...
1408   //
1409   // This opcode is designed for use in string mode, which
1410   // provides the string value of a parameter along with its
1411   // depth rather than resolving it immediately.
1412   pushStringParam: function(string, type) {
1413     this.pushStackLiteral('depth' + this.lastContext);
1415     this.pushString(type);
1417     if (typeof string === 'string') {
1418       this.pushString(string);
1419     } else {
1420       this.pushStackLiteral(string);
1421     }
1422   },
1424   emptyHash: function() {
1425     this.pushStackLiteral('{}');
1427     if (this.options.stringParams) {
1428       this.register('hashTypes', '{}');
1429       this.register('hashContexts', '{}');
1430     }
1431   },
1432   pushHash: function() {
1433     this.hash = {values: [], types: [], contexts: []};
1434   },
1435   popHash: function() {
1436     var hash = this.hash;
1437     this.hash = undefined;
1439     if (this.options.stringParams) {
1440       this.register('hashContexts', '{' + hash.contexts.join(',') + '}');
1441       this.register('hashTypes', '{' + hash.types.join(',') + '}');
1442     }
1443     this.push('{\n    ' + hash.values.join(',\n    ') + '\n  }');
1444   },
1446   // [pushString]
1447   //
1448   // On stack, before: ...
1449   // On stack, after: quotedString(string), ...
1450   //
1451   // Push a quoted version of `string` onto the stack
1452   pushString: function(string) {
1453     this.pushStackLiteral(this.quotedString(string));
1454   },
1456   // [push]
1457   //
1458   // On stack, before: ...
1459   // On stack, after: expr, ...
1460   //
1461   // Push an expression onto the stack
1462   push: function(expr) {
1463     this.inlineStack.push(expr);
1464     return expr;
1465   },
1467   // [pushLiteral]
1468   //
1469   // On stack, before: ...
1470   // On stack, after: value, ...
1471   //
1472   // Pushes a value onto the stack. This operation prevents
1473   // the compiler from creating a temporary variable to hold
1474   // it.
1475   pushLiteral: function(value) {
1476     this.pushStackLiteral(value);
1477   },
1479   // [pushProgram]
1480   //
1481   // On stack, before: ...
1482   // On stack, after: program(guid), ...
1483   //
1484   // Push a program expression onto the stack. This takes
1485   // a compile-time guid and converts it into a runtime-accessible
1486   // expression.
1487   pushProgram: function(guid) {
1488     if (guid != null) {
1489       this.pushStackLiteral(this.programExpression(guid));
1490     } else {
1491       this.pushStackLiteral(null);
1492     }
1493   },
1495   // [invokeHelper]
1496   //
1497   // On stack, before: hash, inverse, program, params..., ...
1498   // On stack, after: result of helper invocation
1499   //
1500   // Pops off the helper's parameters, invokes the helper,
1501   // and pushes the helper's return value onto the stack.
1502   //
1503   // If the helper is not found, `helperMissing` is called.
1504   invokeHelper: function(paramSize, name) {
1505     this.context.aliases.helperMissing = 'helpers.helperMissing';
1507     var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
1508     var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
1510     this.push(helper.name + ' || ' + nonHelper);
1511     this.replaceStack(function(name) {
1512       return name + ' ? ' + name + '.call(' +
1513           helper.callParams + ") " + ": helperMissing.call(" +
1514           helper.helperMissingParams + ")";
1515     });
1516   },
1518   // [invokeKnownHelper]
1519   //
1520   // On stack, before: hash, inverse, program, params..., ...
1521   // On stack, after: result of helper invocation
1522   //
1523   // This operation is used when the helper is known to exist,
1524   // so a `helperMissing` fallback is not required.
1525   invokeKnownHelper: function(paramSize, name) {
1526     var helper = this.setupHelper(paramSize, name);
1527     this.push(helper.name + ".call(" + helper.callParams + ")");
1528   },
1530   // [invokeAmbiguous]
1531   //
1532   // On stack, before: hash, inverse, program, params..., ...
1533   // On stack, after: result of disambiguation
1534   //
1535   // This operation is used when an expression like `{{foo}}`
1536   // is provided, but we don't know at compile-time whether it
1537   // is a helper or a path.
1538   //
1539   // This operation emits more code than the other options,
1540   // and can be avoided by passing the `knownHelpers` and
1541   // `knownHelpersOnly` flags at compile-time.
1542   invokeAmbiguous: function(name, helperCall) {
1543     this.context.aliases.functionType = '"function"';
1545     this.pushStackLiteral('{}');    // Hash value
1546     var helper = this.setupHelper(0, name, helperCall);
1548     var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
1550     var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
1551     var nextStack = this.nextStack();
1553     this.source.push('if (' + nextStack + ' = ' + helperName + ') { ' + nextStack + ' = ' + nextStack + '.call(' + helper.callParams + '); }');
1554     this.source.push('else { ' + nextStack + ' = ' + nonHelper + '; ' + nextStack + ' = typeof ' + nextStack + ' === functionType ? ' + nextStack + '.apply(depth0) : ' + nextStack + '; }');
1555   },
1557   // [invokePartial]
1558   //
1559   // On stack, before: context, ...
1560   // On stack after: result of partial invocation
1561   //
1562   // This operation pops off a context, invokes a partial with that context,
1563   // and pushes the result of the invocation back.
1564   invokePartial: function(name) {
1565     var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
1567     if (this.options.data) {
1568       params.push("data");
1569     }
1571     this.context.aliases.self = "this";
1572     this.push("self.invokePartial(" + params.join(", ") + ")");
1573   },
1575   // [assignToHash]
1576   //
1577   // On stack, before: value, hash, ...
1578   // On stack, after: hash, ...
1579   //
1580   // Pops a value and hash off the stack, assigns `hash[key] = value`
1581   // and pushes the hash back onto the stack.
1582   assignToHash: function(key) {
1583     var value = this.popStack(),
1584         context,
1585         type;
1587     if (this.options.stringParams) {
1588       type = this.popStack();
1589       context = this.popStack();
1590     }
1592     var hash = this.hash;
1593     if (context) {
1594       hash.contexts.push("'" + key + "': " + context);
1595     }
1596     if (type) {
1597       hash.types.push("'" + key + "': " + type);
1598     }
1599     hash.values.push("'" + key + "': (" + value + ")");
1600   },
1602   // HELPERS
1604   compiler: JavaScriptCompiler,
1606   compileChildren: function(environment, options) {
1607     var children = environment.children, child, compiler;
1609     for(var i=0, l=children.length; i<l; i++) {
1610       child = children[i];
1611       compiler = new this.compiler();
1613       var index = this.matchExistingProgram(child);
1615       if (index == null) {
1616         this.context.programs.push('');     // Placeholder to prevent name conflicts for nested children
1617         index = this.context.programs.length;
1618         child.index = index;
1619         child.name = 'program' + index;
1620         this.context.programs[index] = compiler.compile(child, options, this.context);
1621         this.context.environments[index] = child;
1622       } else {
1623         child.index = index;
1624         child.name = 'program' + index;
1625       }
1626     }
1627   },
1628   matchExistingProgram: function(child) {
1629     for (var i = 0, len = this.context.environments.length; i < len; i++) {
1630       var environment = this.context.environments[i];
1631       if (environment && environment.equals(child)) {
1632         return i;
1633       }
1634     }
1635   },
1637   programExpression: function(guid) {
1638     this.context.aliases.self = "this";
1640     if(guid == null) {
1641       return "self.noop";
1642     }
1644     var child = this.environment.children[guid],
1645         depths = child.depths.list, depth;
1647     var programParams = [child.index, child.name, "data"];
1649     for(var i=0, l = depths.length; i<l; i++) {
1650       depth = depths[i];
1652       if(depth === 1) { programParams.push("depth0"); }
1653       else { programParams.push("depth" + (depth - 1)); }
1654     }
1656     return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
1657   },
1659   register: function(name, val) {
1660     this.useRegister(name);
1661     this.source.push(name + " = " + val + ";");
1662   },
1664   useRegister: function(name) {
1665     if(!this.registers[name]) {
1666       this.registers[name] = true;
1667       this.registers.list.push(name);
1668     }
1669   },
1671   pushStackLiteral: function(item) {
1672     return this.push(new Literal(item));
1673   },
1675   pushStack: function(item) {
1676     this.flushInline();
1678     var stack = this.incrStack();
1679     if (item) {
1680       this.source.push(stack + " = " + item + ";");
1681     }
1682     this.compileStack.push(stack);
1683     return stack;
1684   },
1686   replaceStack: function(callback) {
1687     var prefix = '',
1688         inline = this.isInline(),
1689         stack;
1691     // If we are currently inline then we want to merge the inline statement into the
1692     // replacement statement via ','
1693     if (inline) {
1694       var top = this.popStack(true);
1696       if (top instanceof Literal) {
1697         // Literals do not need to be inlined
1698         stack = top.value;
1699       } else {
1700         // Get or create the current stack name for use by the inline
1701         var name = this.stackSlot ? this.topStackName() : this.incrStack();
1703         prefix = '(' + this.push(name) + ' = ' + top + '),';
1704         stack = this.topStack();
1705       }
1706     } else {
1707       stack = this.topStack();
1708     }
1710     var item = callback.call(this, stack);
1712     if (inline) {
1713       if (this.inlineStack.length || this.compileStack.length) {
1714         this.popStack();
1715       }
1716       this.push('(' + prefix + item + ')');
1717     } else {
1718       // Prevent modification of the context depth variable. Through replaceStack
1719       if (!/^stack/.test(stack)) {
1720         stack = this.nextStack();
1721       }
1723       this.source.push(stack + " = (" + prefix + item + ");");
1724     }
1725     return stack;
1726   },
1728   nextStack: function() {
1729     return this.pushStack();
1730   },
1732   incrStack: function() {
1733     this.stackSlot++;
1734     if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
1735     return this.topStackName();
1736   },
1737   topStackName: function() {
1738     return "stack" + this.stackSlot;
1739   },
1740   flushInline: function() {
1741     var inlineStack = this.inlineStack;
1742     if (inlineStack.length) {
1743       this.inlineStack = [];
1744       for (var i = 0, len = inlineStack.length; i < len; i++) {
1745         var entry = inlineStack[i];
1746         if (entry instanceof Literal) {
1747           this.compileStack.push(entry);
1748         } else {
1749           this.pushStack(entry);
1750         }
1751       }
1752     }
1753   },
1754   isInline: function() {
1755     return this.inlineStack.length;
1756   },
1758   popStack: function(wrapped) {
1759     var inline = this.isInline(),
1760         item = (inline ? this.inlineStack : this.compileStack).pop();
1762     if (!wrapped && (item instanceof Literal)) {
1763       return item.value;
1764     } else {
1765       if (!inline) {
1766         this.stackSlot--;
1767       }
1768       return item;
1769     }
1770   },
1772   topStack: function(wrapped) {
1773     var stack = (this.isInline() ? this.inlineStack : this.compileStack),
1774         item = stack[stack.length - 1];
1776     if (!wrapped && (item instanceof Literal)) {
1777       return item.value;
1778     } else {
1779       return item;
1780     }
1781   },
1783   quotedString: function(str) {
1784     return '"' + str
1785       .replace(/\\/g, '\\\\')
1786       .replace(/"/g, '\\"')
1787       .replace(/\n/g, '\\n')
1788       .replace(/\r/g, '\\r')
1789       .replace(/\u2028/g, '\\u2028')   // Per Ecma-262 7.3 + 7.8.4
1790       .replace(/\u2029/g, '\\u2029') + '"';
1791   },
1793   setupHelper: function(paramSize, name, missingParams) {
1794     var params = [];
1795     this.setupParams(paramSize, params, missingParams);
1796     var foundHelper = this.nameLookup('helpers', name, 'helper');
1798     return {
1799       params: params,
1800       name: foundHelper,
1801       callParams: ["depth0"].concat(params).join(", "),
1802       helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
1803     };
1804   },
1806   // the params and contexts arguments are passed in arrays
1807   // to fill in
1808   setupParams: function(paramSize, params, useRegister) {
1809     var options = [], contexts = [], types = [], param, inverse, program;
1811     options.push("hash:" + this.popStack());
1813     inverse = this.popStack();
1814     program = this.popStack();
1816     // Avoid setting fn and inverse if neither are set. This allows
1817     // helpers to do a check for `if (options.fn)`
1818     if (program || inverse) {
1819       if (!program) {
1820         this.context.aliases.self = "this";
1821         program = "self.noop";
1822       }
1824       if (!inverse) {
1825        this.context.aliases.self = "this";
1826         inverse = "self.noop";
1827       }
1829       options.push("inverse:" + inverse);
1830       options.push("fn:" + program);
1831     }
1833     for(var i=0; i<paramSize; i++) {
1834       param = this.popStack();
1835       params.push(param);
1837       if(this.options.stringParams) {
1838         types.push(this.popStack());
1839         contexts.push(this.popStack());
1840       }
1841     }
1843     if (this.options.stringParams) {
1844       options.push("contexts:[" + contexts.join(",") + "]");
1845       options.push("types:[" + types.join(",") + "]");
1846       options.push("hashContexts:hashContexts");
1847       options.push("hashTypes:hashTypes");
1848     }
1850     if(this.options.data) {
1851       options.push("data:data");
1852     }
1854     options = "{" + options.join(",") + "}";
1855     if (useRegister) {
1856       this.register('options', options);
1857       params.push('options');
1858     } else {
1859       params.push(options);
1860     }
1861     return params.join(", ");
1862   }
1865 var reservedWords = (
1866   "break else new var" +
1867   " case finally return void" +
1868   " catch for switch while" +
1869   " continue function this with" +
1870   " default if throw" +
1871   " delete in try" +
1872   " do instanceof typeof" +
1873   " abstract enum int short" +
1874   " boolean export interface static" +
1875   " byte extends long super" +
1876   " char final native synchronized" +
1877   " class float package throws" +
1878   " const goto private transient" +
1879   " debugger implements protected volatile" +
1880   " double import public let yield"
1881 ).split(" ");
1883 var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
1885 for(var i=0, l=reservedWords.length; i<l; i++) {
1886   compilerWords[reservedWords[i]] = true;
1889 JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
1890   if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) {
1891     return true;
1892   }
1893   return false;
1896 Handlebars.precompile = function(input, options) {
1897   if (input == null || (typeof input !== 'string' && input.constructor !== Handlebars.AST.ProgramNode)) {
1898     throw new Handlebars.Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
1899   }
1901   options = options || {};
1902   if (!('data' in options)) {
1903     options.data = true;
1904   }
1905   var ast = Handlebars.parse(input);
1906   var environment = new Compiler().compile(ast, options);
1907   return new JavaScriptCompiler().compile(environment, options);
1910 Handlebars.compile = function(input, options) {
1911   if (input == null || (typeof input !== 'string' && input.constructor !== Handlebars.AST.ProgramNode)) {
1912     throw new Handlebars.Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
1913   }
1915   options = options || {};
1916   if (!('data' in options)) {
1917     options.data = true;
1918   }
1919   var compiled;
1920   function compile() {
1921     var ast = Handlebars.parse(input);
1922     var environment = new Compiler().compile(ast, options);
1923     var templateSpec = new JavaScriptCompiler().compile(environment, options, undefined, true);
1924     return Handlebars.template(templateSpec);
1925   }
1927   // Template is only compiled on first use and cached after that point.
1928   return function(context, options) {
1929     if (!compiled) {
1930       compiled = compile();
1931     }
1932     return compiled.call(this, context, options);
1933   };
1935 // This file contains YUI-specific wrapper code and overrides for the
1936 // handlebars-compiler module.
1939 Handlebars parser and compiler. Use this module when you need to compile
1940 Handlebars templates.
1942 @module handlebars
1943 @submodule handlebars-compiler
1946 var levels = ['debug', 'info', 'warn', 'error'];
1949 Logs a debugging message. Note that messages will only be logged when the
1950 handlebars module is loaded in "debug" mode.
1952 @method log
1953 @param {String} level Log level for this message. Supported levels are "debug",
1954     "info", "warn", and "error".
1955 @param {String} message Message to log.
1956 @for Handlebars
1958 Handlebars.logger.log = function (level, message) {
1959     Y.log(message, levels[level] || 'error', 'Handlebars');
1963 Compiles and renders a Handlebars template string in a single step.
1965 If you'll be using a template more than once, it's more efficient to compile it
1966 into a function once using `compile()`, and then render it whenever you need to
1967 by simply executing the compiled function. However, if you only need to compile
1968 and render a template once, `render()` is a handy shortcut for doing both in a
1969 single step.
1971 @example
1973     Y.Handlebars.render('The pie of the day is {{pie}}!', {
1974         pie: 'Maple Custard'
1975     });
1976     // => "The pie of the day is Maple Custard!"
1978 @method render
1979 @param {String} string Handlebars template string to render.
1980 @param {Object} context Context object to pass to the template.
1981 @param {Object} [options] Compile/render options.
1982     @param {Object} [options.helpers] Helper functions.
1983     @param {Object} [options.partials] Partials.
1984     @param {Object} [options.data] Data.
1985 @return {String} Rendered template string.
1987 Handlebars.render = function (string, context, options) {
1988     return Handlebars.compile(string)(context, options);
1991 // The rest of this file is just API docs for methods defined in Handlebars
1992 // itself.
1995 Compiles a Handlebars template string into a function. To render the template,
1996 call the function and pass in a context object.
1998 @example
2000     var template = Y.Handlebars.compile('The pie of the day is {{pie}}!.');
2001     template({pie: 'Pecan'});
2002     // => "The pie of the day is Pecan!"
2004 @method compile
2005 @param {String} string Handlebars template string to compile.
2006 @param {Object} [options] Compiler options.
2007 @return {Function} Compiled template function.
2011 Precompiles a Handlebars template string into a string of JavaScript code. This
2012 can be used to precompile a template at build time or on the server, and the
2013 resulting template can then be rendered at runtime or on the client without
2014 needing to go through a compile step.
2016 To render a precompiled template, evaluate the code and then pass the resulting
2017 function to `Y.Handlebars.template()` to get back an executable template
2018 function.
2020 @method precompile
2021 @param {String} string Handlebars template string to compile.
2022 @param {Object} [options] Compiler options.
2023 @return {String} Precompiled template code.
2027 }, '3.13.0', {"requires": ["handlebars-base"]});