Repository: mozilla/nunjucks
Pull request #452 (2015-06-01 16:05:28)

Added Jinja2 style express string concatenation with tests
Nunjucks is missing the Jinja2 '~' which expressly concatenates irrespective of source type unlike the javascript '+' which performs an addition between any numbers


Patch:
diff --git a/browser/nunjucks-slim.js b/browser/nunjucks-slim.js
index 8bfa8e0..bbb9144 100644
--- a/browser/nunjucks-slim.js
+++ b/browser/nunjucks-slim.js
@@ -55,7 +55,7 @@ var nunjucks =
 	var lexer = __webpack_require__(9);
 	var runtime = __webpack_require__(3);
 	var Loader = __webpack_require__(4);
-	var loaders = __webpack_require__(9);
+	var loaders = __webpack_require__(5);
 	var precompile = __webpack_require__(9);
 
 	module.exports = {};
@@ -64,14 +64,12 @@ var nunjucks =
 
 	module.exports.Loader = Loader;
 	module.exports.FileSystemLoader = loaders.FileSystemLoader;
-	module.exports.PrecompiledLoader = loaders.PrecompiledLoader;
 	module.exports.WebLoader = loaders.WebLoader;
 
 	module.exports.compiler = compiler;
 	module.exports.parser = parser;
 	module.exports.lexer = lexer;
 	module.exports.runtime = runtime;
-	module.exports.lib = lib;
 
 	// A single instance of an environment, since this is so commonly used
 
@@ -90,7 +88,7 @@ var nunjucks =
 	            noCache: opts.noCache
 	        });
 	    }
