handlebars-source 1.3.0 → 2.0.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of handlebars-source might be problematic. Click here for more details.

Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/handlebars.js +993 -660
  3. data/handlebars.runtime.js +213 -83
  4. metadata +6 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f7ed070b2fd379233146670c48e214ac5a591487
4
- data.tar.gz: 4957de32810607c0596f94202f44f7832a296a77
3
+ metadata.gz: 773c6c002a03148e1170aebc616b08f3fd55f366
4
+ data.tar.gz: 430030831ffbd105b12f91b06dd3eeb390a76edc
5
5
  SHA512:
6
- metadata.gz: 44792c0ed6c83f3e3434bf2f06454015a897d55a0417006a4845dec1f6895f3b6f1696e2542591da36a0a883dffdbdba9e06c10bc172a16c37ef98535320339c
7
- data.tar.gz: 6428de98a351d402e2ea81e6fbf8fb649fb72e1d24b7f424de3b53db7d6dfe061461137ab8019b59ef8afb98bbfb97b44edbdd5d229309869890c04ee5ca304d
6
+ metadata.gz: 41e79a8c477fbc0645eb26b6aa669e1fde4ea5902f7e292be0e53ae90f42fabbcada14cda8a47ae9885d873c32a68a7c6be05bd52b9478ae6d039d37f9feb2fe
7
+ data.tar.gz: 9a8923a8c869ccd11a4754324eb03ada4a73febac4fba7f4396feb20d752f5064d5d0ccf167a24ba8d3e4c2e348d0ddca92ea1e45f6584e43fadfff7498db8ff
@@ -1,8 +1,8 @@
1
1
  /*!
2
2
 
3
- handlebars v1.3.0
3
+ handlebars v2.0.0-beta.1
4
4
 
5
- Copyright (C) 2011 by Yehuda Katz
5
+ Copyright (C) 2011-2014 by Yehuda Katz
6
6
 
7
7
  Permission is hereby granted, free of charge, to any person obtaining a copy
8
8
  of this software and associated documentation files (the "Software"), to deal
@@ -25,7 +25,15 @@ THE SOFTWARE.
25
25
  @license
26
26
  */
27
27
  /* exported Handlebars */
