handlebars_assets 0.18 → 0.19

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: edea242129a27984759bac4928647ff0df60bec8
4
- data.tar.gz: 2ca19e7c44db381df9e82e1456176e59f5053726
3
+ metadata.gz: 86ae472df1dc68b349cd283c6f5890542bd015ef
4
+ data.tar.gz: 06a45ba988b9a64479132f25bb622b2d9cfbf1d4
5
5
  SHA512:
6
- metadata.gz: 2e6bb55ef61eb4fd6667680ccfa5f0bd2f7b2de5616dabe3740cd6858126b494d32829366b630a3cb989820ef1bd9afebccce5b648833d74d868f7f478bb2f9f
7
- data.tar.gz: 92603a8e0458caab9f5069aa049521bd36d64a9f4edf87b640b290774e119ad8dad1b462a2d89a2549fdd75bcbf15aa7d60259ef91a547d86b9dc3772a11594f
6
+ metadata.gz: 37b55ebad1113279ead05407bc51bc54b35fa48cb3cf8c2b1c661835e42223facc5956237d7bd4b51d20af84ce800381b48992d6de5c2e2d5bf2b9fb6f974410
7
+ data.tar.gz: 69bc8d7bc7d3fbde5802f9d02d1b78d8bc6079a70507dd734d244761318461ee02045e7ec9ddc7d63783f1df5657baad154213f9b3c63502118797a9b456b178
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 0.19 (2015-02-18)
2
+
3
+ * Upgrade to Handlebars v3.0
4
+ * Re-fix the issue regarding sprockets
5
+
6
+ ## 0.18.1 (2015-02-18)
7
+
8
+ * Fix issue regarding sprockets versioning of assets
9
+
1
10
  ## 0.18 (2014-09-08)
2
11
 
3
12
  * Update to handlebars v2.0.0 - @AlexRiedler
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.add_runtime_dependency "multi_json"
25
25
  s.add_runtime_dependency "sprockets", ">= 2.0.3"
26
26
 
27
- s.add_development_dependency "debugger"
27
+ s.add_development_dependency "minitest"
28
28
  s.add_development_dependency "haml"
29
29
  s.add_development_dependency "rake"
30
30
  s.add_development_dependency "slim"
@@ -31,6 +31,10 @@ module HandlebarsAssets
31
31
  end
32
32
  end
33
33
 
34
+ def self.add_to_asset_versioning(sprockets_environment)
35
+ sprockets_environment.config.version += "-#{HandlebarsAssets::VERSION}"
36
+ end
37
+
34
38
  end
35
39
 
36
40
  # Register the engine (which will register extension in the app)
@@ -94,19 +94,19 @@ module HandlebarsAssets
94
94
  end
95
95
 
96
96
  def handlebars_extensions
97
- @hbs_extensions ||= ['hbs', 'handlebars']
97
+ @hbs_extensions ||= ['.hbs', '.handlebars']
98
98
  end
99
99
 
100
100
  def hamlbars_extensions
101
- @hamlbars_extensions ||= ['hamlbars']
101
+ @hamlbars_extensions ||= ['.hamlbars']
102
102
  end
103
103
 
104
104
  def slimbars_extensions
105
- @slimbars_extensions ||= ['slimbars']
105
+ @slimbars_extensions ||= ['.slimbars']
106
106
  end
107
107
 
108
108
  def ember_extensions
109
- @ember_extensions ||= ['ember']
109
+ @ember_extensions ||= ['.ember']
110
110
  end
111
111
 
112
112
  def amd?
@@ -3,6 +3,7 @@ module HandlebarsAssets
3
3
  class Engine < ::Rails::Engine
4
4
  initializer "handlebars_assets.assets.register", :group => :all do |app|
5
5
  ::HandlebarsAssets::register_extensions(app.assets)
6
+ app.assets.version += "#{::HandlebarsAssets::VERSION}"
6
7
  end
7
8
  end
8
9
  end
@@ -1,3 +1,3 @@
1
1
  module HandlebarsAssets
2
- VERSION = "0.18"
2
+ VERSION = "0.19"
3
3
  end
@@ -1,7 +1,7 @@
1
1
  require 'test_helper'
2
2
 
3
3
  module HandlebarsAssets
4
- class CompilingTest < Test::Unit::TestCase
4
+ class CompilingTest < ::MiniTest::Test
5
5
 
6
6
  def teardown
7
7
  HandlebarsAssets::Config.reset!
@@ -1,7 +1,7 @@
1
1
  require 'test_helper'
2
2
 
3
3
  module HandlebarsAssets
4
- class HamlbarsTest < Test::Unit::TestCase
4
+ class HamlbarsTest < ::Minitest::Test
5
5
  include SprocketsScope
6
6
  include CompilerSupport
7
7
 
@@ -1,7 +1,7 @@
1
1
  require 'test_helper'
2
2
 
3
3
  module HandlebarsAssets
4
- class SlimbarsTest < Test::Unit::TestCase
4
+ class SlimbarsTest < ::Minitest::Test
5
5
  include SprocketsScope
6
6
  include CompilerSupport
7
7
 
@@ -1,7 +1,7 @@
1
1
  require 'test_helper'
2
2
 
3
3
  module HandlebarsAssets
4
- class HandlebarsTemplateTest < Test::Unit::TestCase
4
+ class HandlebarsTemplateTest < Minitest::Test
5
5
  include CompilerSupport
6
6
  include SprocketsScope
7
7
 
data/test/test_helper.rb CHANGED
@@ -3,7 +3,7 @@ require 'handlebars_assets/config'
3
3
  require 'handlebars_assets/handlebars_template'
4
4
  require 'handlebars_assets/handlebars'
5
5
 
6
- require 'test/unit'
6
+ require 'minitest/autorun'
7
7
 
8
8
  module SprocketsScope
9
9
  # Try to act like sprockets.
@@ -23,7 +23,7 @@ module CompilerSupport
23
23
 
24
24
  def compile_hbs(source)
25
25
  compiler_src = Pathname(HandlebarsAssets::Config.compiler_path).join(HandlebarsAssets::Config.compiler).read
26
- ExecJS.compile(compiler_src).call('Handlebars.precompile', source, HandlebarsAssets::Config.options)
26
+ ExecJS.compile("var window = {}; " + compiler_src).call('Handlebars.precompile', source, HandlebarsAssets::Config.options)
27
27
  end
28
28
 
29
29
  def hbs_compiled(template_name, source)
@@ -1,6 +1,6 @@
1
1
  /*!
2
2
 
3
- handlebars v2.0.0
3
+ handlebars v3.0.0
4
4
 
5
5
  Copyright (C) 2011-2014 by Yehuda Katz
6
6
 
@@ -25,39 +25,24 @@ THE SOFTWARE.
25
25
  @license
26
26
  */
27
27
  /* exported Handlebars */
