handlebars_assets 0.17.2 → 0.18

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