Skip to content
This repository
  • 3 commits
  • 9 files changed
  • 0 comments
  • 2 contributors
59 all/index.js
@@ -7,29 +7,60 @@ module.exports = Generator;
7 7 function Generator() {
8 8 yeoman.generators.Base.apply(this, arguments);
9 9 this.sourceRoot(path.join(path.dirname(__dirname), 'templates'));
  10 + this.indexFile = this.readFileAsString(path.join(this.sourceRoot(), 'index.html'));
10 11 }
11 12
12 13 util.inherits(Generator, yeoman.generators.Base);
13 14
14 15 Generator.prototype.createDirLayout = function createDirLayout() {
15   - this.mkdir('js');
16   - this.mkdir('js/libs');
17   - this.mkdir('css');
  16 + this.mkdir('app/js');
  17 + this.mkdir('app/css');
18 18 };
19 19
20   -Generator.prototype.indexFile = function createIndexFile() {
21   - this.template('index.html', 'index.html');
  20 +Generator.prototype.git = function git() {
  21 + this.copy('gitignore', '.gitignore');
  22 + this.copy('gitattributes', '.gitattributes');
  23 +};
  24 +
  25 +Generator.prototype.bower = function bower() {
  26 + this.copy('bowerrc', '.bowerrc');
  27 + this.copy('_component.json', 'component.json');
  28 +};
  29 +
  30 +Generator.prototype.packageFile = function packageFile() {
  31 + this.copy('_package.json', 'package.json');
  32 +};
  33 +
  34 +Generator.prototype.jshint = function jshint() {
  35 + this.copy('jshintrc', '.jshintrc');
  36 +};
22 37
23   - // yes, I know this isn't exactly where the following
24   - // are supposed to go; it's the poor man's Saturday
25   - // afternoon solution...
26   - this.copy('js/app.js', 'js/app.js');
  38 +Generator.prototype.editorConfig = function editorConfig() {
  39 + this.copy('editorconfig', '.editorconfig');
  40 +};
  41 +
  42 +Generator.prototype.gruntfile = function gruntfile() {
27 43 this.copy('Gruntfile.js', 'Gruntfile.js');
  44 +};
  45 +
  46 +Generator.prototype.writeIndex = function writeIndex() {
  47 + this.indexFile = this.appendScripts(this.indexFile, 'scripts/components.js', [
  48 + 'components/jquery/jquery.js',
  49 + 'components/handlebars/handlebars.js',
  50 + 'components/ember/ember.js',
  51 + ]);
28 52
29   - this.copy('js/libs/ember-1.0.0-rc.2.js', 'js/libs/ember-1.0.0-rc.2.js');
30   - this.copy('js/libs/handlebars-1.0.0-rc.3.js', 'js/libs/handlebars-1.0.0-rc.3.js');
31   - this.copy('js/libs/jquery-1.9.1.js', 'js/libs/jquery-1.9.1.js');
  53 + this.indexFile = this.appendScripts(this.indexFile, 'scripts/main.js', [
  54 + 'js/app.js'
  55 + ]);
  56 +}
  57 +
  58 +Generator.prototype.mainStylesheet = function mainStylesheet() {
  59 + this.copy('css/normalize.css', 'app/css/normalize.css');
  60 + this.copy('css/style.css', 'app/css/style.css');
  61 +};
32 62
33   - this.copy('css/normalize.css', 'css/normalize.css');
34   - this.copy('css/style.css', 'css/style.css');
  63 +Generator.prototype.all = function all() {
  64 + this.write('app/index.html', this.indexFile);
  65 + this.copy('js/app.js', 'app/js/app.js');
35 66 };
1  readme.md
Source Rendered
@@ -7,6 +7,7 @@ Usage:
7 7 - `mkdir webapp; cd webapp`
8 8 - `npm install generator-ember`
9 9 - `yo ember:all`
  10 +- `bower install`
10 11 - open index.html
11 12
12 13 ## Description
6 templates/component.json → templates/_component.json
@@ -2,9 +2,9 @@
2 2 "name": "<%= _.slugify(appname) %>",
3 3 "version": "0.0.0",
4 4 "dependencies": {
5   - "jquery": "~1.9.0",
6   - "handlebars": "1.0.0-rc.1",
7   - "ember": "~1.0.0-pre.4"
  5 + "jquery": "~1.9.1",
  6 + "handlebars": "~1.0.0-rc.3",
  7 + "ember": "~1.0.0-rc.2"
8 8 },
9 9 "devDependencies": {}
10 10 }
0  templates/package.json → templates/_package.json
File renamed without changes
5 templates/index.html
@@ -22,10 +22,5 @@
22 22 </ul>
23 23 </script>
24 24
25   - <script src="js/libs/jquery-1.9.1.js"></script>
26   - <script src="js/libs/handlebars-1.0.0-rc.3.js"></script>
27   - <script src="js/libs/ember-1.0.0-rc.2.js"></script>
28   - <script src="js/app.js"></script>
29   -
30 25 </body>
31 26 </html>
27,756 templates/js/libs/ember-1.0.0-rc.2.js
0 additions, 27,756 deletions not shown
2,201 templates/js/libs/handlebars-1.0.0-rc.3.js
... ... @@ -1,2201 +0,0 @@
1   -/*
2   -
3   -Copyright (C) 2011 by Yehuda Katz
4   -
5   -Permission is hereby granted, free of charge, to any person obtaining a copy
6   -of this software and associated documentation files (the "Software"), to deal
7   -in the Software without restriction, including without limitation the rights
8   -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9   -copies of the Software, and to permit persons to whom the Software is
10   -furnished to do so, subject to the following conditions:
11   -
12   -The above copyright notice and this permission notice shall be included in
13   -all copies or substantial portions of the Software.
14   -
15   -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16   -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17   -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18   -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19   -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20   -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21   -THE SOFTWARE.
22   -
23   -*/
24   -
25   -// lib/handlebars/base.js
26   -
27   -/*jshint eqnull:true*/
28   -this.Handlebars = {};
29   -
30   -(function(Handlebars) {
31   -
32   -Handlebars.VERSION = "1.0.0-rc.3";
33   -Handlebars.COMPILER_REVISION = 2;
34   -
35   -Handlebars.REVISION_CHANGES = {
36   - 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
37   - 2: '>= 1.0.0-rc.3'
38   -};
39   -
40   -Handlebars.helpers = {};
41   -Handlebars.partials = {};
42   -
43   -Handlebars.registerHelper = function(name, fn, inverse) {
44   - if(inverse) { fn.not = inverse; }
45   - this.helpers[name] = fn;
46   -};
47   -
48   -Handlebars.registerPartial = function(name, str) {
49   - this.partials[name] = str;
50   -};
51   -
52   -Handlebars.registerHelper('helperMissing', function(arg) {
53   - if(arguments.length === 2) {
54   - return undefined;
55   - } else {
56   - throw new Error("Could not find property '" + arg + "'");
57   - }
58   -});
59   -
60   -var toString = Object.prototype.toString, functionType = "[object Function]";
61   -
62   -Handlebars.registerHelper('blockHelperMissing', function(context, options) {
63   - var inverse = options.inverse || function() {}, fn = options.fn;
64   -
65   -
66   - var ret = "";
67   - var type = toString.call(context);
68   -
69   - if(type === functionType) { context = context.call(this); }
70   -
71   - if(context === true) {
72   - return fn(this);
73   - } else if(context === false || context == null) {
74   - return inverse(this);
75   - } else if(type === "[object Array]") {
76   - if(context.length > 0) {
77   - return Handlebars.helpers.each(context, options);
78   - } else {
79   - return inverse(this);
80   - }
81   - } else {
82   - return fn(context);
83   - }
84   -});
85   -
86   -Handlebars.K = function() {};
87   -
88   -Handlebars.createFrame = Object.create || function(object) {
89   - Handlebars.K.prototype = object;
90   - var obj = new Handlebars.K();
91   - Handlebars.K.prototype = null;
92   - return obj;
93   -};
94   -
95   -Handlebars.logger = {
96   - DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,
97   -
98   - methodMap: {0: 'debug', 1: 'info', 2: 'warn', 3: 'error'},
99   -
100   - // can be overridden in the host environment
101   - log: function(level, obj) {
102   - if (Handlebars.logger.level <= level) {
103   - var method = Handlebars.logger.methodMap[level];
104   - if (typeof console !== 'undefined' && console[method]) {
105   - console[method].call(console, obj);
106   - }
107   - }
108   - }
109   -};
110   -
111   -Handlebars.log = function(level, obj) { Handlebars.logger.log(level, obj); };
112   -
113   -Handlebars.registerHelper('each', function(context, options) {
114   - var fn = options.fn, inverse = options.inverse;
115   - var i = 0, ret = "", data;
116   -
117   - if (options.data) {
118   - data = Handlebars.createFrame(options.data);
119   - }
120   -
121   - if(context && typeof context === 'object') {
122   - if(context instanceof Array){
123   - for(var j = context.length; i<j; i++) {
124   - if (data) { data.index = i; }
125   - ret = ret + fn(context[i], { data: data });
126   - }
127   - } else {
128   - for(var key in context) {
129   - if(context.hasOwnProperty(key)) {
130   - if(data) { data.key = key; }
131   - ret = ret + fn(context[key], {data: data});
132   - i++;
133   - }
134   - }
135   - }
136   - }
137   -
138   - if(i === 0){
139   - ret = inverse(this);
140   - }
141   -
142   - return ret;
143   -});
144   -
145   -Handlebars.registerHelper('if', function(context, options) {
146   - var type = toString.call(context);
147   - if(type === functionType) { context = context.call(this); }
148   -
149   - if(!context || Handlebars.Utils.isEmpty(context)) {
150   - return options.inverse(this);
151   - } else {
152   - return options.fn(this);
153   - }
154   -});
155   -
156   -Handlebars.registerHelper('unless', function(context, options) {
157   - var fn = options.fn, inverse = options.inverse;
158   - options.fn = inverse;
159   - options.inverse = fn;
160   -
161   - return Handlebars.helpers['if'].call(this, context, options);
162   -});
163   -
164   -Handlebars.registerHelper('with', function(context, options) {
165   - return options.fn(context);
166   -});
167   -
168   -Handlebars.registerHelper('log', function(context, options) {
169   - var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
170   - Handlebars.log(level, context);
171   -});
172   -
173   -}(this.Handlebars));
174   -;
175   -// lib/handlebars/compiler/parser.js
176   -/* Jison generated parser */
177   -var handlebars = (function(){
178   -var parser = {trace: function trace() { },
179   -yy: {},
180   -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,"OPEN_PARTIAL":24,"partialName":25,"params":26,"hash":27,"DATA":28,"param":29,"STRING":30,"INTEGER":31,"BOOLEAN":32,"hashSegments":33,"hashSegment":34,"ID":35,"EQUALS":36,"PARTIAL_NAME":37,"pathSegments":38,"SEP":39,"$accept":0,"$end":1},
181   -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:"OPEN_PARTIAL",28:"DATA",30:"STRING",31:"INTEGER",32:"BOOLEAN",35:"ID",36:"EQUALS",37:"PARTIAL_NAME",39:"SEP"},
182   -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],[26,2],[26,1],[29,1],[29,1],[29,1],[29,1],[29,1],[27,1],[33,2],[33,1],[34,3],[34,3],[34,3],[34,3],[34,3],[25,1],[21,1],[38,3],[38,1]],
183   -performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
184   -
185   -var $0 = $$.length - 1;
186   -switch (yystate) {
187   -case 1: return $$[$0-1];
188   -break;
189   -case 2: this.$ = new yy.ProgramNode([], $$[$0]);
190   -break;
191   -case 3: this.$ = new yy.ProgramNode($$[$0-2], $$[$0]);
192   -break;
193   -case 4: this.$ = new yy.ProgramNode($$[$0-1], []);
194   -break;
195   -case 5: this.$ = new yy.ProgramNode($$[$0]);
196   -break;
197   -case 6: this.$ = new yy.ProgramNode([], []);
198   -break;
199   -case 7: this.$ = new yy.ProgramNode([]);
200   -break;
201   -case 8: this.$ = [$$[$0]];
202   -break;
203   -case 9: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
204   -break;
205   -case 10: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0]);
206   -break;
207   -case 11: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0]);
208   -break;
209   -case 12: this.$ = $$[$0];
210   -break;
211   -case 13: this.$ = $$[$0];
212   -break;
213   -case 14: this.$ = new yy.ContentNode($$[$0]);
214   -break;
215   -case 15: this.$ = new yy.CommentNode($$[$0]);
216   -break;
217   -case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
218   -break;
219   -case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
220   -break;
221   -case 18: this.$ = $$[$0-1];
222   -break;
223   -case 19: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]);
224   -break;
225   -case 20: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true);
226   -break;
227   -case 21: this.$ = new yy.PartialNode($$[$0-1]);
228   -break;
229   -case 22: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1]);
230   -break;
231   -case 23:
232   -break;
233   -case 24: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]];
234   -break;
235   -case 25: this.$ = [[$$[$0-1]].concat($$[$0]), null];
236   -break;
237   -case 26: this.$ = [[$$[$0-1]], $$[$0]];
238   -break;
239   -case 27: this.$ = [[$$[$0]], null];
240   -break;
241   -case 28: this.$ = [[new yy.DataNode($$[$0])], null];
242   -break;
243   -case 29: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
244   -break;
245   -case 30: this.$ = [$$[$0]];
246   -break;
247   -case 31: this.$ = $$[$0];
248   -break;
249   -case 32: this.$ = new yy.StringNode($$[$0]);
250   -break;
251   -case 33: this.$ = new yy.IntegerNode($$[$0]);
252   -break;
253   -case 34: this.$ = new yy.BooleanNode($$[$0]);
254   -break;
255   -case 35: this.$ = new yy.DataNode($$[$0]);
256   -break;
257   -case 36: this.$ = new yy.HashNode($$[$0]);
258   -break;
259   -case 37: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
260   -break;
261   -case 38: this.$ = [$$[$0]];
262   -break;
263   -case 39: this.$ = [$$[$0-2], $$[$0]];
264   -break;
265   -case 40: this.$ = [$$[$0-2], new yy.StringNode($$[$0])];
266   -break;
267   -case 41: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])];
268   -break;
269   -case 42: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])];
270   -break;
271   -case 43: this.$ = [$$[$0-2], new yy.DataNode($$[$0])];
272   -break;
273   -case 44: this.$ = new yy.PartialNameNode($$[$0]);
274   -break;
275   -case 45: this.$ = new yy.IdNode($$[$0]);
276   -break;
277   -case 46: $$[$0-2].push($$[$0]); this.$ = $$[$0-2];
278   -break;
279   -case 47: this.$ = [$$[$0]];
280   -break;
281   -}
282   -},
283   -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],24:[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],24:[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],24:[1,16]},{17:23,18:[1,22],21:24,28:[1,25],35:[1,27],38: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],24:[2,8]},{4:28,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],24:[1,16]},{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],24:[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],24:[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],24:[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],24:[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],24:[2,15]},{17:30,21:24,28:[1,25],35:[1,27],38:26},{17:31,21:24,28:[1,25],35:[1,27],38:26},{17:32,21:24,28:[1,25],35:[1,27],38:26},{25:33,37:[1,34]},{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],24:[1,16]},{17:23,21:24,28:[1,25],35:[1,27],38:26},{5:[2,4],7:35,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],24:[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],24:[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],24:[2,23]},{18:[1,36]},{18:[2,27],21:41,26:37,27:38,28:[1,45],29:39,30:[1,42],31:[1,43],32:[1,44],33:40,34:46,35:[1,47],38:26},{18:[2,28]},{18:[2,45],28:[2,45],30:[2,45],31:[2,45],32:[2,45],35:[2,45],39:[1,48]},{18:[2,47],28:[2,47],30:[2,47],31:[2,47],32:[2,47],35:[2,47],39:[2,47]},{10:49,20:[1,50]},{10:51,20:[1,50]},{18:[1,52]},{18:[1,53]},{18:[1,54]},{18:[1,55],21:56,35:[1,27],38:26},{18:[2,44],35:[2,44]},{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],24:[1,16]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{18:[2,25],21:41,27:57,28:[1,45],29:58,30:[1,42],31:[1,43],32:[1,44],33:40,34:46,35:[1,47],38:26},{18:[2,26]},{18:[2,30],28:[2,30],30:[2,30],31:[2,30],32:[2,30],35:[2,30]},{18:[2,36],34:59,35:[1,60]},{18:[2,31],28:[2,31],30:[2,31],31:[2,31],32:[2,31],35:[2,31]},{18:[2,32],28:[2,32],30:[2,32],31:[2,32],32:[2,32],35:[2,32]},{18:[2,33],28:[2,33],30:[2,33],31:[2,33],32:[2,33],35:[2,33]},{18:[2,34],28:[2,34],30:[2,34],31:[2,34],32:[2,34],35:[2,34]},{18:[2,35],28:[2,35],30:[2,35],31:[2,35],32:[2,35],35:[2,35]},{18:[2,38],35:[2,38]},{18:[2,47],28:[2,47],30:[2,47],31:[2,47],32:[2,47],35:[2,47],36:[1,61],39:[2,47]},{35:[1,62]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{21:63,35:[1,27],38: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],24:[2,11]},{14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[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],24:[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],24:[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],24:[2,21]},{18:[1,64]},{18:[2,24]},{18:[2,29],28:[2,29],30:[2,29],31:[2,29],32:[2,29],35:[2,29]},{18:[2,37],35:[2,37]},{36:[1,61]},{21:65,28:[1,69],30:[1,66],31:[1,67],32:[1,68],35:[1,27],38:26},{18:[2,46],28:[2,46],30:[2,46],31:[2,46],32:[2,46],35:[2,46],39:[2,46]},{18:[1,70]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],24:[2,22]},{18:[2,39],35:[2,39]},{18:[2,40],35:[2,40]},{18:[2,41],35:[2,41]},{18:[2,42],35:[2,42]},{18:[2,43],35:[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],24:[2,18]}],
284   -defaultActions: {17:[2,1],25:[2,28],38:[2,26],57:[2,24]},
285   -parseError: function parseError(str, hash) {
286   - throw new Error(str);
287   -},
288   -parse: function parse(input) {
289   - var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
290   - this.lexer.setInput(input);
291   - this.lexer.yy = this.yy;
292   - this.yy.lexer = this.lexer;
293   - this.yy.parser = this;
294   - if (typeof this.lexer.yylloc == "undefined")
295   - this.lexer.yylloc = {};
296   - var yyloc = this.lexer.yylloc;
297   - lstack.push(yyloc);
298   - var ranges = this.lexer.options && this.lexer.options.ranges;
299   - if (typeof this.yy.parseError === "function")
300   - this.parseError = this.yy.parseError;
301   - function popStack(n) {
302   - stack.length = stack.length - 2 * n;
303   - vstack.length = vstack.length - n;
304   - lstack.length = lstack.length - n;
305   - }
306   - function lex() {
307   - var token;
308   - token = self.lexer.lex() || 1;
309   - if (typeof token !== "number") {
310   - token = self.symbols_[token] || token;
311   - }
312   - return token;
313   - }
314   - var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
315   - while (true) {
316   - state = stack[stack.length - 1];
317   - if (this.defaultActions[state]) {
318   - action = this.defaultActions[state];
319   - } else {
320   - if (symbol === null || typeof symbol == "undefined") {
321   - symbol = lex();
322   - }
323   - action = table[state] && table[state][symbol];
324   - }
325   - if (typeof action === "undefined" || !action.length || !action[0]) {
326   - var errStr = "";
327   - if (!recovering) {
328   - expected = [];
329   - for (p in table[state])
330   - if (this.terminals_[p] && p > 2) {
331   - expected.push("'" + this.terminals_[p] + "'");
332   - }
333   - if (this.lexer.showPosition) {
334   - errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
335   - } else {
336   - errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
337   - }
338   - this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
339   - }
340   - }
341   - if (action[0] instanceof Array && action.length > 1) {
342   - throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
343   - }
344   - switch (action[0]) {
345   - case 1:
346   - stack.push(symbol);
347   - vstack.push(this.lexer.yytext);
348   - lstack.push(this.lexer.yylloc);
349   - stack.push(action[1]);
350   - symbol = null;
351   - if (!preErrorSymbol) {
352   - yyleng = this.lexer.yyleng;
353   - yytext = this.lexer.yytext;
354   - yylineno = this.lexer.yylineno;
355   - yyloc = this.lexer.yylloc;
356   - if (recovering > 0)
357   - recovering--;
358   - } else {
359   - symbol = preErrorSymbol;
360   - preErrorSymbol = null;
361   - }
362   - break;
363   - case 2:
364   - len = this.productions_[action[1]][1];
365   - yyval.$ = vstack[vstack.length - len];
366   - 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};
367   - if (ranges) {
368   - yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
369   - }
370   - r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
371   - if (typeof r !== "undefined") {
372   - return r;
373   - }
374   - if (len) {
375   - stack = stack.slice(0, -1 * len * 2);
376   - vstack = vstack.slice(0, -1 * len);
377   - lstack = lstack.slice(0, -1 * len);
378   - }
379   - stack.push(this.productions_[action[1]][0]);
380   - vstack.push(yyval.$);
381   - lstack.push(yyval._$);
382   - newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
383   - stack.push(newState);
384   - break;
385   - case 3:
386   - return true;
387   - }
388   - }
389   - return true;
390   -}
391   -};
392   -/* Jison generated lexer */
393   -var lexer = (function(){
394   -var lexer = ({EOF:1,
395   -parseError:function parseError(str, hash) {
396   - if (this.yy.parser) {
397   - this.yy.parser.parseError(str, hash);
398   - } else {
399   - throw new Error(str);
400   - }
401   - },
402   -setInput:function (input) {
403   - this._input = input;
404   - this._more = this._less = this.done = false;
405   - this.yylineno = this.yyleng = 0;
406   - this.yytext = this.matched = this.match = '';
407   - this.conditionStack = ['INITIAL'];
408   - this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
409   - if (this.options.ranges) this.yylloc.range = [0,0];
410   - this.offset = 0;
411   - return this;
412   - },
413   -input:function () {
414   - var ch = this._input[0];
415   - this.yytext += ch;
416   - this.yyleng++;
417   - this.offset++;
418   - this.match += ch;
419   - this.matched += ch;
420   - var lines = ch.match(/(?:\r\n?|\n).*/g);
421   - if (lines) {
422   - this.yylineno++;
423   - this.yylloc.last_line++;
424   - } else {
425   - this.yylloc.last_column++;
426   - }
427   - if (this.options.ranges) this.yylloc.range[1]++;
428   -
429   - this._input = this._input.slice(1);
430   - return ch;
431   - },
432   -unput:function (ch) {
433   - var len = ch.length;
434   - var lines = ch.split(/(?:\r\n?|\n)/g);
435   -
436   - this._input = ch + this._input;
437   - this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
438   - //this.yyleng -= len;
439   - this.offset -= len;
440   - var oldLines = this.match.split(/(?:\r\n?|\n)/g);
441   - this.match = this.match.substr(0, this.match.length-1);
442   - this.matched = this.matched.substr(0, this.matched.length-1);
443   -
444   - if (lines.length-1) this.yylineno -= lines.length-1;
445   - var r = this.yylloc.range;
446   -
447   - this.yylloc = {first_line: this.yylloc.first_line,
448   - last_line: this.yylineno+1,
449   - first_column: this.yylloc.first_column,
450   - last_column: lines ?
451   - (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
452   - this.yylloc.first_column - len
453   - };
454   -
455   - if (this.options.ranges) {
456   - this.yylloc.range = [r[0], r[0] + this.yyleng - len];
457   - }
458   - return this;
459   - },
460   -more:function () {
461   - this._more = true;
462   - return this;
463   - },
464   -less:function (n) {
465   - this.unput(this.match.slice(n));
466   - },
467   -pastInput:function () {
468   - var past = this.matched.substr(0, this.matched.length - this.match.length);
469   - return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
470   - },
471   -upcomingInput:function () {
472   - var next = this.match;
473   - if (next.length < 20) {
474   - next += this._input.substr(0, 20-next.length);
475   - }
476   - return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
477   - },
478   -showPosition:function () {
479   - var pre = this.pastInput();
480   - var c = new Array(pre.length + 1).join("-");
481   - return pre + this.upcomingInput() + "\n" + c+"^";
482   - },
483   -next:function () {
484   - if (this.done) {
485   - return this.EOF;
486   - }
487   - if (!this._input) this.done = true;
488   -
489   - var token,
490   - match,
491   - tempMatch,
492   - index,
493   - col,
494   - lines;
495   - if (!this._more) {
496   - this.yytext = '';
497   - this.match = '';
498   - }
499   - var rules = this._currentRules();
500   - for (var i=0;i < rules.length; i++) {
501   - tempMatch = this._input.match(this.rules[rules[i]]);
502   - if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
503   - match = tempMatch;
504   - index = i;
505   - if (!this.options.flex) break;
506   - }
507   - }
508   - if (match) {
509   - lines = match[0].match(/(?:\r\n?|\n).*/g);
510   - if (lines) this.yylineno += lines.length;
511   - this.yylloc = {first_line: this.yylloc.last_line,
512   - last_line: this.yylineno+1,
513   - first_column: this.yylloc.last_column,
514   - last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
515   - this.yytext += match[0];
516   - this.match += match[0];
517   - this.matches = match;
518   - this.yyleng = this.yytext.length;
519   - if (this.options.ranges) {
520   - this.yylloc.range = [this.offset, this.offset += this.yyleng];
521   - }
522   - this._more = false;
523   - this._input = this._input.slice(match[0].length);
524   - this.matched += match[0];
525   - token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
526   - if (this.done && this._input) this.done = false;
527   - if (token) return token;
528   - else return;
529   - }
530   - if (this._input === "") {
531   - return this.EOF;
532   - } else {
533   - return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
534   - {text: "", token: null, line: this.yylineno});
535   - }
536   - },
537   -lex:function lex() {
538   - var r = this.next();
539   - if (typeof r !== 'undefined') {
540   - return r;
541   - } else {
542   - return this.lex();
543   - }
544   - },
545   -begin:function begin(condition) {
546   - this.conditionStack.push(condition);
547   - },
548   -popState:function popState() {
549   - return this.conditionStack.pop();
550   - },
551   -_currentRules:function _currentRules() {
552   - return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
553   - },
554   -topState:function () {
555   - return this.conditionStack[this.conditionStack.length-2];
556   - },
557   -pushState:function begin(condition) {
558   - this.begin(condition);
559   - }});
560   -lexer.options = {};
561   -lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
562   -
563   -var YYSTATE=YY_START
564   -switch($avoiding_name_collisions) {
565   -case 0:
566   - if(yy_.yytext.slice(-1) !== "\\") this.begin("mu");
567   - if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1), this.begin("emu");
568   - if(yy_.yytext) return 14;
569   -
570   -break;
571   -case 1: return 14;
572   -break;
573   -case 2:
574   - if(yy_.yytext.slice(-1) !== "\\") this.popState();
575   - if(yy_.yytext.slice(-1) === "\\") yy_.yytext = yy_.yytext.substr(0,yy_.yyleng-1);
576   - return 14;
577   -
578   -break;
579   -case 3: yy_.yytext = yy_.yytext.substr(0, yy_.yyleng-4); this.popState(); return 15;
580   -break;
581   -case 4: this.begin("par"); return 24;
582   -break;
583   -case 5: return 16;
584   -break;
585   -case 6: return 20;
586   -break;
587   -case 7: return 19;
588   -break;
589   -case 8: return 19;
590   -break;
591   -case 9: return 23;
592   -break;
593   -case 10: return 23;
594   -break;
595   -case 11: this.popState(); this.begin('com');
596   -break;
597   -case 12: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.popState(); return 15;
598   -break;
599   -case 13: return 22;
600   -break;
601   -case 14: return 36;
602   -break;
603   -case 15: return 35;
604   -break;
605   -case 16: return 35;
606   -break;
607   -case 17: return 39;
608   -break;
609   -case 18: /*ignore whitespace*/
610   -break;
611   -case 19: this.popState(); return 18;
612   -break;
613   -case 20: this.popState(); return 18;
614   -break;
615   -case 21: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 30;
616   -break;
617   -case 22: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\'/g,"'"); return 30;
618   -break;
619   -case 23: yy_.yytext = yy_.yytext.substr(1); return 28;
620   -break;
621   -case 24: return 32;
622   -break;
623   -case 25: return 32;
624   -break;
625   -case 26: return 31;
626   -break;
627   -case 27: return 35;
628   -break;
629   -case 28: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 35;
630   -break;
631   -case 29: return 'INVALID';
632   -break;
633   -case 30: /*ignore whitespace*/
634   -break;
635   -case 31: this.popState(); return 37;
636   -break;
637   -case 32: return 5;
638   -break;
639   -}
640   -};
641   -lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\{\{>)/,/^(?:\{\{#)/,/^(?:\{\{\/)/,/^(?:\{\{\^)/,/^(?:\{\{\s*else\b)/,/^(?:\{\{\{)/,/^(?:\{\{&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{)/,/^(?:=)/,/^(?:\.(?=[} ]))/,/^(?:\.\.)/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}\}\})/,/^(?:\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@[a-zA-Z]+)/,/^(?:true(?=[}\s]))/,/^(?:false(?=[}\s]))/,/^(?:[0-9]+(?=[}\s]))/,/^(?:[a-zA-Z0-9_$-]+(?=[=}\s\/.]))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:\s+)/,/^(?:[a-zA-Z0-9_$-/]+)/,/^(?:$)/];
642   -lexer.conditions = {"mu":{"rules":[4,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,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"par":{"rules":[30,31],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}};
643   -return lexer;})()
644   -parser.lexer = lexer;
645   -function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
646   -return new Parser;
647   -})();;
648   -// lib/handlebars/compiler/base.js
649   -Handlebars.Parser = handlebars;
650   -
651   -Handlebars.parse = function(input) {
652   -
653   - // Just return if an already-compile AST was passed in.
654   - if(input.constructor === Handlebars.AST.ProgramNode) { return input; }
655   -
656   - Handlebars.Parser.yy = Handlebars.AST;
657   - return Handlebars.Parser.parse(input);
658   -};
659   -
660   -Handlebars.print = function(ast) {
661   - return new Handlebars.PrintVisitor().accept(ast);
662   -};;
663   -// lib/handlebars/compiler/ast.js
664   -(function() {
665   -
666   - Handlebars.AST = {};
667   -
668   - Handlebars.AST.ProgramNode = function(statements, inverse) {
669   - this.type = "program";
670   - this.statements = statements;
671   - if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
672   - };
673   -
674   - Handlebars.AST.MustacheNode = function(rawParams, hash, unescaped) {
675   - this.type = "mustache";
676   - this.escaped = !unescaped;
677   - this.hash = hash;
678   -
679   - var id = this.id = rawParams[0];
680   - var params = this.params = rawParams.slice(1);
681   -
682   - // a mustache is an eligible helper if:
683   - // * its id is simple (a single part, not `this` or `..`)
684   - var eligibleHelper = this.eligibleHelper = id.isSimple;
685   -
686   - // a mustache is definitely a helper if:
687   - // * it is an eligible helper, and
688   - // * it has at least one parameter or hash segment
689   - this.isHelper = eligibleHelper && (params.length || hash);
690   -
691   - // if a mustache is an eligible helper but not a definite
692   - // helper, it is ambiguous, and will be resolved in a later
693   - // pass or at runtime.
694   - };
695   -
696   - Handlebars.AST.PartialNode = function(partialName, context) {
697   - this.type = "partial";
698   - this.partialName = partialName;
699   - this.context = context;
700   - };
701   -
702   - var verifyMatch = function(open, close) {
703   - if(open.original !== close.original) {
704   - throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
705   - }
706   - };
707   -
708   - Handlebars.AST.BlockNode = function(mustache, program, inverse, close) {
709   - verifyMatch(mustache.id, close);
710   - this.type = "block";
711   - this.mustache = mustache;
712   - this.program = program;
713   - this.inverse = inverse;
714   -
715   - if (this.inverse && !this.program) {
716   - this.isInverse = true;
717   - }
718   - };
719   -
720   - Handlebars.AST.ContentNode = function(string) {
721   - this.type = "content";
722   - this.string = string;
723   - };
724   -
725   - Handlebars.AST.HashNode = function(pairs) {
726   - this.type = "hash";
727   - this.pairs = pairs;
728   - };
729   -
730   - Handlebars.AST.IdNode = function(parts) {
731   - this.type = "ID";
732   - this.original = parts.join(".");
733   -
734   - var dig = [], depth = 0;
735   -
736   - for(var i=0,l=parts.length; i<l; i++) {
737   - var part = parts[i];
738   -
739   - if (part === ".." || part === "." || part === "this") {
740   - if (dig.length > 0) { throw new Handlebars.Exception("Invalid path: " + this.original); }
741   - else if (part === "..") { depth++; }
742   - else { this.isScoped = true; }
743   - }
744   - else { dig.push(part); }
745   - }
746   -
747   - this.parts = dig;
748   - this.string = dig.join('.');
749   - this.depth = depth;
750   -
751   - // an ID is simple if it only has one part, and that part is not
752   - // `..` or `this`.
753   - this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
754   -
755   - this.stringModeValue = this.string;
756   - };
757   -
758   - Handlebars.AST.PartialNameNode = function(name) {
759   - this.type = "PARTIAL_NAME";
760   - this.name = name;
761   - };
762   -
763   - Handlebars.AST.DataNode = function(id) {
764   - this.type = "DATA";
765   - this.id = id;
766   - };
767   -
768   - Handlebars.AST.StringNode = function(string) {
769   - this.type = "STRING";
770   - this.string = string;
771   - this.stringModeValue = string;
772   - };
773   -
774   - Handlebars.AST.IntegerNode = function(integer) {
775   - this.type = "INTEGER";
776   - this.integer = integer;
777   - this.stringModeValue = Number(integer);
778   - };
779   -
780   - Handlebars.AST.BooleanNode = function(bool) {
781   - this.type = "BOOLEAN";
782   - this.bool = bool;
783   - this.stringModeValue = bool === "true";
784   - };
785   -
786   - Handlebars.AST.CommentNode = function(comment) {
787   - this.type = "comment";
788   - this.comment = comment;
789   - };
790   -
791   -})();;
792   -// lib/handlebars/utils.js
793   -
794   -var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
795   -
796   -Handlebars.Exception = function(message) {
797   - var tmp = Error.prototype.constructor.apply(this, arguments);
798   -
799   - // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
800   - for (var idx = 0; idx < errorProps.length; idx++) {
801   - this[errorProps[idx]] = tmp[errorProps[idx]];
802   - }
803   -};
804   -Handlebars.Exception.prototype = new Error();
805   -
806   -// Build out our basic SafeString type
807   -Handlebars.SafeString = function(string) {
808   - this.string = string;
809   -};
810   -Handlebars.SafeString.prototype.toString = function() {
811   - return this.string.toString();
812   -};
813   -
814   -(function() {
815   - var escape = {
816   - "&": "&amp;",
817   - "<": "&lt;",
818   - ">": "&gt;",
819   - '"': "&quot;",
820   - "'": "&#x27;",
821   - "`": "&#x60;"
822   - };
823   -
824   - var badChars = /[&<>"'`]/g;
825   - var possible = /[&<>"'`]/;
826   -
827   - var escapeChar = function(chr) {
828   - return escape[chr] || "&amp;";
829   - };
830   -
831   - Handlebars.Utils = {
832   - escapeExpression: function(string) {
833   - // don't escape SafeStrings, since they're already safe
834   - if (string instanceof Handlebars.SafeString) {
835   - return string.toString();
836   - } else if (string == null || string === false) {
837   - return "";
838   - }
839   -
840   - if(!possible.test(string)) { return string; }
841   - return string.replace(badChars, escapeChar);
842   - },
843   -
844   - isEmpty: function(value) {
845   - if (!value && value !== 0) {
846   - return true;
847   - } else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
848   - return true;
849   - } else {
850   - return false;
851   - }
852   - }
853   - };
854   -})();;
855   -// lib/handlebars/compiler/compiler.js
856   -
857   -/*jshint eqnull:true*/
858   -Handlebars.Compiler = function() {};
859   -Handlebars.JavaScriptCompiler = function() {};
860   -
861   -(function(Compiler, JavaScriptCompiler) {
862   - // the foundHelper register will disambiguate helper lookup from finding a
863   - // function in a context. This is necessary for mustache compatibility, which
864   - // requires that context functions in blocks are evaluated by blockHelperMissing,
865   - // and then proceed as if the resulting value was provided to blockHelperMissing.
866   -
867   - Compiler.prototype = {
868   - compiler: Compiler,
869   -
870   - disassemble: function() {
871   - var opcodes = this.opcodes, opcode, out = [], params, param;
872   -
873   - for (var i=0, l=opcodes.length; i<l; i++) {
874   - opcode = opcodes[i];
875   -
876   - if (opcode.opcode === 'DECLARE') {
877   - out.push("DECLARE " + opcode.name + "=" + opcode.value);
878   - } else {
879   - params = [];
880   - for (var j=0; j<opcode.args.length; j++) {
881   - param = opcode.args[j];
882   - if (typeof param === "string") {
883   - param = "\"" + param.replace("\n", "\\n") + "\"";
884   - }
885   - params.push(param);
886   - }
887   - out.push(opcode.opcode + " " + params.join(" "));
888   - }
889   - }
890   -
891   - return out.join("\n");
892   - },
893   - equals: function(other) {
894   - var len = this.opcodes.length;
895   - if (other.opcodes.length !== len) {
896   - return false;
897   - }
898   -
899   - for (var i = 0; i < len; i++) {
900   - var opcode = this.opcodes[i],
901   - otherOpcode = other.opcodes[i];
902   - if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
903   - return false;
904   - }
905   - for (var j = 0; j < opcode.args.length; j++) {
906   - if (opcode.args[j] !== otherOpcode.args[j]) {
907   - return false;
908   - }
909   - }
910   - }
911   - return true;
912   - },
913   -
914   - guid: 0,
915   -
916   - compile: function(program, options) {
917   - this.children = [];
918   - this.depths = {list: []};
919   - this.options = options;
920   -
921   - // These changes will propagate to the other compiler components
922   - var knownHelpers = this.options.knownHelpers;
923   - this.options.knownHelpers = {
924   - 'helperMissing': true,
925   - 'blockHelperMissing': true,
926   - 'each': true,
927   - 'if': true,
928   - 'unless': true,
929   - 'with': true,
930   - 'log': true
931   - };
932   - if (knownHelpers) {
933   - for (var name in knownHelpers) {
934   - this.options.knownHelpers[name] = knownHelpers[name];
935   - }
936   - }
937   -
938   - return this.program(program);
939   - },
940   -
941   - accept: function(node) {
942   - return this[node.type](node);
943   - },
944   -
945   - program: function(program) {
946   - var statements = program.statements, statement;
947   - this.opcodes = [];
948   -
949   - for(var i=0, l=statements.length; i<l; i++) {
950   - statement = statements[i];
951   - this[statement.type](statement);
952   - }
953   - this.isSimple = l === 1;
954   -
955   - this.depths.list = this.depths.list.sort(function(a, b) {
956   - return a - b;
957   - });
958   -
959   - return this;
960   - },
961   -
962   - compileProgram: function(program) {
963   - var result = new this.compiler().compile(program, this.options);
964   - var guid = this.guid++, depth;
965   -
966   - this.usePartial = this.usePartial || result.usePartial;
967   -
968   - this.children[guid] = result;
969   -
970   - for(var i=0, l=result.depths.list.length; i<l; i++) {
971   - depth = result.depths.list[i];
972   -
973   - if(depth < 2) { continue; }
974   - else { this.addDepth(depth - 1); }
975   - }
976   -
977   - return guid;
978   - },
979   -
980   - block: function(block) {
981   - var mustache = block.mustache,
982   - program = block.program,
983   - inverse = block.inverse;
984   -
985   - if (program) {
986   - program = this.compileProgram(program);
987   - }
988   -
989   - if (inverse) {
990   - inverse = this.compileProgram(inverse);
991   - }
992   -
993   - var type = this.classifyMustache(mustache);
994   -
995   - if (type === "helper") {
996   - this.helperMustache(mustache, program, inverse);
997   - } else if (type === "simple") {
998   - this.simpleMustache(mustache);
999   -
1000   - // now that the simple mustache is resolved, we need to
1001   - // evaluate it by executing `blockHelperMissing`
1002   - this.opcode('pushProgram', program);
1003   - this.opcode('pushProgram', inverse);
1004   - this.opcode('emptyHash');
1005   - this.opcode('blockValue');
1006   - } else {
1007   - this.ambiguousMustache(mustache, program, inverse);
1008   -
1009   - // now that the simple mustache is resolved, we need to
1010   - // evaluate it by executing `blockHelperMissing`
1011   - this.opcode('pushProgram', program);
1012   - this.opcode('pushProgram', inverse);
1013   - this.opcode('emptyHash');
1014   - this.opcode('ambiguousBlockValue');
1015   - }
1016   -
1017   - this.opcode('append');
1018   - },
1019   -
1020   - hash: function(hash) {
1021   - var pairs = hash.pairs, pair, val;
1022   -
1023   - this.opcode('pushHash');
1024   -
1025   - for(var i=0, l=pairs.length; i<l; i++) {
1026   - pair = pairs[i];
1027   - val = pair[1];
1028   -
1029   - if (this.options.stringParams) {
1030   - this.opcode('pushStringParam', val.stringModeValue, val.type);
1031   - } else {
1032   - this.accept(val);
1033   - }
1034   -
1035   - this.opcode('assignToHash', pair[0]);
1036   - }
1037   - this.opcode('popHash');
1038   - },
1039   -
1040   - partial: function(partial) {
1041   - var partialName = partial.partialName;
1042   - this.usePartial = true;
1043   -
1044   - if(partial.context) {
1045   - this.ID(partial.context);
1046   - } else {
1047   - this.opcode('push', 'depth0');
1048   - }
1049   -
1050   - this.opcode('invokePartial', partialName.name);
1051   - this.opcode('append');
1052   - },
1053   -
1054   - content: function(content) {
1055   - this.opcode('appendContent', content.string);
1056   - },
1057   -
1058   - mustache: function(mustache) {
1059   - var options = this.options;
1060   - var type = this.classifyMustache(mustache);
1061   -
1062   - if (type === "simple") {
1063   - this.simpleMustache(mustache);
1064   - } else if (type === "helper") {
1065   - this.helperMustache(mustache);
1066   - } else {
1067   - this.ambiguousMustache(mustache);
1068   - }
1069   -
1070   - if(mustache.escaped && !options.noEscape) {
1071   - this.opcode('appendEscaped');
1072   - } else {
1073   - this.opcode('append');
1074   - }
1075   - },
1076   -
1077   - ambiguousMustache: function(mustache, program, inverse) {
1078   - var id = mustache.id,
1079   - name = id.parts[0],
1080   - isBlock = program != null || inverse != null;
1081   -
1082   - this.opcode('getContext', id.depth);
1083   -
1084   - this.opcode('pushProgram', program);
1085   - this.opcode('pushProgram', inverse);
1086   -
1087   - this.opcode('invokeAmbiguous', name, isBlock);
1088   - },
1089   -
1090   - simpleMustache: function(mustache) {
1091   - var id = mustache.id;
1092   -
1093   - if (id.type === 'DATA') {
1094   - this.DATA(id);
1095   - } else if (id.parts.length) {
1096   - this.ID(id);
1097   - } else {
1098   - // Simplified ID for `this`
1099   - this.addDepth(id.depth);
1100   - this.opcode('getContext', id.depth);
1101   - this.opcode('pushContext');
1102   - }
1103   -
1104   - this.opcode('resolvePossibleLambda');
1105   - },
1106   -
1107   - helperMustache: function(mustache, program, inverse) {
1108   - var params = this.setupFullMustacheParams(mustache, program, inverse),
1109   - name = mustache.id.parts[0];
1110   -
1111   - if (this.options.knownHelpers[name]) {
1112   - this.opcode('invokeKnownHelper', params.length, name);
1113   - } else if (this.knownHelpersOnly) {
1114   - throw new Error("You specified knownHelpersOnly, but used the unknown helper " + name);
1115   - } else {
1116   - this.opcode('invokeHelper', params.length, name);
1117   - }
1118   - },
1119   -
1120   - ID: function(id) {
1121   - this.addDepth(id.depth);
1122   - this.opcode('getContext', id.depth);
1123   -
1124   - var name = id.parts[0];
1125   - if (!name) {
1126   - this.opcode('pushContext');
1127   - } else {
1128   - this.opcode('lookupOnContext', id.parts[0]);
1129   - }
1130   -
1131   - for(var i=1, l=id.parts.length; i<l; i++) {
1132   - this.opcode('lookup', id.parts[i]);
1133   - }
1134   - },
1135   -
1136   - DATA: function(data) {
1137   - this.options.data = true;
1138   - this.opcode('lookupData', data.id);
1139   - },
1140   -
1141   - STRING: function(string) {
1142   - this.opcode('pushString', string.string);
1143   - },
1144   -
1145   - INTEGER: function(integer) {
1146   - this.opcode('pushLiteral', integer.integer);
1147   - },
1148   -
1149   - BOOLEAN: function(bool) {
1150   - this.opcode('pushLiteral', bool.bool);
1151   - },
1152   -
1153   - comment: function() {},
1154   -
1155   - // HELPERS
1156   - opcode: function(name) {
1157   - this.opcodes.push({ opcode: name, args: [].slice.call(arguments, 1) });
1158   - },
1159   -
1160   - declare: function(name, value) {
1161   - this.opcodes.push({ opcode: 'DECLARE', name: name, value: value });
1162   - },
1163   -
1164   - addDepth: function(depth) {
1165   - if(isNaN(depth)) { throw new Error("EWOT"); }
1166   - if(depth === 0) { return; }
1167   -
1168   - if(!this.depths[depth]) {
1169   - this.depths[depth] = true;
1170   - this.depths.list.push(depth);
1171   - }
1172   - },
1173   -
1174   - classifyMustache: function(mustache) {
1175   - var isHelper = mustache.isHelper;
1176   - var isEligible = mustache.eligibleHelper;
1177   - var options = this.options;
1178   -
1179   - // if ambiguous, we can possibly resolve the ambiguity now
1180   - if (isEligible && !isHelper) {
1181   - var name = mustache.id.parts[0];
1182   -
1183   - if (options.knownHelpers[name]) {
1184   - isHelper = true;
1185   - } else if (options.knownHelpersOnly) {
1186   - isEligible = false;
1187   - }
1188   - }
1189   -
1190   - if (isHelper) { return "helper"; }
1191   - else if (isEligible) { return "ambiguous"; }
1192   - else { return "simple"; }
1193   - },
1194   -
1195   - pushParams: function(params) {
1196   - var i = params.length, param;
1197   -
1198   - while(i--) {
1199   - param = params[i];
1200   -
1201   - if(this.options.stringParams) {
1202   - if(param.depth) {
1203   - this.addDepth(param.depth);
1204   - }
1205   -
1206   - this.opcode('getContext', param.depth || 0);
1207   - this.opcode('pushStringParam', param.stringModeValue, param.type);
1208   - } else {
1209   - this[param.type](param);
1210   - }
1211   - }
1212   - },
1213   -
1214   - setupMustacheParams: function(mustache) {
1215   - var params = mustache.params;
1216   - this.pushParams(params);
1217   -
1218   - if(mustache.hash) {
1219   - this.hash(mustache.hash);
1220   - } else {
1221   - this.opcode('emptyHash');
1222   - }
1223   -
1224   - return params;
1225   - },
1226   -
1227   - // this will replace setupMustacheParams when we're done
1228   - setupFullMustacheParams: function(mustache, program, inverse) {
1229   - var params = mustache.params;
1230   - this.pushParams(params);
1231   -
1232   - this.opcode('pushProgram', program);
1233   - this.opcode('pushProgram', inverse);
1234   -
1235   - if(mustache.hash) {
1236   - this.hash(mustache.hash);
1237   - } else {
1238   - this.opcode('emptyHash');
1239   - }
1240   -
1241   - return params;
1242   - }
1243   - };
1244   -
1245   - var Literal = function(value) {
1246   - this.value = value;
1247   - };
1248   -
1249   - JavaScriptCompiler.prototype = {
1250   - // PUBLIC API: You can override these methods in a subclass to provide
1251   - // alternative compiled forms for name lookup and buffering semantics
1252   - nameLookup: function(parent, name /* , type*/) {
1253   - if (/^[0-9]+$/.test(name)) {
1254   - return parent + "[" + name + "]";
1255   - } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
1256   - return parent + "." + name;
1257   - }
1258   - else {
1259   - return parent + "['" + name + "']";
1260   - }
1261   - },
1262   -
1263   - appendToBuffer: function(string) {
1264   - if (this.environment.isSimple) {
1265