28
+ if (!window) {
29
+ var window = {};
30
+ }
31
+
28
32
  (function (root, factory) {
29
33
  if (typeof define === 'function' && define.amd) {
30
34
  define([], factory);
31
35
  } else if (typeof exports === 'object') {
32
36
  module.exports = factory();
33
37
  } else {
34
- root.Handlebars = root.Handlebars || factory();
38
+ root.Handlebars = factory();
35
39
  }
36
40
  }(this, function () {
37
- // handlebars/safe-string.js
38
- var __module4__ = (function() {
39
- "use strict";
40
- var __exports__;
41
- // Build out our basic SafeString type
42
- function SafeString(string) {
43
- this.string = string;
44
- }
45
-
46
- SafeString.prototype.toString = function() {
47
- return "" + this.string;
48
- };
49
-
50
- __exports__ = SafeString;
51
- return __exports__;
52
- })();
53
-
54
41
  // handlebars/utils.js
55
- var __module3__ = (function(__dependency1__) {
42
+ var __module3__ = (function() {
56
43
  "use strict";
57
44
  var __exports__ = {};
58
45
  /*jshint -W004 */
59
- var SafeString = __dependency1__;
60
-
61
46
  var escape = {
62
47
  "&": "&amp;",
63
48
  "<": "&lt;",
@@ -107,11 +92,21 @@ var __module3__ = (function(__dependency1__) {
107
92
  return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
108
93
  };
109
94
  __exports__.isArray = isArray;
95
+ // Older IE versions do not directly support indexOf so we must implement our own, sadly.
96
+ function indexOf(array, value) {
97
+ for (var i = 0, len = array.length; i < len; i++) {
98
+ if (array[i] === value) {
99
+ return i;
100
+ }
101
+ }
102
+ return -1;
103
+ }
110
104
 
105
+ __exports__.indexOf = indexOf;
111
106
  function escapeExpression(string) {
112
107
  // don't escape SafeStrings, since they're already safe
113
- if (string instanceof SafeString) {
114
- return string.toString();
108
+ if (string && string.toHTML) {
109
+ return string.toHTML();
115
110
  } else if (string == null) {
116
111
  return "";
117
112
  } else if (!string) {
@@ -137,27 +132,35 @@ var __module3__ = (function(__dependency1__) {
137
132
  }
138
133
  }
139
134
 
140
- __exports__.isEmpty = isEmpty;function appendContextPath(contextPath, id) {
135
+ __exports__.isEmpty = isEmpty;function blockParams(params, ids) {
136
+ params.path = ids;
137
+ return params;
138
+ }
139
+
140
+ __exports__.blockParams = blockParams;function appendContextPath(contextPath, id) {
141
141
  return (contextPath ? contextPath + '.' : '') + id;
142
142
  }
143
143
 
144
144
  __exports__.appendContextPath = appendContextPath;
145
145
  return __exports__;
146
- })(__module4__);
146
+ })();
147
147
 
148
148
  // handlebars/exception.js
149
- var __module5__ = (function() {
149
+ var __module4__ = (function() {
150
150
  "use strict";
151
151
  var __exports__;
152
152
 
153
153
  var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
154
154
 
155
155
  function Exception(message, node) {
156
- var line;
157
- if (node && node.firstLine) {
158
- line = node.firstLine;
159
-
160
- message += ' - ' + line + ':' + node.firstColumn;
156
+ var loc = node && node.loc,
157
+ line,
158
+ column;
159
+ if (loc) {
160
+ line = loc.start.line;
161
+ column = loc.start.column;
162
+
163
+ message += ' - ' + line + ':' + column;
161
164
  }
162
165
 
163
166
  var tmp = Error.prototype.constructor.call(this, message);
@@ -167,9 +170,9 @@ var __module5__ = (function() {
167
170
  this[errorProps[idx]] = tmp[errorProps[idx]];
168
171
  }
169
172
 
170
- if (line) {
173
+ if (loc) {
171
174
  this.lineNumber = line;
172
- this.column = node.firstColumn;
175
+ this.column = column;
173
176
  }
174
177
  }
175
178
 
@@ -186,7 +189,7 @@ var __module2__ = (function(__dependency1__, __dependency2__) {
186
189
  var Utils = __dependency1__;
187
190
  var Exception = __dependency2__;
188
191
 
189
- var VERSION = "2.0.0";
192
+ var VERSION = "3.0.0";
190
193
  __exports__.VERSION = VERSION;var COMPILER_REVISION = 6;
191
194
  __exports__.COMPILER_REVISION = COMPILER_REVISION;
192
195
  var REVISION_CHANGES = {
@@ -232,6 +235,9 @@ var __module2__ = (function(__dependency1__, __dependency2__) {
232
235
  if (toString.call(name) === objectType) {
233
236
  Utils.extend(this.partials, name);
234
237
  } else {
238
+ if (typeof partial === 'undefined') {
239
+ throw new Exception('Attempting to register a partial as undefined');
240
+ }
235
241
  this.partials[name] = partial;
236
242
  }
237
243
  },
@@ -299,36 +305,47 @@ var __module2__ = (function(__dependency1__, __dependency2__) {
299
305
  data = createFrame(options.data);
300
306
  }
301
307
 
308
+ function execIteration(key, i, last) {
309
+ if (data) {
310
+ data.key = key;
311
+ data.index = i;
312
+ data.first = i === 0;
313
+ data.last = !!last;
314
+
315
+ if (contextPath) {
316
+ data.contextPath = contextPath + key;
317
+ }
318
+ }
319
+
320
+ ret = ret + fn(context[key], {
321
+ data: data,
322
+ blockParams: Utils.blockParams([context[key], key], [contextPath + key, null])
323
+ });
324
+ }
325
+
302
326
  if(context && typeof context === 'object') {
303
327
  if (isArray(context)) {
304
328
  for(var j = context.length; i<j; i++) {
305
- if (data) {
306
- data.index = i;
307
- data.first = (i === 0);
308
- data.last = (i === (context.length-1));
309
-
310
- if (contextPath) {
311
- data.contextPath = contextPath + i;
312
- }
313
- }
314
- ret = ret + fn(context[i], { data: data });
329
+ execIteration(i, i, i === context.length-1);
315
330
  }
316
331
  } else {
332
+ var priorKey;
333
+
317
334
  for(var key in context) {
318
335
  if(context.hasOwnProperty(key)) {
319
- if(data) {
320
- data.key = key;
321
- data.index = i;
322
- data.first = (i === 0);
323
-
324
- if (contextPath) {
325
- data.contextPath = contextPath + key;
326
- }
336
+ // We're running the iterations one step out of sync so we can detect
337
+ // the last iteration without have to scan the object twice and create
338
+ // an itermediate keys array.
339
+ if (priorKey) {
340
+ execIteration(priorKey, i-1);
327
341
  }
328
- ret = ret + fn(context[key], {data: data});
342
+ priorKey = key;
329
343
  i++;
330
344
  }
331
345
  }
346
+ if (priorKey) {
347
+ execIteration(priorKey, i-1, true);
348
+ }
332
349
  }
333
350
  }
334
351
 
@@ -392,15 +409,13 @@ var __module2__ = (function(__dependency1__, __dependency2__) {
392
409
  INFO: 1,
393
410
  WARN: 2,
394
411
  ERROR: 3,
395
- level: 3,
412
+ level: 1,
396
413
 
397
- // can be overridden in the host environment
414
+ // Can be overridden in the host environment
398
415
  log: function(level, message) {
399
- if (logger.level <= level) {
416
+ if (typeof console !== 'undefined' && logger.level <= level) {
400
417
  var method = logger.methodMap[level];
401
- if (typeof console !== 'undefined' && console[method]) {
402
- console[method].call(console, message);
403
- }
418
+ (console[method] || console.log).call(console, message);
404
419
  }
405
420
  }
406
421
  };
@@ -414,7 +429,24 @@ var __module2__ = (function(__dependency1__, __dependency2__) {
414
429
  };
415
430
  __exports__.createFrame = createFrame;
416
431
  return __exports__;
417
- })(__module3__, __module5__);
432
+ })(__module3__, __module4__);
433
+
434
+ // handlebars/safe-string.js
435
+ var __module5__ = (function() {
436
+ "use strict";
437
+ var __exports__;
438
+ // Build out our basic SafeString type
439
+ function SafeString(string) {
440
+ this.string = string;
441
+ }
442
+
443
+ SafeString.prototype.toString = SafeString.prototype.toHTML = function() {
444
+ return "" + this.string;
445
+ };
446
+
447
+ __exports__ = SafeString;
448
+ return __exports__;
449
+ })();
418
450
 
419
451
  // handlebars/runtime.js
420
452
  var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
@@ -459,38 +491,44 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
459
491
  // for external users to override these as psuedo-supported APIs.
460
492
  env.VM.checkRevision(templateSpec.compiler);
461
493
 
462
- var invokePartialWrapper = function(partial, indent, name, context, hash, helpers, partials, data, depths) {
463
- if (hash) {
464
- context = Utils.extend({}, context, hash);
494
+ var invokePartialWrapper = function(partial, context, options) {
495
+ if (options.hash) {
496
+ context = Utils.extend({}, context, options.hash);
465
497
  }
466
498
 
467
- var result = env.VM.invokePartial.call(this, partial, name, context, helpers, partials, data, depths);
499
+ partial = env.VM.resolvePartial.call(this, partial, context, options);
500
+ var result = env.VM.invokePartial.call(this, partial, context, options);
468
501
 
469
502
  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);
503
+ options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env);
504
+ result = options.partials[options.name](context, options);
473
505
  }
474
506
  if (result != null) {
475
- if (indent) {
507
+ if (options.indent) {
476
508
  var lines = result.split('\n');
477
509
  for (var i = 0, l = lines.length; i < l; i++) {
478
510
  if (!lines[i] && i + 1 === l) {
479
511
  break;
480
512
  }
481
513
 
482
- lines[i] = indent + lines[i];
514
+ lines[i] = options.indent + lines[i];
483
515
  }
484
516
  result = lines.join('\n');
485
517
  }
486
518
  return result;
487
519
  } else {
488
- throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
520
+ throw new Exception("The partial " + options.name + " could not be compiled when running in runtime-only mode");
489
521
  }
490
522
  };
491
523
 
492
524
  // Just add water
493
525
  var container = {
526
+ strict: function(obj, name) {
527
+ if (!(name in obj)) {
528
+ throw new Exception('"' + name + '" not defined in ' + obj);
529
+ }
530
+ return obj[name];
531
+ },
494
532
  lookup: function(depths, name) {
495
533
  var len = depths.length;
496
534
  for (var i = 0; i < len; i++) {
@@ -511,11 +549,11 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
511
549
  },
512
550
 
513
551
  programs: [],
514
- program: function(i, data, depths) {
552
+ program: function(i, data, declaredBlockParams, blockParams, depths) {
515
553
  var programWrapper = this.programs[i],
516
554
  fn = this.fn(i);
517
- if (data || depths) {
518
- programWrapper = program(this, i, fn, data, depths);
555
+ if (data || depths || blockParams || declaredBlockParams) {
556
+ programWrapper = program(this, i, fn, data, declaredBlockParams, blockParams, depths);
519
557
  } else if (!programWrapper) {
520
558
  programWrapper = this.programs[i] = program(this, i, fn);
521
559
  }
@@ -550,12 +588,13 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
550
588
  if (!options.partial && templateSpec.useData) {
551
589
  data = initData(context, data);
552
590
  }
553
- var depths;
591
+ var depths,
592
+ blockParams = templateSpec.useBlockParams ? [] : undefined;
554
593
  if (templateSpec.useDepths) {
555
594
  depths = options.depths ? [context].concat(options.depths) : [context];
556
595
  }
557
596
 
558
- return templateSpec.main.call(container, context, container.helpers, container.partials, data, depths);
597
+ return templateSpec.main.call(container, context, container.helpers, container.partials, data, blockParams, depths);
559
598
  };
560
599
  ret.isTop = true;
561
600
 
@@ -572,32 +611,52 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
572
611
  }
573
612
  };
574
613
 
575
- ret._child = function(i, data, depths) {
614
+ ret._child = function(i, data, blockParams, depths) {
615
+ if (templateSpec.useBlockParams && !blockParams) {
616
+ throw new Exception('must pass block params');
617
+ }
576
618
  if (templateSpec.useDepths && !depths) {
577
619
  throw new Exception('must pass parent depths');
578
620
  }
579
621
 
580
- return program(container, i, templateSpec[i], data, depths);
622
+ return program(container, i, templateSpec[i], data, 0, blockParams, depths);
581
623
  };
582
624
  return ret;
583
625
  }
584
626
 
585
- __exports__.template = template;function program(container, i, fn, data, depths) {
627
+ __exports__.template = template;function program(container, i, fn, data, declaredBlockParams, blockParams, depths) {
586
628
  var prog = function(context, options) {
587
629
  options = options || {};
588
630
 
589
- return fn.call(container, context, container.helpers, container.partials, options.data || data, depths && [context].concat(depths));
631
+ return fn.call(container,
632
+ context,
633
+ container.helpers, container.partials,
634
+ options.data || data,
635
+ blockParams && [options.blockParams].concat(blockParams),
636
+ depths && [context].concat(depths));
590
637
  };
591
638
  prog.program = i;
592
639
  prog.depth = depths ? depths.length : 0;
640
+ prog.blockParams = declaredBlockParams || 0;
593
641
  return prog;
594
642
  }
595
643
 
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 };
644
+ __exports__.program = program;function resolvePartial(partial, context, options) {
645
+ if (!partial) {
646
+ partial = options.partials[options.name];
647
+ } else if (!partial.call && !options.name) {
648
+ // This is a dynamic partial that returned a string
649
+ options.name = partial;
650
+ partial = options.partials[partial];
651
+ }
652
+ return partial;
653
+ }
654
+
655
+ __exports__.resolvePartial = resolvePartial;function invokePartial(partial, context, options) {
656
+ options.partial = true;
598
657
 
599
658
  if(partial === undefined) {
600
- throw new Exception("The partial " + name + " could not be found");
659
+ throw new Exception("The partial " + options.name + " could not be found");
601
660
  } else if(partial instanceof Function) {
602
661
  return partial(context, options);
603
662
  }
@@ -613,7 +672,7 @@ var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
613
672
  return data;
614
673
  }
615
674
  return __exports__;
616
- })(__module3__, __module5__, __module2__);
675
+ })(__module3__, __module4__, __module2__);
617
676
 
618
677
  // handlebars.runtime.js
619
678
  var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
@@ -650,231 +709,170 @@ var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, _
650
709
  var Handlebars = create();
651
710
  Handlebars.create = create;
652
711
 
712
+ /*jshint -W040 */
713
+ /* istanbul ignore next */
714
+ var root = typeof global !== 'undefined' ? global : window,
715
+ $Handlebars = root.Handlebars;
716
+ /* istanbul ignore next */
717
+ Handlebars.noConflict = function() {
718
+ if (root.Handlebars === Handlebars) {
719
+ root.Handlebars = $Handlebars;
720
+ }
721
+ };
722
+
653
723
  Handlebars['default'] = Handlebars;
654
724
 
655
725
  __exports__ = Handlebars;
656
726
  return __exports__;
657
- })(__module2__, __module4__, __module5__, __module3__, __module6__);
727
+ })(__module2__, __module5__, __module4__, __module3__, __module6__);
658
728
 
659
729
  // handlebars/compiler/ast.js
660
- var __module7__ = (function(__dependency1__) {
730
+ var __module7__ = (function() {
661
731
  "use strict";
662
732
  var __exports__;
663
- var Exception = __dependency1__;
664
-
665
- function LocationInfo(locInfo) {
666
- locInfo = locInfo || {};
667
- this.firstLine = locInfo.first_line;
668
- this.firstColumn = locInfo.first_column;
669
- this.lastColumn = locInfo.last_column;
670
- this.lastLine = locInfo.last_line;
671
- }
672
-
673
733
  var AST = {
674
- ProgramNode: function(statements, strip, locInfo) {
675
- LocationInfo.call(this, locInfo);
676
- this.type = "program";
677
- this.statements = statements;
678
- this.strip = strip;
679
- },
734
+ Program: function(statements, blockParams, strip, locInfo) {
735
+ this.loc = locInfo;
736
+ this.type = 'Program';
737
+ this.body = statements;
680
738
 
681
- MustacheNode: function(rawParams, hash, open, strip, locInfo) {
682
- LocationInfo.call(this, locInfo);
683
- this.type = "mustache";
739
+ this.blockParams = blockParams;
684
740
  this.strip = strip;
685
-
686
- // Open may be a string parsed from the parser or a passed boolean flag
687
- if (open != null && open.charAt) {
688
- // Must use charAt to support IE pre-10
689
- var escapeFlag = open.charAt(3) || open.charAt(2);
690
- this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
691
- } else {
692
- this.escaped = !!open;
693
- }
694
-
695
- if (rawParams instanceof AST.SexprNode) {
696
- this.sexpr = rawParams;
697
- } else {
698
- // Support old AST API
699
- this.sexpr = new AST.SexprNode(rawParams, hash);
700
- }
701
-
702
- // Support old AST API that stored this info in MustacheNode
703
- this.id = this.sexpr.id;
704
- this.params = this.sexpr.params;
705
- this.hash = this.sexpr.hash;
706
- this.eligibleHelper = this.sexpr.eligibleHelper;
707
- this.isHelper = this.sexpr.isHelper;
708
741
  },
709
742
 
710
- SexprNode: function(rawParams, hash, locInfo) {
711
- LocationInfo.call(this, locInfo);
743
+ MustacheStatement: function(path, params, hash, escaped, strip, locInfo) {
744
+ this.loc = locInfo;
745
+ this.type = 'MustacheStatement';
712
746
 
713
- this.type = "sexpr";
747
+ this.path = path;
748
+ this.params = params || [];
714
749
  this.hash = hash;
750
+ this.escaped = escaped;
715
751
 
716
- var id = this.id = rawParams[0];
717
- var params = this.params = rawParams.slice(1);
718
-
719
- // a mustache is definitely a helper if:
720
- // * it is an eligible helper, and
721
- // * it has at least one parameter or hash segment
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;
727
-
728
- // if a mustache is an eligible helper but not a definite
729
- // helper, it is ambiguous, and will be resolved in a later
730
- // pass or at runtime.
731
- },
732
-
733
- PartialNode: function(partialName, context, hash, strip, locInfo) {
734
- LocationInfo.call(this, locInfo);
735
- this.type = "partial";
736
- this.partialName = partialName;
737
- this.context = context;
738
- this.hash = hash;
739
752
  this.strip = strip;
740
-
741
- this.strip.inlineStandalone = true;
742
753
  },
743
754
 
744
- BlockNode: function(mustache, program, inverse, strip, locInfo) {
745
- LocationInfo.call(this, locInfo);
755
+ BlockStatement: function(path, params, hash, program, inverse, openStrip, inverseStrip, closeStrip, locInfo) {
756
+ this.loc = locInfo;
757
+ this.type = 'BlockStatement';
746
758
 
747
- this.type = 'block';
748
- this.mustache = mustache;
759
+ this.path = path;
760
+ this.params = params || [];
761
+ this.hash = hash;
749
762
  this.program = program;
750
763
  this.inverse = inverse;
751
- this.strip = strip;
752
764
 
753
- if (inverse && !program) {
754
- this.isInverse = true;
755
- }
765
+ this.openStrip = openStrip;
766
+ this.inverseStrip = inverseStrip;
767
+ this.closeStrip = closeStrip;
756
768
  },
757
769
 
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
- }
770
+ PartialStatement: function(name, params, hash, strip, locInfo) {
771
+ this.loc = locInfo;
772
+ this.type = 'PartialStatement';
764
773
 
765
- content = new AST.ContentNode(content, locInfo);
774
+ this.name = name;
775
+ this.params = params || [];
776
+ this.hash = hash;
766
777
 
767
- this.type = 'block';
768
- this.mustache = mustache;
769
- this.program = new AST.ProgramNode([content], {}, locInfo);
778
+ this.indent = '';
779
+ this.strip = strip;
770
780
  },
771
781
 
772
- ContentNode: function(string, locInfo) {
773
- LocationInfo.call(this, locInfo);
774
- this.type = "content";
775
- this.original = this.string = string;
782
+ ContentStatement: function(string, locInfo) {
783
+ this.loc = locInfo;
784
+ this.type = 'ContentStatement';
785
+ this.original = this.value = string;
776
786
  },
777
787
 
778
- HashNode: function(pairs, locInfo) {
779
- LocationInfo.call(this, locInfo);
780
- this.type = "hash";
781
- this.pairs = pairs;
782
- },
788
+ CommentStatement: function(comment, strip, locInfo) {
789
+ this.loc = locInfo;
790
+ this.type = 'CommentStatement';
791
+ this.value = comment;
783
792
 
784
- IdNode: function(parts, locInfo) {
785
- LocationInfo.call(this, locInfo);
786
- this.type = "ID";
793
+ this.strip = strip;
794
+ },
787
795
 
788
- var original = "",
789
- dig = [],
790
- depth = 0,
791
- depthString = '';
796
+ SubExpression: function(path, params, hash, locInfo) {
797
+ this.loc = locInfo;
792
798
 
793
- for(var i=0,l=parts.length; i<l; i++) {
794
- var part = parts[i].part;
795
- original += (parts[i].separator || '') + part;
799
+ this.type = 'SubExpression';
800
+ this.path = path;
801
+ this.params = params || [];
802
+ this.hash = hash;
803
+ },
796
804
 
797
- if (part === ".." || part === "." || part === "this") {
798
- if (dig.length > 0) {
799
- throw new Exception("Invalid path: " + original, this);
800
- } else if (part === "..") {
801
- depth++;
802
- depthString += '../';
803
- } else {
804
- this.isScoped = true;
805
- }
806
- } else {
807
- dig.push(part);
808
- }
809
- }
805
+ PathExpression: function(data, depth, parts, original, locInfo) {
806
+ this.loc = locInfo;
807
+ this.type = 'PathExpression';
810
808
 
809
+ this.data = data;
811
810
  this.original = original;
812
- this.parts = dig;
813
- this.string = dig.join('.');
811
+ this.parts = parts;
814
812
  this.depth = depth;
815
- this.idName = depthString + this.string;
816
-
817
- // an ID is simple if it only has one part, and that part is not
818
- // `..` or `this`.
819
- this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
820
-
821
- this.stringModeValue = this.string;
822
813
  },
823
814
 
824
- PartialNameNode: function(name, locInfo) {
825
- LocationInfo.call(this, locInfo);
826
- this.type = "PARTIAL_NAME";
827
- this.name = name.original;
828
- },
829
-
830
- DataNode: function(id, locInfo) {
831
- LocationInfo.call(this, locInfo);
832
- this.type = "DATA";
833
- this.id = id;
834
- this.stringModeValue = id.stringModeValue;
835
- this.idName = '@' + id.stringModeValue;
815
+ StringLiteral: function(string, locInfo) {
816
+ this.loc = locInfo;
817
+ this.type = 'StringLiteral';
818
+ this.original =
819
+ this.value = string;
836
820
  },
837
821
 
838
- StringNode: function(string, locInfo) {
839
- LocationInfo.call(this, locInfo);
840
- this.type = "STRING";
822
+ NumberLiteral: function(number, locInfo) {
823
+ this.loc = locInfo;
824
+ this.type = 'NumberLiteral';
841
825
  this.original =
842
- this.string =
843
- this.stringModeValue = string;
826
+ this.value = Number(number);
844
827
  },
845
828
 
846
- NumberNode: function(number, locInfo) {
847
- LocationInfo.call(this, locInfo);
848
- this.type = "NUMBER";
829
+ BooleanLiteral: function(bool, locInfo) {
830
+ this.loc = locInfo;
831
+ this.type = 'BooleanLiteral';
849
832
  this.original =
850
- this.number = number;
851
- this.stringModeValue = Number(number);
833
+ this.value = bool === 'true';
852
834
  },
853
835
 
854
- BooleanNode: function(bool, locInfo) {
855
- LocationInfo.call(this, locInfo);
856
- this.type = "BOOLEAN";
857
- this.bool = bool;
858
- this.stringModeValue = bool === "true";
836
+ Hash: function(pairs, locInfo) {
837
+ this.loc = locInfo;
838
+ this.type = 'Hash';
839
+ this.pairs = pairs;
859
840
  },
841
+ HashPair: function(key, value, locInfo) {
842
+ this.loc = locInfo;
843
+ this.type = 'HashPair';
844
+ this.key = key;
845
+ this.value = value;
846
+ },
847
+
848
+ // Public API used to evaluate derived attributes regarding AST nodes
849
+ helpers: {
850
+ // a mustache is definitely a helper if:
851
+ // * it is an eligible helper, and
852
+ // * it has at least one parameter or hash segment
853
+ // TODO: Make these public utility methods
854
+ helperExpression: function(node) {
855
+ return !!(node.type === 'SubExpression' || node.params.length || node.hash);
856
+ },
860
857
 
861
- CommentNode: function(comment, locInfo) {
862
- LocationInfo.call(this, locInfo);
863
- this.type = "comment";
864
- this.comment = comment;
858
+ scopedId: function(path) {
859
+ return (/^\.|this\b/).test(path.original);
860
+ },
865
861
 
866
- this.strip = {
867
- inlineStandalone: true
868
- };
862
+ // an ID is simple if it only has one part, and that part is not
863
+ // `..` or `this`.
864
+ simpleId: function(path) {
865
+ return path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth;
866
+ }
869
867
  }
870
868
  };
871
869
 
872
870
 
873
871
  // Must be exported as an object rather than the root of the module as the jison lexer
874
- // most modify the object to operate properly.
872
+ // must modify the object to operate properly.
875
873
  __exports__ = AST;
876
874
  return __exports__;
877
- })(__module5__);
875
+ })();
878
876
 
879
877
  // handlebars/compiler/parser.js
880
878
  var __module9__ = (function() {
@@ -886,16 +884,16 @@ var __module9__ = (function() {
886
884
  var handlebars = (function(){
887
885
  var parser = {trace: function trace() { },
888
886
  yy: {},
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]],
887
+ 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,"CONTENT":14,"openRawBlock":15,"END_RAW_BLOCK":16,"OPEN_RAW_BLOCK":17,"helperName":18,"openRawBlock_repetition0":19,"openRawBlock_option0":20,"CLOSE_RAW_BLOCK":21,"openBlock":22,"block_option0":23,"closeBlock":24,"openInverse":25,"block_option1":26,"OPEN_BLOCK":27,"openBlock_repetition0":28,"openBlock_option0":29,"openBlock_option1":30,"CLOSE":31,"OPEN_INVERSE":32,"openInverse_repetition0":33,"openInverse_option0":34,"openInverse_option1":35,"openInverseChain":36,"OPEN_INVERSE_CHAIN":37,"openInverseChain_repetition0":38,"openInverseChain_option0":39,"openInverseChain_option1":40,"inverseAndProgram":41,"INVERSE":42,"inverseChain":43,"inverseChain_option0":44,"OPEN_ENDBLOCK":45,"OPEN":46,"mustache_repetition0":47,"mustache_option0":48,"OPEN_UNESCAPED":49,"mustache_repetition1":50,"mustache_option1":51,"CLOSE_UNESCAPED":52,"OPEN_PARTIAL":53,"partialName":54,"partial_repetition0":55,"partial_option0":56,"param":57,"sexpr":58,"OPEN_SEXPR":59,"sexpr_repetition0":60,"sexpr_option0":61,"CLOSE_SEXPR":62,"hash":63,"hash_repetition_plus0":64,"hashSegment":65,"ID":66,"EQUALS":67,"blockParams":68,"OPEN_BLOCK_PARAMS":69,"blockParams_repetition_plus0":70,"CLOSE_BLOCK_PARAMS":71,"path":72,"dataName":73,"STRING":74,"NUMBER":75,"BOOLEAN":76,"DATA":77,"pathSegments":78,"SEP":79,"$accept":0,"$end":1},
888
+ terminals_: {2:"error",5:"EOF",13:"COMMENT",14:"CONTENT",16:"END_RAW_BLOCK",17:"OPEN_RAW_BLOCK",21:"CLOSE_RAW_BLOCK",27:"OPEN_BLOCK",31:"CLOSE",32:"OPEN_INVERSE",37:"OPEN_INVERSE_CHAIN",42:"INVERSE",45:"OPEN_ENDBLOCK",46:"OPEN",49:"OPEN_UNESCAPED",52:"CLOSE_UNESCAPED",53:"OPEN_PARTIAL",59:"OPEN_SEXPR",62:"CLOSE_SEXPR",66:"ID",67:"EQUALS",69:"OPEN_BLOCK_PARAMS",71:"CLOSE_BLOCK_PARAMS",74:"STRING",75:"NUMBER",76:"BOOLEAN",77:"DATA",79:"SEP"},
889
+ productions_: [0,[3,2],[4,1],[7,1],[7,1],[7,1],[7,1],[7,1],[7,1],[12,1],[10,3],[15,5],[9,4],[9,4],[22,6],[25,6],[36,6],[41,2],[43,3],[43,1],[24,3],[8,5],[8,5],[11,5],[57,1],[57,1],[58,5],[63,1],[65,3],[68,3],[18,1],[18,1],[18,1],[18,1],[18,1],[54,1],[54,1],[73,2],[72,1],[78,3],[78,1],[6,0],[6,2],[19,0],[19,2],[20,0],[20,1],[23,0],[23,1],[26,0],[26,1],[28,0],[28,2],[29,0],[29,1],[30,0],[30,1],[33,0],[33,2],[34,0],[34,1],[35,0],[35,1],[38,0],[38,2],[39,0],[39,1],[40,0],[40,1],[44,0],[44,1],[47,0],[47,2],[48,0],[48,1],[50,0],[50,2],[51,0],[51,1],[55,0],[55,2],[56,0],[56,1],[60,0],[60,2],[61,0],[61,1],[64,1],[64,2],[70,1],[70,2]],
892
890
  performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
893
891
 
894
892
  var $0 = $$.length - 1;
895
893
  switch (yystate) {
896
- case 1: yy.prepareProgram($$[$0-1].statements, true); return $$[$0-1];
894
+ case 1: return $$[$0-1];
897
895
  break;
898
- case 2:this.$ = new yy.ProgramNode(yy.prepareProgram($$[$0]), {}, this._$);
896
+ case 2:this.$ = new yy.Program($$[$0], null, {}, yy.locInfo(this._$));
899
897
  break;
900
898
  case 3:this.$ = $$[$0];
901
899
  break;
@@ -905,84 +903,128 @@ var __module9__ = (function() {
905
903
  break;
906
904
  case 6:this.$ = $$[$0];
907
905
  break;
908
- case 7:this.$ = new yy.ContentNode($$[$0], this._$);
906
+ case 7:this.$ = $$[$0];
907
+ break;
908
+ case 8:this.$ = new yy.CommentStatement(yy.stripComment($$[$0]), yy.stripFlags($$[$0], $$[$0]), yy.locInfo(this._$));
909
+ break;
910
+ case 9:this.$ = new yy.ContentStatement($$[$0], yy.locInfo(this._$));
911
+ break;
912
+ case 10:this.$ = yy.prepareRawBlock($$[$0-2], $$[$0-1], $$[$0], this._$);
913
+ break;
914
+ case 11:this.$ = { path: $$[$0-3], params: $$[$0-2], hash: $$[$0-1] };
915
+ break;
916
+ case 12:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], false, this._$);
917
+ break;
918
+ case 13:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], true, this._$);
919
+ break;
920
+ case 14:this.$ = { path: $$[$0-4], params: $$[$0-3], hash: $$[$0-2], blockParams: $$[$0-1], strip: yy.stripFlags($$[$0-5], $$[$0]) };
921
+ break;
922
+ case 15:this.$ = { path: $$[$0-4], params: $$[$0-3], hash: $$[$0-2], blockParams: $$[$0-1], strip: yy.stripFlags($$[$0-5], $$[$0]) };
909
923
  break;
910
- case 8:this.$ = new yy.CommentNode($$[$0], this._$);
924
+ case 16:this.$ = { path: $$[$0-4], params: $$[$0-3], hash: $$[$0-2], blockParams: $$[$0-1], strip: yy.stripFlags($$[$0-5], $$[$0]) };
911
925
  break;
912
- case 9:this.$ = new yy.RawBlockNode($$[$0-2], $$[$0-1], $$[$0], this._$);
926
+ case 17:this.$ = { strip: yy.stripFlags($$[$0-1], $$[$0-1]), program: $$[$0] };
913
927
  break;
914
- case 10:this.$ = new yy.MustacheNode($$[$0-1], null, '', '', this._$);
928
+ case 18:
929
+ var inverse = yy.prepareBlock($$[$0-2], $$[$0-1], $$[$0], $$[$0], false, this._$),
930
+ program = new yy.Program([inverse], null, {}, yy.locInfo(this._$));
931
+ program.chained = true;
932
+
933
+ this.$ = { strip: $$[$0-2].strip, program: program, chain: true };
934
+
935
+ break;
936
+ case 19:this.$ = $$[$0];
937
+ break;
938
+ case 20:this.$ = {path: $$[$0-1], strip: yy.stripFlags($$[$0-2], $$[$0])};
939
+ break;
940
+ case 21:this.$ = yy.prepareMustache($$[$0-3], $$[$0-2], $$[$0-1], $$[$0-4], yy.stripFlags($$[$0-4], $$[$0]), this._$);
941
+ break;
942
+ case 22:this.$ = yy.prepareMustache($$[$0-3], $$[$0-2], $$[$0-1], $$[$0-4], yy.stripFlags($$[$0-4], $$[$0]), this._$);
943
+ break;
944
+ case 23:this.$ = new yy.PartialStatement($$[$0-3], $$[$0-2], $$[$0-1], yy.stripFlags($$[$0-4], $$[$0]), yy.locInfo(this._$));
945
+ break;
946
+ case 24:this.$ = $$[$0];
915
947
  break;
916
- case 11:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], false, this._$);
948
+ case 25:this.$ = $$[$0];
917
949
  break;
918
- case 12:this.$ = yy.prepareBlock($$[$0-3], $$[$0-2], $$[$0-1], $$[$0], true, this._$);
950
+ case 26:this.$ = new yy.SubExpression($$[$0-3], $$[$0-2], $$[$0-1], yy.locInfo(this._$));
919
951
  break;
920
- case 13:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$);
952
+ case 27:this.$ = new yy.Hash($$[$0], yy.locInfo(this._$));
921
953
  break;
922
- case 14:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$);
954
+ case 28:this.$ = new yy.HashPair($$[$0-2], $$[$0], yy.locInfo(this._$));
923
955
  break;
924
- case 15:this.$ = { strip: yy.stripFlags($$[$0-1], $$[$0-1]), program: $$[$0] };
956
+ case 29:this.$ = $$[$0-1];
925
957
  break;
926
- case 16:this.$ = {path: $$[$0-1], strip: yy.stripFlags($$[$0-2], $$[$0])};
958
+ case 30:this.$ = $$[$0];
927
959
  break;
928
- case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$);
960
+ case 31:this.$ = $$[$0];
929
961
  break;
930
- case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], yy.stripFlags($$[$0-2], $$[$0]), this._$);
962
+ case 32:this.$ = new yy.StringLiteral($$[$0], yy.locInfo(this._$));
931
963
  break;
932
- case 19:this.$ = new yy.PartialNode($$[$0-3], $$[$0-2], $$[$0-1], yy.stripFlags($$[$0-4], $$[$0]), this._$);
964
+ case 33:this.$ = new yy.NumberLiteral($$[$0], yy.locInfo(this._$));
933
965
  break;
934
- case 20:this.$ = new yy.PartialNode($$[$0-2], undefined, $$[$0-1], yy.stripFlags($$[$0-3], $$[$0]), this._$);
966
+ case 34:this.$ = new yy.BooleanLiteral($$[$0], yy.locInfo(this._$));
935
967
  break;
936
- case 21:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
968
+ case 35:this.$ = $$[$0];
937
969
  break;
938
- case 22:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
970
+ case 36:this.$ = $$[$0];
939
971
  break;
940
- case 23:this.$ = $$[$0];
972
+ case 37:this.$ = yy.preparePath(true, $$[$0], this._$);
941
973
  break;
942
- case 24:this.$ = new yy.StringNode($$[$0], this._$);
974
+ case 38:this.$ = yy.preparePath(false, $$[$0], this._$);
943
975
  break;
944
- case 25:this.$ = new yy.NumberNode($$[$0], this._$);
976
+ case 39: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
945
977
  break;
946
- case 26:this.$ = new yy.BooleanNode($$[$0], this._$);
978
+ case 40:this.$ = [{part: $$[$0]}];
947
979
  break;
948
- case 27:this.$ = $$[$0];
980
+ case 41:this.$ = [];
949
981
  break;
950
- case 28:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
982
+ case 42:$$[$0-1].push($$[$0]);
951
983
  break;
952
- case 29:this.$ = new yy.HashNode($$[$0], this._$);
984
+ case 43:this.$ = [];
953
985
  break;
954
- case 30:this.$ = [$$[$0-2], $$[$0]];
986
+ case 44:$$[$0-1].push($$[$0]);
955
987
  break;
956
- case 31:this.$ = new yy.PartialNameNode($$[$0], this._$);
988
+ case 51:this.$ = [];
957
989
  break;
958
- case 32:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
990
+ case 52:$$[$0-1].push($$[$0]);
959
991
  break;
960
- case 33:this.$ = new yy.PartialNameNode(new yy.NumberNode($$[$0], this._$));
992
+ case 57:this.$ = [];
961
993
  break;
962
- case 34:this.$ = new yy.DataNode($$[$0], this._$);
994
+ case 58:$$[$0-1].push($$[$0]);
963
995
  break;
964
- case 35:this.$ = new yy.IdNode($$[$0], this._$);
996
+ case 63:this.$ = [];
965
997
  break;
966
- case 36: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
998
+ case 64:$$[$0-1].push($$[$0]);
967
999
  break;
968
- case 37:this.$ = [{part: $$[$0]}];
1000
+ case 71:this.$ = [];
969
1001
  break;
970
- case 38:this.$ = [];
1002
+ case 72:$$[$0-1].push($$[$0]);
971
1003
  break;
972
- case 39:$$[$0-1].push($$[$0]);
1004
+ case 75:this.$ = [];
973
1005
  break;
974
- case 48:this.$ = [];
1006
+ case 76:$$[$0-1].push($$[$0]);
975
1007
  break;
976
- case 49:$$[$0-1].push($$[$0]);
1008
+ case 79:this.$ = [];
977
1009
  break;
978
- case 52:this.$ = [$$[$0]];
1010
+ case 80:$$[$0-1].push($$[$0]);
979
1011
  break;
980
- case 53:$$[$0-1].push($$[$0]);
1012
+ case 83:this.$ = [];
1013
+ break;
1014
+ case 84:$$[$0-1].push($$[$0]);
1015
+ break;
1016
+ case 87:this.$ = [$$[$0]];
1017
+ break;
1018
+ case 88:$$[$0-1].push($$[$0]);
1019
+ break;
1020
+ case 89:this.$ = [$$[$0]];
1021
+ break;
1022
+ case 90:$$[$0-1].push($$[$0]);
981
1023
  break;
982
1024
  }
983
1025
  },
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]},
1026
+ table: [{3:1,4:2,5:[2,41],6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],46:[2,41],49:[2,41],53:[2,41]},{1:[3]},{5:[1,4]},{5:[2,2],7:5,8:6,9:7,10:8,11:9,12:10,13:[1,11],14:[1,18],15:16,17:[1,21],22:14,25:15,27:[1,19],32:[1,20],37:[2,2],42:[2,2],45:[2,2],46:[1,12],49:[1,13],53:[1,17]},{1:[2,1]},{5:[2,42],13:[2,42],14:[2,42],17:[2,42],27:[2,42],32:[2,42],37:[2,42],42:[2,42],45:[2,42],46:[2,42],49:[2,42],53:[2,42]},{5:[2,3],13:[2,3],14:[2,3],17:[2,3],27:[2,3],32:[2,3],37:[2,3],42:[2,3],45:[2,3],46:[2,3],49:[2,3],53:[2,3]},{5:[2,4],13:[2,4],14:[2,4],17:[2,4],27:[2,4],32:[2,4],37:[2,4],42:[2,4],45:[2,4],46:[2,4],49:[2,4],53:[2,4]},{5:[2,5],13:[2,5],14:[2,5],17:[2,5],27:[2,5],32:[2,5],37:[2,5],42:[2,5],45:[2,5],46:[2,5],49:[2,5],53:[2,5]},{5:[2,6],13:[2,6],14:[2,6],17:[2,6],27:[2,6],32:[2,6],37:[2,6],42:[2,6],45:[2,6],46:[2,6],49:[2,6],53:[2,6]},{5:[2,7],13:[2,7],14:[2,7],17:[2,7],27:[2,7],32:[2,7],37:[2,7],42:[2,7],45:[2,7],46:[2,7],49:[2,7],53:[2,7]},{5:[2,8],13:[2,8],14:[2,8],17:[2,8],27:[2,8],32:[2,8],37:[2,8],42:[2,8],45:[2,8],46:[2,8],49:[2,8],53:[2,8]},{18:22,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:31,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{4:32,6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],37:[2,41],42:[2,41],45:[2,41],46:[2,41],49:[2,41],53:[2,41]},{4:33,6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],42:[2,41],45:[2,41],46:[2,41],49:[2,41],53:[2,41]},{12:34,14:[1,18]},{18:36,54:35,58:37,59:[1,38],66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{5:[2,9],13:[2,9],14:[2,9],16:[2,9],17:[2,9],27:[2,9],32:[2,9],37:[2,9],42:[2,9],45:[2,9],46:[2,9],49:[2,9],53:[2,9]},{18:39,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:40,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:41,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{31:[2,71],47:42,59:[2,71],66:[2,71],74:[2,71],75:[2,71],76:[2,71],77:[2,71]},{21:[2,30],31:[2,30],52:[2,30],59:[2,30],62:[2,30],66:[2,30],69:[2,30],74:[2,30],75:[2,30],76:[2,30],77:[2,30]},{21:[2,31],31:[2,31],52:[2,31],59:[2,31],62:[2,31],66:[2,31],69:[2,31],74:[2,31],75:[2,31],76:[2,31],77:[2,31]},{21:[2,32],31:[2,32],52:[2,32],59:[2,32],62:[2,32],66:[2,32],69:[2,32],74:[2,32],75:[2,32],76:[2,32],77:[2,32]},{21:[2,33],31:[2,33],52:[2,33],59:[2,33],62:[2,33],66:[2,33],69:[2,33],74:[2,33],75:[2,33],76:[2,33],77:[2,33]},{21:[2,34],31:[2,34],52:[2,34],59:[2,34],62:[2,34],66:[2,34],69:[2,34],74:[2,34],75:[2,34],76:[2,34],77:[2,34]},{21:[2,38],31:[2,38],52:[2,38],59:[2,38],62:[2,38],66:[2,38],69:[2,38],74:[2,38],75:[2,38],76:[2,38],77:[2,38],79:[1,43]},{66:[1,30],78:44},{21:[2,40],31:[2,40],52:[2,40],59:[2,40],62:[2,40],66:[2,40],69:[2,40],74:[2,40],75:[2,40],76:[2,40],77:[2,40],79:[2,40]},{50:45,52:[2,75],59:[2,75],66:[2,75],74:[2,75],75:[2,75],76:[2,75],77:[2,75]},{23:46,36:48,37:[1,50],41:49,42:[1,51],43:47,45:[2,47]},{26:52,41:53,42:[1,51],45:[2,49]},{16:[1,54]},{31:[2,79],55:55,59:[2,79],66:[2,79],74:[2,79],75:[2,79],76:[2,79],77:[2,79]},{31:[2,35],59:[2,35],66:[2,35],74:[2,35],75:[2,35],76:[2,35],77:[2,35]},{31:[2,36],59:[2,36],66:[2,36],74:[2,36],75:[2,36],76:[2,36],77:[2,36]},{18:56,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{28:57,31:[2,51],59:[2,51],66:[2,51],69:[2,51],74:[2,51],75:[2,51],76:[2,51],77:[2,51]},{31:[2,57],33:58,59:[2,57],66:[2,57],69:[2,57],74:[2,57],75:[2,57],76:[2,57],77:[2,57]},{19:59,21:[2,43],59:[2,43],66:[2,43],74:[2,43],75:[2,43],76:[2,43],77:[2,43]},{18:63,31:[2,73],48:60,57:61,58:64,59:[1,38],63:62,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{66:[1,68]},{21:[2,37],31:[2,37],52:[2,37],59:[2,37],62:[2,37],66:[2,37],69:[2,37],74:[2,37],75:[2,37],76:[2,37],77:[2,37],79:[1,43]},{18:63,51:69,52:[2,77],57:70,58:64,59:[1,38],63:71,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{24:72,45:[1,73]},{45:[2,48]},{4:74,6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],37:[2,41],42:[2,41],45:[2,41],46:[2,41],49:[2,41],53:[2,41]},{45:[2,19]},{18:75,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{4:76,6:3,13:[2,41],14:[2,41],17:[2,41],27:[2,41],32:[2,41],45:[2,41],46:[2,41],49:[2,41],53:[2,41]},{24:77,45:[1,73]},{45:[2,50]},{5:[2,10],13:[2,10],14:[2,10],17:[2,10],27:[2,10],32:[2,10],37:[2,10],42:[2,10],45:[2,10],46:[2,10],49:[2,10],53:[2,10]},{18:63,31:[2,81],56:78,57:79,58:64,59:[1,38],63:80,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{59:[2,83],60:81,62:[2,83],66:[2,83],74:[2,83],75:[2,83],76:[2,83],77:[2,83]},{18:63,29:82,31:[2,53],57:83,58:64,59:[1,38],63:84,64:65,65:66,66:[1,67],69:[2,53],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:63,31:[2,59],34:85,57:86,58:64,59:[1,38],63:87,64:65,65:66,66:[1,67],69:[2,59],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{18:63,20:88,21:[2,45],57:89,58:64,59:[1,38],63:90,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{31:[1,91]},{31:[2,72],59:[2,72],66:[2,72],74:[2,72],75:[2,72],76:[2,72],77:[2,72]},{31:[2,74]},{21:[2,24],31:[2,24],52:[2,24],59:[2,24],62:[2,24],66:[2,24],69:[2,24],74:[2,24],75:[2,24],76:[2,24],77:[2,24]},{21:[2,25],31:[2,25],52:[2,25],59:[2,25],62:[2,25],66:[2,25],69:[2,25],74:[2,25],75:[2,25],76:[2,25],77:[2,25]},{21:[2,27],31:[2,27],52:[2,27],62:[2,27],65:92,66:[1,93],69:[2,27]},{21:[2,87],31:[2,87],52:[2,87],62:[2,87],66:[2,87],69:[2,87]},{21:[2,40],31:[2,40],52:[2,40],59:[2,40],62:[2,40],66:[2,40],67:[1,94],69:[2,40],74:[2,40],75:[2,40],76:[2,40],77:[2,40],79:[2,40]},{21:[2,39],31:[2,39],52:[2,39],59:[2,39],62:[2,39],66:[2,39],69:[2,39],74:[2,39],75:[2,39],76:[2,39],77:[2,39],79:[2,39]},{52:[1,95]},{52:[2,76],59:[2,76],66:[2,76],74:[2,76],75:[2,76],76:[2,76],77:[2,76]},{52:[2,78]},{5:[2,12],13:[2,12],14:[2,12],17:[2,12],27:[2,12],32:[2,12],37:[2,12],42:[2,12],45:[2,12],46:[2,12],49:[2,12],53:[2,12]},{18:96,66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{36:48,37:[1,50],41:49,42:[1,51],43:98,44:97,45:[2,69]},{31:[2,63],38:99,59:[2,63],66:[2,63],69:[2,63],74:[2,63],75:[2,63],76:[2,63],77:[2,63]},{45:[2,17]},{5:[2,13],13:[2,13],14:[2,13],17:[2,13],27:[2,13],32:[2,13],37:[2,13],42:[2,13],45:[2,13],46:[2,13],49:[2,13],53:[2,13]},{31:[1,100]},{31:[2,80],59:[2,80],66:[2,80],74:[2,80],75:[2,80],76:[2,80],77:[2,80]},{31:[2,82]},{18:63,57:102,58:64,59:[1,38],61:101,62:[2,85],63:103,64:65,65:66,66:[1,67],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{30:104,31:[2,55],68:105,69:[1,106]},{31:[2,52],59:[2,52],66:[2,52],69:[2,52],74:[2,52],75:[2,52],76:[2,52],77:[2,52]},{31:[2,54],69:[2,54]},{31:[2,61],35:107,68:108,69:[1,106]},{31:[2,58],59:[2,58],66:[2,58],69:[2,58],74:[2,58],75:[2,58],76:[2,58],77:[2,58]},{31:[2,60],69:[2,60]},{21:[1,109]},{21:[2,44],59:[2,44],66:[2,44],74:[2,44],75:[2,44],76:[2,44],77:[2,44]},{21:[2,46]},{5:[2,21],13:[2,21],14:[2,21],17:[2,21],27:[2,21],32:[2,21],37:[2,21],42:[2,21],45:[2,21],46:[2,21],49:[2,21],53:[2,21]},{21:[2,88],31:[2,88],52:[2,88],62:[2,88],66:[2,88],69:[2,88]},{67:[1,94]},{18:63,57:110,58:64,59:[1,38],66:[1,30],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{5:[2,22],13:[2,22],14:[2,22],17:[2,22],27:[2,22],32:[2,22],37:[2,22],42:[2,22],45:[2,22],46:[2,22],49:[2,22],53:[2,22]},{31:[1,111]},{45:[2,18]},{45:[2,70]},{18:63,31:[2,65],39:112,57:113,58:64,59:[1,38],63:114,64:65,65:66,66:[1,67],69:[2,65],72:23,73:24,74:[1,25],75:[1,26],76:[1,27],77:[1,29],78:28},{5:[2,23],13:[2,23],14:[2,23],17:[2,23],27:[2,23],32:[2,23],37:[2,23],42:[2,23],45:[2,23],46:[2,23],49:[2,23],53:[2,23]},{62:[1,115]},{59:[2,84],62:[2,84],66:[2,84],74:[2,84],75:[2,84],76:[2,84],77:[2,84]},{62:[2,86]},{31:[1,116]},{31:[2,56]},{66:[1,118],70:117},{31:[1,119]},{31:[2,62]},{14:[2,11]},{21:[2,28],31:[2,28],52:[2,28],62:[2,28],66:[2,28],69:[2,28]},{5:[2,20],13:[2,20],14:[2,20],17:[2,20],27:[2,20],32:[2,20],37:[2,20],42:[2,20],45:[2,20],46:[2,20],49:[2,20],53:[2,20]},{31:[2,67],40:120,68:121,69:[1,106]},{31:[2,64],59:[2,64],66:[2,64],69:[2,64],74:[2,64],75:[2,64],76:[2,64],77:[2,64]},{31:[2,66],69:[2,66]},{21:[2,26],31:[2,26],52:[2,26],59:[2,26],62:[2,26],66:[2,26],69:[2,26],74:[2,26],75:[2,26],76:[2,26],77:[2,26]},{13:[2,14],14:[2,14],17:[2,14],27:[2,14],32:[2,14],37:[2,14],42:[2,14],45:[2,14],46:[2,14],49:[2,14],53:[2,14]},{66:[1,123],71:[1,122]},{66:[2,89],71:[2,89]},{13:[2,15],14:[2,15],17:[2,15],27:[2,15],32:[2,15],42:[2,15],45:[2,15],46:[2,15],49:[2,15],53:[2,15]},{31:[1,124]},{31:[2,68]},{31:[2,29]},{66:[2,90],71:[2,90]},{13:[2,16],14:[2,16],17:[2,16],27:[2,16],32:[2,16],37:[2,16],42:[2,16],45:[2,16],46:[2,16],49:[2,16],53:[2,16]}],
1027
+ defaultActions: {4:[2,1],47:[2,48],49:[2,19],53:[2,50],62:[2,74],71:[2,78],76:[2,17],80:[2,82],90:[2,46],97:[2,18],98:[2,70],103:[2,86],105:[2,56],108:[2,62],109:[2,11],121:[2,68],122:[2,29]},
986
1028
  parseError: function parseError(str, hash) {
987
1029
  throw new Error(str);
988
1030
  },
@@ -1279,100 +1321,114 @@ var __module9__ = (function() {
1279
1321
  } else {
1280
1322
  this.begin("mu");
1281
1323
  }
1282
- if(yy_.yytext) return 12;
1283
-
1324
+ if(yy_.yytext) return 14;
1325
+
1284
1326
  break;
1285
- case 1:return 12;
1327
+ case 1:return 14;
1286
1328
  break;
1287
1329
  case 2:
1288
1330
  this.popState();
1289
- return 12;
1290
-
1331
+ return 14;
1332
+
1291
1333
  break;
1292
1334
  case 3:
1293
1335
  yy_.yytext = yy_.yytext.substr(5, yy_.yyleng-9);
1294
1336
  this.popState();
1295
- return 15;
1296
-
1337
+ return 16;
1338
+
1297
1339
  break;
1298
- case 4: return 12;
1340
+ case 4: return 14;
1299
1341
  break;
1300
- case 5:strip(0,4); this.popState(); return 13;
1342
+ case 5:
1343
+ this.popState();
1344
+ return 13;
1345
+
1301
1346
  break;
1302
- case 6:return 45;
1347
+ case 6:return 59;
1303
1348
  break;
1304
- case 7:return 46;
1349
+ case 7:return 62;
1305
1350
  break;
1306
- case 8: return 16;
1351
+ case 8: return 17;
1307
1352
  break;
1308
1353
  case 9:
1309
1354
  this.popState();
1310
1355
  this.begin('raw');
1311
- return 18;
1312
-
1356
+ return 21;
1357
+
1313
1358
  break;
1314
- case 10:return 34;
1359
+ case 10:return 53;
1315
1360
  break;
1316
- case 11:return 24;
1361
+ case 11:return 27;
1317
1362
  break;
1318
- case 12:return 29;
1363
+ case 12:return 45;
1319
1364
  break;
1320
- case 13:this.popState(); return 28;
1365
+ case 13:this.popState(); return 42;
1321
1366
  break;
1322
- case 14:this.popState(); return 28;
1367
+ case 14:this.popState(); return 42;
1323
1368
  break;
1324
- case 15:return 26;
1369
+ case 15:return 32;
1325
1370
  break;
1326
- case 16:return 26;
1371
+ case 16:return 37;
1327
1372
  break;
1328
- case 17:return 32;
1373
+ case 17:return 49;
1329
1374
  break;
1330
- case 18:return 31;
1375
+ case 18:return 46;
1331
1376
  break;
1332
- case 19:this.popState(); this.begin('com');
1377
+ case 19:
1378
+ this.unput(yy_.yytext);
1379
+ this.popState();
1380
+ this.begin('com');
1381
+
1333
1382
  break;
1334
- case 20:strip(3,5); this.popState(); return 13;
1383
+ case 20:
1384
+ this.popState();
1385
+ return 13;
1386
+
1335
1387
  break;
1336
- case 21:return 31;
1388
+ case 21:return 46;
1337
1389
  break;
1338
- case 22:return 51;
1390
+ case 22:return 67;
1339
1391
  break;
1340
- case 23:return 50;
1392
+ case 23:return 66;
1341
1393
  break;
1342
- case 24:return 50;
1394
+ case 24:return 66;
1343
1395
  break;
1344
- case 25:return 54;
1396
+ case 25:return 79;
1345
1397
  break;
1346
1398
  case 26:// ignore whitespace
1347
1399
  break;
1348
- case 27:this.popState(); return 33;
1400
+ case 27:this.popState(); return 52;
1349
1401
  break;
1350
- case 28:this.popState(); return 25;
1402
+ case 28:this.popState(); return 31;
1351
1403
  break;
1352
- case 29:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 42;
1404
+ case 29:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 74;
1353
1405
  break;
1354
- case 30:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 42;
1406
+ case 30:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 74;
1355
1407
  break;
1356
- case 31:return 52;
1408
+ case 31:return 77;
1357
1409
  break;
1358
- case 32:return 44;
1410
+ case 32:return 76;
1359
1411
  break;
1360
- case 33:return 44;
1412
+ case 33:return 76;
1361
1413
  break;
1362
- case 34:return 43;
1414
+ case 34:return 75;
1363
1415
  break;
1364
- case 35:return 50;
1416
+ case 35:return 69;
1365
1417
  break;
1366
- case 36:yy_.yytext = strip(1,2); return 50;
1418
+ case 36:return 71;
1367
1419
  break;
1368
- case 37:return 'INVALID';
1420
+ case 37:return 66;
1369
1421
  break;
1370
- case 38:return 5;
1422
+ case 38:yy_.yytext = strip(1,2); return 66;
1423
+ break;
1424
+ case 39:return 'INVALID';
1425
+ break;
1426
+ case 40:return 5;
1371
1427
  break;
1372
1428
  }
1373
1429
  };
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}};
1430
+ 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)])))/,/^(?:as\s+\|)/,/^(?:\|)/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
1431
+ 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,39,40],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[5],"inclusive":false},"raw":{"rules":[3,4],"inclusive":false},"INITIAL":{"rules":[0,1,40],"inclusive":true}};
1376
1432
  return lexer;})()
1377
1433
  parser.lexer = lexer;
1378
1434
  function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
@@ -1382,175 +1438,327 @@ var __module9__ = (function() {
1382
1438
  return __exports__;
1383
1439
  })();
1384
1440
 
1385
- // handlebars/compiler/helpers.js
1386
- var __module10__ = (function(__dependency1__) {
1441
+ // handlebars/compiler/visitor.js
1442
+ var __module11__ = (function(__dependency1__, __dependency2__) {
1387
1443
  "use strict";
1388
- var __exports__ = {};
1444
+ var __exports__;
1389
1445
  var Exception = __dependency1__;
1446
+ var AST = __dependency2__;
1390
1447
 
1391
- function stripFlags(open, close) {
1392
- return {
1393
- left: open.charAt(2) === '~',
1394
- right: close.charAt(close.length-3) === '~'
1395
- };
1448
+ function Visitor() {
1449
+ this.parents = [];
1396
1450
  }
1397
1451
 
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,
1452
+ Visitor.prototype = {
1453
+ constructor: Visitor,
1454
+ mutating: false,
1455
+
1456
+ // Visits a given value. If mutating, will replace the value if necessary.
1457
+ acceptKey: function(node, name) {
1458
+ var value = this.accept(node[name]);
1459
+ if (this.mutating) {
1460
+ // Hacky sanity check:
1461
+ if (value && (!value.type || !AST[value.type])) {
1462
+ throw new Exception('Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type);
1463
+ }
1464
+ node[name] = value;
1465
+ }
1466
+ },
1410
1467
 
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
- };
1468
+ // Performs an accept operation with added sanity check to ensure
1469
+ // required keys are not removed.
1470
+ acceptRequired: function(node, name) {
1471
+ this.acceptKey(node, name);
1416
1472
 
1417
- if (mustache.strip.right) {
1418
- omitRight(program.statements, null, true);
1419
- }
1473
+ if (!node[name]) {
1474
+ throw new Exception(node.type + ' requires ' + name);
1475
+ }
1476
+ },
1420
1477
 
1421
- if (inverse) {
1422
- var inverseStrip = inverseAndProgram.strip;
1478
+ // Traverses a given array. If mutating, empty respnses will be removed
1479
+ // for child elements.
1480
+ acceptArray: function(array) {
1481
+ for (var i = 0, l = array.length; i < l; i++) {
1482
+ this.acceptKey(array, i);
1423
1483
 
1424
- if (inverseStrip.left) {
1425
- omitLeft(program.statements, null, true);
1484
+ if (!array[i]) {
1485
+ array.splice(i, 1);
1486
+ i--;
1487
+ l--;
1488
+ }
1426
1489
  }
1427
- if (inverseStrip.right) {
1428
- omitRight(inverse.statements, null, true);
1490
+ },
1491
+
1492
+ accept: function(object) {
1493
+ if (!object) {
1494
+ return;
1429
1495
  }
1430
- if (close.strip.left) {
1431
- omitLeft(inverse.statements, null, true);
1496
+
1497
+ if (this.current) {
1498
+ this.parents.unshift(this.current);
1432
1499
  }
1500
+ this.current = object;
1433
1501
 
1434
- // Find standalone else statments
1435
- if (isPrevWhitespace(program.statements)
1436
- && isNextWhitespace(inverse.statements)) {
1502
+ var ret = this[object.type](object);
1437
1503
 
1438
- omitLeft(program.statements);
1439
- omitRight(inverse.statements);
1440
- }
1441
- } else {
1442
- if (close.strip.left) {
1443
- omitLeft(program.statements, null, true);
1504
+ this.current = this.parents.shift();
1505
+
1506
+ if (!this.mutating || ret) {
1507
+ return ret;
1508
+ } else if (ret !== false) {
1509
+ return object;
1444
1510
  }
1445
- }
1511
+ },
1446
1512
 
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);
1513
+ Program: function(program) {
1514
+ this.acceptArray(program.body);
1515
+ },
1516
+
1517
+ MustacheStatement: function(mustache) {
1518
+ this.acceptRequired(mustache, 'path');
1519
+ this.acceptArray(mustache.params);
1520
+ this.acceptKey(mustache, 'hash');
1521
+ },
1522
+
1523
+ BlockStatement: function(block) {
1524
+ this.acceptRequired(block, 'path');
1525
+ this.acceptArray(block.params);
1526
+ this.acceptKey(block, 'hash');
1527
+
1528
+ this.acceptKey(block, 'program');
1529
+ this.acceptKey(block, 'inverse');
1530
+ },
1531
+
1532
+ PartialStatement: function(partial) {
1533
+ this.acceptRequired(partial, 'name');
1534
+ this.acceptArray(partial.params);
1535
+ this.acceptKey(partial, 'hash');
1536
+ },
1537
+
1538
+ ContentStatement: function(/* content */) {},
1539
+ CommentStatement: function(/* comment */) {},
1540
+
1541
+ SubExpression: function(sexpr) {
1542
+ this.acceptRequired(sexpr, 'path');
1543
+ this.acceptArray(sexpr.params);
1544
+ this.acceptKey(sexpr, 'hash');
1545
+ },
1546
+ PartialExpression: function(partial) {
1547
+ this.acceptRequired(partial, 'name');
1548
+ this.acceptArray(partial.params);
1549
+ this.acceptKey(partial, 'hash');
1550
+ },
1551
+
1552
+ PathExpression: function(/* path */) {},
1553
+
1554
+ StringLiteral: function(/* string */) {},
1555
+ NumberLiteral: function(/* number */) {},
1556
+ BooleanLiteral: function(/* bool */) {},
1557
+
1558
+ Hash: function(hash) {
1559
+ this.acceptArray(hash.pairs);
1560
+ },
1561
+ HashPair: function(pair) {
1562
+ this.acceptRequired(pair, 'value');
1451
1563
  }
1564
+ };
1565
+
1566
+ __exports__ = Visitor;
1567
+ return __exports__;
1568
+ })(__module4__, __module7__);
1569
+
1570
+ // handlebars/compiler/whitespace-control.js
1571
+ var __module10__ = (function(__dependency1__) {
1572
+ "use strict";
1573
+ var __exports__;
1574
+ var Visitor = __dependency1__;
1575
+
1576
+ function WhitespaceControl() {
1452
1577
  }
1578
+ WhitespaceControl.prototype = new Visitor();
1453
1579
 
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;
1580
+ WhitespaceControl.prototype.Program = function(program) {
1581
+ var isRoot = !this.isRootSeen;
1582
+ this.isRootSeen = true;
1583
+
1584
+ var body = program.body;
1585
+ for (var i = 0, l = body.length; i < l; i++) {
1586
+ var current = body[i],
1587
+ strip = this.accept(current);
1459
1588
 
1460
1589
  if (!strip) {
1461
1590
  continue;
1462
1591
  }
1463
1592
 
1464
- var _isPrevWhitespace = isPrevWhitespace(statements, i, isRoot, current.type === 'partial'),
1465
- _isNextWhitespace = isNextWhitespace(statements, i, isRoot),
1593
+ var _isPrevWhitespace = isPrevWhitespace(body, i, isRoot),
1594
+ _isNextWhitespace = isNextWhitespace(body, i, isRoot),
1466
1595
 
1467
1596
  openStandalone = strip.openStandalone && _isPrevWhitespace,
1468
1597
  closeStandalone = strip.closeStandalone && _isNextWhitespace,
1469
1598
  inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace;
1470
1599
 
1471
- if (strip.right) {
1472
- omitRight(statements, i, true);
1600
+ if (strip.close) {
1601
+ omitRight(body, i, true);
1473
1602
  }
1474
- if (strip.left) {
1475
- omitLeft(statements, i, true);
1603
+ if (strip.open) {
1604
+ omitLeft(body, i, true);
1476
1605
  }
1477
1606
 
1478
1607
  if (inlineStandalone) {
1479
- omitRight(statements, i);
1608
+ omitRight(body, i);
1480
1609
 
1481
- if (omitLeft(statements, i)) {
1610
+ if (omitLeft(body, i)) {
1482
1611
  // 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 : '';
1612
+ if (current.type === 'PartialStatement') {
1613
+ // Pull out the whitespace from the final line
1614
+ current.indent = (/([ \t]+$)/).exec(body[i-1].original)[1];
1485
1615
  }
1486
1616
  }
1487
1617
  }
1488
1618
  if (openStandalone) {
1489
- omitRight((current.program || current.inverse).statements);
1619
+ omitRight((current.program || current.inverse).body);
1490
1620
 
1491
1621
  // Strip out the previous content node if it's whitespace only
1492
- omitLeft(statements, i);
1622
+ omitLeft(body, i);
1493
1623
  }
1494
1624
  if (closeStandalone) {
1495
1625
  // Always strip the next node
1496
- omitRight(statements, i);
1626
+ omitRight(body, i);
1497
1627
 
1498
- omitLeft((current.inverse || current.program).statements);
1628
+ omitLeft((current.inverse || current.program).body);
1499
1629
  }
1500
1630
  }
1501
1631
 
1502
- return statements;
1503
- }
1632
+ return program;
1633
+ };
1634
+ WhitespaceControl.prototype.BlockStatement = function(block) {
1635
+ this.accept(block.program);
1636
+ this.accept(block.inverse);
1504
1637
 
1505
- __exports__.prepareProgram = prepareProgram;function isPrevWhitespace(statements, i, isRoot) {
1506
- if (i === undefined) {
1507
- i = statements.length;
1508
- }
1638
+ // Find the inverse program that is involed with whitespace stripping.
1639
+ var program = block.program || block.inverse,
1640
+ inverse = block.program && block.inverse,
1641
+ firstInverse = inverse,
1642
+ lastInverse = inverse;
1509
1643
 
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
- }
1644
+ if (inverse && inverse.chained) {
1645
+ firstInverse = inverse.body[0].program;
1517
1646
 
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;
1647
+ // Walk the inverse chain to find the last inverse that is actually in the chain.
1648
+ while (lastInverse.chained) {
1649
+ lastInverse = lastInverse.body[lastInverse.body.length-1].program;
1650
+ }
1525
1651
  }
1526
1652
 
1527
- var next = statements[i+1],
1528
- sibling = statements[i+2];
1529
- if (!next) {
1530
- return isRoot;
1531
- }
1653
+ var strip = {
1654
+ open: block.openStrip.open,
1655
+ close: block.closeStrip.close,
1532
1656
 
1533
- if (next.type === 'content') {
1534
- return (sibling || !isRoot ? (/^\s*?\r?\n/) : (/^\s*?(\r?\n|$)/)).test(next.original);
1657
+ // Determine the standalone candiacy. Basically flag our content as being possibly standalone
1658
+ // so our parent can determine if we actually are standalone
1659
+ openStandalone: isNextWhitespace(program.body),
1660
+ closeStandalone: isPrevWhitespace((firstInverse || program).body)
1661
+ };
1662
+
1663
+ if (block.openStrip.close) {
1664
+ omitRight(program.body, null, true);
1535
1665
  }
1536
- }
1537
1666
 
1538
- // Marks the node to the right of the position as omitted.
1539
- // I.e. {{foo}}' ' will mark the ' ' node as omitted.
1540
- //
1667
+ if (inverse) {
1668
+ var inverseStrip = block.inverseStrip;
1669
+
1670
+ if (inverseStrip.open) {
1671
+ omitLeft(program.body, null, true);
1672
+ }
1673
+
1674
+ if (inverseStrip.close) {
1675
+ omitRight(firstInverse.body, null, true);
1676
+ }
1677
+ if (block.closeStrip.open) {
1678
+ omitLeft(lastInverse.body, null, true);
1679
+ }
1680
+
1681
+ // Find standalone else statments
1682
+ if (isPrevWhitespace(program.body)
1683
+ && isNextWhitespace(firstInverse.body)) {
1684
+
1685
+ omitLeft(program.body);
1686
+ omitRight(firstInverse.body);
1687
+ }
1688
+ } else {
1689
+ if (block.closeStrip.open) {
1690
+ omitLeft(program.body, null, true);
1691
+ }
1692
+ }
1693
+
1694
+ return strip;
1695
+ };
1696
+
1697
+ WhitespaceControl.prototype.MustacheStatement = function(mustache) {
1698
+ return mustache.strip;
1699
+ };
1700
+
1701
+ WhitespaceControl.prototype.PartialStatement =
1702
+ WhitespaceControl.prototype.CommentStatement = function(node) {
1703
+ /* istanbul ignore next */
1704
+ var strip = node.strip || {};
1705
+ return {
1706
+ inlineStandalone: true,
1707
+ open: strip.open,
1708
+ close: strip.close
1709
+ };
1710
+ };
1711
+
1712
+
1713
+ function isPrevWhitespace(body, i, isRoot) {
1714
+ if (i === undefined) {
1715
+ i = body.length;
1716
+ }
1717
+
1718
+ // Nodes that end with newlines are considered whitespace (but are special
1719
+ // cased for strip operations)
1720
+ var prev = body[i-1],
1721
+ sibling = body[i-2];
1722
+ if (!prev) {
1723
+ return isRoot;
1724
+ }
1725
+
1726
+ if (prev.type === 'ContentStatement') {
1727
+ return (sibling || !isRoot ? (/\r?\n\s*?$/) : (/(^|\r?\n)\s*?$/)).test(prev.original);
1728
+ }
1729
+ }
1730
+ function isNextWhitespace(body, i, isRoot) {
1731
+ if (i === undefined) {
1732
+ i = -1;
1733
+ }
1734
+
1735
+ var next = body[i+1],
1736
+ sibling = body[i+2];
1737
+ if (!next) {
1738
+ return isRoot;
1739
+ }
1740
+
1741
+ if (next.type === 'ContentStatement') {
1742
+ return (sibling || !isRoot ? (/^\s*?\r?\n/) : (/^\s*?(\r?\n|$)/)).test(next.original);
1743
+ }
1744
+ }
1745
+
1746
+ // Marks the node to the right of the position as omitted.
1747
+ // I.e. {{foo}}' ' will mark the ' ' node as omitted.
1748
+ //
1541
1749
  // If i is undefined, then the first child will be marked as such.
1542
1750
  //
1543
1751
  // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
1544
1752
  // 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)) {
1753
+ function omitRight(body, i, multiple) {
1754
+ var current = body[i == null ? 0 : i + 1];
1755
+ if (!current || current.type !== 'ContentStatement' || (!multiple && current.rightStripped)) {
1548
1756
  return;
1549
1757
  }
1550
1758
 
1551
- var original = current.string;
1552
- current.string = current.string.replace(multiple ? (/^\s+/) : (/^[ \t]*\r?\n?/), '');
1553
- current.rightStripped = current.string !== original;
1759
+ var original = current.value;
1760
+ current.value = current.value.replace(multiple ? (/^\s+/) : (/^[ \t]*\r?\n?/), '');
1761
+ current.rightStripped = current.value !== original;
1554
1762
  }
1555
1763
 
1556
1764
  // Marks the node to the left of the position as omitted.
@@ -1560,57 +1768,194 @@ var __module10__ = (function(__dependency1__) {
1560
1768
  //
1561
1769
  // If mulitple is truthy then all whitespace will be stripped out until non-whitespace
1562
1770
  // 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)) {
1771
+ function omitLeft(body, i, multiple) {
1772
+ var current = body[i == null ? body.length - 1 : i - 1];
1773
+ if (!current || current.type !== 'ContentStatement' || (!multiple && current.leftStripped)) {
1566
1774
  return;
1567
1775
  }
1568
1776
 
1569
1777
  // 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;
1778
+ var original = current.value;
1779
+ current.value = current.value.replace(multiple ? (/\s+$/) : (/[ \t]+$/), '');
1780
+ current.leftStripped = current.value !== original;
1573
1781
  return current.leftStripped;
1574
1782
  }
1783
+
1784
+ __exports__ = WhitespaceControl;
1785
+ return __exports__;
1786
+ })(__module11__);
1787
+
1788
+ // handlebars/compiler/helpers.js
1789
+ var __module12__ = (function(__dependency1__) {
1790
+ "use strict";
1791
+ var __exports__ = {};
1792
+ var Exception = __dependency1__;
1793
+
1794
+ function SourceLocation(source, locInfo) {
1795
+ this.source = source;
1796
+ this.start = {
1797
+ line: locInfo.first_line,
1798
+ column: locInfo.first_column
1799
+ };
1800
+ this.end = {
1801
+ line: locInfo.last_line,
1802
+ column: locInfo.last_column
1803
+ };
1804
+ }
1805
+
1806
+ __exports__.SourceLocation = SourceLocation;function stripFlags(open, close) {
1807
+ return {
1808
+ open: open.charAt(2) === '~',
1809
+ close: close.charAt(close.length-3) === '~'
1810
+ };
1811
+ }
1812
+
1813
+ __exports__.stripFlags = stripFlags;function stripComment(comment) {
1814
+ return comment.replace(/^\{\{~?\!-?-?/, '')
1815
+ .replace(/-?-?~?\}\}$/, '');
1816
+ }
1817
+
1818
+ __exports__.stripComment = stripComment;function preparePath(data, parts, locInfo) {
1819
+ /*jshint -W040 */
1820
+ locInfo = this.locInfo(locInfo);
1821
+
1822
+ var original = data ? '@' : '',
1823
+ dig = [],
1824
+ depth = 0,
1825
+ depthString = '';
1826
+
1827
+ for(var i=0,l=parts.length; i<l; i++) {
1828
+ var part = parts[i].part;
1829
+ original += (parts[i].separator || '') + part;
1830
+
1831
+ if (part === '..' || part === '.' || part === 'this') {
1832
+ if (dig.length > 0) {
1833
+ throw new Exception('Invalid path: ' + original, {loc: locInfo});
1834
+ } else if (part === '..') {
1835
+ depth++;
1836
+ depthString += '../';
1837
+ }
1838
+ } else {
1839
+ dig.push(part);
1840
+ }
1841
+ }
1842
+
1843
+ return new this.PathExpression(data, depth, dig, original, locInfo);
1844
+ }
1845
+
1846
+ __exports__.preparePath = preparePath;function prepareMustache(path, params, hash, open, strip, locInfo) {
1847
+ /*jshint -W040 */
1848
+ // Must use charAt to support IE pre-10
1849
+ var escapeFlag = open.charAt(3) || open.charAt(2),
1850
+ escaped = escapeFlag !== '{' && escapeFlag !== '&';
1851
+
1852
+ return new this.MustacheStatement(path, params, hash, escaped, strip, this.locInfo(locInfo));
1853
+ }
1854
+
1855
+ __exports__.prepareMustache = prepareMustache;function prepareRawBlock(openRawBlock, content, close, locInfo) {
1856
+ /*jshint -W040 */
1857
+ if (openRawBlock.path.original !== close) {
1858
+ var errorNode = {loc: openRawBlock.path.loc};
1859
+
1860
+ throw new Exception(openRawBlock.path.original + " doesn't match " + close, errorNode);
1861
+ }
1862
+
1863
+ locInfo = this.locInfo(locInfo);
1864
+ var program = new this.Program([content], null, {}, locInfo);
1865
+
1866
+ return new this.BlockStatement(
1867
+ openRawBlock.path, openRawBlock.params, openRawBlock.hash,
1868
+ program, undefined,
1869
+ {}, {}, {},
1870
+ locInfo);
1871
+ }
1872
+
1873
+ __exports__.prepareRawBlock = prepareRawBlock;function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) {
1874
+ /*jshint -W040 */
1875
+ // When we are chaining inverse calls, we will not have a close path
1876
+ if (close && close.path && openBlock.path.original !== close.path.original) {
1877
+ var errorNode = {loc: openBlock.path.loc};
1878
+
1879
+ throw new Exception(openBlock.path.original + ' doesn\'t match ' + close.path.original, errorNode);
1880
+ }
1881
+
1882
+ program.blockParams = openBlock.blockParams;
1883
+
1884
+ var inverse,
1885
+ inverseStrip;
1886
+
1887
+ if (inverseAndProgram) {
1888
+ if (inverseAndProgram.chain) {
1889
+ inverseAndProgram.program.body[0].closeStrip = close.strip;
1890
+ }
1891
+
1892
+ inverseStrip = inverseAndProgram.strip;
1893
+ inverse = inverseAndProgram.program;
1894
+ }
1895
+
1896
+ if (inverted) {
1897
+ inverted = inverse;
1898
+ inverse = program;
1899
+ program = inverted;
1900
+ }
1901
+
1902
+ return new this.BlockStatement(
1903
+ openBlock.path, openBlock.params, openBlock.hash,
1904
+ program, inverse,
1905
+ openBlock.strip, inverseStrip, close && close.strip,
1906
+ this.locInfo(locInfo));
1907
+ }
1908
+
1909
+ __exports__.prepareBlock = prepareBlock;
1575
1910
  return __exports__;
1576
- })(__module5__);
1911
+ })(__module4__);
1577
1912
 
1578
1913
  // handlebars/compiler/base.js
1579
- var __module8__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__) {
1914
+ var __module8__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
1580
1915
  "use strict";
1581
1916
  var __exports__ = {};
1582
1917
  var parser = __dependency1__;
1583
1918
  var AST = __dependency2__;
1584
- var Helpers = __dependency3__;
1585
- var extend = __dependency4__.extend;
1919
+ var WhitespaceControl = __dependency3__;
1920
+ var Helpers = __dependency4__;
1921
+ var extend = __dependency5__.extend;
1586
1922
 
1587
1923
  __exports__.parser = parser;
1588
1924
 
1589
1925
  var yy = {};
1590
1926
  extend(yy, Helpers, AST);
1591
1927
 
1592
- function parse(input) {
1593
- // Just return if an already-compile AST was passed in.
1594
- if (input.constructor === AST.ProgramNode) { return input; }
1928
+ function parse(input, options) {
1929
+ // Just return if an already-compiled AST was passed in.
1930
+ if (input.type === 'Program') { return input; }
1595
1931
 
1596
1932
  parser.yy = yy;
1597
1933
 
1598
- return parser.parse(input);
1934
+ // Altering the shared object here, but this is ok as parser is a sync operation
1935
+ yy.locInfo = function(locInfo) {
1936
+ return new yy.SourceLocation(options && options.srcName, locInfo);
1937
+ };
1938
+
1939
+ var strip = new WhitespaceControl();
1940
+ return strip.accept(parser.parse(input));
1599
1941
  }
1600
1942
 
1601
1943
  __exports__.parse = parse;
1602
1944
  return __exports__;
1603
- })(__module9__, __module7__, __module10__, __module3__);
1945
+ })(__module9__, __module7__, __module10__, __module12__, __module3__);
1604
1946
 
1605
1947
  // handlebars/compiler/compiler.js
1606
- var __module11__ = (function(__dependency1__, __dependency2__) {
1948
+ var __module13__ = (function(__dependency1__, __dependency2__, __dependency3__) {
1607
1949
  "use strict";
1608
1950
  var __exports__ = {};
1609
1951
  var Exception = __dependency1__;
1610
1952
  var isArray = __dependency2__.isArray;
1953
+ var indexOf = __dependency2__.indexOf;
1954
+ var AST = __dependency3__;
1611
1955
 
1612
1956
  var slice = [].slice;
1613
1957
 
1958
+
1614
1959
  function Compiler() {}
1615
1960
 
1616
1961
  __exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
@@ -1650,16 +1995,18 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
1650
1995
  guid: 0,
1651
1996
 
1652
1997
  compile: function(program, options) {
1998
+ this.sourceNode = [];
1653
1999
  this.opcodes = [];
1654
2000
  this.children = [];
1655
- this.depths = {list: []};
1656
2001
  this.options = options;
1657
2002
  this.stringParams = options.stringParams;
1658
2003
  this.trackIds = options.trackIds;
1659
2004
 
2005
+ options.blockParams = options.blockParams || [];
2006
+
1660
2007
  // These changes will propagate to the other compiler components
1661
- var knownHelpers = this.options.knownHelpers;
1662
- this.options.knownHelpers = {
2008
+ var knownHelpers = options.knownHelpers;
2009
+ options.knownHelpers = {
1663
2010
  'helperMissing': true,
1664
2011
  'blockHelperMissing': true,
1665
2012
  'each': true,
@@ -1671,79 +2018,72 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
1671
2018
  };
1672
2019
  if (knownHelpers) {
1673
2020
  for (var name in knownHelpers) {
1674
- this.options.knownHelpers[name] = knownHelpers[name];
2021
+ options.knownHelpers[name] = knownHelpers[name];
1675
2022
  }
1676
2023
  }
1677
2024
 
1678
2025
  return this.accept(program);
1679
2026
  },
1680
2027
 
1681
- accept: function(node) {
1682
- return this[node.type](node);
1683
- },
1684
-
1685
- program: function(program) {
1686
- var statements = program.statements;
1687
-
1688
- for(var i=0, l=statements.length; i<l; i++) {
1689
- this.accept(statements[i]);
1690
- }
1691
- this.isSimple = l === 1;
1692
-
1693
- this.depths.list = this.depths.list.sort(function(a, b) {
1694
- return a - b;
1695
- });
1696
-
1697
- return this;
1698
- },
1699
-
1700
2028
  compileProgram: function(program) {
1701
2029
  var result = new this.compiler().compile(program, this.options);
1702
- var guid = this.guid++, depth;
2030
+ var guid = this.guid++;
1703
2031
 
1704
2032
  this.usePartial = this.usePartial || result.usePartial;
1705
2033
 
1706
2034
  this.children[guid] = result;
2035
+ this.useDepths = this.useDepths || result.useDepths;
2036
+
2037
+ return guid;
2038
+ },
1707
2039
 
1708
- for(var i=0, l=result.depths.list.length; i<l; i++) {
1709
- depth = result.depths.list[i];
2040
+ accept: function(node) {
2041
+ this.sourceNode.unshift(node);
2042
+ var ret = this[node.type](node);
2043
+ this.sourceNode.shift();
2044
+ return ret;
2045
+ },
1710
2046
 
1711
- if(depth < 2) { continue; }
1712
- else { this.addDepth(depth - 1); }
2047
+ Program: function(program) {
2048
+ this.options.blockParams.unshift(program.blockParams);
2049
+
2050
+ var body = program.body;
2051
+ for(var i=0, l=body.length; i<l; i++) {
2052
+ this.accept(body[i]);
1713
2053
  }
1714
2054
 
1715
- return guid;
2055
+ this.options.blockParams.shift();
2056
+
2057
+ this.isSimple = l === 1;
2058
+ this.blockParams = program.blockParams ? program.blockParams.length : 0;
2059
+
2060
+ return this;
1716
2061
  },
1717
2062
 
1718
- block: function(block) {
1719
- var mustache = block.mustache,
1720
- program = block.program,
2063
+ BlockStatement: function(block) {
2064
+ transformLiteralToPath(block);
2065
+
2066
+ var program = block.program,
1721
2067
  inverse = block.inverse;
1722
2068
 
1723
- if (program) {
1724
- program = this.compileProgram(program);
1725
- }
2069
+ program = program && this.compileProgram(program);
2070
+ inverse = inverse && this.compileProgram(inverse);
1726
2071
 
1727
- if (inverse) {
1728
- inverse = this.compileProgram(inverse);
1729
- }
2072
+ var type = this.classifySexpr(block);
1730
2073
 
1731
- var sexpr = mustache.sexpr;
1732
- var type = this.classifySexpr(sexpr);
1733
-
1734
- if (type === "helper") {
1735
- this.helperSexpr(sexpr, program, inverse);
1736
- } else if (type === "simple") {
1737
- this.simpleSexpr(sexpr);
2074
+ if (type === 'helper') {
2075
+ this.helperSexpr(block, program, inverse);
2076
+ } else if (type === 'simple') {
2077
+ this.simpleSexpr(block);
1738
2078
 
1739
2079
  // now that the simple mustache is resolved, we need to
1740
2080
  // evaluate it by executing `blockHelperMissing`
1741
2081
  this.opcode('pushProgram', program);
1742
2082
  this.opcode('pushProgram', inverse);
1743
2083
  this.opcode('emptyHash');
1744
- this.opcode('blockValue', sexpr.id.original);
2084
+ this.opcode('blockValue', block.path.original);
1745
2085
  } else {
1746
- this.ambiguousSexpr(sexpr, program, inverse);
2086
+ this.ambiguousSexpr(block, program, inverse);
1747
2087
 
1748
2088
  // now that the simple mustache is resolved, we need to
1749
2089
  // evaluate it by executing `blockHelperMissing`
@@ -1756,49 +2096,36 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
1756
2096
  this.opcode('append');
1757
2097
  },
1758
2098
 
1759
- hash: function(hash) {
1760
- var pairs = hash.pairs, i, l;
1761
-
1762
- this.opcode('pushHash');
1763
-
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]);
1769
- }
1770
- this.opcode('popHash');
1771
- },
1772
-
1773
- partial: function(partial) {
1774
- var partialName = partial.partialName;
2099
+ PartialStatement: function(partial) {
1775
2100
  this.usePartial = true;
1776
2101
 
1777
- if (partial.hash) {
1778
- this.accept(partial.hash);
1779
- } else {
1780
- this.opcode('push', 'undefined');
2102
+ var params = partial.params;
2103
+ if (params.length > 1) {
2104
+ throw new Exception('Unsupported number of partial arguments: ' + params.length, partial);
2105
+ } else if (!params.length) {
2106
+ params.push({type: 'PathExpression', parts: [], depth: 0});
1781
2107
  }
1782
2108
 
1783
- if (partial.context) {
1784
- this.accept(partial.context);
1785
- } else {
1786
- this.opcode('getContext', 0);
1787
- this.opcode('pushContext');
2109
+ var partialName = partial.name.original,
2110
+ isDynamic = partial.name.type === 'SubExpression';
2111
+ if (isDynamic) {
2112
+ this.accept(partial.name);
1788
2113
  }
1789
2114
 
1790
- this.opcode('invokePartial', partialName.name, partial.indent || '');
1791
- this.opcode('append');
1792
- },
2115
+ this.setupFullMustacheParams(partial, undefined, undefined, true);
1793
2116
 
1794
- content: function(content) {
1795
- if (content.string) {
1796
- this.opcode('appendContent', content.string);
2117
+ var indent = partial.indent || '';
2118
+ if (this.options.preventIndent && indent) {
2119
+ this.opcode('appendContent', indent);
2120
+ indent = '';
1797
2121
  }
2122
+
2123
+ this.opcode('invokePartial', isDynamic, partialName, indent);
2124
+ this.opcode('append');
1798
2125
  },
1799
2126
 
1800
- mustache: function(mustache) {
1801
- this.sexpr(mustache.sexpr);
2127
+ MustacheStatement: function(mustache) {
2128
+ this.SubExpression(mustache);
1802
2129
 
1803
2130
  if(mustache.escaped && !this.options.noEscape) {
1804
2131
  this.opcode('appendEscaped');
@@ -1807,122 +2134,143 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
1807
2134
  }
1808
2135
  },
1809
2136
 
2137
+ ContentStatement: function(content) {
2138
+ if (content.value) {
2139
+ this.opcode('appendContent', content.value);
2140
+ }
2141
+ },
2142
+
2143
+ CommentStatement: function() {},
2144
+
2145
+ SubExpression: function(sexpr) {
2146
+ transformLiteralToPath(sexpr);
2147
+ var type = this.classifySexpr(sexpr);
2148
+
2149
+ if (type === 'simple') {
2150
+ this.simpleSexpr(sexpr);
2151
+ } else if (type === 'helper') {
2152
+ this.helperSexpr(sexpr);
2153
+ } else {
2154
+ this.ambiguousSexpr(sexpr);
2155
+ }
2156
+ },
1810
2157
  ambiguousSexpr: function(sexpr, program, inverse) {
1811
- var id = sexpr.id,
1812
- name = id.parts[0],
2158
+ var path = sexpr.path,
2159
+ name = path.parts[0],
1813
2160
  isBlock = program != null || inverse != null;
1814
2161
 
1815
- this.opcode('getContext', id.depth);
2162
+ this.opcode('getContext', path.depth);
1816
2163
 
1817
2164
  this.opcode('pushProgram', program);
1818
2165
  this.opcode('pushProgram', inverse);
1819
2166
 
1820
- this.ID(id);
2167
+ this.accept(path);
1821
2168
 
1822
2169
  this.opcode('invokeAmbiguous', name, isBlock);
1823
2170
  },
1824
2171
 
1825
2172
  simpleSexpr: function(sexpr) {
1826
- var id = sexpr.id;
1827
-
1828
- if (id.type === 'DATA') {
1829
- this.DATA(id);
1830
- } else if (id.parts.length) {
1831
- this.ID(id);
1832
- } else {
1833
- // Simplified ID for `this`
1834
- this.addDepth(id.depth);
1835
- this.opcode('getContext', id.depth);
1836
- this.opcode('pushContext');
1837
- }
1838
-
2173
+ this.accept(sexpr.path);
1839
2174
  this.opcode('resolvePossibleLambda');
1840
2175
  },
1841
2176
 
1842
2177
  helperSexpr: function(sexpr, program, inverse) {
1843
2178
  var params = this.setupFullMustacheParams(sexpr, program, inverse),
1844
- id = sexpr.id,
1845
- name = id.parts[0];
2179
+ path = sexpr.path,
2180
+ name = path.parts[0];
1846
2181
 
1847
2182
  if (this.options.knownHelpers[name]) {
1848
2183
  this.opcode('invokeKnownHelper', params.length, name);
1849
2184
  } else if (this.options.knownHelpersOnly) {
1850
2185
  throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
1851
2186
  } else {
1852
- id.falsy = true;
2187
+ path.falsy = true;
1853
2188
 
1854
- this.ID(id);
1855
- this.opcode('invokeHelper', params.length, id.original, id.isSimple);
2189
+ this.accept(path);
2190
+ this.opcode('invokeHelper', params.length, path.original, AST.helpers.simpleId(path));
1856
2191
  }
1857
2192
  },
1858
2193
 
1859
- sexpr: function(sexpr) {
1860
- var type = this.classifySexpr(sexpr);
1861
-
1862
- if (type === "simple") {
1863
- this.simpleSexpr(sexpr);
1864
- } else if (type === "helper") {
1865
- this.helperSexpr(sexpr);
1866
- } else {
1867
- this.ambiguousSexpr(sexpr);
1868
- }
1869
- },
2194
+ PathExpression: function(path) {
2195
+ this.addDepth(path.depth);
2196
+ this.opcode('getContext', path.depth);
1870
2197
 
1871
- ID: function(id) {
1872
- this.addDepth(id.depth);
1873
- this.opcode('getContext', id.depth);
2198
+ var name = path.parts[0],
2199
+ scoped = AST.helpers.scopedId(path),
2200
+ blockParamId = !path.depth && !scoped && this.blockParamIndex(name);
1874
2201
 
1875
- var name = id.parts[0];
1876
- if (!name) {
2202
+ if (blockParamId) {
2203
+ this.opcode('lookupBlockParam', blockParamId, path.parts);
2204
+ } else if (!name) {
1877
2205
  // Context reference, i.e. `{{foo .}}` or `{{foo ..}}`
1878
2206
  this.opcode('pushContext');
2207
+ } else if (path.data) {
2208
+ this.options.data = true;
2209
+ this.opcode('lookupData', path.depth, path.parts);
1879
2210
  } else {
1880
- this.opcode('lookupOnContext', id.parts, id.falsy, id.isScoped);
2211
+ this.opcode('lookupOnContext', path.parts, path.falsy, scoped);
1881
2212
  }
1882
2213
  },
1883
2214
 
1884
- DATA: function(data) {
1885
- this.options.data = true;
1886
- this.opcode('lookupData', data.id.depth, data.id.parts);
2215
+ StringLiteral: function(string) {
2216
+ this.opcode('pushString', string.value);
1887
2217
  },
1888
2218
 
1889
- STRING: function(string) {
1890
- this.opcode('pushString', string.string);
2219
+ NumberLiteral: function(number) {
2220
+ this.opcode('pushLiteral', number.value);
1891
2221
  },
1892
2222
 
1893
- NUMBER: function(number) {
1894
- this.opcode('pushLiteral', number.number);
2223
+ BooleanLiteral: function(bool) {
2224
+ this.opcode('pushLiteral', bool.value);
1895
2225
  },
1896
2226
 
1897
- BOOLEAN: function(bool) {
1898
- this.opcode('pushLiteral', bool.bool);
1899
- },
2227
+ Hash: function(hash) {
2228
+ var pairs = hash.pairs, i, l;
1900
2229
 
1901
- comment: function() {},
2230
+ this.opcode('pushHash');
2231
+
2232
+ for (i=0, l=pairs.length; i<l; i++) {
2233
+ this.pushParam(pairs[i].value);
2234
+ }
2235
+ while (i--) {
2236
+ this.opcode('assignToHash', pairs[i].key);
2237
+ }
2238
+ this.opcode('popHash');
2239
+ },
1902
2240
 
1903
2241
  // HELPERS
1904
2242
  opcode: function(name) {
1905
- this.opcodes.push({ opcode: name, args: slice.call(arguments, 1) });
2243
+ this.opcodes.push({ opcode: name, args: slice.call(arguments, 1), loc: this.sourceNode[0].loc });
1906
2244
  },
1907
2245
 
1908
2246
  addDepth: function(depth) {
1909
- if(depth === 0) { return; }
1910
-
1911
- if(!this.depths[depth]) {
1912
- this.depths[depth] = true;
1913
- this.depths.list.push(depth);
2247
+ if (!depth) {
2248
+ return;
1914
2249
  }
2250
+
2251
+ this.useDepths = true;
1915
2252
  },
1916
2253
 
1917
2254
  classifySexpr: function(sexpr) {
1918
- var isHelper = sexpr.isHelper;
1919
- var isEligible = sexpr.eligibleHelper;
1920
- var options = this.options;
2255
+ var isSimple = AST.helpers.simpleId(sexpr.path);
2256
+
2257
+ var isBlockParam = isSimple && !!this.blockParamIndex(sexpr.path.parts[0]);
2258
+
2259
+ // a mustache is an eligible helper if:
2260
+ // * its id is simple (a single part, not `this` or `..`)
2261
+ var isHelper = !isBlockParam && AST.helpers.helperExpression(sexpr);
2262
+
2263
+ // if a mustache is an eligible helper but not a definite
2264
+ // helper, it is ambiguous, and will be resolved in a later
2265
+ // pass or at runtime.
2266
+ var isEligible = !isBlockParam && (isHelper || isSimple);
2267
+
2268
+ var options = this.options;
1921
2269
 
1922
2270
  // if ambiguous, we can possibly resolve the ambiguity now
1923
2271
  // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc.
1924
2272
  if (isEligible && !isHelper) {
1925
- var name = sexpr.id.parts[0];
2273
+ var name = sexpr.path.parts[0];
1926
2274
 
1927
2275
  if (options.knownHelpers[name]) {
1928
2276
  isHelper = true;
@@ -1931,9 +2279,9 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
1931
2279
  }
1932
2280
  }
1933
2281
 
1934
- if (isHelper) { return "helper"; }
1935
- else if (isEligible) { return "ambiguous"; }
1936
- else { return "simple"; }
2282
+ if (isHelper) { return 'helper'; }
2283
+ else if (isEligible) { return 'ambiguous'; }
2284
+ else { return 'simple'; }
1937
2285
  },
1938
2286
 
1939
2287
  pushParams: function(params) {
@@ -1943,27 +2291,51 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
1943
2291
  },
1944
2292
 
1945
2293
  pushParam: function(val) {
2294
+ var value = val.value != null ? val.value : val.original || '';
2295
+
1946
2296
  if (this.stringParams) {
2297
+ if (value.replace) {
2298
+ value = value
2299
+ .replace(/^(\.?\.\/)*/g, '')
2300
+ .replace(/\//g, '.');
2301
+ }
2302
+
1947
2303
  if(val.depth) {
1948
2304
  this.addDepth(val.depth);
1949
2305
  }
1950
2306
  this.opcode('getContext', val.depth || 0);
1951
- this.opcode('pushStringParam', val.stringModeValue, val.type);
2307
+ this.opcode('pushStringParam', value, val.type);
1952
2308
 
1953
- if (val.type === 'sexpr') {
1954
- // Subexpressions get evaluated and passed in
2309
+ if (val.type === 'SubExpression') {
2310
+ // SubExpressions get evaluated and passed in
1955
2311
  // in string params mode.
1956
- this.sexpr(val);
2312
+ this.accept(val);
1957
2313
  }
1958
2314
  } else {
1959
2315
  if (this.trackIds) {
1960
- this.opcode('pushId', val.type, val.idName || val.stringModeValue);
2316
+ var blockParamIndex;
2317
+ if (val.parts && !AST.helpers.scopedId(val) && !val.depth) {
2318
+ blockParamIndex = this.blockParamIndex(val.parts[0]);
2319
+ }
2320
+ if (blockParamIndex) {
2321
+ var blockParamChild = val.parts.slice(1).join('.');
2322
+ this.opcode('pushId', 'BlockParam', blockParamIndex, blockParamChild);
2323
+ } else {
2324
+ value = val.original || value;
2325
+ if (value.replace) {
2326
+ value = value
2327
+ .replace(/^\.\//g, '')
2328
+ .replace(/^\.$/g, '');
2329
+ }
2330
+
2331
+ this.opcode('pushId', val.type, value);
2332
+ }
1961
2333
  }
1962
2334
  this.accept(val);
1963
2335
  }
1964
2336
  },
1965
2337
 
1966
- setupFullMustacheParams: function(sexpr, program, inverse) {
2338
+ setupFullMustacheParams: function(sexpr, program, inverse, omitEmpty) {
1967
2339
  var params = sexpr.params;
1968
2340
  this.pushParams(params);
1969
2341
 
@@ -1971,17 +2343,27 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
1971
2343
  this.opcode('pushProgram', inverse);
1972
2344
 
1973
2345
  if (sexpr.hash) {
1974
- this.hash(sexpr.hash);
2346
+ this.accept(sexpr.hash);
1975
2347
  } else {
1976
- this.opcode('emptyHash');
2348
+ this.opcode('emptyHash', omitEmpty);
1977
2349
  }
1978
2350
 
1979
2351
  return params;
2352
+ },
2353
+
2354
+ blockParamIndex: function(name) {
2355
+ for (var depth = 0, len = this.options.blockParams.length; depth < len; depth++) {
2356
+ var blockParams = this.options.blockParams[depth],
2357
+ param = blockParams && indexOf(blockParams, name);
2358
+ if (blockParams && param >= 0) {
2359
+ return [depth, param];
2360
+ }
2361
+ }
1980
2362
  }
1981
2363
  };
1982
2364
 
1983
2365
  function precompile(input, options, env) {
1984
- if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
2366
+ if (input == null || (typeof input !== 'string' && input.type !== 'Program')) {
1985
2367
  throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
1986
2368
  }
1987
2369
 
@@ -1993,13 +2375,13 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
1993
2375
  options.useDepths = true;
1994
2376
  }
1995
2377
 
1996
- var ast = env.parse(input);
2378
+ var ast = env.parse(input, options);
1997
2379
  var environment = new env.Compiler().compile(ast, options);
1998
2380
  return new env.JavaScriptCompiler().compile(environment, options);
1999
2381
  }
2000
2382
 
2001
2383
  __exports__.precompile = precompile;function compile(input, options, env) {
2002
- if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
2384
+ if (input == null || (typeof input !== 'string' && input.type !== 'Program')) {
2003
2385
  throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
2004
2386
  }
2005
2387
 
@@ -2015,7 +2397,7 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2015
2397
  var compiled;
2016
2398
 
2017
2399
  function compileInput() {
2018
- var ast = env.parse(input);
2400
+ var ast = env.parse(input, options);
2019
2401
  var environment = new env.Compiler().compile(ast, options);
2020
2402
  var templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
2021
2403
  return env.template(templateSpec);
@@ -2034,11 +2416,11 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2034
2416
  }
2035
2417
  return compiled._setup(options);
2036
2418
  };
2037
- ret._child = function(i, data, depths) {
2419
+ ret._child = function(i, data, blockParams, depths) {
2038
2420
  if (!compiled) {
2039
2421
  compiled = compileInput();
2040
2422
  }
2041
- return compiled._child(i, data, depths);
2423
+ return compiled._child(i, data, blockParams, depths);
2042
2424
  };
2043
2425
  return ret;
2044
2426
  }
@@ -2057,16 +2439,187 @@ var __module11__ = (function(__dependency1__, __dependency2__) {
2057
2439
  return true;
2058
2440
  }
2059
2441
  }
2442
+
2443
+ function transformLiteralToPath(sexpr) {
2444
+ if (!sexpr.path.parts) {
2445
+ var literal = sexpr.path;
2446
+ // Casting to string here to make false and 0 literal values play nicely with the rest
2447
+ // of the system.
2448
+ sexpr.path = new AST.PathExpression(false, 0, [literal.original+''], literal.original+'', literal.log);
2449
+ }
2450
+ }
2451
+ return __exports__;
2452
+ })(__module4__, __module3__, __module7__);
2453
+
2454
+ // handlebars/compiler/code-gen.js
2455
+ var __module15__ = (function(__dependency1__) {
2456
+ "use strict";
2457
+ var __exports__;
2458
+ var isArray = __dependency1__.isArray;
2459
+
2460
+ try {
2461
+ var SourceMap = require('source-map'),
2462
+ SourceNode = SourceMap.SourceNode;
2463
+ } catch (err) {
2464
+ /* istanbul ignore next: tested but not covered in istanbul due to dist build */
2465
+ SourceNode = function(line, column, srcFile, chunks) {
2466
+ this.src = '';
2467
+ if (chunks) {
2468
+ this.add(chunks);
2469
+ }
2470
+ };
2471
+ /* istanbul ignore next */
2472
+ SourceNode.prototype = {
2473
+ add: function(chunks) {
2474
+ if (isArray(chunks)) {
2475
+ chunks = chunks.join('');
2476
+ }
2477
+ this.src += chunks;
2478
+ },
2479
+ prepend: function(chunks) {
2480
+ if (isArray(chunks)) {
2481
+ chunks = chunks.join('');
2482
+ }
2483
+ this.src = chunks + this.src;
2484
+ },
2485
+ toStringWithSourceMap: function() {
2486
+ return {code: this.toString()};
2487
+ },
2488
+ toString: function() {
2489
+ return this.src;
2490
+ }
2491
+ };
2492
+ }
2493
+
2494
+
2495
+ function castChunk(chunk, codeGen, loc) {
2496
+ if (isArray(chunk)) {
2497
+ var ret = [];
2498
+
2499
+ for (var i = 0, len = chunk.length; i < len; i++) {
2500
+ ret.push(codeGen.wrap(chunk[i], loc));
2501
+ }
2502
+ return ret;
2503
+ } else if (typeof chunk === 'boolean' || typeof chunk === 'number') {
2504
+ // Handle primitives that the SourceNode will throw up on
2505
+ return chunk+'';
2506
+ }
2507
+ return chunk;
2508
+ }
2509
+
2510
+
2511
+ function CodeGen(srcFile) {
2512
+ this.srcFile = srcFile;
2513
+ this.source = [];
2514
+ }
2515
+
2516
+ CodeGen.prototype = {
2517
+ prepend: function(source, loc) {
2518
+ this.source.unshift(this.wrap(source, loc));
2519
+ },
2520
+ push: function(source, loc) {
2521
+ this.source.push(this.wrap(source, loc));
2522
+ },
2523
+
2524
+ merge: function() {
2525
+ var source = this.empty();
2526
+ this.each(function(line) {
2527
+ source.add([' ', line, '\n']);
2528
+ });
2529
+ return source;
2530
+ },
2531
+
2532
+ each: function(iter) {
2533
+ for (var i = 0, len = this.source.length; i < len; i++) {
2534
+ iter(this.source[i]);
2535
+ }
2536
+ },
2537
+
2538
+ empty: function(loc) {
2539
+ loc = loc || this.currentLocation || {start:{}};
2540
+ return new SourceNode(loc.start.line, loc.start.column, this.srcFile);
2541
+ },
2542
+ wrap: function(chunk, loc) {
2543
+ if (chunk instanceof SourceNode) {
2544
+ return chunk;
2545
+ }
2546
+
2547
+ loc = loc || this.currentLocation || {start:{}};
2548
+ chunk = castChunk(chunk, this, loc);
2549
+
2550
+ return new SourceNode(loc.start.line, loc.start.column, this.srcFile, chunk);
2551
+ },
2552
+
2553
+ functionCall: function(fn, type, params) {
2554
+ params = this.generateList(params);
2555
+ return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']);
2556
+ },
2557
+
2558
+ quotedString: function(str) {
2559
+ return '"' + (str + '')
2560
+ .replace(/\\/g, '\\\\')
2561
+ .replace(/"/g, '\\"')
2562
+ .replace(/\n/g, '\\n')
2563
+ .replace(/\r/g, '\\r')
2564
+ .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
2565
+ .replace(/\u2029/g, '\\u2029') + '"';
2566
+ },
2567
+
2568
+ objectLiteral: function(obj) {
2569
+ var pairs = [];
2570
+
2571
+ for (var key in obj) {
2572
+ if (obj.hasOwnProperty(key)) {
2573
+ var value = castChunk(obj[key], this);
2574
+ if (value !== 'undefined') {
2575
+ pairs.push([this.quotedString(key), ':', value]);
2576
+ }
2577
+ }
2578
+ }
2579
+
2580
+ var ret = this.generateList(pairs);
2581
+ ret.prepend('{');
2582
+ ret.add('}');
2583
+ return ret;
2584
+ },
2585
+
2586
+
2587
+ generateList: function(entries, loc) {
2588
+ var ret = this.empty(loc);
2589
+
2590
+ for (var i = 0, len = entries.length; i < len; i++) {
2591
+ if (i) {
2592
+ ret.add(',');
2593
+ }
2594
+
2595
+ ret.add(castChunk(entries[i], this, loc));
2596
+ }
2597
+
2598
+ return ret;
2599
+ },
2600
+
2601
+ generateArray: function(entries, loc) {
2602
+ var ret = this.generateList(entries, loc);
2603
+ ret.prepend('[');
2604
+ ret.add(']');
2605
+
2606
+ return ret;
2607
+ }
2608
+ };
2609
+
2610
+ __exports__ = CodeGen;
2060
2611
  return __exports__;
2061
- })(__module5__, __module3__);
2612
+ })(__module3__);
2062
2613
 
2063
2614
  // handlebars/compiler/javascript-compiler.js
2064
- var __module12__ = (function(__dependency1__, __dependency2__) {
2615
+ var __module14__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__) {
2065
2616
  "use strict";
2066
2617
  var __exports__;
2067
2618
  var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;
2068
2619
  var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
2069
2620
  var Exception = __dependency2__;
2621
+ var isArray = __dependency3__.isArray;
2622
+ var CodeGen = __dependency4__;
2070
2623
 
2071
2624
  function Literal(value) {
2072
2625
  this.value = value;
@@ -2079,15 +2632,13 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2079
2632
  // alternative compiled forms for name lookup and buffering semantics
2080
2633
  nameLookup: function(parent, name /* , type*/) {
2081
2634
  if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
2082
- return parent + "." + name;
2635
+ return [parent, ".", name];
2083
2636
  } else {
2084
- return parent + "['" + name + "']";
2637
+ return [parent, "['", name, "']"];
2085
2638
  }
2086
2639
  },
2087
2640
  depthedLookup: function(name) {
2088
- this.aliases.lookup = 'this.lookup';
2089
-
2090
- return 'lookup(depths, "' + name + '")';
2641
+ return [this.aliasable('this.lookup'), '(depths, "', name, '")'];
2091
2642
  },
2092
2643
 
2093
2644
  compilerInfo: function() {
@@ -2096,23 +2647,29 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2096
2647
  return [revision, versions];
2097
2648
  },
2098
2649
 
2099
- appendToBuffer: function(string) {
2650
+ appendToBuffer: function(source, location, explicit) {
2651
+ // Force a source as this simplifies the merge logic.
2652
+ if (!isArray(source)) {
2653
+ source = [source];
2654
+ }
2655
+ source = this.source.wrap(source, location);
2656
+
2100
2657
  if (this.environment.isSimple) {
2101
- return "return " + string + ";";
2658
+ return ['return ', source, ';'];
2659
+ } else if (explicit) {
2660
+ // This is a case where the buffer operation occurs as a child of another
2661
+ // construct, generally braces. We have to explicitly output these buffer
2662
+ // operations to ensure that the emitted code goes in the correct location.
2663
+ return ['buffer += ', source, ';'];
2102
2664
  } else {
2103
- return {
2104
- appendToBuffer: true,
2105
- content: string,
2106
- toString: function() { return "buffer += " + string + ";"; }
2107
- };
2665
+ source.appendToBuffer = true;
2666
+ return source;
2108
2667
  }
2109
2668
  },
2110
2669
 
2111
2670
  initializeBuffer: function() {
2112
2671
  return this.quotedString("");
2113
2672
  },
2114
-
2115
- namespace: "Handlebars",
2116
2673
  // END PUBLIC API
2117
2674
 
2118
2675
  compile: function(environment, options, context, asObject) {
@@ -2138,23 +2695,29 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2138
2695
  this.hashes = [];
2139
2696
  this.compileStack = [];
2140
2697
  this.inlineStack = [];
2698
+ this.blockParams = [];
2141
2699
 
2142
2700
  this.compileChildren(environment, options);
2143
2701
 
2144
- this.useDepths = this.useDepths || environment.depths.list.length || this.options.compat;
2702
+ this.useDepths = this.useDepths || environment.useDepths || this.options.compat;
2703
+ this.useBlockParams = this.useBlockParams || environment.useBlockParams;
2145
2704
 
2146
2705
  var opcodes = environment.opcodes,
2147
2706
  opcode,
2707
+ firstLoc,
2148
2708
  i,
2149
2709
  l;
2150
2710
 
2151
2711
  for (i = 0, l = opcodes.length; i < l; i++) {
2152
2712
  opcode = opcodes[i];
2153
2713
 
2714
+ this.source.currentLocation = opcode.loc;
2715
+ firstLoc = firstLoc || opcode.loc;
2154
2716
  this[opcode.opcode].apply(this, opcode.args);
2155
2717
  }
2156
2718
 
2157
2719
  // Flush any trailing content that might be pending.
2720
+ this.source.currentLocation = firstLoc;
2158
2721
  this.pushSource('');
2159
2722
 
2160
2723
  /* istanbul ignore next */
@@ -2184,13 +2747,27 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2184
2747
  if (this.useDepths) {
2185
2748
  ret.useDepths = true;
2186
2749
  }
2750
+ if (this.useBlockParams) {
2751
+ ret.useBlockParams = true;
2752
+ }
2187
2753
  if (this.options.compat) {
2188
2754
  ret.compat = true;
2189
2755
  }
2190
2756
 
2191
2757
  if (!asObject) {
2192
2758
  ret.compiler = JSON.stringify(ret.compiler);
2759
+
2760
+ this.source.currentLocation = {start: {line: 1, column: 0}};
2193
2761
  ret = this.objectLiteral(ret);
2762
+
2763
+ if (options.srcName) {
2764
+ ret = ret.toStringWithSourceMap({file: options.destName});
2765
+ ret.map = ret.map && ret.map.toString();
2766
+ } else {
2767
+ ret = ret.toString();
2768
+ }
2769
+ } else {
2770
+ ret.compilerOptions = this.options;
2194
2771
  }
2195
2772
 
2196
2773
  return ret;
@@ -2203,7 +2780,7 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2203
2780
  // track the last context pushed into place to allow skipping the
2204
2781
  // getContext opcode when it would be a noop
2205
2782
  this.lastContext = 0;
2206
- this.source = [];
2783
+ this.source = new CodeGen(this.options.srcName);
2207
2784
  },
2208
2785
 
2209
2786
  createFunctionContext: function(asObject) {
@@ -2215,14 +2792,26 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2215
2792
  }
2216
2793
 
2217
2794
  // Generate minimizer alias mappings
2795
+ //
2796
+ // When using true SourceNodes, this will update all references to the given alias
2797
+ // as the source nodes are reused in situ. For the non-source node compilation mode,
2798
+ // aliases will not be used, but this case is already being run on the client and
2799
+ // we aren't concern about minimizing the template size.
2800
+ var aliasCount = 0;
2218
2801
  for (var alias in this.aliases) {
2219
- if (this.aliases.hasOwnProperty(alias)) {
2220
- varDeclarations += ', ' + alias + '=' + this.aliases[alias];
2802
+ var node = this.aliases[alias];
2803
+
2804
+ if (this.aliases.hasOwnProperty(alias) && node.children && node.referenceCount > 1) {
2805
+ varDeclarations += ', alias' + (++aliasCount) + '=' + alias;
2806
+ node.children[0] = 'alias' + aliasCount;
2221
2807
  }
2222
2808
  }
2223
2809
 
2224
2810
  var params = ["depth0", "helpers", "partials", "data"];
2225
2811
 
2812
+ if (this.useBlockParams || this.useDepths) {
2813
+ params.push('blockParams');
2814
+ }
2226
2815
  if (this.useDepths) {
2227
2816
  params.push('depths');
2228
2817
  }
@@ -2235,59 +2824,67 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2235
2824
 
2236
2825
  return Function.apply(this, params);
2237
2826
  } else {
2238
- return 'function(' + params.join(',') + ') {\n ' + source + '}';
2827
+ return this.source.wrap(['function(', params.join(','), ') {\n ', source, '}']);
2239
2828
  }
2240
2829
  },
2241
2830
  mergeSource: function(varDeclarations) {
2242
- var source = '',
2243
- buffer,
2831
+ var isSimple = this.environment.isSimple,
2244
2832
  appendOnly = !this.forceBuffer,
2245
- appendFirst;
2833
+ appendFirst,
2246
2834
 
2247
- for (var i = 0, len = this.source.length; i < len; i++) {
2248
- var line = this.source[i];
2835
+ sourceSeen,
2836
+ bufferStart,
2837
+ bufferEnd;
2838
+ this.source.each(function(line) {
2249
2839
  if (line.appendToBuffer) {
2250
- if (buffer) {
2251
- buffer = buffer + '\n + ' + line.content;
2840
+ if (bufferStart) {
2841
+ line.prepend(' + ');
2252
2842
  } else {
2253
- buffer = line.content;
2843
+ bufferStart = line;
2254
2844
  }
2845
+ bufferEnd = line;
2255
2846
  } else {
2256
- if (buffer) {
2257
- if (!source) {
2847
+ if (bufferStart) {
2848
+ if (!sourceSeen) {
2258
2849
  appendFirst = true;
2259
- source = buffer + ';\n ';
2260
2850
  } else {
2261
- source += 'buffer += ' + buffer + ';\n ';
2851
+ bufferStart.prepend('buffer += ');
2262
2852
  }
2263
- buffer = undefined;
2853
+ bufferEnd.add(';');
2854
+ bufferStart = bufferEnd = undefined;
2264
2855
  }
2265
- source += line + '\n ';
2266
2856
 
2267
- if (!this.environment.isSimple) {
2857
+ sourceSeen = true;
2858
+ if (!isSimple) {
2268
2859
  appendOnly = false;
2269
2860
  }
2270
2861
  }
2271
- }
2862
+ });
2863
+
2272
2864
 
2273
2865
  if (appendOnly) {
2274
- if (buffer || !source) {
2275
- source += 'return ' + (buffer || '""') + ';\n';
2866
+ if (bufferStart) {
2867
+ bufferStart.prepend('return ');
2868
+ bufferEnd.add(';');
2869
+ } else if (!sourceSeen) {
2870
+ this.source.push('return "";');
2276
2871
  }
2277
2872
  } else {
2278
2873
  varDeclarations += ", buffer = " + (appendFirst ? '' : this.initializeBuffer());
2279
- if (buffer) {
2280
- source += 'return buffer + ' + buffer + ';\n';
2874
+
2875
+ if (bufferStart) {
2876
+ bufferStart.prepend('return buffer + ');
2877
+ bufferEnd.add(';');
2281
2878
  } else {
2282
- source += 'return buffer;\n';
2879
+ this.source.push('return buffer;');
2283
2880
  }
2284
2881
  }
2285
2882
 
2286
2883
  if (varDeclarations) {
2287
- source = 'var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n ') + source;
2884
+ this.source.prepend('var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n'));
2288
2885
  }
2289
2886
 
2290
- return source;
2887
+ return this.source.merge();
2291
2888
  },
2292
2889
 
2293
2890
  // [blockValue]
@@ -2300,15 +2897,14 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2300
2897
  // replace it on the stack with the result of properly
2301
2898
  // invoking blockHelperMissing.
2302
2899
  blockValue: function(name) {
2303
- this.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
2304
-
2305
- var params = [this.contextName(0)];
2306
- this.setupParams(name, 0, params);
2900
+ var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
2901
+ params = [this.contextName(0)];
2902
+ this.setupHelperArgs(name, 0, params);
2307
2903
 
2308
2904
  var blockName = this.popStack();
2309
2905
  params.splice(1, 0, blockName);
2310
2906
 
2311
- this.push('blockHelperMissing.call(' + params.join(', ') + ')');
2907
+ this.push(this.source.functionCall(blockHelperMissing, 'call', params));
2312
2908
  },
2313
2909
 
2314
2910
  // [ambiguousBlockValue]
@@ -2318,18 +2914,20 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2318
2914
  // On stack, after, if no lastHelper: same as [blockValue]
2319
2915
  // On stack, after, if lastHelper: value
2320
2916
  ambiguousBlockValue: function() {
2321
- this.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
2322
-
2323
2917
  // 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);
2918
+ var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'),
2919
+ params = [this.contextName(0)];
2920
+ this.setupHelperArgs('', 0, params, true);
2326
2921
 
2327
2922
  this.flushInline();
2328
2923
 
2329
2924
  var current = this.topStack();
2330
2925
  params.splice(1, 0, current);
2331
2926
 
2332
- this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
2927
+ this.pushSource([
2928
+ 'if (!', this.lastHelper, ') { ',
2929
+ current, ' = ', this.source.functionCall(blockHelperMissing, 'call', params),
2930
+ '}']);
2333
2931
  },
2334
2932
 
2335
2933
  // [appendContent]
@@ -2341,6 +2939,8 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2341
2939
  appendContent: function(content) {
2342
2940
  if (this.pendingContent) {
2343
2941
  content = this.pendingContent + content;
2942
+ } else {
2943
+ this.pendingLocation = this.source.currentLocation;
2344
2944
  }
2345
2945
 
2346
2946
  this.pendingContent = content;
@@ -2356,13 +2956,18 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2356
2956
  // If `value` is truthy, or 0, it is coerced into a string and appended
2357
2957
  // Otherwise, the empty string is appended
2358
2958
  append: function() {
2359
- // Force anything that is inlined onto the stack so we don't have duplication
2360
- // when we examine local
2361
- this.flushInline();
2362
- var local = this.popStack();
2363
- this.pushSource('if (' + local + ' != null) { ' + this.appendToBuffer(local) + ' }');
2364
- if (this.environment.isSimple) {
2365
- this.pushSource("else { " + this.appendToBuffer("''") + " }");
2959
+ if (this.isInline()) {
2960
+ this.replaceStack(function(current) {
2961
+ return [' != null ? ', current, ' : ""'];
2962
+ });
2963
+
2964
+ this.pushSource(this.appendToBuffer(this.popStack()));
2965
+ } else {
2966
+ var local = this.popStack();
2967
+ this.pushSource(['if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }']);
2968
+ if (this.environment.isSimple) {
2969
+ this.pushSource(['else { ', this.appendToBuffer("''", undefined, true), ' }']);
2970
+ }
2366
2971
  }
2367
2972
  },
2368
2973
 
@@ -2373,9 +2978,8 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2373
2978
  //
2374
2979
  // Escape `value` and append it to the buffer
2375
2980
  appendEscaped: function() {
2376
- this.aliases.escapeExpression = 'this.escapeExpression';
2377
-
2378
- this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
2981
+ this.pushSource(this.appendToBuffer(
2982
+ [this.aliasable('this.escapeExpression'), '(', this.popStack(), ')']));
2379
2983
  },
2380
2984
 
2381
2985
  // [getContext]
@@ -2407,9 +3011,7 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2407
3011
  // Looks up the value of `name` on the current context and pushes
2408
3012
  // it onto the stack.
2409
3013
  lookupOnContext: function(parts, falsy, scoped) {
2410
- /*jshint -W083 */
2411
- var i = 0,
2412
- len = parts.length;
3014
+ var i = 0;
2413
3015
 
2414
3016
  if (!scoped && this.options.compat && !this.lastContext) {
2415
3017
  // The depthed query is expected to handle the undefined logic for the root level that
@@ -2419,19 +3021,21 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2419
3021
  this.pushContext();
2420
3022
  }
2421
3023
 
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
- }
3024
+ this.resolvePath('context', parts, i, falsy);
3025
+ },
3026
+
3027
+ // [lookupBlockParam]
3028
+ //
3029
+ // On stack, before: ...
3030
+ // On stack, after: blockParam[name], ...
3031
+ //
3032
+ // Looks up the value of `parts` on the given block param and pushes
3033
+ // it onto the stack.
3034
+ lookupBlockParam: function(blockParamId, parts) {
3035
+ this.useBlockParams = true;
3036
+
3037
+ this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']);
3038
+ this.resolvePath('context', parts, 1);
2435
3039
  },
2436
3040
 
2437
3041
  // [lookupData]
@@ -2448,10 +3052,28 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2448
3052
  this.pushStackLiteral('this.data(data, ' + depth + ')');
2449
3053
  }
2450
3054
 
3055
+ this.resolvePath('data', parts, 0, true);
3056
+ },
3057
+
3058
+ resolvePath: function(type, parts, i, falsy) {
3059
+ /*jshint -W083 */
3060
+ if (this.options.strict || this.options.assumeObjects) {
3061
+ this.push(strictLookup(this.options.strict, this, parts, type));
3062
+ return;
3063
+ }
3064
+
2451
3065
  var len = parts.length;
2452
- for (var i = 0; i < len; i++) {
3066
+ for (; i < len; i++) {
2453
3067
  this.replaceStack(function(current) {
2454
- return ' && ' + this.nameLookup(current, parts[i], 'data');
3068
+ var lookup = this.nameLookup(current, parts[i], type);
3069
+ // We want to ensure that zero and false are handled properly if the context (falsy flag)
3070
+ // needs to have the special handling for these values.
3071
+ if (!falsy) {
3072
+ return [' != null ? ', lookup, ' : ', current];
3073
+ } else {
3074
+ // Otherwise we can use generic falsy handling
3075
+ return [' && ', lookup];
3076
+ }
2455
3077
  });
2456
3078
  }
2457
3079
  },
@@ -2464,9 +3086,7 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2464
3086
  // If the `value` is a lambda, replace it on the stack by
2465
3087
  // the return value of the lambda
2466
3088
  resolvePossibleLambda: function() {
2467
- this.aliases.lambda = 'this.lambda';
2468
-
2469
- this.push('lambda(' + this.popStack() + ', ' + this.contextName(0) + ')');
3089
+ this.push([this.aliasable('this.lambda'), '(', this.popStack(), ', ', this.contextName(0), ')']);
2470
3090
  },
2471
3091
 
2472
3092
  // [pushStringParam]
@@ -2483,7 +3103,7 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2483
3103
 
2484
3104
  // If it's a subexpression, the string result
2485
3105
  // will be pushed after this opcode.
2486
- if (type !== 'sexpr') {
3106
+ if (type !== 'SubExpression') {
2487
3107
  if (typeof string === 'string') {
2488
3108
  this.pushString(string);
2489
3109
  } else {
@@ -2492,9 +3112,7 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2492
3112
  }
2493
3113
  },
2494
3114
 
2495
- emptyHash: function() {
2496
- this.pushStackLiteral('{}');
2497
-
3115
+ emptyHash: function(omitEmpty) {
2498
3116
  if (this.trackIds) {
2499
3117
  this.push('{}'); // hashIds
2500
3118
  }
@@ -2502,6 +3120,7 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2502
3120
  this.push('{}'); // hashContexts
2503
3121
  this.push('{}'); // hashTypes
2504
3122
  }
3123
+ this.pushStackLiteral(omitEmpty ? 'undefined' : '{}');
2505
3124
  },
2506
3125
  pushHash: function() {
2507
3126
  if (this.hash) {
@@ -2514,14 +3133,14 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2514
3133
  this.hash = this.hashes.pop();
2515
3134
 
2516
3135
  if (this.trackIds) {
2517
- this.push('{' + hash.ids.join(',') + '}');
3136
+ this.push(this.objectLiteral(hash.ids));
2518
3137
  }
2519
3138
  if (this.stringParams) {
2520
- this.push('{' + hash.contexts.join(',') + '}');
2521
- this.push('{' + hash.types.join(',') + '}');
3139
+ this.push(this.objectLiteral(hash.contexts));
3140
+ this.push(this.objectLiteral(hash.types));
2522
3141
  }
2523
3142
 
2524
- this.push('{\n ' + hash.values.join(',\n ') + '\n }');
3143
+ this.push(this.objectLiteral(hash.values));
2525
3144
  },
2526
3145
 
2527
3146
  // [pushString]
@@ -2534,17 +3153,6 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2534
3153
  this.pushStackLiteral(this.quotedString(string));
2535
3154
  },
2536
3155
 
2537
- // [push]
2538
- //
2539
- // On stack, before: ...
2540
- // On stack, after: expr, ...
2541
- //
2542
- // Push an expression onto the stack
2543
- push: function(expr) {
2544
- this.inlineStack.push(expr);
2545
- return expr;
2546
- },
2547
-
2548
3156
  // [pushLiteral]
2549
3157
  //
2550
3158
  // On stack, before: ...
@@ -2583,13 +3191,17 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2583
3191
  //
2584
3192
  // If the helper is not found, `helperMissing` is called.
2585
3193
  invokeHelper: function(paramSize, name, isSimple) {
2586
- this.aliases.helperMissing = 'helpers.helperMissing';
2587
-
2588
3194
  var nonHelper = this.popStack();
2589
3195
  var helper = this.setupHelper(paramSize, name);
3196
+ var simple = isSimple ? [helper.name, ' || '] : '';
3197
+
3198
+ var lookup = ['('].concat(simple, nonHelper);
3199
+ if (!this.options.strict) {
3200
+ lookup.push(' || ', this.aliasable('helpers.helperMissing'));
3201
+ }
3202
+ lookup.push(')');
2590
3203
 
2591
- var lookup = (isSimple ? helper.name + ' || ' : '') + nonHelper + ' || helperMissing';
2592
- this.push('((' + lookup + ').call(' + helper.callParams + '))');
3204
+ this.push(this.source.functionCall(lookup, 'call', helper.callParams));
2593
3205
  },
2594
3206
 
2595
3207
  // [invokeKnownHelper]
@@ -2601,7 +3213,7 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2601
3213
  // so a `helperMissing` fallback is not required.
2602
3214
  invokeKnownHelper: function(paramSize, name) {
2603
3215
  var helper = this.setupHelper(paramSize, name);
2604
- this.push(helper.name + ".call(" + helper.callParams + ")");
3216
+ this.push(this.source.functionCall(helper.name, 'call', helper.callParams));
2605
3217
  },
2606
3218
 
2607
3219
  // [invokeAmbiguous]
@@ -2617,8 +3229,6 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2617
3229
  // and can be avoided by passing the `knownHelpers` and
2618
3230
  // `knownHelpersOnly` flags at compile-time.
2619
3231
  invokeAmbiguous: function(name, helperCall) {
2620
- this.aliases.functionType = '"function"';
2621
- this.aliases.helperMissing = 'helpers.helperMissing';
2622
3232
  this.useRegister('helper');
2623
3233
 
2624
3234
  var nonHelper = this.popStack();
@@ -2628,10 +3238,21 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2628
3238
 
2629
3239
  var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
2630
3240
 
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))');
3241
+ var lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')'];
3242
+ if (!this.options.strict) {
3243
+ lookup[0] = '(helper = ';
3244
+ lookup.push(
3245
+ ' != null ? helper : ',
3246
+ this.aliasable('helpers.helperMissing')
3247
+ );
3248
+ }
3249
+
3250
+ this.push([
3251
+ '(', lookup,
3252
+ (helper.paramsInit ? ['),(', helper.paramsInit] : []), '),',
3253
+ '(typeof helper === ', this.aliasable('"function"'), ' ? ',
3254
+ this.source.functionCall('helper','call', helper.callParams), ' : helper))'
3255
+ ]);
2635
3256
  },
2636
3257
 
2637
3258
  // [invokePartial]
@@ -2641,19 +3262,34 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2641
3262
  //
2642
3263
  // This operation pops off a context, invokes a partial with that context,
2643
3264
  // and pushes the result of the invocation back.
2644
- invokePartial: function(name, indent) {
2645
- var params = [this.nameLookup('partials', name, 'partial'), "'" + indent + "'", "'" + name + "'", this.popStack(), this.popStack(), "helpers", "partials"];
3265
+ invokePartial: function(isDynamic, name, indent) {
3266
+ var params = [],
3267
+ options = this.setupParams(name, 1, params, false);
2646
3268
 
2647
- if (this.options.data) {
2648
- params.push("data");
2649
- } else if (this.options.compat) {
2650
- params.push('undefined');
3269
+ if (isDynamic) {
3270
+ name = this.popStack();
3271
+ delete options.name;
2651
3272
  }
3273
+
3274
+ if (indent) {
3275
+ options.indent = JSON.stringify(indent);
3276
+ }
3277
+ options.helpers = 'helpers';
3278
+ options.partials = 'partials';
3279
+
3280
+ if (!isDynamic) {
3281
+ params.unshift(this.nameLookup('partials', name, 'partial'));
3282
+ } else {
3283
+ params.unshift(name);
3284
+ }
3285
+
2652
3286
  if (this.options.compat) {
2653
- params.push('depths');
3287
+ options.depths = 'depths';
2654
3288
  }
3289
+ options = this.objectLiteral(options);
3290
+ params.push(options);
2655
3291
 
2656
- this.push("this.invokePartial(" + params.join(", ") + ")");
3292
+ this.push(this.source.functionCall('this.invokePartial', '', params));
2657
3293
  },
2658
3294
 
2659
3295
  // [assignToHash]
@@ -2678,21 +3314,25 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2678
3314
 
2679
3315
  var hash = this.hash;
2680
3316
  if (context) {
2681
- hash.contexts.push("'" + key + "': " + context);
3317
+ hash.contexts[key] = context;
2682
3318
  }
2683
3319
  if (type) {
2684
- hash.types.push("'" + key + "': " + type);
3320
+ hash.types[key] = type;
2685
3321
  }
2686
3322
  if (id) {
2687
- hash.ids.push("'" + key + "': " + id);
3323
+ hash.ids[key] = id;
2688
3324
  }
2689
- hash.values.push("'" + key + "': (" + value + ")");
3325
+ hash.values[key] = value;
2690
3326
  },
2691
3327
 
2692
- pushId: function(type, name) {
2693
- if (type === 'ID' || type === 'DATA') {
3328
+ pushId: function(type, name, child) {
3329
+ if (type === 'BlockParam') {
3330
+ this.pushStackLiteral(
3331
+ 'blockParams[' + name[0] + '].path[' + name[1] + ']'
3332
+ + (child ? ' + ' + JSON.stringify('.' + child) : ''));
3333
+ } else if (type === 'PathExpression') {
2694
3334
  this.pushString(name);
2695
- } else if (type === 'sexpr') {
3335
+ } else if (type === 'SubExpression') {
2696
3336
  this.pushStackLiteral('true');
2697
3337
  } else {
2698
3338
  this.pushStackLiteral('null');
@@ -2721,9 +3361,13 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2721
3361
  this.context.environments[index] = child;
2722
3362
 
2723
3363
  this.useDepths = this.useDepths || compiler.useDepths;
3364
+ this.useBlockParams = this.useBlockParams || compiler.useBlockParams;
2724
3365
  } else {
2725
3366
  child.index = index;
2726
3367
  child.name = 'program' + index;
3368
+
3369
+ this.useDepths = this.useDepths || child.useDepths;
3370
+ this.useBlockParams = this.useBlockParams || child.useBlockParams;
2727
3371
  }
2728
3372
  }
2729
3373
  },
@@ -2738,13 +3382,12 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2738
3382
 
2739
3383
  programExpression: function(guid) {
2740
3384
  var child = this.environment.children[guid],
2741
- depths = child.depths.list,
2742
- useDepths = this.useDepths,
2743
- depth;
2744
-
2745
- var programParams = [child.index, 'data'];
3385
+ programParams = [child.index, 'data', child.blockParams];
2746
3386
 
2747
- if (useDepths) {
3387
+ if (this.useBlockParams || this.useDepths) {
3388
+ programParams.push('blockParams');
3389
+ }
3390
+ if (this.useDepths) {
2748
3391
  programParams.push('depths');
2749
3392
  }
2750
3393
 
@@ -2758,13 +3401,23 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2758
3401
  }
2759
3402
  },
2760
3403
 
3404
+ push: function(expr) {
3405
+ if (!(expr instanceof Literal)) {
3406
+ expr = this.source.wrap(expr);
3407
+ }
3408
+
3409
+ this.inlineStack.push(expr);
3410
+ return expr;
3411
+ },
3412
+
2761
3413
  pushStackLiteral: function(item) {
2762
- return this.push(new Literal(item));
3414
+ this.push(new Literal(item));
2763
3415
  },
2764
3416
 
2765
3417
  pushSource: function(source) {
2766
3418
  if (this.pendingContent) {
2767
- this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
3419
+ this.source.push(
3420
+ this.appendToBuffer(this.source.quotedString(this.pendingContent), this.pendingLocation));
2768
3421
  this.pendingContent = undefined;
2769
3422
  }
2770
3423
 
@@ -2773,18 +3426,8 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2773
3426
  }
2774
3427
  },
2775
3428
 
2776
- pushStack: function(item) {
2777
- this.flushInline();
2778
-
2779
- var stack = this.incrStack();
2780
- this.pushSource(stack + " = " + item + ";");
2781
- this.compileStack.push(stack);
2782
- return stack;
2783
- },
2784
-
2785
3429
  replaceStack: function(callback) {
2786
- var prefix = '',
2787
- inline = this.isInline(),
3430
+ var prefix = ['('],
2788
3431
  stack,
2789
3432
  createdStack,
2790
3433
  usedLiteral;
@@ -2799,14 +3442,15 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2799
3442
 
2800
3443
  if (top instanceof Literal) {
2801
3444
  // Literals do not need to be inlined
2802
- prefix = stack = top.value;
3445
+ stack = [top.value];
3446
+ prefix = ['(', stack];
2803
3447
  usedLiteral = true;
2804
3448
  } else {
2805
3449
  // Get or create the current stack name for use by the inline
2806
- createdStack = !this.stackSlot;
2807
- var name = !createdStack ? this.topStackName() : this.incrStack();
3450
+ createdStack = true;
3451
+ var name = this.incrStack();
2808
3452
 
2809
- prefix = '(' + this.push(name) + ' = ' + top + ')';
3453
+ prefix = ['((', this.push(name), ' = ', top, ')'];
2810
3454
  stack = this.topStack();
2811
3455
  }
2812
3456
 
@@ -2818,7 +3462,7 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2818
3462
  if (createdStack) {
2819
3463
  this.stackSlot--;
2820
3464
  }
2821
- this.push('(' + prefix + item + ')');
3465
+ this.push(prefix.concat(item, ')'));
2822
3466
  },
2823
3467
 
2824
3468
  incrStack: function() {
@@ -2831,15 +3475,16 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2831
3475
  },
2832
3476
  flushInline: function() {
2833
3477
  var inlineStack = this.inlineStack;
2834
- if (inlineStack.length) {
2835
- this.inlineStack = [];
2836
- for (var i = 0, len = inlineStack.length; i < len; i++) {
2837
- var entry = inlineStack[i];
2838
- if (entry instanceof Literal) {
2839
- this.compileStack.push(entry);
2840
- } else {
2841
- this.pushStack(entry);
2842
- }
3478
+ this.inlineStack = [];
3479
+ for (var i = 0, len = inlineStack.length; i < len; i++) {
3480
+ var entry = inlineStack[i];
3481
+ /* istanbul ignore if */
3482
+ if (entry instanceof Literal) {
3483
+ this.compileStack.push(entry);
3484
+ } else {
3485
+ var stack = this.incrStack();
3486
+ this.pushSource([stack, ' = ', entry, ';']);
3487
+ this.compileStack.push(stack);
2843
3488
  }
2844
3489
  }
2845
3490
  },
@@ -2869,6 +3514,7 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2869
3514
  var stack = (this.isInline() ? this.inlineStack : this.compileStack),
2870
3515
  item = stack[stack.length - 1];
2871
3516
 
3517
+ /* istanbul ignore if */
2872
3518
  if (item instanceof Literal) {
2873
3519
  return item.value;
2874
3520
  } else {
@@ -2885,42 +3531,42 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2885
3531
  },
2886
3532
 
2887
3533
  quotedString: function(str) {
2888
- return '"' + str
2889
- .replace(/\\/g, '\\\\')
2890
- .replace(/"/g, '\\"')
2891
- .replace(/\n/g, '\\n')
2892
- .replace(/\r/g, '\\r')
2893
- .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
2894
- .replace(/\u2029/g, '\\u2029') + '"';
3534
+ return this.source.quotedString(str);
2895
3535
  },
2896
3536
 
2897
3537
  objectLiteral: function(obj) {
2898
- var pairs = [];
3538
+ return this.source.objectLiteral(obj);
3539
+ },
2899
3540
 
2900
- for (var key in obj) {
2901
- if (obj.hasOwnProperty(key)) {
2902
- pairs.push(this.quotedString(key) + ':' + obj[key]);
2903
- }
3541
+ aliasable: function(name) {
3542
+ var ret = this.aliases[name];
3543
+ if (ret) {
3544
+ ret.referenceCount++;
3545
+ return ret;
2904
3546
  }
2905
3547
 
2906
- return '{' + pairs.join(',') + '}';
3548
+ ret = this.aliases[name] = this.source.wrap(name);
3549
+ ret.aliasable = true;
3550
+ ret.referenceCount = 1;
3551
+
3552
+ return ret;
2907
3553
  },
2908
3554
 
2909
3555
  setupHelper: function(paramSize, name, blockHelper) {
2910
3556
  var params = [],
2911
- paramsInit = this.setupParams(name, paramSize, params, blockHelper);
3557
+ paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper);
2912
3558
  var foundHelper = this.nameLookup('helpers', name, 'helper');
2913
3559
 
2914
3560
  return {
2915
3561
  params: params,
2916
3562
  paramsInit: paramsInit,
2917
3563
  name: foundHelper,
2918
- callParams: [this.contextName(0)].concat(params).join(", ")
3564
+ callParams: [this.contextName(0)].concat(params)
2919
3565
  };
2920
3566
  },
2921
3567
 
2922
- setupOptions: function(helper, paramSize, params) {
2923
- var options = {}, contexts = [], types = [], ids = [], param, inverse, program;
3568
+ setupParams: function(helper, paramSize, params) {
3569
+ var options = {}, contexts = [], types = [], ids = [], param;
2924
3570
 
2925
3571
  options.name = this.quotedString(helper);
2926
3572
  options.hash = this.popStack();
@@ -2933,22 +3579,14 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2933
3579
  options.hashContexts = this.popStack();
2934
3580
  }
2935
3581
 
2936
- inverse = this.popStack();
2937
- program = this.popStack();
3582
+ var inverse = this.popStack(),
3583
+ program = this.popStack();
2938
3584
 
2939
3585
  // Avoid setting fn and inverse if neither are set. This allows
2940
3586
  // helpers to do a check for `if (options.fn)`
2941
3587
  if (program || inverse) {
2942
- if (!program) {
2943
- program = 'this.noop';
2944
- }
2945
-
2946
- if (!inverse) {
2947
- inverse = 'this.noop';
2948
- }
2949
-
2950
- options.fn = program;
2951
- options.inverse = inverse;
3588
+ options.fn = program || 'this.noop';
3589
+ options.inverse = inverse || 'this.noop';
2952
3590
  }
2953
3591
 
2954
3592
  // The parameters go on to the stack in order (making sure that they are evaluated in order)
@@ -2968,29 +3606,29 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2968
3606
  }
2969
3607
 
2970
3608
  if (this.trackIds) {
2971
- options.ids = "[" + ids.join(",") + "]";
3609
+ options.ids = this.source.generateArray(ids);
2972
3610
  }
2973
3611
  if (this.stringParams) {
2974
- options.types = "[" + types.join(",") + "]";
2975
- options.contexts = "[" + contexts.join(",") + "]";
3612
+ options.types = this.source.generateArray(types);
3613
+ options.contexts = this.source.generateArray(contexts);
2976
3614
  }
2977
3615
 
2978
3616
  if (this.options.data) {
2979
- options.data = "data";
3617
+ options.data = 'data';
3618
+ }
3619
+ if (this.useBlockParams) {
3620
+ options.blockParams = 'blockParams';
2980
3621
  }
2981
-
2982
3622
  return options;
2983
3623
  },
2984
3624
 
2985
- // the params and contexts arguments are passed in arrays
2986
- // to fill in
2987
- setupParams: function(helperName, paramSize, params, useRegister) {
2988
- var options = this.objectLiteral(this.setupOptions(helperName, paramSize, params));
2989
-
3625
+ setupHelperArgs: function(helper, paramSize, params, useRegister) {
3626
+ var options = this.setupParams(helper, paramSize, params, true);
3627
+ options = this.objectLiteral(options);
2990
3628
  if (useRegister) {
2991
3629
  this.useRegister('options');
2992
3630
  params.push('options');
2993
- return 'options=' + options;
3631
+ return ['options=', options];
2994
3632
  } else {
2995
3633
  params.push(options);
2996
3634
  return '';
@@ -2998,6 +3636,7 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
2998
3636
  }
2999
3637
  };
3000
3638
 
3639
+
3001
3640
  var reservedWords = (
3002
3641
  "break else new var" +
3003
3642
  " case finally return void" +
@@ -3013,7 +3652,8 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
3013
3652
  " class float package throws" +
3014
3653
  " const goto private transient" +
3015
3654
  " debugger implements protected volatile" +
3016
- " double import public let yield"
3655
+ " double import public let yield await" +
3656
+ " null true false"
3017
3657
  ).split(" ");
3018
3658
 
3019
3659
  var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
@@ -3026,9 +3666,29 @@ var __module12__ = (function(__dependency1__, __dependency2__) {
3026
3666
  return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name);
3027
3667
  };
3028
3668
 
3669
+ function strictLookup(requireTerminal, compiler, parts, type) {
3670
+ var stack = compiler.popStack();
3671
+
3672
+ var i = 0,
3673
+ len = parts.length;
3674
+ if (requireTerminal) {
3675
+ len--;
3676
+ }
3677
+
3678
+ for (; i < len; i++) {
3679
+ stack = compiler.nameLookup(stack, parts[i], type);
3680
+ }
3681
+
3682
+ if (requireTerminal) {
3683
+ return [compiler.aliasable('this.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ')'];
3684
+ } else {
3685
+ return stack;
3686
+ }
3687
+ }
3688
+
3029
3689
  __exports__ = JavaScriptCompiler;
3030
3690
  return __exports__;
3031
- })(__module2__, __module5__);
3691
+ })(__module2__, __module4__, __module3__, __module15__);
3032
3692
 
3033
3693
  // handlebars.js
3034
3694
  var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
@@ -3069,11 +3729,22 @@ var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, _
3069
3729
  Handlebars = create();
3070
3730
  Handlebars.create = create;
3071
3731
 
3732
+ /*jshint -W040 */
3733
+ /* istanbul ignore next */
3734
+ var root = typeof global !== 'undefined' ? global : window,
3735
+ $Handlebars = root.Handlebars;
3736
+ /* istanbul ignore next */
3737
+ Handlebars.noConflict = function() {
3738
+ if (root.Handlebars === Handlebars) {
3739
+ root.Handlebars = $Handlebars;
3740
+ }
3741
+ };
3742
+
3072
3743
  Handlebars['default'] = Handlebars;
3073
3744
 
3074
3745
  __exports__ = Handlebars;
3075
3746
  return __exports__;
3076
- })(__module1__, __module7__, __module8__, __module11__, __module12__);
3747
+ })(__module1__, __module7__, __module8__, __module13__, __module14__);
3077
3748
 
3078
3749
  return __module0__;
3079
3750
  }));