28
- var Handlebars = (function() {
28
+ (function (root, factory) {
29
+ if (typeof define === 'function' && define.amd) {
30
+ define([], factory);
31
+ } else if (typeof exports === 'object') {
32
+ module.exports = factory();
33
+ } else {
34
+ root.Handlebars = root.Handlebars || factory();
35
+ }
36
+ }(this, function () {
29
37
  // handlebars/safe-string.js
30
38
  var __module4__ = (function() {
31
39
  "use strict";
@@ -63,15 +71,19 @@ var __module3__ = (function(__dependency1__) {
63
71
  var possible = /[&<>"'`]/;
64
72
 
65
73
  function escapeChar(chr) {
66
- return escape[chr] || "&amp;";
74
+ return escape[chr];
67
75
  }
68
76
 
69
- function extend(obj, value) {
70
- for(var key in value) {
71
- if(Object.prototype.hasOwnProperty.call(value, key)) {
72
- obj[key] = value[key];
77
+ function extend(obj /* , ...source */) {
78
+ for (var i = 1; i < arguments.length; i++) {
79
+ for (var key in arguments[i]) {
80
+ if (Object.prototype.hasOwnProperty.call(arguments[i], key)) {
81
+ obj[key] = arguments[i][key];
82
+ }
73
83
  }
74
84
  }
85
+
86
+ return obj;
75
87
  }
76
88
 
77
89
  __exports__.extend = extend;var toString = Object.prototype.toString;
@@ -82,6 +94,7 @@ var __module3__ = (function(__dependency1__) {
82
94
  return typeof value === 'function';
83
95
  };
84
96
  // fallback for older versions of Chrome and Safari
97
+ /* istanbul ignore next */
85
98
  if (isFunction(/x/)) {
86
99
  isFunction = function(value) {
87
100
  return typeof value === 'function' && toString.call(value) === '[object Function]';
@@ -89,6 +102,7 @@ var __module3__ = (function(__dependency1__) {
89
102
  }
90
103
  var isFunction;
91
104
  __exports__.isFunction = isFunction;
105
+ /* istanbul ignore next */
92
106
  var isArray = Array.isArray || function(value) {
93
107
  return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
94
108
  };
@@ -98,8 +112,10 @@ var __module3__ = (function(__dependency1__) {
98
112
  // don't escape SafeStrings, since they're already safe
99
113
  if (string instanceof SafeString) {
100
114
  return string.toString();
101
- } else if (!string && string !== 0) {
115
+ } else if (string == null) {
102
116
  return "";
117
+ } else if (!string) {
118
+ return string + '';
103
119
  }
104
120
 
105
121
  // Force a string conversion as this will be done by the append regardless and
@@ -121,7 +137,11 @@ var __module3__ = (function(__dependency1__) {
121
137
  }
122
138
  }
123
139
 
124
- __exports__.isEmpty = isEmpty;
140
+ __exports__.isEmpty = isEmpty;function appendContextPath(contextPath, id) {
141
+ return (contextPath ? contextPath + '.' : '') + id;
142
+ }
143
+
144
+ __exports__.appendContextPath = appendContextPath;
125
145
  return __exports__;
126
146
  })(__module4__);
127
147
 
@@ -166,14 +186,16 @@ var __module2__ = (function(__dependency1__, __dependency2__) {
166
186
  var Utils = __dependency1__;
167
187
  var Exception = __dependency2__;
168
188
 
169
- var VERSION = "1.3.0";
170
- __exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
189
+ var VERSION = "2.0.0-beta.1";
190
+ __exports__.VERSION = VERSION;var COMPILER_REVISION = 6;
171
191
  __exports__.COMPILER_REVISION = COMPILER_REVISION;
172
192
  var REVISION_CHANGES = {
173
193
  1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
174
194
  2: '== 1.0.0-rc.3',
175
195
  3: '== 1.0.0-rc.4',
176
- 4: '>= 1.0.0'
196
+ 4: '== 1.x.x',
197
+ 5: '== 2.0.0-alpha.x',
198
+ 6: '>= 2.0.0-beta.1'
177
199
  };
178
200
  __exports__.REVISION_CHANGES = REVISION_CHANGES;
179
201
  var isArray = Utils.isArray,
@@ -194,15 +216,17 @@ var __module2__ = (function(__dependency1__, __dependency2__) {
194
216
  logger: logger,
195
217
  log: log,
196
218
 
197
- registerHelper: function(name, fn, inverse) {
219
+ registerHelper: function(name, fn) {
198
220
  if (toString.call(name) === objectType) {
199
- if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
221
+ if (fn) { throw new Exception('Arg not supported with multiple helpers'); }
200
222
  Utils.extend(this.helpers, name);
201
223
  } else {
202
- if (inverse) { fn.not = inverse; }
203
224
  this.helpers[name] = fn;
204
225
  }
205
226
  },
227
+ unregisterHelper: function(name) {
228
+ delete this.helpers[name];
229
+ },
206
230
 
207
231
  registerPartial: function(name, str) {
208
232
  if (toString.call(name) === objectType) {
@@ -210,22 +234,26 @@ var __module2__ = (function(__dependency1__, __dependency2__) {
210
234
  } else {
211
235
  this.partials[name] = str;
212
236
  }
237
+ },
238
+ unregisterPartial: function(name) {
239
+ delete this.partials[name];
213
240
  }
214
241
  };
215
242
 
216
243
  function registerDefaultHelpers(instance) {
217
- instance.registerHelper('helperMissing', function(arg) {
218
- if(arguments.length === 2) {
244
+ instance.registerHelper('helperMissing', function(/* [args, ]options */) {
245
+ if(arguments.length === 1) {
246
+ // A missing field in a {{foo}} constuct.
219
247
  return undefined;
220
248
  } else {
221
- throw new Exception("Missing helper: '" + arg + "'");
249
+ // Someone is actually trying to call something, blow up.
250
+ throw new Exception("Missing helper: '" + arguments[arguments.length-1].name + "'");
222
251
  }
223
252
  });
224
253
 
225
254
  instance.registerHelper('blockHelperMissing', function(context, options) {
226
- var inverse = options.inverse || function() {}, fn = options.fn;
227
-
228
- if (isFunction(context)) { context = context.call(this); }
255
+ var inverse = options.inverse,
256
+ fn = options.fn;
229
257
 
230
258
  if(context === true) {
231
259
  return fn(this);
@@ -233,19 +261,38 @@ var __module2__ = (function(__dependency1__, __dependency2__) {
233
261
  return inverse(this);
234
262
  } else if (isArray(context)) {
235
263
  if(context.length > 0) {
264
+ if (options.ids) {
265
+ options.ids = [options.name];
266
+ }
267
+
236
268
  return instance.helpers.each(context, options);
237
269
  } else {
238
270
  return inverse(this);
239
271
  }
240
272
  } else {
241
- return fn(context);
273
+ if (options.data && options.ids) {
274
+ var data = createFrame(options.data);
275
+ data.contextPath = Utils.appendContextPath(options.data.contextPath, options.name);
276
+ options = {data: data};
277
+ }
278
+
279
+ return fn(context, options);
242
280
  }
243
281
  });
244
282
 
245
283
  instance.registerHelper('each', function(context, options) {
284
+ if (!options) {
285
+ throw new Exception('Must pass iterator to #each');
286
+ }
287
+
246
288
  var fn = options.fn, inverse = options.inverse;
247
289
  var i = 0, ret = "", data;
248
290
 
291
+ var contextPath;
292
+ if (options.data && options.ids) {
293
+ contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.';
294
+ }
295
+
249
296
  if (isFunction(context)) { context = context.call(this); }
250
297
 
251
298
  if (options.data) {
@@ -259,16 +306,24 @@ var __module2__ = (function(__dependency1__, __dependency2__) {
259
306
  data.index = i;
260
307
  data.first = (i === 0);
261
308
  data.last = (i === (context.length-1));
309
+
310
+ if (contextPath) {
311
+ data.contextPath = contextPath + i;
312
+ }
262
313
  }
263
314
  ret = ret + fn(context[i], { data: data });
264
315
  }
265
316
  } else {
266
317
  for(var key in context) {
267
318
  if(context.hasOwnProperty(key)) {
268
- if(data) {
269
- data.key = key;
319
+ if(data) {
320
+ data.key = key;
270
321
  data.index = i;
271
322
  data.first = (i === 0);
323
+
324
+ if (contextPath) {
325
+ data.contextPath = contextPath + key;
326
+ }
272
327
  }
273
328
  ret = ret + fn(context[key], {data: data});
274
329
  i++;
@@ -304,13 +359,29 @@ var __module2__ = (function(__dependency1__, __dependency2__) {
304
359
  instance.registerHelper('with', function(context, options) {
305
360
  if (isFunction(context)) { context = context.call(this); }
306
361
 
307
- if (!Utils.isEmpty(context)) return options.fn(context);
362
+ var fn = options.fn;
363
+
364
+ if (!Utils.isEmpty(context)) {
365
+ if (options.data && options.ids) {
366
+ var data = createFrame(options.data);
367
+ data.contextPath = Utils.appendContextPath(options.data.contextPath, options.ids[0]);
368
+ options = {data:data};
369
+ }
370
+
371
+ return fn(context, options);
372
+ } else {
373
+ return options.inverse(this);
374
+ }
308
375
  });
309
376
 
310
377
  instance.registerHelper('log', function(context, options) {
311
378
  var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
312
379
  instance.log(level, context);
313
380
  });
381
+
382
+ instance.registerHelper('lookup', function(obj, field) {
383
+ return obj && obj[field];
384
+ });
314
385
  }
315
386
 
316
387
  var logger = {
@@ -334,12 +405,12 @@ var __module2__ = (function(__dependency1__, __dependency2__) {
334
405
  }
335
406
  };
336
407
  __exports__.logger = logger;
337
- function log(level, obj) { logger.log(level, obj); }
338
-
339
- __exports__.log = log;var createFrame = function(object) {
340
- var obj = {};
341
- Utils.extend(obj, object);
342
- return obj;
408
+ var log = logger.log;
409
+ __exports__.log = log;
410
+ var createFrame = function(object) {
411
+ var frame = Utils.extend({}, object);
412
+ frame._parent = object;
413
+ return frame;
343
414
  };
344
415
  __exports__.createFrame = createFrame;
345
416
  return __exports__;
@@ -353,6 +424,7 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
353
424
  var Exception = __dependency2__;
354
425
  var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
355
426
  var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
427
+ var createFrame = __dependency3__.createFrame;
356
428
 
357
429
  function checkRevision(compilerInfo) {
358
430
  var compilerRevision = compilerInfo && compilerInfo[0] || 1,
@@ -375,20 +447,43 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
375
447
  __exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
376
448
 
377
449
  function template(templateSpec, env) {
450
+ /* istanbul ignore next */
378
451
  if (!env) {
379
452
  throw new Exception("No environment passed to template");
380
453
  }
454
+ if (!templateSpec || !templateSpec.main) {
455
+ throw new Exception('Unknown template object: ' + typeof templateSpec);
456
+ }
381
457
 
382
458
  // Note: Using env.VM references rather than local var references throughout this section to allow
383
459
  // for external users to override these as psuedo-supported APIs.
384
- var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
385
- var result = env.VM.invokePartial.apply(this, arguments);
386
- if (result != null) { return result; }
387
-
388
- if (env.compile) {
389
- var options = { helpers: helpers, partials: partials, data: data };
390
- partials[name] = env.compile(partial, { data: data !== undefined }, env);
391
- return partials[name](context, options);
460
+ env.VM.checkRevision(templateSpec.compiler);
461
+
462
+ var invokePartialWrapper = function(partial, indent, name, context, hash, helpers, partials, data, depths) {
463
+ if (hash) {
464
+ context = Utils.extend({}, context, hash);
465
+ }
466
+
467
+ var result = env.VM.invokePartial.call(this, partial, name, context, helpers, partials, data, depths);
468
+
469
+ if (result == null && env.compile) {
470
+ var options = { helpers: helpers, partials: partials, data: data, depths: depths };
471
+ partials[name] = env.compile(partial, { data: data !== undefined, compat: templateSpec.compat }, env);
472
+ result = partials[name](context, options);
473
+ }
474
+ if (result != null) {
475
+ if (indent) {
476
+ var lines = result.split('\n');
477
+ for (var i = 0, l = lines.length; i < l; i++) {
478
+ if (!lines[i] && i + 1 === l) {
479
+ break;
480
+ }
481
+
482
+ lines[i] = indent + lines[i];
483
+ }
484
+ result = lines.join('\n');
485
+ }
486
+ return result;
392
487
  } else {
393
488
  throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
394
489
  }
@@ -396,84 +491,110 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
396
491
 
397
492
  // Just add water
398
493
  var container = {
494
+ lookup: function(depths, name) {
495
+ var len = depths.length;
496
+ for (var i = 0; i < len; i++) {
497
+ if (depths[i] && depths[i][name] != null) {
498
+ return depths[i][name];
499
+ }
500
+ }
501
+ },
502
+ lambda: function(current, context) {
503
+ return typeof current === 'function' ? current.call(context) : current;
504
+ },
505
+
399
506
  escapeExpression: Utils.escapeExpression,
400
507
  invokePartial: invokePartialWrapper,
508
+
509
+ fn: function(i) {
510
+ return templateSpec[i];
511
+ },
512
+
401
513
  programs: [],
402
- program: function(i, fn, data) {
403
- var programWrapper = this.programs[i];
404
- if(data) {
405
- programWrapper = program(i, fn, data);
514
+ program: function(i, data, depths) {
515
+ var programWrapper = this.programs[i],
516
+ fn = this.fn(i);
517
+ if (data || depths) {
518
+ programWrapper = program(this, i, fn, data, depths);
406
519
  } else if (!programWrapper) {
407
- programWrapper = this.programs[i] = program(i, fn);
520
+ programWrapper = this.programs[i] = program(this, i, fn);
408
521
  }
409
522
  return programWrapper;
410
523
  },
524
+
525
+ data: function(data, depth) {
526
+ while (data && depth--) {
527
+ data = data._parent;
528
+ }
529
+ return data;
530
+ },
411
531
  merge: function(param, common) {
412
532
  var ret = param || common;
413
533
 
414
534
  if (param && common && (param !== common)) {
415
- ret = {};
416
- Utils.extend(ret, common);
417
- Utils.extend(ret, param);
535
+ ret = Utils.extend({}, common, param);
418
536
  }
537
+
419
538
  return ret;
420
539
  },
421
- programWithDepth: env.VM.programWithDepth,
540
+
422
541
  noop: env.VM.noop,
423
- compilerInfo: null
542
+ compilerInfo: templateSpec.compiler
424
543
  };
425
544
 
426
- return function(context, options) {
545
+ var ret = function(context, options) {
427
546
  options = options || {};
428
- var namespace = options.partial ? options : env,
429
- helpers,
430
- partials;
547
+ var data = options.data;
431
548
 
432
- if (!options.partial) {
433
- helpers = options.helpers;
434
- partials = options.partials;
549
+ ret._setup(options);
550
+ if (!options.partial && templateSpec.useData) {
551
+ data = initData(context, data);
435
552
  }
436
- var result = templateSpec.call(
437
- container,
438
- namespace, context,
439
- helpers,
440
- partials,
441
- options.data);
442
-
443
- if (!options.partial) {
444
- env.VM.checkRevision(container.compilerInfo);
553
+ var depths;
554
+ if (templateSpec.useDepths) {
555
+ depths = options.depths ? [context].concat(options.depths) : [context];
445
556
  }
446
557
 
447
- return result;
558
+ return templateSpec.main.call(container, context, container.helpers, container.partials, data, depths);
448
559
  };
449
- }
560
+ ret.isTop = true;
450
561
 
451
- __exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
452
- var args = Array.prototype.slice.call(arguments, 3);
562
+ ret._setup = function(options) {
563
+ if (!options.partial) {
564
+ container.helpers = container.merge(options.helpers, env.helpers);
453
565
 
454
- var prog = function(context, options) {
455
- options = options || {};
566
+ if (templateSpec.usePartial) {
567
+ container.partials = container.merge(options.partials, env.partials);
568
+ }
569
+ } else {
570
+ container.helpers = options.helpers;
571
+ container.partials = options.partials;
572
+ }
573
+ };
456
574
 
457
- return fn.apply(this, [context, options.data || data].concat(args));
575
+ ret._child = function(i, data, depths) {
576
+ if (templateSpec.useDepths && !depths) {
577
+ throw new Exception('must pass parent depths');
578
+ }
579
+
580
+ return program(container, i, templateSpec[i], data, depths);
458
581
  };
459
- prog.program = i;
460
- prog.depth = args.length;
461
- return prog;
582
+ return ret;
462
583
  }
463
584
 
464
- __exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
585
+ __exports__.template = template;function program(container, i, fn, data, depths) {
465
586
  var prog = function(context, options) {
466
587
  options = options || {};
467
588
 
468
- return fn(context, options.data || data);
589
+ return fn.call(container, context, container.helpers, container.partials, options.data || data, depths && [context].concat(depths));
469
590
  };
470
591
  prog.program = i;
471
- prog.depth = 0;
592
+ prog.depth = depths ? depths.length : 0;
472
593
  return prog;
473
594
  }
474
595
 
475
- __exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
476
- var options = { partial: true, helpers: helpers, partials: partials, data: data };
596
+ __exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data, depths) {
597
+ var options = { partial: true, helpers: helpers, partials: partials, data: data, depths: depths };
477
598
 
478
599
  if(partial === undefined) {
479
600
  throw new Exception("The partial " + name + " could not be found");
@@ -484,7 +605,13 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
484
605
 
485
606
  __exports__.invokePartial = invokePartial;function noop() { return ""; }
486
607
 
487
- __exports__.noop = noop;
608
+ __exports__.noop = noop;function initData(context, data) {
609
+ if (!data || !('root' in data)) {
610
+ data = data ? createFrame(data) : {};
611
+ data.root = context;
612
+ }
613
+ return data;
614
+ }
488
615
  return __exports__;
489
616
  })(__module3__, __module5__, __module2__);
490
617
 
@@ -510,6 +637,7 @@ var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, _
510
637
  hb.SafeString = SafeString;
511
638
  hb.Exception = Exception;
512
639
  hb.Utils = Utils;
640
+ hb.escapeExpression = Utils.escapeExpression;
513
641
 
514
642
  hb.VM = runtime;
515
643
  hb.template = function(spec) {
@@ -522,6 +650,8 @@ var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, _
522
650
  var Handlebars = create();
523
651
  Handlebars.create = create;
524
652
 
653
+ Handlebars['default'] = Handlebars;
654
+
525
655
  __exports__ = Handlebars;
526
656
  return __exports__;
527
657
  })(__module2__, __module4__, __module5__, __module3__, __module6__);
@@ -532,7 +662,7 @@ var __module7__ = (function(__dependency1__) {
532
662
  var __exports__;
533
663
  var Exception = __dependency1__;
534
664
 
535
- function LocationInfo(locInfo){
665
+ function LocationInfo(locInfo) {
536
666
  locInfo = locInfo || {};
537
667
  this.firstLine = locInfo.first_line;
538
668
  this.firstColumn = locInfo.first_column;
@@ -541,38 +671,11 @@ var __module7__ = (function(__dependency1__) {
541
671
  }
542
672
 
543
673
  var AST = {
544
- ProgramNode: function(statements, inverseStrip, inverse, locInfo) {
545
- var inverseLocationInfo, firstInverseNode;
546
- if (arguments.length === 3) {
547
- locInfo = inverse;
548
- inverse = null;
549
- } else if (arguments.length === 2) {
550
- locInfo = inverseStrip;
551
- inverseStrip = null;
552
- }
553
-
674
+ ProgramNode: function(statements, strip, locInfo) {
554
675
  LocationInfo.call(this, locInfo);
555
676
  this.type = "program";
556
677
  this.statements = statements;
557
- this.strip = {};
558
-
559
- if(inverse) {
560
- firstInverseNode = inverse[0];
561
- if (firstInverseNode) {
562
- inverseLocationInfo = {
563
- first_line: firstInverseNode.firstLine,
564
- last_line: firstInverseNode.lastLine,
565
- last_column: firstInverseNode.lastColumn,
566
- first_column: firstInverseNode.firstColumn
567
- };
568
- this.inverse = new AST.ProgramNode(inverse, inverseStrip, inverseLocationInfo);
569
- } else {
570
- this.inverse = new AST.ProgramNode(inverse, inverseStrip);
571
- }
572
- this.strip.right = inverseStrip.left;
573
- } else if (inverseStrip) {
574
- this.strip.left = inverseStrip.right;
575
- }
678
+ this.strip = strip;
576
679
  },
577
680
 
578
681
  MustacheNode: function(rawParams, hash, open, strip, locInfo) {
@@ -596,8 +699,6 @@ var __module7__ = (function(__dependency1__) {
596
699
  this.sexpr = new AST.SexprNode(rawParams, hash);
597
700
  }
598
701
 
599
- this.sexpr.isRoot = true;
600
-
601
702
  // Support old AST API that stored this info in MustacheNode
602
703
  this.id = this.sexpr.id;
603
704
  this.params = this.sexpr.params;
@@ -615,57 +716,63 @@ var __module7__ = (function(__dependency1__) {
615
716
  var id = this.id = rawParams[0];
616
717
  var params = this.params = rawParams.slice(1);
617
718
 
618
- // a mustache is an eligible helper if:
619
- // * its id is simple (a single part, not `this` or `..`)
620
- var eligibleHelper = this.eligibleHelper = id.isSimple;
621
-
622
719
  // a mustache is definitely a helper if:
623
720
  // * it is an eligible helper, and
624
721
  // * it has at least one parameter or hash segment
625
- this.isHelper = eligibleHelper && (params.length || hash);
722
+ this.isHelper = !!(params.length || hash);
723
+
724
+ // a mustache is an eligible helper if:
725
+ // * its id is simple (a single part, not `this` or `..`)
726
+ this.eligibleHelper = this.isHelper || id.isSimple;
626
727
 
627
728
  // if a mustache is an eligible helper but not a definite
628
729
  // helper, it is ambiguous, and will be resolved in a later
629
730
  // pass or at runtime.
630
731
  },
631
732
 
632
- PartialNode: function(partialName, context, strip, locInfo) {
733
+ PartialNode: function(partialName, context, hash, strip, locInfo) {
633
734
  LocationInfo.call(this, locInfo);
634
735
  this.type = "partial";
635
736
  this.partialName = partialName;
636
737
  this.context = context;
738
+ this.hash = hash;
637
739
  this.strip = strip;
740
+
741
+ this.strip.inlineStandalone = true;
638
742
  },
639
743
 
640
- BlockNode: function(mustache, program, inverse, close, locInfo) {
744
+ BlockNode: function(mustache, program, inverse, strip, locInfo) {
641
745
  LocationInfo.call(this, locInfo);
642
746
 
643
- if(mustache.sexpr.id.original !== close.path.original) {
644
- throw new Exception(mustache.sexpr.id.original + " doesn't match " + close.path.original, this);
645
- }
646
-
647
747
  this.type = 'block';
648
748
  this.mustache = mustache;
649
749
  this.program = program;
650
750
  this.inverse = inverse;
651
-
652
- this.strip = {
653
- left: mustache.strip.left,
654
- right: close.strip.right
655
- };
656
-
657
- (program || inverse).strip.left = mustache.strip.right;
658
- (inverse || program).strip.right = close.strip.left;
751
+ this.strip = strip;
659
752
 
660
753
  if (inverse && !program) {
661
754
  this.isInverse = true;
662
755
  }
663
756
  },
664
757
 
758
+ RawBlockNode: function(mustache, content, close, locInfo) {
759
+ LocationInfo.call(this, locInfo);
760
+
761
+ if (mustache.sexpr.id.original !== close) {
762
+ throw new Exception(mustache.sexpr.id.original + " doesn't match " + close, this);
763
+ }
764
+
765
+ content = new AST.ContentNode(content, locInfo);
766
+
767
+ this.type = 'block';
768
+ this.mustache = mustache;
769
+ this.program = new AST.ProgramNode([content], {}, locInfo);
770
+ },
771
+
665
772
  ContentNode: function(string, locInfo) {
666
773
  LocationInfo.call(this, locInfo);
667
774
  this.type = "content";
668
- this.string = string;
775
+ this.original = this.string = string;
669
776
  },
670
777
 
671
778
  HashNode: function(pairs, locInfo) {
@@ -680,7 +787,8 @@ var __module7__ = (function(__dependency1__) {
680
787
 
681
788
  var original = "",
682
789
  dig = [],
683
- depth = 0;
790
+ depth = 0,
791
+ depthString = '';
684
792
 
685
793
  for(var i=0,l=parts.length; i<l; i++) {
686
794
  var part = parts[i].part;
@@ -691,6 +799,7 @@ var __module7__ = (function(__dependency1__) {
691
799
  throw new Exception("Invalid path: " + original, this);
692
800
  } else if (part === "..") {
693
801
  depth++;
802
+ depthString += '../';
694
803
  } else {
695
804
  this.isScoped = true;
696
805
  }
@@ -703,6 +812,7 @@ var __module7__ = (function(__dependency1__) {
703
812
  this.parts = dig;
704
813
  this.string = dig.join('.');
705
814
  this.depth = depth;
815
+ this.idName = depthString + this.string;
706
816
 
707
817
  // an ID is simple if it only has one part, and that part is not
708
818
  // `..` or `this`.
@@ -721,6 +831,8 @@ var __module7__ = (function(__dependency1__) {
721
831
  LocationInfo.call(this, locInfo);
722
832
  this.type = "DATA";
723
833
  this.id = id;
834
+ this.stringModeValue = id.stringModeValue;
835
+ this.idName = '@' + id.stringModeValue;
724
836
  },
725
837
 
726
838
  StringNode: function(string, locInfo) {
@@ -731,12 +843,12 @@ var __module7__ = (function(__dependency1__) {
731
843
  this.stringModeValue = string;
732
844
  },
733
845
 
734
- IntegerNode: function(integer, locInfo) {
846
+ NumberNode: function(number, locInfo) {
735
847
  LocationInfo.call(this, locInfo);
736
- this.type = "INTEGER";
848
+ this.type = "NUMBER";
737
849
  this.original =
738
- this.integer = integer;
739
- this.stringModeValue = Number(integer);
850
+ this.number = number;
851
+ this.stringModeValue = Number(number);
740
852
  },
741
853
 
742
854
  BooleanNode: function(bool, locInfo) {
@@ -750,9 +862,14 @@ var __module7__ = (function(__dependency1__) {
750
862
  LocationInfo.call(this, locInfo);
751
863
  this.type = "comment";
752
864
  this.comment = comment;
865
+
866
+ this.strip = {
867
+ inlineStandalone: true
868
+ };
753
869
  }
754
870
  };
755
871
 
872
+
756
873
  // Must be exported as an object rather than the root of the module as the jison lexer
757
874
  // most modify the object to operate properly.
758
875
  __exports__ = AST;
@@ -764,109 +881,108 @@ var __module9__ = (function() {
764
881
  "use strict";
765
882
  var __exports__;
766
883
  /* jshint ignore:start */
884
+ /* istanbul ignore next */
767
885
  /* Jison generated parser */
768
886
  var handlebars = (function(){
769
887
  var parser = {trace: function trace() { },
770
888
  yy: {},
771
- symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"sexpr":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"sexpr_repetition0":28,"sexpr_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"OPEN_SEXPR":35,"CLOSE_SEXPR":36,"hash":37,"hash_repetition_plus0":38,"hashSegment":39,"ID":40,"EQUALS":41,"DATA":42,"pathSegments":43,"SEP":44,"$accept":0,"$end":1},
772
- 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",32:"STRING",33:"INTEGER",34:"BOOLEAN",35:"OPEN_SEXPR",36:"CLOSE_SEXPR",40:"ID",41:"EQUALS",42:"DATA",44:"SEP"},
773
- productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[31,3],[37,1],[39,3],[26,1],[26,1],[26,1],[30,2],[21,1],[43,3],[43,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[38,1],[38,2]],
889
+ symbols_: {"error":2,"root":3,"program":4,"EOF":5,"program_repetition0":6,"statement":7,"mustache":8,"block":9,"rawBlock":10,"partial":11,"CONTENT":12,"COMMENT":13,"openRawBlock":14,"END_RAW_BLOCK":15,"OPEN_RAW_BLOCK":16,"sexpr":17,"CLOSE_RAW_BLOCK":18,"openBlock":19,"block_option0":20,"closeBlock":21,"openInverse":22,"block_option1":23,"OPEN_BLOCK":24,"CLOSE":25,"OPEN_INVERSE":26,"inverseAndProgram":27,"INVERSE":28,"OPEN_ENDBLOCK":29,"path":30,"OPEN":31,"OPEN_UNESCAPED":32,"CLOSE_UNESCAPED":33,"OPEN_PARTIAL":34,"partialName":35,"param":36,"partial_option0":37,"partial_option1":38,"sexpr_repetition0":39,"sexpr_option0":40,"dataName":41,"STRING":42,"NUMBER":43,"BOOLEAN":44,"OPEN_SEXPR":45,"CLOSE_SEXPR":46,"hash":47,"hash_repetition_plus0":48,"hashSegment":49,"ID":50,"EQUALS":51,"DATA":52,"pathSegments":53,"SEP":54,"$accept":0,"$end":1},
890
+ terminals_: {2:"error",5:"EOF",12:"CONTENT",13:"COMMENT",15:"END_RAW_BLOCK",16:"OPEN_RAW_BLOCK",18:"CLOSE_RAW_BLOCK",24:"OPEN_BLOCK",25:"CLOSE",26:"OPEN_INVERSE",28:"INVERSE",29:"OPEN_ENDBLOCK",31:"OPEN",32:"OPEN_UNESCAPED",33:"CLOSE_UNESCAPED",34:"OPEN_PARTIAL",42:"STRING",43:"NUMBER",44:"BOOLEAN",45:"OPEN_SEXPR",46:"CLOSE_SEXPR",50:"ID",51:"EQUALS",52:"DATA",54:"SEP"},
891
+ productions_: [0,[3,2],[4,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[10,3],[14,3],[9,4],[9,4],[19,3],[22,3],[27,2],[21,3],[8,3],[8,3],[11,5],[11,4],[17,3],[17,1],[36,1],[36,1],[36,1],[36,1],[36,1],[36,3],[47,1],[49,3],[35,1],[35,1],[35,1],[41,2],[30,1],[53,3],[53,1],[6,0],[6,2],[20,0],[20,1],[23,0],[23,1],[37,0],[37,1],[38,0],[38,1],[39,0],[39,2],[40,0],[40,1],[48,1],[48,2]],
774
892
  performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
775
893
 
776
894
  var $0 = $$.length - 1;
777
895
  switch (yystate) {
778
- case 1: return new yy.ProgramNode($$[$0-1], this._$);
779
- break;
780
- case 2: return new yy.ProgramNode([], this._$);
896
+ case 1: yy.prepareProgram($$[$0-1].statements, true); return $$[$0-1];
781
897
  break;
782
- case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0], this._$);
898
+ case 2:this.$ = new yy.ProgramNode(yy.prepareProgram($$[$0]), {}, this._$);
783
899
  break;
784
- case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0], this._$);
900
+ case 3:this.$ = $$[$0];
785
901
  break;
786
- case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], [], this._$);
902
+ case 4:this.$ = $$[$0];
787
903
  break;
788
- case 6:this.$ = new yy.ProgramNode($$[$0], this._$);
904
+ case 5:this.$ = $$[$0];
789
905
  break;
790
- case 7:this.$ = new yy.ProgramNode([], this._$);
906
+ case 6:this.$ = $$[$0];
791
907
  break;
792
- case 8:this.$ = new yy.ProgramNode([], this._$);
908
+ case 7:this.$ = new yy.ContentNode($$[$0], this._$);
793
909
  break;
794
- case 9:this.$ = [$$[$0]];
910
+ case 8:this.$ = new yy.CommentNode($$[$0], this._$);
795
911
  break;
796
- case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
912
+ case 9:this.$ = new yy.RawBlockNode($$[$0-2], $$[$0-1], $$[$0], this._$);
797
913
  break;
798
- case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0], this._$);
914
+ case 10:this.$ = new yy.MustacheNode($$[$0-1], null, '', '', this._$);
799
915
  break;
800
- case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0], this._$);
916
+ case 11:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], false, this._$);
801
917
  break;
802
- case 13:this.$ = $$[$0];
918
+ case 12:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], true, this._$);
803
919
  break;
804
- case 14:this.$ = $$[$0];
920
+ case 13:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$);
805
921
  break;
806
- case 15:this.$ = new yy.ContentNode($$[$0], this._$);
922
+ case 14:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$);
807
923
  break;
808
- case 16:this.$ = new yy.CommentNode($$[$0], this._$);
924
+ case 15:this.$ = { strip: yy.stripFlags($$[$0-1], $$[$0-1]), program: $$[$0] };
809
925
  break;
810
- case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
926
+ case 16:this.$ = {path: $$[$0-1], strip: yy.stripFlags($$[$0-2], $$[$0])};
811
927
  break;
812
- case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
928
+ case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$);
813
929
  break;
814
- case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
930
+ case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$);
815
931
  break;
816
- case 20:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
932
+ case 19:this.$ = new yy.PartialNode($$[$0-3], $$[$0-2], $$[$0-1], yy.stripFlags($$[$0-4], $$[$0]), this._$);
817
933
  break;
818
- case 21:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
934
+ case 20:this.$ = new yy.PartialNode($$[$0-2], undefined, $$[$0-1], yy.stripFlags($$[$0-3], $$[$0]), this._$);
819
935
  break;
820
- case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]), this._$);
936
+ case 21:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
821
937
  break;
822
- case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
938
+ case 22:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
823
939
  break;
824
- case 24:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
940
+ case 23:this.$ = $$[$0];
825
941
  break;
826
- case 25:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
942
+ case 24:this.$ = new yy.StringNode($$[$0], this._$);
827
943
  break;
828
- case 26:this.$ = $$[$0];
944
+ case 25:this.$ = new yy.NumberNode($$[$0], this._$);
829
945
  break;
830
- case 27:this.$ = new yy.StringNode($$[$0], this._$);
946
+ case 26:this.$ = new yy.BooleanNode($$[$0], this._$);
831
947
  break;
832
- case 28:this.$ = new yy.IntegerNode($$[$0], this._$);
948
+ case 27:this.$ = $$[$0];
833
949
  break;
834
- case 29:this.$ = new yy.BooleanNode($$[$0], this._$);
950
+ case 28:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
835
951
  break;
836
- case 30:this.$ = $$[$0];
952
+ case 29:this.$ = new yy.HashNode($$[$0], this._$);
837
953
  break;
838
- case 31:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
954
+ case 30:this.$ = [$$[$0-2], $$[$0]];
839
955
  break;
840
- case 32:this.$ = new yy.HashNode($$[$0], this._$);
956
+ case 31:this.$ = new yy.PartialNameNode($$[$0], this._$);
841
957
  break;
842
- case 33:this.$ = [$$[$0-2], $$[$0]];
958
+ case 32:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
843
959
  break;
844
- case 34:this.$ = new yy.PartialNameNode($$[$0], this._$);
960
+ case 33:this.$ = new yy.PartialNameNode(new yy.NumberNode($$[$0], this._$));
845
961
  break;
846
- case 35:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
962
+ case 34:this.$ = new yy.DataNode($$[$0], this._$);
847
963
  break;
848
- case 36:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0], this._$));
964
+ case 35:this.$ = new yy.IdNode($$[$0], this._$);
849
965
  break;
850
- case 37:this.$ = new yy.DataNode($$[$0], this._$);
966
+ case 36: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
851
967
  break;
852
- case 38:this.$ = new yy.IdNode($$[$0], this._$);
968
+ case 37:this.$ = [{part: $$[$0]}];
853
969
  break;
854
- case 39: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
970
+ case 38:this.$ = [];
855
971
  break;
856
- case 40:this.$ = [{part: $$[$0]}];
972
+ case 39:$$[$0-1].push($$[$0]);
857
973
  break;
858
- case 43:this.$ = [];
974
+ case 48:this.$ = [];
859
975
  break;
860
- case 44:$$[$0-1].push($$[$0]);
976
+ case 49:$$[$0-1].push($$[$0]);
861
977
  break;
862
- case 47:this.$ = [$$[$0]];
978
+ case 52:this.$ = [$$[$0]];
863
979
  break;
864
- case 48:$$[$0-1].push($$[$0]);
980
+ case 53:$$[$0-1].push($$[$0]);
865
981
  break;
866
982
  }
867
983
  },
868
- table: [{3:1,4:2,5:[1,3],8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[3]},{5:[1,16],8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[2,2]},{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]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{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]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:29,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:30,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:31,21:24,30:25,40:[1,28],42:[1,27],43:26},{21:33,26:32,32:[1,34],33:[1,35],40:[1,28],43:26},{1:[2,1]},{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]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,40:[1,28],42:[1,27],43:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,43],24:[2,43],28:43,32:[2,43],33:[2,43],34:[2,43],35:[2,43],36:[2,43],40:[2,43],42:[2,43]},{18:[2,25],24:[2,25],36:[2,25]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],35:[2,38],36:[2,38],40:[2,38],42:[2,38],44:[1,44]},{21:45,40:[1,28],43:26},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],42:[2,40],44:[2,40]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,41],21:50,27:49,40:[1,28],43:26},{18:[2,34],40:[2,34]},{18:[2,35],40:[2,35]},{18:[2,36],40:[2,36]},{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]},{21:51,40:[1,28],43:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{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]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,45],21:56,24:[2,45],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:[1,61],36:[2,45],37:55,38:62,39:63,40:[1,64],42:[1,27],43:26},{40:[1,65]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],35:[2,37],36:[2,37],40:[2,37],42:[2,37]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{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,66]},{18:[2,42]},{18:[1,67]},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],25:[1,15]},{18:[2,24],24:[2,24],36:[2,24]},{18:[2,44],24:[2,44],32:[2,44],33:[2,44],34:[2,44],35:[2,44],36:[2,44],40:[2,44],42:[2,44]},{18:[2,46],24:[2,46],36:[2,46]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],35:[2,26],36:[2,26],40:[2,26],42:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],35:[2,27],36:[2,27],40:[2,27],42:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],35:[2,28],36:[2,28],40:[2,28],42:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],35:[2,29],36:[2,29],40:[2,29],42:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],35:[2,30],36:[2,30],40:[2,30],42:[2,30]},{17:68,21:24,30:25,40:[1,28],42:[1,27],43:26},{18:[2,32],24:[2,32],36:[2,32],39:69,40:[1,70]},{18:[2,47],24:[2,47],36:[2,47],40:[2,47]},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],41:[1,71],42:[2,40],44:[2,40]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],35:[2,39],36:[2,39],40:[2,39],42:[2,39],44:[2,39]},{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]},{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]},{36:[1,72]},{18:[2,48],24:[2,48],36:[2,48],40:[2,48]},{41:[1,71]},{21:56,30:60,31:73,32:[1,57],33:[1,58],34:[1,59],35:[1,61],40:[1,28],42:[1,27],43:26},{18:[2,31],24:[2,31],32:[2,31],33:[2,31],34:[2,31],35:[2,31],36:[2,31],40:[2,31],42:[2,31]},{18:[2,33],24:[2,33],36:[2,33],40:[2,33]}],
869
- defaultActions: {3:[2,2],16:[2,1],50:[2,42]},
984
+ table: [{3:1,4:2,5:[2,38],6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],31:[2,38],32:[2,38],34:[2,38]},{1:[3]},{5:[1,4]},{5:[2,2],7:5,8:6,9:7,10:8,11:9,12:[1,10],13:[1,11],14:16,16:[1,20],19:14,22:15,24:[1,18],26:[1,19],28:[2,2],29:[2,2],31:[1,12],32:[1,13],34:[1,17]},{1:[2,1]},{5:[2,39],12:[2,39],13:[2,39],16:[2,39],24:[2,39],26:[2,39],28:[2,39],29:[2,39],31:[2,39],32:[2,39],34:[2,39]},{5:[2,3],12:[2,3],13:[2,3],16:[2,3],24:[2,3],26:[2,3],28:[2,3],29:[2,3],31:[2,3],32:[2,3],34:[2,3]},{5:[2,4],12:[2,4],13:[2,4],16:[2,4],24:[2,4],26:[2,4],28:[2,4],29:[2,4],31:[2,4],32:[2,4],34:[2,4]},{5:[2,5],12:[2,5],13:[2,5],16:[2,5],24:[2,5],26:[2,5],28:[2,5],29:[2,5],31:[2,5],32:[2,5],34:[2,5]},{5:[2,6],12:[2,6],13:[2,6],16:[2,6],24:[2,6],26:[2,6],28:[2,6],29:[2,6],31:[2,6],32:[2,6],34:[2,6]},{5:[2,7],12:[2,7],13:[2,7],16:[2,7],24:[2,7],26:[2,7],28:[2,7],29:[2,7],31:[2,7],32:[2,7],34:[2,7]},{5:[2,8],12:[2,8],13:[2,8],16:[2,8],24:[2,8],26:[2,8],28:[2,8],29:[2,8],31:[2,8],32:[2,8],34:[2,8]},{17:21,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:27,30:22,41:23,50:[1,26],52:[1,25],53:24},{4:28,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{4:29,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],28:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{12:[1,30]},{30:32,35:31,42:[1,33],43:[1,34],50:[1,26],53:24},{17:35,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:36,30:22,41:23,50:[1,26],52:[1,25],53:24},{17:37,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[1,38]},{18:[2,48],25:[2,48],33:[2,48],39:39,42:[2,48],43:[2,48],44:[2,48],45:[2,48],46:[2,48],50:[2,48],52:[2,48]},{18:[2,22],25:[2,22],33:[2,22],46:[2,22]},{18:[2,35],25:[2,35],33:[2,35],42:[2,35],43:[2,35],44:[2,35],45:[2,35],46:[2,35],50:[2,35],52:[2,35],54:[1,40]},{30:41,50:[1,26],53:24},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],52:[2,37],54:[2,37]},{33:[1,42]},{20:43,27:44,28:[1,45],29:[2,40]},{23:46,27:47,28:[1,45],29:[2,42]},{15:[1,48]},{25:[2,46],30:51,36:49,38:50,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],47:57,48:58,49:60,50:[1,59],52:[1,25],53:24},{25:[2,31],42:[2,31],43:[2,31],44:[2,31],45:[2,31],50:[2,31],52:[2,31]},{25:[2,32],42:[2,32],43:[2,32],44:[2,32],45:[2,32],50:[2,32],52:[2,32]},{25:[2,33],42:[2,33],43:[2,33],44:[2,33],45:[2,33],50:[2,33],52:[2,33]},{25:[1,61]},{25:[1,62]},{18:[1,63]},{5:[2,17],12:[2,17],13:[2,17],16:[2,17],24:[2,17],26:[2,17],28:[2,17],29:[2,17],31:[2,17],32:[2,17],34:[2,17]},{18:[2,50],25:[2,50],30:51,33:[2,50],36:65,40:64,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],46:[2,50],47:66,48:58,49:60,50:[1,59],52:[1,25],53:24},{50:[1,67]},{18:[2,34],25:[2,34],33:[2,34],42:[2,34],43:[2,34],44:[2,34],45:[2,34],46:[2,34],50:[2,34],52:[2,34]},{5:[2,18],12:[2,18],13:[2,18],16:[2,18],24:[2,18],26:[2,18],28:[2,18],29:[2,18],31:[2,18],32:[2,18],34:[2,18]},{21:68,29:[1,69]},{29:[2,41]},{4:70,6:3,12:[2,38],13:[2,38],16:[2,38],24:[2,38],26:[2,38],29:[2,38],31:[2,38],32:[2,38],34:[2,38]},{21:71,29:[1,69]},{29:[2,43]},{5:[2,9],12:[2,9],13:[2,9],16:[2,9],24:[2,9],26:[2,9],28:[2,9],29:[2,9],31:[2,9],32:[2,9],34:[2,9]},{25:[2,44],37:72,47:73,48:58,49:60,50:[1,74]},{25:[1,75]},{18:[2,23],25:[2,23],33:[2,23],42:[2,23],43:[2,23],44:[2,23],45:[2,23],46:[2,23],50:[2,23],52:[2,23]},{18:[2,24],25:[2,24],33:[2,24],42:[2,24],43:[2,24],44:[2,24],45:[2,24],46:[2,24],50:[2,24],52:[2,24]},{18:[2,25],25:[2,25],33:[2,25],42:[2,25],43:[2,25],44:[2,25],45:[2,25],46:[2,25],50:[2,25],52:[2,25]},{18:[2,26],25:[2,26],33:[2,26],42:[2,26],43:[2,26],44:[2,26],45:[2,26],46:[2,26],50:[2,26],52:[2,26]},{18:[2,27],25:[2,27],33:[2,27],42:[2,27],43:[2,27],44:[2,27],45:[2,27],46:[2,27],50:[2,27],52:[2,27]},{17:76,30:22,41:23,50:[1,26],52:[1,25],53:24},{25:[2,47]},{18:[2,29],25:[2,29],33:[2,29],46:[2,29],49:77,50:[1,74]},{18:[2,37],25:[2,37],33:[2,37],42:[2,37],43:[2,37],44:[2,37],45:[2,37],46:[2,37],50:[2,37],51:[1,78],52:[2,37],54:[2,37]},{18:[2,52],25:[2,52],33:[2,52],46:[2,52],50:[2,52]},{12:[2,13],13:[2,13],16:[2,13],24:[2,13],26:[2,13],28:[2,13],29:[2,13],31:[2,13],32:[2,13],34:[2,13]},{12:[2,14],13:[2,14],16:[2,14],24:[2,14],26:[2,14],28:[2,14],29:[2,14],31:[2,14],32:[2,14],34:[2,14]},{12:[2,10]},{18:[2,21],25:[2,21],33:[2,21],46:[2,21]},{18:[2,49],25:[2,49],33:[2,49],42:[2,49],43:[2,49],44:[2,49],45:[2,49],46:[2,49],50:[2,49],52:[2,49]},{18:[2,51],25:[2,51],33:[2,51],46:[2,51]},{18:[2,36],25:[2,36],33:[2,36],42:[2,36],43:[2,36],44:[2,36],45:[2,36],46:[2,36],50:[2,36],52:[2,36],54:[2,36]},{5:[2,11],12:[2,11],13:[2,11],16:[2,11],24:[2,11],26:[2,11],28:[2,11],29:[2,11],31:[2,11],32:[2,11],34:[2,11]},{30:79,50:[1,26],53:24},{29:[2,15]},{5:[2,12],12:[2,12],13:[2,12],16:[2,12],24:[2,12],26:[2,12],28:[2,12],29:[2,12],31:[2,12],32:[2,12],34:[2,12]},{25:[1,80]},{25:[2,45]},{51:[1,78]},{5:[2,20],12:[2,20],13:[2,20],16:[2,20],24:[2,20],26:[2,20],28:[2,20],29:[2,20],31:[2,20],32:[2,20],34:[2,20]},{46:[1,81]},{18:[2,53],25:[2,53],33:[2,53],46:[2,53],50:[2,53]},{30:51,36:82,41:55,42:[1,52],43:[1,53],44:[1,54],45:[1,56],50:[1,26],52:[1,25],53:24},{25:[1,83]},{5:[2,19],12:[2,19],13:[2,19],16:[2,19],24:[2,19],26:[2,19],28:[2,19],29:[2,19],31:[2,19],32:[2,19],34:[2,19]},{18:[2,28],25:[2,28],33:[2,28],42:[2,28],43:[2,28],44:[2,28],45:[2,28],46:[2,28],50:[2,28],52:[2,28]},{18:[2,30],25:[2,30],33:[2,30],46:[2,30],50:[2,30]},{5:[2,16],12:[2,16],13:[2,16],16:[2,16],24:[2,16],26:[2,16],28:[2,16],29:[2,16],31:[2,16],32:[2,16],34:[2,16]}],
985
+ defaultActions: {4:[2,1],44:[2,41],47:[2,43],57:[2,47],63:[2,10],70:[2,15],73:[2,45]},
870
986
  parseError: function parseError(str, hash) {
871
987
  throw new Error(str);
872
988
  },
@@ -974,15 +1090,6 @@ var __module9__ = (function() {
974
1090
  return true;
975
1091
  }
976
1092
  };
977
-
978
-
979
- function stripFlags(open, close) {
980
- return {
981
- left: open.charAt(2) === '~',
982
- right: close.charAt(0) === '~' || close.charAt(1) === '~'
983
- };
984
- }
985
-
986
1093
  /* Jison generated lexer */
987
1094
  var lexer = (function(){
988
1095
  var lexer = ({EOF:1,
@@ -1172,80 +1279,100 @@ var __module9__ = (function() {
1172
1279
  } else {
1173
1280
  this.begin("mu");
1174
1281
  }
1175
- if(yy_.yytext) return 14;
1282
+ if(yy_.yytext) return 12;
1176
1283
 
1177
1284
  break;
1178
- case 1:return 14;
1285
+ case 1:return 12;
1179
1286
  break;
1180
1287
  case 2:
1181
1288
  this.popState();
1182
- return 14;
1289
+ return 12;
1183
1290
 
1184
1291
  break;
1185
- case 3:strip(0,4); this.popState(); return 15;
1292
+ case 3:
1293
+ yy_.yytext = yy_.yytext.substr(5, yy_.yyleng-9);
1294
+ this.popState();
1295
+ return 15;
1296
+
1297
+ break;
1298
+ case 4: return 12;
1299
+ break;
1300
+ case 5:strip(0,4); this.popState(); return 13;
1301
+ break;
1302
+ case 6:return 45;
1303
+ break;
1304
+ case 7:return 46;
1305
+ break;
1306
+ case 8: return 16;
1307
+ break;
1308
+ case 9:
1309
+ this.popState();
1310
+ this.begin('raw');
1311
+ return 18;
1312
+
1186
1313
  break;
1187
- case 4:return 35;
1314
+ case 10:return 34;
1188
1315
  break;
1189
- case 5:return 36;
1316
+ case 11:return 24;
1190
1317
  break;
1191
- case 6:return 25;
1318
+ case 12:return 29;
1192
1319
  break;
1193
- case 7:return 16;
1320
+ case 13:this.popState(); return 28;
1194
1321
  break;
1195
- case 8:return 20;
1322
+ case 14:this.popState(); return 28;
1196
1323
  break;
1197
- case 9:return 19;
1324
+ case 15:return 26;
1198
1325
  break;
1199
- case 10:return 19;
1326
+ case 16:return 26;
1200
1327
  break;
1201
- case 11:return 23;
1328
+ case 17:return 32;
1202
1329
  break;
1203
- case 12:return 22;
1330
+ case 18:return 31;
1204
1331
  break;
1205
- case 13:this.popState(); this.begin('com');
1332
+ case 19:this.popState(); this.begin('com');
1206
1333
  break;
1207
- case 14:strip(3,5); this.popState(); return 15;
1334
+ case 20:strip(3,5); this.popState(); return 13;
1208
1335
  break;
1209
- case 15:return 22;
1336
+ case 21:return 31;
1210
1337
  break;
1211
- case 16:return 41;
1338
+ case 22:return 51;
1212
1339
  break;
1213
- case 17:return 40;
1340
+ case 23:return 50;
1214
1341
  break;
1215
- case 18:return 40;
1342
+ case 24:return 50;
1216
1343
  break;
1217
- case 19:return 44;
1344
+ case 25:return 54;
1218
1345
  break;
1219
- case 20:// ignore whitespace
1346
+ case 26:// ignore whitespace
1220
1347
  break;
1221
- case 21:this.popState(); return 24;
1348
+ case 27:this.popState(); return 33;
1222
1349
  break;
1223
- case 22:this.popState(); return 18;
1350
+ case 28:this.popState(); return 25;
1224
1351
  break;
1225
- case 23:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32;
1352
+ case 29:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 42;
1226
1353
  break;
1227
- case 24:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32;
1354
+ case 30:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 42;
1228
1355
  break;
1229
- case 25:return 42;
1356
+ case 31:return 52;
1230
1357
  break;
1231
- case 26:return 34;
1358
+ case 32:return 44;
1232
1359
  break;
1233
- case 27:return 34;
1360
+ case 33:return 44;
1234
1361
  break;
1235
- case 28:return 33;
1362
+ case 34:return 43;
1236
1363
  break;
1237
- case 29:return 40;
1364
+ case 35:return 50;
1238
1365
  break;
1239
- case 30:yy_.yytext = strip(1,2); return 40;
1366
+ case 36:yy_.yytext = strip(1,2); return 50;
1240
1367
  break;
1241
- case 31:return 'INVALID';
1368
+ case 37:return 'INVALID';
1242
1369
  break;
1243
- case 32:return 5;
1370
+ case 38:return 5;
1244
1371
  break;
1245
1372
  }
1246
1373
  };
1247
- lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
1248
- 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,30,31,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}};
1374
+ lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]*?(?=(\{\{\{\{\/)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
1375
+ lexer.conditions = {"mu":{"rules":[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,32,33,34,35,36,37,38],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[5],"inclusive":false},"raw":{"rules":[3,4],"inclusive":false},"INITIAL":{"rules":[0,1,38],"inclusive":true}};
1249
1376
  return lexer;})()
1250
1377
  parser.lexer = lexer;
1251
1378
  function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
@@ -1255,32 +1382,234 @@ var __module9__ = (function() {
1255
1382
  return __exports__;
1256
1383
  })();
1257
1384
 
1385
+ // handlebars/compiler/helpers.js
1386
+ var __module10__ = (function(__dependency1__) {
1387
+ "use strict";
1388
+ var __exports__ = {};
1389
+ var Exception = __dependency1__;
1390
+
1391
+ function stripFlags(open, close) {
1392
+ return {
1393
+ left: open.charAt(2) === '~',
1394
+ right: close.charAt(close.length-3) === '~'
1395
+ };
1396
+ }
1397
+
1398
+ __exports__.stripFlags = stripFlags;
1399
+ function prepareBlock(mustache, program, inverseAndProgram, close, inverted, locInfo) {
1400
+ /*jshint -W040 */
1401
+ if (mustache.sexpr.id.original !== close.path.original) {
1402
+ throw new Exception(mustache.sexpr.id.original + ' doesn\'t match ' + close.path.original, mustache);
1403
+ }
1404
+
1405
+ var inverse = inverseAndProgram && inverseAndProgram.program;
1406
+
1407
+ var strip = {
1408
+ left: mustache.strip.left,
1409
+ right: close.strip.right,
1410
+
1411
+ // Determine the standalone candiacy. Basically flag our content as being possibly standalone
1412
+ // so our parent can determine if we actually are standalone
1413
+ openStandalone: isNextWhitespace(program.statements),
1414
+ closeStandalone: isPrevWhitespace((inverse || program).statements)
1415
+ };
1416
+
1417
+ if (mustache.strip.right) {
1418
+ omitRight(program.statements, null, true);
1419
+ }
1420
+
1421
+ if (inverse) {
1422
+ var inverseStrip = inverseAndProgram.strip;
1423
+
1424
+ if (inverseStrip.left) {
1425
+ omitLeft(program.statements, null, true);
1426
+ }
1427
+ if (inverseStrip.right) {
1428
+ omitRight(inverse.statements, null, true);
1429
+ }
1430
+ if (close.strip.left) {
1431
+ omitLeft(inverse.statements, null, true);
1432
+ }
1433
+
1434
+ // Find standalone else statments
1435
+ if (isPrevWhitespace(program.statements)
1436
+ && isNextWhitespace(inverse.statements)) {
1437
+
1438
+ omitLeft(program.statements);
1439
+ omitRight(inverse.statements);
1440
+ }
1441
+ } else {
1442
+ if (close.strip.left) {
1443
+ omitLeft(program.statements, null, true);
1444
+ }
1445
+ }
1446
+
1447
+ if (inverted) {
1448
+ return new this.BlockNode(mustache, inverse, program, strip, locInfo);
1449
+ } else {
1450
+ return new this.BlockNode(mustache, program, inverse, strip, locInfo);
1451
+ }
1452
+ }
1453
+
1454
+ __exports__.prepareBlock = prepareBlock;
1455
+ function prepareProgram(statements, isRoot) {
1456
+ for (var i = 0, l = statements.length; i < l; i++) {
1457
+ var current = statements[i],
1458
+ strip = current.strip;
1459
+
1460
+ if (!strip) {
1461
+ continue;
1462
+ }
1463
+
1464
+ var _isPrevWhitespace = isPrevWhitespace(statements, i, isRoot, current.type === 'partial'),
1465
+ _isNextWhitespace = isNextWhitespace(statements, i, isRoot),
1466
+
1467
+ openStandalone = strip.openStandalone && _isPrevWhitespace,
1468
+ closeStandalone = strip.closeStandalone && _isNextWhitespace,
1469
+ inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;
1470
+
1471
+ if (strip.right) {
1472
+ omitRight(statements, i, true);
1473
+ }
1474
+ if (strip.left) {
1475
+ omitLeft(statements, i, true);
1476
+ }
1477
+
1478
+ if (inlineStandalone) {
1479
+ omitRight(statements, i);
1480
+
1481
+ if (omitLeft(statements, i)) {
1482
+ // If we are on a standalone node, save the indent info for partials
1483
+ if (current.type === 'partial') {
1484
+ current.indent = (/([ \t]+$)/).exec(statements[i-1].original) ? RegExp.$1 : '';
1485
+ }
1486
+ }
1487
+ }
1488
+ if (openStandalone) {
1489
+ omitRight((current.program || current.inverse).statements);
1490
+
1491
+ // Strip out the previous content node if it's whitespace only
1492
+ omitLeft(statements, i);
1493
+ }
1494
+ if (closeStandalone) {
1495
+ // Always strip the next node
1496
+ omitRight(statements, i);
1497
+
1498
+ omitLeft((current.inverse || current.program).statements);
1499
+ }
1500
+ }
1501
+
1502
+ return statements;
1503
+ }
1504
+
1505
+ __exports__.prepareProgram = prepareProgram;function isPrevWhitespace(statements, i, isRoot) {
1506
+ if (i === undefined) {
1507
+ i = statements.length;
1508
+ }
1509
+
1510
+ // Nodes that end with newlines are considered whitespace (but are special
1511
+ // cased for strip operations)
1512
+ var prev = statements[i-1],
1513
+ sibling = statements[i-2];
1514
+ if (!prev) {
1515
+ return isRoot;
1516
+ }
1517
+
1518
+ if (prev.type === 'content') {
1519
+ return (sibling || !isRoot ? (/\r?\n\s*?$/) : (/(^|\r?\n)\s*?$/)).test(prev.original);
1520
+ }
1521
+ }
1522
+ function isNextWhitespace(statements, i, isRoot) {
1523
+ if (i === undefined) {
1524
+ i = -1;
1525
+ }
1526
+
1527
+ var next = statements[i+1],
1528
+ sibling = statements[i+2];
1529
+ if (!next) {
1530
+ return isRoot;
1531
+ }
1532
+
1533
+ if (next.type === 'content') {
1534
+ return (sibling || !isRoot ? (/^\s*?\r?\n/) : (/^\s*?(\r?\n|$)/)).test(next.original);
1535
+ }
1536
+ }
1537
+
1538
+ // Marks the node to the right of the position as omitted.
1539
+ // I.e. {{foo}}' ' will mark the ' ' node as omitted.
1540
+ //
1541
+ // If i is undefined, then the first child will be marked as such.
1542
+ //
1543
+ // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
1544
+ // content is met.
1545
+ function omitRight(statements, i, multiple) {
1546
+ var current = statements[i == null ? 0 : i + 1];
1547
+ if (!current || current.type !== 'content' || (!multiple && current.rightStripped)) {
1548
+ return;
1549
+ }
1550
+
1551
+ var original = current.string;
1552
+ current.string = current.string.replace(multiple ? (/^\s+/) : (/^[ \t]*\r?\n?/), '');
1553
+ current.rightStripped = current.string !== original;
1554
+ }
1555
+
1556
+ // Marks the node to the left of the position as omitted.
1557
+ // I.e. ' '{{foo}} will mark the ' ' node as omitted.
1558
+ //
1559
+ // If i is undefined then the last child will be marked as such.
1560
+ //
1561
+ // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
1562
+ // content is met.
1563
+ function omitLeft(statements, i, multiple) {
1564
+ var current = statements[i == null ? statements.length - 1 : i - 1];
1565
+ if (!current || current.type !== 'content' || (!multiple && current.leftStripped)) {
1566
+ return;
1567
+ }
1568
+
1569
+ // We omit the last node if it's whitespace only and not preceeded by a non-content node.
1570
+ var original = current.string;
1571
+ current.string = current.string.replace(multiple ? (/\s+$/) : (/[ \t]+$/), '');
1572
+ current.leftStripped = current.string !== original;
1573
+ return current.leftStripped;
1574
+ }
1575
+ return __exports__;
1576
+ })(__module5__);
1577
+
1258
1578
  // handlebars/compiler/base.js
1259
- var __module8__ = (function(__dependency1__, __dependency2__) {
1579
+ var __module8__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__) {
1260
1580
  "use strict";
1261
1581
  var __exports__ = {};
1262
1582
  var parser = __dependency1__;
1263
1583
  var AST = __dependency2__;
1584
+ var Helpers = __dependency3__;
1585
+ var extend = __dependency4__.extend;
1264
1586
 
1265
1587
  __exports__.parser = parser;
1266
1588
 
1589
+ var yy = {};
1590
+ extend(yy, Helpers, AST);
1591
+
1267
1592
  function parse(input) {
1268
1593
  // Just return if an already-compile AST was passed in.
1269
- if(input.constructor === AST.ProgramNode) { return input; }
1594
+ if (input.constructor === AST.ProgramNode) { return input; }
1595
+
1596
+ parser.yy = yy;
1270
1597
 
1271
- parser.yy = AST;
1272
1598
  return parser.parse(input);
1273
1599
  }
1274
1600
 
1275
1601
  __exports__.parse = parse;
1276
1602
  return __exports__;
1277
- })(__module9__, __module7__);
1603
+ })(__module9__, __module7__, __module10__, __module3__);
1278
1604
 
1279
1605
  // handlebars/compiler/compiler.js
1280
- var __module10__ = (function(__dependency1__) {
1606
+ var __module11__ = (function(__dependency1__, __dependency2__) {
1281
1607
  "use strict";
1282
1608
  var __exports__ = {};
1283
1609
  var Exception = __dependency1__;
1610
+ var isArray = __dependency2__.isArray;
1611
+
1612
+ var slice = [].slice;
1284
1613
 
1285
1614
  function Compiler() {}
1286
1615
 
@@ -1292,30 +1621,6 @@ var __module10__ = (function(__dependency1__) {
1292
1621
  Compiler.prototype = {
1293
1622
  compiler: Compiler,
1294
1623
 
1295
- disassemble: function() {
1296
- var opcodes = this.opcodes, opcode, out = [], params, param;
1297
-
1298
- for (var i=0, l=opcodes.length; i<l; i++) {
1299
- opcode = opcodes[i];
1300
-
1301
- if (opcode.opcode === 'DECLARE') {
1302
- out.push("DECLARE " + opcode.name + "=" + opcode.value);
1303
- } else {
1304
- params = [];
1305
- for (var j=0; j<opcode.args.length; j++) {
1306
- param = opcode.args[j];
1307
- if (typeof param === "string") {
1308
- param = "\"" + param.replace("\n", "\\n") + "\"";
1309
- }
1310
- params.push(param);
1311
- }
1312
- out.push(opcode.opcode + " " + params.join(" "));
1313
- }
1314
- }
1315
-
1316
- return out.join("\n");
1317
- },
1318
-
1319
1624
  equals: function(other) {
1320
1625
  var len = this.opcodes.length;
1321
1626
  if (other.opcodes.length !== len) {
@@ -1325,20 +1630,14 @@ var __module10__ = (function(__dependency1__) {
1325
1630
  for (var i = 0; i < len; i++) {
1326
1631
  var opcode = this.opcodes[i],
1327
1632
  otherOpcode = other.opcodes[i];
1328
- if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
1633
+ if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) {
1329
1634
  return false;
1330
1635
  }
1331
- for (var j = 0; j < opcode.args.length; j++) {
1332
- if (opcode.args[j] !== otherOpcode.args[j]) {
1333
- return false;
1334
- }
1335
- }
1336
1636
  }
1337
1637
 
1638
+ // We know that length is the same between the two arrays because they are directly tied
1639
+ // to the opcode behavior above.
1338
1640
  len = this.children.length;
1339
- if (other.children.length !== len) {
1340
- return false;
1341
- }
1342
1641
  for (i = 0; i < len; i++) {
1343
1642
  if (!this.children[i].equals(other.children[i])) {
1344
1643
  return false;
@@ -1355,6 +1654,8 @@ var __module10__ = (function(__dependency1__) {
1355
1654
  this.children = [];
1356
1655
  this.depths = {list: []};
1357
1656
  this.options = options;
1657
+ this.stringParams = options.stringParams;
1658
+ this.trackIds = options.trackIds;
1358
1659
 
1359
1660
  // These changes will propagate to the other compiler components
1360
1661
  var knownHelpers = this.options.knownHelpers;
@@ -1365,7 +1666,8 @@ var __module10__ = (function(__dependency1__) {
1365
1666
  'if': true,
1366
1667
  'unless': true,
1367
1668
  'with': true,
1368
- 'log': true
1669
+ 'log': true,
1670
+ 'lookup': true
1369
1671
  };
1370
1672
  if (knownHelpers) {
1371
1673
  for (var name in knownHelpers) {
@@ -1377,19 +1679,7 @@ var __module10__ = (function(__dependency1__) {
1377
1679
  },
1378
1680
 
1379
1681
  accept: function(node) {
1380
- var strip = node.strip || {},
1381
- ret;
1382
- if (strip.left) {
1383
- this.opcode('strip');
1384
- }
1385
-
1386
- ret = this[node.type](node);
1387
-
1388
- if (strip.right) {
1389
- this.opcode('strip');
1390
- }
1391
-
1392
- return ret;
1682
+ return this[node.type](node);
1393
1683
  },
1394
1684
 
1395
1685
  program: function(program) {
@@ -1451,7 +1741,7 @@ var __module10__ = (function(__dependency1__) {
1451
1741
  this.opcode('pushProgram', program);
1452
1742
  this.opcode('pushProgram', inverse);
1453
1743
  this.opcode('emptyHash');
1454
- this.opcode('blockValue');
1744
+ this.opcode('blockValue', sexpr.id.original);
1455
1745
  } else {
1456
1746
  this.ambiguousSexpr(sexpr, program, inverse);
1457
1747
 
@@ -1467,31 +1757,15 @@ var __module10__ = (function(__dependency1__) {
1467
1757
  },
1468
1758
 
1469
1759
  hash: function(hash) {
1470
- var pairs = hash.pairs, pair, val;
1760
+ var pairs = hash.pairs, i, l;
1471
1761
 
1472
1762
  this.opcode('pushHash');
1473
1763
 
1474
- for(var i=0, l=pairs.length; i<l; i++) {
1475
- pair = pairs[i];
1476
- val = pair[1];
1477
-
1478
- if (this.options.stringParams) {
1479
- if(val.depth) {
1480
- this.addDepth(val.depth);
1481
- }
1482
- this.opcode('getContext', val.depth || 0);
1483
- this.opcode('pushStringParam', val.stringModeValue, val.type);
1484
-
1485
- if (val.type === 'sexpr') {
1486
- // Subexpressions get evaluated and passed in
1487
- // in string params mode.
1488
- this.sexpr(val);
1489
- }
1490
- } else {
1491
- this.accept(val);
1492
- }
1493
-
1494
- this.opcode('assignToHash', pair[0]);
1764
+ for(i=0, l=pairs.length; i<l; i++) {
1765
+ this.pushParam(pairs[i][1]);
1766
+ }
1767
+ while(i--) {
1768
+ this.opcode('assignToHash', pairs[i][0]);
1495
1769
  }
1496
1770
  this.opcode('popHash');
1497
1771
  },
@@ -1500,18 +1774,27 @@ var __module10__ = (function(__dependency1__) {
1500
1774
  var partialName = partial.partialName;
1501
1775
  this.usePartial = true;
1502
1776
 
1503
- if(partial.context) {
1504
- this.ID(partial.context);
1777
+ if (partial.hash) {
1778
+ this.accept(partial.hash);
1505
1779
  } else {
1506
- this.opcode('push', 'depth0');
1780
+ this.opcode('push', 'undefined');
1507
1781
  }
1508
1782
 
1509
- this.opcode('invokePartial', partialName.name);
1783
+ if (partial.context) {
1784
+ this.accept(partial.context);
1785
+ } else {
1786
+ this.opcode('getContext', 0);
1787
+ this.opcode('pushContext');
1788
+ }
1789
+
1790
+ this.opcode('invokePartial', partialName.name, partial.indent || '');
1510
1791
  this.opcode('append');
1511
1792
  },
1512
1793
 
1513
1794
  content: function(content) {
1514
- this.opcode('appendContent', content.string);
1795
+ if (content.string) {
1796
+ this.opcode('appendContent', content.string);
1797
+ }
1515
1798
  },
1516
1799
 
1517
1800
  mustache: function(mustache) {
@@ -1534,6 +1817,8 @@ var __module10__ = (function(__dependency1__) {
1534
1817
  this.opcode('pushProgram', program);
1535
1818
  this.opcode('pushProgram', inverse);
1536
1819
 
1820
+ this.ID(id);
1821
+
1537
1822
  this.opcode('invokeAmbiguous', name, isBlock);
1538
1823
  },
1539
1824
 
@@ -1556,14 +1841,18 @@ var __module10__ = (function(__dependency1__) {
1556
1841
 
1557
1842
  helperSexpr: function(sexpr, program, inverse) {
1558
1843
  var params = this.setupFullMustacheParams(sexpr, program, inverse),
1559
- name = sexpr.id.parts[0];
1844
+ id = sexpr.id,
1845
+ name = id.parts[0];
1560
1846
 
1561
1847
  if (this.options.knownHelpers[name]) {
1562
1848
  this.opcode('invokeKnownHelper', params.length, name);
1563
1849
  } else if (this.options.knownHelpersOnly) {
1564
1850
  throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
1565
1851
  } else {
1566
- this.opcode('invokeHelper', params.length, name, sexpr.isRoot);
1852
+ id.falsy = true;
1853
+
1854
+ this.ID(id);
1855
+ this.opcode('invokeHelper', params.length, id.original, id.isSimple);
1567
1856
  }
1568
1857
  },
1569
1858
 
@@ -1585,35 +1874,24 @@ var __module10__ = (function(__dependency1__) {
1585
1874
 
1586
1875
  var name = id.parts[0];
1587
1876
  if (!name) {
1877
+ // Context reference, i.e. `{{foo .}}` or `{{foo ..}}`
1588
1878
  this.opcode('pushContext');
1589
1879
  } else {
1590
- this.opcode('lookupOnContext', id.parts[0]);
1591
- }
1592
-
1593
- for(var i=1, l=id.parts.length; i<l; i++) {
1594
- this.opcode('lookup', id.parts[i]);
1880
+ this.opcode('lookupOnContext', id.parts, id.falsy, id.isScoped);
1595
1881
  }
1596
1882
  },
1597
1883
 
1598
1884
  DATA: function(data) {
1599
1885
  this.options.data = true;
1600
- if (data.id.isScoped || data.id.depth) {
1601
- throw new Exception('Scoped data references are not supported: ' + data.original, data);
1602
- }
1603
-
1604
- this.opcode('lookupData');
1605
- var parts = data.id.parts;
1606
- for(var i=0, l=parts.length; i<l; i++) {
1607
- this.opcode('lookup', parts[i]);
1608
- }
1886
+ this.opcode('lookupData', data.id.depth, data.id.parts);
1609
1887
  },
1610
1888
 
1611
1889
  STRING: function(string) {
1612
1890
  this.opcode('pushString', string.string);
1613
1891
  },
1614
1892
 
1615
- INTEGER: function(integer) {
1616
- this.opcode('pushLiteral', integer.integer);
1893
+ NUMBER: function(number) {
1894
+ this.opcode('pushLiteral', number.number);
1617
1895
  },
1618
1896
 
1619
1897
  BOOLEAN: function(bool) {
@@ -1624,11 +1902,7 @@ var __module10__ = (function(__dependency1__) {
1624
1902
 
1625
1903
  // HELPERS
1626
1904
  opcode: function(name) {
1627
- this.opcodes.push({ opcode: name, args: [].slice.call(arguments, 1) });
1628
- },
1629
-
1630
- declare: function(name, value) {
1631
- this.opcodes.push({ opcode: 'DECLARE', name: name, value: value });
1905
+ this.opcodes.push({ opcode: name, args: slice.call(arguments, 1) });
1632
1906
  },
1633
1907
 
1634
1908
  addDepth: function(depth) {
@@ -1646,6 +1920,7 @@ var __module10__ = (function(__dependency1__) {
1646
1920
  var options = this.options;
1647
1921
 
1648
1922
  // if ambiguous, we can possibly resolve the ambiguity now
1923
+ // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
1649
1924
  if (isEligible && !isHelper) {
1650
1925
  var name = sexpr.id.parts[0];
1651
1926
 
@@ -1662,27 +1937,29 @@ var __module10__ = (function(__dependency1__) {
1662
1937
  },
1663
1938
 
1664
1939
  pushParams: function(params) {
1665
- var i = params.length, param;
1666
-
1667
- while(i--) {
1668
- param = params[i];
1669
-
1670
- if(this.options.stringParams) {
1671
- if(param.depth) {
1672
- this.addDepth(param.depth);
1673
- }
1940
+ for(var i=0, l=params.length; i<l; i++) {
1941
+ this.pushParam(params[i]);
1942
+ }
1943
+ },
1674
1944
 
1675
- this.opcode('getContext', param.depth || 0);
1676
- this.opcode('pushStringParam', param.stringModeValue, param.type);
1945
+ pushParam: function(val) {
1946
+ if (this.stringParams) {
1947
+ if(val.depth) {
1948
+ this.addDepth(val.depth);
1949
+ }
1950
+ this.opcode('getContext', val.depth || 0);
1951
+ this.opcode('pushStringParam', val.stringModeValue, val.type);
1677
1952
 
1678
- if (param.type === 'sexpr') {
1679
- // Subexpressions get evaluated and passed in
1680
- // in string params mode.
1681
- this.sexpr(param);
1682
- }
1683
- } else {
1684
- this[param.type](param);
1953
+ if (val.type === 'sexpr') {
1954
+ // Subexpressions get evaluated and passed in
1955
+ // in string params mode.
1956
+ this.sexpr(val);
1957
+ }
1958
+ } else {
1959
+ if (this.trackIds) {
1960
+ this.opcode('pushId', val.type, val.idName || val.stringModeValue);
1685
1961
  }
1962
+ this.accept(val);
1686
1963
  }
1687
1964
  },
1688
1965
 
@@ -1712,6 +1989,9 @@ var __module10__ = (function(__dependency1__) {
1712
1989
  if (!('data' in options)) {
1713
1990
  options.data = true;
1714
1991
  }
1992
+ if (options.compat) {
1993
+ options.useDepths = true;
1994
+ }
1715
1995
 
1716
1996
  var ast = env.parse(input);
1717
1997
  var environment = new env.Compiler().compile(ast, options);
@@ -1728,6 +2008,9 @@ var __module10__ = (function(__dependency1__) {
1728
2008
  if (!('data' in options)) {
1729
2009
  options.data = true;
1730
2010
  }
2011
+ if (options.compat) {
2012
+ options.useDepths = true;
2013
+ }
1731
2014
 
1732
2015
  var compiled;
1733
2016
 
@@ -1739,25 +2022,50 @@ var __module10__ = (function(__dependency1__) {
1739
2022
  }
1740
2023
 
1741
2024
  // Template is only compiled on first use and cached after that point.
1742
- return function(context, options) {
2025
+ var ret = function(context, options) {
1743
2026
  if (!compiled) {
1744
2027
  compiled = compileInput();
1745
2028
  }
1746
2029
  return compiled.call(this, context, options);
1747
2030
  };
2031
+ ret._setup = function(options) {
2032
+ if (!compiled) {
2033
+ compiled = compileInput();
2034
+ }
2035
+ return compiled._setup(options);
2036
+ };
2037
+ ret._child = function(i, data, depths) {
2038
+ if (!compiled) {
2039
+ compiled = compileInput();
2040
+ }
2041
+ return compiled._child(i, data, depths);
2042
+ };
2043
+ return ret;
1748
2044
  }
1749
2045
 
1750
- __exports__.compile = compile;
2046
+ __exports__.compile = compile;function argEquals(a, b) {
2047
+ if (a === b) {
2048
+ return true;
2049
+ }
2050
+
2051
+ if (isArray(a) && isArray(b) && a.length === b.length) {
2052
+ for (var i = 0; i < a.length; i++) {
2053
+ if (!argEquals(a[i], b[i])) {
2054
+ return false;
2055
+ }
2056
+ }
2057
+ return true;
2058
+ }
2059
+ }
1751
2060
  return __exports__;
1752
- })(__module5__);
2061
+ })(__module5__, __module3__);
1753
2062
 
1754
2063
  // handlebars/compiler/javascript-compiler.js
1755
- var __module11__ = (function(__dependency1__, __dependency2__) {
2064
+ var __module12__ = (function(__dependency1__, __dependency2__) {
1756
2065
  "use strict";
1757
2066
  var __exports__;
1758
2067
  var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;
1759
2068
  var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
1760
- var log = __dependency1__.log;
1761
2069
  var Exception = __dependency2__;
1762
2070
 
1763
2071
  function Literal(value) {
@@ -1770,32 +2078,22 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
1770
2078
  // PUBLIC API: You can override these methods in a subclass to provide
1771
2079
  // alternative compiled forms for name lookup and buffering semantics
1772
2080
  nameLookup: function(parent, name /* , type*/) {
1773
- var wrap,
1774
- ret;
1775
- if (parent.indexOf('depth') === 0) {
1776
- wrap = true;
1777
- }
1778
-
1779
- if (/^[0-9]+$/.test(name)) {
1780
- ret = parent + "[" + name + "]";
1781
- } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
1782
- ret = parent + "." + name;
1783
- }
1784
- else {
1785
- ret = parent + "['" + name + "']";
1786
- }
1787
-
1788
- if (wrap) {
1789
- return '(' + parent + ' && ' + ret + ')';
2081
+ if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
2082
+ return parent + "." + name;
1790
2083
  } else {
1791
- return ret;
2084
+ return parent + "['" + name + "']";
1792
2085
  }
1793
2086
  },
2087
+ depthedLookup: function(name) {
2088
+ this.aliases.lookup = 'this.lookup';
2089
+
2090
+ return 'lookup(depths, "' + name + '")';
2091
+ },
1794
2092
 
1795
2093
  compilerInfo: function() {
1796
2094
  var revision = COMPILER_REVISION,
1797
2095
  versions = REVISION_CHANGES[revision];
1798
- return "this.compilerInfo = ["+revision+",'"+versions+"'];\n";
2096
+ return [revision, versions];
1799
2097
  },
1800
2098
 
1801
2099
  appendToBuffer: function(string) {
@@ -1819,22 +2117,23 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
1819
2117
 
1820
2118
  compile: function(environment, options, context, asObject) {
1821
2119
  this.environment = environment;
1822
- this.options = options || {};
1823
-
1824
- log('debug', this.environment.disassemble() + "\n\n");
2120
+ this.options = options;
2121
+ this.stringParams = this.options.stringParams;
2122
+ this.trackIds = this.options.trackIds;
2123
+ this.precompile = !asObject;
1825
2124
 
1826
2125
  this.name = this.environment.name;
1827
2126
  this.isChild = !!context;
1828
2127
  this.context = context || {
1829
2128
  programs: [],
1830
- environments: [],
1831
- aliases: { }
2129
+ environments: []
1832
2130
  };
1833
2131
 
1834
2132
  this.preamble();
1835
2133
 
1836
2134
  this.stackSlot = 0;
1837
2135
  this.stackVars = [];
2136
+ this.aliases = {};
1838
2137
  this.registers = { list: [] };
1839
2138
  this.hashes = [];
1840
2139
  this.compileStack = [];
@@ -1842,118 +2141,109 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
1842
2141
 
1843
2142
  this.compileChildren(environment, options);
1844
2143
 
1845
- var opcodes = environment.opcodes, opcode;
2144
+ this.useDepths = this.useDepths || environment.depths.list.length || this.options.compat;
1846
2145
 
1847
- this.i = 0;
2146
+ var opcodes = environment.opcodes,
2147
+ opcode,
2148
+ i,
2149
+ l;
1848
2150
 
1849
- for(var l=opcodes.length; this.i<l; this.i++) {
1850
- opcode = opcodes[this.i];
1851
-
1852
- if(opcode.opcode === 'DECLARE') {
1853
- this[opcode.name] = opcode.value;
1854
- } else {
1855
- this[opcode.opcode].apply(this, opcode.args);
1856
- }
2151
+ for (i = 0, l = opcodes.length; i < l; i++) {
2152
+ opcode = opcodes[i];
1857
2153
 
1858
- // Reset the stripNext flag if it was not set by this operation.
1859
- if (opcode.opcode !== this.stripNext) {
1860
- this.stripNext = false;
1861
- }
2154
+ this[opcode.opcode].apply(this, opcode.args);
1862
2155
  }
1863
2156
 
1864
2157
  // Flush any trailing content that might be pending.
1865
2158
  this.pushSource('');
1866
2159
 
2160
+ /* istanbul ignore next */
1867
2161
  if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
1868
2162
  throw new Exception('Compile completed with content left on stack');
1869
2163
  }
1870
2164
 
1871
- return this.createFunctionContext(asObject);
1872
- },
1873
-
1874
- preamble: function() {
1875
- var out = [];
1876
-
2165
+ var fn = this.createFunctionContext(asObject);
1877
2166
  if (!this.isChild) {
1878
- var namespace = this.namespace;
2167
+ var ret = {
2168
+ compiler: this.compilerInfo(),
2169
+ main: fn
2170
+ };
2171
+ var programs = this.context.programs;
2172
+ for (i = 0, l = programs.length; i < l; i++) {
2173
+ if (programs[i]) {
2174
+ ret[i] = programs[i];
2175
+ }
2176
+ }
1879
2177
 
1880
- var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
1881
- if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
1882
- if (this.options.data) { copies = copies + " data = data || {};"; }
1883
- out.push(copies);
1884
- } else {
1885
- out.push('');
1886
- }
2178
+ if (this.environment.usePartial) {
2179
+ ret.usePartial = true;
2180
+ }
2181
+ if (this.options.data) {
2182
+ ret.useData = true;
2183
+ }
2184
+ if (this.useDepths) {
2185
+ ret.useDepths = true;
2186
+ }
2187
+ if (this.options.compat) {
2188
+ ret.compat = true;
2189
+ }
2190
+
2191
+ if (!asObject) {
2192
+ ret.compiler = JSON.stringify(ret.compiler);
2193
+ ret = this.objectLiteral(ret);
2194
+ }
1887
2195
 
1888
- if (!this.environment.isSimple) {
1889
- out.push(", buffer = " + this.initializeBuffer());
2196
+ return ret;
1890
2197
  } else {
1891
- out.push("");
2198
+ return fn;
1892
2199
  }
2200
+ },
1893
2201
 
2202
+ preamble: function() {
1894
2203
  // track the last context pushed into place to allow skipping the
1895
2204
  // getContext opcode when it would be a noop
1896
2205
  this.lastContext = 0;
1897
- this.source = out;
2206
+ this.source = [];
1898
2207
  },
1899
2208
 
1900
2209
  createFunctionContext: function(asObject) {
1901
- var locals = this.stackVars.concat(this.registers.list);
2210
+ var varDeclarations = '';
1902
2211
 
2212
+ var locals = this.stackVars.concat(this.registers.list);
1903
2213
  if(locals.length > 0) {
1904
- this.source[1] = this.source[1] + ", " + locals.join(", ");
2214
+ varDeclarations += ", " + locals.join(", ");
1905
2215
  }
1906
2216
 
1907
2217
  // Generate minimizer alias mappings
1908
- if (!this.isChild) {
1909
- for (var alias in this.context.aliases) {
1910
- if (this.context.aliases.hasOwnProperty(alias)) {
1911
- this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
1912
- }
2218
+ for (var alias in this.aliases) {
2219
+ if (this.aliases.hasOwnProperty(alias)) {
2220
+ varDeclarations += ', ' + alias + '=' + this.aliases[alias];
1913
2221
  }
1914
2222
  }
1915
2223
 
1916
- if (this.source[1]) {
1917
- this.source[1] = "var " + this.source[1].substring(2) + ";";
1918
- }
1919
-
1920
- // Merge children
1921
- if (!this.isChild) {
1922
- this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
1923
- }
2224
+ var params = ["depth0", "helpers", "partials", "data"];
1924
2225
 
1925
- if (!this.environment.isSimple) {
1926
- this.pushSource("return buffer;");
1927
- }
1928
-
1929
- var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
1930
-
1931
- for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
1932
- params.push("depth" + this.environment.depths.list[i]);
2226
+ if (this.useDepths) {
2227
+ params.push('depths');
1933
2228
  }
1934
2229
 
1935
2230
  // Perform a second pass over the output to merge content when possible
1936
- var source = this.mergeSource();
1937
-
1938
- if (!this.isChild) {
1939
- source = this.compilerInfo()+source;
1940
- }
2231
+ var source = this.mergeSource(varDeclarations);
1941
2232
 
1942
2233
  if (asObject) {
1943
2234
  params.push(source);
1944
2235
 
1945
2236
  return Function.apply(this, params);
1946
2237
  } else {
1947
- var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + source + '}';
1948
- log('debug', functionSource + "\n\n");
1949
- return functionSource;
2238
+ return 'function(' + params.join(',') + ') {\n ' + source + '}';
1950
2239
  }
1951
2240
  },
1952
- mergeSource: function() {
1953
- // WARN: We are not handling the case where buffer is still populated as the source should
1954
- // not have buffer append operations as their final action.
2241
+ mergeSource: function(varDeclarations) {
1955
2242
  var source = '',
1956
- buffer;
2243
+ buffer,
2244
+ appendOnly = !this.forceBuffer,
2245
+ appendFirst;
2246
+
1957
2247
  for (var i = 0, len = this.source.length; i < len; i++) {
1958
2248
  var line = this.source[i];
1959
2249
  if (line.appendToBuffer) {
@@ -1964,12 +2254,39 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
1964
2254
  }
1965
2255
  } else {
1966
2256
  if (buffer) {
1967
- source += 'buffer += ' + buffer + ';\n ';
2257
+ if (!source) {
2258
+ appendFirst = true;
2259
+ source = buffer + ';\n ';
2260
+ } else {
2261
+ source += 'buffer += ' + buffer + ';\n ';
2262
+ }
1968
2263
  buffer = undefined;
1969
2264
  }
1970
2265
  source += line + '\n ';
2266
+
2267
+ if (!this.environment.isSimple) {
2268
+ appendOnly = false;
2269
+ }
2270
+ }
2271
+ }
2272
+
2273
+ if (appendOnly) {
2274
+ if (buffer || !source) {
2275
+ source += 'return ' + (buffer || '""') + ';\n';
2276
+ }
2277
+ } else {
2278
+ varDeclarations += ", buffer = " + (appendFirst ? '' : this.initializeBuffer());
2279
+ if (buffer) {
2280
+ source += 'return buffer + ' + buffer + ';\n';
2281
+ } else {
2282
+ source += 'return buffer;\n';
1971
2283
  }
1972
2284
  }
2285
+
2286
+ if (varDeclarations) {
2287
+ source = 'var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n ') + source;
2288
+ }
2289
+
1973
2290
  return source;
1974
2291
  },
1975
2292
 
@@ -1979,19 +2296,19 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
1979
2296
  // On stack, after: return value of blockHelperMissing
1980
2297
  //
1981
2298
  // The purpose of this opcode is to take a block of the form
1982
- // `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
2299
+ // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and
1983
2300
  // replace it on the stack with the result of properly
1984
2301
  // invoking blockHelperMissing.
1985
- blockValue: function() {
1986
- this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
2302
+ blockValue: function(name) {
2303
+ this.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
1987
2304
 
1988
- var params = ["depth0"];
1989
- this.setupParams(0, params);
2305
+ var params = [this.contextName(0)];
2306
+ this.setupParams(name, 0, params);
1990
2307
 
1991
- this.replaceStack(function(current) {
1992
- params.splice(1, 0, current);
1993
- return "blockHelperMissing.call(" + params.join(", ") + ")";
1994
- });
2308
+ var blockName = this.popStack();
2309
+ params.splice(1, 0, blockName);
2310
+
2311
+ this.push('blockHelperMissing.call(' + params.join(', ') + ')');
1995
2312
  },
1996
2313
 
1997
2314
  // [ambiguousBlockValue]
@@ -2001,10 +2318,13 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2001
2318
  // On stack, after, if no lastHelper: same as [blockValue]
2002
2319
  // On stack, after, if lastHelper: value
2003
2320
  ambiguousBlockValue: function() {
2004
- this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
2321
+ this.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
2005
2322
 
2006
- var params = ["depth0"];
2007
- this.setupParams(0, params);
2323
+ // We're being a bit cheeky and reusing the options value from the prior exec
2324
+ var params = [this.contextName(0)];
2325
+ this.setupParams('', 0, params, true);
2326
+
2327
+ this.flushInline();
2008
2328
 
2009
2329
  var current = this.topStack();
2010
2330
  params.splice(1, 0, current);
@@ -2022,27 +2342,10 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2022
2342
  if (this.pendingContent) {
2023
2343
  content = this.pendingContent + content;
2024
2344
  }
2025
- if (this.stripNext) {
2026
- content = content.replace(/^\s+/, '');
2027
- }
2028
2345
 
2029
2346
  this.pendingContent = content;
2030
2347
  },
2031
2348
 
2032
- // [strip]
2033
- //
2034
- // On stack, before: ...
2035
- // On stack, after: ...
2036
- //
2037
- // Removes any trailing whitespace from the prior content node and flags
2038
- // the next operation for stripping if it is a content node.
2039
- strip: function() {
2040
- if (this.pendingContent) {
2041
- this.pendingContent = this.pendingContent.replace(/\s+$/, '');
2042
- }
2043
- this.stripNext = 'strip';
2044
- },
2045
-
2046
2349
  // [append]
2047
2350
  //
2048
2351
  // On stack, before: value, ...
@@ -2057,7 +2360,7 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2057
2360
  // when we examine local
2058
2361
  this.flushInline();
2059
2362
  var local = this.popStack();
2060
- this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
2363
+ this.pushSource('if (' + local + ' != null) { ' + this.appendToBuffer(local) + ' }');
2061
2364
  if (this.environment.isSimple) {
2062
2365
  this.pushSource("else { " + this.appendToBuffer("''") + " }");
2063
2366
  }
@@ -2070,7 +2373,7 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2070
2373
  //
2071
2374
  // Escape `value` and append it to the buffer
2072
2375
  appendEscaped: function() {
2073
- this.context.aliases.escapeExpression = 'this.escapeExpression';
2376
+ this.aliases.escapeExpression = 'this.escapeExpression';
2074
2377
 
2075
2378
  this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
2076
2379
  },
@@ -2083,9 +2386,17 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2083
2386
  //
2084
2387
  // Set the value of the `lastContext` compiler value to the depth
2085
2388
  getContext: function(depth) {
2086
- if(this.lastContext !== depth) {
2087
- this.lastContext = depth;
2088
- }
2389
+ this.lastContext = depth;
2390
+ },
2391
+
2392
+ // [pushContext]
2393
+ //
2394
+ // On stack, before: ...
2395
+ // On stack, after: currentContext, ...
2396
+ //
2397
+ // Pushes the value of the current context onto the stack.
2398
+ pushContext: function() {
2399
+ this.pushStackLiteral(this.contextName(this.lastContext));
2089
2400
  },
2090
2401
 
2091
2402
  // [lookupOnContext]
@@ -2095,18 +2406,54 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2095
2406
  //
2096
2407
  // Looks up the value of `name` on the current context and pushes
2097
2408
  // it onto the stack.
2098
- lookupOnContext: function(name) {
2099
- this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
2409
+ lookupOnContext: function(parts, falsy, scoped) {
2410
+ /*jshint -W083 */
2411
+ var i = 0,
2412
+ len = parts.length;
2413
+
2414
+ if (!scoped && this.options.compat && !this.lastContext) {
2415
+ // The depthed query is expected to handle the undefined logic for the root level that
2416
+ // is implemented below, so we evaluate that directly in compat mode
2417
+ this.push(this.depthedLookup(parts[i++]));
2418
+ } else {
2419
+ this.pushContext();
2420
+ }
2421
+
2422
+ for (; i < len; i++) {
2423
+ this.replaceStack(function(current) {
2424
+ var lookup = this.nameLookup(current, parts[i], 'context');
2425
+ // We want to ensure that zero and false are handled properly if the context (falsy flag)
2426
+ // needs to have the special handling for these values.
2427
+ if (!falsy) {
2428
+ return ' != null ? ' + lookup + ' : ' + current;
2429
+ } else {
2430
+ // Otherwise we can use generic falsy handling
2431
+ return ' && ' + lookup;
2432
+ }
2433
+ });
2434
+ }
2100
2435
  },
2101
2436
 
2102
- // [pushContext]
2437
+ // [lookupData]
2103
2438
  //
2104
2439
  // On stack, before: ...
2105
- // On stack, after: currentContext, ...
2440
+ // On stack, after: data, ...
2106
2441
  //
2107
- // Pushes the value of the current context onto the stack.
2108
- pushContext: function() {
2109
- this.pushStackLiteral('depth' + this.lastContext);
2442
+ // Push the data lookup operator
2443
+ lookupData: function(depth, parts) {
2444
+ /*jshint -W083 */
2445
+ if (!depth) {
2446
+ this.pushStackLiteral('data');
2447
+ } else {
2448
+ this.pushStackLiteral('this.data(data, ' + depth + ')');
2449
+ }
2450
+
2451
+ var len = parts.length;
2452
+ for (var i = 0; i < len; i++) {
2453
+ this.replaceStack(function(current) {
2454
+ return ' && ' + this.nameLookup(current, parts[i], 'data');
2455
+ });
2456
+ }
2110
2457
  },
2111
2458
 
2112
2459
  // [resolvePossibleLambda]
@@ -2117,34 +2464,9 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2117
2464
  // If the `value` is a lambda, replace it on the stack by
2118
2465
  // the return value of the lambda
2119
2466
  resolvePossibleLambda: function() {
2120
- this.context.aliases.functionType = '"function"';
2467
+ this.aliases.lambda = 'this.lambda';
2121
2468
 
2122
- this.replaceStack(function(current) {
2123
- return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
2124
- });
2125
- },
2126
-
2127
- // [lookup]
2128
- //
2129
- // On stack, before: value, ...
2130
- // On stack, after: value[name], ...
2131
- //
2132
- // Replace the value on the stack with the result of looking
2133
- // up `name` on `value`
2134
- lookup: function(name) {
2135
- this.replaceStack(function(current) {
2136
- return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
2137
- });
2138
- },
2139
-
2140
- // [lookupData]
2141
- //
2142
- // On stack, before: ...
2143
- // On stack, after: data, ...
2144
- //
2145
- // Push the data lookup operator
2146
- lookupData: function() {
2147
- this.pushStackLiteral('data');
2469
+ this.push('lambda(' + this.popStack() + ', ' + this.contextName(0) + ')');
2148
2470
  },
2149
2471
 
2150
2472
  // [pushStringParam]
@@ -2156,8 +2478,7 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2156
2478
  // provides the string value of a parameter along with its
2157
2479
  // depth rather than resolving it immediately.
2158
2480
  pushStringParam: function(string, type) {
2159
- this.pushStackLiteral('depth' + this.lastContext);
2160
-
2481
+ this.pushContext();
2161
2482
  this.pushString(type);
2162
2483
 
2163
2484
  // If it's a subexpression, the string result
@@ -2174,7 +2495,10 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2174
2495
  emptyHash: function() {
2175
2496
  this.pushStackLiteral('{}');
2176
2497
 
2177
- if (this.options.stringParams) {
2498
+ if (this.trackIds) {
2499
+ this.push('{}'); // hashIds
2500
+ }
2501
+ if (this.stringParams) {
2178
2502
  this.push('{}'); // hashContexts
2179
2503
  this.push('{}'); // hashTypes
2180
2504
  }
@@ -2183,13 +2507,16 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2183
2507
  if (this.hash) {
2184
2508
  this.hashes.push(this.hash);
2185
2509
  }
2186
- this.hash = {values: [], types: [], contexts: []};
2510
+ this.hash = {values: [], types: [], contexts: [], ids: []};
2187
2511
  },
2188
2512
  popHash: function() {
2189
2513
  var hash = this.hash;
2190
2514
  this.hash = this.hashes.pop();
2191
2515
 
2192
- if (this.options.stringParams) {
2516
+ if (this.trackIds) {
2517
+ this.push('{' + hash.ids.join(',') + '}');
2518
+ }
2519
+ if (this.stringParams) {
2193
2520
  this.push('{' + hash.contexts.join(',') + '}');
2194
2521
  this.push('{' + hash.types.join(',') + '}');
2195
2522
  }
@@ -2255,31 +2582,14 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2255
2582
  // and pushes the helper's return value onto the stack.
2256
2583
  //
2257
2584
  // If the helper is not found, `helperMissing` is called.
2258
- invokeHelper: function(paramSize, name, isRoot) {
2259
- this.context.aliases.helperMissing = 'helpers.helperMissing';
2260
- this.useRegister('helper');
2585
+ invokeHelper: function(paramSize, name, isSimple) {
2586
+ this.aliases.helperMissing = 'helpers.helperMissing';
2261
2587
 
2262
- var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
2263
- var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
2264
-
2265
- var lookup = 'helper = ' + helper.name + ' || ' + nonHelper;
2266
- if (helper.paramsInit) {
2267
- lookup += ',' + helper.paramsInit;
2268
- }
2269
-
2270
- this.push(
2271
- '('
2272
- + lookup
2273
- + ',helper '
2274
- + '? helper.call(' + helper.callParams + ') '
2275
- + ': helperMissing.call(' + helper.helperMissingParams + '))');
2588
+ var nonHelper = this.popStack();
2589
+ var helper = this.setupHelper(paramSize, name);
2276
2590
 
2277
- // Always flush subexpressions. This is both to prevent the compounding size issue that
2278
- // occurs when the code has to be duplicated for inlining and also to prevent errors
2279
- // due to the incorrect options object being passed due to the shared register.
2280
- if (!isRoot) {
2281
- this.flushInline();
2282
- }
2591
+ var lookup = (isSimple ? helper.name + ' || ' : '') + nonHelper + ' || helperMissing';
2592
+ this.push('((' + lookup + ').call(' + helper.callParams + '))');
2283
2593
  },
2284
2594
 
2285
2595
  // [invokeKnownHelper]
@@ -2307,22 +2617,21 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2307
2617
  // and can be avoided by passing the `knownHelpers` and
2308
2618
  // `knownHelpersOnly` flags at compile-time.
2309
2619
  invokeAmbiguous: function(name, helperCall) {
2310
- this.context.aliases.functionType = '"function"';
2620
+ this.aliases.functionType = '"function"';
2621
+ this.aliases.helperMissing = 'helpers.helperMissing';
2311
2622
  this.useRegister('helper');
2312
2623
 
2624
+ var nonHelper = this.popStack();
2625
+
2313
2626
  this.emptyHash();
2314
2627
  var helper = this.setupHelper(0, name, helperCall);
2315
2628
 
2316
2629
  var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
2317
2630
 
2318
- var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
2319
- var nextStack = this.nextStack();
2320
-
2321
- if (helper.paramsInit) {
2322
- this.pushSource(helper.paramsInit);
2323
- }
2324
- this.pushSource('if (helper = ' + helperName + ') { ' + nextStack + ' = helper.call(' + helper.callParams + '); }');
2325
- this.pushSource('else { helper = ' + nonHelper + '; ' + nextStack + ' = typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper; }');
2631
+ this.push(
2632
+ '((helper = (helper = ' + helperName + ' || ' + nonHelper + ') != null ? helper : helperMissing'
2633
+ + (helper.paramsInit ? '),(' + helper.paramsInit : '') + '),'
2634
+ + '(typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper))');
2326
2635
  },
2327
2636
 
2328
2637
  // [invokePartial]
@@ -2332,30 +2641,37 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2332
2641
  //
2333
2642
  // This operation pops off a context, invokes a partial with that context,
2334
2643
  // and pushes the result of the invocation back.
2335
- invokePartial: function(name) {
2336
- var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
2644
+ invokePartial: function(name, indent) {
2645
+ var params = [this.nameLookup('partials', name, 'partial'), "'" + indent + "'", "'" + name + "'", this.popStack(), this.popStack(), "helpers", "partials"];
2337
2646
 
2338
2647
  if (this.options.data) {
2339
2648
  params.push("data");
2649
+ } else if (this.options.compat) {
2650
+ params.push('undefined');
2651
+ }
2652
+ if (this.options.compat) {
2653
+ params.push('depths');
2340
2654
  }
2341
2655
 
2342
- this.context.aliases.self = "this";
2343
- this.push("self.invokePartial(" + params.join(", ") + ")");
2656
+ this.push("this.invokePartial(" + params.join(", ") + ")");
2344
2657
  },
2345
2658
 
2346
2659
  // [assignToHash]
2347
2660
  //
2348
- // On stack, before: value, hash, ...
2349
- // On stack, after: hash, ...
2661
+ // On stack, before: value, ..., hash, ...
2662
+ // On stack, after: ..., hash, ...
2350
2663
  //
2351
- // Pops a value and hash off the stack, assigns `hash[key] = value`
2352
- // and pushes the hash back onto the stack.
2664
+ // Pops a value off the stack and assigns it to the current hash
2353
2665
  assignToHash: function(key) {
2354
2666
  var value = this.popStack(),
2355
2667
  context,
2356
- type;
2668
+ type,
2669
+ id;
2357
2670
 
2358
- if (this.options.stringParams) {
2671
+ if (this.trackIds) {
2672
+ id = this.popStack();
2673
+ }
2674
+ if (this.stringParams) {
2359
2675
  type = this.popStack();
2360
2676
  context = this.popStack();
2361
2677
  }
@@ -2367,9 +2683,22 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2367
2683
  if (type) {
2368
2684
  hash.types.push("'" + key + "': " + type);
2369
2685
  }
2686
+ if (id) {
2687
+ hash.ids.push("'" + key + "': " + id);
2688
+ }
2370
2689
  hash.values.push("'" + key + "': (" + value + ")");
2371
2690
  },
2372
2691
 
2692
+ pushId: function(type, name) {
2693
+ if (type === 'ID' || type === 'DATA') {
2694
+ this.pushString(name);
2695
+ } else if (type === 'sexpr') {
2696
+ this.pushStackLiteral('true');
2697
+ } else {
2698
+ this.pushStackLiteral('null');
2699
+ }
2700
+ },
2701
+
2373
2702
  // HELPERS
2374
2703
 
2375
2704
  compiler: JavaScriptCompiler,
@@ -2388,8 +2717,10 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2388
2717
  index = this.context.programs.length;
2389
2718
  child.index = index;
2390
2719
  child.name = 'program' + index;
2391
- this.context.programs[index] = compiler.compile(child, options, this.context);
2720
+ this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile);
2392
2721
  this.context.environments[index] = child;
2722
+
2723
+ this.useDepths = this.useDepths || compiler.useDepths;
2393
2724
  } else {
2394
2725
  child.index = index;
2395
2726
  child.name = 'program' + index;
@@ -2406,30 +2737,18 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2406
2737
  },
2407
2738
 
2408
2739
  programExpression: function(guid) {
2409
- this.context.aliases.self = "this";
2410
-
2411
- if(guid == null) {
2412
- return "self.noop";
2413
- }
2414
-
2415
2740
  var child = this.environment.children[guid],
2416
- depths = child.depths.list, depth;
2417
-
2418
- var programParams = [child.index, child.name, "data"];
2741
+ depths = child.depths.list,
2742
+ useDepths = this.useDepths,
2743
+ depth;
2419
2744
 
2420
- for(var i=0, l = depths.length; i<l; i++) {
2421
- depth = depths[i];
2745
+ var programParams = [child.index, 'data'];
2422
2746
 
2423
- if(depth === 1) { programParams.push("depth0"); }
2424
- else { programParams.push("depth" + (depth - 1)); }
2747
+ if (useDepths) {
2748
+ programParams.push('depths');
2425
2749
  }
2426
2750
 
2427
- return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
2428
- },
2429
-
2430
- register: function(name, val) {
2431
- this.useRegister(name);
2432
- this.pushSource(name + " = " + val + ";");
2751
+ return 'this.program(' + programParams.join(', ') + ')';
2433
2752
  },
2434
2753
 
2435
2754
  useRegister: function(name) {
@@ -2458,9 +2777,7 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2458
2777
  this.flushInline();
2459
2778
 
2460
2779
  var stack = this.incrStack();
2461
- if (item) {
2462
- this.pushSource(stack + " = " + item + ";");
2463
- }
2780
+ this.pushSource(stack + " = " + item + ";");
2464
2781
  this.compileStack.push(stack);
2465
2782
  return stack;
2466
2783
  },
@@ -2472,50 +2789,36 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2472
2789
  createdStack,
2473
2790
  usedLiteral;
2474
2791
 
2475
- // If we are currently inline then we want to merge the inline statement into the
2476
- // replacement statement via ','
2477
- if (inline) {
2478
- var top = this.popStack(true);
2792
+ /* istanbul ignore next */
2793
+ if (!this.isInline()) {
2794
+ throw new Exception('replaceStack on non-inline');
2795
+ }
2479
2796
 
2480
- if (top instanceof Literal) {
2481
- // Literals do not need to be inlined
2482
- stack = top.value;
2483
- usedLiteral = true;
2484
- } else {
2485
- // Get or create the current stack name for use by the inline
2486
- createdStack = !this.stackSlot;
2487
- var name = !createdStack ? this.topStackName() : this.incrStack();
2797
+ // We want to merge the inline statement into the replacement statement via ','
2798
+ var top = this.popStack(true);
2488
2799
 
2489
- prefix = '(' + this.push(name) + ' = ' + top + '),';
2490
- stack = this.topStack();
2491
- }
2800
+ if (top instanceof Literal) {
2801
+ // Literals do not need to be inlined
2802
+ prefix = stack = top.value;
2803
+ usedLiteral = true;
2492
2804
  } else {
2805
+ // Get or create the current stack name for use by the inline
2806
+ createdStack = !this.stackSlot;
2807
+ var name = !createdStack ? this.topStackName() : this.incrStack();
2808
+
2809
+ prefix = '(' + this.push(name) + ' = ' + top + ')';
2493
2810
  stack = this.topStack();
2494
2811
  }
2495
2812
 
2496
2813
  var item = callback.call(this, stack);
2497
2814
 
2498
- if (inline) {
2499
- if (!usedLiteral) {
2500
- this.popStack();
2501
- }
2502
- if (createdStack) {
2503
- this.stackSlot--;
2504
- }
2505
- this.push('(' + prefix + item + ')');
2506
- } else {
2507
- // Prevent modification of the context depth variable. Through replaceStack
2508
- if (!/^stack/.test(stack)) {
2509
- stack = this.nextStack();
2510
- }
2511
-
2512
- this.pushSource(stack + " = (" + prefix + item + ");");
2815
+ if (!usedLiteral) {
2816
+ this.popStack();
2513
2817
  }
2514
- return stack;
2515
- },
2516
-
2517
- nextStack: function() {
2518
- return this.pushStack();
2818
+ if (createdStack) {
2819
+ this.stackSlot--;
2820
+ }
2821
+ this.push('(' + prefix + item + ')');
2519
2822
  },
2520
2823
 
2521
2824
  incrStack: function() {
@@ -2552,6 +2855,7 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2552
2855
  return item.value;
2553
2856
  } else {
2554
2857
  if (!inline) {
2858
+ /* istanbul ignore next */
2555
2859
  if (!this.stackSlot) {
2556
2860
  throw new Exception('Invalid stack pop');
2557
2861
  }
@@ -2561,17 +2865,25 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2561
2865
  }
2562
2866
  },
2563
2867
 
2564
- topStack: function(wrapped) {
2868
+ topStack: function() {
2565
2869
  var stack = (this.isInline() ? this.inlineStack : this.compileStack),
2566
2870
  item = stack[stack.length - 1];
2567
2871
 
2568
- if (!wrapped && (item instanceof Literal)) {
2872
+ if (item instanceof Literal) {
2569
2873
  return item.value;
2570
2874
  } else {
2571
2875
  return item;
2572
2876
  }
2573
2877
  },
2574
2878
 
2879
+ contextName: function(context) {
2880
+ if (this.useDepths && context) {
2881
+ return 'depths[' + context + ']';
2882
+ } else {
2883
+ return 'depth' + context;
2884
+ }
2885
+ },
2886
+
2575
2887
  quotedString: function(str) {
2576
2888
  return '"' + str
2577
2889
  .replace(/\\/g, '\\\\')
@@ -2582,28 +2894,43 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2582
2894
  .replace(/\u2029/g, '\\u2029') + '"';
2583
2895
  },
2584
2896
 
2585
- setupHelper: function(paramSize, name, missingParams) {
2897
+ objectLiteral: function(obj) {
2898
+ var pairs = [];
2899
+
2900
+ for (var key in obj) {
2901
+ if (obj.hasOwnProperty(key)) {
2902
+ pairs.push(this.quotedString(key) + ':' + obj[key]);
2903
+ }
2904
+ }
2905
+
2906
+ return '{' + pairs.join(',') + '}';
2907
+ },
2908
+
2909
+ setupHelper: function(paramSize, name, blockHelper) {
2586
2910
  var params = [],
2587
- paramsInit = this.setupParams(paramSize, params, missingParams);
2911
+ paramsInit = this.setupParams(name, paramSize, params, blockHelper);
2588
2912
  var foundHelper = this.nameLookup('helpers', name, 'helper');
2589
2913
 
2590
2914
  return {
2591
2915
  params: params,
2592
2916
  paramsInit: paramsInit,
2593
2917
  name: foundHelper,
2594
- callParams: ["depth0"].concat(params).join(", "),
2595
- helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
2918
+ callParams: [this.contextName(0)].concat(params).join(", ")
2596
2919
  };
2597
2920
  },
2598
2921
 
2599
- setupOptions: function(paramSize, params) {
2600
- var options = [], contexts = [], types = [], param, inverse, program;
2922
+ setupOptions: function(helper, paramSize, params) {
2923
+ var options = {}, contexts = [], types = [], ids = [], param, inverse, program;
2601
2924
 
2602
- options.push("hash:" + this.popStack());
2925
+ options.name = this.quotedString(helper);
2926
+ options.hash = this.popStack();
2603
2927
 
2604
- if (this.options.stringParams) {
2605
- options.push("hashTypes:" + this.popStack());
2606
- options.push("hashContexts:" + this.popStack());
2928
+ if (this.trackIds) {
2929
+ options.hashIds = this.popStack();
2930
+ }
2931
+ if (this.stringParams) {
2932
+ options.hashTypes = this.popStack();
2933
+ options.hashContexts = this.popStack();
2607
2934
  }
2608
2935
 
2609
2936
  inverse = this.popStack();
@@ -2613,36 +2940,43 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2613
2940
  // helpers to do a check for `if (options.fn)`
2614
2941
  if (program || inverse) {
2615
2942
  if (!program) {
2616
- this.context.aliases.self = "this";
2617
- program = "self.noop";
2943
+ program = 'this.noop';
2618
2944
  }
2619
2945
 
2620
2946
  if (!inverse) {
2621
- this.context.aliases.self = "this";
2622
- inverse = "self.noop";
2947
+ inverse = 'this.noop';
2623
2948
  }
2624
2949
 
2625
- options.push("inverse:" + inverse);
2626
- options.push("fn:" + program);
2950
+ options.fn = program;
2951
+ options.inverse = inverse;
2627
2952
  }
2628
2953
 
2629
- for(var i=0; i<paramSize; i++) {
2954
+ // The parameters go on to the stack in order (making sure that they are evaluated in order)
2955
+ // so we need to pop them off the stack in reverse order
2956
+ var i = paramSize;
2957
+ while (i--) {
2630
2958
  param = this.popStack();
2631
- params.push(param);
2959
+ params[i] = param;
2632
2960
 
2633
- if(this.options.stringParams) {
2634
- types.push(this.popStack());
2635
- contexts.push(this.popStack());
2961
+ if (this.trackIds) {
2962
+ ids[i] = this.popStack();
2963
+ }
2964
+ if (this.stringParams) {
2965
+ types[i] = this.popStack();
2966
+ contexts[i] = this.popStack();
2636
2967
  }
2637
2968
  }
2638
2969
 
2639
- if (this.options.stringParams) {
2640
- options.push("contexts:[" + contexts.join(",") + "]");
2641
- options.push("types:[" + types.join(",") + "]");
2970
+ if (this.trackIds) {
2971
+ options.ids = "[" + ids.join(",") + "]";
2972
+ }
2973
+ if (this.stringParams) {
2974
+ options.types = "[" + types.join(",") + "]";
2975
+ options.contexts = "[" + contexts.join(",") + "]";
2642
2976
  }
2643
2977
 
2644
- if(this.options.data) {
2645
- options.push("data:data");
2978
+ if (this.options.data) {
2979
+ options.data = "data";
2646
2980
  }
2647
2981
 
2648
2982
  return options;
@@ -2650,8 +2984,8 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2650
2984
 
2651
2985
  // the params and contexts arguments are passed in arrays
2652
2986
  // to fill in
2653
- setupParams: function(paramSize, params, useRegister) {
2654
- var options = '{' + this.setupOptions(paramSize, params).join(',') + '}';
2987
+ setupParams: function(helperName, paramSize, params, useRegister) {
2988
+ var options = this.objectLiteral(this.setupOptions(helperName, paramSize, params));
2655
2989
 
2656
2990
  if (useRegister) {
2657
2991
  this.useRegister('options');
@@ -2689,10 +3023,7 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2689
3023
  }
2690
3024
 
2691
3025
  JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
2692
- if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) {
2693
- return true;
2694
- }
2695
- return false;
3026
+ return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name);
2696
3027
  };
2697
3028
 
2698
3029
  __exports__ = JavaScriptCompiler;
@@ -2738,9 +3069,11 @@ var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, _
2738
3069
  Handlebars = create();
2739
3070
  Handlebars.create = create;
2740
3071
 
3072
+ Handlebars['default'] = Handlebars;
3073
+
2741
3074
  __exports__ = Handlebars;
2742
3075
  return __exports__;
2743
- })(__module1__, __module7__, __module8__, __module10__, __module11__);
3076
+ })(__module1__, __module7__, __module8__, __module11__, __module12__);
2744
3077
 
2745
3078
  return __module0__;
2746
- })();
3079
+ }));