-	    else if(loaders.WebLoader) {
+	    else {
 	        TemplateLoader = new loaders.WebLoader(templatesPath, {
 	            useCache: opts.web && opts.web.useCache,
 	            async: opts.web && opts.web.async
@@ -427,19 +425,15 @@ var nunjucks =
 	var path = __webpack_require__(9);
 	var asap = __webpack_require__(10);
 	var lib = __webpack_require__(1);
-	var Obj = __webpack_require__(5);
+	var Obj = __webpack_require__(6);
 	var compiler = __webpack_require__(9);
-	var builtin_filters = __webpack_require__(6);
-	var builtin_loaders = __webpack_require__(9);
+	var builtin_filters = __webpack_require__(7);
+	var builtin_loaders = __webpack_require__(5);
 	var runtime = __webpack_require__(3);
-	var globals = __webpack_require__(7);
+	var globals = __webpack_require__(8);
 	var Frame = runtime.Frame;
 	var Template;
 
-	// Unconditionally load in this loader, even if no other ones are
-	// included (possible in the slim browser build)
-	builtin_loaders.PrecompiledLoader = __webpack_require__(8);
-
 	// If the user is using the async API, *always* call it
 	// asynchronously even if the template was synchronous.
 	function callbackAsap(cb, err, res) {
@@ -460,23 +454,22 @@ var nunjucks =
 	        // The autoescape flag sets global autoescaping. If true,
 	        // every string variable will be escaped by default.
 	        // If false, strings can be manually escaped using the `escape` filter.
-	        // defaults to true
-	        this.opts.autoescape = opts.autoescape != null ? opts.autoescape : true;
+	        // defaults to false
+	        this.opts.autoescape = !!opts.autoescape;
 
 	        // If true, this will make the system throw errors if trying
 	        // to output a null or undefined value
 	        this.opts.throwOnUndefined = !!opts.throwOnUndefined;
+
 	        this.opts.trimBlocks = !!opts.trimBlocks;
 	        this.opts.lstripBlocks = !!opts.lstripBlocks;
 
-	        this.loaders = [];
-
 	        if(!loaders) {
-	            // The filesystem loader is only available server-side
+	            // The filesystem loader is only available client-side
 	            if(builtin_loaders.FileSystemLoader) {
 	                this.loaders = [new builtin_loaders.FileSystemLoader('views')];
 	            }
-	            else if(builtin_loaders.WebLoader) {
+	            else {
 	                this.loaders = [new builtin_loaders.WebLoader('/views')];
 	            }
 	        }
@@ -484,15 +477,6 @@ var nunjucks =
 	            this.loaders = lib.isArray(loaders) ? loaders : [loaders];
 	        }
 
-	        // It's easy to use precompiled templates: just include them
-	        // before you configure nunjucks and this will automatically
-	        // pick it up and use it
-	        if((true) && window.nunjucksPrecompiled) {
-	            this.loaders.unshift(
-	                new builtin_loaders.PrecompiledLoader(window.nunjucksPrecompiled)
-	            );
-	        }
-
 	        this.initCache();
 	        this.filters = {};
 	        this.asyncFilters = [];
@@ -596,7 +580,30 @@ var nunjucks =
 	            var syncResult;
 	            var _this = this;
 
-	            var createTemplate = function(info) {
+	            lib.asyncIter(this.loaders, function(loader, i, next, done) {
+	                function handle(src) {
+	                    if(src) {
+	                        src.loader = loader;
+	                        done(src);
+	                    }
+	                    else {
+	                        next();
+	                    }
+	                }
+
+	                // Resolve name relative to parentName
+	                name = that.resolveTemplate(loader, parentName, name);
+
+	                if(loader.async) {
+	                    loader.getSource(name, function(err, src) {
+	                        if(err) { throw err; }
+	                        handle(src);
+	                    });
+	                }
+	                else {
+	                    handle(loader.getSource(name));
+	                }
+	            }, function(info) {
 	                if(!info) {
 	                    var err = new Error('template not found: ' + name);
 	                    if(cb) {
@@ -621,32 +628,7 @@ var nunjucks =
 	                        syncResult = tmpl;
 	                    }
 	                }
-	            };
-
-	            lib.asyncIter(this.loaders, function(loader, i, next, done) {
-	                function handle(src) {
-	                    if(src) {
-	                        src.loader = loader;
-	                        done(src);
-	                    }
-	                    else {
-	                        next();
-	                    }
-	                }
-
-	                // Resolve name relative to parentName
-	                name = that.resolveTemplate(loader, parentName, name);
-
-	                if(loader.async) {
-	                    loader.getSource(name, function(err, src) {
-	                        if(err) { throw err; }
-	                        handle(src);
-	                    });
-	                }
-	                else {
-	                    handle(loader.getSource(name));
-	                }
-	            }, createTemplate);
+	            });
 
 	            return syncResult;
 	        }
@@ -932,6 +914,7 @@ var nunjucks =
 	            var source = compiler.compile(this.tmplStr,
 	                                          this.env.asyncFilters,
 	                                          this.env.extensionsList,
+	                                          this.env.opts.throwOnUndefined,
 	                                          this.path,
 	                                          this.env.opts);
 
@@ -971,7 +954,7 @@ var nunjucks =
 	'use strict';
 
 	var lib = __webpack_require__(1);
-	var Obj = __webpack_require__(5);
+	var Obj = __webpack_require__(6);
 
 	// Frames keep track of scoping both at compile-time and run-time so
 	// we know how to access variables. Block tags can introduce special
@@ -1336,7 +1319,7 @@ var nunjucks =
 	'use strict';
 
 	var path = __webpack_require__(9);
-	var Obj = __webpack_require__(5);
+	var Obj = __webpack_require__(6);
 	var lib = __webpack_require__(1);
 
 	var Loader = Obj.extend({
@@ -1374,6 +1357,114 @@ var nunjucks =
 
 	'use strict';
 
+	var Loader = __webpack_require__(4);
+
+	var WebLoader = Loader.extend({
+	    init: function(baseURL, opts) {
+	        // It's easy to use precompiled templates: just include them
+	        // before you configure nunjucks and this will automatically
+	        // pick it up and use it
+	        this.precompiled = window.nunjucksPrecompiled || {};
+
+	        this.baseURL = baseURL || '';
+
+	        // By default, the cache is turned off because there's no way
+	        // to "watch" templates over HTTP, so they are re-downloaded
+	        // and compiled each time. (Remember, PRECOMPILE YOUR
+	        // TEMPLATES in production!)
+	        this.useCache = opts.useCache;
+
+	        // We default `async` to false so that the simple synchronous
+	        // API can be used when you aren't doing anything async in
+	        // your templates (which is most of the time). This performs a
+	        // sync ajax request, but that's ok because it should *only*
+	        // happen in development. PRECOMPILE YOUR TEMPLATES.
+	        this.async = opts.async;
+	    },
+
+	    resolve: function(from, to) {
+	        throw new Error('relative templates not support in the browser yet');
+	    },
+
+	    getSource: function(name, cb) {
+	        if(this.precompiled[name]) {
+	            return {
+	                src: { type: 'code',
+	                       obj: this.precompiled[name] },
+	                path: name
+	            };
+	        }
+	        else {
+	            var useCache = this.useCache;
+	            var result;
+	            this.fetch(this.baseURL + '/' + name, function(err, src) {
+	                if(err) {
+	                    if(!cb) {
+	                        throw err;
+	                    }
+	                    cb(err);
+	                }
+	                else {
+	                    result = { src: src,
+	                               path: name,
+	                               noCache: !useCache };
+	                    if(cb) {
+	                        cb(null, result);
+	                    }
+	                }
+	            });
+
+	            // if this WebLoader isn't running asynchronously, the
+	            // fetch above would actually run sync and we'll have a
+	            // result here
+	            return result;
+	        }
+	    },
+
+	    fetch: function(url, cb) {
+	        // Only in the browser please
+	        var ajax;
+	        var loading = true;
+
+	        if(window.XMLHttpRequest) { // Mozilla, Safari, ...
+	            ajax = new XMLHttpRequest();
+	        }
+	        else if(window.ActiveXObject) { // IE 8 and older
+	            /* global ActiveXObject */
+	            ajax = new ActiveXObject('Microsoft.XMLHTTP');
+	        }
+
+	        ajax.onreadystatechange = function() {
+	            if(ajax.readyState === 4 && loading) {
+	                loading = false;
+	                if(ajax.status === 0 || ajax.status === 200) {
+	                    cb(null, ajax.responseText);
+	                }
+	                else {
+	                    cb(ajax.responseText);
+	                }
+	            }
+	        };
+
+	        url += (url.indexOf('?') === -1 ? '?' : '&') + 's=' +
+	               (new Date().getTime());
+
+	        ajax.open('GET', url, this.async);
+	        ajax.send();
+	    }
+	});
+
+	module.exports = {
+	    WebLoader: WebLoader
+	};
+
+
+/***/ },
+/* 6 */
+/***/ function(module, exports, __webpack_require__) {
+
+	'use strict';
+
 	// A simple class system, more documentation to come
 
 	function extend(cls, name, props) {
@@ -1439,7 +1530,7 @@ var nunjucks =
 
 
 /***/ },
-/* 6 */
+/* 7 */
 /***/ function(module, exports, __webpack_require__) {
 
 	'use strict';
@@ -1454,7 +1545,6 @@ var nunjucks =
 	    return value;
 	}
 
-	var hasWarnedDefault = false;
 
 	var filters = {
 	    abs: function(n) {
@@ -1508,25 +1598,8 @@ var nunjucks =
 	        return r.copySafeness(str, pre + str + post);
 	    },
 
-	    'default': function(val, def, bool) {
-	        if(bool !== true && bool !== false && !hasWarnedDefault) {
-	            hasWarnedDefault = true;
-	            console.log(
-	                '[nunjucks] Warning: the "default" filter was used without ' +
-	                'specifying the type of comparison. 2.0 changed the default ' +
-	                'behavior from boolean (val ? val : def) to strictly undefined, ' +
-	                'so you should make sure that doesn\'t break anything. ' +
-	                'Be explicit about this to make this warning go away, or wait until 2.1. ' +
-	                'See http://mozilla.github.io/nunjucks/templating.html#defaultvalue-default-boolean'
-	            );
-	        }
-
-	        if(bool) {
-	            return val ? val : def;
-	        }
-	        else {
-	            return (val !== undefined) ? val : def;
-	        }
+	    'default': function(val, def) {
+	        return val ? val : def;
 	    },
 
 	    dictsort: function(val, case_sensitive, by) {
@@ -1939,8 +2012,11 @@ var nunjucks =
 	          return word && word.length;
 	        }).map(function(word) {
 	          var matches = word.match(puncRE);
+
+
 	          var possibleUrl = matches && matches[1] || word;
 
+
 	          // url that starts with http or https
 	          if (httpHttpsRE.test(possibleUrl))
 	            return '<a href="' + possibleUrl + '"' + noFollowAttr + '>' + possibleUrl.substr(0, length) + '</a>';
@@ -1989,7 +2065,7 @@ var nunjucks =
 
 
 /***/ },
-/* 7 */
+/* 8 */
 /***/ function(module, exports, __webpack_require__) {
 
 	'use strict';
@@ -2061,34 +2137,6 @@ var nunjucks =
 	module.exports = globals;
 
 
-/***/ },
-/* 8 */
-/***/ function(module, exports, __webpack_require__) {
-
-	'use strict';
-
-	var Loader = __webpack_require__(4);
-
-	var PrecompiledLoader = Loader.extend({
-	    init: function(compiledTemplates) {
-	        this.precompiled = compiledTemplates || {};
-	    },
-
-	    getSource: function(name) {
-	        if (this.precompiled[name]) {
-	            return {
-	                src: { type: 'code',
-	                       obj: this.precompiled[name] },
-	                path: name
-	            };
-	        }
-	        return null;
-	    }
-	});
-
-	module.exports = PrecompiledLoader;
-
-
 /***/ },
 /* 9 */
 /***/ function(module, exports, __webpack_require__) {
diff --git a/browser/nunjucks-slim.min.js b/browser/nunjucks-slim.min.js
index 7adce12..f585650 100644
--- a/browser/nunjucks-slim.min.js
+++ b/browser/nunjucks-slim.min.js
@@ -1,2 +1,2 @@
 /*! Browser bundle of nunjucks 1.3.5-unreleased (slim, only works with precompiled templates) */
-var nunjucks=function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return t[r].call(i.exports,i,i.exports,e),i.loaded=!0,i.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){"use strict";var r=n(1),i=n(2),o=n(9),s=n(9),a=n(9),u=n(3),c=n(4),l=n(9),f=n(9);t.exports={},t.exports.Environment=i.Environment,t.exports.Template=i.Template,t.exports.Loader=c,t.exports.FileSystemLoader=l.FileSystemLoader,t.exports.PrecompiledLoader=l.PrecompiledLoader,t.exports.WebLoader=l.WebLoader,t.exports.compiler=o,t.exports.parser=s,t.exports.lexer=a,t.exports.runtime=u,t.exports.lib=r;var p;t.exports.configure=function(t,e){e=e||{},r.isObject(t)&&(e=t,t=null);var n;return l.FileSystemLoader?n=new l.FileSystemLoader(t,{watch:e.watch,noCache:e.noCache}):l.WebLoader&&(n=new l.WebLoader(t,{useCache:e.web&&e.web.useCache,async:e.web&&e.web.async})),p=new i.Environment(n,e),e&&e.express&&p.express(e.express),p},t.exports.compile=function(e,n,r,i){return p||t.exports.configure(),new t.exports.Template(e,n,r,i)},t.exports.render=function(e,n,r){return p||t.exports.configure(),p.render(e,n,r)},t.exports.renderString=function(e,n,r){return p||t.exports.configure(),p.renderString(e,n,r)},f&&(t.exports.precompile=f.precompile,t.exports.precompileString=f.precompileString)},function(t,e,n){"use strict";var r=Array.prototype,i=Object.prototype,o={"&":"&amp;",'"':"&quot;","'":"&#39;","<":"&lt;",">":"&gt;"},s=/[&"'<>]/g,a=function(t){return o[t]},e=t.exports={};e.prettifyError=function(t,n,r){if(r.Update||(r=new e.TemplateError(r)),r.Update(t),!n){var i=r;r=new Error(i.message),r.name=i.name}return r},e.TemplateError=function(t,e,n){var r=this;return t instanceof Error?(r=t,t=t.name+": "+t.message):Error.captureStackTrace&&Error.captureStackTrace(r),r.name="Template render error",r.message=t,r.lineno=e,r.colno=n,r.firstUpdate=!0,r.Update=function(t){var e="("+(t||"unknown path")+")";return this.firstUpdate&&(this.lineno&&this.colno?e+=" [Line "+this.lineno+", Column "+this.colno+"]":this.lineno&&(e+=" [Line "+this.lineno+"]")),e+="\n ",this.firstUpdate&&(e+=" "),this.message=e+(this.message||""),this.firstUpdate=!1,this},r},e.TemplateError.prototype=Error.prototype,e.escape=function(t){return t.replace(s,a)},e.isFunction=function(t){return"[object Function]"===i.toString.call(t)},e.isArray=Array.isArray||function(t){return"[object Array]"===i.toString.call(t)},e.isString=function(t){return"[object String]"===i.toString.call(t)},e.isObject=function(t){return"[object Object]"===i.toString.call(t)},e.groupBy=function(t,n){for(var r={},i=e.isFunction(n)?n:function(t){return t[n]},o=0;o<t.length;o++){var s=t[o],a=i(s,o);(r[a]||(r[a]=[])).push(s)}return r},e.toArray=function(t){return Array.prototype.slice.call(t)},e.without=function(t){var n=[];if(!t)return n;for(var r=-1,i=t.length,o=e.toArray(arguments).slice(1);++r<i;)-1===e.indexOf(o,t[r])&&n.push(t[r]);return n},e.extend=function(t,e){for(var n in e)t[n]=e[n];return t},e.repeat=function(t,e){for(var n="",r=0;e>r;r++)n+=t;return n},e.each=function(t,e,n){if(null!=t)if(r.each&&t.each===r.each)t.forEach(e,n);else if(t.length===+t.length)for(var i=0,o=t.length;o>i;i++)e.call(n,t[i],i,t)},e.map=function(t,e){var n=[];if(null==t)return n;if(r.map&&t.map===r.map)return t.map(e);for(var i=0;i<t.length;i++)n[n.length]=e(t[i],i);return t.length===+t.length&&(n.length=t.length),n},e.asyncIter=function(t,e,n){function r(){i++,i<t.length?e(t[i],i,r,n):n()}var i=-1;r()},e.asyncFor=function(t,n,r){function i(){a++;var e=o[a];s>a?n(e,t[e],a,s,i):r()}var o=e.keys(t),s=o.length,a=-1;i()},e.indexOf=Array.prototype.indexOf?function(t,e,n){return Array.prototype.indexOf.call(t,e,n)}:function(t,e,n){var r=this.length>>>0;for(n=+n||0,Math.abs(n)===1/0&&(n=0),0>n&&(n+=r,0>n&&(n=0));r>n;n++)if(t[n]===e)return n;return-1},Array.prototype.map||(Array.prototype.map=function(){throw new Error("map is unimplemented for this js engine")}),e.keys=function(t){if(Object.prototype.keys)return t.keys();var e=[];for(var n in t)t.hasOwnProperty(n)&&e.push(n);return e}},function(t,e,n){"use strict";function r(t,e,n){s(function(){t(e,n)})}var i,o=n(9),s=n(10),a=n(1),u=n(5),c=n(9),l=n(6),f=n(9),p=n(3),h=n(7),v=p.Frame;f.PrecompiledLoader=n(8);var d=u.extend({init:function(t,e){e=this.opts=e||{},this.opts.dev=!!e.dev,this.opts.autoescape=null!=e.autoescape?e.autoescape:!0,this.opts.throwOnUndefined=!!e.throwOnUndefined,this.opts.trimBlocks=!!e.trimBlocks,this.opts.lstripBlocks=!!e.lstripBlocks,this.loaders=[],t?this.loaders=a.isArray(t)?t:[t]:f.FileSystemLoader?this.loaders=[new f.FileSystemLoader("views")]:f.WebLoader&&(this.loaders=[new f.WebLoader("/views")]),window.nunjucksPrecompiled&&this.loaders.unshift(new f.PrecompiledLoader(window.nunjucksPrecompiled)),this.initCache(),this.filters={},this.asyncFilters=[],this.extensions={},this.extensionsList=[];for(var n in l)this.addFilter(n,l[n])},initCache:function(){a.each(this.loaders,function(t){t.cache={},"function"==typeof t.on&&t.on("update",function(e){t.cache[e]=null})})},addExtension:function(t,e){e._name=t,this.extensions[t]=e,this.extensionsList.push(e)},getExtension:function(t){return this.extensions[t]},addGlobal:function(t,e){h[t]=e},addFilter:function(t,e,n){var r=e;n&&this.asyncFilters.push(t),this.filters[t]=r},getFilter:function(t){if(!this.filters[t])throw new Error("filter not found: "+t);return this.filters[t]},resolveTemplate:function(t,e,n){var r=t.isRelative&&e?t.isRelative(n):!1;return r&&t.resolve?t.resolve(e,n):n},getTemplate:function(t,e,n,r){var o=this,s=null;if(t&&t.raw&&(t=t.raw),a.isFunction(n)&&(r=n,n=null,e=e||!1),a.isFunction(e)&&(r=e,e=!1),"string"!=typeof t)throw new Error("template names must be a string: "+t);for(var u=0;u<this.loaders.length;u++){var c=this.resolveTemplate(this.loaders[u],n,t);if(s=this.loaders[u].cache[c])break}if(!s){var l,f=this,p=function(n){if(n){var o=new i(n.src,f,n.path,e);n.noCache||(n.loader.cache[t]=o),r?r(null,o):l=o}else{var s=new Error("template not found: "+t);if(!r)throw s;r(s)}};return a.asyncIter(this.loaders,function(e,r,i,s){function a(t){t?(t.loader=e,s(t)):i()}t=o.resolveTemplate(e,n,t),e.async?e.getSource(t,function(t,e){if(t)throw t;a(e)}):a(e.getSource(t))},p),l}return e&&s.compile(),r?void r(null,s):s},express:function(t){function e(t,e){if(this.name=t,this.path=t,this.defaultEngine=e.defaultEngine,this.ext=o.extname(t),!this.ext&&!this.defaultEngine)throw new Error("No default engine was specified and no extension was provided.");this.ext||(this.name+=this.ext=("."!==this.defaultEngine[0]?".":"")+this.defaultEngine)}var n=this;e.prototype.render=function(t,e){n.render(this.name,t,e)},t.set("view",e)},render:function(t,e,n){a.isFunction(e)&&(n=e,e=null);var i=null;return this.getTemplate(t,function(t,o){if(t&&n)r(n,t);else{if(t)throw t;i=o.render(e,n)}}),i},renderString:function(t,e,n,r){a.isFunction(n)&&(r=n,n={}),n=n||{};var o=new i(t,this,n.path);return o.render(e,r)}}),g=u.extend({init:function(t,e){this.ctx={};for(var n in t)t.hasOwnProperty(n)&&(this.ctx[n]=t[n]);this.blocks={},this.exported=[];for(var r in e)this.addBlock(r,e[r])},lookup:function(t){return t in h&&!(t in this.ctx)?h[t]:this.ctx[t]},setVariable:function(t,e){this.ctx[t]=e},getVariables:function(){return this.ctx},addBlock:function(t,e){this.blocks[t]=this.blocks[t]||[],this.blocks[t].push(e)},getBlock:function(t){if(!this.blocks[t])throw new Error('unknown block "'+t+'"');return this.blocks[t][0]},getSuper:function(t,e,n,r,i,o){var s=a.indexOf(this.blocks[e]||[],n),u=this.blocks[e][s+1],c=this;if(-1===s||!u)throw new Error('no super block available for "'+e+'"');u(t,c,r,i,o)},addExport:function(t){this.exported.push(t)},getExported:function(){for(var t={},e=0;e<this.exported.length;e++){var n=this.exported[e];t[n]=this.ctx[n]}return t}});i=u.extend({init:function(t,e,n,r){if(this.env=e||new d,a.isObject(t))switch(t.type){case"code":this.tmplProps=t.obj;break;case"string":this.tmplStr=t.obj}else{if(!a.isString(t))throw new Error("src must be a string or an object describing the source");this.tmplStr=t}if(this.path=n,r){var i=this;try{i._compile()}catch(o){throw a.prettifyError(this.path,this.env.dev,o)}}else this.compiled=!1},render:function(t,e,n){"function"==typeof t?(n=t,t={}):"function"==typeof e&&(n=e,e=null);var i=!0;e&&(i=!1);var o=this;try{o.compile()}catch(s){var u=a.prettifyError(this.path,this.env.dev,s);if(n)return r(n,u);throw u}var c=new g(t||{},o.blocks),l=e?e.push():new v;l.topLevel=!0;var f=null;return o.rootRenderFunc(o.env,c,l||new v,p,function(t,e){if(t&&(t=a.prettifyError(o.path,o.env.dev,t)),n)i?r(n,t,e):n(t,e);else{if(t)throw t;f=e}}),f},getExported:function(t,e,n){"function"==typeof t&&(n=t,t={}),"function"==typeof e&&(n=e,e=null);try{this.compile()}catch(r){if(n)return n(r);throw r}var i=e?e.push():new v;i.topLevel=!0;var o=new g(t||{},this.blocks);this.rootRenderFunc(this.env,o,i,p,function(){n(null,o.getExported())})},compile:function(){this.compiled||this._compile()},_compile:function(){var t;if(this.tmplProps)t=this.tmplProps;else{var e=c.compile(this.tmplStr,this.env.asyncFilters,this.env.extensionsList,this.path,this.env.opts),n=new Function(e);t=n()}this.blocks=this._getBlocks(t),this.rootRenderFunc=t.root,this.compiled=!0},_getBlocks:function(t){var e={};for(var n in t)"b_"===n.slice(0,2)&&(e[n.slice(2)]=t[n]);return e}}),t.exports={Environment:d,Template:i}},function(t,e,n){"use strict";function r(t,e,n){return function(){var r,i,a=s(arguments),u=o(arguments);if(a>t.length){r=Array.prototype.slice.call(arguments,0,t.length);var c=Array.prototype.slice.call(arguments,r.length,a);for(i=0;i<c.length;i++)i<e.length&&(u[e[i]]=c[i]);r.push(u)}else if(a<t.length){for(r=Array.prototype.slice.call(arguments,0,a),i=a;i<t.length;i++){var l=t[i];r.push(u[l]),delete u[l]}r.push(u)}else r=arguments;return n.apply(this,r)}}function i(t){return t.__keywords=!0,t}function o(t){var e=t.length;if(e){var n=t[e-1];if(n&&n.hasOwnProperty("__keywords"))return n}return{}}function s(t){var e=t.length;if(0===e)return 0;var n=t[e-1];return n&&n.hasOwnProperty("__keywords")?e-1:e}function a(t){return"string"!=typeof t?t:(this.val=t,void(this.length=t.length))}function u(t,e){return t instanceof a?new a(e):e.toString()}function c(t){var e=typeof t;return"string"===e?new a(t):"function"!==e?t:function(){var e=t.apply(this,arguments);return"string"==typeof e?new a(e):e}}function l(t,e){return t=void 0!==t&&null!==t?t:"",e&&"string"==typeof t&&(t=m.escape(t)),t}function f(t,e,n){if(null===t||void 0===t)throw new m.TemplateError("attempted to output null or undefined value",e+1,n+1);return t}function p(t,e){return t=t||{},"function"==typeof t[e]?function(){return t[e].apply(t,arguments)}:t[e]}function h(t,e,n){if(!t)throw new Error("Unable to call `"+e+"`, which is undefined or falsey");if("function"!=typeof t)throw new Error("Unable to call `"+e+"`, which is not a function");return t.apply(this,n)}function v(t,e,n){var r=e.lookup(n);return void 0!==r&&null!==r?r:t.lookup(n)}function d(t,e,n){return t.lineno?t:new m.TemplateError(t,e,n)}function g(t,e,n,r){if(m.isArray(t)){var i=t.length;m.asyncIter(t,function(t,r,o){switch(e){case 1:n(t,r,i,o);break;case 2:n(t[0],t[1],r,i,o);break;case 3:n(t[0],t[1],t[2],r,i,o);break;default:t.push(r,o),n.apply(this,t)}},r)}else m.asyncFor(t,function(t,e,r,i,o){n(t,e,r,i,o)},r)}function y(t,e,n,r){function i(t,e){u++,a[t]=e,u===o&&r(null,a.join(""))}var o,s,a,u=0;if(m.isArray(t))if(o=t.length,a=new Array(o),0===o)r(null,"");else for(s=0;s<t.length;s++){var c=t[s];switch(e){case 1:n(c,s,o,i);break;case 2:n(c[0],c[1],s,o,i);break;case 3:n(c[0],c[1],c[2],s,o,i);break;default:c.push(s,i),n.apply(this,c)}}else{var l=m.keys(t);if(o=l.length,a=new Array(o),0===o)r(null,"");else for(s=0;s<l.length;s++){var f=l[s];n(f,t[f],s,o,i)}}}var m=n(1),w=n(5),b=w.extend({init:function(t){this.variables={},this.parent=t,this.topLevel=!1},set:function(t,e,n){var r=t.split("."),i=this.variables,o=this;if(n){if(o=this.resolve(r[0]))return void o.set(t,e);o=this}for(var s=0;s<r.length-1;s++){var a=r[s];i[a]||(i[a]={}),i=i[a]}i[r[r.length-1]]=e},get:function(t){var e=this.variables[t];return void 0!==e&&null!==e?e:null},lookup:function(t){var e=this.parent,n=this.variables[t];return void 0!==n&&null!==n?n:e&&e.lookup(t)},resolve:function(t){var e=this.parent,n=this.variables[t];return void 0!==n&&null!==n?this:e&&e.resolve(t)},push:function(){return new b(this)},pop:function(){return this.parent}});a.prototype=Object.create(String.prototype,{length:{writable:!0,configurable:!0,value:0}}),a.prototype.valueOf=function(){return this.val},a.prototype.toString=function(){return this.val},t.exports={Frame:b,makeMacro:r,makeKeywordArgs:i,numArgs:s,suppressValue:l,ensureDefined:f,memberLookup:p,contextOrFrameLookup:v,callWrap:h,handleError:d,isArray:m.isArray,keys:m.keys,SafeString:a,copySafeness:u,markSafe:c,asyncEach:g,asyncAll:y}},function(t,e,n){"use strict";var r=n(9),i=n(5),o=n(1),s=i.extend({on:function(t,e){this.listeners=this.listeners||{},this.listeners[t]=this.listeners[t]||[],this.listeners[t].push(e)},emit:function(t){var e=Array.prototype.slice.call(arguments,1);this.listeners&&this.listeners[t]&&o.each(this.listeners[t],function(t){t.apply(null,e)})},resolve:function(t,e){return r.resolve(r.dirname(t),e)},isRelative:function(t){return 0===t.indexOf("./")||0===t.indexOf("../")}});t.exports=s},function(t,e,n){"use strict";function r(t,e,n){var i=function(){};i.prototype=t.prototype;var o=new i,s=/xyz/.test(function(){xyz})?/\bparent\b/:/.*/;n=n||{};for(var a in n){var u=n[a],c=o[a];"function"==typeof c&&"function"==typeof u&&s.test(u)?o[a]=function(t,e){return function(){var n=this.parent;this.parent=e;var r=t.apply(this,arguments);return this.parent=n,r}}(u,c):o[a]=u}o.typename=e;var l=function(){o.init&&o.init.apply(this,arguments)};return l.prototype=o,l.prototype.constructor=l,l.extend=function(t,e){return"object"==typeof t&&(e=t,t="anonymous"),r(l,t,e)},l}t.exports=r(Object,"Object",{})},function(t,e,n){"use strict";function r(t,e){return null===t||void 0===t||t===!1?e:t}var i=n(1),o=n(3),s=!1,a={abs:function(t){return Math.abs(t)},batch:function(t,e,n){var r,i=[],o=[];for(r=0;r<t.length;r++)r%e===0&&o.length&&(i.push(o),o=[]),o.push(t[r]);if(o.length){if(n)for(r=o.length;e>r;r++)o.push(n);i.push(o)}return i},capitalize:function(t){t=r(t,"");var e=t.toLowerCase();return o.copySafeness(t,e.charAt(0).toUpperCase()+e.slice(1))},center:function(t,e){if(t=r(t,""),e=e||80,t.length>=e)return t;var n=e-t.length,s=i.repeat(" ",n/2-n%2),a=i.repeat(" ",n/2);return o.copySafeness(t,s+t+a)},"default":function(t,e,n){return n===!0||n===!1||s||(s=!0,console.log('[nunjucks] Warning: the "default" filter was used without specifying the type of comparison. 2.0 changed the default behavior from boolean (val ? val : def) to strictly undefined, so you should make sure that doesn\'t break anything. Be explicit about this to make this warning go away, or wait until 2.1. See http://mozilla.github.io/nunjucks/templating.html#defaultvalue-default-boolean')),n?t?t:e:void 0!==t?t:e},dictsort:function(t,e,n){if(!i.isObject(t))throw new i.TemplateError("dictsort filter: val must be an object");var r=[];for(var o in t)r.push([o,t[o]]);var s;if(void 0===n||"key"===n)s=0;else{if("value"!==n)throw new i.TemplateError("dictsort filter: You can only sort by either key or value");s=1}return r.sort(function(t,n){var r=t[s],o=n[s];return e||(i.isString(r)&&(r=r.toUpperCase()),i.isString(o)&&(o=o.toUpperCase())),r>o?1:r===o?0:-1}),r},dump:function(t){return JSON.stringify(t)},escape:function(t){return"string"==typeof t||t instanceof o.SafeString?i.escape(t):t},safe:function(t){return o.markSafe(t)},first:function(t){return t[0]},groupby:function(t,e){return i.groupBy(t,e)},indent:function(t,e,n){if(t=r(t,""),""===t)return"";e=e||4;for(var s="",a=t.split("\n"),u=i.repeat(" ",e),c=0;c<a.length;c++)s+=0!==c||n?u+a[c]+"\n":a[c]+"\n";return o.copySafeness(t,s)},join:function(t,e,n){return e=e||"",n&&(t=i.map(t,function(t){return t[n]})),t.join(e)},last:function(t){return t[t.length-1]},length:function(t){var e=r(t,"");return void 0!==e?e.length:0},list:function(t){if(i.isString(t))return t.split("");if(i.isObject(t)){var e=[];if(Object.keys)e=Object.keys(t);else for(var n in t)e.push(n);return i.map(e,function(e){return{key:e,value:t[e]}})}if(i.isArray(t))return t;throw new i.TemplateError("list filter: type not iterable")},lower:function(t){return t=r(t,""),t.toLowerCase()},random:function(t){return t[Math.floor(Math.random()*t.length)]},rejectattr:function(t,e){return t.filter(function(t){return!t[e]})},selectattr:function(t,e){return t.filter(function(t){return!!t[e]})},replace:function(t,e,n,r){var i=t;if(e instanceof RegExp)return t.replace(e,n);"undefined"==typeof r&&(r=-1);var s="";if("number"==typeof e)e+="";else if("string"!=typeof e)return t;if("number"==typeof t&&(t+=""),"string"!=typeof t&&!(t instanceof o.SafeString))return t;if(""===e)return s=n+t.split("").join(n)+n,o.copySafeness(t,s);var a=t.indexOf(e);if(0===r||-1===a)return t;for(var u=0,c=0;a>-1&&(-1===r||r>c);)s+=t.substring(u,a)+n,u=a+e.length,c++,a=t.indexOf(e,u);return u<t.length&&(s+=t.substring(u)),o.copySafeness(i,s)},reverse:function(t){var e;return e=i.isString(t)?a.list(t):i.map(t,function(t){return t}),e.reverse(),i.isString(t)?o.copySafeness(t,e.join("")):e},round:function(t,e,n){e=e||0;var r,i=Math.pow(10,e);return r="ceil"===n?Math.ceil:"floor"===n?Math.floor:Math.round,r(t*i)/i},slice:function(t,e,n){for(var r=Math.floor(t.length/e),i=t.length%e,o=0,s=[],a=0;e>a;a++){var u=o+a*r;i>a&&o++;var c=o+(a+1)*r,l=t.slice(u,c);n&&a>=i&&l.push(n),s.push(l)}return s},sort:function(t,e,n,r){return t=i.map(t,function(t){return t}),t.sort(function(t,o){var s,a;return r?(s=t[r],a=o[r]):(s=t,a=o),!n&&i.isString(s)&&i.isString(a)&&(s=s.toLowerCase(),a=a.toLowerCase()),a>s?e?1:-1:s>a?e?-1:1:0}),t},string:function(t){return o.copySafeness(t,t)},title:function(t){t=r(t,"");for(var e=t.split(" "),n=0;n<e.length;n++)e[n]=a.capitalize(e[n]);return o.copySafeness(t,e.join(" "))},trim:function(t){return o.copySafeness(t,t.replace(/^\s*|\s*$/g,""))},truncate:function(t,e,n,i){var s=t;if(t=r(t,""),e=e||255,t.length<=e)return t;if(n)t=t.substring(0,e);else{var a=t.lastIndexOf(" ",e);-1===a&&(a=e),t=t.substring(0,a)}return t+=void 0!==i&&null!==i?i:"...",o.copySafeness(s,t)},upper:function(t){return t=r(t,""),t.toUpperCase()},urlencode:function(t){var e=encodeURIComponent;if(i.isString(t))return e(t);var n;if(i.isArray(t))n=t.map(function(t){return e(t[0])+"="+e(t[1])});else{n=[];for(var r in t)t.hasOwnProperty(r)&&n.push(e(r)+"="+e(t[r]))}return n.join("&")},urlize:function(t,e,n){isNaN(e)&&(e=1/0);var r=n===!0?' rel="nofollow"':"",i=/^(?:\(|<|&lt;)?(.*?)(?:\.|,|\)|\n|&gt;)?$/,o=/^[\w.!#$%&'*+\-\/=?\^`{|}~]+@[a-z\d\-]+(\.[a-z\d\-]+)+$/i,s=/^https?:\/\/.*$/,a=/^www\./,u=/\.(?:org|net|com)(?:\:|\/|$)/,c=t.split(/\s+/).filter(function(t){return t&&t.length}).map(function(t){var n=t.match(i),c=n&&n[1]||t;return s.test(c)?'<a href="'+c+'"'+r+">"+c.substr(0,e)+"</a>":a.test(c)?'<a href="http://'+c+'"'+r+">"+c.substr(0,e)+"</a>":o.test(c)?'<a href="mailto:'+c+'">'+c+"</a>":u.test(c)?'<a href="http://'+c+'"'+r+">"+c.substr(0,e)+"</a>":t});return c.join(" ")},wordcount:function(t){t=r(t,"");var e=t?t.match(/\w+/g):null;return e?e.length:null},"float":function(t,e){var n=parseFloat(t);return isNaN(n)?e:n},"int":function(t,e){var n=parseInt(t,10);return isNaN(n)?e:n}};a.d=a["default"],a.e=a.escape,t.exports=a},function(t,e,n){"use strict";function r(t){var e=-1;return{current:null,reset:function(){e=-1,this.current=null},next:function(){return e++,e>=t.length&&(e=0),this.current=t[e],this.current}}}function i(t){t=t||",";var e=!0;return function(){var n=e?"":t;return e=!1,n}}var o={range:function(t,e,n){e?n||(n=1):(e=t,t=0,n=1);for(var r=[],i=t;e>i;i+=n)r.push(i);return r},cycler:function(){return r(Array.prototype.slice.call(arguments))},joiner:function(t){return i(t)}};t.exports=o},function(t,e,n){"use strict";var r=n(4),i=r.extend({init:function(t){this.precompiled=t||{}},getSource:function(t){return this.precompiled[t]?{src:{type:"code",obj:this.precompiled[t]},path:t}:null}});t.exports=i},function(t,e,n){},function(t,e,n){"use strict";function r(){if(u.length)throw u.shift()}function i(t){var e;e=a.length?a.pop():new o,e.task=t,s(e)}function o(){this.task=null}var s=n(11),a=[],u=[],c=s.makeRequestCallFromTimer(r);t.exports=i,o.prototype.call=function(){try{this.task.call()}catch(t){i.onerror?i.onerror(t):(u.push(t),c())}finally{this.task=null,a[a.length]=this}}},function(t,e,n){(function(e){"use strict";function n(t){a.length||(s(),u=!0),a[a.length]=t}function r(){for(;c<a.length;){var t=c;if(c+=1,a[t].call(),c>l){for(var e=0,n=a.length-c;n>e;e++)a[e]=a[e+c];a.length-=c,c=0}}a.length=0,c=0,u=!1}function i(t){var e=1,n=new f(t),r=document.createTextNode("");return n.observe(r,{characterData:!0}),function(){e=-e,r.data=e}}function o(t){return function(){function e(){clearTimeout(n),clearInterval(r),t()}var n=setTimeout(e,0),r=setInterval(e,50)}}t.exports=n;var s,a=[],u=!1,c=0,l=1024,f=e.MutationObserver||e.WebKitMutationObserver;s="function"==typeof f?i(r):o(r),n.requestFlush=s,n.makeRequestCallFromTimer=o}).call(e,function(){return this}())}]);
\ No newline at end of file
+var nunjucks=function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return t[r].call(i.exports,i,i.exports,e),i.loaded=!0,i.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){"use strict";var r=n(1),i=n(2),o=n(9),s=n(9),a=n(9),u=n(3),c=n(4),l=n(5),f=n(9);t.exports={},t.exports.Environment=i.Environment,t.exports.Template=i.Template,t.exports.Loader=c,t.exports.FileSystemLoader=l.FileSystemLoader,t.exports.WebLoader=l.WebLoader,t.exports.compiler=o,t.exports.parser=s,t.exports.lexer=a,t.exports.runtime=u;var p;t.exports.configure=function(t,e){e=e||{},r.isObject(t)&&(e=t,t=null);var n;return n=l.FileSystemLoader?new l.FileSystemLoader(t,{watch:e.watch,noCache:e.noCache}):new l.WebLoader(t,{useCache:e.web&&e.web.useCache,async:e.web&&e.web.async}),p=new i.Environment(n,e),e&&e.express&&p.express(e.express),p},t.exports.compile=function(e,n,r,i){return p||t.exports.configure(),new t.exports.Template(e,n,r,i)},t.exports.render=function(e,n,r){return p||t.exports.configure(),p.render(e,n,r)},t.exports.renderString=function(e,n,r){return p||t.exports.configure(),p.renderString(e,n,r)},f&&(t.exports.precompile=f.precompile,t.exports.precompileString=f.precompileString)},function(t,e,n){"use strict";var r=Array.prototype,i=Object.prototype,o={"&":"&amp;",'"':"&quot;","'":"&#39;","<":"&lt;",">":"&gt;"},s=/[&"'<>]/g,a=function(t){return o[t]},e=t.exports={};e.prettifyError=function(t,n,r){if(r.Update||(r=new e.TemplateError(r)),r.Update(t),!n){var i=r;r=new Error(i.message),r.name=i.name}return r},e.TemplateError=function(t,e,n){var r=this;return t instanceof Error?(r=t,t=t.name+": "+t.message):Error.captureStackTrace&&Error.captureStackTrace(r),r.name="Template render error",r.message=t,r.lineno=e,r.colno=n,r.firstUpdate=!0,r.Update=function(t){var e="("+(t||"unknown path")+")";return this.firstUpdate&&(this.lineno&&this.colno?e+=" [Line "+this.lineno+", Column "+this.colno+"]":this.lineno&&(e+=" [Line "+this.lineno+"]")),e+="\n ",this.firstUpdate&&(e+=" "),this.message=e+(this.message||""),this.firstUpdate=!1,this},r},e.TemplateError.prototype=Error.prototype,e.escape=function(t){return t.replace(s,a)},e.isFunction=function(t){return"[object Function]"===i.toString.call(t)},e.isArray=Array.isArray||function(t){return"[object Array]"===i.toString.call(t)},e.isString=function(t){return"[object String]"===i.toString.call(t)},e.isObject=function(t){return"[object Object]"===i.toString.call(t)},e.groupBy=function(t,n){for(var r={},i=e.isFunction(n)?n:function(t){return t[n]},o=0;o<t.length;o++){var s=t[o],a=i(s,o);(r[a]||(r[a]=[])).push(s)}return r},e.toArray=function(t){return Array.prototype.slice.call(t)},e.without=function(t){var n=[];if(!t)return n;for(var r=-1,i=t.length,o=e.toArray(arguments).slice(1);++r<i;)-1===e.indexOf(o,t[r])&&n.push(t[r]);return n},e.extend=function(t,e){for(var n in e)t[n]=e[n];return t},e.repeat=function(t,e){for(var n="",r=0;e>r;r++)n+=t;return n},e.each=function(t,e,n){if(null!=t)if(r.each&&t.each===r.each)t.forEach(e,n);else if(t.length===+t.length)for(var i=0,o=t.length;o>i;i++)e.call(n,t[i],i,t)},e.map=function(t,e){var n=[];if(null==t)return n;if(r.map&&t.map===r.map)return t.map(e);for(var i=0;i<t.length;i++)n[n.length]=e(t[i],i);return t.length===+t.length&&(n.length=t.length),n},e.asyncIter=function(t,e,n){function r(){i++,i<t.length?e(t[i],i,r,n):n()}var i=-1;r()},e.asyncFor=function(t,n,r){function i(){a++;var e=o[a];s>a?n(e,t[e],a,s,i):r()}var o=e.keys(t),s=o.length,a=-1;i()},e.indexOf=Array.prototype.indexOf?function(t,e,n){return Array.prototype.indexOf.call(t,e,n)}:function(t,e,n){var r=this.length>>>0;for(n=+n||0,Math.abs(n)===1/0&&(n=0),0>n&&(n+=r,0>n&&(n=0));r>n;n++)if(t[n]===e)return n;return-1},Array.prototype.map||(Array.prototype.map=function(){throw new Error("map is unimplemented for this js engine")}),e.keys=function(t){if(Object.prototype.keys)return t.keys();var e=[];for(var n in t)t.hasOwnProperty(n)&&e.push(n);return e}},function(t,e,n){"use strict";function r(t,e,n){s(function(){t(e,n)})}var i,o=n(9),s=n(10),a=n(1),u=n(6),c=n(9),l=n(7),f=n(5),p=n(3),h=n(8),v=p.Frame,d=u.extend({init:function(t,e){e=this.opts=e||{},this.opts.dev=!!e.dev,this.opts.autoescape=!!e.autoescape,this.opts.throwOnUndefined=!!e.throwOnUndefined,this.opts.trimBlocks=!!e.trimBlocks,this.opts.lstripBlocks=!!e.lstripBlocks,t?this.loaders=a.isArray(t)?t:[t]:f.FileSystemLoader?this.loaders=[new f.FileSystemLoader("views")]:this.loaders=[new f.WebLoader("/views")],this.initCache(),this.filters={},this.asyncFilters=[],this.extensions={},this.extensionsList=[];for(var n in l)this.addFilter(n,l[n])},initCache:function(){a.each(this.loaders,function(t){t.cache={},"function"==typeof t.on&&t.on("update",function(e){t.cache[e]=null})})},addExtension:function(t,e){e._name=t,this.extensions[t]=e,this.extensionsList.push(e)},getExtension:function(t){return this.extensions[t]},addGlobal:function(t,e){h[t]=e},addFilter:function(t,e,n){var r=e;n&&this.asyncFilters.push(t),this.filters[t]=r},getFilter:function(t){if(!this.filters[t])throw new Error("filter not found: "+t);return this.filters[t]},resolveTemplate:function(t,e,n){var r=t.isRelative&&e?t.isRelative(n):!1;return r&&t.resolve?t.resolve(e,n):n},getTemplate:function(t,e,n,r){var o=this,s=null;if(t&&t.raw&&(t=t.raw),a.isFunction(n)&&(r=n,n=null,e=e||!1),a.isFunction(e)&&(r=e,e=!1),"string"!=typeof t)throw new Error("template names must be a string: "+t);for(var u=0;u<this.loaders.length;u++){var c=this.resolveTemplate(this.loaders[u],n,t);if(s=this.loaders[u].cache[c])break}if(!s){var l,f=this;return a.asyncIter(this.loaders,function(e,r,i,s){function a(t){t?(t.loader=e,s(t)):i()}t=o.resolveTemplate(e,n,t),e.async?e.getSource(t,function(t,e){if(t)throw t;a(e)}):a(e.getSource(t))},function(n){if(n){var o=new i(n.src,f,n.path,e);n.noCache||(n.loader.cache[t]=o),r?r(null,o):l=o}else{var s=new Error("template not found: "+t);if(!r)throw s;r(s)}}),l}return e&&s.compile(),r?void r(null,s):s},express:function(t){function e(t,e){if(this.name=t,this.path=t,this.defaultEngine=e.defaultEngine,this.ext=o.extname(t),!this.ext&&!this.defaultEngine)throw new Error("No default engine was specified and no extension was provided.");this.ext||(this.name+=this.ext=("."!==this.defaultEngine[0]?".":"")+this.defaultEngine)}var n=this;e.prototype.render=function(t,e){n.render(this.name,t,e)},t.set("view",e)},render:function(t,e,n){a.isFunction(e)&&(n=e,e=null);var i=null;return this.getTemplate(t,function(t,o){if(t&&n)r(n,t);else{if(t)throw t;i=o.render(e,n)}}),i},renderString:function(t,e,n,r){a.isFunction(n)&&(r=n,n={}),n=n||{};var o=new i(t,this,n.path);return o.render(e,r)}}),g=u.extend({init:function(t,e){this.ctx={};for(var n in t)t.hasOwnProperty(n)&&(this.ctx[n]=t[n]);this.blocks={},this.exported=[];for(var r in e)this.addBlock(r,e[r])},lookup:function(t){return t in h&&!(t in this.ctx)?h[t]:this.ctx[t]},setVariable:function(t,e){this.ctx[t]=e},getVariables:function(){return this.ctx},addBlock:function(t,e){this.blocks[t]=this.blocks[t]||[],this.blocks[t].push(e)},getBlock:function(t){if(!this.blocks[t])throw new Error('unknown block "'+t+'"');return this.blocks[t][0]},getSuper:function(t,e,n,r,i,o){var s=a.indexOf(this.blocks[e]||[],n),u=this.blocks[e][s+1],c=this;if(-1===s||!u)throw new Error('no super block available for "'+e+'"');u(t,c,r,i,o)},addExport:function(t){this.exported.push(t)},getExported:function(){for(var t={},e=0;e<this.exported.length;e++){var n=this.exported[e];t[n]=this.ctx[n]}return t}});i=u.extend({init:function(t,e,n,r){if(this.env=e||new d,a.isObject(t))switch(t.type){case"code":this.tmplProps=t.obj;break;case"string":this.tmplStr=t.obj}else{if(!a.isString(t))throw new Error("src must be a string or an object describing the source");this.tmplStr=t}if(this.path=n,r){var i=this;try{i._compile()}catch(o){throw a.prettifyError(this.path,this.env.dev,o)}}else this.compiled=!1},render:function(t,e,n){"function"==typeof t?(n=t,t={}):"function"==typeof e&&(n=e,e=null);var i=!0;e&&(i=!1);var o=this;try{o.compile()}catch(s){var u=a.prettifyError(this.path,this.env.dev,s);if(n)return r(n,u);throw u}var c=new g(t||{},o.blocks),l=e?e.push():new v;l.topLevel=!0;var f=null;return o.rootRenderFunc(o.env,c,l||new v,p,function(t,e){if(t&&(t=a.prettifyError(o.path,o.env.dev,t)),n)i?r(n,t,e):n(t,e);else{if(t)throw t;f=e}}),f},getExported:function(t,e,n){"function"==typeof t&&(n=t,t={}),"function"==typeof e&&(n=e,e=null);try{this.compile()}catch(r){if(n)return n(r);throw r}var i=e?e.push():new v;i.topLevel=!0;var o=new g(t||{},this.blocks);this.rootRenderFunc(this.env,o,i,p,function(){n(null,o.getExported())})},compile:function(){this.compiled||this._compile()},_compile:function(){var t;if(this.tmplProps)t=this.tmplProps;else{var e=c.compile(this.tmplStr,this.env.asyncFilters,this.env.extensionsList,this.env.opts.throwOnUndefined,this.path,this.env.opts),n=new Function(e);t=n()}this.blocks=this._getBlocks(t),this.rootRenderFunc=t.root,this.compiled=!0},_getBlocks:function(t){var e={};for(var n in t)"b_"===n.slice(0,2)&&(e[n.slice(2)]=t[n]);return e}}),t.exports={Environment:d,Template:i}},function(t,e,n){"use strict";function r(t,e,n){return function(){var r,i,a=s(arguments),u=o(arguments);if(a>t.length){r=Array.prototype.slice.call(arguments,0,t.length);var c=Array.prototype.slice.call(arguments,r.length,a);for(i=0;i<c.length;i++)i<e.length&&(u[e[i]]=c[i]);r.push(u)}else if(a<t.length){for(r=Array.prototype.slice.call(arguments,0,a),i=a;i<t.length;i++){var l=t[i];r.push(u[l]),delete u[l]}r.push(u)}else r=arguments;return n.apply(this,r)}}function i(t){return t.__keywords=!0,t}function o(t){var e=t.length;if(e){var n=t[e-1];if(n&&n.hasOwnProperty("__keywords"))return n}return{}}function s(t){var e=t.length;if(0===e)return 0;var n=t[e-1];return n&&n.hasOwnProperty("__keywords")?e-1:e}function a(t){return"string"!=typeof t?t:(this.val=t,void(this.length=t.length))}function u(t,e){return t instanceof a?new a(e):e.toString()}function c(t){var e=typeof t;return"string"===e?new a(t):"function"!==e?t:function(){var e=t.apply(this,arguments);return"string"==typeof e?new a(e):e}}function l(t,e){return t=void 0!==t&&null!==t?t:"",e&&"string"==typeof t&&(t=m.escape(t)),t}function f(t,e,n){if(null===t||void 0===t)throw new m.TemplateError("attempted to output null or undefined value",e+1,n+1);return t}function p(t,e){return t=t||{},"function"==typeof t[e]?function(){return t[e].apply(t,arguments)}:t[e]}function h(t,e,n){if(!t)throw new Error("Unable to call `"+e+"`, which is undefined or falsey");if("function"!=typeof t)throw new Error("Unable to call `"+e+"`, which is not a function");return t.apply(this,n)}function v(t,e,n){var r=e.lookup(n);return void 0!==r&&null!==r?r:t.lookup(n)}function d(t,e,n){return t.lineno?t:new m.TemplateError(t,e,n)}function g(t,e,n,r){if(m.isArray(t)){var i=t.length;m.asyncIter(t,function(t,r,o){switch(e){case 1:n(t,r,i,o);break;case 2:n(t[0],t[1],r,i,o);break;case 3:n(t[0],t[1],t[2],r,i,o);break;default:t.push(r,o),n.apply(this,t)}},r)}else m.asyncFor(t,function(t,e,r,i,o){n(t,e,r,i,o)},r)}function y(t,e,n,r){function i(t,e){u++,a[t]=e,u===o&&r(null,a.join(""))}var o,s,a,u=0;if(m.isArray(t))if(o=t.length,a=new Array(o),0===o)r(null,"");else for(s=0;s<t.length;s++){var c=t[s];switch(e){case 1:n(c,s,o,i);break;case 2:n(c[0],c[1],s,o,i);break;case 3:n(c[0],c[1],c[2],s,o,i);break;default:c.push(s,i),n.apply(this,c)}}else{var l=m.keys(t);if(o=l.length,a=new Array(o),0===o)r(null,"");else for(s=0;s<l.length;s++){var f=l[s];n(f,t[f],s,o,i)}}}var m=n(1),w=n(6),b=w.extend({init:function(t){this.variables={},this.parent=t,this.topLevel=!1},set:function(t,e,n){var r=t.split("."),i=this.variables,o=this;if(n){if(o=this.resolve(r[0]))return void o.set(t,e);o=this}for(var s=0;s<r.length-1;s++){var a=r[s];i[a]||(i[a]={}),i=i[a]}i[r[r.length-1]]=e},get:function(t){var e=this.variables[t];return void 0!==e&&null!==e?e:null},lookup:function(t){var e=this.parent,n=this.variables[t];return void 0!==n&&null!==n?n:e&&e.lookup(t)},resolve:function(t){var e=this.parent,n=this.variables[t];return void 0!==n&&null!==n?this:e&&e.resolve(t)},push:function(){return new b(this)},pop:function(){return this.parent}});a.prototype=Object.create(String.prototype,{length:{writable:!0,configurable:!0,value:0}}),a.prototype.valueOf=function(){return this.val},a.prototype.toString=function(){return this.val},t.exports={Frame:b,makeMacro:r,makeKeywordArgs:i,numArgs:s,suppressValue:l,ensureDefined:f,memberLookup:p,contextOrFrameLookup:v,callWrap:h,handleError:d,isArray:m.isArray,keys:m.keys,SafeString:a,copySafeness:u,markSafe:c,asyncEach:g,asyncAll:y}},function(t,e,n){"use strict";var r=n(9),i=n(6),o=n(1),s=i.extend({on:function(t,e){this.listeners=this.listeners||{},this.listeners[t]=this.listeners[t]||[],this.listeners[t].push(e)},emit:function(t){var e=Array.prototype.slice.call(arguments,1);this.listeners&&this.listeners[t]&&o.each(this.listeners[t],function(t){t.apply(null,e)})},resolve:function(t,e){return r.resolve(r.dirname(t),e)},isRelative:function(t){return 0===t.indexOf("./")||0===t.indexOf("../")}});t.exports=s},function(t,e,n){"use strict";var r=n(4),i=r.extend({init:function(t,e){this.precompiled=window.nunjucksPrecompiled||{},this.baseURL=t||"",this.useCache=e.useCache,this.async=e.async},resolve:function(t,e){throw new Error("relative templates not support in the browser yet")},getSource:function(t,e){if(this.precompiled[t])return{src:{type:"code",obj:this.precompiled[t]},path:t};var n,r=this.useCache;return this.fetch(this.baseURL+"/"+t,function(i,o){if(i){if(!e)throw i;e(i)}else n={src:o,path:t,noCache:!r},e&&e(null,n)}),n},fetch:function(t,e){var n,r=!0;window.XMLHttpRequest?n=new XMLHttpRequest:window.ActiveXObject&&(n=new ActiveXObject("Microsoft.XMLHTTP")),n.onreadystatechange=function(){4===n.readyState&&r&&(r=!1,0===n.status||200===n.status?e(null,n.responseText):e(n.responseText))},t+=(-1===t.indexOf("?")?"?":"&")+"s="+(new Date).getTime(),n.open("GET",t,this.async),n.send()}});t.exports={WebLoader:i}},function(t,e,n){"use strict";function r(t,e,n){var i=function(){};i.prototype=t.prototype;var o=new i,s=/xyz/.test(function(){xyz})?/\bparent\b/:/.*/;n=n||{};for(var a in n){var u=n[a],c=o[a];"function"==typeof c&&"function"==typeof u&&s.test(u)?o[a]=function(t,e){return function(){var n=this.parent;this.parent=e;var r=t.apply(this,arguments);return this.parent=n,r}}(u,c):o[a]=u}o.typename=e;var l=function(){o.init&&o.init.apply(this,arguments)};return l.prototype=o,l.prototype.constructor=l,l.extend=function(t,e){return"object"==typeof t&&(e=t,t="anonymous"),r(l,t,e)},l}t.exports=r(Object,"Object",{})},function(t,e,n){"use strict";function r(t,e){return null===t||void 0===t||t===!1?e:t}var i=n(1),o=n(3),s={abs:function(t){return Math.abs(t)},batch:function(t,e,n){var r,i=[],o=[];for(r=0;r<t.length;r++)r%e===0&&o.length&&(i.push(o),o=[]),o.push(t[r]);if(o.length){if(n)for(r=o.length;e>r;r++)o.push(n);i.push(o)}return i},capitalize:function(t){t=r(t,"");var e=t.toLowerCase();return o.copySafeness(t,e.charAt(0).toUpperCase()+e.slice(1))},center:function(t,e){if(t=r(t,""),e=e||80,t.length>=e)return t;var n=e-t.length,s=i.repeat(" ",n/2-n%2),a=i.repeat(" ",n/2);return o.copySafeness(t,s+t+a)},"default":function(t,e){return t?t:e},dictsort:function(t,e,n){if(!i.isObject(t))throw new i.TemplateError("dictsort filter: val must be an object");var r=[];for(var o in t)r.push([o,t[o]]);var s;if(void 0===n||"key"===n)s=0;else{if("value"!==n)throw new i.TemplateError("dictsort filter: You can only sort by either key or value");s=1}return r.sort(function(t,n){var r=t[s],o=n[s];return e||(i.isString(r)&&(r=r.toUpperCase()),i.isString(o)&&(o=o.toUpperCase())),r>o?1:r===o?0:-1}),r},dump:function(t){return JSON.stringify(t)},escape:function(t){return"string"==typeof t||t instanceof o.SafeString?i.escape(t):t},safe:function(t){return o.markSafe(t)},first:function(t){return t[0]},groupby:function(t,e){return i.groupBy(t,e)},indent:function(t,e,n){if(t=r(t,""),""===t)return"";e=e||4;for(var s="",a=t.split("\n"),u=i.repeat(" ",e),c=0;c<a.length;c++)s+=0!==c||n?u+a[c]+"\n":a[c]+"\n";return o.copySafeness(t,s)},join:function(t,e,n){return e=e||"",n&&(t=i.map(t,function(t){return t[n]})),t.join(e)},last:function(t){return t[t.length-1]},length:function(t){var e=r(t,"");return void 0!==e?e.length:0},list:function(t){if(i.isString(t))return t.split("");if(i.isObject(t)){var e=[];if(Object.keys)e=Object.keys(t);else for(var n in t)e.push(n);return i.map(e,function(e){return{key:e,value:t[e]}})}if(i.isArray(t))return t;throw new i.TemplateError("list filter: type not iterable")},lower:function(t){return t=r(t,""),t.toLowerCase()},random:function(t){return t[Math.floor(Math.random()*t.length)]},rejectattr:function(t,e){return t.filter(function(t){return!t[e]})},selectattr:function(t,e){return t.filter(function(t){return!!t[e]})},replace:function(t,e,n,r){var i=t;if(e instanceof RegExp)return t.replace(e,n);"undefined"==typeof r&&(r=-1);var s="";if("number"==typeof e)e+="";else if("string"!=typeof e)return t;if("number"==typeof t&&(t+=""),"string"!=typeof t&&!(t instanceof o.SafeString))return t;if(""===e)return s=n+t.split("").join(n)+n,o.copySafeness(t,s);var a=t.indexOf(e);if(0===r||-1===a)return t;for(var u=0,c=0;a>-1&&(-1===r||r>c);)s+=t.substring(u,a)+n,u=a+e.length,c++,a=t.indexOf(e,u);return u<t.length&&(s+=t.substring(u)),o.copySafeness(i,s)},reverse:function(t){var e;return e=i.isString(t)?s.list(t):i.map(t,function(t){return t}),e.reverse(),i.isString(t)?o.copySafeness(t,e.join("")):e},round:function(t,e,n){e=e||0;var r,i=Math.pow(10,e);return r="ceil"===n?Math.ceil:"floor"===n?Math.floor:Math.round,r(t*i)/i},slice:function(t,e,n){for(var r=Math.floor(t.length/e),i=t.length%e,o=0,s=[],a=0;e>a;a++){var u=o+a*r;i>a&&o++;var c=o+(a+1)*r,l=t.slice(u,c);n&&a>=i&&l.push(n),s.push(l)}return s},sort:function(t,e,n,r){return t=i.map(t,function(t){return t}),t.sort(function(t,o){var s,a;return r?(s=t[r],a=o[r]):(s=t,a=o),!n&&i.isString(s)&&i.isString(a)&&(s=s.toLowerCase(),a=a.toLowerCase()),a>s?e?1:-1:s>a?e?-1:1:0}),t},string:function(t){return o.copySafeness(t,t)},title:function(t){t=r(t,"");for(var e=t.split(" "),n=0;n<e.length;n++)e[n]=s.capitalize(e[n]);return o.copySafeness(t,e.join(" "))},trim:function(t){return o.copySafeness(t,t.replace(/^\s*|\s*$/g,""))},truncate:function(t,e,n,i){var s=t;if(t=r(t,""),e=e||255,t.length<=e)return t;if(n)t=t.substring(0,e);else{var a=t.lastIndexOf(" ",e);-1===a&&(a=e),t=t.substring(0,a)}return t+=void 0!==i&&null!==i?i:"...",o.copySafeness(s,t)},upper:function(t){return t=r(t,""),t.toUpperCase()},urlencode:function(t){var e=encodeURIComponent;if(i.isString(t))return e(t);var n;if(i.isArray(t))n=t.map(function(t){return e(t[0])+"="+e(t[1])});else{n=[];for(var r in t)t.hasOwnProperty(r)&&n.push(e(r)+"="+e(t[r]))}return n.join("&")},urlize:function(t,e,n){isNaN(e)&&(e=1/0);var r=n===!0?' rel="nofollow"':"",i=/^(?:\(|<|&lt;)?(.*?)(?:\.|,|\)|\n|&gt;)?$/,o=/^[\w.!#$%&'*+\-\/=?\^`{|}~]+@[a-z\d\-]+(\.[a-z\d\-]+)+$/i,s=/^https?:\/\/.*$/,a=/^www\./,u=/\.(?:org|net|com)(?:\:|\/|$)/,c=t.split(/\s+/).filter(function(t){return t&&t.length}).map(function(t){var n=t.match(i),c=n&&n[1]||t;return s.test(c)?'<a href="'+c+'"'+r+">"+c.substr(0,e)+"</a>":a.test(c)?'<a href="http://'+c+'"'+r+">"+c.substr(0,e)+"</a>":o.test(c)?'<a href="mailto:'+c+'">'+c+"</a>":u.test(c)?'<a href="http://'+c+'"'+r+">"+c.substr(0,e)+"</a>":t});return c.join(" ")},wordcount:function(t){t=r(t,"");var e=t?t.match(/\w+/g):null;return e?e.length:null},"float":function(t,e){var n=parseFloat(t);return isNaN(n)?e:n},"int":function(t,e){var n=parseInt(t,10);return isNaN(n)?e:n}};s.d=s["default"],s.e=s.escape,t.exports=s},function(t,e,n){"use strict";function r(t){var e=-1;return{current:null,reset:function(){e=-1,this.current=null},next:function(){return e++,e>=t.length&&(e=0),this.current=t[e],this.current}}}function i(t){t=t||",";var e=!0;return function(){var n=e?"":t;return e=!1,n}}var o={range:function(t,e,n){e?n||(n=1):(e=t,t=0,n=1);for(var r=[],i=t;e>i;i+=n)r.push(i);return r},cycler:function(){return r(Array.prototype.slice.call(arguments))},joiner:function(t){return i(t)}};t.exports=o},function(t,e,n){},function(t,e,n){"use strict";function r(){if(u.length)throw u.shift()}function i(t){var e;e=a.length?a.pop():new o,e.task=t,s(e)}function o(){this.task=null}var s=n(11),a=[],u=[],c=s.makeRequestCallFromTimer(r);t.exports=i,o.prototype.call=function(){try{this.task.call()}catch(t){i.onerror?i.onerror(t):(u.push(t),c())}finally{this.task=null,a[a.length]=this}}},function(t,e,n){(function(e){"use strict";function n(t){a.length||(s(),u=!0),a[a.length]=t}function r(){for(;c<a.length;){var t=c;if(c+=1,a[t].call(),c>l){for(var e=0,n=a.length-c;n>e;e++)a[e]=a[e+c];a.length-=c,c=0}}a.length=0,c=0,u=!1}function i(t){var e=1,n=new f(t),r=document.createTextNode("");return n.observe(r,{characterData:!0}),function(){e=-e,r.data=e}}function o(t){return function(){function e(){clearTimeout(n),clearInterval(r),t()}var n=setTimeout(e,0),r=setInterval(e,50)}}t.exports=n;var s,a=[],u=!1,c=0,l=1024,f=e.MutationObserver||e.WebKitMutationObserver;s="function"==typeof f?i(r):o(r),n.requestFlush=s,n.makeRequestCallFromTimer=o}).call(e,function(){return this}())}]);
\ No newline at end of file
diff --git a/browser/nunjucks.js b/browser/nunjucks.js
index 5d130f7..cb44d8b 100644
--- a/browser/nunjucks.js
+++ b/browser/nunjucks.js
@@ -56,7 +56,7 @@ var nunjucks =
 	var runtime = __webpack_require__(6);
 	var Loader = __webpack_require__(7);
 	var loaders = __webpack_require__(8);
-	var precompile = __webpack_require__(15);
+	var precompile = __webpack_require__(14);
 
 	module.exports = {};
 	module.exports.Environment = env.Environment;
@@ -64,14 +64,12 @@ var nunjucks =
 
 	module.exports.Loader = Loader;
 	module.exports.FileSystemLoader = loaders.FileSystemLoader;
-	module.exports.PrecompiledLoader = loaders.PrecompiledLoader;
 	module.exports.WebLoader = loaders.WebLoader;
 
 	module.exports.compiler = compiler;
 	module.exports.parser = parser;
 	module.exports.lexer = lexer;
 	module.exports.runtime = runtime;
-	module.exports.lib = lib;
 
 	// A single instance of an environment, since this is so commonly used
 
@@ -90,7 +88,7 @@ var nunjucks =
 	            noCache: opts.noCache
 	        });
 	    }
-	    else if(loaders.WebLoader) {
+	    else {
 	        TemplateLoader = new loaders.WebLoader(templatesPath, {
 	            useCache: opts.web && opts.web.useCache,
 	            async: opts.web && opts.web.async
@@ -424,8 +422,8 @@ var nunjucks =
 
 	'use strict';
 
-	var path = __webpack_require__(15);
-	var asap = __webpack_require__(16);
+	var path = __webpack_require__(14);
+	var asap = __webpack_require__(15);
 	var lib = __webpack_require__(1);
 	var Obj = __webpack_require__(11);
 	var compiler = __webpack_require__(3);
@@ -436,10 +434,6 @@ var nunjucks =
 	var Frame = runtime.Frame;
 	var Template;
 
-	// Unconditionally load in this loader, even if no other ones are
-	// included (possible in the slim browser build)
-	builtin_loaders.PrecompiledLoader = __webpack_require__(14);
-
 	// If the user is using the async API, *always* call it
 	// asynchronously even if the template was synchronous.
 	function callbackAsap(cb, err, res) {
@@ -460,23 +454,22 @@ var nunjucks =
 	        // The autoescape flag sets global autoescaping. If true,
 	        // every string variable will be escaped by default.
 	        // If false, strings can be manually escaped using the `escape` filter.
-	        // defaults to true
-	        this.opts.autoescape = opts.autoescape != null ? opts.autoescape : true;
+	        // defaults to false
+	        this.opts.autoescape = !!opts.autoescape;
 
 	        // If true, this will make the system throw errors if trying
 	        // to output a null or undefined value
 	        this.opts.throwOnUndefined = !!opts.throwOnUndefined;
+
 	        this.opts.trimBlocks = !!opts.trimBlocks;
 	        this.opts.lstripBlocks = !!opts.lstripBlocks;
 
-	        this.loaders = [];
-
 	        if(!loaders) {
-	            // The filesystem loader is only available server-side
+	            // The filesystem loader is only available client-side
 	            if(builtin_loaders.FileSystemLoader) {
 	                this.loaders = [new builtin_loaders.FileSystemLoader('views')];
 	            }
-	            else if(builtin_loaders.WebLoader) {
+	            else {
 	                this.loaders = [new builtin_loaders.WebLoader('/views')];
 	            }
 	        }
@@ -484,15 +477,6 @@ var nunjucks =
 	            this.loaders = lib.isArray(loaders) ? loaders : [loaders];
 	        }
 
-	        // It's easy to use precompiled templates: just include them
-	        // before you configure nunjucks and this will automatically
-	        // pick it up and use it
-	        if((true) && window.nunjucksPrecompiled) {
-	            this.loaders.unshift(
-	                new builtin_loaders.PrecompiledLoader(window.nunjucksPrecompiled)
-	            );
-	        }
-
 	        this.initCache();
 	        this.filters = {};
 	        this.asyncFilters = [];
@@ -596,7 +580,30 @@ var nunjucks =
 	            var syncResult;
 	            var _this = this;
 
-	            var createTemplate = function(info) {
+	            lib.asyncIter(this.loaders, function(loader, i, next, done) {
+	                function handle(src) {
+	                    if(src) {
+	                        src.loader = loader;
+	                        done(src);
+	                    }
+	                    else {
+	                        next();
+	                    }
+	                }
+
+	                // Resolve name relative to parentName
+	                name = that.resolveTemplate(loader, parentName, name);
+
+	                if(loader.async) {
+	                    loader.getSource(name, function(err, src) {
+	                        if(err) { throw err; }
+	                        handle(src);
+	                    });
+	                }
+	                else {
+	                    handle(loader.getSource(name));
+	                }
+	            }, function(info) {
 	                if(!info) {
 	                    var err = new Error('template not found: ' + name);
 	                    if(cb) {
@@ -621,32 +628,7 @@ var nunjucks =
 	                        syncResult = tmpl;
 	                    }
 	                }
-	            };
-
-	            lib.asyncIter(this.loaders, function(loader, i, next, done) {
-	                function handle(src) {
-	                    if(src) {
-	                        src.loader = loader;
-	                        done(src);
-	                    }
-	                    else {
-	                        next();
-	                    }
-	                }
-
-	                // Resolve name relative to parentName
-	                name = that.resolveTemplate(loader, parentName, name);
-
-	                if(loader.async) {
-	                    loader.getSource(name, function(err, src) {
-	                        if(err) { throw err; }
-	                        handle(src);
-	                    });
-	                }
-	                else {
-	                    handle(loader.getSource(name));
-	                }
-	            }, createTemplate);
+	            });
 
 	            return syncResult;
 	        }
@@ -932,6 +914,7 @@ var nunjucks =
 	            var source = compiler.compile(this.tmplStr,
 	                                          this.env.asyncFilters,
 	                                          this.env.extensionsList,
+	                                          this.env.opts.throwOnUndefined,
 	                                          this.path,
 	                                          this.env.opts);
 
@@ -1005,8 +988,8 @@ var nunjucks =
 	        this.lastId = 0;
 	        this.buffer = null;
 	        this.bufferStack = [];
+	        this.isChild = false;
 	        this.scopeClosers = '';
-	        this.inBlock = false;
 	        this.throwOnUndefined = throwOnUndefined;
 	    },
 
@@ -1922,28 +1905,14 @@ var nunjucks =
 	    },
 
 	    compileBlock: function(node) {
-	        var id = this.tmpid();
+	        if(!this.isChild) {
+	            var id = this.tmpid();
 
-	        // If we are executing outside a block (creating a top-level
-	        // block), we really don't want to execute its code because it
-	        // will execute twice: once when the child template runs and
-	        // again when the parent template runs. Note that blocks
-	        // within blocks will *always* execute immediately *and*
-	        // wherever else they are invoked (like used in a parent
-	        // template). This may have behavioral differences from jinja
-	        // because blocks can have side effects, but it seems like a
-	        // waste of performance to always execute huge top-level
-	        // blocks twice
-	        if(!this.inBlock) {
-	            this.emit('(parentTemplate ? function(e, c, f, r, cb) { cb(""); } : ');
-	        }
-	        this.emit('context.getBlock("' + node.name.value + '")');
-	        if(!this.inBlock) {
-	            this.emit(')');
+	            this.emitLine('context.getBlock("' + node.name.value + '")' +
+	                          '(env, context, frame, runtime, ' + this.makeCallback(id));
+	            this.emitLine(this.buffer + ' += ' + id + ';');
+	            this.addScopeLevel();
 	        }
-	        this.emitLine('(env, context, frame, runtime, ' + this.makeCallback(id));
-	        this.emitLine(this.buffer + ' += ' + id + ';');
-	        this.addScopeLevel();
 	    },
 
 	    compileSuper: function(node, frame) {
@@ -1961,16 +1930,17 @@ var nunjucks =
 	    },
 
 	    compileExtends: function(node, frame) {
+	        if(this.isChild) {
+	            this.fail('compileExtends: cannot extend multiple times',
+	                      node.template.lineno,
+	                      node.template.colno);
+	        }
+
 	        var k = this.tmpid();
 
 	        this.emit('env.getTemplate(');
 	        this._compileExpression(node.template, frame);
-	        this.emitLine(', true, '+this._templateName()+', ' + this.makeCallback('_parentTemplate'));
-
-	        // extends is a dynamic tag and can occur within a block like
-	        // `if`, so if this happens we need to capture the parent
-	        // template in the top-level scope
-	        this.emitLine('parentTemplate = _parentTemplate');
+	        this.emitLine(', true, '+this._templateName()+', ' + this.makeCallback('parentTemplate'));
 
 	        this.emitLine('for(var ' + k + ' in parentTemplate.blocks) {');
 	        this.emitLine('context.addBlock(' + k +
@@ -1978,6 +1948,7 @@ var nunjucks =
 	        this.emitLine('}');
 
 	        this.addScopeLevel();
+	        this.isChild = true;
 	    },
 
 	    compileInclude: function(node, frame) {
@@ -2033,16 +2004,14 @@ var nunjucks =
 	        frame = new Frame();
 
 	        this.emitFuncBegin('root');
-	        this.emitLine('var parentTemplate = null;');
 	        this._compileChildren(node, frame);
-	        this.emitLine('if(parentTemplate) {');
-	        this.emitLine('parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);');
-	        this.emitLine('} else {');
-	        this.emitLine('cb(null, ' + this.buffer +');');
-	        this.emitLine('}');
-	        this.emitFuncEnd(true);
+	        if(this.isChild) {
+	            this.emitLine('parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);');
+	        }
+	        this.emitFuncEnd(this.isChild);
 
-	        this.inBlock = true;
+	        // When compiling the blocks, they should all act as top-level code
+	        this.isChild = false;
 
 	        var i, name, block, blocks = node.findAll(nodes.Block);
 	        for (i = 0; i < blocks.length; i++) {
@@ -2083,9 +2052,7 @@ var nunjucks =
 	});
 
 	// var c = new Compiler();
-	// var src = 'hello {% filter title %}' +
-	//     'Hello madam how are you' +
-	//     '{% endfilter %}'
+	// var src = '{% asyncEach i in arr %}{{ i }}{% else %}empty{% endeach %}';
 	// var ast = transformer.transform(parser.parse(src));
 	// nodes.printNodes(ast);
 	// c.compile(ast);
@@ -2093,8 +2060,8 @@ var nunjucks =
 	// console.log(tmpl);
 
 	module.exports = {
-	    compile: function(src, asyncFilters, extensions, name, opts) {
-	        var c = new Compiler(name, opts.throwOnUndefined);
+	    compile: function(src, asyncFilters, extensions, throwOnUndefined, name, opts) {
+	        var c = new Compiler(name, throwOnUndefined);
 
 	        // Run the extension preprocessors against the source.
 	        if(extensions && extensions.length) {
@@ -2218,6 +2185,10 @@ var nunjucks =
 	        return true;
 	    },
 
+	    skipWhitespace: function () {
+	        return this.skip(lexer.TOKEN_WHITESPACE);
+	    },
+
 	    skipSymbol: function(val) {
 	        return this.skipValue(lexer.TOKEN_SYMBOL, val);
 	    },
@@ -2655,7 +2626,6 @@ var nunjucks =
 	        case 'call': return this.parseCall();
 	        case 'import': return this.parseImport();
 	        case 'from': return this.parseFrom();
-	        case 'filter': return this.parseFilterStatement();
 	        default:
 	            if (this.extensions.length) {
 	                for (var i = 0; i < this.extensions.length; i++) {
@@ -3074,77 +3044,36 @@ var nunjucks =
 	        }
 	    },
 
-	    parseFilterName: function() {
-	        var tok = this.expect(lexer.TOKEN_SYMBOL);
-	        var name = tok.value;
-
-	        while(this.skipValue(lexer.TOKEN_OPERATOR, '.')) {
-	            name += '.' + this.expect(lexer.TOKEN_SYMBOL).value;
-	        }
-
-	        return new nodes.Symbol(tok.lineno, tok.colno, name);
-	    },
-
-	    parseFilterArgs: function(node) {
-	        if(this.peekToken().type === lexer.TOKEN_LEFT_PAREN) {
-	            // Get a FunCall node and add the parameters to the
-	            // filter
-	            var call = this.parsePostfix(node);
-	            return call.args.children;
-	        }
-	        return [];
-	    },
-
 	    parseFilter: function(node) {
 	        while(this.skip(lexer.TOKEN_PIPE)) {
-	            var name = this.parseFilterName();
+	            var tok = this.expect(lexer.TOKEN_SYMBOL);
+	            var name = tok.value;
+
+	            while(this.skipValue(lexer.TOKEN_OPERATOR, '.')) {
+	                name += '.' + this.expect(lexer.TOKEN_SYMBOL).value;
+	            }
 
 	            node = new nodes.Filter(
-	                name.lineno,
-	                name.colno,
-	                name,
+	                tok.lineno,
+	                tok.colno,
+	                new nodes.Symbol(tok.lineno,
+	                                 tok.colno,
+	                                 name),
 	                new nodes.NodeList(
-	                    name.lineno,
-	                    name.colno,
-	                    [node].concat(this.parseFilterArgs(node))
-	                )
+	                    tok.lineno,
+	                    tok.colno,
+	                    [node])
 	            );
-	        }
-
-	        return node;
-	    },
 
-	    parseFilterStatement: function() {
-	        var filterTok = this.peekToken();
-	        if(!this.skipSymbol('filter')) {
-	            this.fail('parseFilterStatement: expected filter');
+	            if(this.peekToken().type === lexer.TOKEN_LEFT_PAREN) {
+	                // Get a FunCall node and add the parameters to the
+	                // filter
+	                var call = this.parsePostfix(node);
+	                node.args.children = node.args.children.concat(call.args.children);
+	            }
 	        }
 
-	        var name = this.parseFilterName();
-	        var args = this.parseFilterArgs(name);
-
-	        this.advanceAfterBlockEnd(filterTok.value);
-	        var body = this.parseUntilBlocks('endfilter');
-	        this.advanceAfterBlockEnd();
-
-	        var node = new nodes.Filter(
-	            name.lineno,
-	            name.colno,
-	            name,
-	            new nodes.NodeList(
-	                name.lineno,
-	                name.colno,
-	                // Body is a NodeList with an Output node as a child,
-	                // need to strip those
-	                body.children[0].children.concat(args)
-	            )
-	        );
-
-	        return new nodes.Output(
-	            name.lineno,
-	            name.colno,
-	            [node]
-	        );
+	        return node;
 	    },
 
 	    parseAggregate: function() {
@@ -3350,9 +3279,7 @@ var nunjucks =
 	//     console.log(util.inspect(t));
 	// }
 
-	// var p = new Parser(lexer.lex('hello {% filter title %}' +
-	//                              'Hello madam how are you' +
-	//                              '{% endfilter %}'));
+	// var p = new Parser(lexer.lex('{% if not x %}foo{% endif %}'));
 	// var n = p.parseAsRoot();
 	// nodes.printNodes(n);
 
@@ -4213,7 +4140,7 @@ var nunjucks =
 
 	'use strict';
 
-	var path = __webpack_require__(15);
+	var path = __webpack_require__(14);
 	var Obj = __webpack_require__(11);
 	var lib = __webpack_require__(1);
 
@@ -4253,10 +4180,14 @@ var nunjucks =
 	'use strict';
 
 	var Loader = __webpack_require__(7);
-	var PrecompiledLoader = __webpack_require__(14);
 
 	var WebLoader = Loader.extend({
 	    init: function(baseURL, opts) {
+	        // It's easy to use precompiled templates: just include them
+	        // before you configure nunjucks and this will automatically
+	        // pick it up and use it
+	        this.precompiled = window.nunjucksPrecompiled || {};
+
 	        this.baseURL = baseURL || '';
 
 	        // By default, the cache is turned off because there's no way
@@ -4273,34 +4204,43 @@ var nunjucks =
 	        this.async = opts.async;
 	    },
 
-	    resolve: function(from, to) { // jshint ignore:line
+	    resolve: function(from, to) {
 	        throw new Error('relative templates not support in the browser yet');
 	    },
 
 	    getSource: function(name, cb) {
-	        var useCache = this.useCache;
-	        var result;
-	        this.fetch(this.baseURL + '/' + name, function(err, src) {
-	            if(err) {
-	                if(!cb) {
-	                    throw err;
+	        if(this.precompiled[name]) {
+	            return {
+	                src: { type: 'code',
+	                       obj: this.precompiled[name] },
+	                path: name
+	            };
+	        }
+	        else {
+	            var useCache = this.useCache;
+	            var result;
+	            this.fetch(this.baseURL + '/' + name, function(err, src) {
+	                if(err) {
+	                    if(!cb) {
+	                        throw err;
+	                    }
+	                    cb(err);
 	                }
-	                cb(err);
-	            }
-	            else {
-	                result = { src: src,
-	                           path: name,
-	                           noCache: !useCache };
-	                if(cb) {
-	                    cb(null, result);
+	                else {
+	                    result = { src: src,
+	                               path: name,
+	                               noCache: !useCache };
+	                    if(cb) {
+	                        cb(null, result);
+	                    }
 	                }
-	            }
-	        });
+	            });
 
-	        // if this WebLoader isn't running asynchronously, the
-	        // fetch above would actually run sync and we'll have a
-	        // result here
-	        return result;
+	            // if this WebLoader isn't running asynchronously, the
+	            // fetch above would actually run sync and we'll have a
+	            // result here
+	            return result;
+	        }
 	    },
 
 	    fetch: function(url, cb) {
@@ -4337,8 +4277,7 @@ var nunjucks =
 	});
 
 	module.exports = {
-	    WebLoader: WebLoader,
-	    PrecompiledLoader: PrecompiledLoader
+	    WebLoader: WebLoader
 	};
 
 
@@ -4892,7 +4831,7 @@ var nunjucks =
 	    printNodes: printNodes
 	};
 
-	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(15)))
+	/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(14)))
 
 /***/ },
 /* 11 */
@@ -4980,7 +4919,6 @@ var nunjucks =
 	    return value;
 	}
 
-	var hasWarnedDefault = false;
 
 	var filters = {
 	    abs: function(n) {
@@ -5034,25 +4972,8 @@ var nunjucks =
 	        return r.copySafeness(str, pre + str + post);
 	    },
 
-	    'default': function(val, def, bool) {
-	        if(bool !== true && bool !== false && !hasWarnedDefault) {
-	            hasWarnedDefault = true;
-	            console.log(
-	                '[nunjucks] Warning: the "default" filter was used without ' +
-	                'specifying the type of comparison. 2.0 changed the default ' +
-	                'behavior from boolean (val ? val : def) to strictly undefined, ' +
-	                'so you should make sure that doesn\'t break anything. ' +
-	                'Be explicit about this to make this warning go away, or wait until 2.1. ' +
-	                'See http://mozilla.github.io/nunjucks/templating.html#defaultvalue-default-boolean'
-	            );
-	        }
-
-	        if(bool) {
-	            return val ? val : def;
-	        }
-	        else {
-	            return (val !== undefined) ? val : def;
-	        }
+	    'default': function(val, def) {
+	        return val ? val : def;
 	    },
 
 	    dictsort: function(val, case_sensitive, by) {
@@ -5465,8 +5386,11 @@ var nunjucks =
 	          return word && word.length;
 	        }).map(function(word) {
 	          var matches = word.match(puncRE);
+
+
 	          var possibleUrl = matches && matches[1] || word;
 
+
 	          // url that starts with http or https
 	          if (httpHttpsRE.test(possibleUrl))
 	            return '<a href="' + possibleUrl + '"' + noFollowAttr + '>' + possibleUrl.substr(0, length) + '</a>';
@@ -5591,44 +5515,16 @@ var nunjucks =
 /* 14 */
 /***/ function(module, exports, __webpack_require__) {
 
-	'use strict';
-
-	var Loader = __webpack_require__(7);
-
-	var PrecompiledLoader = Loader.extend({
-	    init: function(compiledTemplates) {
-	        this.precompiled = compiledTemplates || {};
-	    },
-
-	    getSource: function(name) {
-	        if (this.precompiled[name]) {
-	            return {
-	                src: { type: 'code',
-	                       obj: this.precompiled[name] },
-	                path: name
-	            };
-	        }
-	        return null;
-	    }
-	});
-
-	module.exports = PrecompiledLoader;
-
-
-/***/ },
-/* 15 */
-/***/ function(module, exports, __webpack_require__) {
-
 	
 
 /***/ },
-/* 16 */
+/* 15 */
 /***/ function(module, exports, __webpack_require__) {
 
 	"use strict";
 
 	// rawAsap provides everything we need except exception management.
-	var rawAsap = __webpack_require__(17);
+	var rawAsap = __webpack_require__(16);
 	// RawTasks are recycled to reduce GC churn.
 	var freeTasks = [];
 	// We queue errors to ensure they are thrown in right order (FIFO).
@@ -5694,7 +5590,7 @@ var nunjucks =
 
 
 /***/ },
-/* 17 */
+/* 16 */
 /***/ function(module, exports, __webpack_require__) {
 
 	/* WEBPACK VAR INJECTION */(function(global) {"use strict";
diff --git a/browser/nunjucks.min.js b/browser/nunjucks.min.js
index 9e9c5cb..6f5f0b8 100644
--- a/browser/nunjucks.min.js
+++ b/browser/nunjucks.min.js
@@ -1,6 +1,4 @@
 /*! Browser bundle of nunjucks 1.3.5-unreleased  */
-var nunjucks=function(e){function t(i){if(n[i])return n[i].exports;var r=n[i]={exports:{},id:i,loaded:!1};return e[i].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";var i=n(1),r=n(2),s=n(3),o=n(4),a=n(5),l=n(6),c=n(7),h=n(8),u=n(15);e.exports={},e.exports.Environment=r.Environment,e.exports.Template=r.Template,e.exports.Loader=c,e.exports.FileSystemLoader=h.FileSystemLoader,e.exports.PrecompiledLoader=h.PrecompiledLoader,e.exports.WebLoader=h.WebLoader,e.exports.compiler=s,e.exports.parser=o,e.exports.lexer=a,e.exports.runtime=l,e.exports.lib=i;var p;e.exports.configure=function(e,t){t=t||{},i.isObject(e)&&(t=e,e=null);var n;return h.FileSystemLoader?n=new h.FileSystemLoader(e,{watch:t.watch,noCache:t.noCache}):h.WebLoader&&(n=new h.WebLoader(e,{useCache:t.web&&t.web.useCache,async:t.web&&t.web.async})),p=new r.Environment(n,t),t&&t.express&&p.express(t.express),p},e.exports.compile=function(t,n,i,r){return p||e.exports.configure(),new e.exports.Template(t,n,i,r)},e.exports.render=function(t,n,i){return p||e.exports.configure(),p.render(t,n,i)},e.exports.renderString=function(t,n,i){return p||e.exports.configure(),p.renderString(t,n,i)},u&&(e.exports.precompile=u.precompile,e.exports.precompileString=u.precompileString)},function(e,t,n){"use strict";var i=Array.prototype,r=Object.prototype,s={"&":"&amp;",'"':"&quot;","'":"&#39;","<":"&lt;",">":"&gt;"},o=/[&"'<>]/g,a=function(e){return s[e]},t=e.exports={};t.prettifyError=function(e,n,i){if(i.Update||(i=new t.TemplateError(i)),i.Update(e),!n){var r=i;i=new Error(r.message),i.name=r.name}return i},t.TemplateError=function(e,t,n){var i=this;return e instanceof Error?(i=e,e=e.name+": "+e.message):Error.captureStackTrace&&Error.captureStackTrace(i),i.name="Template render error",i.message=e,i.lineno=t,i.colno=n,i.firstUpdate=!0,i.Update=function(e){var t="("+(e||"unknown path")+")";return this.firstUpdate&&(this.lineno&&this.colno?t+=" [Line "+this.lineno+", Column "+this.colno+"]":this.lineno&&(t+=" [Line "+this.lineno+"]")),t+="\n ",this.firstUpdate&&(t+=" "),this.message=t+(this.message||""),this.firstUpdate=!1,this},i},t.TemplateError.prototype=Error.prototype,t.escape=function(e){return e.replace(o,a)},t.isFunction=function(e){return"[object Function]"===r.toString.call(e)},t.isArray=Array.isArray||function(e){return"[object Array]"===r.toString.call(e)},t.isString=function(e){return"[object String]"===r.toString.call(e)},t.isObject=function(e){return"[object Object]"===r.toString.call(e)},t.groupBy=function(e,n){for(var i={},r=t.isFunction(n)?n:function(e){return e[n]},s=0;s<e.length;s++){var o=e[s],a=r(o,s);(i[a]||(i[a]=[])).push(o)}return i},t.toArray=function(e){return Array.prototype.slice.call(e)},t.without=function(e){var n=[];if(!e)return n;for(var i=-1,r=e.length,s=t.toArray(arguments).slice(1);++i<r;)-1===t.indexOf(s,e[i])&&n.push(e[i]);return n},t.extend=function(e,t){for(var n in t)e[n]=t[n];return e},t.repeat=function(e,t){for(var n="",i=0;t>i;i++)n+=e;return n},t.each=function(e,t,n){if(null!=e)if(i.each&&e.each===i.each)e.forEach(t,n);else if(e.length===+e.length)for(var r=0,s=e.length;s>r;r++)t.call(n,e[r],r,e)},t.map=function(e,t){var n=[];if(null==e)return n;if(i.map&&e.map===i.map)return e.map(t);for(var r=0;r<e.length;r++)n[n.length]=t(e[r],r);return e.length===+e.length&&(n.length=e.length),n},t.asyncIter=function(e,t,n){function i(){r++,r<e.length?t(e[r],r,i,n):n()}var r=-1;i()},t.asyncFor=function(e,n,i){function r(){a++;var t=s[a];o>a?n(t,e[t],a,o,r):i()}var s=t.keys(e),o=s.length,a=-1;r()},t.indexOf=Array.prototype.indexOf?function(e,t,n){return Array.prototype.indexOf.call(e,t,n)}:function(e,t,n){var i=this.length>>>0;for(n=+n||0,Math.abs(n)===1/0&&(n=0),0>n&&(n+=i,0>n&&(n=0));i>n;n++)if(e[n]===t)return n;return-1},Array.prototype.map||(Array.prototype.map=function(){throw new Error("map is unimplemented for this js engine")}),t.keys=function(e){if(Object.prototype.keys)return e.keys();var t=[];for(var n in e)e.hasOwnProperty(n)&&t.push(n);return t}},function(e,t,n){"use strict";function i(e,t,n){o(function(){e(t,n)})}var r,s=n(15),o=n(16),a=n(1),l=n(9),c=n(3),h=n(10),u=n(8),p=n(6),f=n(11),m=p.Frame;u.PrecompiledLoader=n(12);var d=l.extend({init:function(e,t){t=this.opts=t||{},this.opts.dev=!!t.dev,this.opts.autoescape=null!=t.autoescape?t.autoescape:!0,this.opts.throwOnUndefined=!!t.throwOnUndefined,this.opts.trimBlocks=!!t.trimBlocks,this.opts.lstripBlocks=!!t.lstripBlocks,this.loaders=[],e?this.loaders=a.isArray(e)?e:[e]:u.FileSystemLoader?this.loaders=[new u.FileSystemLoader("views")]:u.WebLoader&&(this.loaders=[new u.WebLoader("/views")]),window.nunjucksPrecompiled&&this.loaders.unshift(new u.PrecompiledLoader(window.nunjucksPrecompiled)),this.initCache(),this.filters={},this.asyncFilters=[],this.extensions={},this.extensionsList=[];for(var n in h)this.addFilter(n,h[n])},initCache:function(){a.each(this.loaders,function(e){e.cache={},"function"==typeof e.on&&e.on("update",function(t){e.cache[t]=null})})},addExtension:function(e,t){t._name=e,this.extensions[e]=t,this.extensionsList.push(t)},getExtension:function(e){return this.extensions[e]},addGlobal:function(e,t){f[e]=t},addFilter:function(e,t,n){var i=t;n&&this.asyncFilters.push(e),this.filters[e]=i},getFilter:function(e){if(!this.filters[e])throw new Error("filter not found: "+e);return this.filters[e]},resolveTemplate:function(e,t,n){var i=e.isRelative&&t?e.isRelative(n):!1;return i&&e.resolve?e.resolve(t,n):n},getTemplate:function(e,t,n,i){var s=this,o=null;if(e&&e.raw&&(e=e.raw),a.isFunction(n)&&(i=n,n=null,t=t||!1),a.isFunction(t)&&(i=t,t=!1),"string"!=typeof e)throw new Error("template names must be a string: "+e);for(var l=0;l<this.loaders.length;l++){var c=this.resolveTemplate(this.loaders[l],n,e);if(o=this.loaders[l].cache[c])break}if(!o){var h,u=this,p=function(n){if(n){var s=new r(n.src,u,n.path,t);n.noCache||(n.loader.cache[e]=s),i?i(null,s):h=s}else{var o=new Error("template not found: "+e);if(!i)throw o;i(o)}};return a.asyncIter(this.loaders,function(t,i,r,o){function a(e){e?(e.loader=t,o(e)):r()}e=s.resolveTemplate(t,n,e),t.async?t.getSource(e,function(e,t){if(e)throw e;a(t)}):a(t.getSource(e))},p),h}return t&&o.compile(),i?void i(null,o):o},express:function(e){function t(e,t){if(this.name=e,this.path=e,this.defaultEngine=t.defaultEngine,this.ext=s.extname(e),!this.ext&&!this.defaultEngine)throw new Error("No default engine was specified and no extension was provided.");this.ext||(this.name+=this.ext=("."!==this.defaultEngine[0]?".":"")+this.defaultEngine)}var n=this;t.prototype.render=function(e,t){n.render(this.name,e,t)},e.set("view",t)},render:function(e,t,n){a.isFunction(t)&&(n=t,t=null);var r=null;return this.getTemplate(e,function(e,s){if(e&&n)i(n,e);else{if(e)throw e;r=s.render(t,n)}}),r},renderString:function(e,t,n,i){a.isFunction(n)&&(i=n,n={}),n=n||{};var s=new r(e,this,n.path);return s.render(t,i)}}),v=l.extend({init:function(e,t){this.ctx={};for(var n in e)e.hasOwnProperty(n)&&(this.ctx[n]=e[n]);this.blocks={},this.exported=[];for(var i in t)this.addBlock(i,t[i])},lookup:function(e){return e in f&&!(e in this.ctx)?f[e]:this.ctx[e]},setVariable:function(e,t){this.ctx[e]=t},getVariables:function(){return this.ctx},addBlock:function(e,t){this.blocks[e]=this.blocks[e]||[],this.blocks[e].push(t)},getBlock:function(e){if(!this.blocks[e])throw new Error('unknown block "'+e+'"');return this.blocks[e][0]},getSuper:function(e,t,n,i,r,s){var o=a.indexOf(this.blocks[t]||[],n),l=this.blocks[t][o+1],c=this;if(-1===o||!l)throw new Error('no super block available for "'+t+'"');l(e,c,i,r,s)},addExport:function(e){this.exported.push(e)},getExported:function(){for(var e={},t=0;t<this.exported.length;t++){var n=this.exported[t];e[n]=this.ctx[n]}return e}});r=l.extend({init:function(e,t,n,i){if(this.env=t||new d,a.isObject(e))switch(e.type){case"code":this.tmplProps=e.obj;break;case"string":this.tmplStr=e.obj}else{if(!a.isString(e))throw new Error("src must be a string or an object describing the source");this.tmplStr=e}if(this.path=n,i){var r=this;try{r._compile()}catch(s){throw a.prettifyError(this.path,this.env.dev,s)}}else this.compiled=!1},render:function(e,t,n){"function"==typeof e?(n=e,e={}):"function"==typeof t&&(n=t,t=null);var r=!0;t&&(r=!1);var s=this;try{s.compile()}catch(o){var l=a.prettifyError(this.path,this.env.dev,o);if(n)return i(n,l);throw l}var c=new v(e||{},s.blocks),h=t?t.push():new m;h.topLevel=!0;var u=null;return s.rootRenderFunc(s.env,c,h||new m,p,function(e,t){if(e&&(e=a.prettifyError(s.path,s.env.dev,e)),n)r?i(n,e,t):n(e,t);else{if(e)throw e;u=t}}),u},getExported:function(e,t,n){"function"==typeof e&&(n=e,e={}),"function"==typeof t&&(n=t,t=null);try{this.compile()}catch(i){if(n)return n(i);throw i}var r=t?t.push():new m;r.topLevel=!0;var s=new v(e||{},this.blocks);this.rootRenderFunc(this.env,s,r,p,function(){n(null,s.getExported())})},compile:function(){this.compiled||this._compile()},_compile:function(){var e;if(this.tmplProps)e=this.tmplProps;else{var t=c.compile(this.tmplStr,this.env.asyncFilters,this.env.extensionsList,this.path,this.env.opts),n=new Function(t);e=n()}this.blocks=this._getBlocks(e),this.rootRenderFunc=e.root,this.compiled=!0},_getBlocks:function(e){var t={};for(var n in e)"b_"===n.slice(0,2)&&(t[n.slice(2)]=e[n]);return t}}),e.exports={Environment:d,Template:r}},function(e,t,n){"use strict";function i(e){return function(t,n){this.compile(t.left,n),this.emit(e),this.compile(t.right,n)}}var r=n(1),s=n(4),o=n(13),a=n(14),l=n(9),c=n(6).Frame,h={"==":"==","!=":"!=","<":"<",">":">","<=":"<=",">=":">="},u=l.extend({init:function(e,t){this.templateName=e,this.codebuf=[],this.lastId=0,this.buffer=null,this.bufferStack=[],this.scopeClosers="",this.inBlock=!1,this.throwOnUndefined=t},fail:function(e,t,n){throw void 0!==t&&(t+=1),void 0!==n&&(n+=1),new r.TemplateError(e,t,n)},pushBufferId:function(e){this.bufferStack.push(this.buffer),this.buffer=e,this.emit("var "+this.buffer+' = "";')},popBufferId:function(){this.buffer=this.bufferStack.pop()},emit:function(e){this.codebuf.push(e)},emitLine:function(e){this.emit(e+"\n")},emitLines:function(){r.each(r.toArray(arguments),function(e){this.emitLine(e)},this)},emitFuncBegin:function(e){this.buffer="output",this.scopeClosers="",this.emitLine("function "+e+"(env, context, frame, runtime, cb) {"),this.emitLine("var lineno = null;"),this.emitLine("var colno = null;"),this.emitLine("var "+this.buffer+' = "";'),this.emitLine("try {")},emitFuncEnd:function(e){e||this.emitLine("cb(null, "+this.buffer+");"),this.closeScopeLevels(),this.emitLine("} catch (e) {"),this.emitLine("  cb(runtime.handleError(e, lineno, colno));"),this.emitLine("}"),this.emitLine("}"),this.buffer=null},addScopeLevel:function(){this.scopeClosers+="})"},closeScopeLevels:function(){this.emitLine(this.scopeClosers+";"),this.scopeClosers=""},withScopedSyntax:function(e){var t=this.scopeClosers;this.scopeClosers="",e.call(this),this.closeScopeLevels(),this.scopeClosers=t},makeCallback:function(e){var t=this.tmpid();return"function("+t+(e?","+e:"")+") {\nif("+t+") { cb("+t+"); return; }"},tmpid:function(){return this.lastId++,"t_"+this.lastId},_templateName:function(){return null==this.templateName?"undefined":JSON.stringify(this.templateName)},_compileChildren:function(e,t){for(var n=e.children,i=0,r=n.length;r>i;i++)this.compile(n[i],t)},_compileAggregate:function(e,t,n,i){n&&this.emit(n);for(var r=0;r<e.children.length;r++)r>0&&this.emit(","),this.compile(e.children[r],t);i&&this.emit(i)},_compileExpression:function(e,t){this.assertType(e,a.Literal,a.Symbol,a.Group,a.Array,a.Dict,a.FunCall,a.Caller,a.Filter,a.LookupVal,a.Compare,a.InlineIf,a.In,a.And,a.Or,a.Not,a.Add,a.Sub,a.Mul,a.Div,a.FloorDiv,a.Mod,a.Pow,a.Neg,a.Pos,a.Compare,a.NodeList),this.compile(e,t)},assertType:function(e){for(var t=r.toArray(arguments).slice(1),n=!1,i=0;i<t.length;i++)e instanceof t[i]&&(n=!0);n||this.fail("assertType: invalid type: "+e.typename,e.lineno,e.colno)},compileCallExtension:function(e,t,n){var i=e.args,s=e.contentArgs,o="boolean"==typeof e.autoescape?e.autoescape:!0;if(n||this.emit(this.buffer+" += runtime.suppressValue("),this.emit('env.getExtension("'+e.extName+'")["'+e.prop+'"]('),this.emit("context"),(i||s)&&this.emit(","),i&&(i instanceof a.NodeList||this.fail("compileCallExtension: arguments must be a NodeList, use `parser.parseSignature`"),r.each(i.children,function(e,n){this._compileExpression(e,t),(n!==i.children.length-1||s.length)&&this.emit(",")},this)),s.length&&r.each(s,function(e,n){if(n>0&&this.emit(","),e){var i=this.tmpid();this.emitLine("function(cb) {"),this.emitLine("if(!cb) { cb = function(err) { if(err) { throw err; }}}"),this.pushBufferId(i),this.withScopedSyntax(function(){this.compile(e,t),this.emitLine("cb(null, "+i+");")}),this.popBufferId(),this.emitLine("return "+i+";"),this.emitLine("}")}else this.emit("null")},this),n){var l=this.tmpid();this.emitLine(", "+this.makeCallback(l)),this.emitLine(this.buffer+" += runtime.suppressValue("+l+", "+o+" && env.opts.autoescape);"),this.addScopeLevel()}else this.emit(")"),this.emit(", "+o+" && env.opts.autoescape);\n")},compileCallExtensionAsync:function(e,t){this.compileCallExtension(e,t,!0)},compileNodeList:function(e,t){this._compileChildren(e,t)},compileLiteral:function(e){if("string"==typeof e.value){var t=e.value.replace(/\\/g,"\\\\");t=t.replace(/"/g,'\\"'),t=t.replace(/\n/g,"\\n"),t=t.replace(/\r/g,"\\r"),t=t.replace(/\t/g,"\\t"),this.emit('"'+t+'"')}else this.emit(e.value.toString())},compileSymbol:function(e,t){var n,i=e.value;this.emit((n=t.lookup(i))?n:'runtime.contextOrFrameLookup(context, frame, "'+i+'")')},compileGroup:function(e,t){this._compileAggregate(e,t,"(",")")},compileArray:function(e,t){this._compileAggregate(e,t,"[","]")},compileDict:function(e,t){this._compileAggregate(e,t,"{","}")},compilePair:function(e,t){var n=e.key,i=e.value;n instanceof a.Symbol?n=new a.Literal(n.lineno,n.colno,n.value):n instanceof a.Literal&&"string"==typeof n.value||this.fail("compilePair: Dict keys must be strings or names",n.lineno,n.colno),this.compile(n,t),this.emit(": "),this._compileExpression(i,t)},compileInlineIf:function(e,t){this.emit("("),this.compile(e.cond,t),this.emit("?"),this.compile(e.body,t),this.emit(":"),null!==e.else_?this.compile(e.else_,t):this.emit('""'),this.emit(")")},compileIn:function(e,t){this.emit("("),this.compile(e.right,t),this.emit(".indexOf("),this.compile(e.left,t),this.emit(") !== -1)")},compileOr:i(" || "),compileAnd:i(" && "),compileAdd:i(" + "),compileSub:i(" - "),compileMul:i(" * "),compileDiv:i(" / "),compileMod:i(" % "),compileNot:function(e,t){this.emit("!"),this.compile(e.target,t)},compileFloorDiv:function(e,t){this.emit("Math.floor("),this.compile(e.left,t),this.emit(" / "),this.compile(e.right,t),this.emit(")")},compilePow:function(e,t){this.emit("Math.pow("),this.compile(e.left,t),this.emit(", "),this.compile(e.right,t),this.emit(")")},compileNeg:function(e,t){this.emit("-"),this.compile(e.target,t)},compilePos:function(e,t){this.emit("+"),this.compile(e.target,t)},compileCompare:function(e,t){this.compile(e.expr,t);for(var n=0;n<e.ops.length;n++){var i=e.ops[n];this.emit(" "+h[i.type]+" "),this.compile(i.expr,t)}},compileLookupVal:function(e,t){this.emit("runtime.memberLookup(("),this._compileExpression(e.target,t),this.emit("),"),this._compileExpression(e.val,t),this.emit(")")},_getNodeName:function(e){switch(e.typename){case"Symbol":return e.value;case"FunCall":return"the return value of ("+this._getNodeName(e.name)+")";case"LookupVal":return this._getNodeName(e.target)+'["'+this._getNodeName(e.val)+'"]';case"Literal":return e.value.toString().substr(0,10);default:return"--expression--"}},compileFunCall:function(e,t){this.emit("(lineno = "+e.lineno+", colno = "+e.colno+", "),this.emit("runtime.callWrap("),this._compileExpression(e.name,t),this.emit(', "'+this._getNodeName(e.name).replace(/"/g,'\\"')+'", '),this._compileAggregate(e.args,t,"[","])"),this.emit(")")},compileFilter:function(e,t){var n=e.name;this.assertType(n,a.Symbol),this.emit('env.getFilter("'+n.value+'").call(context, '),this._compileAggregate(e.args,t),this.emit(")")},compileFilterAsync:function(e,t){var n=e.name;this.assertType(n,a.Symbol);var i=e.symbol.value;t.set(i,i),this.emit('env.getFilter("'+n.value+'").call(context, '),this._compileAggregate(e.args,t),this.emitLine(", "+this.makeCallback(i)),this.addScopeLevel()},compileKeywordArgs:function(e,t){var n=[];r.each(e.children,function(e){n.push(e.key.value)}),this.emit("runtime.makeKeywordArgs("),this.compileDict(e,t),this.emit(")")},compileSet:function(e,t){var n=[];r.each(e.targets,function(e){var i=e.value,r=t.lookup(i);(null===r||void 0===r)&&(r=this.tmpid(),this.emitLine("var "+r+";")),n.push(r)},this),this.emit(n.join(" = ")+" = "),this._compileExpression(e.value,t),this.emitLine(";"),r.each(e.targets,function(e,t){var i=n[t],r=e.value;this.emitLine('frame.set("'+r+'", '+i+", true);"),this.emitLine("if(frame.topLevel) {"),this.emitLine('context.setVariable("'+r+'", '+i+");"),this.emitLine("}"),"_"!==r.charAt(0)&&(this.emitLine("if(frame.topLevel) {"),this.emitLine('context.addExport("'+r+'", '+i+");"),this.emitLine("}"))},this)},compileIf:function(e,t,n){this.emit("if("),this._compileExpression(e.cond,t),this.emitLine(") {"),this.withScopedSyntax(function(){this.compile(e.body,t),n&&this.emit("cb()")}),e.else_?(this.emitLine("}\nelse {"),this.withScopedSyntax(function(){this.compile(e.else_,t),n&&this.emit("cb()")})):n&&(this.emitLine("}\nelse {"),this.emit("cb()")),this.emitLine("}")},compileIfAsync:function(e,t){this.emit("(function(cb) {"),this.compileIf(e,t,!0),this.emit("})(function() {"),this.addScopeLevel()},emitLoopBindings:function(e,t,n,i){var r={index:n+" + 1",index0:n,revindex:i+" - "+n,revindex0:i+" - "+n+" - 1",first:n+" === 0",last:n+" === "+i+" - 1",length:i};for(var s in r)this.emitLine('frame.set("loop.'+s+'", '+r[s]+");")},compileFor:function(e,t){var n,i=this.tmpid(),r=this.tmpid(),s=this.tmpid();if(t=t.push(),this.emitLine("frame = frame.push();"),this.emit("var "+s+" = "),this._compileExpression(e.arr,t),this.emitLine(";"),this.emit("if("+s+") {"),e.name instanceof a.Array){this.emitLine("var "+i+";"),this.emitLine("if(runtime.isArray("+s+")) {"),this.emitLine("var "+r+" = "+s+".length;"),this.emitLine("for("+i+"=0; "+i+" < "+s+".length; "+i+"++) {");for(var o=0;o<e.name.children.length;o++){var l=this.tmpid();this.emitLine("var "+l+" = "+s+"["+i+"]["+o+"]"),this.emitLine('frame.set("'+e.name.children[o].value+'", '+s+"["+i+"]["+o+"]);"),t.set(e.name.children[o].value,l)}this.emitLoopBindings(e,s,i,r),this.withScopedSyntax(function(){this.compile(e.body,t)}),this.emitLine("}"),this.emitLine("} else {");var c=e.name.children[0],h=e.name.children[1],u=this.tmpid();n=this.tmpid(),t.set(c.value,u),t.set(h.value,n),this.emitLine(i+" = -1;"),this.emitLine("var "+r+" = runtime.keys("+s+").length;"),this.emitLine("for(var "+u+" in "+s+") {"),this.emitLine(i+"++;"),this.emitLine("var "+n+" = "+s+"["+u+"];"),this.emitLine('frame.set("'+c.value+'", '+u+");"),this.emitLine('frame.set("'+h.value+'", '+n+");"),this.emitLoopBindings(e,s,i,r),this.withScopedSyntax(function(){this.compile(e.body,t)}),this.emitLine("}"),this.emitLine("}")}else n=this.tmpid(),t.set(e.name.value,n),this.emitLine("var "+r+" = "+s+".length;"),this.emitLine("for(var "+i+"=0; "+i+" < "+s+".length; "+i+"++) {"),this.emitLine("var "+n+" = "+s+"["+i+"];"),this.emitLine('frame.set("'+e.name.value+'", '+n+");"),this.emitLoopBindings(e,s,i,r),this.withScopedSyntax(function(){this.compile(e.body,t)}),this.emitLine("}");this.emitLine("}"),e.else_&&(this.emitLine("if (!"+r+") {"),this.compile(e.else_,t),this.emitLine("}")),this.emitLine("frame = frame.pop();")},_compileAsyncLoop:function(e,t,n){var i=this.tmpid(),s=this.tmpid(),o=this.tmpid(),l=n?"asyncAll":"asyncEach";if(t=t.push(),this.emitLine("frame = frame.push();"),this.emit("var "+o+" = "),this._compileExpression(e.arr,t),this.emitLine(";"),e.name instanceof a.Array)this.emit("runtime."+l+"("+o+", "+e.name.children.length+", function("),r.each(e.name.children,function(e){this.emit(e.value+",")},this),this.emit(i+","+s+",next) {"),r.each(e.name.children,function(e){var n=e.value;t.set(n,n),this.emitLine('frame.set("'+n+'", '+n+");")},this);else{var c=e.name.value;this.emitLine("runtime."+l+"("+o+", 1, function("+c+", "+i+", "+s+",next) {"),this.emitLine('frame.set("'+c+'", '+c+");"),t.set(c,c)}this.emitLoopBindings(e,o,i,s),this.withScopedSyntax(function(){var r;n&&(r=this.tmpid(),this.pushBufferId(r)),this.compile(e.body,t),this.emitLine("next("+i+(r?","+r:"")+");"),n&&this.popBufferId()});var h=this.tmpid();this.emitLine("}, "+this.makeCallback(h)),this.addScopeLevel(),n&&this.emitLine(this.buffer+" += "+h+";"),e.else_&&(this.emitLine("if (!"+o+".length) {"),this.compile(e.else_,t),this.emitLine("}")),this.emitLine("frame = frame.pop();")},compileAsyncEach:function(e,t){this._compileAsyncLoop(e,t)},compileAsyncAll:function(e,t){this._compileAsyncLoop(e,t,!0)},_compileMacro:function(e,t){var n=[],i=null,s="macro_"+this.tmpid();r.each(e.args.children,function(t,r){r===e.args.children.length-1&&t instanceof a.Dict?i=t:(this.assertType(t,a.Symbol),n.push(t))},this);var o=r.map(n,function(e){return"l_"+e.value});o.push("kwargs");var l=r.map(n,function(e){return'"'+e.value+'"'}),c=r.map(i&&i.children||[],function(e){return'"'+e.key.value+'"'});t=t.push(),this.emitLines("var "+s+" = runtime.makeMacro(","["+l.join(", ")+"], ","["+c.join(", ")+"], ","function ("+o.join(", ")+") {","frame = frame.push();","kwargs = kwargs || {};",'if (kwargs.hasOwnProperty("caller")) {','frame.set("caller", kwargs.caller); }'),r.each(n,function(e){this.emitLine('frame.set("'+e.value+'", l_'+e.value+");"),t.set(e.value,"l_"+e.value)},this),i&&r.each(i.children,function(e){var n=e.key.value;this.emit('frame.set("'+n+'", kwargs.hasOwnProperty("'+n+'") ? kwargs["'+n+'"] : '),this._compileExpression(e.value,t),this.emitLine(");")},this);var h=this.tmpid();return this.pushBufferId(h),this.withScopedSyntax(function(){this.compile(e.body,t)}),t=t.pop(),this.emitLine("frame = frame.pop();"),this.emitLine("return new runtime.SafeString("+h+");"),this.emitLine("});"),this.popBufferId(),s},compileMacro:function(e,t){var n=this._compileMacro(e,t),i=e.name.value;t.set(i,n),t.parent?this.emitLine('frame.set("'+i+'", '+n+");"):("_"!==e.name.value.charAt(0)&&this.emitLine('context.addExport("'+i+'");'),this.emitLine('context.setVariable("'+i+'", '+n+");"))},compileCaller:function(e,t){this.emit("(function (){");var n=this._compileMacro(e,t);this.emit("return "+n+";})()")},compileImport:function(e,t){var n=this.tmpid(),i=e.target.value;this.emit("env.getTemplate("),this._compileExpression(e.template,t),this.emitLine(", false, "+this._templateName()+", "+this.makeCallback(n)),this.addScopeLevel(),this.emitLine(n+".getExported("+(e.withContext?"context.getVariables(), frame, ":"")+this.makeCallback(n)),this.addScopeLevel(),t.set(i,n),this.emitLine(t.parent?'frame.set("'+i+'", '+n+");":'context.setVariable("'+i+'", '+n+");")},compileFromImport:function(e,t){var n=this.tmpid();this.emit("env.getTemplate("),this._compileExpression(e.template,t),this.emitLine(", false, "+this._templateName()+", "+this.makeCallback(n)),this.addScopeLevel(),this.emitLine(n+".getExported("+(e.withContext?"context.getVariables(), frame, ":"")+this.makeCallback(n)),this.addScopeLevel(),r.each(e.names.children,function(e){var i,r,s=this.tmpid();e instanceof a.Pair?(i=e.key.value,r=e.value.value):(i=e.value,r=i),this.emitLine("if("+n+'.hasOwnProperty("'+i+'")) {'),this.emitLine("var "+s+" = "+n+"."+i+";"),this.emitLine("} else {"),this.emitLine("cb(new Error(\"cannot import '"+i+"'\")); return;"),this.emitLine("}"),t.set(r,s),this.emitLine(t.parent?'frame.set("'+r+'", '+s+");":'context.setVariable("'+r+'", '+s+");")},this)},compileBlock:function(e){var t=this.tmpid();this.inBlock||this.emit('(parentTemplate ? function(e, c, f, r, cb) { cb(""); } : '),this.emit('context.getBlock("'+e.name.value+'")'),this.inBlock||this.emit(")"),this.emitLine("(env, context, frame, runtime, "+this.makeCallback(t)),this.emitLine(this.buffer+" += "+t+";"),this.addScopeLevel()},compileSuper:function(e,t){var n=e.blockName.value,i=e.symbol.value;this.emitLine('context.getSuper(env, "'+n+'", b_'+n+", frame, runtime, "+this.makeCallback(i)),this.emitLine(i+" = runtime.markSafe("+i+");"),this.addScopeLevel(),t.set(i,i)},compileExtends:function(e,t){var n=this.tmpid();this.emit("env.getTemplate("),this._compileExpression(e.template,t),this.emitLine(", true, "+this._templateName()+", "+this.makeCallback("_parentTemplate")),this.emitLine("parentTemplate = _parentTemplate"),this.emitLine("for(var "+n+" in parentTemplate.blocks) {"),this.emitLine("context.addBlock("+n+", parentTemplate.blocks["+n+"]);"),this.emitLine("}"),this.addScopeLevel()},compileInclude:function(e,t){var n=this.tmpid(),i=this.tmpid();this.emit("env.getTemplate("),this._compileExpression(e.template,t),this.emitLine(", false, "+this._templateName()+", "+this.makeCallback(n)),this.addScopeLevel(),this.emitLine(n+".render(context.getVariables(), frame, "+this.makeCallback(i)),this.emitLine(this.buffer+" += "+i),this.addScopeLevel()},compileTemplateData:function(e,t){this.compileLiteral(e,t)},compileOutput:function(e,t){for(var n=e.children,i=0,r=n.length;r>i;i++)n[i]instanceof a.TemplateData?n[i].value&&(this.emit(this.buffer+" += "),this.compileLiteral(n[i],t),this.emitLine(";")):(this.emit(this.buffer+" += runtime.suppressValue("),this.throwOnUndefined&&this.emit("runtime.ensureDefined("),this.compile(n[i],t),this.throwOnUndefined&&this.emit(","+e.lineno+","+e.colno+")"),this.emit(", env.opts.autoescape);\n"))},compileRoot:function(e,t){t&&this.fail("compileRoot: root node can't have frame"),t=new c,this.emitFuncBegin("root"),this.emitLine("var parentTemplate = null;"),this._compileChildren(e,t),this.emitLine("if(parentTemplate) {"),this.emitLine("parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);"),this.emitLine("} else {"),this.emitLine("cb(null, "+this.buffer+");"),this.emitLine("}"),this.emitFuncEnd(!0),this.inBlock=!0;var n,i,r,s=e.findAll(a.Block);for(n=0;n<s.length;n++){r=s[n],i=r.name.value,this.emitFuncBegin("b_"+i);var o=new c;this.compile(r.body,o),this.emitFuncEnd()}for(this.emitLine("return {"),n=0;n<s.length;n++)r=s[n],i="b_"+r.name.value,this.emitLine(i+": "+i+",");this.emitLine("root: root\n};")},compile:function(e,t){var n=this["compile"+e.typename];n?n.call(this,e,t):this.fail("compile: Cannot compile node: "+e.typename,e.lineno,e.colno)},getCode:function(){return this.codebuf.join("")}});e.exports={compile:function(e,t,n,i,r){var a=new u(i,r.throwOnUndefined);if(n&&n.length)for(var l=0;l<n.length;l++)"preprocess"in n[l]&&(e=n[l].preprocess(e,i));return a.compile(o.transform(s.parse(e,n,r),t,i)),a.getCode()},Compiler:u}},function(e,t,n){"use strict";var i=n(5),r=n(14),s=n(9),o=n(1),a=s.extend({init:function(e){this.tokens=e,this.peeked=null,this.breakOnBlocks=null,this.dropLeadingWhitespace=!1,this.extensions=[]},nextToken:function(e){var t;if(this.peeked){if(e||this.peeked.type!==i.TOKEN_WHITESPACE)return t=this.peeked,this.peeked=null,t;this.peeked=null}if(t=this.tokens.nextToken(),!e)for(;t&&t.type===i.TOKEN_WHITESPACE;)t=this.tokens.nextToken();return t},peekToken:function(){return this.peeked=this.peeked||this.nextToken(),this.peeked},pushToken:function(e){if(this.peeked)throw new Error("pushToken: can only push one token on between reads");this.peeked=e},fail:function(e,t,n){if((void 0===t||void 0===n)&&this.peekToken()){var i=this.peekToken();t=i.lineno,n=i.colno}throw void 0!==t&&(t+=1),void 0!==n&&(n+=1),new o.TemplateError(e,t,n)},skip:function(e){var t=this.nextToken();return t&&t.type===e?!0:(this.pushToken(t),!1)},expect:function(e){var t=this.nextToken();return t.type!==e&&this.fail("expected "+e+", got "+t.type,t.lineno,t.colno),t},skipValue:function(e,t){var n=this.nextToken();return n&&n.type===e&&n.value===t?!0:(this.pushToken(n),!1)},skipSymbol:function(e){return this.skipValue(i.TOKEN_SYMBOL,e)},advanceAfterBlockEnd:function(e){var t;e||(t=this.peekToken(),t||this.fail("unexpected end of file"),t.type!==i.TOKEN_SYMBOL&&this.fail("advanceAfterBlockEnd: expected symbol token or explicit name to be passed"),e=this.nextToken().value),t=this.nextToken(),t&&t.type===i.TOKEN_BLOCK_END?"-"===t.value.charAt(0)&&(this.dropLeadingWhitespace=!0):this.fail("expected block end in "+e+" statement")},advanceAfterVariableEnd:function(){this.skip(i.TOKEN_VARIABLE_END)||this.fail("expected variable end")},parseFor:function(){var e,t,n=this.peekToken();this.skipSymbol("for")?(e=new r.For(n.lineno,n.colno),t="endfor"):this.skipSymbol("asyncEach")?(e=new r.AsyncEach(n.lineno,n.colno),t="endeach"):this.skipSymbol("asyncAll")?(e=new r.AsyncAll(n.lineno,n.colno),t="endall"):this.fail("parseFor: expected for{Async}",n.lineno,n.colno),e.name=this.parsePrimary(),e.name instanceof r.Symbol||this.fail("parseFor: variable name expected for loop");var s=this.peekToken().type;if(s===i.TOKEN_COMMA){var o=e.name;for(e.name=new r.Array(o.lineno,o.colno),e.name.addChild(o);this.skip(i.TOKEN_COMMA);){var a=this.parsePrimary();e.name.addChild(a)}}return this.skipSymbol("in")||this.fail('parseFor: expected "in" keyword for loop',n.lineno,n.colno),e.arr=this.parseExpression(),this.advanceAfterBlockEnd(n.value),e.body=this.parseUntilBlocks(t,"else"),this.skipSymbol("else")&&(this.advanceAfterBlockEnd("else"),e.else_=this.parseUntilBlocks(t)),this.advanceAfterBlockEnd(),e},parseMacro:function(){var e=this.peekToken();this.skipSymbol("macro")||this.fail("expected macro");var t=this.parsePrimary(!0),n=this.parseSignature(),i=new r.Macro(e.lineno,e.colno,t,n);return this.advanceAfterBlockEnd(e.value),i.body=this.parseUntilBlocks("endmacro"),this.advanceAfterBlockEnd(),i},parseCall:function(){var e=this.peekToken();this.skipSymbol("call")||this.fail("expected call");var t=this.parseSignature(!0)||new r.NodeList,n=this.parsePrimary();this.advanceAfterBlockEnd(e.value);var i=this.parseUntilBlocks("endcall");this.advanceAfterBlockEnd();var s=new r.Symbol(e.lineno,e.colno,"caller"),o=new r.Caller(e.lineno,e.colno,s,t,i),a=n.args.children;a[a.length-1]instanceof r.KeywordArgs||a.push(new r.KeywordArgs);var l=a[a.length-1];return l.addChild(new r.Pair(e.lineno,e.colno,s,o)),new r.Output(e.lineno,e.colno,[n])},parseWithContext:function(){var e=this.peekToken(),t=null;return this.skipSymbol("with")?t=!0:this.skipSymbol("without")&&(t=!1),null!==t&&(this.skipSymbol("context")||this.fail("parseFrom: expected context after with/without",e.lineno,e.colno)),t},parseImport:function(){var e=this.peekToken();this.skipSymbol("import")||this.fail("parseImport: expected import",e.lineno,e.colno);var t=this.parseExpression();this.skipSymbol("as")||this.fail('parseImport: expected "as" keyword',e.lineno,e.colno);var n=this.parsePrimary(),i=this.parseWithContext(),s=new r.Import(e.lineno,e.colno,t,n,i);return this.advanceAfterBlockEnd(e.value),s},parseFrom:function(){var e=this.peekToken();this.skipSymbol("from")||this.fail("parseFrom: expected from");var t=this.parsePrimary();this.skipSymbol("import")||this.fail("parseFrom: expected import",e.lineno,e.colno);for(var n,s=new r.NodeList;;){var o=this.peekToken();if(o.type===i.TOKEN_BLOCK_END){s.children.length||this.fail("parseFrom: Expected at least one import name",e.lineno,e.colno),"-"===o.value.charAt(0)&&(this.dropLeadingWhitespace=!0),this.nextToken();break}s.children.length>0&&!this.skip(i.TOKEN_COMMA)&&this.fail("parseFrom: expected comma",e.lineno,e.colno);var a=this.parsePrimary();if("_"===a.value.charAt(0)&&this.fail("parseFrom: names starting with an underscore cannot be imported",a.lineno,a.colno),this.skipSymbol("as")){var l=this.parsePrimary();s.addChild(new r.Pair(a.lineno,a.colno,a,l))}else s.addChild(a);n=this.parseWithContext()}return new r.FromImport(e.lineno,e.colno,t,s,n);
-
-},parseBlock:function(){var e=this.peekToken();this.skipSymbol("block")||this.fail("parseBlock: expected block",e.lineno,e.colno);var t=new r.Block(e.lineno,e.colno);return t.name=this.parsePrimary(),t.name instanceof r.Symbol||this.fail("parseBlock: variable name expected",e.lineno,e.colno),this.advanceAfterBlockEnd(e.value),t.body=this.parseUntilBlocks("endblock"),this.peekToken()||this.fail("parseBlock: expected endblock, got end of file"),this.advanceAfterBlockEnd(),t},parseTemplateRef:function(e,t){var n=this.peekToken();this.skipSymbol(e)||this.fail("parseTemplateRef: expected "+e);var i=new t(n.lineno,n.colno);return i.template=this.parseExpression(),this.advanceAfterBlockEnd(n.value),i},parseExtends:function(){return this.parseTemplateRef("extends",r.Extends)},parseInclude:function(){return this.parseTemplateRef("include",r.Include)},parseIf:function(){var e,t=this.peekToken();this.skipSymbol("if")||this.skipSymbol("elif")?e=new r.If(t.lineno,t.colno):this.skipSymbol("ifAsync")?e=new r.IfAsync(t.lineno,t.colno):this.fail("parseIf: expected if or elif",t.lineno,t.colno),e.cond=this.parseExpression(),this.advanceAfterBlockEnd(t.value),e.body=this.parseUntilBlocks("elif","else","endif");var n=this.peekToken();switch(n&&n.value){case"elif":e.else_=this.parseIf();break;case"else":this.advanceAfterBlockEnd(),e.else_=this.parseUntilBlocks("endif"),this.advanceAfterBlockEnd();break;case"endif":e.else_=null,this.advanceAfterBlockEnd();break;default:this.fail("parseIf: expected endif, else, or endif, got end of file")}return e},parseSet:function(){var e=this.peekToken();this.skipSymbol("set")||this.fail("parseSet: expected set",e.lineno,e.colno);for(var t,n=new r.Set(e.lineno,e.colno,[]);(t=this.parsePrimary())&&(n.targets.push(t),this.skip(i.TOKEN_COMMA)););return this.skipValue(i.TOKEN_OPERATOR,"=")||this.fail("parseSet: expected = in set tag",e.lineno,e.colno),n.value=this.parseExpression(),this.advanceAfterBlockEnd(e.value),n},parseStatement:function(){var e,t=this.peekToken();if(t.type!==i.TOKEN_SYMBOL&&this.fail("tag name expected",t.lineno,t.colno),this.breakOnBlocks&&-1!==o.indexOf(this.breakOnBlocks,t.value))return null;switch(t.value){case"raw":return this.parseRaw();case"if":case"ifAsync":return this.parseIf();case"for":case"asyncEach":case"asyncAll":return this.parseFor();case"block":return this.parseBlock();case"extends":return this.parseExtends();case"include":return this.parseInclude();case"set":return this.parseSet();case"macro":return this.parseMacro();case"call":return this.parseCall();case"import":return this.parseImport();case"from":return this.parseFrom();case"filter":return this.parseFilterStatement();default:if(this.extensions.length)for(var n=0;n<this.extensions.length;n++){var s=this.extensions[n];if(-1!==o.indexOf(s.tags||[],t.value))return s.parse(this,r,i)}this.fail("unknown block tag: "+t.value,t.lineno,t.colno)}return e},parseRaw:function(){this.advanceAfterBlockEnd();for(var e="",t=this.peekToken();;){var n=this.nextToken(!0);if(n||this.fail("expected endraw, got end of file"),n.type===i.TOKEN_BLOCK_START){var s=null,o=this.nextToken(!0);if(o.type===i.TOKEN_WHITESPACE&&(s=o,o=this.nextToken()),o.type===i.TOKEN_SYMBOL&&"endraw"===o.value){this.advanceAfterBlockEnd(o.value);break}e+=n.value,s&&(e+=s.value),e+=o.value}else e+=n.type===i.TOKEN_STRING?'"'+n.value+'"':n.value}var a=new r.Output(t.lineno,t.colno,[new r.TemplateData(t.lineno,t.colno,e)]);return a},parsePostfix:function(e){for(var t,n=this.peekToken();n;){if(n.type===i.TOKEN_LEFT_PAREN)e=new r.FunCall(n.lineno,n.colno,e,this.parseSignature());else if(n.type===i.TOKEN_LEFT_BRACKET)t=this.parseAggregate(),t.children.length>1&&this.fail("invalid index"),e=new r.LookupVal(n.lineno,n.colno,e,t.children[0]);else{if(n.type!==i.TOKEN_OPERATOR||"."!==n.value)break;this.nextToken();var s=this.nextToken();s.type!==i.TOKEN_SYMBOL&&this.fail("expected name as lookup value, got "+s.value,s.lineno,s.colno),t=new r.Literal(s.lineno,s.colno,s.value),e=new r.LookupVal(n.lineno,n.colno,e,t)}n=this.peekToken()}return e},parseExpression:function(){var e=this.parseInlineIf();return e},parseInlineIf:function(){var e=this.parseOr();if(this.skipSymbol("if")){var t=this.parseOr(),n=e;e=new r.InlineIf(e.lineno,e.colno),e.body=n,e.cond=t,this.skipSymbol("else")?e.else_=this.parseOr():e.else_=null}return e},parseOr:function(){for(var e=this.parseAnd();this.skipSymbol("or");){var t=this.parseAnd();e=new r.Or(e.lineno,e.colno,e,t)}return e},parseAnd:function(){for(var e=this.parseNot();this.skipSymbol("and");){var t=this.parseNot();e=new r.And(e.lineno,e.colno,e,t)}return e},parseNot:function(){var e=this.peekToken();return this.skipSymbol("not")?new r.Not(e.lineno,e.colno,this.parseNot()):this.parseIn()},parseIn:function(){for(var e=this.parseCompare();;){var t=this.nextToken();if(!t)break;var n=t.type===i.TOKEN_SYMBOL&&"not"===t.value;if(n||this.pushToken(t),!this.skipSymbol("in")){n&&this.pushToken(t);break}var s=this.parseCompare();e=new r.In(e.lineno,e.colno,e,s),n&&(e=new r.Not(e.lineno,e.colno,e))}return e},parseCompare:function(){for(var e=["==","!=","<",">","<=",">="],t=this.parseAdd(),n=[];;){var i=this.nextToken();if(!i)break;if(-1===o.indexOf(e,i.value)){this.pushToken(i);break}n.push(new r.CompareOperand(i.lineno,i.colno,this.parseAdd(),i.value))}return n.length?new r.Compare(n[0].lineno,n[0].colno,t,n):t},parseAdd:function(){for(var e=this.parseSub();this.skipValue(i.TOKEN_OPERATOR,"+");){var t=this.parseSub();e=new r.Add(e.lineno,e.colno,e,t)}return e},parseSub:function(){for(var e=this.parseMul();this.skipValue(i.TOKEN_OPERATOR,"-");){var t=this.parseMul();e=new r.Sub(e.lineno,e.colno,e,t)}return e},parseMul:function(){for(var e=this.parseDiv();this.skipValue(i.TOKEN_OPERATOR,"*");){var t=this.parseDiv();e=new r.Mul(e.lineno,e.colno,e,t)}return e},parseDiv:function(){for(var e=this.parseFloorDiv();this.skipValue(i.TOKEN_OPERATOR,"/");){var t=this.parseFloorDiv();e=new r.Div(e.lineno,e.colno,e,t)}return e},parseFloorDiv:function(){for(var e=this.parseMod();this.skipValue(i.TOKEN_OPERATOR,"//");){var t=this.parseMod();e=new r.FloorDiv(e.lineno,e.colno,e,t)}return e},parseMod:function(){for(var e=this.parsePow();this.skipValue(i.TOKEN_OPERATOR,"%");){var t=this.parsePow();e=new r.Mod(e.lineno,e.colno,e,t)}return e},parsePow:function(){for(var e=this.parseUnary();this.skipValue(i.TOKEN_OPERATOR,"**");){var t=this.parseUnary();e=new r.Pow(e.lineno,e.colno,e,t)}return e},parseUnary:function(e){var t,n=this.peekToken();return t=this.skipValue(i.TOKEN_OPERATOR,"-")?new r.Neg(n.lineno,n.colno,this.parseUnary(!0)):this.skipValue(i.TOKEN_OPERATOR,"+")?new r.Pos(n.lineno,n.colno,this.parseUnary(!0)):this.parsePrimary(),e||(t=this.parseFilter(t)),t},parsePrimary:function(e){var t=this.nextToken(),n=null,s=null;return t?t.type===i.TOKEN_STRING?n=t.value:t.type===i.TOKEN_INT?n=parseInt(t.value,10):t.type===i.TOKEN_FLOAT?n=parseFloat(t.value):t.type===i.TOKEN_BOOLEAN?"true"===t.value?n=!0:"false"===t.value?n=!1:this.fail("invalid boolean: "+t.value,t.lineno,t.colno):t.type===i.TOKEN_REGEX&&(n=new RegExp(t.value.body,t.value.flags)):this.fail("expected expression, got end of file"),null!==n?s=new r.Literal(t.lineno,t.colno,n):t.type===i.TOKEN_SYMBOL?(s=new r.Symbol(t.lineno,t.colno,t.value),e||(s=this.parsePostfix(s))):(this.pushToken(t),s=this.parseAggregate()),s?s:void this.fail("unexpected token: "+t.value,t.lineno,t.colno)},parseFilterName:function(){for(var e=this.expect(i.TOKEN_SYMBOL),t=e.value;this.skipValue(i.TOKEN_OPERATOR,".");)t+="."+this.expect(i.TOKEN_SYMBOL).value;return new r.Symbol(e.lineno,e.colno,t)},parseFilterArgs:function(e){if(this.peekToken().type===i.TOKEN_LEFT_PAREN){var t=this.parsePostfix(e);return t.args.children}return[]},parseFilter:function(e){for(;this.skip(i.TOKEN_PIPE);){var t=this.parseFilterName();e=new r.Filter(t.lineno,t.colno,t,new r.NodeList(t.lineno,t.colno,[e].concat(this.parseFilterArgs(e))))}return e},parseFilterStatement:function(){var e=this.peekToken();this.skipSymbol("filter")||this.fail("parseFilterStatement: expected filter");var t=this.parseFilterName(),n=this.parseFilterArgs(t);this.advanceAfterBlockEnd(e.value);var i=this.parseUntilBlocks("endfilter");this.advanceAfterBlockEnd();var s=new r.Filter(t.lineno,t.colno,t,new r.NodeList(t.lineno,t.colno,i.children[0].children.concat(n)));return new r.Output(t.lineno,t.colno,[s])},parseAggregate:function(){var e,t=this.nextToken();switch(t.type){case i.TOKEN_LEFT_PAREN:e=new r.Group(t.lineno,t.colno);break;case i.TOKEN_LEFT_BRACKET:e=new r.Array(t.lineno,t.colno);break;case i.TOKEN_LEFT_CURLY:e=new r.Dict(t.lineno,t.colno);break;default:return null}for(;;){var n=this.peekToken().type;if(n===i.TOKEN_RIGHT_PAREN||n===i.TOKEN_RIGHT_BRACKET||n===i.TOKEN_RIGHT_CURLY){this.nextToken();break}if(e.children.length>0&&(this.skip(i.TOKEN_COMMA)||this.fail("parseAggregate: expected comma after expression",t.lineno,t.colno)),e instanceof r.Dict){var s=this.parsePrimary();this.skip(i.TOKEN_COLON)||this.fail("parseAggregate: expected colon after dict key",t.lineno,t.colno);var o=this.parseExpression();e.addChild(new r.Pair(s.lineno,s.colno,s,o))}else{var a=this.parseExpression();e.addChild(a)}}return e},parseSignature:function(e,t){var n=this.peekToken();if(!t&&n.type!==i.TOKEN_LEFT_PAREN){if(e)return null;this.fail("expected arguments",n.lineno,n.colno)}n.type===i.TOKEN_LEFT_PAREN&&(n=this.nextToken());for(var s=new r.NodeList(n.lineno,n.colno),o=new r.KeywordArgs(n.lineno,n.colno),a=!1;;){if(n=this.peekToken(),!t&&n.type===i.TOKEN_RIGHT_PAREN){this.nextToken();break}if(t&&n.type===i.TOKEN_BLOCK_END)break;if(a&&!this.skip(i.TOKEN_COMMA))this.fail("parseSignature: expected comma after expression",n.lineno,n.colno);else{var l=this.parseExpression();this.skipValue(i.TOKEN_OPERATOR,"=")?o.addChild(new r.Pair(l.lineno,l.colno,l,this.parseExpression())):s.addChild(l)}a=!0}return o.children.length&&s.addChild(o),s},parseUntilBlocks:function(){var e=this.breakOnBlocks;this.breakOnBlocks=o.toArray(arguments);var t=this.parse();return this.breakOnBlocks=e,t},parseNodes:function(){for(var e,t=[];e=this.nextToken();)if(e.type===i.TOKEN_DATA){var n=e.value,s=this.peekToken(),o=s&&s.value;this.dropLeadingWhitespace&&(n=n.replace(/^\s*/,""),this.dropLeadingWhitespace=!1),s&&s.type===i.TOKEN_BLOCK_START&&"-"===o.charAt(o.length-1)&&(n=n.replace(/\s*$/,"")),t.push(new r.Output(e.lineno,e.colno,[new r.TemplateData(e.lineno,e.colno,n)]))}else if(e.type===i.TOKEN_BLOCK_START){var a=this.parseStatement();if(!a)break;t.push(a)}else if(e.type===i.TOKEN_VARIABLE_START){var l=this.parseExpression();this.advanceAfterVariableEnd(),t.push(new r.Output(e.lineno,e.colno,[l]))}else e.type!==i.TOKEN_COMMENT&&this.fail("Unexpected token at top-level: "+e.type,e.lineno,e.colno);return t},parse:function(){return new r.NodeList(0,0,this.parseNodes())},parseAsRoot:function(){return new r.Root(0,0,this.parseNodes())}});e.exports={parse:function(e,t,n){var r=new a(i.lex(e,n));return void 0!==t&&(r.extensions=t),r.parseAsRoot()}}},function(e,t,n){"use strict";function i(e,t,n,i){return{type:e,value:t,lineno:n,colno:i}}function r(e,t){this.str=e,this.index=0,this.len=e.length,this.lineno=0,this.colno=0,this.in_code=!1,t=t||{};var n=t.tags||{};this.tags={BLOCK_START:n.blockStart||c,BLOCK_END:n.blockEnd||h,VARIABLE_START:n.variableStart||u,VARIABLE_END:n.variableEnd||p,COMMENT_START:n.commentStart||f,COMMENT_END:n.commentEnd||m},this.trimBlocks=!!t.trimBlocks,this.lstripBlocks=!!t.lstripBlocks}var s=n(1),o=" \n	\r ",a="()[]{}%*-+/#,:|.<>=!",l="0123456789",c="{%",h="%}",u="{{",p="}}",f="{#",m="#}",d="string",v="whitespace",g="data",y="block-start",k="block-end",x="variable-start",b="variable-end",E="comment",T="left-paren",w="right-paren",L="left-bracket",_="right-bracket",A="left-curly",O="right-curly",S="operator",N="comma",C="colon",B="pipe",F="int",R="float",K="boolean",I="symbol",M="special",P="regex";r.prototype.nextToken=function(){var e,t=this.lineno,n=this.colno;if(this.in_code){var r=this.current();if(this.is_finished())return null;if('"'===r||"'"===r)return i(d,this.parseString(r),t,n);if(e=this._extract(o))return i(v,e,t,n);if((e=this._extractString(this.tags.BLOCK_END))||(e=this._extractString("-"+this.tags.BLOCK_END)))return this.in_code=!1,this.trimBlocks&&(r=this.current(),"\n"===r&&this.forward()),i(k,e,t,n);if(e=this._extractString(this.tags.VARIABLE_END))return this.in_code=!1,i(b,e,t,n);if("r"===r&&"/"===this.str.charAt(this.index+1)){this.forwardN(2);for(var c="";!this.is_finished();){if("/"===this.current()&&"\\"!==this.previous()){this.forward();break}c+=this.current(),this.forward()}for(var h=["g","i","m","y"],u="";!this.is_finished();){var p=-1!==h.indexOf(this.current());if(!p)break;u+=this.current(),this.forward()}return i(P,{body:c,flags:u},t,n)}if(-1!==a.indexOf(r)){this.forward();var f,m=["==","!=","<=",">=","//","**"],M=r+this.current();switch(-1!==s.indexOf(m,M)&&(this.forward(),r=M),r){case"(":f=T;break;case")":f=w;break;case"[":f=L;break;case"]":f=_;break;case"{":f=A;break;case"}":f=O;break;case",":f=N;break;case":":f=C;break;case"|":f=B;break;default:f=S}return i(f,r,t,n)}if(e=this._extractUntil(o+a),e.match(/^[-+]?[0-9]+$/)){if("."===this.current()){this.forward();var D=this._extract(l);return i(R,e+"."+D,t,n)}return i(F,e,t,n)}if(e.match(/^(true|false)$/))return i(K,e,t,n);if(e)return i(I,e,t,n);throw new Error("Unexpected value while parsing: "+e)}var V=this.tags.BLOCK_START.charAt(0)+this.tags.VARIABLE_START.charAt(0)+this.tags.COMMENT_START.charAt(0)+this.tags.COMMENT_END.charAt(0);if(this.is_finished())return null;if((e=this._extractString(this.tags.BLOCK_START+"-"))||(e=this._extractString(this.tags.BLOCK_START)))return this.in_code=!0,i(y,e,t,n);if(e=this._extractString(this.tags.VARIABLE_START))return this.in_code=!0,i(x,e,t,n);e="";var j,U=!1;for(this._matches(this.tags.COMMENT_START)&&(U=!0,e=this._extractString(this.tags.COMMENT_START));null!==(j=this._extractUntil(V));){if(e+=j,(this._matches(this.tags.BLOCK_START)||this._matches(this.tags.VARIABLE_START)||this._matches(this.tags.COMMENT_START))&&!U){if(this.lstripBlocks&&this._matches(this.tags.BLOCK_START)&&this.colno>0&&this.colno<=e.length){var W=e.slice(-this.colno);if(/^\s+$/.test(W)&&(e=e.slice(0,-this.colno),!e.length))return this.nextToken()}break}if(this._matches(this.tags.COMMENT_END)){if(!U)throw new Error("unexpected end of comment");e+=this._extractString(this.tags.COMMENT_END);break}e+=this.current(),this.forward()}if(null===j&&U)throw new Error("expected end of comment, got end of file");return i(U?E:g,e,t,n)},r.prototype.parseString=function(e){this.forward();for(var t="";!this.is_finished()&&this.current()!==e;){var n=this.current();if("\\"===n){switch(this.forward(),this.current()){case"n":t+="\n";break;case"t":t+="	";break;case"r":t+="\r";break;default:t+=this.current()}this.forward()}else t+=n,this.forward()}return this.forward(),t},r.prototype._matches=function(e){if(this.index+e.length>this.len)return null;var t=this.str.slice(this.index,this.index+e.length);return t===e},r.prototype._extractString=function(e){return this._matches(e)?(this.index+=e.length,e):null},r.prototype._extractUntil=function(e){return this._extractMatching(!0,e||"")},r.prototype._extract=function(e){return this._extractMatching(!1,e)},r.prototype._extractMatching=function(e,t){if(this.is_finished())return null;var n=t.indexOf(this.current());if(e&&-1===n||!e&&-1!==n){var i=this.current();this.forward();for(var r=t.indexOf(this.current());(e&&-1===r||!e&&-1!==r)&&!this.is_finished();)i+=this.current(),this.forward(),r=t.indexOf(this.current());return i}return""},r.prototype.is_finished=function(){return this.index>=this.len},r.prototype.forwardN=function(e){for(var t=0;e>t;t++)this.forward()},r.prototype.forward=function(){this.index++,"\n"===this.previous()?(this.lineno++,this.colno=0):this.colno++},r.prototype.back=function(){if(this.index--,"\n"===this.current()){this.lineno--;var e=this.src.lastIndexOf("\n",this.index-1);-1===e?this.colno=this.index:this.colno=this.index-e}else this.colno--},r.prototype.current=function(){return this.is_finished()?"":this.str.charAt(this.index)},r.prototype.previous=function(){return this.str.charAt(this.index-1)},e.exports={lex:function(e,t){return new r(e,t)},TOKEN_STRING:d,TOKEN_WHITESPACE:v,TOKEN_DATA:g,TOKEN_BLOCK_START:y,TOKEN_BLOCK_END:k,TOKEN_VARIABLE_START:x,TOKEN_VARIABLE_END:b,TOKEN_COMMENT:E,TOKEN_LEFT_PAREN:T,TOKEN_RIGHT_PAREN:w,TOKEN_LEFT_BRACKET:L,TOKEN_RIGHT_BRACKET:_,TOKEN_LEFT_CURLY:A,TOKEN_RIGHT_CURLY:O,TOKEN_OPERATOR:S,TOKEN_COMMA:N,TOKEN_COLON:C,TOKEN_PIPE:B,TOKEN_INT:F,TOKEN_FLOAT:R,TOKEN_BOOLEAN:K,TOKEN_SYMBOL:I,TOKEN_SPECIAL:M,TOKEN_REGEX:P}},function(e,t,n){"use strict";function i(e,t,n){return function(){var i,r,a=o(arguments),l=s(arguments);if(a>e.length){i=Array.prototype.slice.call(arguments,0,e.length);var c=Array.prototype.slice.call(arguments,i.length,a);for(r=0;r<c.length;r++)r<t.length&&(l[t[r]]=c[r]);i.push(l)}else if(a<e.length){for(i=Array.prototype.slice.call(arguments,0,a),r=a;r<e.length;r++){var h=e[r];i.push(l[h]),delete l[h]}i.push(l)}else i=arguments;return n.apply(this,i)}}function r(e){return e.__keywords=!0,e}function s(e){var t=e.length;if(t){var n=e[t-1];if(n&&n.hasOwnProperty("__keywords"))return n}return{}}function o(e){var t=e.length;if(0===t)return 0;var n=e[t-1];return n&&n.hasOwnProperty("__keywords")?t-1:t}function a(e){return"string"!=typeof e?e:(this.val=e,void(this.length=e.length))}function l(e,t){return e instanceof a?new a(t):t.toString()}function c(e){var t=typeof e;return"string"===t?new a(e):"function"!==t?e:function(){var t=e.apply(this,arguments);return"string"==typeof t?new a(t):t}}function h(e,t){return e=void 0!==e&&null!==e?e:"",t&&"string"==typeof e&&(e=y.escape(e)),e}function u(e,t,n){if(null===e||void 0===e)throw new y.TemplateError("attempted to output null or undefined value",t+1,n+1);return e}function p(e,t){return e=e||{},"function"==typeof e[t]?function(){return e[t].apply(e,arguments)}:e[t]}function f(e,t,n){if(!e)throw new Error("Unable to call `"+t+"`, which is undefined or falsey");if("function"!=typeof e)throw new Error("Unable to call `"+t+"`, which is not a function");return e.apply(this,n)}function m(e,t,n){var i=t.lookup(n);return void 0!==i&&null!==i?i:e.lookup(n)}function d(e,t,n){return e.lineno?e:new y.TemplateError(e,t,n)}function v(e,t,n,i){if(y.isArray(e)){var r=e.length;y.asyncIter(e,function(e,i,s){switch(t){case 1:n(e,i,r,s);break;case 2:n(e[0],e[1],i,r,s);break;case 3:n(e[0],e[1],e[2],i,r,s);break;default:e.push(i,s),n.apply(this,e)}},i)}else y.asyncFor(e,function(e,t,i,r,s){n(e,t,i,r,s)},i)}function g(e,t,n,i){function r(e,t){l++,a[e]=t,l===s&&i(null,a.join(""))}var s,o,a,l=0;if(y.isArray(e))if(s=e.length,a=new Array(s),0===s)i(null,"");else for(o=0;o<e.length;o++){var c=e[o];switch(t){case 1:n(c,o,s,r);break;case 2:n(c[0],c[1],o,s,r);break;case 3:n(c[0],c[1],c[2],o,s,r);break;default:c.push(o,r),n.apply(this,c)}}else{var h=y.keys(e);if(s=h.length,a=new Array(s),0===s)i(null,"");else for(o=0;o<h.length;o++){var u=h[o];n(u,e[u],o,s,r)}}}var y=n(1),k=n(9),x=k.extend({init:function(e){this.variables={},this.parent=e,this.topLevel=!1},set:function(e,t,n){var i=e.split("."),r=this.variables,s=this;if(n){if(s=this.resolve(i[0]))return void s.set(e,t);s=this}for(var o=0;o<i.length-1;o++){var a=i[o];r[a]||(r[a]={}),r=r[a]}r[i[i.length-1]]=t},get:function(e){var t=this.variables[e];return void 0!==t&&null!==t?t:null},lookup:function(e){var t=this.parent,n=this.variables[e];return void 0!==n&&null!==n?n:t&&t.lookup(e)},resolve:function(e){var t=this.parent,n=this.variables[e];return void 0!==n&&null!==n?this:t&&t.resolve(e)},push:function(){return new x(this)},pop:function(){return this.parent}});a.prototype=Object.create(String.prototype,{length:{writable:!0,configurable:!0,value:0}}),a.prototype.valueOf=function(){return this.val},a.prototype.toString=function(){return this.val},e.exports={Frame:x,makeMacro:i,makeKeywordArgs:r,numArgs:o,suppressValue:h,ensureDefined:u,memberLookup:p,contextOrFrameLookup:m,callWrap:f,handleError:d,isArray:y.isArray,keys:y.keys,SafeString:a,copySafeness:l,markSafe:c,asyncEach:v,asyncAll:g}},function(e,t,n){"use strict";var i=n(15),r=n(9),s=n(1),o=r.extend({on:function(e,t){this.listeners=this.listeners||{},this.listeners[e]=this.listeners[e]||[],this.listeners[e].push(t)},emit:function(e){var t=Array.prototype.slice.call(arguments,1);this.listeners&&this.listeners[e]&&s.each(this.listeners[e],function(e){e.apply(null,t)})},resolve:function(e,t){return i.resolve(i.dirname(e),t)},isRelative:function(e){return 0===e.indexOf("./")||0===e.indexOf("../")}});e.exports=o},function(e,t,n){"use strict";var i=n(7),r=n(12),s=i.extend({init:function(e,t){this.baseURL=e||"",this.useCache=t.useCache,this.async=t.async},resolve:function(e,t){throw new Error("relative templates not support in the browser yet")},getSource:function(e,t){var n,i=this.useCache;return this.fetch(this.baseURL+"/"+e,function(r,s){if(r){if(!t)throw r;t(r)}else n={src:s,path:e,noCache:!i},t&&t(null,n)}),n},fetch:function(e,t){var n,i=!0;window.XMLHttpRequest?n=new XMLHttpRequest:window.ActiveXObject&&(n=new ActiveXObject("Microsoft.XMLHTTP")),n.onreadystatechange=function(){4===n.readyState&&i&&(i=!1,0===n.status||200===n.status?t(null,n.responseText):t(n.responseText))},e+=(-1===e.indexOf("?")?"?":"&")+"s="+(new Date).getTime(),n.open("GET",e,this.async),n.send()}});e.exports={WebLoader:s,PrecompiledLoader:r}},function(e,t,n){"use strict";function i(e,t,n){var r=function(){};r.prototype=e.prototype;var s=new r,o=/xyz/.test(function(){xyz})?/\bparent\b/:/.*/;n=n||{};for(var a in n){var l=n[a],c=s[a];"function"==typeof c&&"function"==typeof l&&o.test(l)?s[a]=function(e,t){return function(){var n=this.parent;this.parent=t;var i=e.apply(this,arguments);return this.parent=n,i}}(l,c):s[a]=l}s.typename=t;var h=function(){s.init&&s.init.apply(this,arguments)};return h.prototype=s,h.prototype.constructor=h,h.extend=function(e,t){return"object"==typeof e&&(t=e,e="anonymous"),i(h,e,t)},h}e.exports=i(Object,"Object",{})},function(e,t,n){"use strict";function i(e,t){return null===e||void 0===e||e===!1?t:e}var r=n(1),s=n(6),o=!1,a={abs:function(e){return Math.abs(e)},batch:function(e,t,n){var i,r=[],s=[];for(i=0;i<e.length;i++)i%t===0&&s.length&&(r.push(s),s=[]),s.push(e[i]);if(s.length){if(n)for(i=s.length;t>i;i++)s.push(n);r.push(s)}return r},capitalize:function(e){e=i(e,"");var t=e.toLowerCase();return s.copySafeness(e,t.charAt(0).toUpperCase()+t.slice(1))},center:function(e,t){if(e=i(e,""),t=t||80,e.length>=t)return e;var n=t-e.length,o=r.repeat(" ",n/2-n%2),a=r.repeat(" ",n/2);return s.copySafeness(e,o+e+a)},"default":function(e,t,n){return n===!0||n===!1||o||(o=!0,console.log('[nunjucks] Warning: the "default" filter was used without specifying the type of comparison. 2.0 changed the default behavior from boolean (val ? val : def) to strictly undefined, so you should make sure that doesn\'t break anything. Be explicit about this to make this warning go away, or wait until 2.1. See http://mozilla.github.io/nunjucks/templating.html#defaultvalue-default-boolean')),n?e?e:t:void 0!==e?e:t},dictsort:function(e,t,n){if(!r.isObject(e))throw new r.TemplateError("dictsort filter: val must be an object");var i=[];for(var s in e)i.push([s,e[s]]);var o;if(void 0===n||"key"===n)o=0;else{if("value"!==n)throw new r.TemplateError("dictsort filter: You can only sort by either key or value");o=1}return i.sort(function(e,n){var i=e[o],s=n[o];return t||(r.isString(i)&&(i=i.toUpperCase()),r.isString(s)&&(s=s.toUpperCase())),i>s?1:i===s?0:-1}),i},dump:function(e){return JSON.stringify(e)},escape:function(e){return"string"==typeof e||e instanceof s.SafeString?r.escape(e):e},safe:function(e){return s.markSafe(e)},first:function(e){return e[0]},groupby:function(e,t){return r.groupBy(e,t)},indent:function(e,t,n){if(e=i(e,""),""===e)return"";t=t||4;for(var o="",a=e.split("\n"),l=r.repeat(" ",t),c=0;c<a.length;c++)o+=0!==c||n?l+a[c]+"\n":a[c]+"\n";return s.copySafeness(e,o)},join:function(e,t,n){return t=t||"",n&&(e=r.map(e,function(e){return e[n]})),e.join(t)},last:function(e){return e[e.length-1]},length:function(e){var t=i(e,"");return void 0!==t?t.length:0},list:function(e){if(r.isString(e))return e.split("");if(r.isObject(e)){var t=[];if(Object.keys)t=Object.keys(e);else for(var n in e)t.push(n);return r.map(t,function(t){return{key:t,value:e[t]}})}if(r.isArray(e))return e;throw new r.TemplateError("list filter: type not iterable")},lower:function(e){return e=i(e,""),e.toLowerCase()},random:function(e){return e[Math.floor(Math.random()*e.length)]},rejectattr:function(e,t){return e.filter(function(e){return!e[t]})},selectattr:function(e,t){return e.filter(function(e){return!!e[t]})},replace:function(e,t,n,i){var r=e;if(t instanceof RegExp)return e.replace(t,n);"undefined"==typeof i&&(i=-1);var o="";if("number"==typeof t)t+="";else if("string"!=typeof t)return e;if("number"==typeof e&&(e+=""),"string"!=typeof e&&!(e instanceof s.SafeString))return e;if(""===t)return o=n+e.split("").join(n)+n,s.copySafeness(e,o);var a=e.indexOf(t);if(0===i||-1===a)return e;for(var l=0,c=0;a>-1&&(-1===i||i>c);)o+=e.substring(l,a)+n,l=a+t.length,c++,a=e.indexOf(t,l);return l<e.length&&(o+=e.substring(l)),s.copySafeness(r,o)},reverse:function(e){var t;return t=r.isString(e)?a.list(e):r.map(e,function(e){return e}),t.reverse(),r.isString(e)?s.copySafeness(e,t.join("")):t},round:function(e,t,n){t=t||0;var i,r=Math.pow(10,t);return i="ceil"===n?Math.ceil:"floor"===n?Math.floor:Math.round,i(e*r)/r},slice:function(e,t,n){for(var i=Math.floor(e.length/t),r=e.length%t,s=0,o=[],a=0;t>a;a++){var l=s+a*i;r>a&&s++;var c=s+(a+1)*i,h=e.slice(l,c);n&&a>=r&&h.push(n),o.push(h)}return o},sort:function(e,t,n,i){return e=r.map(e,function(e){return e}),e.sort(function(e,s){var o,a;return i?(o=e[i],a=s[i]):(o=e,a=s),!n&&r.isString(o)&&r.isString(a)&&(o=o.toLowerCase(),a=a.toLowerCase()),a>o?t?1:-1:o>a?t?-1:1:0}),e},string:function(e){return s.copySafeness(e,e)},title:function(e){e=i(e,"");for(var t=e.split(" "),n=0;n<t.length;n++)t[n]=a.capitalize(t[n]);return s.copySafeness(e,t.join(" "))},trim:function(e){return s.copySafeness(e,e.replace(/^\s*|\s*$/g,""))},truncate:function(e,t,n,r){var o=e;if(e=i(e,""),t=t||255,e.length<=t)return e;if(n)e=e.substring(0,t);else{var a=e.lastIndexOf(" ",t);-1===a&&(a=t),e=e.substring(0,a)}return e+=void 0!==r&&null!==r?r:"...",s.copySafeness(o,e)},upper:function(e){return e=i(e,""),e.toUpperCase()},urlencode:function(e){var t=encodeURIComponent;if(r.isString(e))return t(e);var n;if(r.isArray(e))n=e.map(function(e){return t(e[0])+"="+t(e[1])});else{n=[];for(var i in e)e.hasOwnProperty(i)&&n.push(t(i)+"="+t(e[i]))}return n.join("&")},urlize:function(e,t,n){isNaN(t)&&(t=1/0);var i=n===!0?' rel="nofollow"':"",r=/^(?:\(|<|&lt;)?(.*?)(?:\.|,|\)|\n|&gt;)?$/,s=/^[\w.!#$%&'*+\-\/=?\^`{|}~]+@[a-z\d\-]+(\.[a-z\d\-]+)+$/i,o=/^https?:\/\/.*$/,a=/^www\./,l=/\.(?:org|net|com)(?:\:|\/|$)/,c=e.split(/\s+/).filter(function(e){return e&&e.length}).map(function(e){var n=e.match(r),c=n&&n[1]||e;return o.test(c)?'<a href="'+c+'"'+i+">"+c.substr(0,t)+"</a>":a.test(c)?'<a href="http://'+c+'"'+i+">"+c.substr(0,t)+"</a>":s.test(c)?'<a href="mailto:'+c+'">'+c+"</a>":l.test(c)?'<a href="http://'+c+'"'+i+">"+c.substr(0,t)+"</a>":e});return c.join(" ")},wordcount:function(e){e=i(e,"");var t=e?e.match(/\w+/g):null;return t?t.length:null},"float":function(e,t){var n=parseFloat(e);return isNaN(n)?t:n},"int":function(e,t){var n=parseInt(e,10);return isNaN(n)?t:n}};a.d=a["default"],a.e=a.escape,e.exports=a},function(e,t,n){"use strict";function i(e){var t=-1;return{current:null,reset:function(){t=-1,this.current=null},next:function(){return t++,t>=e.length&&(t=0),this.current=e[t],this.current}}}function r(e){e=e||",";var t=!0;return function(){var n=t?"":e;return t=!1,n}}var s={range:function(e,t,n){t?n||(n=1):(t=e,e=0,n=1);for(var i=[],r=e;t>r;r+=n)i.push(r);return i},cycler:function(){return i(Array.prototype.slice.call(arguments))},joiner:function(e){return r(e)}};e.exports=s},function(e,t,n){"use strict";var i=n(7),r=i.extend({init:function(e){this.precompiled=e||{}},getSource:function(e){return this.precompiled[e]?{src:{type:"code",obj:this.precompiled[e]},path:e}:null}});e.exports=r},function(e,t,n){"use strict";function i(){return"hole_"+d++}function r(e,t){for(var n=null,i=0;i<e.length;i++){var r=t(e[i]);r!==e[i]&&(n||(n=e.slice()),n[i]=r)}return n||e}function s(e,t,n){if(!(e instanceof f.Node))return e;if(!n){var i=t(e);if(i&&i!==e)return i}if(e instanceof f.NodeList){var o=r(e.children,function(e){return s(e,t,n)});o!==e.children&&(e=new f[e.typename](e.lineno,e.colno,o))}else if(e instanceof f.CallExtension){var a=s(e.args,t,n),l=r(e.contentArgs,function(e){return s(e,t,n)});(a!==e.args||l!==e.contentArgs)&&(e=new f[e.typename](e.extName,e.prop,a,l))}else{var c=e.fields.map(function(t){return e[t]}),h=r(c,function(e){return s(e,t,n)});h!==c&&(e=new f[e.typename](e.lineno,e.colno),h.forEach(function(t,n){e[e.fields[n]]=t}))}return n?t(e)||e:e}function o(e,t){return s(e,t,!0)}function a(e,t,n){var r=[],s=o(n?e[n]:e,function(e){if(e instanceof f.Block)return e;if(e instanceof f.Filter&&-1!==m.indexOf(t,e.name.value)||e instanceof f.CallExtensionAsync){var n=new f.Symbol(e.lineno,e.colno,i());return r.push(new f.FilterAsync(e.lineno,e.colno,e.name,e.args,n)),n}});return n?e[n]=s:e=s,r.length?(r.push(e),new f.NodeList(e.lineno,e.colno,r)):e}function l(e,t){return o(e,function(e){return e instanceof f.Output?a(e,t):e instanceof f.Set?a(e,t,"value"):e instanceof f.For?a(e,t,"arr"):e instanceof f.If?a(e,t,"cond"):e instanceof f.CallExtension?a(e,t,"args"):void 0})}function c(e){return s(e,function(e){if(e instanceof f.Block){var t=!1,n=i();e.body=s(e.body,function(e){return e instanceof f.FunCall&&"super"===e.name.value?(t=!0,new f.Symbol(e.lineno,e.colno,n)):void 0}),t&&e.body.children.unshift(new f.Super(0,0,e.name,new f.Symbol(0,0,n)))}})}function h(e){return o(e,function(e){if(e instanceof f.If||e instanceof f.For){var t=!1;if(s(e,function(e){return e instanceof f.FilterAsync||e instanceof f.IfAsync||e instanceof f.AsyncEach||e instanceof f.AsyncAll||e instanceof f.CallExtensionAsync||e instanceof f.Include?(t=!0,e):void 0}),t){if(e instanceof f.If)return new f.IfAsync(e.lineno,e.colno,e.cond,e.body,e.else_);if(e instanceof f.For)return new f.AsyncEach(e.lineno,e.colno,e.arr,e.name,e.body,e.else_)}}})}function u(e,t){return h(c(l(e,t)))}function p(e,t){return u(e,t||[])}var f=n(14),m=n(1),d=0;e.exports={transform:p}},function(e,t,n){(function(t){"use strict";function i(e,t,n){e instanceof t&&n.push(e),e instanceof a&&e.findAll(t,n)}function r(e,n){function i(e,n,i){for(var r=e.split("\n"),s=0;s<r.length;s++){if(r[s]&&(i&&s>0||!i))for(var o=0;n>o;o++)t.stdout.write(" ");t.stdout.write(s===r.length-1?r[s]:r[s]+"\n")}}if(n=n||0,i(e.typename+": ",n),e instanceof c)i("\n"),s.each(e.children,function(e){r(e,n+2)});else if(e instanceof ie)i(e.extName+"."+e.prop),i("\n"),e.args&&r(e.args,n+2),e.contentArgs&&s.each(e.contentArgs,function(e){r(e,n+2)});else{var o=null,l=null;if(e.iterFields(function(e,t){e instanceof a?(o=o||{},o[t]=e):(l=l||{},l[t]=e)}),l?i(JSON.stringify(l,null,2)+"\n",null,!0):i("\n"),o)for(var h in o)r(o[h],n+2)}}var s=n(1),o=n(9),a=o.extend("Node",{init:function(e,t){this.lineno=e,this.colno=t;for(var n=this.fields,i=0,r=n.length;r>i;i++){var s=n[i],o=arguments[i+2];void 0===o&&(o=null),this[s]=o}},findAll:function(e,t){t=t||[];var n,r;if(this instanceof c){var s=this.children;for(n=0,r=s.length;r>n;n++)i(s[n],e,t)}else{var o=this.fields;for(n=0,r=o.length;r>n;n++)i(this[o[n]],e,t)}return t},iterFields:function(e){s.each(this.fields,function(t){e(this[t],t)},this)}}),l=a.extend("Value",{fields:["value"]}),c=a.extend("NodeList",{fields:["children"],init:function(e,t,n){this.parent(e,t,n||[])},addChild:function(e){this.children.push(e);
-
-}}),h=c.extend("Root"),u=l.extend("Literal"),p=l.extend("Symbol"),f=c.extend("Group"),m=c.extend("Array"),d=a.extend("Pair",{fields:["key","value"]}),v=c.extend("Dict"),g=a.extend("LookupVal",{fields:["target","val"]}),y=a.extend("If",{fields:["cond","body","else_"]}),k=y.extend("IfAsync"),x=a.extend("InlineIf",{fields:["cond","body","else_"]}),b=a.extend("For",{fields:["arr","name","body","else_"]}),E=b.extend("AsyncEach"),T=b.extend("AsyncAll"),w=a.extend("Macro",{fields:["name","args","body"]}),L=w.extend("Caller"),_=a.extend("Import",{fields:["template","target","withContext"]}),A=a.extend("FromImport",{fields:["template","names","withContext"],init:function(e,t,n,i,r){this.parent(e,t,n,i||new c,r)}}),O=a.extend("FunCall",{fields:["name","args"]}),S=O.extend("Filter"),N=S.extend("FilterAsync",{fields:["name","args","symbol"]}),C=v.extend("KeywordArgs"),B=a.extend("Block",{fields:["name","body"]}),F=a.extend("Super",{fields:["blockName","symbol"]}),R=a.extend("TemplateRef",{fields:["template"]}),K=R.extend("Extends"),I=R.extend("Include"),M=a.extend("Set",{fields:["targets","value"]}),P=c.extend("Output"),D=u.extend("TemplateData"),V=a.extend("UnaryOp",{fields:["target"]}),j=a.extend("BinOp",{fields:["left","right"]}),U=j.extend("In"),W=j.extend("Or"),G=j.extend("And"),Y=V.extend("Not"),H=j.extend("Add"),$=j.extend("Sub"),z=j.extend("Mul"),X=j.extend("Div"),q=j.extend("FloorDiv"),J=j.extend("Mod"),Q=j.extend("Pow"),Z=V.extend("Neg"),ee=V.extend("Pos"),te=a.extend("Compare",{fields:["expr","ops"]}),ne=a.extend("CompareOperand",{fields:["expr","type"]}),ie=a.extend("CallExtension",{fields:["extName","prop","args","contentArgs"],init:function(e,t,n,i){this.extName=e._name||e,this.prop=t,this.args=n||new c,this.contentArgs=i||[],this.autoescape=e.autoescape}}),re=ie.extend("CallExtensionAsync");e.exports={Node:a,Root:h,NodeList:c,Value:l,Literal:u,Symbol:p,Group:f,Array:m,Pair:d,Dict:v,Output:P,TemplateData:D,If:y,IfAsync:k,InlineIf:x,For:b,AsyncEach:E,AsyncAll:T,Macro:w,Caller:L,Import:_,FromImport:A,FunCall:O,Filter:S,FilterAsync:N,KeywordArgs:C,Block:B,Super:F,Extends:K,Include:I,Set:M,LookupVal:g,BinOp:j,In:U,Or:W,And:G,Not:Y,Add:H,Sub:$,Mul:z,Div:X,FloorDiv:q,Mod:J,Pow:Q,Neg:Z,Pos:ee,Compare:te,CompareOperand:ne,CallExtension:ie,CallExtensionAsync:re,printNodes:r}}).call(t,n(15))},function(e,t,n){},function(e,t,n){"use strict";function i(){if(l.length)throw l.shift()}function r(e){var t;t=a.length?a.pop():new s,t.task=e,o(t)}function s(){this.task=null}var o=n(17),a=[],l=[],c=o.makeRequestCallFromTimer(i);e.exports=r,s.prototype.call=function(){try{this.task.call()}catch(e){r.onerror?r.onerror(e):(l.push(e),c())}finally{this.task=null,a[a.length]=this}}},function(e,t,n){(function(t){"use strict";function n(e){a.length||(o(),l=!0),a[a.length]=e}function i(){for(;c<a.length;){var e=c;if(c+=1,a[e].call(),c>h){for(var t=0,n=a.length-c;n>t;t++)a[t]=a[t+c];a.length-=c,c=0}}a.length=0,c=0,l=!1}function r(e){var t=1,n=new u(e),i=document.createTextNode("");return n.observe(i,{characterData:!0}),function(){t=-t,i.data=t}}function s(e){return function(){function t(){clearTimeout(n),clearInterval(i),e()}var n=setTimeout(t,0),i=setInterval(t,50)}}e.exports=n;var o,a=[],l=!1,c=0,h=1024,u=t.MutationObserver||t.WebKitMutationObserver;o="function"==typeof u?r(i):s(i),n.requestFlush=o,n.makeRequestCallFromTimer=s}).call(t,function(){return this}())}]);
\ No newline at end of file
+var nunjucks=function(e){function t(i){if(n[i])return n[i].exports;var r=n[i]={exports:{},id:i,loaded:!1};return e[i].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";var i=n(1),r=n(2),s=n(3),o=n(4),a=n(5),l=n(6),c=n(7),h=n(8),u=n(14);e.exports={},e.exports.Environment=r.Environment,e.exports.Template=r.Template,e.exports.Loader=c,e.exports.FileSystemLoader=h.FileSystemLoader,e.exports.WebLoader=h.WebLoader,e.exports.compiler=s,e.exports.parser=o,e.exports.lexer=a,e.exports.runtime=l;var p;e.exports.configure=function(e,t){t=t||{},i.isObject(e)&&(t=e,e=null);var n;return n=h.FileSystemLoader?new h.FileSystemLoader(e,{watch:t.watch,noCache:t.noCache}):new h.WebLoader(e,{useCache:t.web&&t.web.useCache,async:t.web&&t.web.async}),p=new r.Environment(n,t),t&&t.express&&p.express(t.express),p},e.exports.compile=function(t,n,i,r){return p||e.exports.configure(),new e.exports.Template(t,n,i,r)},e.exports.render=function(t,n,i){return p||e.exports.configure(),p.render(t,n,i)},e.exports.renderString=function(t,n,i){return p||e.exports.configure(),p.renderString(t,n,i)},u&&(e.exports.precompile=u.precompile,e.exports.precompileString=u.precompileString)},function(e,t,n){"use strict";var i=Array.prototype,r=Object.prototype,s={"&":"&amp;",'"':"&quot;","'":"&#39;","<":"&lt;",">":"&gt;"},o=/[&"'<>]/g,a=function(e){return s[e]},t=e.exports={};t.prettifyError=function(e,n,i){if(i.Update||(i=new t.TemplateError(i)),i.Update(e),!n){var r=i;i=new Error(r.message),i.name=r.name}return i},t.TemplateError=function(e,t,n){var i=this;return e instanceof Error?(i=e,e=e.name+": "+e.message):Error.captureStackTrace&&Error.captureStackTrace(i),i.name="Template render error",i.message=e,i.lineno=t,i.colno=n,i.firstUpdate=!0,i.Update=function(e){var t="("+(e||"unknown path")+")";return this.firstUpdate&&(this.lineno&&this.colno?t+=" [Line "+this.lineno+", Column "+this.colno+"]":this.lineno&&(t+=" [Line "+this.lineno+"]")),t+="\n ",this.firstUpdate&&(t+=" "),this.message=t+(this.message||""),this.firstUpdate=!1,this},i},t.TemplateError.prototype=Error.prototype,t.escape=function(e){return e.replace(o,a)},t.isFunction=function(e){return"[object Function]"===r.toString.call(e)},t.isArray=Array.isArray||function(e){return"[object Array]"===r.toString.call(e)},t.isString=function(e){return"[object String]"===r.toString.call(e)},t.isObject=function(e){return"[object Object]"===r.toString.call(e)},t.groupBy=function(e,n){for(var i={},r=t.isFunction(n)?n:function(e){return e[n]},s=0;s<e.length;s++){var o=e[s],a=r(o,s);(i[a]||(i[a]=[])).push(o)}return i},t.toArray=function(e){return Array.prototype.slice.call(e)},t.without=function(e){var n=[];if(!e)return n;for(var i=-1,r=e.length,s=t.toArray(arguments).slice(1);++i<r;)-1===t.indexOf(s,e[i])&&n.push(e[i]);return n},t.extend=function(e,t){for(var n in t)e[n]=t[n];return e},t.repeat=function(e,t){for(var n="",i=0;t>i;i++)n+=e;return n},t.each=function(e,t,n){if(null!=e)if(i.each&&e.each===i.each)e.forEach(t,n);else if(e.length===+e.length)for(var r=0,s=e.length;s>r;r++)t.call(n,e[r],r,e)},t.map=function(e,t){var n=[];if(null==e)return n;if(i.map&&e.map===i.map)return e.map(t);for(var r=0;r<e.length;r++)n[n.length]=t(e[r],r);return e.length===+e.length&&(n.length=e.length),n},t.asyncIter=function(e,t,n){function i(){r++,r<e.length?t(e[r],r,i,n):n()}var r=-1;i()},t.asyncFor=function(e,n,i){function r(){a++;var t=s[a];o>a?n(t,e[t],a,o,r):i()}var s=t.keys(e),o=s.length,a=-1;r()},t.indexOf=Array.prototype.indexOf?function(e,t,n){return Array.prototype.indexOf.call(e,t,n)}:function(e,t,n){var i=this.length>>>0;for(n=+n||0,Math.abs(n)===1/0&&(n=0),0>n&&(n+=i,0>n&&(n=0));i>n;n++)if(e[n]===t)return n;return-1},Array.prototype.map||(Array.prototype.map=function(){throw new Error("map is unimplemented for this js engine")}),t.keys=function(e){if(Object.prototype.keys)return e.keys();var t=[];for(var n in e)e.hasOwnProperty(n)&&t.push(n);return t}},function(e,t,n){"use strict";function i(e,t,n){o(function(){e(t,n)})}var r,s=n(14),o=n(15),a=n(1),l=n(9),c=n(3),h=n(10),u=n(8),p=n(6),f=n(11),m=p.Frame,d=l.extend({init:function(e,t){t=this.opts=t||{},this.opts.dev=!!t.dev,this.opts.autoescape=!!t.autoescape,this.opts.throwOnUndefined=!!t.throwOnUndefined,this.opts.trimBlocks=!!t.trimBlocks,this.opts.lstripBlocks=!!t.lstripBlocks,e?this.loaders=a.isArray(e)?e:[e]:u.FileSystemLoader?this.loaders=[new u.FileSystemLoader("views")]:this.loaders=[new u.WebLoader("/views")],this.initCache(),this.filters={},this.asyncFilters=[],this.extensions={},this.extensionsList=[];for(var n in h)this.addFilter(n,h[n])},initCache:function(){a.each(this.loaders,function(e){e.cache={},"function"==typeof e.on&&e.on("update",function(t){e.cache[t]=null})})},addExtension:function(e,t){t._name=e,this.extensions[e]=t,this.extensionsList.push(t)},getExtension:function(e){return this.extensions[e]},addGlobal:function(e,t){f[e]=t},addFilter:function(e,t,n){var i=t;n&&this.asyncFilters.push(e),this.filters[e]=i},getFilter:function(e){if(!this.filters[e])throw new Error("filter not found: "+e);return this.filters[e]},resolveTemplate:function(e,t,n){var i=e.isRelative&&t?e.isRelative(n):!1;return i&&e.resolve?e.resolve(t,n):n},getTemplate:function(e,t,n,i){var s=this,o=null;if(e&&e.raw&&(e=e.raw),a.isFunction(n)&&(i=n,n=null,t=t||!1),a.isFunction(t)&&(i=t,t=!1),"string"!=typeof e)throw new Error("template names must be a string: "+e);for(var l=0;l<this.loaders.length;l++){var c=this.resolveTemplate(this.loaders[l],n,e);if(o=this.loaders[l].cache[c])break}if(!o){var h,u=this;return a.asyncIter(this.loaders,function(t,i,r,o){function a(e){e?(e.loader=t,o(e)):r()}e=s.resolveTemplate(t,n,e),t.async?t.getSource(e,function(e,t){if(e)throw e;a(t)}):a(t.getSource(e))},function(n){if(n){var s=new r(n.src,u,n.path,t);n.noCache||(n.loader.cache[e]=s),i?i(null,s):h=s}else{var o=new Error("template not found: "+e);if(!i)throw o;i(o)}}),h}return t&&o.compile(),i?void i(null,o):o},express:function(e){function t(e,t){if(this.name=e,this.path=e,this.defaultEngine=t.defaultEngine,this.ext=s.extname(e),!this.ext&&!this.defaultEngine)throw new Error("No default engine was specified and no extension was provided.");this.ext||(this.name+=this.ext=("."!==this.defaultEngine[0]?".":"")+this.defaultEngine)}var n=this;t.prototype.render=function(e,t){n.render(this.name,e,t)},e.set("view",t)},render:function(e,t,n){a.isFunction(t)&&(n=t,t=null);var r=null;return this.getTemplate(e,function(e,s){if(e&&n)i(n,e);else{if(e)throw e;r=s.render(t,n)}}),r},renderString:function(e,t,n,i){a.isFunction(n)&&(i=n,n={}),n=n||{};var s=new r(e,this,n.path);return s.render(t,i)}}),v=l.extend({init:function(e,t){this.ctx={};for(var n in e)e.hasOwnProperty(n)&&(this.ctx[n]=e[n]);this.blocks={},this.exported=[];for(var i in t)this.addBlock(i,t[i])},lookup:function(e){return e in f&&!(e in this.ctx)?f[e]:this.ctx[e]},setVariable:function(e,t){this.ctx[e]=t},getVariables:function(){return this.ctx},addBlock:function(e,t){this.blocks[e]=this.blocks[e]||[],this.blocks[e].push(t)},getBlock:function(e){if(!this.blocks[e])throw new Error('unknown block "'+e+'"');return this.blocks[e][0]},getSuper:function(e,t,n,i,r,s){var o=a.indexOf(this.blocks[t]||[],n),l=this.blocks[t][o+1],c=this;if(-1===o||!l)throw new Error('no super block available for "'+t+'"');l(e,c,i,r,s)},addExport:function(e){this.exported.push(e)},getExported:function(){for(var e={},t=0;t<this.exported.length;t++){var n=this.exported[t];e[n]=this.ctx[n]}return e}});r=l.extend({init:function(e,t,n,i){if(this.env=t||new d,a.isObject(e))switch(e.type){case"code":this.tmplProps=e.obj;break;case"string":this.tmplStr=e.obj}else{if(!a.isString(e))throw new Error("src must be a string or an object describing the source");this.tmplStr=e}if(this.path=n,i){var r=this;try{r._compile()}catch(s){throw a.prettifyError(this.path,this.env.dev,s)}}else this.compiled=!1},render:function(e,t,n){"function"==typeof e?(n=e,e={}):"function"==typeof t&&(n=t,t=null);var r=!0;t&&(r=!1);var s=this;try{s.compile()}catch(o){var l=a.prettifyError(this.path,this.env.dev,o);if(n)return i(n,l);throw l}var c=new v(e||{},s.blocks),h=t?t.push():new m;h.topLevel=!0;var u=null;return s.rootRenderFunc(s.env,c,h||new m,p,function(e,t){if(e&&(e=a.prettifyError(s.path,s.env.dev,e)),n)r?i(n,e,t):n(e,t);else{if(e)throw e;u=t}}),u},getExported:function(e,t,n){"function"==typeof e&&(n=e,e={}),"function"==typeof t&&(n=t,t=null);try{this.compile()}catch(i){if(n)return n(i);throw i}var r=t?t.push():new m;r.topLevel=!0;var s=new v(e||{},this.blocks);this.rootRenderFunc(this.env,s,r,p,function(){n(null,s.getExported())})},compile:function(){this.compiled||this._compile()},_compile:function(){var e;if(this.tmplProps)e=this.tmplProps;else{var t=c.compile(this.tmplStr,this.env.asyncFilters,this.env.extensionsList,this.env.opts.throwOnUndefined,this.path,this.env.opts),n=new Function(t);e=n()}this.blocks=this._getBlocks(e),this.rootRenderFunc=e.root,this.compiled=!0},_getBlocks:function(e){var t={};for(var n in e)"b_"===n.slice(0,2)&&(t[n.slice(2)]=e[n]);return t}}),e.exports={Environment:d,Template:r}},function(e,t,n){"use strict";function i(e){return function(t,n){this.compile(t.left,n),this.emit(e),this.compile(t.right,n)}}var r=n(1),s=n(4),o=n(12),a=n(13),l=n(9),c=n(6).Frame,h={"==":"==","!=":"!=","<":"<",">":">","<=":"<=",">=":">="},u=l.extend({init:function(e,t){this.templateName=e,this.codebuf=[],this.lastId=0,this.buffer=null,this.bufferStack=[],this.isChild=!1,this.scopeClosers="",this.throwOnUndefined=t},fail:function(e,t,n){throw void 0!==t&&(t+=1),void 0!==n&&(n+=1),new r.TemplateError(e,t,n)},pushBufferId:function(e){this.bufferStack.push(this.buffer),this.buffer=e,this.emit("var "+this.buffer+' = "";')},popBufferId:function(){this.buffer=this.bufferStack.pop()},emit:function(e){this.codebuf.push(e)},emitLine:function(e){this.emit(e+"\n")},emitLines:function(){r.each(r.toArray(arguments),function(e){this.emitLine(e)},this)},emitFuncBegin:function(e){this.buffer="output",this.scopeClosers="",this.emitLine("function "+e+"(env, context, frame, runtime, cb) {"),this.emitLine("var lineno = null;"),this.emitLine("var colno = null;"),this.emitLine("var "+this.buffer+' = "";'),this.emitLine("try {")},emitFuncEnd:function(e){e||this.emitLine("cb(null, "+this.buffer+");"),this.closeScopeLevels(),this.emitLine("} catch (e) {"),this.emitLine("  cb(runtime.handleError(e, lineno, colno));"),this.emitLine("}"),this.emitLine("}"),this.buffer=null},addScopeLevel:function(){this.scopeClosers+="})"},closeScopeLevels:function(){this.emitLine(this.scopeClosers+";"),this.scopeClosers=""},withScopedSyntax:function(e){var t=this.scopeClosers;this.scopeClosers="",e.call(this),this.closeScopeLevels(),this.scopeClosers=t},makeCallback:function(e){var t=this.tmpid();return"function("+t+(e?","+e:"")+") {\nif("+t+") { cb("+t+"); return; }"},tmpid:function(){return this.lastId++,"t_"+this.lastId},_templateName:function(){return null==this.templateName?"undefined":JSON.stringify(this.templateName)},_compileChildren:function(e,t){for(var n=e.children,i=0,r=n.length;r>i;i++)this.compile(n[i],t)},_compileAggregate:function(e,t,n,i){n&&this.emit(n);for(var r=0;r<e.children.length;r++)r>0&&this.emit(","),this.compile(e.children[r],t);i&&this.emit(i)},_compileExpression:function(e,t){this.assertType(e,a.Literal,a.Symbol,a.Group,a.Array,a.Dict,a.FunCall,a.Caller,a.Filter,a.LookupVal,a.Compare,a.InlineIf,a.In,a.And,a.Or,a.Not,a.Add,a.Sub,a.Mul,a.Div,a.FloorDiv,a.Mod,a.Pow,a.Neg,a.Pos,a.Compare,a.NodeList),this.compile(e,t)},assertType:function(e){for(var t=r.toArray(arguments).slice(1),n=!1,i=0;i<t.length;i++)e instanceof t[i]&&(n=!0);n||this.fail("assertType: invalid type: "+e.typename,e.lineno,e.colno)},compileCallExtension:function(e,t,n){var i=e.args,s=e.contentArgs,o="boolean"==typeof e.autoescape?e.autoescape:!0;if(n||this.emit(this.buffer+" += runtime.suppressValue("),this.emit('env.getExtension("'+e.extName+'")["'+e.prop+'"]('),this.emit("context"),(i||s)&&this.emit(","),i&&(i instanceof a.NodeList||this.fail("compileCallExtension: arguments must be a NodeList, use `parser.parseSignature`"),r.each(i.children,function(e,n){this._compileExpression(e,t),(n!==i.children.length-1||s.length)&&this.emit(",")},this)),s.length&&r.each(s,function(e,n){if(n>0&&this.emit(","),e){var i=this.tmpid();this.emitLine("function(cb) {"),this.emitLine("if(!cb) { cb = function(err) { if(err) { throw err; }}}"),this.pushBufferId(i),this.withScopedSyntax(function(){this.compile(e,t),this.emitLine("cb(null, "+i+");")}),this.popBufferId(),this.emitLine("return "+i+";"),this.emitLine("}")}else this.emit("null")},this),n){var l=this.tmpid();this.emitLine(", "+this.makeCallback(l)),this.emitLine(this.buffer+" += runtime.suppressValue("+l+", "+o+" && env.opts.autoescape);"),this.addScopeLevel()}else this.emit(")"),this.emit(", "+o+" && env.opts.autoescape);\n")},compileCallExtensionAsync:function(e,t){this.compileCallExtension(e,t,!0)},compileNodeList:function(e,t){this._compileChildren(e,t)},compileLiteral:function(e){if("string"==typeof e.value){var t=e.value.replace(/\\/g,"\\\\");t=t.replace(/"/g,'\\"'),t=t.replace(/\n/g,"\\n"),t=t.replace(/\r/g,"\\r"),t=t.replace(/\t/g,"\\t"),this.emit('"'+t+'"')}else this.emit(e.value.toString())},compileSymbol:function(e,t){var n,i=e.value;this.emit((n=t.lookup(i))?n:'runtime.contextOrFrameLookup(context, frame, "'+i+'")')},compileGroup:function(e,t){this._compileAggregate(e,t,"(",")")},compileArray:function(e,t){this._compileAggregate(e,t,"[","]")},compileDict:function(e,t){this._compileAggregate(e,t,"{","}")},compilePair:function(e,t){var n=e.key,i=e.value;n instanceof a.Symbol?n=new a.Literal(n.lineno,n.colno,n.value):n instanceof a.Literal&&"string"==typeof n.value||this.fail("compilePair: Dict keys must be strings or names",n.lineno,n.colno),this.compile(n,t),this.emit(": "),this._compileExpression(i,t)},compileInlineIf:function(e,t){this.emit("("),this.compile(e.cond,t),this.emit("?"),this.compile(e.body,t),this.emit(":"),null!==e.else_?this.compile(e.else_,t):this.emit('""'),this.emit(")")},compileIn:function(e,t){this.emit("("),this.compile(e.right,t),this.emit(".indexOf("),this.compile(e.left,t),this.emit(") !== -1)")},compileOr:i(" || "),compileAnd:i(" && "),compileAdd:i(" + "),compileSub:i(" - "),compileMul:i(" * "),compileDiv:i(" / "),compileMod:i(" % "),compileNot:function(e,t){this.emit("!"),this.compile(e.target,t)},compileFloorDiv:function(e,t){this.emit("Math.floor("),this.compile(e.left,t),this.emit(" / "),this.compile(e.right,t),this.emit(")")},compilePow:function(e,t){this.emit("Math.pow("),this.compile(e.left,t),this.emit(", "),this.compile(e.right,t),this.emit(")")},compileNeg:function(e,t){this.emit("-"),this.compile(e.target,t)},compilePos:function(e,t){this.emit("+"),this.compile(e.target,t)},compileCompare:function(e,t){this.compile(e.expr,t);for(var n=0;n<e.ops.length;n++){var i=e.ops[n];this.emit(" "+h[i.type]+" "),this.compile(i.expr,t)}},compileLookupVal:function(e,t){this.emit("runtime.memberLookup(("),this._compileExpression(e.target,t),this.emit("),"),this._compileExpression(e.val,t),this.emit(")")},_getNodeName:function(e){switch(e.typename){case"Symbol":return e.value;case"FunCall":return"the return value of ("+this._getNodeName(e.name)+")";case"LookupVal":return this._getNodeName(e.target)+'["'+this._getNodeName(e.val)+'"]';case"Literal":return e.value.toString().substr(0,10);default:return"--expression--"}},compileFunCall:function(e,t){this.emit("(lineno = "+e.lineno+", colno = "+e.colno+", "),this.emit("runtime.callWrap("),this._compileExpression(e.name,t),this.emit(', "'+this._getNodeName(e.name).replace(/"/g,'\\"')+'", '),this._compileAggregate(e.args,t,"[","])"),this.emit(")")},compileFilter:function(e,t){var n=e.name;this.assertType(n,a.Symbol),this.emit('env.getFilter("'+n.value+'").call(context, '),this._compileAggregate(e.args,t),this.emit(")")},compileFilterAsync:function(e,t){var n=e.name;this.assertType(n,a.Symbol);var i=e.symbol.value;t.set(i,i),this.emit('env.getFilter("'+n.value+'").call(context, '),this._compileAggregate(e.args,t),this.emitLine(", "+this.makeCallback(i)),this.addScopeLevel()},compileKeywordArgs:function(e,t){var n=[];r.each(e.children,function(e){n.push(e.key.value)}),this.emit("runtime.makeKeywordArgs("),this.compileDict(e,t),this.emit(")")},compileSet:function(e,t){var n=[];r.each(e.targets,function(e){var i=e.value,r=t.lookup(i);(null===r||void 0===r)&&(r=this.tmpid(),this.emitLine("var "+r+";")),n.push(r)},this),this.emit(n.join(" = ")+" = "),this._compileExpression(e.value,t),this.emitLine(";"),r.each(e.targets,function(e,t){var i=n[t],r=e.value;this.emitLine('frame.set("'+r+'", '+i+", true);"),this.emitLine("if(frame.topLevel) {"),this.emitLine('context.setVariable("'+r+'", '+i+");"),this.emitLine("}"),"_"!==r.charAt(0)&&(this.emitLine("if(frame.topLevel) {"),this.emitLine('context.addExport("'+r+'", '+i+");"),this.emitLine("}"))},this)},compileIf:function(e,t,n){this.emit("if("),this._compileExpression(e.cond,t),this.emitLine(") {"),this.withScopedSyntax(function(){this.compile(e.body,t),n&&this.emit("cb()")}),e.else_?(this.emitLine("}\nelse {"),this.withScopedSyntax(function(){this.compile(e.else_,t),n&&this.emit("cb()")})):n&&(this.emitLine("}\nelse {"),this.emit("cb()")),this.emitLine("}")},compileIfAsync:function(e,t){this.emit("(function(cb) {"),this.compileIf(e,t,!0),this.emit("})(function() {"),this.addScopeLevel()},emitLoopBindings:function(e,t,n,i){var r={index:n+" + 1",index0:n,revindex:i+" - "+n,revindex0:i+" - "+n+" - 1",first:n+" === 0",last:n+" === "+i+" - 1",length:i};for(var s in r)this.emitLine('frame.set("loop.'+s+'", '+r[s]+");")},compileFor:function(e,t){var n,i=this.tmpid(),r=this.tmpid(),s=this.tmpid();if(t=t.push(),this.emitLine("frame = frame.push();"),this.emit("var "+s+" = "),this._compileExpression(e.arr,t),this.emitLine(";"),this.emit("if("+s+") {"),e.name instanceof a.Array){this.emitLine("var "+i+";"),this.emitLine("if(runtime.isArray("+s+")) {"),this.emitLine("var "+r+" = "+s+".length;"),this.emitLine("for("+i+"=0; "+i+" < "+s+".length; "+i+"++) {");for(var o=0;o<e.name.children.length;o++){var l=this.tmpid();this.emitLine("var "+l+" = "+s+"["+i+"]["+o+"]"),this.emitLine('frame.set("'+e.name.children[o].value+'", '+s+"["+i+"]["+o+"]);"),t.set(e.name.children[o].value,l)}this.emitLoopBindings(e,s,i,r),this.withScopedSyntax(function(){this.compile(e.body,t)}),this.emitLine("}"),this.emitLine("} else {");var c=e.name.children[0],h=e.name.children[1],u=this.tmpid();n=this.tmpid(),t.set(c.value,u),t.set(h.value,n),this.emitLine(i+" = -1;"),this.emitLine("var "+r+" = runtime.keys("+s+").length;"),this.emitLine("for(var "+u+" in "+s+") {"),this.emitLine(i+"++;"),this.emitLine("var "+n+" = "+s+"["+u+"];"),this.emitLine('frame.set("'+c.value+'", '+u+");"),this.emitLine('frame.set("'+h.value+'", '+n+");"),this.emitLoopBindings(e,s,i,r),this.withScopedSyntax(function(){this.compile(e.body,t)}),this.emitLine("}"),this.emitLine("}")}else n=this.tmpid(),t.set(e.name.value,n),this.emitLine("var "+r+" = "+s+".length;"),this.emitLine("for(var "+i+"=0; "+i+" < "+s+".length; "+i+"++) {"),this.emitLine("var "+n+" = "+s+"["+i+"];"),this.emitLine('frame.set("'+e.name.value+'", '+n+");"),this.emitLoopBindings(e,s,i,r),this.withScopedSyntax(function(){this.compile(e.body,t)}),this.emitLine("}");this.emitLine("}"),e.else_&&(this.emitLine("if (!"+r+") {"),this.compile(e.else_,t),this.emitLine("}")),this.emitLine("frame = frame.pop();")},_compileAsyncLoop:function(e,t,n){var i=this.tmpid(),s=this.tmpid(),o=this.tmpid(),l=n?"asyncAll":"asyncEach";if(t=t.push(),this.emitLine("frame = frame.push();"),this.emit("var "+o+" = "),this._compileExpression(e.arr,t),this.emitLine(";"),e.name instanceof a.Array)this.emit("runtime."+l+"("+o+", "+e.name.children.length+", function("),r.each(e.name.children,function(e){this.emit(e.value+",")},this),this.emit(i+","+s+",next) {"),r.each(e.name.children,function(e){var n=e.value;t.set(n,n),this.emitLine('frame.set("'+n+'", '+n+");")},this);else{var c=e.name.value;this.emitLine("runtime."+l+"("+o+", 1, function("+c+", "+i+", "+s+",next) {"),this.emitLine('frame.set("'+c+'", '+c+");"),t.set(c,c)}this.emitLoopBindings(e,o,i,s),this.withScopedSyntax(function(){var r;n&&(r=this.tmpid(),this.pushBufferId(r)),this.compile(e.body,t),this.emitLine("next("+i+(r?","+r:"")+");"),n&&this.popBufferId()});var h=this.tmpid();this.emitLine("}, "+this.makeCallback(h)),this.addScopeLevel(),n&&this.emitLine(this.buffer+" += "+h+";"),e.else_&&(this.emitLine("if (!"+o+".length) {"),this.compile(e.else_,t),this.emitLine("}")),this.emitLine("frame = frame.pop();")},compileAsyncEach:function(e,t){this._compileAsyncLoop(e,t)},compileAsyncAll:function(e,t){this._compileAsyncLoop(e,t,!0)},_compileMacro:function(e,t){var n=[],i=null,s="macro_"+this.tmpid();r.each(e.args.children,function(t,r){r===e.args.children.length-1&&t instanceof a.Dict?i=t:(this.assertType(t,a.Symbol),n.push(t))},this);var o=r.map(n,function(e){return"l_"+e.value});o.push("kwargs");var l=r.map(n,function(e){return'"'+e.value+'"'}),c=r.map(i&&i.children||[],function(e){return'"'+e.key.value+'"'});t=t.push(),this.emitLines("var "+s+" = runtime.makeMacro(","["+l.join(", ")+"], ","["+c.join(", ")+"], ","function ("+o.join(", ")+") {","frame = frame.push();","kwargs = kwargs || {};",'if (kwargs.hasOwnProperty("caller")) {','frame.set("caller", kwargs.caller); }'),r.each(n,function(e){this.emitLine('frame.set("'+e.value+'", l_'+e.value+");"),t.set(e.value,"l_"+e.value)},this),i&&r.each(i.children,function(e){var n=e.key.value;this.emit('frame.set("'+n+'", kwargs.hasOwnProperty("'+n+'") ? kwargs["'+n+'"] : '),this._compileExpression(e.value,t),this.emitLine(");")},this);var h=this.tmpid();return this.pushBufferId(h),this.withScopedSyntax(function(){this.compile(e.body,t)}),t=t.pop(),this.emitLine("frame = frame.pop();"),this.emitLine("return new runtime.SafeString("+h+");"),this.emitLine("});"),this.popBufferId(),s},compileMacro:function(e,t){var n=this._compileMacro(e,t),i=e.name.value;t.set(i,n),t.parent?this.emitLine('frame.set("'+i+'", '+n+");"):("_"!==e.name.value.charAt(0)&&this.emitLine('context.addExport("'+i+'");'),this.emitLine('context.setVariable("'+i+'", '+n+");"))},compileCaller:function(e,t){this.emit("(function (){");var n=this._compileMacro(e,t);this.emit("return "+n+";})()")},compileImport:function(e,t){var n=this.tmpid(),i=e.target.value;this.emit("env.getTemplate("),this._compileExpression(e.template,t),this.emitLine(", false, "+this._templateName()+", "+this.makeCallback(n)),this.addScopeLevel(),this.emitLine(n+".getExported("+(e.withContext?"context.getVariables(), frame, ":"")+this.makeCallback(n)),this.addScopeLevel(),t.set(i,n),this.emitLine(t.parent?'frame.set("'+i+'", '+n+");":'context.setVariable("'+i+'", '+n+");")},compileFromImport:function(e,t){var n=this.tmpid();this.emit("env.getTemplate("),this._compileExpression(e.template,t),this.emitLine(", false, "+this._templateName()+", "+this.makeCallback(n)),this.addScopeLevel(),this.emitLine(n+".getExported("+(e.withContext?"context.getVariables(), frame, ":"")+this.makeCallback(n)),this.addScopeLevel(),r.each(e.names.children,function(e){var i,r,s=this.tmpid();e instanceof a.Pair?(i=e.key.value,r=e.value.value):(i=e.value,r=i),this.emitLine("if("+n+'.hasOwnProperty("'+i+'")) {'),this.emitLine("var "+s+" = "+n+"."+i+";"),this.emitLine("} else {"),this.emitLine("cb(new Error(\"cannot import '"+i+"'\")); return;"),this.emitLine("}"),t.set(r,s),this.emitLine(t.parent?'frame.set("'+r+'", '+s+");":'context.setVariable("'+r+'", '+s+");")},this)},compileBlock:function(e){if(!this.isChild){var t=this.tmpid();this.emitLine('context.getBlock("'+e.name.value+'")(env, context, frame, runtime, '+this.makeCallback(t)),this.emitLine(this.buffer+" += "+t+";"),this.addScopeLevel()}},compileSuper:function(e,t){var n=e.blockName.value,i=e.symbol.value;this.emitLine('context.getSuper(env, "'+n+'", b_'+n+", frame, runtime, "+this.makeCallback(i)),this.emitLine(i+" = runtime.markSafe("+i+");"),this.addScopeLevel(),t.set(i,i)},compileExtends:function(e,t){this.isChild&&this.fail("compileExtends: cannot extend multiple times",e.template.lineno,e.template.colno);var n=this.tmpid();this.emit("env.getTemplate("),this._compileExpression(e.template,t),this.emitLine(", true, "+this._templateName()+", "+this.makeCallback("parentTemplate")),this.emitLine("for(var "+n+" in parentTemplate.blocks) {"),this.emitLine("context.addBlock("+n+", parentTemplate.blocks["+n+"]);"),this.emitLine("}"),this.addScopeLevel(),this.isChild=!0},compileInclude:function(e,t){var n=this.tmpid(),i=this.tmpid();this.emit("env.getTemplate("),this._compileExpression(e.template,t),this.emitLine(", false, "+this._templateName()+", "+this.makeCallback(n)),this.addScopeLevel(),this.emitLine(n+".render(context.getVariables(), frame, "+this.makeCallback(i)),this.emitLine(this.buffer+" += "+i),this.addScopeLevel()},compileTemplateData:function(e,t){this.compileLiteral(e,t)},compileOutput:function(e,t){for(var n=e.children,i=0,r=n.length;r>i;i++)n[i]instanceof a.TemplateData?n[i].value&&(this.emit(this.buffer+" += "),this.compileLiteral(n[i],t),this.emitLine(";")):(this.emit(this.buffer+" += runtime.suppressValue("),this.throwOnUndefined&&this.emit("runtime.ensureDefined("),this.compile(n[i],t),this.throwOnUndefined&&this.emit(","+e.lineno+","+e.colno+")"),this.emit(", env.opts.autoescape);\n"))},compileRoot:function(e,t){t&&this.fail("compileRoot: root node can't have frame"),t=new c,this.emitFuncBegin("root"),this._compileChildren(e,t),this.isChild&&this.emitLine("parentTemplate.rootRenderFunc(env, context, frame, runtime, cb);"),this.emitFuncEnd(this.isChild),this.isChild=!1;var n,i,r,s=e.findAll(a.Block);for(n=0;n<s.length;n++){r=s[n],i=r.name.value,this.emitFuncBegin("b_"+i);var o=new c;this.compile(r.body,o),this.emitFuncEnd()}for(this.emitLine("return {"),n=0;n<s.length;n++)r=s[n],i="b_"+r.name.value,this.emitLine(i+": "+i+",");this.emitLine("root: root\n};")},compile:function(e,t){var n=this["compile"+e.typename];n?n.call(this,e,t):this.fail("compile: Cannot compile node: "+e.typename,e.lineno,e.colno)},getCode:function(){return this.codebuf.join("")}});e.exports={compile:function(e,t,n,i,r,a){var l=new u(r,i);if(n&&n.length)for(var c=0;c<n.length;c++)"preprocess"in n[c]&&(e=n[c].preprocess(e,r));return l.compile(o.transform(s.parse(e,n,a),t,r)),l.getCode()},Compiler:u}},function(e,t,n){"use strict";var i=n(5),r=n(13),s=n(9),o=n(1),a=s.extend({init:function(e){this.tokens=e,this.peeked=null,this.breakOnBlocks=null,this.dropLeadingWhitespace=!1,this.extensions=[]},nextToken:function(e){var t;if(this.peeked){if(e||this.peeked.type!==i.TOKEN_WHITESPACE)return t=this.peeked,this.peeked=null,t;this.peeked=null}if(t=this.tokens.nextToken(),!e)for(;t&&t.type===i.TOKEN_WHITESPACE;)t=this.tokens.nextToken();return t},peekToken:function(){return this.peeked=this.peeked||this.nextToken(),this.peeked},pushToken:function(e){if(this.peeked)throw new Error("pushToken: can only push one token on between reads");this.peeked=e},fail:function(e,t,n){if((void 0===t||void 0===n)&&this.peekToken()){var i=this.peekToken();t=i.lineno,n=i.colno}throw void 0!==t&&(t+=1),void 0!==n&&(n+=1),new o.TemplateError(e,t,n)},skip:function(e){var t=this.nextToken();return t&&t.type===e?!0:(this.pushToken(t),!1)},expect:function(e){var t=this.nextToken();return t.type!==e&&this.fail("expected "+e+", got "+t.type,t.lineno,t.colno),t},skipValue:function(e,t){var n=this.nextToken();return n&&n.type===e&&n.value===t?!0:(this.pushToken(n),!1)},skipWhitespace:function(){return this.skip(i.TOKEN_WHITESPACE)},skipSymbol:function(e){return this.skipValue(i.TOKEN_SYMBOL,e)},advanceAfterBlockEnd:function(e){var t;e||(t=this.peekToken(),t||this.fail("unexpected end of file"),t.type!==i.TOKEN_SYMBOL&&this.fail("advanceAfterBlockEnd: expected symbol token or explicit name to be passed"),e=this.nextToken().value),t=this.nextToken(),t&&t.type===i.TOKEN_BLOCK_END?"-"===t.value.charAt(0)&&(this.dropLeadingWhitespace=!0):this.fail("expected block end in "+e+" statement")},advanceAfterVariableEnd:function(){this.skip(i.TOKEN_VARIABLE_END)||this.fail("expected variable end")},parseFor:function(){var e,t,n=this.peekToken();this.skipSymbol("for")?(e=new r.For(n.lineno,n.colno),t="endfor"):this.skipSymbol("asyncEach")?(e=new r.AsyncEach(n.lineno,n.colno),t="endeach"):this.skipSymbol("asyncAll")?(e=new r.AsyncAll(n.lineno,n.colno),t="endall"):this.fail("parseFor: expected for{Async}",n.lineno,n.colno),e.name=this.parsePrimary(),e.name instanceof r.Symbol||this.fail("parseFor: variable name expected for loop");var s=this.peekToken().type;if(s===i.TOKEN_COMMA){var o=e.name;for(e.name=new r.Array(o.lineno,o.colno),e.name.addChild(o);this.skip(i.TOKEN_COMMA);){var a=this.parsePrimary();e.name.addChild(a)}}return this.skipSymbol("in")||this.fail('parseFor: expected "in" keyword for loop',n.lineno,n.colno),e.arr=this.parseExpression(),this.advanceAfterBlockEnd(n.value),e.body=this.parseUntilBlocks(t,"else"),this.skipSymbol("else")&&(this.advanceAfterBlockEnd("else"),e.else_=this.parseUntilBlocks(t)),this.advanceAfterBlockEnd(),e},parseMacro:function(){var e=this.peekToken();this.skipSymbol("macro")||this.fail("expected macro");var t=this.parsePrimary(!0),n=this.parseSignature(),i=new r.Macro(e.lineno,e.colno,t,n);return this.advanceAfterBlockEnd(e.value),i.body=this.parseUntilBlocks("endmacro"),this.advanceAfterBlockEnd(),i},parseCall:function(){var e=this.peekToken();this.skipSymbol("call")||this.fail("expected call");var t=this.parseSignature(!0)||new r.NodeList,n=this.parsePrimary();this.advanceAfterBlockEnd(e.value);var i=this.parseUntilBlocks("endcall");this.advanceAfterBlockEnd();var s=new r.Symbol(e.lineno,e.colno,"caller"),o=new r.Caller(e.lineno,e.colno,s,t,i),a=n.args.children;a[a.length-1]instanceof r.KeywordArgs||a.push(new r.KeywordArgs);var l=a[a.length-1];return l.addChild(new r.Pair(e.lineno,e.colno,s,o)),new r.Output(e.lineno,e.colno,[n])},parseWithContext:function(){var e=this.peekToken(),t=null;return this.skipSymbol("with")?t=!0:this.skipSymbol("without")&&(t=!1),null!==t&&(this.skipSymbol("context")||this.fail("parseFrom: expected context after with/without",e.lineno,e.colno)),t},parseImport:function(){var e=this.peekToken();this.skipSymbol("import")||this.fail("parseImport: expected import",e.lineno,e.colno);var t=this.parseExpression();this.skipSymbol("as")||this.fail('parseImport: expected "as" keyword',e.lineno,e.colno);var n=this.parsePrimary(),i=this.parseWithContext(),s=new r.Import(e.lineno,e.colno,t,n,i);return this.advanceAfterBlockEnd(e.value),s},parseFrom:function(){var e=this.peekToken();this.skipSymbol("from")||this.fail("parseFrom: expected from");var t=this.parsePrimary();this.skipSymbol("import")||this.fail("parseFrom: expected import",e.lineno,e.colno);for(var n,s=new r.NodeList;;){var o=this.peekToken();if(o.type===i.TOKEN_BLOCK_END){s.children.length||this.fail("parseFrom: Expected at least one import name",e.lineno,e.colno),"-"===o.value.charAt(0)&&(this.dropLeadingWhitespace=!0),this.nextToken();break}s.children.length>0&&!this.skip(i.TOKEN_COMMA)&&this.fail("parseFrom: expected comma",e.lineno,e.colno);var a=this.parsePrimary();if("_"===a.value.charAt(0)&&this.fail("parseFrom: names starting with an underscore cannot be imported",a.lineno,a.colno),this.skipSymbol("as")){var l=this.parsePrimary();s.addChild(new r.Pair(a.lineno,a.colno,a,l))}else s.addChild(a);n=this.parseWithContext()}return new r.FromImport(e.lineno,e.colno,t,s,n)},parseBlock:function(){var e=this.peekToken();this.skipSymbol("block")||this.fail("parseBlock: expected block",e.lineno,e.colno);var t=new r.Block(e.lineno,e.colno);return t.name=this.parsePrimary(),t.name instanceof r.Symbol||this.fail("parseBlock: variable name expected",e.lineno,e.colno),this.advanceAfterBlockEnd(e.value),t.body=this.parseUntilBlocks("endblock"),
+this.peekToken()||this.fail("parseBlock: expected endblock, got end of file"),this.advanceAfterBlockEnd(),t},parseTemplateRef:function(e,t){var n=this.peekToken();this.skipSymbol(e)||this.fail("parseTemplateRef: expected "+e);var i=new t(n.lineno,n.colno);return i.template=this.parseExpression(),this.advanceAfterBlockEnd(n.value),i},parseExtends:function(){return this.parseTemplateRef("extends",r.Extends)},parseInclude:function(){return this.parseTemplateRef("include",r.Include)},parseIf:function(){var e,t=this.peekToken();this.skipSymbol("if")||this.skipSymbol("elif")?e=new r.If(t.lineno,t.colno):this.skipSymbol("ifAsync")?e=new r.IfAsync(t.lineno,t.colno):this.fail("parseIf: expected if or elif",t.lineno,t.colno),e.cond=this.parseExpression(),this.advanceAfterBlockEnd(t.value),e.body=this.parseUntilBlocks("elif","else","endif");var n=this.peekToken();switch(n&&n.value){case"elif":e.else_=this.parseIf();break;case"else":this.advanceAfterBlockEnd(),e.else_=this.parseUntilBlocks("endif"),this.advanceAfterBlockEnd();break;case"endif":e.else_=null,this.advanceAfterBlockEnd();break;default:this.fail("parseIf: expected endif, else, or endif, got end of file")}return e},parseSet:function(){var e=this.peekToken();this.skipSymbol("set")||this.fail("parseSet: expected set",e.lineno,e.colno);for(var t,n=new r.Set(e.lineno,e.colno,[]);(t=this.parsePrimary())&&(n.targets.push(t),this.skip(i.TOKEN_COMMA)););return this.skipValue(i.TOKEN_OPERATOR,"=")||this.fail("parseSet: expected = in set tag",e.lineno,e.colno),n.value=this.parseExpression(),this.advanceAfterBlockEnd(e.value),n},parseStatement:function(){var e,t=this.peekToken();if(t.type!==i.TOKEN_SYMBOL&&this.fail("tag name expected",t.lineno,t.colno),this.breakOnBlocks&&-1!==o.indexOf(this.breakOnBlocks,t.value))return null;switch(t.value){case"raw":return this.parseRaw();case"if":case"ifAsync":return this.parseIf();case"for":case"asyncEach":case"asyncAll":return this.parseFor();case"block":return this.parseBlock();case"extends":return this.parseExtends();case"include":return this.parseInclude();case"set":return this.parseSet();case"macro":return this.parseMacro();case"call":return this.parseCall();case"import":return this.parseImport();case"from":return this.parseFrom();default:if(this.extensions.length)for(var n=0;n<this.extensions.length;n++){var s=this.extensions[n];if(-1!==o.indexOf(s.tags||[],t.value))return s.parse(this,r,i)}this.fail("unknown block tag: "+t.value,t.lineno,t.colno)}return e},parseRaw:function(){this.advanceAfterBlockEnd();for(var e="",t=this.peekToken();;){var n=this.nextToken(!0);if(n||this.fail("expected endraw, got end of file"),n.type===i.TOKEN_BLOCK_START){var s=null,o=this.nextToken(!0);if(o.type===i.TOKEN_WHITESPACE&&(s=o,o=this.nextToken()),o.type===i.TOKEN_SYMBOL&&"endraw"===o.value){this.advanceAfterBlockEnd(o.value);break}e+=n.value,s&&(e+=s.value),e+=o.value}else e+=n.type===i.TOKEN_STRING?'"'+n.value+'"':n.value}var a=new r.Output(t.lineno,t.colno,[new r.TemplateData(t.lineno,t.colno,e)]);return a},parsePostfix:function(e){for(var t,n=this.peekToken();n;){if(n.type===i.TOKEN_LEFT_PAREN)e=new r.FunCall(n.lineno,n.colno,e,this.parseSignature());else if(n.type===i.TOKEN_LEFT_BRACKET)t=this.parseAggregate(),t.children.length>1&&this.fail("invalid index"),e=new r.LookupVal(n.lineno,n.colno,e,t.children[0]);else{if(n.type!==i.TOKEN_OPERATOR||"."!==n.value)break;this.nextToken();var s=this.nextToken();s.type!==i.TOKEN_SYMBOL&&this.fail("expected name as lookup value, got "+s.value,s.lineno,s.colno),t=new r.Literal(s.lineno,s.colno,s.value),e=new r.LookupVal(n.lineno,n.colno,e,t)}n=this.peekToken()}return e},parseExpression:function(){var e=this.parseInlineIf();return e},parseInlineIf:function(){var e=this.parseOr();if(this.skipSymbol("if")){var t=this.parseOr(),n=e;e=new r.InlineIf(e.lineno,e.colno),e.body=n,e.cond=t,this.skipSymbol("else")?e.else_=this.parseOr():e.else_=null}return e},parseOr:function(){for(var e=this.parseAnd();this.skipSymbol("or");){var t=this.parseAnd();e=new r.Or(e.lineno,e.colno,e,t)}return e},parseAnd:function(){for(var e=this.parseNot();this.skipSymbol("and");){var t=this.parseNot();e=new r.And(e.lineno,e.colno,e,t)}return e},parseNot:function(){var e=this.peekToken();return this.skipSymbol("not")?new r.Not(e.lineno,e.colno,this.parseNot()):this.parseIn()},parseIn:function(){for(var e=this.parseCompare();;){var t=this.nextToken();if(!t)break;var n=t.type===i.TOKEN_SYMBOL&&"not"===t.value;if(n||this.pushToken(t),!this.skipSymbol("in")){n&&this.pushToken(t);break}var s=this.parseCompare();e=new r.In(e.lineno,e.colno,e,s),n&&(e=new r.Not(e.lineno,e.colno,e))}return e},parseCompare:function(){for(var e=["==","!=","<",">","<=",">="],t=this.parseAdd(),n=[];;){var i=this.nextToken();if(!i)break;if(-1===o.indexOf(e,i.value)){this.pushToken(i);break}n.push(new r.CompareOperand(i.lineno,i.colno,this.parseAdd(),i.value))}return n.length?new r.Compare(n[0].lineno,n[0].colno,t,n):t},parseAdd:function(){for(var e=this.parseSub();this.skipValue(i.TOKEN_OPERATOR,"+");){var t=this.parseSub();e=new r.Add(e.lineno,e.colno,e,t)}return e},parseSub:function(){for(var e=this.parseMul();this.skipValue(i.TOKEN_OPERATOR,"-");){var t=this.parseMul();e=new r.Sub(e.lineno,e.colno,e,t)}return e},parseMul:function(){for(var e=this.parseDiv();this.skipValue(i.TOKEN_OPERATOR,"*");){var t=this.parseDiv();e=new r.Mul(e.lineno,e.colno,e,t)}return e},parseDiv:function(){for(var e=this.parseFloorDiv();this.skipValue(i.TOKEN_OPERATOR,"/");){var t=this.parseFloorDiv();e=new r.Div(e.lineno,e.colno,e,t)}return e},parseFloorDiv:function(){for(var e=this.parseMod();this.skipValue(i.TOKEN_OPERATOR,"//");){var t=this.parseMod();e=new r.FloorDiv(e.lineno,e.colno,e,t)}return e},parseMod:function(){for(var e=this.parsePow();this.skipValue(i.TOKEN_OPERATOR,"%");){var t=this.parsePow();e=new r.Mod(e.lineno,e.colno,e,t)}return e},parsePow:function(){for(var e=this.parseUnary();this.skipValue(i.TOKEN_OPERATOR,"**");){var t=this.parseUnary();e=new r.Pow(e.lineno,e.colno,e,t)}return e},parseUnary:function(e){var t,n=this.peekToken();return t=this.skipValue(i.TOKEN_OPERATOR,"-")?new r.Neg(n.lineno,n.colno,this.parseUnary(!0)):this.skipValue(i.TOKEN_OPERATOR,"+")?new r.Pos(n.lineno,n.colno,this.parseUnary(!0)):this.parsePrimary(),e||(t=this.parseFilter(t)),t},parsePrimary:function(e){var t=this.nextToken(),n=null,s=null;return t?t.type===i.TOKEN_STRING?n=t.value:t.type===i.TOKEN_INT?n=parseInt(t.value,10):t.type===i.TOKEN_FLOAT?n=parseFloat(t.value):t.type===i.TOKEN_BOOLEAN?"true"===t.value?n=!0:"false"===t.value?n=!1:this.fail("invalid boolean: "+t.value,t.lineno,t.colno):t.type===i.TOKEN_REGEX&&(n=new RegExp(t.value.body,t.value.flags)):this.fail("expected expression, got end of file"),null!==n?s=new r.Literal(t.lineno,t.colno,n):t.type===i.TOKEN_SYMBOL?(s=new r.Symbol(t.lineno,t.colno,t.value),e||(s=this.parsePostfix(s))):(this.pushToken(t),s=this.parseAggregate()),s?s:void this.fail("unexpected token: "+t.value,t.lineno,t.colno)},parseFilter:function(e){for(;this.skip(i.TOKEN_PIPE);){for(var t=this.expect(i.TOKEN_SYMBOL),n=t.value;this.skipValue(i.TOKEN_OPERATOR,".");)n+="."+this.expect(i.TOKEN_SYMBOL).value;if(e=new r.Filter(t.lineno,t.colno,new r.Symbol(t.lineno,t.colno,n),new r.NodeList(t.lineno,t.colno,[e])),this.peekToken().type===i.TOKEN_LEFT_PAREN){var s=this.parsePostfix(e);e.args.children=e.args.children.concat(s.args.children)}}return e},parseAggregate:function(){var e,t=this.nextToken();switch(t.type){case i.TOKEN_LEFT_PAREN:e=new r.Group(t.lineno,t.colno);break;case i.TOKEN_LEFT_BRACKET:e=new r.Array(t.lineno,t.colno);break;case i.TOKEN_LEFT_CURLY:e=new r.Dict(t.lineno,t.colno);break;default:return null}for(;;){var n=this.peekToken().type;if(n===i.TOKEN_RIGHT_PAREN||n===i.TOKEN_RIGHT_BRACKET||n===i.TOKEN_RIGHT_CURLY){this.nextToken();break}if(e.children.length>0&&(this.skip(i.TOKEN_COMMA)||this.fail("parseAggregate: expected comma after expression",t.lineno,t.colno)),e instanceof r.Dict){var s=this.parsePrimary();this.skip(i.TOKEN_COLON)||this.fail("parseAggregate: expected colon after dict key",t.lineno,t.colno);var o=this.parseExpression();e.addChild(new r.Pair(s.lineno,s.colno,s,o))}else{var a=this.parseExpression();e.addChild(a)}}return e},parseSignature:function(e,t){var n=this.peekToken();if(!t&&n.type!==i.TOKEN_LEFT_PAREN){if(e)return null;this.fail("expected arguments",n.lineno,n.colno)}n.type===i.TOKEN_LEFT_PAREN&&(n=this.nextToken());for(var s=new r.NodeList(n.lineno,n.colno),o=new r.KeywordArgs(n.lineno,n.colno),a=!1;;){if(n=this.peekToken(),!t&&n.type===i.TOKEN_RIGHT_PAREN){this.nextToken();break}if(t&&n.type===i.TOKEN_BLOCK_END)break;if(a&&!this.skip(i.TOKEN_COMMA))this.fail("parseSignature: expected comma after expression",n.lineno,n.colno);else{var l=this.parseExpression();this.skipValue(i.TOKEN_OPERATOR,"=")?o.addChild(new r.Pair(l.lineno,l.colno,l,this.parseExpression())):s.addChild(l)}a=!0}return o.children.length&&s.addChild(o),s},parseUntilBlocks:function(){var e=this.breakOnBlocks;this.breakOnBlocks=o.toArray(arguments);var t=this.parse();return this.breakOnBlocks=e,t},parseNodes:function(){for(var e,t=[];e=this.nextToken();)if(e.type===i.TOKEN_DATA){var n=e.value,s=this.peekToken(),o=s&&s.value;this.dropLeadingWhitespace&&(n=n.replace(/^\s*/,""),this.dropLeadingWhitespace=!1),s&&s.type===i.TOKEN_BLOCK_START&&"-"===o.charAt(o.length-1)&&(n=n.replace(/\s*$/,"")),t.push(new r.Output(e.lineno,e.colno,[new r.TemplateData(e.lineno,e.colno,n)]))}else if(e.type===i.TOKEN_BLOCK_START){var a=this.parseStatement();if(!a)break;t.push(a)}else if(e.type===i.TOKEN_VARIABLE_START){var l=this.parseExpression();this.advanceAfterVariableEnd(),t.push(new r.Output(e.lineno,e.colno,[l]))}else e.type!==i.TOKEN_COMMENT&&this.fail("Unexpected token at top-level: "+e.type,e.lineno,e.colno);return t},parse:function(){return new r.NodeList(0,0,this.parseNodes())},parseAsRoot:function(){return new r.Root(0,0,this.parseNodes())}});e.exports={parse:function(e,t,n){var r=new a(i.lex(e,n));return void 0!==t&&(r.extensions=t),r.parseAsRoot()}}},function(e,t,n){"use strict";function i(e,t,n,i){return{type:e,value:t,lineno:n,colno:i}}function r(e,t){this.str=e,this.index=0,this.len=e.length,this.lineno=0,this.colno=0,this.in_code=!1,t=t||{};var n=t.tags||{};this.tags={BLOCK_START:n.blockStart||c,BLOCK_END:n.blockEnd||h,VARIABLE_START:n.variableStart||u,VARIABLE_END:n.variableEnd||p,COMMENT_START:n.commentStart||f,COMMENT_END:n.commentEnd||m},this.trimBlocks=!!t.trimBlocks,this.lstripBlocks=!!t.lstripBlocks}var s=n(1),o=" \n	\r ",a="()[]{}%*-+/#,:|.<>=!",l="0123456789",c="{%",h="%}",u="{{",p="}}",f="{#",m="#}",d="string",v="whitespace",g="data",y="block-start",k="block-end",x="variable-start",E="variable-end",b="comment",T="left-paren",w="right-paren",_="left-bracket",L="right-bracket",O="left-curly",A="right-curly",S="operator",N="comma",C="colon",B="pipe",R="int",K="float",F="boolean",I="symbol",M="special",P="regex";r.prototype.nextToken=function(){var e,t=this.lineno,n=this.colno;if(this.in_code){var r=this.current();if(this.is_finished())return null;if('"'===r||"'"===r)return i(d,this.parseString(r),t,n);if(e=this._extract(o))return i(v,e,t,n);if((e=this._extractString(this.tags.BLOCK_END))||(e=this._extractString("-"+this.tags.BLOCK_END)))return this.in_code=!1,this.trimBlocks&&(r=this.current(),"\n"===r&&this.forward()),i(k,e,t,n);if(e=this._extractString(this.tags.VARIABLE_END))return this.in_code=!1,i(E,e,t,n);if("r"===r&&"/"===this.str.charAt(this.index+1)){this.forwardN(2);for(var c="";!this.is_finished();){if("/"===this.current()&&"\\"!==this.previous()){this.forward();break}c+=this.current(),this.forward()}for(var h=["g","i","m","y"],u="";!this.is_finished();){var p=-1!==h.indexOf(this.current());if(!p)break;u+=this.current(),this.forward()}return i(P,{body:c,flags:u},t,n)}if(-1!==a.indexOf(r)){this.forward();var f,m=["==","!=","<=",">=","//","**"],M=r+this.current();switch(-1!==s.indexOf(m,M)&&(this.forward(),r=M),r){case"(":f=T;break;case")":f=w;break;case"[":f=_;break;case"]":f=L;break;case"{":f=O;break;case"}":f=A;break;case",":f=N;break;case":":f=C;break;case"|":f=B;break;default:f=S}return i(f,r,t,n)}if(e=this._extractUntil(o+a),e.match(/^[-+]?[0-9]+$/)){if("."===this.current()){this.forward();var D=this._extract(l);return i(K,e+"."+D,t,n)}return i(R,e,t,n)}if(e.match(/^(true|false)$/))return i(F,e,t,n);if(e)return i(I,e,t,n);throw new Error("Unexpected value while parsing: "+e)}var V=this.tags.BLOCK_START.charAt(0)+this.tags.VARIABLE_START.charAt(0)+this.tags.COMMENT_START.charAt(0)+this.tags.COMMENT_END.charAt(0);if(this.is_finished())return null;if((e=this._extractString(this.tags.BLOCK_START+"-"))||(e=this._extractString(this.tags.BLOCK_START)))return this.in_code=!0,i(y,e,t,n);if(e=this._extractString(this.tags.VARIABLE_START))return this.in_code=!0,i(x,e,t,n);e="";var U,j=!1;for(this._matches(this.tags.COMMENT_START)&&(j=!0,e=this._extractString(this.tags.COMMENT_START));null!==(U=this._extractUntil(V));){if(e+=U,(this._matches(this.tags.BLOCK_START)||this._matches(this.tags.VARIABLE_START)||this._matches(this.tags.COMMENT_START))&&!j){if(this.lstripBlocks&&this._matches(this.tags.BLOCK_START)&&this.colno>0&&this.colno<=e.length){var W=e.slice(-this.colno);if(/^\s+$/.test(W)&&(e=e.slice(0,-this.colno),!e.length))return this.nextToken()}break}if(this._matches(this.tags.COMMENT_END)){if(!j)throw new Error("unexpected end of comment");e+=this._extractString(this.tags.COMMENT_END);break}e+=this.current(),this.forward()}if(null===U&&j)throw new Error("expected end of comment, got end of file");return i(j?b:g,e,t,n)},r.prototype.parseString=function(e){this.forward();for(var t="";!this.is_finished()&&this.current()!==e;){var n=this.current();if("\\"===n){switch(this.forward(),this.current()){case"n":t+="\n";break;case"t":t+="	";break;case"r":t+="\r";break;default:t+=this.current()}this.forward()}else t+=n,this.forward()}return this.forward(),t},r.prototype._matches=function(e){if(this.index+e.length>this.len)return null;var t=this.str.slice(this.index,this.index+e.length);return t===e},r.prototype._extractString=function(e){return this._matches(e)?(this.index+=e.length,e):null},r.prototype._extractUntil=function(e){return this._extractMatching(!0,e||"")},r.prototype._extract=function(e){return this._extractMatching(!1,e)},r.prototype._extractMatching=function(e,t){if(this.is_finished())return null;var n=t.indexOf(this.current());if(e&&-1===n||!e&&-1!==n){var i=this.current();this.forward();for(var r=t.indexOf(this.current());(e&&-1===r||!e&&-1!==r)&&!this.is_finished();)i+=this.current(),this.forward(),r=t.indexOf(this.current());return i}return""},r.prototype.is_finished=function(){return this.index>=this.len},r.prototype.forwardN=function(e){for(var t=0;e>t;t++)this.forward()},r.prototype.forward=function(){this.index++,"\n"===this.previous()?(this.lineno++,this.colno=0):this.colno++},r.prototype.back=function(){if(this.index--,"\n"===this.current()){this.lineno--;var e=this.src.lastIndexOf("\n",this.index-1);-1===e?this.colno=this.index:this.colno=this.index-e}else this.colno--},r.prototype.current=function(){return this.is_finished()?"":this.str.charAt(this.index)},r.prototype.previous=function(){return this.str.charAt(this.index-1)},e.exports={lex:function(e,t){return new r(e,t)},TOKEN_STRING:d,TOKEN_WHITESPACE:v,TOKEN_DATA:g,TOKEN_BLOCK_START:y,TOKEN_BLOCK_END:k,TOKEN_VARIABLE_START:x,TOKEN_VARIABLE_END:E,TOKEN_COMMENT:b,TOKEN_LEFT_PAREN:T,TOKEN_RIGHT_PAREN:w,TOKEN_LEFT_BRACKET:_,TOKEN_RIGHT_BRACKET:L,TOKEN_LEFT_CURLY:O,TOKEN_RIGHT_CURLY:A,TOKEN_OPERATOR:S,TOKEN_COMMA:N,TOKEN_COLON:C,TOKEN_PIPE:B,TOKEN_INT:R,TOKEN_FLOAT:K,TOKEN_BOOLEAN:F,TOKEN_SYMBOL:I,TOKEN_SPECIAL:M,TOKEN_REGEX:P}},function(e,t,n){"use strict";function i(e,t,n){return function(){var i,r,a=o(arguments),l=s(arguments);if(a>e.length){i=Array.prototype.slice.call(arguments,0,e.length);var c=Array.prototype.slice.call(arguments,i.length,a);for(r=0;r<c.length;r++)r<t.length&&(l[t[r]]=c[r]);i.push(l)}else if(a<e.length){for(i=Array.prototype.slice.call(arguments,0,a),r=a;r<e.length;r++){var h=e[r];i.push(l[h]),delete l[h]}i.push(l)}else i=arguments;return n.apply(this,i)}}function r(e){return e.__keywords=!0,e}function s(e){var t=e.length;if(t){var n=e[t-1];if(n&&n.hasOwnProperty("__keywords"))return n}return{}}function o(e){var t=e.length;if(0===t)return 0;var n=e[t-1];return n&&n.hasOwnProperty("__keywords")?t-1:t}function a(e){return"string"!=typeof e?e:(this.val=e,void(this.length=e.length))}function l(e,t){return e instanceof a?new a(t):t.toString()}function c(e){var t=typeof e;return"string"===t?new a(e):"function"!==t?e:function(){var t=e.apply(this,arguments);return"string"==typeof t?new a(t):t}}function h(e,t){return e=void 0!==e&&null!==e?e:"",t&&"string"==typeof e&&(e=y.escape(e)),e}function u(e,t,n){if(null===e||void 0===e)throw new y.TemplateError("attempted to output null or undefined value",t+1,n+1);return e}function p(e,t){return e=e||{},"function"==typeof e[t]?function(){return e[t].apply(e,arguments)}:e[t]}function f(e,t,n){if(!e)throw new Error("Unable to call `"+t+"`, which is undefined or falsey");if("function"!=typeof e)throw new Error("Unable to call `"+t+"`, which is not a function");return e.apply(this,n)}function m(e,t,n){var i=t.lookup(n);return void 0!==i&&null!==i?i:e.lookup(n)}function d(e,t,n){return e.lineno?e:new y.TemplateError(e,t,n)}function v(e,t,n,i){if(y.isArray(e)){var r=e.length;y.asyncIter(e,function(e,i,s){switch(t){case 1:n(e,i,r,s);break;case 2:n(e[0],e[1],i,r,s);break;case 3:n(e[0],e[1],e[2],i,r,s);break;default:e.push(i,s),n.apply(this,e)}},i)}else y.asyncFor(e,function(e,t,i,r,s){n(e,t,i,r,s)},i)}function g(e,t,n,i){function r(e,t){l++,a[e]=t,l===s&&i(null,a.join(""))}var s,o,a,l=0;if(y.isArray(e))if(s=e.length,a=new Array(s),0===s)i(null,"");else for(o=0;o<e.length;o++){var c=e[o];switch(t){case 1:n(c,o,s,r);break;case 2:n(c[0],c[1],o,s,r);break;case 3:n(c[0],c[1],c[2],o,s,r);break;default:c.push(o,r),n.apply(this,c)}}else{var h=y.keys(e);if(s=h.length,a=new Array(s),0===s)i(null,"");else for(o=0;o<h.length;o++){var u=h[o];n(u,e[u],o,s,r)}}}var y=n(1),k=n(9),x=k.extend({init:function(e){this.variables={},this.parent=e,this.topLevel=!1},set:function(e,t,n){var i=e.split("."),r=this.variables,s=this;if(n){if(s=this.resolve(i[0]))return void s.set(e,t);s=this}for(var o=0;o<i.length-1;o++){var a=i[o];r[a]||(r[a]={}),r=r[a]}r[i[i.length-1]]=t},get:function(e){var t=this.variables[e];return void 0!==t&&null!==t?t:null},lookup:function(e){var t=this.parent,n=this.variables[e];return void 0!==n&&null!==n?n:t&&t.lookup(e)},resolve:function(e){var t=this.parent,n=this.variables[e];return void 0!==n&&null!==n?this:t&&t.resolve(e)},push:function(){return new x(this)},pop:function(){return this.parent}});a.prototype=Object.create(String.prototype,{length:{writable:!0,configurable:!0,value:0}}),a.prototype.valueOf=function(){return this.val},a.prototype.toString=function(){return this.val},e.exports={Frame:x,makeMacro:i,makeKeywordArgs:r,numArgs:o,suppressValue:h,ensureDefined:u,memberLookup:p,contextOrFrameLookup:m,callWrap:f,handleError:d,isArray:y.isArray,keys:y.keys,SafeString:a,copySafeness:l,markSafe:c,asyncEach:v,asyncAll:g}},function(e,t,n){"use strict";var i=n(14),r=n(9),s=n(1),o=r.extend({on:function(e,t){this.listeners=this.listeners||{},this.listeners[e]=this.listeners[e]||[],this.listeners[e].push(t)},emit:function(e){var t=Array.prototype.slice.call(arguments,1);this.listeners&&this.listeners[e]&&s.each(this.listeners[e],function(e){e.apply(null,t)})},resolve:function(e,t){return i.resolve(i.dirname(e),t)},isRelative:function(e){return 0===e.indexOf("./")||0===e.indexOf("../")}});e.exports=o},function(e,t,n){"use strict";var i=n(7),r=i.extend({init:function(e,t){this.precompiled=window.nunjucksPrecompiled||{},this.baseURL=e||"",this.useCache=t.useCache,this.async=t.async},resolve:function(e,t){throw new Error("relative templates not support in the browser yet")},getSource:function(e,t){if(this.precompiled[e])return{src:{type:"code",obj:this.precompiled[e]},path:e};var n,i=this.useCache;return this.fetch(this.baseURL+"/"+e,function(r,s){if(r){if(!t)throw r;t(r)}else n={src:s,path:e,noCache:!i},t&&t(null,n)}),n},fetch:function(e,t){var n,i=!0;window.XMLHttpRequest?n=new XMLHttpRequest:window.ActiveXObject&&(n=new ActiveXObject("Microsoft.XMLHTTP")),n.onreadystatechange=function(){4===n.readyState&&i&&(i=!1,0===n.status||200===n.status?t(null,n.responseText):t(n.responseText))},e+=(-1===e.indexOf("?")?"?":"&")+"s="+(new Date).getTime(),n.open("GET",e,this.async),n.send()}});e.exports={WebLoader:r}},function(e,t,n){"use strict";function i(e,t,n){var r=function(){};r.prototype=e.prototype;var s=new r,o=/xyz/.test(function(){xyz})?/\bparent\b/:/.*/;n=n||{};for(var a in n){var l=n[a],c=s[a];"function"==typeof c&&"function"==typeof l&&o.test(l)?s[a]=function(e,t){return function(){var n=this.parent;this.parent=t;var i=e.apply(this,arguments);return this.parent=n,i}}(l,c):s[a]=l}s.typename=t;var h=function(){s.init&&s.init.apply(this,arguments)};return h.prototype=s,h.prototype.constructor=h,h.extend=function(e,t){return"object"==typeof e&&(t=e,e="anonymous"),i(h,e,t)},h}e.exports=i(Object,"Object",{})},function(e,t,n){"use strict";function i(e,t){return null===e||void 0===e||e===!1?t:e}var r=n(1),s=n(6),o={abs:function(e){return Math.abs(e)},batch:function(e,t,n){var i,r=[],s=[];for(i=0;i<e.length;i++)i%t===0&&s.length&&(r.push(s),s=[]),s.push(e[i]);if(s.length){if(n)for(i=s.length;t>i;i++)s.push(n);r.push(s)}return r},capitalize:function(e){e=i(e,"");var t=e.toLowerCase();return s.copySafeness(e,t.charAt(0).toUpperCase()+t.slice(1))},center:function(e,t){if(e=i(e,""),t=t||80,e.length>=t)return e;var n=t-e.length,o=r.repeat(" ",n/2-n%2),a=r.repeat(" ",n/2);return s.copySafeness(e,o+e+a)},"default":function(e,t){return e?e:t},dictsort:function(e,t,n){if(!r.isObject(e))throw new r.TemplateError("dictsort filter: val must be an object");var i=[];for(var s in e)i.push([s,e[s]]);var o;if(void 0===n||"key"===n)o=0;else{if("value"!==n)throw new r.TemplateError("dictsort filter: You can only sort by either key or value");o=1}return i.sort(function(e,n){var i=e[o],s=n[o];return t||(r.isString(i)&&(i=i.toUpperCase()),r.isString(s)&&(s=s.toUpperCase())),i>s?1:i===s?0:-1}),i},dump:function(e){return JSON.stringify(e)},escape:function(e){return"string"==typeof e||e instanceof s.SafeString?r.escape(e):e},safe:function(e){return s.markSafe(e)},first:function(e){return e[0]},groupby:function(e,t){return r.groupBy(e,t)},indent:function(e,t,n){if(e=i(e,""),""===e)return"";t=t||4;for(var o="",a=e.split("\n"),l=r.repeat(" ",t),c=0;c<a.length;c++)o+=0!==c||n?l+a[c]+"\n":a[c]+"\n";return s.copySafeness(e,o)},join:function(e,t,n){return t=t||"",n&&(e=r.map(e,function(e){return e[n]})),e.join(t)},last:function(e){return e[e.length-1]},length:function(e){var t=i(e,"");return void 0!==t?t.length:0},list:function(e){if(r.isString(e))return e.split("");if(r.isObject(e)){var t=[];if(Object.keys)t=Object.keys(e);else for(var n in e)t.push(n);return r.map(t,function(t){return{key:t,value:e[t]}})}if(r.isArray(e))return e;throw new r.TemplateError("list filter: type not iterable")},lower:function(e){return e=i(e,""),e.toLowerCase()},random:function(e){return e[Math.floor(Math.random()*e.length)]},rejectattr:function(e,t){return e.filter(function(e){return!e[t]})},selectattr:function(e,t){return e.filter(function(e){return!!e[t]})},replace:function(e,t,n,i){var r=e;if(t instanceof RegExp)return e.replace(t,n);"undefined"==typeof i&&(i=-1);var o="";if("number"==typeof t)t+="";else if("string"!=typeof t)return e;if("number"==typeof e&&(e+=""),"string"!=typeof e&&!(e instanceof s.SafeString))return e;if(""===t)return o=n+e.split("").join(n)+n,s.copySafeness(e,o);var a=e.indexOf(t);if(0===i||-1===a)return e;for(var l=0,c=0;a>-1&&(-1===i||i>c);)o+=e.substring(l,a)+n,l=a+t.length,c++,a=e.indexOf(t,l);return l<e.length&&(o+=e.substring(l)),s.copySafeness(r,o)},reverse:function(e){var t;return t=r.isString(e)?o.list(e):r.map(e,function(e){return e}),t.reverse(),r.isString(e)?s.copySafeness(e,t.join("")):t},round:function(e,t,n){t=t||0;var i,r=Math.pow(10,t);return i="ceil"===n?Math.ceil:"floor"===n?Math.floor:Math.round,i(e*r)/r},slice:function(e,t,n){for(var i=Math.floor(e.length/t),r=e.length%t,s=0,o=[],a=0;t>a;a++){var l=s+a*i;r>a&&s++;var c=s+(a+1)*i,h=e.slice(l,c);n&&a>=r&&h.push(n),o.push(h)}return o},sort:function(e,t,n,i){return e=r.map(e,function(e){return e}),e.sort(function(e,s){var o,a;return i?(o=e[i],a=s[i]):(o=e,a=s),!n&&r.isString(o)&&r.isString(a)&&(o=o.toLowerCase(),a=a.toLowerCase()),a>o?t?1:-1:o>a?t?-1:1:0}),e},string:function(e){return s.copySafeness(e,e)},title:function(e){e=i(e,"");for(var t=e.split(" "),n=0;n<t.length;n++)t[n]=o.capitalize(t[n]);return s.copySafeness(e,t.join(" "))},trim:function(e){return s.copySafeness(e,e.replace(/^\s*|\s*$/g,""))},truncate:function(e,t,n,r){var o=e;if(e=i(e,""),t=t||255,e.length<=t)return e;if(n)e=e.substring(0,t);else{var a=e.lastIndexOf(" ",t);-1===a&&(a=t),e=e.substring(0,a)}return e+=void 0!==r&&null!==r?r:"...",s.copySafeness(o,e)},upper:function(e){return e=i(e,""),e.toUpperCase()},urlencode:function(e){var t=encodeURIComponent;if(r.isString(e))return t(e);var n;if(r.isArray(e))n=e.map(function(e){return t(e[0])+"="+t(e[1])});else{n=[];for(var i in e)e.hasOwnProperty(i)&&n.push(t(i)+"="+t(e[i]))}return n.join("&")},urlize:function(e,t,n){isNaN(t)&&(t=1/0);var i=n===!0?' rel="nofollow"':"",r=/^(?:\(|<|&lt;)?(.*?)(?:\.|,|\)|\n|&gt;)?$/,s=/^[\w.!#$%&'*+\-\/=?\^`{|}~]+@[a-z\d\-]+(\.[a-z\d\-]+)+$/i,o=/^https?:\/\/.*$/,a=/^www\./,l=/\.(?:org|net|com)(?:\:|\/|$)/,c=e.split(/\s+/).filter(function(e){return e&&e.length}).map(function(e){var n=e.match(r),c=n&&n[1]||e;return o.test(c)?'<a href="'+c+'"'+i+">"+c.substr(0,t)+"</a>":a.test(c)?'<a href="http://'+c+'"'+i+">"+c.substr(0,t)+"</a>":s.test(c)?'<a href="mailto:'+c+'">'+c+"</a>":l.test(c)?'<a href="http://'+c+'"'+i+">"+c.substr(0,t)+"</a>":e});return c.join(" ")},wordcount:function(e){e=i(e,"");var t=e?e.match(/\w+/g):null;return t?t.length:null},"float":function(e,t){var n=parseFloat(e);return isNaN(n)?t:n},"int":function(e,t){var n=parseInt(e,10);return isNaN(n)?t:n}};o.d=o["default"],o.e=o.escape,e.exports=o},function(e,t,n){"use strict";function i(e){var t=-1;return{current:null,reset:function(){t=-1,this.current=null},next:function(){return t++,t>=e.length&&(t=0),this.current=e[t],this.current}}}function r(e){e=e||",";var t=!0;return function(){var n=t?"":e;return t=!1,n}}var s={range:function(e,t,n){t?n||(n=1):(t=e,e=0,n=1);for(var i=[],r=e;t>r;r+=n)i.push(r);return i},cycler:function(){return i(Array.prototype.slice.call(arguments))},joiner:function(e){return r(e)}};e.exports=s},function(e,t,n){"use strict";function i(){return"hole_"+d++}function r(e,t){for(var n=null,i=0;i<e.length;i++){var r=t(e[i]);r!==e[i]&&(n||(n=e.slice()),n[i]=r)}return n||e}function s(e,t,n){if(!(e instanceof f.Node))return e;if(!n){var i=t(e);if(i&&i!==e)return i}if(e instanceof f.NodeList){var o=r(e.children,function(e){return s(e,t,n)});o!==e.children&&(e=new f[e.typename](e.lineno,e.colno,o))}else if(e instanceof f.CallExtension){var a=s(e.args,t,n),l=r(e.contentArgs,function(e){return s(e,t,n)});(a!==e.args||l!==e.contentArgs)&&(e=new f[e.typename](e.extName,e.prop,a,l))}else{var c=e.fields.map(function(t){return e[t]}),h=r(c,function(e){return s(e,t,n)});h!==c&&(e=new f[e.typename](e.lineno,e.colno),h.forEach(function(t,n){e[e.fields[n]]=t}))}return n?t(e)||e:e}function o(e,t){return s(e,t,!0)}function a(e,t,n){var r=[],s=o(n?e[n]:e,function(e){if(e instanceof f.Block)return e;if(e instanceof f.Filter&&-1!==m.indexOf(t,e.name.value)||e instanceof f.CallExtensionAsync){var n=new f.Symbol(e.lineno,e.colno,i());return r.push(new f.FilterAsync(e.lineno,e.colno,e.name,e.args,n)),n}});return n?e[n]=s:e=s,r.length?(r.push(e),new f.NodeList(e.lineno,e.colno,r)):e}function l(e,t){return o(e,function(e){return e instanceof f.Output?a(e,t):e instanceof f.Set?a(e,t,"value"):e instanceof f.For?a(e,t,"arr"):e instanceof f.If?a(e,t,"cond"):e instanceof f.CallExtension?a(e,t,"args"):void 0})}function c(e){return s(e,function(e){if(e instanceof f.Block){var t=!1,n=i();e.body=s(e.body,function(e){return e instanceof f.FunCall&&"super"===e.name.value?(t=!0,new f.Symbol(e.lineno,e.colno,n)):void 0}),t&&e.body.children.unshift(new f.Super(0,0,e.name,new f.Symbol(0,0,n)))}})}function h(e){return o(e,function(e){if(e instanceof f.If||e instanceof f.For){var t=!1;if(s(e,function(e){return e instanceof f.FilterAsync||e instanceof f.IfAsync||e instanceof f.AsyncEach||e instanceof f.AsyncAll||e instanceof f.CallExtensionAsync||e instanceof f.Include?(t=!0,e):void 0}),t){if(e instanceof f.If)return new f.IfAsync(e.lineno,e.colno,e.cond,e.body,e.else_);if(e instanceof f.For)return new f.AsyncEach(e.lineno,e.colno,e.arr,e.name,e.body,e.else_)}}})}function u(e,t){return h(c(l(e,t)))}function p(e,t){return u(e,t||[])}var f=n(13),m=n(1),d=0;e.exports={transform:p}},function(e,t,n){(function(t){"use strict";function i(e,t,n){e instanceof t&&n.push(e),e instanceof a&&e.findAll(t,n)}function r(e,n){function i(e,n,i){for(var r=e.split("\n"),s=0;s<r.length;s++){if(r[s]&&(i&&s>0||!i))for(var o=0;n>o;o++)t.stdout.write(" ");t.stdout.write(s===r.length-1?r[s]:r[s]+"\n")}}if(n=n||0,i(e.typename+": ",n),e instanceof c)i("\n"),s.each(e.children,function(e){r(e,n+2)});else if(e instanceof ie)i(e.extName+"."+e.prop),i("\n"),e.args&&r(e.args,n+2),e.contentArgs&&s.each(e.contentArgs,function(e){r(e,n+2)});else{var o=null,l=null;if(e.iterFields(function(e,t){e instanceof a?(o=o||{},o[t]=e):(l=l||{},l[t]=e)}),l?i(JSON.stringify(l,null,2)+"\n",null,!0):i("\n"),o)for(var h in o)r(o[h],n+2)}}var s=n(1),o=n(9),a=o.extend("Node",{init:function(e,t){this.lineno=e,this.colno=t;for(var n=this.fields,i=0,r=n.length;r>i;i++){var s=n[i],o=arguments[i+2];void 0===o&&(o=null),this[s]=o}},findAll:function(e,t){t=t||[];var n,r;if(this instanceof c){var s=this.children;for(n=0,r=s.length;r>n;n++)i(s[n],e,t)}else{var o=this.fields;for(n=0,r=o.length;r>n;n++)i(this[o[n]],e,t)}return t},iterFields:function(e){s.each(this.fields,function(t){e(this[t],t)},this)}}),l=a.extend("Value",{fields:["value"]}),c=a.extend("NodeList",{fields:["children"],init:function(e,t,n){this.parent(e,t,n||[])},addChild:function(e){this.children.push(e)}}),h=c.extend("Root"),u=l.extend("Literal"),p=l.extend("Symbol"),f=c.extend("Group"),m=c.extend("Array"),d=a.extend("Pair",{fields:["key","value"]}),v=c.extend("Dict"),g=a.extend("LookupVal",{fields:["target","val"]}),y=a.extend("If",{fields:["cond","body","else_"]}),k=y.extend("IfAsync"),x=a.extend("InlineIf",{fields:["cond","body","else_"]}),E=a.extend("For",{fields:["arr","name","body","else_"]}),b=E.extend("AsyncEach"),T=E.extend("AsyncAll"),w=a.extend("Macro",{fields:["name","args","body"]}),_=w.extend("Caller"),L=a.extend("Import",{fields:["template","target","withContext"]}),O=a.extend("FromImport",{fields:["template","names","withContext"],init:function(e,t,n,i,r){this.parent(e,t,n,i||new c,r)}}),A=a.extend("FunCall",{fields:["name","args"]}),S=A.extend("Filter"),N=S.extend("FilterAsync",{fields:["name","args","symbol"]}),C=v.extend("KeywordArgs"),B=a.extend("Block",{fields:["name","body"]}),R=a.extend("Super",{fields:["blockName","symbol"]}),K=a.extend("TemplateRef",{fields:["template"]}),F=K.extend("Extends"),I=K.extend("Include"),M=a.extend("Set",{fields:["targets","value"]}),P=c.extend("Output"),D=u.extend("TemplateData"),V=a.extend("UnaryOp",{fields:["target"]}),U=a.extend("BinOp",{fields:["left","right"]}),j=U.extend("In"),W=U.extend("Or"),G=U.extend("And"),H=V.extend("Not"),Y=U.extend("Add"),$=U.extend("Sub"),z=U.extend("Mul"),X=U.extend("Div"),q=U.extend("FloorDiv"),J=U.extend("Mod"),Q=U.extend("Pow"),Z=V.extend("Neg"),ee=V.extend("Pos"),te=a.extend("Compare",{fields:["expr","ops"]
+}),ne=a.extend("CompareOperand",{fields:["expr","type"]}),ie=a.extend("CallExtension",{fields:["extName","prop","args","contentArgs"],init:function(e,t,n,i){this.extName=e._name||e,this.prop=t,this.args=n||new c,this.contentArgs=i||[],this.autoescape=e.autoescape}}),re=ie.extend("CallExtensionAsync");e.exports={Node:a,Root:h,NodeList:c,Value:l,Literal:u,Symbol:p,Group:f,Array:m,Pair:d,Dict:v,Output:P,TemplateData:D,If:y,IfAsync:k,InlineIf:x,For:E,AsyncEach:b,AsyncAll:T,Macro:w,Caller:_,Import:L,FromImport:O,FunCall:A,Filter:S,FilterAsync:N,KeywordArgs:C,Block:B,Super:R,Extends:F,Include:I,Set:M,LookupVal:g,BinOp:U,In:j,Or:W,And:G,Not:H,Add:Y,Sub:$,Mul:z,Div:X,FloorDiv:q,Mod:J,Pow:Q,Neg:Z,Pos:ee,Compare:te,CompareOperand:ne,CallExtension:ie,CallExtensionAsync:re,printNodes:r}}).call(t,n(14))},function(e,t,n){},function(e,t,n){"use strict";function i(){if(l.length)throw l.shift()}function r(e){var t;t=a.length?a.pop():new s,t.task=e,o(t)}function s(){this.task=null}var o=n(16),a=[],l=[],c=o.makeRequestCallFromTimer(i);e.exports=r,s.prototype.call=function(){try{this.task.call()}catch(e){r.onerror?r.onerror(e):(l.push(e),c())}finally{this.task=null,a[a.length]=this}}},function(e,t,n){(function(t){"use strict";function n(e){a.length||(o(),l=!0),a[a.length]=e}function i(){for(;c<a.length;){var e=c;if(c+=1,a[e].call(),c>h){for(var t=0,n=a.length-c;n>t;t++)a[t]=a[t+c];a.length-=c,c=0}}a.length=0,c=0,l=!1}function r(e){var t=1,n=new u(e),i=document.createTextNode("");return n.observe(i,{characterData:!0}),function(){t=-t,i.data=t}}function s(e){return function(){function t(){clearTimeout(n),clearInterval(i),e()}var n=setTimeout(t,0),i=setInterval(t,50)}}e.exports=n;var o,a=[],l=!1,c=0,h=1024,u=t.MutationObserver||t.WebKitMutationObserver;o="function"==typeof u?r(i):s(i),n.requestFlush=o,n.makeRequestCallFromTimer=s}).call(t,function(){return this}())}]);
\ No newline at end of file
diff --git a/index.js b/index.js
index 2a047ed..d35daf0 100644
--- a/index.js
+++ b/index.js
@@ -23,7 +23,6 @@ module.exports.compiler = compiler;
 module.exports.parser = parser;
 module.exports.lexer = lexer;
 module.exports.runtime = runtime;
-module.exports.lib = lib;
 
 // A single instance of an environment, since this is so commonly used
 
diff --git a/package.json b/package.json
index 4414768..4ef3dc1 100644
--- a/package.json
+++ b/package.json
@@ -40,7 +40,12 @@
     "template",
     "templating"
   ],
-  "license": "BSD-2-Clause",
+  "license": [
+    {
+      "type": "BSD",
+      "url": "https://github.com/mozilla/nunjucks/blob/master/LICENSE"
+    }
+  ],
   "bugs": {
     "url": "https://github.com/mozilla/nunjucks/issues"
   }
diff --git a/src/compiler.js b/src/compiler.js
index 77d0ba6..fdf29f6 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -175,6 +175,7 @@ var Compiler = Object.extend({
             nodes.Or,
             nodes.Not,
             nodes.Add,
+            nodes.Concat,
             nodes.Sub,
             nodes.Mul,
             nodes.Div,
@@ -370,6 +371,9 @@ var Compiler = Object.extend({
     compileOr: binOpEmitter(' || '),
     compileAnd: binOpEmitter(' && '),
     compileAdd: binOpEmitter(' + '),
+    // ensure concatenation instead of addition
+    // by adding empty string in between
+    compileConcat: binOpEmitter(' + "" + '),
     compileSub: binOpEmitter(' - '),
     compileMul: binOpEmitter(' * '),
     compileDiv: binOpEmitter(' / '),
diff --git a/src/lexer.js b/src/lexer.js
index 0ef3f2b..cec145e 100644
--- a/src/lexer.js
+++ b/src/lexer.js
@@ -3,7 +3,7 @@
 var lib = require('./lib');
 
 var whitespaceChars = ' \n\t\r\u00A0';
-var delimChars = '()[]{}%*-+/#,:|.<>=!';
+var delimChars = '()[]{}%*-+~/#,:|.<>=!';
 var intChars = '0123456789';
 
 var BLOCK_START = '{%';
@@ -30,6 +30,7 @@ var TOKEN_RIGHT_CURLY = 'right-curly';
 var TOKEN_OPERATOR = 'operator';
 var TOKEN_COMMA = 'comma';
 var TOKEN_COLON = 'colon';
+var TOKEN_TILDE = 'tilde';
 var TOKEN_PIPE = 'pipe';
 var TOKEN_INT = 'int';
 var TOKEN_FLOAT = 'float';
@@ -169,6 +170,7 @@ Tokenizer.prototype.nextToken = function() {
             case '}': type = TOKEN_RIGHT_CURLY; break;
             case ',': type = TOKEN_COMMA; break;
             case ':': type = TOKEN_COLON; break;
+            case '~': type = TOKEN_TILDE; break;
             case '|': type = TOKEN_PIPE; break;
             default: type = TOKEN_OPERATOR;
             }
@@ -459,6 +461,7 @@ module.exports = {
     TOKEN_OPERATOR: TOKEN_OPERATOR,
     TOKEN_COMMA: TOKEN_COMMA,
     TOKEN_COLON: TOKEN_COLON,
+    TOKEN_TILDE: TOKEN_TILDE,
     TOKEN_PIPE: TOKEN_PIPE,
     TOKEN_INT: TOKEN_INT,
     TOKEN_FLOAT: TOKEN_FLOAT,
diff --git a/src/nodes.js b/src/nodes.js
index b5cdf5c..47ae613 100644
--- a/src/nodes.js
+++ b/src/nodes.js
@@ -128,6 +128,7 @@ var Or = BinOp.extend('Or');
 var And = BinOp.extend('And');
 var Not = UnaryOp.extend('Not');
 var Add = BinOp.extend('Add');
+var Concat = BinOp.extend('Concat');
 var Sub = BinOp.extend('Sub');
 var Mul = BinOp.extend('Mul');
 var Div = BinOp.extend('Div');
@@ -281,6 +282,7 @@ module.exports = {
     And: And,
     Not: Not,
     Add: Add,
+    Concat: Concat,
     Sub: Sub,
     Mul: Mul,
     Div: Div,
diff --git a/src/parser.js b/src/parser.js
index f0af7da..c979405 100644
--- a/src/parser.js
+++ b/src/parser.js
@@ -747,7 +747,7 @@ var Parser = Object.extend({
 
     parseCompare: function() {
         var compareOps = ['==', '!=', '<', '>', '<=', '>='];
-        var expr = this.parseAdd();
+        var expr = this.parseConcat();
         var ops = [];
 
         while(1) {
@@ -759,7 +759,7 @@ var Parser = Object.extend({
             else if(lib.indexOf(compareOps, tok.value) !== -1) {
                 ops.push(new nodes.CompareOperand(tok.lineno,
                                                   tok.colno,
-                                                  this.parseAdd(),
+                                                  this.parseConcat(),
                                                   tok.value));
             }
             else {
@@ -779,6 +779,19 @@ var Parser = Object.extend({
         }
     },
 
+    // finds the '~' for string concatenation
+    parseConcat: function(){
+        var node = this.parseAdd();
+        while(this.skipValue(lexer.TOKEN_TILDE, '~')) {
+            var node2 = this.parseAdd();
+            node = new nodes.Concat(node.lineno,
+                                 node.colno,
+                                 node,
+                                 node2);
+        }
+        return node;
+    },
+
     parseAdd: function() {
         var node = this.parseSub();
         while(this.skipValue(lexer.TOKEN_OPERATOR, '+')) {


Test patch:
diff --git a/tests/compiler.js b/tests/compiler.js
index 5879e14..9bf559d 100644
--- a/tests/compiler.js
+++ b/tests/compiler.js
@@ -387,6 +387,13 @@
             finish(done);
         });
 
+        it('should compile string concatenations with tilde', function(done){
+            equal('{{ 4 ~ \'hello\' }}', '4hello');
+            equal('{{ 4 ~ 5 }}', '45');
+            equal('{{ \'a\' ~ \'b\' ~ 5 }}', 'ab5');
+            finish(done);
+        });
+
         it('should compile macros', function(done) {
             equal('{% macro foo() %}This is a macro{% endmacro %}' +
                   '{{ foo() }}',
diff --git a/tests/parser.js b/tests/parser.js
index eb047e6..b99b749 100644
--- a/tests/parser.js
+++ b/tests/parser.js
@@ -235,6 +235,17 @@
                       [nodes.Symbol, 'y']]]]]);
         });
 
+        it('should parse tilde', function(){
+            isAST(parser.parse('{{ 2 ~ 3 }}'),
+              [nodes.Root,
+               [nodes.Output,
+                [nodes.Concat,
+                  [nodes.Literal, 2],
+                  [nodes.Literal, 3]
+                ]]]
+              );
+        });
+
         it('should parse operators with correct precedence', function() {
             isAST(parser.parse('{{ x in y and z }}'),
                   [nodes.Root,