Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

nunjucks

Package Overview
Dependencies
Maintainers
2
Versions
58
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nunjucks - npm Package Compare versions

Comparing version 1.3.0 to 1.3.1

docs/files/tests/express-sample/js/nunjucks-slim.js

2

bower.json
{
"name": "nunjucks",
"version": "1.0.5",
"version": "1.3.1",
"main": "browser/nunjucks.min.js",

@@ -5,0 +5,0 @@ "ignore": [

@@ -1,2 +0,2 @@

// Browser bundle of nunjucks 1.3.0 (slim, only works with precompiled templates)
// Browser bundle of nunjucks 1.3.1 (slim, only works with precompiled templates)

@@ -800,4 +800,2 @@ (function() {

(function() {
'use strict';
if(typeof window === 'undefined' || window !== this) {

@@ -804,0 +802,0 @@ modules['loaders'] = modules["node-loaders"];

@@ -1,3 +0,3 @@

// Browser bundle of nunjucks 1.3.0 (slim, only works with precompiled templates)
// Browser bundle of nunjucks 1.3.1 (slim, only works with precompiled templates)
(function(){var modules={};(function(){"use strict";function extend(cls,name,props){var F=function(){};F.prototype=cls.prototype;var prototype=new F;var fnTest=/xyz/.test(function(){xyz})?/\bparent\b/:/.*/;props=props||{};for(var k in props){var src=props[k];var parent=prototype[k];if(typeof parent==="function"&&typeof src==="function"&&fnTest.test(src)){prototype[k]=function(src,parent){return function(){var tmp=this.parent;this.parent=parent;var res=src.apply(this,arguments);this.parent=tmp;return res}}(src,parent)}else{prototype[k]=src}}prototype.typename=name;var new_cls=function(){if(prototype.init){prototype.init.apply(this,arguments)}};new_cls.prototype=prototype;new_cls.prototype.constructor=new_cls;new_cls.extend=function(name,props){if(typeof name==="object"){props=name;name="anonymous"}return extend(new_cls,name,props)};return new_cls}modules["object"]=extend(Object,"Object",{})})();(function(){"use strict";var ArrayProto=Array.prototype;var ObjProto=Object.prototype;var escapeMap={"&":"&amp;",'"':"&quot;","'":"&#39;","<":"&lt;",">":"&gt;"};var escapeRegex=/[&"'<>]/g;var lookupEscape=function(ch){return escapeMap[ch]};var exports=modules["lib"]={};exports.withPrettyErrors=function(path,withInternals,func){try{return func()}catch(e){if(!e.Update){e=new exports.TemplateError(e)}e.Update(path);if(!withInternals){var old=e;e=new Error(old.message);e.name=old.name}throw e}};exports.TemplateError=function(message,lineno,colno){var err=this;if(message instanceof Error){err=message;message=message.name+": "+message.message}else{if(Error.captureStackTrace){Error.captureStackTrace(err)}}err.name="Template render error";err.message=message;err.lineno=lineno;err.colno=colno;err.firstUpdate=true;err.Update=function(path){var message="("+(path||"unknown path")+")";if(this.firstUpdate){if(this.lineno&&this.colno){message+=" [Line "+this.lineno+", Column "+this.colno+"]"}else if(this.lineno){message+=" [Line "+this.lineno+"]"}}message+="\n ";if(this.firstUpdate){message+=" "}this.message=message+(this.message||"");this.firstUpdate=false;return this};return err};exports.TemplateError.prototype=Error.prototype;exports.escape=function(val){return val.replace(escapeRegex,lookupEscape)};exports.isFunction=function(obj){return ObjProto.toString.call(obj)==="[object Function]"};exports.isArray=Array.isArray||function(obj){return ObjProto.toString.call(obj)==="[object Array]"};exports.isString=function(obj){return ObjProto.toString.call(obj)==="[object String]"};exports.isObject=function(obj){return ObjProto.toString.call(obj)==="[object Object]"};exports.groupBy=function(obj,val){var result={};var iterator=exports.isFunction(val)?val:function(obj){return obj[val]};for(var i=0;i<obj.length;i++){var value=obj[i];var key=iterator(value,i);(result[key]||(result[key]=[])).push(value)}return result};exports.toArray=function(obj){return Array.prototype.slice.call(obj)};exports.without=function(array){var result=[];if(!array){return result}var index=-1,length=array.length,contains=exports.toArray(arguments).slice(1);while(++index<length){if(exports.indexOf(contains,array[index])===-1){result.push(array[index])}}return result};exports.extend=function(obj,obj2){for(var k in obj2){obj[k]=obj2[k]}return obj};exports.repeat=function(char_,n){var str="";for(var i=0;i<n;i++){str+=char_}return str};exports.each=function(obj,func,context){if(obj==null){return}if(ArrayProto.each&&obj.each===ArrayProto.each){obj.forEach(func,context)}else if(obj.length===+obj.length){for(var i=0,l=obj.length;i<l;i++){func.call(context,obj[i],i,obj)}}};exports.map=function(obj,func){var results=[];if(obj==null){return results}if(ArrayProto.map&&obj.map===ArrayProto.map){return obj.map(func)}for(var i=0;i<obj.length;i++){results[results.length]=func(obj[i],i)}if(obj.length===+obj.length){results.length=obj.length}return results};exports.asyncIter=function(arr,iter,cb){var i=-1;function next(){i++;if(i<arr.length){iter(arr[i],i,next,cb)}else{cb()}}next()};exports.asyncFor=function(obj,iter,cb){var keys=exports.keys(obj);var len=keys.length;var i=-1;function next(){i++;var k=keys[i];if(i<len){iter(k,obj[k],i,len,next)}else{cb()}}next()};exports.indexOf=Array.prototype.indexOf?function(arr,searchElement,fromIndex){return Array.prototype.indexOf.call(arr,searchElement,fromIndex)}:function(arr,searchElement,fromIndex){var length=this.length>>>0;fromIndex=+fromIndex||0;if(Math.abs(fromIndex)===Infinity){fromIndex=0}if(fromIndex<0){fromIndex+=length;if(fromIndex<0){fromIndex=0}}for(;fromIndex<length;fromIndex++){if(arr[fromIndex]===searchElement){return fromIndex}}return-1};if(!Array.prototype.map){Array.prototype.map=function(){throw new Error("map is unimplemented for this js engine")}}exports.keys=function(obj){if(Object.prototype.keys){return obj.keys()}else{var keys=[];for(var k in obj){if(obj.hasOwnProperty(k)){keys.push(k)}}return keys}}})();(function(){"use strict";var lib=modules["lib"];var Obj=modules["object"];var Frame=Obj.extend({init:function(parent){this.variables={};this.parent=parent},set:function(name,val,resolveUp){var parts=name.split(".");var obj=this.variables;var frame=this;if(resolveUp){if(frame=this.resolve(parts[0])){frame.set(name,val);return}frame=this}for(var i=0;i<parts.length-1;i++){var id=parts[i];if(!obj[id]){obj[id]={}}obj=obj[id]}obj[parts[parts.length-1]]=val},get:function(name){var val=this.variables[name];if(val!==undefined&&val!==null){return val}return null},lookup:function(name){var p=this.parent;var val=this.variables[name];if(val!==undefined&&val!==null){return val}return p&&p.lookup(name)},resolve:function(name){var p=this.parent;var val=this.variables[name];if(val!==undefined&&val!==null){return this}return p&&p.resolve(name)},push:function(){return new Frame(this)},pop:function(){return this.parent}});function makeMacro(argNames,kwargNames,func){return function(){var argCount=numArgs(arguments);var args;var kwargs=getKeywordArgs(arguments);if(argCount>argNames.length){args=Array.prototype.slice.call(arguments,0,argNames.length);var vals=Array.prototype.slice.call(arguments,args.length,argCount);for(var i=0;i<vals.length;i++){if(i<kwargNames.length){kwargs[kwargNames[i]]=vals[i]}}args.push(kwargs)}else if(argCount<argNames.length){args=Array.prototype.slice.call(arguments,0,argCount);for(var i=argCount;i<argNames.length;i++){var arg=argNames[i];args.push(kwargs[arg]);delete kwargs[arg]}args.push(kwargs)}else{args=arguments}return func.apply(this,args)}}function makeKeywordArgs(obj){obj.__keywords=true;return obj}function getKeywordArgs(args){var len=args.length;if(len){var lastArg=args[len-1];if(lastArg&&lastArg.hasOwnProperty("__keywords")){return lastArg}}return{}}function numArgs(args){var len=args.length;if(len===0){return 0}var lastArg=args[len-1];if(lastArg&&lastArg.hasOwnProperty("__keywords")){return len-1}else{return len}}function SafeString(val){if(typeof val!=="string"){return val}this.val=val}SafeString.prototype=Object.create(String.prototype);SafeString.prototype.valueOf=function(){return this.val};SafeString.prototype.toString=function(){return this.val};function copySafeness(dest,target){if(dest instanceof SafeString){return new SafeString(target)}return target.toString()}function markSafe(val){var type=typeof val;if(type==="string"){return new SafeString(val)}else if(type!=="function"){return val}else{return function(){var ret=val.apply(this,arguments);if(typeof ret==="string"){return new SafeString(ret)}return ret}}}function suppressValue(val,autoescape){val=val!==undefined&&val!==null?val:"";if(autoescape&&typeof val==="string"){val=lib.escape(val)}return val}function memberLookup(obj,val){obj=obj||{};if(typeof obj[val]==="function"){return function(){return obj[val].apply(obj,arguments)}}return obj[val]}function callWrap(obj,name,args){if(!obj){throw new Error("Unable to call `"+name+"`, which is undefined or falsey")}else if(typeof obj!=="function"){throw new Error("Unable to call `"+name+"`, which is not a function")}return obj.apply(this,args)}function contextOrFrameLookup(context,frame,name){var val=frame.lookup(name);return val!==undefined&&val!==null?val:context.lookup(name)}function handleError(error,lineno,colno){if(error.lineno){return error}else{return new lib.TemplateError(error,lineno,colno)}}function asyncEach(arr,dimen,iter,cb){if(lib.isArray(arr)){var len=arr.length;lib.asyncIter(arr,function(item,i,next){switch(dimen){case 1:iter(item,i,len,next);break;case 2:iter(item[0],item[1],i,len,next);break;case 3:iter(item[0],item[1],item[2],i,len,next);break;default:item.push(i,next);iter.apply(this,item)}},cb)}else{lib.asyncFor(arr,function(key,val,i,len,next){iter(key,val,i,len,next)},cb)}}function asyncAll(arr,dimen,func,cb){var finished=0;var len;var outputArr;function done(i,output){finished++;outputArr[i]=output;if(finished===len){cb(null,outputArr.join(""))}}if(lib.isArray(arr)){len=arr.length;outputArr=new Array(len);if(len===0){cb(null,"")}else{for(var i=0;i<arr.length;i++){var item=arr[i];switch(dimen){case 1:func(item,i,len,done);break;case 2:func(item[0],item[1],i,len,done);break;case 3:func(item[0],item[1],item[2],i,len,done);break;default:item.push(i,done);func.apply(this,item)}}}}else{var keys=lib.keys(arr);len=keys.length;outputArr=new Array(len);if(len===0){cb(null,"")}else{for(var i=0;i<keys.length;i++){var k=keys[i];func(k,arr[k],i,len,done)}}}}modules["runtime"]={Frame:Frame,makeMacro:makeMacro,makeKeywordArgs:makeKeywordArgs,numArgs:numArgs,suppressValue:suppressValue,memberLookup:memberLookup,contextOrFrameLookup:contextOrFrameLookup,callWrap:callWrap,handleError:handleError,isArray:lib.isArray,keys:lib.keys,SafeString:SafeString,copySafeness:copySafeness,markSafe:markSafe,asyncEach:asyncEach,asyncAll:asyncAll}})();(function(){"use strict";var path=modules["path"];var Obj=modules["object"];var lib=modules["lib"];var Loader=Obj.extend({on:function(name,func){this.listeners=this.listeners||{};this.listeners[name]=this.listeners[name]||[];this.listeners[name].push(func)},emit:function(name){var args=Array.prototype.slice.call(arguments,1);if(this.listeners&&this.listeners[name]){lib.each(this.listeners[name],function(listener){listener.apply(null,args)})}},resolve:function(from,to){return path.resolve(path.dirname(from),to)},isRelative:function(filename){return filename.indexOf("./")===0||filename.indexOf("../")===0}});modules["loader"]=Loader})();(function(){"use strict";var Loader=modules["loader"];var WebLoader=Loader.extend({init:function(baseURL,neverUpdate){this.precompiled=window.nunjucksPrecompiled||{};this.baseURL=baseURL||"";this.neverUpdate=neverUpdate},getSource:function(name){if(this.precompiled[name]){return{src:{type:"code",obj:this.precompiled[name]},path:name}}else{var src=this.fetch(this.baseURL+"/"+name);if(!src){return null}return{src:src,path:name,noCache:!this.neverUpdate}}},fetch:function(url,callback){var ajax;var loading=true;var src;if(window.XMLHttpRequest){ajax=new XMLHttpRequest}else if(window.ActiveXObject){ajax=new ActiveXObject("Microsoft.XMLHTTP")}ajax.onreadystatechange=function(){if(ajax.readyState===4&&(ajax.status===0||ajax.status===200)&&loading){loading=false;src=ajax.responseText}};url+=(url.indexOf("?")===-1?"?":"&")+"s="+(new Date).getTime();ajax.open("GET",url,false);ajax.send();return src}});modules["web-loaders"]={WebLoader:WebLoader}})();(function(){"use strict";if(typeof window==="undefined"||window!==this){modules["loaders"]=modules["node-loaders"]}else{modules["loaders"]=modules["web-loaders"]}})();(function(){"use strict";var lib=modules["lib"];var r=modules["runtime"];var filters={abs:function(n){return Math.abs(n)},batch:function(arr,linecount,fill_with){var res=[];var tmp=[];for(var i=0;i<arr.length;i++){if(i%linecount===0&&tmp.length){res.push(tmp);tmp=[]}tmp.push(arr[i])}if(tmp.length){if(fill_with){for(var i=tmp.length;i<linecount;i++){tmp.push(fill_with)}}res.push(tmp)}return res},capitalize:function(str){var ret=str.toLowerCase();return r.copySafeness(str,ret.charAt(0).toUpperCase()+ret.slice(1))},center:function(str,width){width=width||80;if(str.length>=width){return str}var spaces=width-str.length;var pre=lib.repeat(" ",spaces/2-spaces%2);var post=lib.repeat(" ",spaces/2);return r.copySafeness(str,pre+str+post)},"default":function(val,def){return val?val:def},dictsort:function(val,case_sensitive,by){if(!lib.isObject(val)){throw new lib.TemplateError("dictsort filter: val must be an object")}var array=[];for(var k in val){array.push([k,val[k]])}var si;if(by===undefined||by==="key"){si=0}else if(by==="value"){si=1}else{throw new lib.TemplateError("dictsort filter: You can only sort by either key or value")}array.sort(function(t1,t2){var a=t1[si];var b=t2[si];if(!case_sensitive){if(lib.isString(a)){a=a.toUpperCase()}if(lib.isString(b)){b=b.toUpperCase()}}return a>b?1:a===b?0:-1});return array},escape:function(str){if(typeof str==="string"||str instanceof r.SafeString){return lib.escape(str)}return str},safe:function(str){return r.markSafe(str)},first:function(arr){return arr[0]},groupby:function(arr,attr){return lib.groupBy(arr,attr)},indent:function(str,width,indentfirst){width=width||4;var res="";var lines=str.split("\n");var sp=lib.repeat(" ",width);for(var i=0;i<lines.length;i++){if(i===0&&!indentfirst){res+=lines[i]+"\n"}else{res+=sp+lines[i]+"\n"}}return r.copySafeness(str,res)},join:function(arr,del,attr){del=del||"";if(attr){arr=lib.map(arr,function(v){return v[attr]})}return arr.join(del)},last:function(arr){return arr[arr.length-1]},length:function(arr){return arr!==undefined?arr.length:0},list:function(val){if(lib.isString(val)){return val.split("")}else if(lib.isObject(val)){var keys=[];if(Object.keys){keys=Object.keys(val)}else{for(var k in val){keys.push(k)}}return lib.map(keys,function(k){return{key:k,value:val[k]}})}else if(lib.isArray(val)){return val}else{throw new lib.TemplateError("list filter: type not iterable")}},lower:function(str){return str.toLowerCase()},random:function(arr){return arr[Math.floor(Math.random()*arr.length)]},rejectattr:function(arr,attr){return arr.filter(function(item){return!item[attr]})},selectattr:function(arr,attr){return arr.filter(function(item){return!!item[attr]})},replace:function(str,old,new_,maxCount){if(old instanceof RegExp){return str.replace(old,new_)}var res=str;var last=res;var count=1;res=res.replace(old,new_);while(last!==res){if(count>=maxCount){break}last=res;res=res.replace(old,new_);count++}return r.copySafeness(str,res)},reverse:function(val){var arr;if(lib.isString(val)){arr=filters.list(val)}else{arr=lib.map(val,function(v){return v})}arr.reverse();if(lib.isString(val)){return r.copySafeness(val,arr.join(""))}return arr},round:function(val,precision,method){precision=precision||0;var factor=Math.pow(10,precision);var rounder;if(method==="ceil"){rounder=Math.ceil}else if(method==="floor"){rounder=Math.floor}else{rounder=Math.round}return rounder(val*factor)/factor},slice:function(arr,slices,fillWith){var sliceLength=Math.floor(arr.length/slices);var extra=arr.length%slices;var offset=0;var res=[];for(var i=0;i<slices;i++){var start=offset+i*sliceLength;if(i<extra){offset++}var end=offset+(i+1)*sliceLength;var slice=arr.slice(start,end);if(fillWith&&i>=extra){slice.push(fillWith)}res.push(slice)}return res},sort:function(arr,reverse,caseSens,attr){arr=lib.map(arr,function(v){return v});arr.sort(function(a,b){var x,y;if(attr){x=a[attr];y=b[attr]}else{x=a;y=b}if(!caseSens&&lib.isString(x)&&lib.isString(y)){x=x.toLowerCase();y=y.toLowerCase()}if(x<y){return reverse?1:-1}else if(x>y){return reverse?-1:1}else{return 0}});return arr},string:function(obj){return r.copySafeness(obj,obj)},title:function(str){var words=str.split(" ");for(var i=0;i<words.length;i++){words[i]=filters.capitalize(words[i])}return r.copySafeness(str,words.join(" "))},trim:function(str){return r.copySafeness(str,str.replace(/^\s*|\s*$/g,""))},truncate:function(input,length,killwords,end){var orig=input;length=length||255;if(input.length<=length)return input;if(killwords){input=input.substring(0,length)}else{var idx=input.lastIndexOf(" ",length);if(idx===-1){idx=length}input=input.substring(0,idx)}input+=end!==undefined&&end!==null?end:"...";return r.copySafeness(orig,input)},upper:function(str){return str.toUpperCase()},urlencode:function(obj){var enc=encodeURIComponent;if(lib.isString(obj)){return enc(obj)}else{var parts;if(lib.isArray(obj)){parts=obj.map(function(item){return enc(item[0])+"="+enc(item[1])})}else{parts=[];for(var k in obj){if(obj.hasOwnProperty(k)){parts.push(enc(k)+"="+enc(obj[k]))}}}return parts.join("&")}},urlize:function(str,length,nofollow){if(isNaN(length))length=Infinity;var noFollowAttr=nofollow===true?' rel="nofollow"':"";var puncRE=/^(?:\(|<|&lt;)?(.*?)(?:\.|,|\)|\n|&gt;)?$/;var emailRE=/^[\w.!#$%&'*+\-\/=?\^`{|}~]+@[a-z\d\-]+(\.[a-z\d\-]+)+$/i;var httpHttpsRE=/^https?:\/\/.*$/;var wwwRE=/^www\./;var tldRE=/\.(?:org|net|com)(?:\:|\/|$)/;var words=str.split(/\s+/).filter(function(word){return word&&word.length}).map(function(word){var matches=word.match(puncRE);var possibleUrl=matches&&matches[1]||word;if(httpHttpsRE.test(possibleUrl))return'<a href="'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";if(wwwRE.test(possibleUrl))return'<a href="http://'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";if(emailRE.test(possibleUrl))return'<a href="mailto:'+possibleUrl+'">'+possibleUrl+"</a>";if(tldRE.test(possibleUrl))return'<a href="http://'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";return word});return words.join(" ")},wordcount:function(str){var words=str?str.match(/\w+/g):null;return words?words.length:null},"float":function(val,def){var res=parseFloat(val);return isNaN(res)?def:res},"int":function(val,def){var res=parseInt(val,10);return isNaN(res)?def:res}};filters.d=filters["default"];filters.e=filters.escape;modules["filters"]=filters})();(function(){"use strict";function cycler(items){var index=-1;return{current:null,reset:function(){index=-1;this.current=null},next:function(){index++;if(index>=items.length){index=0}this.current=items[index];return this.current}}}function joiner(sep){sep=sep||",";var first=true;return function(){var val=first?"":sep;first=false;return val}}var globals={range:function(start,stop,step){if(!stop){stop=start;start=0;step=1}else if(!step){step=1}var arr=[];for(var i=start;i<stop;i+=step){arr.push(i)}return arr},cycler:function(){return cycler(Array.prototype.slice.call(arguments))},joiner:function(sep){return joiner(sep)}};modules["globals"]=globals})();(function(){"use strict";var path=modules["path"];var lib=modules["lib"];var Obj=modules["object"];var lexer=modules["lexer"];var compiler=modules["compiler"];var builtin_filters=modules["filters"];var builtin_loaders=modules["loaders"];var runtime=modules["runtime"];var globals=modules["globals"];var Frame=runtime.Frame;var Environment=Obj.extend({init:function(loaders,opts){var opts=this.opts=opts||{};this.opts.dev=!!opts.dev;this.opts.autoescape=!!opts.autoescape;this.opts.trimBlocks=!!opts.trimBlocks;this.opts.lstripBlocks=!!opts.lstripBlocks;if(!loaders){if(builtin_loaders.FileSystemLoader){this.loaders=[new builtin_loaders.FileSystemLoader("views")]}else{this.loaders=[new builtin_loaders.WebLoader("/views")]}}else{this.loaders=lib.isArray(loaders)?loaders:[loaders]}this.initCache();this.filters={};this.asyncFilters=[];this.extensions={};this.extensionsList=[];for(var name in builtin_filters){this.addFilter(name,builtin_filters[name])}},initCache:function(){lib.each(this.loaders,function(loader){loader.cache={};if(typeof loader.on==="function"){loader.on("update",function(template){loader.cache[template]=null})}})},addExtension:function(name,extension){extension._name=name;this.extensions[name]=extension;this.extensionsList.push(extension)},getExtension:function(name){return this.extensions[name]},addGlobal:function(name,value){globals[name]=value},addFilter:function(name,func,async){var wrapped=func;if(async){this.asyncFilters.push(name)}this.filters[name]=wrapped},getFilter:function(name){if(!this.filters[name]){throw new Error("filter not found: "+name)}return this.filters[name]},resolveTemplate:function(loader,parentName,filename){var isRelative=loader.isRelative&&parentName?loader.isRelative(filename):false;return isRelative&&loader.resolve?loader.resolve(parentName,filename):filename},getTemplate:function(name,eagerCompile,parentName,cb){var that=this;var tmpl=null;if(name&&name.raw){name=name.raw}if(lib.isFunction(parentName)){cb=parentName;parentName=null;eagerCompile=eagerCompile||false}if(lib.isFunction(eagerCompile)){cb=eagerCompile;eagerCompile=false}if(typeof name!=="string"){throw new Error("template names must be a string: "+name)}for(var i=0;i<this.loaders.length;i++){var _name=this.resolveTemplate(this.loaders[i],parentName,name);tmpl=this.loaders[i].cache[_name];if(tmpl)break}if(tmpl){if(eagerCompile){tmpl.compile()}if(cb){cb(null,tmpl)}else{return tmpl}}else{var syncResult;lib.asyncIter(this.loaders,function(loader,i,next,done){function handle(src){if(src){src.loader=loader;done(src)}else{next()}}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){cb(err)}else{throw err}}else{var tmpl=new Template(info.src,this,info.path,eagerCompile);if(!info.noCache){info.loader.cache[name]=tmpl}if(cb){cb(null,tmpl)}else{syncResult=tmpl}}}.bind(this));return syncResult}},express:function(app){var env=this;function NunjucksView(name,opts){this.name=name;this.path=name;this.defaultEngine=opts.defaultEngine;this.ext=path.extname(name);if(!this.ext&&!this.defaultEngine)throw new Error("No default engine was specified and no extension was provided.");if(!this.ext)this.name+=this.ext=("."!==this.defaultEngine[0]?".":"")+this.defaultEngine}NunjucksView.prototype.render=function(opts,cb){env.render(this.name,opts,cb)};app.set("view",NunjucksView)},render:function(name,ctx,cb){if(lib.isFunction(ctx)){cb=ctx;ctx=null}var syncResult=null;this.getTemplate(name,function(err,tmpl){if(err&&cb){cb(err)}else if(err){throw err}else{tmpl.render(ctx,cb||function(err,res){if(err){throw err}syncResult=res})}});return syncResult},renderString:function(src,ctx,opts,cb){if(lib.isFunction(opts)){cb=opts;opts={}}opts=opts||{};var tmpl=new Template(src,this,opts.path);return tmpl.render(ctx,cb)}});var Context=Obj.extend({init:function(ctx,blocks){this.ctx=ctx;this.blocks={};this.exported=[];for(var name in blocks){this.addBlock(name,blocks[name])}},lookup:function(name){if(name in globals&&!(name in this.ctx)){return globals[name]}else{return this.ctx[name]}},setVariable:function(name,val){this.ctx[name]=val},getVariables:function(){return this.ctx},addBlock:function(name,block){this.blocks[name]=this.blocks[name]||[];this.blocks[name].push(block)},getBlock:function(name){if(!this.blocks[name]){throw new Error('unknown block "'+name+'"')}return this.blocks[name][0]},getSuper:function(env,name,block,frame,runtime,cb){var idx=lib.indexOf(this.blocks[name]||[],block);var blk=this.blocks[name][idx+1];var context=this;if(idx===-1||!blk){throw new Error('no super block available for "'+name+'"')}blk(env,context,frame,runtime,cb)},addExport:function(name){this.exported.push(name)},getExported:function(){var exported={};for(var i=0;i<this.exported.length;i++){var name=this.exported[i];exported[name]=this.ctx[name]}return exported}});var Template=Obj.extend({init:function(src,env,path,eagerCompile){this.env=env||new Environment;if(lib.isObject(src)){switch(src.type){case"code":this.tmplProps=src.obj;break;case"string":this.tmplStr=src.obj;break}}else if(lib.isString(src)){this.tmplStr=src}else{throw new Error("src must be a string or an object describing "+"the source")}this.path=path;if(eagerCompile){lib.withPrettyErrors(this.path,this.env.dev,this._compile.bind(this))}else{this.compiled=false}},render:function(ctx,frame,cb){if(typeof ctx==="function"){cb=ctx;ctx={}}else if(typeof frame==="function"){cb=frame;frame=null}return lib.withPrettyErrors(this.path,this.env.dev,function(){try{this.compile()}catch(e){if(cb)return cb(e);else throw e}var context=new Context(ctx||{},this.blocks);var syncResult=null;this.rootRenderFunc(this.env,context,frame||new Frame,runtime,cb||function(err,res){if(err){throw err}syncResult=res});return syncResult}.bind(this))},getExported:function(ctx,frame,cb){if(typeof ctx==="function"){cb=ctx;ctx={}}if(typeof frame==="function"){cb=frame;frame=null}try{this.compile()}catch(e){if(cb)return cb(e);else throw e}var context=new Context(ctx||{},this.blocks);this.rootRenderFunc(this.env,context,frame||new Frame,runtime,function(){cb(null,context.getExported())})},compile:function(){if(!this.compiled){this._compile()}},_compile:function(){var props;if(this.tmplProps){props=this.tmplProps}else{var source=compiler.compile(this.tmplStr,this.env.asyncFilters,this.env.extensionsList,this.path,this.env.opts);var func=new Function(source);props=func()}this.blocks=this._getBlocks(props);this.rootRenderFunc=props.root;this.compiled=true},_getBlocks:function(props){var blocks={};for(var k in props){if(k.slice(0,2)==="b_"){blocks[k.slice(2)]=props[k]}}return blocks}});modules["environment"]={Environment:Environment,Template:Template}})();var nunjucks;var lib=modules["lib"];var env=modules["environment"];var compiler=modules["compiler"];var parser=modules["parser"];var lexer=modules["lexer"];var runtime=modules["runtime"];var Loader=modules["loader"];var loaders=modules["loaders"];var precompile=modules["precompile"];nunjucks={};nunjucks.Environment=env.Environment;nunjucks.Template=env.Template;nunjucks.Loader=Loader;nunjucks.FileSystemLoader=loaders.FileSystemLoader;nunjucks.WebLoader=loaders.WebLoader;nunjucks.compiler=compiler;nunjucks.parser=parser;nunjucks.lexer=lexer;nunjucks.runtime=runtime;var e;nunjucks.configure=function(templatesPath,opts){opts=opts||{};if(lib.isObject(templatesPath)){opts=templatesPath;templatesPath=null}var noWatch="watch"in opts?!opts.watch:false;var loader=loaders.FileSystemLoader||loaders.WebLoader;e=new env.Environment(new loader(templatesPath,noWatch),opts);if(opts&&opts.express){e.express(opts.express)}return e};nunjucks.compile=function(src,env,path,eagerCompile){if(!e){nunjucks.configure()}return new nunjucks.Template(src,env,path,eagerCompile)};nunjucks.render=function(name,ctx,cb){if(!e){nunjucks.configure()}return e.render(name,ctx,cb)};nunjucks.renderString=function(src,ctx,cb){if(!e){nunjucks.configure()}return e.renderString(src,ctx,cb)};if(precompile){nunjucks.precompile=precompile.precompile;nunjucks.precompileString=precompile.precompileString}nunjucks.require=function(name){return modules[name]};if(typeof define==="function"&&define.amd){define(function(){return nunjucks})}else{window.nunjucks=nunjucks;if(typeof module!=="undefined")module.exports=nunjucks}})();
(function(){var modules={};(function(){"use strict";function extend(cls,name,props){var F=function(){};F.prototype=cls.prototype;var prototype=new F;var fnTest=/xyz/.test(function(){xyz})?/\bparent\b/:/.*/;props=props||{};for(var k in props){var src=props[k];var parent=prototype[k];if(typeof parent==="function"&&typeof src==="function"&&fnTest.test(src)){prototype[k]=function(src,parent){return function(){var tmp=this.parent;this.parent=parent;var res=src.apply(this,arguments);this.parent=tmp;return res}}(src,parent)}else{prototype[k]=src}}prototype.typename=name;var new_cls=function(){if(prototype.init){prototype.init.apply(this,arguments)}};new_cls.prototype=prototype;new_cls.prototype.constructor=new_cls;new_cls.extend=function(name,props){if(typeof name==="object"){props=name;name="anonymous"}return extend(new_cls,name,props)};return new_cls}modules["object"]=extend(Object,"Object",{})})();(function(){"use strict";var ArrayProto=Array.prototype;var ObjProto=Object.prototype;var escapeMap={"&":"&amp;",'"':"&quot;","'":"&#39;","<":"&lt;",">":"&gt;"};var escapeRegex=/[&"'<>]/g;var lookupEscape=function(ch){return escapeMap[ch]};var exports=modules["lib"]={};exports.withPrettyErrors=function(path,withInternals,func){try{return func()}catch(e){if(!e.Update){e=new exports.TemplateError(e)}e.Update(path);if(!withInternals){var old=e;e=new Error(old.message);e.name=old.name}throw e}};exports.TemplateError=function(message,lineno,colno){var err=this;if(message instanceof Error){err=message;message=message.name+": "+message.message}else{if(Error.captureStackTrace){Error.captureStackTrace(err)}}err.name="Template render error";err.message=message;err.lineno=lineno;err.colno=colno;err.firstUpdate=true;err.Update=function(path){var message="("+(path||"unknown path")+")";if(this.firstUpdate){if(this.lineno&&this.colno){message+=" [Line "+this.lineno+", Column "+this.colno+"]"}else if(this.lineno){message+=" [Line "+this.lineno+"]"}}message+="\n ";if(this.firstUpdate){message+=" "}this.message=message+(this.message||"");this.firstUpdate=false;return this};return err};exports.TemplateError.prototype=Error.prototype;exports.escape=function(val){return val.replace(escapeRegex,lookupEscape)};exports.isFunction=function(obj){return ObjProto.toString.call(obj)==="[object Function]"};exports.isArray=Array.isArray||function(obj){return ObjProto.toString.call(obj)==="[object Array]"};exports.isString=function(obj){return ObjProto.toString.call(obj)==="[object String]"};exports.isObject=function(obj){return ObjProto.toString.call(obj)==="[object Object]"};exports.groupBy=function(obj,val){var result={};var iterator=exports.isFunction(val)?val:function(obj){return obj[val]};for(var i=0;i<obj.length;i++){var value=obj[i];var key=iterator(value,i);(result[key]||(result[key]=[])).push(value)}return result};exports.toArray=function(obj){return Array.prototype.slice.call(obj)};exports.without=function(array){var result=[];if(!array){return result}var index=-1,length=array.length,contains=exports.toArray(arguments).slice(1);while(++index<length){if(exports.indexOf(contains,array[index])===-1){result.push(array[index])}}return result};exports.extend=function(obj,obj2){for(var k in obj2){obj[k]=obj2[k]}return obj};exports.repeat=function(char_,n){var str="";for(var i=0;i<n;i++){str+=char_}return str};exports.each=function(obj,func,context){if(obj==null){return}if(ArrayProto.each&&obj.each===ArrayProto.each){obj.forEach(func,context)}else if(obj.length===+obj.length){for(var i=0,l=obj.length;i<l;i++){func.call(context,obj[i],i,obj)}}};exports.map=function(obj,func){var results=[];if(obj==null){return results}if(ArrayProto.map&&obj.map===ArrayProto.map){return obj.map(func)}for(var i=0;i<obj.length;i++){results[results.length]=func(obj[i],i)}if(obj.length===+obj.length){results.length=obj.length}return results};exports.asyncIter=function(arr,iter,cb){var i=-1;function next(){i++;if(i<arr.length){iter(arr[i],i,next,cb)}else{cb()}}next()};exports.asyncFor=function(obj,iter,cb){var keys=exports.keys(obj);var len=keys.length;var i=-1;function next(){i++;var k=keys[i];if(i<len){iter(k,obj[k],i,len,next)}else{cb()}}next()};exports.indexOf=Array.prototype.indexOf?function(arr,searchElement,fromIndex){return Array.prototype.indexOf.call(arr,searchElement,fromIndex)}:function(arr,searchElement,fromIndex){var length=this.length>>>0;fromIndex=+fromIndex||0;if(Math.abs(fromIndex)===Infinity){fromIndex=0}if(fromIndex<0){fromIndex+=length;if(fromIndex<0){fromIndex=0}}for(;fromIndex<length;fromIndex++){if(arr[fromIndex]===searchElement){return fromIndex}}return-1};if(!Array.prototype.map){Array.prototype.map=function(){throw new Error("map is unimplemented for this js engine")}}exports.keys=function(obj){if(Object.prototype.keys){return obj.keys()}else{var keys=[];for(var k in obj){if(obj.hasOwnProperty(k)){keys.push(k)}}return keys}}})();(function(){"use strict";var lib=modules["lib"];var Obj=modules["object"];var Frame=Obj.extend({init:function(parent){this.variables={};this.parent=parent},set:function(name,val,resolveUp){var parts=name.split(".");var obj=this.variables;var frame=this;if(resolveUp){if(frame=this.resolve(parts[0])){frame.set(name,val);return}frame=this}for(var i=0;i<parts.length-1;i++){var id=parts[i];if(!obj[id]){obj[id]={}}obj=obj[id]}obj[parts[parts.length-1]]=val},get:function(name){var val=this.variables[name];if(val!==undefined&&val!==null){return val}return null},lookup:function(name){var p=this.parent;var val=this.variables[name];if(val!==undefined&&val!==null){return val}return p&&p.lookup(name)},resolve:function(name){var p=this.parent;var val=this.variables[name];if(val!==undefined&&val!==null){return this}return p&&p.resolve(name)},push:function(){return new Frame(this)},pop:function(){return this.parent}});function makeMacro(argNames,kwargNames,func){return function(){var argCount=numArgs(arguments);var args;var kwargs=getKeywordArgs(arguments);if(argCount>argNames.length){args=Array.prototype.slice.call(arguments,0,argNames.length);var vals=Array.prototype.slice.call(arguments,args.length,argCount);for(var i=0;i<vals.length;i++){if(i<kwargNames.length){kwargs[kwargNames[i]]=vals[i]}}args.push(kwargs)}else if(argCount<argNames.length){args=Array.prototype.slice.call(arguments,0,argCount);for(var i=argCount;i<argNames.length;i++){var arg=argNames[i];args.push(kwargs[arg]);delete kwargs[arg]}args.push(kwargs)}else{args=arguments}return func.apply(this,args)}}function makeKeywordArgs(obj){obj.__keywords=true;return obj}function getKeywordArgs(args){var len=args.length;if(len){var lastArg=args[len-1];if(lastArg&&lastArg.hasOwnProperty("__keywords")){return lastArg}}return{}}function numArgs(args){var len=args.length;if(len===0){return 0}var lastArg=args[len-1];if(lastArg&&lastArg.hasOwnProperty("__keywords")){return len-1}else{return len}}function SafeString(val){if(typeof val!=="string"){return val}this.val=val}SafeString.prototype=Object.create(String.prototype);SafeString.prototype.valueOf=function(){return this.val};SafeString.prototype.toString=function(){return this.val};function copySafeness(dest,target){if(dest instanceof SafeString){return new SafeString(target)}return target.toString()}function markSafe(val){var type=typeof val;if(type==="string"){return new SafeString(val)}else if(type!=="function"){return val}else{return function(){var ret=val.apply(this,arguments);if(typeof ret==="string"){return new SafeString(ret)}return ret}}}function suppressValue(val,autoescape){val=val!==undefined&&val!==null?val:"";if(autoescape&&typeof val==="string"){val=lib.escape(val)}return val}function memberLookup(obj,val){obj=obj||{};if(typeof obj[val]==="function"){return function(){return obj[val].apply(obj,arguments)}}return obj[val]}function callWrap(obj,name,args){if(!obj){throw new Error("Unable to call `"+name+"`, which is undefined or falsey")}else if(typeof obj!=="function"){throw new Error("Unable to call `"+name+"`, which is not a function")}return obj.apply(this,args)}function contextOrFrameLookup(context,frame,name){var val=frame.lookup(name);return val!==undefined&&val!==null?val:context.lookup(name)}function handleError(error,lineno,colno){if(error.lineno){return error}else{return new lib.TemplateError(error,lineno,colno)}}function asyncEach(arr,dimen,iter,cb){if(lib.isArray(arr)){var len=arr.length;lib.asyncIter(arr,function(item,i,next){switch(dimen){case 1:iter(item,i,len,next);break;case 2:iter(item[0],item[1],i,len,next);break;case 3:iter(item[0],item[1],item[2],i,len,next);break;default:item.push(i,next);iter.apply(this,item)}},cb)}else{lib.asyncFor(arr,function(key,val,i,len,next){iter(key,val,i,len,next)},cb)}}function asyncAll(arr,dimen,func,cb){var finished=0;var len;var outputArr;function done(i,output){finished++;outputArr[i]=output;if(finished===len){cb(null,outputArr.join(""))}}if(lib.isArray(arr)){len=arr.length;outputArr=new Array(len);if(len===0){cb(null,"")}else{for(var i=0;i<arr.length;i++){var item=arr[i];switch(dimen){case 1:func(item,i,len,done);break;case 2:func(item[0],item[1],i,len,done);break;case 3:func(item[0],item[1],item[2],i,len,done);break;default:item.push(i,done);func.apply(this,item)}}}}else{var keys=lib.keys(arr);len=keys.length;outputArr=new Array(len);if(len===0){cb(null,"")}else{for(var i=0;i<keys.length;i++){var k=keys[i];func(k,arr[k],i,len,done)}}}}modules["runtime"]={Frame:Frame,makeMacro:makeMacro,makeKeywordArgs:makeKeywordArgs,numArgs:numArgs,suppressValue:suppressValue,memberLookup:memberLookup,contextOrFrameLookup:contextOrFrameLookup,callWrap:callWrap,handleError:handleError,isArray:lib.isArray,keys:lib.keys,SafeString:SafeString,copySafeness:copySafeness,markSafe:markSafe,asyncEach:asyncEach,asyncAll:asyncAll}})();(function(){"use strict";var path=modules["path"];var Obj=modules["object"];var lib=modules["lib"];var Loader=Obj.extend({on:function(name,func){this.listeners=this.listeners||{};this.listeners[name]=this.listeners[name]||[];this.listeners[name].push(func)},emit:function(name){var args=Array.prototype.slice.call(arguments,1);if(this.listeners&&this.listeners[name]){lib.each(this.listeners[name],function(listener){listener.apply(null,args)})}},resolve:function(from,to){return path.resolve(path.dirname(from),to)},isRelative:function(filename){return filename.indexOf("./")===0||filename.indexOf("../")===0}});modules["loader"]=Loader})();(function(){"use strict";var Loader=modules["loader"];var WebLoader=Loader.extend({init:function(baseURL,neverUpdate){this.precompiled=window.nunjucksPrecompiled||{};this.baseURL=baseURL||"";this.neverUpdate=neverUpdate},getSource:function(name){if(this.precompiled[name]){return{src:{type:"code",obj:this.precompiled[name]},path:name}}else{var src=this.fetch(this.baseURL+"/"+name);if(!src){return null}return{src:src,path:name,noCache:!this.neverUpdate}}},fetch:function(url,callback){var ajax;var loading=true;var src;if(window.XMLHttpRequest){ajax=new XMLHttpRequest}else if(window.ActiveXObject){ajax=new ActiveXObject("Microsoft.XMLHTTP")}ajax.onreadystatechange=function(){if(ajax.readyState===4&&(ajax.status===0||ajax.status===200)&&loading){loading=false;src=ajax.responseText}};url+=(url.indexOf("?")===-1?"?":"&")+"s="+(new Date).getTime();ajax.open("GET",url,false);ajax.send();return src}});modules["web-loaders"]={WebLoader:WebLoader}})();(function(){if(typeof window==="undefined"||window!==this){modules["loaders"]=modules["node-loaders"]}else{modules["loaders"]=modules["web-loaders"]}})();(function(){"use strict";var lib=modules["lib"];var r=modules["runtime"];var filters={abs:function(n){return Math.abs(n)},batch:function(arr,linecount,fill_with){var res=[];var tmp=[];for(var i=0;i<arr.length;i++){if(i%linecount===0&&tmp.length){res.push(tmp);tmp=[]}tmp.push(arr[i])}if(tmp.length){if(fill_with){for(var i=tmp.length;i<linecount;i++){tmp.push(fill_with)}}res.push(tmp)}return res},capitalize:function(str){var ret=str.toLowerCase();return r.copySafeness(str,ret.charAt(0).toUpperCase()+ret.slice(1))},center:function(str,width){width=width||80;if(str.length>=width){return str}var spaces=width-str.length;var pre=lib.repeat(" ",spaces/2-spaces%2);var post=lib.repeat(" ",spaces/2);return r.copySafeness(str,pre+str+post)},"default":function(val,def){return val?val:def},dictsort:function(val,case_sensitive,by){if(!lib.isObject(val)){throw new lib.TemplateError("dictsort filter: val must be an object")}var array=[];for(var k in val){array.push([k,val[k]])}var si;if(by===undefined||by==="key"){si=0}else if(by==="value"){si=1}else{throw new lib.TemplateError("dictsort filter: You can only sort by either key or value")}array.sort(function(t1,t2){var a=t1[si];var b=t2[si];if(!case_sensitive){if(lib.isString(a)){a=a.toUpperCase()}if(lib.isString(b)){b=b.toUpperCase()}}return a>b?1:a===b?0:-1});return array},escape:function(str){if(typeof str==="string"||str instanceof r.SafeString){return lib.escape(str)}return str},safe:function(str){return r.markSafe(str)},first:function(arr){return arr[0]},groupby:function(arr,attr){return lib.groupBy(arr,attr)},indent:function(str,width,indentfirst){width=width||4;var res="";var lines=str.split("\n");var sp=lib.repeat(" ",width);for(var i=0;i<lines.length;i++){if(i===0&&!indentfirst){res+=lines[i]+"\n"}else{res+=sp+lines[i]+"\n"}}return r.copySafeness(str,res)},join:function(arr,del,attr){del=del||"";if(attr){arr=lib.map(arr,function(v){return v[attr]})}return arr.join(del)},last:function(arr){return arr[arr.length-1]},length:function(arr){return arr!==undefined?arr.length:0},list:function(val){if(lib.isString(val)){return val.split("")}else if(lib.isObject(val)){var keys=[];if(Object.keys){keys=Object.keys(val)}else{for(var k in val){keys.push(k)}}return lib.map(keys,function(k){return{key:k,value:val[k]}})}else if(lib.isArray(val)){return val}else{throw new lib.TemplateError("list filter: type not iterable")}},lower:function(str){return str.toLowerCase()},random:function(arr){return arr[Math.floor(Math.random()*arr.length)]},rejectattr:function(arr,attr){return arr.filter(function(item){return!item[attr]})},selectattr:function(arr,attr){return arr.filter(function(item){return!!item[attr]})},replace:function(str,old,new_,maxCount){if(old instanceof RegExp){return str.replace(old,new_)}var res=str;var last=res;var count=1;res=res.replace(old,new_);while(last!==res){if(count>=maxCount){break}last=res;res=res.replace(old,new_);count++}return r.copySafeness(str,res)},reverse:function(val){var arr;if(lib.isString(val)){arr=filters.list(val)}else{arr=lib.map(val,function(v){return v})}arr.reverse();if(lib.isString(val)){return r.copySafeness(val,arr.join(""))}return arr},round:function(val,precision,method){precision=precision||0;var factor=Math.pow(10,precision);var rounder;if(method==="ceil"){rounder=Math.ceil}else if(method==="floor"){rounder=Math.floor}else{rounder=Math.round}return rounder(val*factor)/factor},slice:function(arr,slices,fillWith){var sliceLength=Math.floor(arr.length/slices);var extra=arr.length%slices;var offset=0;var res=[];for(var i=0;i<slices;i++){var start=offset+i*sliceLength;if(i<extra){offset++}var end=offset+(i+1)*sliceLength;var slice=arr.slice(start,end);if(fillWith&&i>=extra){slice.push(fillWith)}res.push(slice)}return res},sort:function(arr,reverse,caseSens,attr){arr=lib.map(arr,function(v){return v});arr.sort(function(a,b){var x,y;if(attr){x=a[attr];y=b[attr]}else{x=a;y=b}if(!caseSens&&lib.isString(x)&&lib.isString(y)){x=x.toLowerCase();y=y.toLowerCase()}if(x<y){return reverse?1:-1}else if(x>y){return reverse?-1:1}else{return 0}});return arr},string:function(obj){return r.copySafeness(obj,obj)},title:function(str){var words=str.split(" ");for(var i=0;i<words.length;i++){words[i]=filters.capitalize(words[i])}return r.copySafeness(str,words.join(" "))},trim:function(str){return r.copySafeness(str,str.replace(/^\s*|\s*$/g,""))},truncate:function(input,length,killwords,end){var orig=input;length=length||255;if(input.length<=length)return input;if(killwords){input=input.substring(0,length)}else{var idx=input.lastIndexOf(" ",length);if(idx===-1){idx=length}input=input.substring(0,idx)}input+=end!==undefined&&end!==null?end:"...";return r.copySafeness(orig,input)},upper:function(str){return str.toUpperCase()},urlencode:function(obj){var enc=encodeURIComponent;if(lib.isString(obj)){return enc(obj)}else{var parts;if(lib.isArray(obj)){parts=obj.map(function(item){return enc(item[0])+"="+enc(item[1])})}else{parts=[];for(var k in obj){if(obj.hasOwnProperty(k)){parts.push(enc(k)+"="+enc(obj[k]))}}}return parts.join("&")}},urlize:function(str,length,nofollow){if(isNaN(length))length=Infinity;var noFollowAttr=nofollow===true?' rel="nofollow"':"";var puncRE=/^(?:\(|<|&lt;)?(.*?)(?:\.|,|\)|\n|&gt;)?$/;var emailRE=/^[\w.!#$%&'*+\-\/=?\^`{|}~]+@[a-z\d\-]+(\.[a-z\d\-]+)+$/i;var httpHttpsRE=/^https?:\/\/.*$/;var wwwRE=/^www\./;var tldRE=/\.(?:org|net|com)(?:\:|\/|$)/;var words=str.split(/\s+/).filter(function(word){return word&&word.length}).map(function(word){var matches=word.match(puncRE);var possibleUrl=matches&&matches[1]||word;if(httpHttpsRE.test(possibleUrl))return'<a href="'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";if(wwwRE.test(possibleUrl))return'<a href="http://'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";if(emailRE.test(possibleUrl))return'<a href="mailto:'+possibleUrl+'">'+possibleUrl+"</a>";if(tldRE.test(possibleUrl))return'<a href="http://'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";return word});return words.join(" ")},wordcount:function(str){var words=str?str.match(/\w+/g):null;return words?words.length:null},"float":function(val,def){var res=parseFloat(val);return isNaN(res)?def:res},"int":function(val,def){var res=parseInt(val,10);return isNaN(res)?def:res}};filters.d=filters["default"];filters.e=filters.escape;modules["filters"]=filters})();(function(){"use strict";function cycler(items){var index=-1;return{current:null,reset:function(){index=-1;this.current=null},next:function(){index++;if(index>=items.length){index=0}this.current=items[index];return this.current}}}function joiner(sep){sep=sep||",";var first=true;return function(){var val=first?"":sep;first=false;return val}}var globals={range:function(start,stop,step){if(!stop){stop=start;start=0;step=1}else if(!step){step=1}var arr=[];for(var i=start;i<stop;i+=step){arr.push(i)}return arr},cycler:function(){return cycler(Array.prototype.slice.call(arguments))},joiner:function(sep){return joiner(sep)}};modules["globals"]=globals})();(function(){"use strict";var path=modules["path"];var lib=modules["lib"];var Obj=modules["object"];var lexer=modules["lexer"];var compiler=modules["compiler"];var builtin_filters=modules["filters"];var builtin_loaders=modules["loaders"];var runtime=modules["runtime"];var globals=modules["globals"];var Frame=runtime.Frame;var Environment=Obj.extend({init:function(loaders,opts){var opts=this.opts=opts||{};this.opts.dev=!!opts.dev;this.opts.autoescape=!!opts.autoescape;this.opts.trimBlocks=!!opts.trimBlocks;this.opts.lstripBlocks=!!opts.lstripBlocks;if(!loaders){if(builtin_loaders.FileSystemLoader){this.loaders=[new builtin_loaders.FileSystemLoader("views")]}else{this.loaders=[new builtin_loaders.WebLoader("/views")]}}else{this.loaders=lib.isArray(loaders)?loaders:[loaders]}this.initCache();this.filters={};this.asyncFilters=[];this.extensions={};this.extensionsList=[];for(var name in builtin_filters){this.addFilter(name,builtin_filters[name])}},initCache:function(){lib.each(this.loaders,function(loader){loader.cache={};if(typeof loader.on==="function"){loader.on("update",function(template){loader.cache[template]=null})}})},addExtension:function(name,extension){extension._name=name;this.extensions[name]=extension;this.extensionsList.push(extension)},getExtension:function(name){return this.extensions[name]},addGlobal:function(name,value){globals[name]=value},addFilter:function(name,func,async){var wrapped=func;if(async){this.asyncFilters.push(name)}this.filters[name]=wrapped},getFilter:function(name){if(!this.filters[name]){throw new Error("filter not found: "+name)}return this.filters[name]},resolveTemplate:function(loader,parentName,filename){var isRelative=loader.isRelative&&parentName?loader.isRelative(filename):false;return isRelative&&loader.resolve?loader.resolve(parentName,filename):filename},getTemplate:function(name,eagerCompile,parentName,cb){var that=this;var tmpl=null;if(name&&name.raw){name=name.raw}if(lib.isFunction(parentName)){cb=parentName;parentName=null;eagerCompile=eagerCompile||false}if(lib.isFunction(eagerCompile)){cb=eagerCompile;eagerCompile=false}if(typeof name!=="string"){throw new Error("template names must be a string: "+name)}for(var i=0;i<this.loaders.length;i++){var _name=this.resolveTemplate(this.loaders[i],parentName,name);tmpl=this.loaders[i].cache[_name];if(tmpl)break}if(tmpl){if(eagerCompile){tmpl.compile()}if(cb){cb(null,tmpl)}else{return tmpl}}else{var syncResult;lib.asyncIter(this.loaders,function(loader,i,next,done){function handle(src){if(src){src.loader=loader;done(src)}else{next()}}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){cb(err)}else{throw err}}else{var tmpl=new Template(info.src,this,info.path,eagerCompile);if(!info.noCache){info.loader.cache[name]=tmpl}if(cb){cb(null,tmpl)}else{syncResult=tmpl}}}.bind(this));return syncResult}},express:function(app){var env=this;function NunjucksView(name,opts){this.name=name;this.path=name;this.defaultEngine=opts.defaultEngine;this.ext=path.extname(name);if(!this.ext&&!this.defaultEngine)throw new Error("No default engine was specified and no extension was provided.");if(!this.ext)this.name+=this.ext=("."!==this.defaultEngine[0]?".":"")+this.defaultEngine}NunjucksView.prototype.render=function(opts,cb){env.render(this.name,opts,cb)};app.set("view",NunjucksView)},render:function(name,ctx,cb){if(lib.isFunction(ctx)){cb=ctx;ctx=null}var syncResult=null;this.getTemplate(name,function(err,tmpl){if(err&&cb){cb(err)}else if(err){throw err}else{tmpl.render(ctx,cb||function(err,res){if(err){throw err}syncResult=res})}});return syncResult},renderString:function(src,ctx,opts,cb){if(lib.isFunction(opts)){cb=opts;opts={}}opts=opts||{};var tmpl=new Template(src,this,opts.path);return tmpl.render(ctx,cb)}});var Context=Obj.extend({init:function(ctx,blocks){this.ctx=ctx;this.blocks={};this.exported=[];for(var name in blocks){this.addBlock(name,blocks[name])}},lookup:function(name){if(name in globals&&!(name in this.ctx)){return globals[name]}else{return this.ctx[name]}},setVariable:function(name,val){this.ctx[name]=val},getVariables:function(){return this.ctx},addBlock:function(name,block){this.blocks[name]=this.blocks[name]||[];this.blocks[name].push(block)},getBlock:function(name){if(!this.blocks[name]){throw new Error('unknown block "'+name+'"')}return this.blocks[name][0]},getSuper:function(env,name,block,frame,runtime,cb){var idx=lib.indexOf(this.blocks[name]||[],block);var blk=this.blocks[name][idx+1];var context=this;if(idx===-1||!blk){throw new Error('no super block available for "'+name+'"')}blk(env,context,frame,runtime,cb)},addExport:function(name){this.exported.push(name)},getExported:function(){var exported={};for(var i=0;i<this.exported.length;i++){var name=this.exported[i];exported[name]=this.ctx[name]}return exported}});var Template=Obj.extend({init:function(src,env,path,eagerCompile){this.env=env||new Environment;if(lib.isObject(src)){switch(src.type){case"code":this.tmplProps=src.obj;break;case"string":this.tmplStr=src.obj;break}}else if(lib.isString(src)){this.tmplStr=src}else{throw new Error("src must be a string or an object describing "+"the source")}this.path=path;if(eagerCompile){lib.withPrettyErrors(this.path,this.env.dev,this._compile.bind(this))}else{this.compiled=false}},render:function(ctx,frame,cb){if(typeof ctx==="function"){cb=ctx;ctx={}}else if(typeof frame==="function"){cb=frame;frame=null}return lib.withPrettyErrors(this.path,this.env.dev,function(){try{this.compile()}catch(e){if(cb)return cb(e);else throw e}var context=new Context(ctx||{},this.blocks);var syncResult=null;this.rootRenderFunc(this.env,context,frame||new Frame,runtime,cb||function(err,res){if(err){throw err}syncResult=res});return syncResult}.bind(this))},getExported:function(ctx,frame,cb){if(typeof ctx==="function"){cb=ctx;ctx={}}if(typeof frame==="function"){cb=frame;frame=null}try{this.compile()}catch(e){if(cb)return cb(e);else throw e}var context=new Context(ctx||{},this.blocks);this.rootRenderFunc(this.env,context,frame||new Frame,runtime,function(){cb(null,context.getExported())})},compile:function(){if(!this.compiled){this._compile()}},_compile:function(){var props;if(this.tmplProps){props=this.tmplProps}else{var source=compiler.compile(this.tmplStr,this.env.asyncFilters,this.env.extensionsList,this.path,this.env.opts);var func=new Function(source);props=func()}this.blocks=this._getBlocks(props);this.rootRenderFunc=props.root;this.compiled=true},_getBlocks:function(props){var blocks={};for(var k in props){if(k.slice(0,2)==="b_"){blocks[k.slice(2)]=props[k]}}return blocks}});modules["environment"]={Environment:Environment,Template:Template}})();var nunjucks;var lib=modules["lib"];var env=modules["environment"];var compiler=modules["compiler"];var parser=modules["parser"];var lexer=modules["lexer"];var runtime=modules["runtime"];var Loader=modules["loader"];var loaders=modules["loaders"];var precompile=modules["precompile"];nunjucks={};nunjucks.Environment=env.Environment;nunjucks.Template=env.Template;nunjucks.Loader=Loader;nunjucks.FileSystemLoader=loaders.FileSystemLoader;nunjucks.WebLoader=loaders.WebLoader;nunjucks.compiler=compiler;nunjucks.parser=parser;nunjucks.lexer=lexer;nunjucks.runtime=runtime;var e;nunjucks.configure=function(templatesPath,opts){opts=opts||{};if(lib.isObject(templatesPath)){opts=templatesPath;templatesPath=null}var noWatch="watch"in opts?!opts.watch:false;var loader=loaders.FileSystemLoader||loaders.WebLoader;e=new env.Environment(new loader(templatesPath,noWatch),opts);if(opts&&opts.express){e.express(opts.express)}return e};nunjucks.compile=function(src,env,path,eagerCompile){if(!e){nunjucks.configure()}return new nunjucks.Template(src,env,path,eagerCompile)};nunjucks.render=function(name,ctx,cb){if(!e){nunjucks.configure()}return e.render(name,ctx,cb)};nunjucks.renderString=function(src,ctx,cb){if(!e){nunjucks.configure()}return e.renderString(src,ctx,cb)};if(precompile){nunjucks.precompile=precompile.precompile;nunjucks.precompileString=precompile.precompileString}nunjucks.require=function(name){return modules[name]};if(typeof define==="function"&&define.amd){define(function(){return nunjucks})}else{window.nunjucks=nunjucks;if(typeof module!=="undefined")module.exports=nunjucks}})();

@@ -17,2 +17,9 @@ ---

**Warning**: nunjucks does not sandbox execution so it is potentially
unsafe to run user-defined templates. On the server, you may expose
attack vectors for accessing sensitive data. On the client, you may
expose cross-site scripting vulnerabilities (see [this
issue](https://github.com/mozilla/nunjucks-docs/issues/17) for more
information).
{% endraw %}

@@ -190,3 +197,3 @@ {% api %}

```js
var res = nunjucks.render('Hello {{ username }}', { username: 'James' });
var res = nunjucks.renderString('Hello {{ username }}', { username: 'James' });
```

@@ -356,3 +363,3 @@ {% endraw %}

production, this should always be the case. See
[Precompiling Templates](#precompiling-templates).
[Precompiling](#precompiling).

@@ -828,3 +835,3 @@ ```js

// parse the body and possibly the error block, which is optional
var body = parser.parseUntilBlocks('error', 'endtruncate');
var body = parser.parseUntilBlocks('error', 'endremote');
var errorBody = null;

@@ -831,0 +838,0 @@

@@ -138,3 +138,3 @@ ---

```js
var res = nunjucks.render('Hello {{ username }}', { username: 'James' });
var res = nunjucks.renderString('Hello {{ username }}', { username: 'James' });
```

@@ -141,0 +141,0 @@ {% endraw %}

@@ -11,3 +11,3 @@ ---

> Nunjucks 是 [jinja2](http://jinja.pocoo.org/docs/) 的 javascript 的实现,所以如果此文档有什么缺失,你可以直接查看 [jinja2 的文档](http://jinja.pocoo.org/docs/templates/),不过两者之间还存在一些[差异](http://mozilla.github.io/nunjucks/faq.html#can-i-use-the-same-templates-between-nunjucks-and-jinja2-what-are-the-differences)。
> Nunjucks 是 [jinja2](http://jinja.pocoo.org/docs/) 的 javascript 的实现,所以如果此文档有什么缺失,你可以直接查看 [jinja2 的文档](http://jinja.pocoo.org/docs/templates/),不过两者之间还存在一些[差异](http://mozilla.github.io/nunjucks/cn/faq.html)。

@@ -44,3 +44,3 @@ ## 变量

Nunjucks 提供了一些[内置的过滤器](#builtin-filters),你也可以[自定义过滤器](api#Registering-custom-filters)。
Nunjucks 提供了一些[内置的过滤器](#builtin-filters),你也可以[自定义过滤器](api#custom-filters)。

@@ -107,4 +107,3 @@ ## 模板继承

Tags are special blocks that perform operations on sections of the
template. Nunjucks 包含一些内置的标签,你也可以[自定义](api.html#custom-tags)。
标签是一些特殊的区块,它们可以对模板执行一些操作。Nunjucks 包含一些内置的标签,你也可以[自定义](api.html#custom-tags)。

@@ -339,3 +338,3 @@ ### if

This is especially useful for cutting up templates into pieces so that the browser-side environment can render the small chunks when it needs to change the page.
这一点可以帮助我们把模板切分成更小的部分,从而使得在浏览器上,当我们需要改变页面时,我们可以渲染这些小部分的模板,而非一整个的大的模板。

@@ -579,3 +578,3 @@ `include` 可以接受任何表达式,你可以如下传入: `{% include name + ".html" as obj %}`.

如果你需要遍历固定范围的数字可以使用 `range`,`start` (默认为 0) 为起始数字,`start` 为结束数字,`step` 为间隔 (默认为 1)。
如果你需要遍历固定范围的数字可以使用 `range`,`start` (默认为 0) 为起始数字,`stop` 为结束数字,`step` 为间隔 (默认为 1)。

@@ -618,4 +617,2 @@ ```jinja

Nunjucks has ported most of jinja's filters (click through for documentation):
Nunjucks 已经支持了大部分 jinja 的过滤器 (点击查看文档)。

@@ -622,0 +619,0 @@

@@ -30,3 +30,3 @@ ---

`True` and more). You can [see it
here](https://github.com/mozilla/fireplace/blob/master/hearth/media/js/lib/nunjucks.compat.js).
here](https://github.com/mozilla/fireplace/blob/9fb5f147c136926e406fd725e4062b0866d431c4/src/media/js/lib/nunjucks.compat.js).

@@ -33,0 +33,0 @@ Additionally, there are few jinja2 features not implemented in nunjucks:

@@ -1,2 +0,2 @@

// Browser bundle of nunjucks 1.1.0 (slim, only works with precompiled templates)
// Browser bundle of nunjucks 1.3.1 (slim, only works with precompiled templates)

@@ -6,2 +6,3 @@ (function() {

(function() {
'use strict';

@@ -23,4 +24,4 @@ // A simple class system, more documentation to come

if(typeof parent == "function" &&
typeof src == "function" &&
if(typeof parent === 'function' &&
typeof src === 'function' &&
fnTest.test(src)) {

@@ -58,5 +59,5 @@ prototype[k] = (function (src, parent) {

new_cls.extend = function(name, props) {
if(typeof name == "object") {
if(typeof name === 'object') {
props = name;
name = "anonymous";
name = 'anonymous';
}

@@ -69,5 +70,7 @@ return extend(new_cls, name, props);

modules['object'] = extend(Object, "Object", {});
modules['object'] = extend(Object, 'Object', {});
})();
(function() {
'use strict';
var ArrayProto = Array.prototype;

@@ -79,5 +82,5 @@ var ObjProto = Object.prototype;

'"': '&quot;',
"'": '&#39;',
"<": '&lt;',
">": '&gt;'
'\'': '&#39;',
'<': '&lt;',
'>': '&gt;'
};

@@ -119,3 +122,3 @@

err = message;
message = message.name + ": " + message.message;
message = message.name + ': ' + message.message;
} else {

@@ -134,3 +137,3 @@ if(Error.captureStackTrace) {

err.Update = function(path) {
var message = "(" + (path || "unknown path") + ")";
var message = '(' + (path || 'unknown path') + ')';

@@ -168,15 +171,15 @@ // only show lineno + colno next to path of template

exports.isFunction = function(obj) {
return ObjProto.toString.call(obj) == '[object Function]';
return ObjProto.toString.call(obj) === '[object Function]';
};
exports.isArray = Array.isArray || function(obj) {
return ObjProto.toString.call(obj) == '[object Array]';
return ObjProto.toString.call(obj) === '[object Array]';
};
exports.isString = function(obj) {
return ObjProto.toString.call(obj) == '[object String]';
return ObjProto.toString.call(obj) === '[object String]';
};
exports.isObject = function(obj) {
return ObjProto.toString.call(obj) == '[object Object]';
return ObjProto.toString.call(obj) === '[object Object]';
};

@@ -236,3 +239,3 @@

if(ArrayProto.each && obj.each == ArrayProto.each) {
if(ArrayProto.each && obj.each === ArrayProto.each) {
obj.forEach(func, context);

@@ -337,3 +340,3 @@ }

Array.prototype.map = function() {
throw new Error("map is unimplemented for this js engine");
throw new Error('map is unimplemented for this js engine');
};

@@ -358,2 +361,4 @@ }

(function() {
'use strict';
var lib = modules["lib"];

@@ -377,3 +382,3 @@ var Obj = modules["object"];

var frame = this;
if(resolveUp) {

@@ -419,3 +424,3 @@ if((frame = this.resolve(parts[0]))) {

var val = this.variables[name];
if(val != null) {
if(val !== undefined && val !== null) {
return this;

@@ -513,3 +518,3 @@ }

function SafeString(val) {
if(typeof val != 'string') {
if(typeof val !== 'string') {
return val;

@@ -559,5 +564,5 @@ }

function suppressValue(val, autoescape) {
val = (val !== undefined && val !== null) ? val : "";
val = (val !== undefined && val !== null) ? val : '';
if(autoescape && typeof val === "string") {
if(autoescape && typeof val === 'string') {
val = lib.escape(val);

@@ -639,3 +644,3 @@ }

if(finished == len) {
if(finished === len) {
cb(null, outputArr.join(''));

@@ -649,3 +654,3 @@ }

if(len == 0) {
if(len === 0) {
cb(null, '');

@@ -673,3 +678,3 @@ }

if(len == 0) {
if(len === 0) {
cb(null, '');

@@ -706,2 +711,5 @@ }

(function() {
'use strict';
var path = modules["path"];
var Obj = modules["object"];

@@ -725,2 +733,10 @@ var lib = modules["lib"];

}
},
resolve: function(from, to) {
return path.resolve(path.dirname(from), to);
},
isRelative: function(filename) {
return (filename.indexOf('./') === 0 || filename.indexOf('../') === 0);
}

@@ -732,2 +748,4 @@ });

(function() {
'use strict';
var Loader = modules["loader"];

@@ -749,3 +767,3 @@

return {
src: { type: "code",
src: { type: 'code',
obj: this.precompiled[name] },

@@ -777,3 +795,3 @@ path: name

else if(window.ActiveXObject) { // IE 8 and older
ajax = new ActiveXObject("Microsoft.XMLHTTP");
ajax = new ActiveXObject('Microsoft.XMLHTTP');
}

@@ -813,2 +831,4 @@

(function() {
'use strict';
var lib = modules["lib"];

@@ -861,4 +881,4 @@ var r = modules["runtime"];

var spaces = width - str.length;
var pre = lib.repeat(" ", spaces/2 - spaces % 2);
var post = lib.repeat(" ", spaces/2);
var pre = lib.repeat(' ', spaces/2 - spaces % 2);
var post = lib.repeat(' ', spaces/2);
return r.copySafeness(str, pre + str + post);

@@ -873,3 +893,3 @@ },

if (!lib.isObject(val)) {
throw new lib.TemplateError("dictsort filter: val must be an object");
throw new lib.TemplateError('dictsort filter: val must be an object');
}

@@ -884,9 +904,9 @@

var si;
if (by === undefined || by === "key") {
if (by === undefined || by === 'key') {
si = 0;
} else if (by === "value") {
} else if (by === 'value') {
si = 1;
} else {
throw new lib.TemplateError(
"dictsort filter: You can only sort by either key or value");
'dictsort filter: You can only sort by either key or value');
}

@@ -907,3 +927,3 @@

return a > b ? 1 : (a == b ? 0 : -1);
return a > b ? 1 : (a === b ? 0 : -1);
});

@@ -915,3 +935,3 @@

escape: function(str) {
if(typeof str == 'string' ||
if(typeof str === 'string' ||
str instanceof r.SafeString) {

@@ -942,3 +962,3 @@ return lib.escape(str);

for(var i=0; i<lines.length; i++) {
if(i == 0 && !indentfirst) {
if(i === 0 && !indentfirst) {
res += lines[i] + '\n';

@@ -995,4 +1015,7 @@ }

}
else if(lib.isArray(val)) {
return val;
}
else {
throw new lib.TemplateError("list filter: type not iterable");
throw new lib.TemplateError('list filter: type not iterable');
}

@@ -1009,2 +1032,14 @@ },

rejectattr: function(arr, attr) {
return arr.filter(function (item) {
return !item[attr];
});
},
selectattr: function(arr, attr) {
return arr.filter(function (item) {
return !!item[attr];
});
},
replace: function(str, old, new_, maxCount) {

@@ -1020,3 +1055,3 @@ if (old instanceof RegExp) {

while(last != res) {
while(last !== res) {
if(count >= maxCount) {

@@ -1057,6 +1092,6 @@ break;

if(method == 'ceil') {
if(method === 'ceil') {
rounder = Math.ceil;
}
else if(method == 'floor') {
else if(method === 'floor') {
rounder = Math.floor;

@@ -1264,8 +1299,9 @@ }

(function() {
'use strict';
function cycler(items) {
var index = -1;
this.current = null;
return {
current: null,
reset: function() {

@@ -1333,2 +1369,4 @@ index = -1;

(function() {
'use strict';
var path = modules["path"];

@@ -1353,5 +1391,4 @@ var lib = modules["lib"];

// defaults to false
opts = opts || {};
this.dev = !!opts.dev;
this.lexerTags = opts.tags;
var opts = this.opts = opts || {};
this.opts.dev = !!opts.dev;

@@ -1362,4 +1399,8 @@ // The autoescape flag sets global autoescaping. If true,

// defaults to false
this.autoesc = !!opts.autoescape;
this.opts.autoescape = !!opts.autoescape;
this.opts.trimBlocks = !!opts.trimBlocks;
this.opts.lstripBlocks = !!opts.lstripBlocks;
if(!loaders) {

@@ -1391,13 +1432,11 @@ // The filesystem loader is only available client-side

// Caching and cache busting
var cache = {};
lib.each(this.loaders, function(loader) {
loader.cache = {};
lib.each(this.loaders, function(loader) {
if(typeof loader.on === 'function'){
if(typeof loader.on === 'function') {
loader.on('update', function(template) {
cache[template] = null;
loader.cache[template] = null;
});
}
});
this.cache = cache;
},

@@ -1435,3 +1474,10 @@

getTemplate: function(name, eagerCompile, cb) {
resolveTemplate: function(loader, parentName, filename) {
var isRelative = (loader.isRelative && parentName)? loader.isRelative(filename) : false;
return (isRelative && loader.resolve)? loader.resolve(parentName, filename) : filename;
},
getTemplate: function(name, eagerCompile, parentName, cb) {
var that = this;
var tmpl = null;
if(name && name.raw) {

@@ -1442,2 +1488,8 @@ // this fixes autoescape for templates referenced in symbols

if(lib.isFunction(parentName)) {
cb = parentName;
parentName = null;
eagerCompile = eagerCompile || false;
}
if(lib.isFunction(eagerCompile)) {

@@ -1452,3 +1504,7 @@ cb = eagerCompile;

var tmpl = this.cache[name];
for (var i = 0; i < this.loaders.length; i++) {
var _name = this.resolveTemplate(this.loaders[i], parentName, name);
tmpl = this.loaders[i].cache[_name];
if (tmpl) break;
}

@@ -1472,2 +1528,3 @@ if(tmpl) {

if(src) {
src.loader = loader;
done(src);

@@ -1480,2 +1537,5 @@ }

// Resolve name relative to parentName
name = that.resolveTemplate(loader, parentName, name);
if(loader.async) {

@@ -1505,3 +1565,3 @@ loader.getSource(name, function(err, src) {

if(!info.noCache) {
this.cache[name] = tmpl;
info.loader.cache[name] = tmpl;
}

@@ -1571,4 +1631,10 @@

renderString: function(src, ctx, cb) {
var tmpl = new Template(src, this);
renderString: function(src, ctx, opts, cb) {
if(lib.isFunction(opts)) {
cb = opts;
opts = {};
}
opts = opts || {};
var tmpl = new Template(src, this, opts.path);
return tmpl.render(ctx, cb);

@@ -1626,3 +1692,3 @@ }

if(idx == -1 || !blk) {
if(idx === -1 || !blk) {
throw new Error('no super block available for "' + name + '"');

@@ -1662,4 +1728,4 @@ }

else {
throw new Error("src must be a string or an object describing " +
"the source");
throw new Error('src must be a string or an object describing ' +
'the source');
}

@@ -1690,4 +1756,11 @@

return lib.withPrettyErrors(this.path, this.env.dev, function() {
this.compile();
// Catch compile errors for async rendering
try {
this.compile();
} catch (e) {
if (cb) return cb(e);
else throw e;
}
var context = new Context(ctx || {}, this.blocks);

@@ -1709,10 +1782,27 @@ var syncResult = null;

getExported: function(cb) {
this.compile();
getExported: function(ctx, frame, cb) {
if (typeof ctx === 'function') {
cb = ctx;
ctx = {};
}
if (typeof frame === 'function') {
cb = frame;
frame = null;
}
// Catch compile errors for async rendering
try {
this.compile();
} catch (e) {
if (cb) return cb(e);
else throw e;
}
// Run the rootRenderFunc to populate the context with exported vars
var context = new Context({}, this.blocks);
var context = new Context(ctx || {}, this.blocks);
this.rootRenderFunc(this.env,
context,
new Frame(),
frame || new Frame(),
runtime,

@@ -1741,3 +1831,4 @@ function() {

this.path,
this.env.lexerTags);
this.env.opts);
var func = new Function(source);

@@ -1756,3 +1847,3 @@ props = func();

for(var k in props) {
if(k.slice(0, 2) == 'b_') {
if(k.slice(0, 2) === 'b_') {
blocks[k.slice(2)] = props[k];

@@ -1759,0 +1850,0 @@ }

@@ -1,3 +0,3 @@

// Browser bundle of nunjucks 1.1.0 (slim, only works with precompiled templates)
// Browser bundle of nunjucks 1.3.1 (slim, only works with precompiled templates)
(function(){var modules={};(function(){function extend(cls,name,props){var F=function(){};F.prototype=cls.prototype;var prototype=new F;var fnTest=/xyz/.test(function(){xyz})?/\bparent\b/:/.*/;props=props||{};for(var k in props){var src=props[k];var parent=prototype[k];if(typeof parent=="function"&&typeof src=="function"&&fnTest.test(src)){prototype[k]=function(src,parent){return function(){var tmp=this.parent;this.parent=parent;var res=src.apply(this,arguments);this.parent=tmp;return res}}(src,parent)}else{prototype[k]=src}}prototype.typename=name;var new_cls=function(){if(prototype.init){prototype.init.apply(this,arguments)}};new_cls.prototype=prototype;new_cls.prototype.constructor=new_cls;new_cls.extend=function(name,props){if(typeof name=="object"){props=name;name="anonymous"}return extend(new_cls,name,props)};return new_cls}modules["object"]=extend(Object,"Object",{})})();(function(){var ArrayProto=Array.prototype;var ObjProto=Object.prototype;var escapeMap={"&":"&amp;",'"':"&quot;","'":"&#39;","<":"&lt;",">":"&gt;"};var escapeRegex=/[&"'<>]/g;var lookupEscape=function(ch){return escapeMap[ch]};var exports=modules["lib"]={};exports.withPrettyErrors=function(path,withInternals,func){try{return func()}catch(e){if(!e.Update){e=new exports.TemplateError(e)}e.Update(path);if(!withInternals){var old=e;e=new Error(old.message);e.name=old.name}throw e}};exports.TemplateError=function(message,lineno,colno){var err=this;if(message instanceof Error){err=message;message=message.name+": "+message.message}else{if(Error.captureStackTrace){Error.captureStackTrace(err)}}err.name="Template render error";err.message=message;err.lineno=lineno;err.colno=colno;err.firstUpdate=true;err.Update=function(path){var message="("+(path||"unknown path")+")";if(this.firstUpdate){if(this.lineno&&this.colno){message+=" [Line "+this.lineno+", Column "+this.colno+"]"}else if(this.lineno){message+=" [Line "+this.lineno+"]"}}message+="\n ";if(this.firstUpdate){message+=" "}this.message=message+(this.message||"");this.firstUpdate=false;return this};return err};exports.TemplateError.prototype=Error.prototype;exports.escape=function(val){return val.replace(escapeRegex,lookupEscape)};exports.isFunction=function(obj){return ObjProto.toString.call(obj)=="[object Function]"};exports.isArray=Array.isArray||function(obj){return ObjProto.toString.call(obj)=="[object Array]"};exports.isString=function(obj){return ObjProto.toString.call(obj)=="[object String]"};exports.isObject=function(obj){return ObjProto.toString.call(obj)=="[object Object]"};exports.groupBy=function(obj,val){var result={};var iterator=exports.isFunction(val)?val:function(obj){return obj[val]};for(var i=0;i<obj.length;i++){var value=obj[i];var key=iterator(value,i);(result[key]||(result[key]=[])).push(value)}return result};exports.toArray=function(obj){return Array.prototype.slice.call(obj)};exports.without=function(array){var result=[];if(!array){return result}var index=-1,length=array.length,contains=exports.toArray(arguments).slice(1);while(++index<length){if(exports.indexOf(contains,array[index])===-1){result.push(array[index])}}return result};exports.extend=function(obj,obj2){for(var k in obj2){obj[k]=obj2[k]}return obj};exports.repeat=function(char_,n){var str="";for(var i=0;i<n;i++){str+=char_}return str};exports.each=function(obj,func,context){if(obj==null){return}if(ArrayProto.each&&obj.each==ArrayProto.each){obj.forEach(func,context)}else if(obj.length===+obj.length){for(var i=0,l=obj.length;i<l;i++){func.call(context,obj[i],i,obj)}}};exports.map=function(obj,func){var results=[];if(obj==null){return results}if(ArrayProto.map&&obj.map===ArrayProto.map){return obj.map(func)}for(var i=0;i<obj.length;i++){results[results.length]=func(obj[i],i)}if(obj.length===+obj.length){results.length=obj.length}return results};exports.asyncIter=function(arr,iter,cb){var i=-1;function next(){i++;if(i<arr.length){iter(arr[i],i,next,cb)}else{cb()}}next()};exports.asyncFor=function(obj,iter,cb){var keys=exports.keys(obj);var len=keys.length;var i=-1;function next(){i++;var k=keys[i];if(i<len){iter(k,obj[k],i,len,next)}else{cb()}}next()};exports.indexOf=Array.prototype.indexOf?function(arr,searchElement,fromIndex){return Array.prototype.indexOf.call(arr,searchElement,fromIndex)}:function(arr,searchElement,fromIndex){var length=this.length>>>0;fromIndex=+fromIndex||0;if(Math.abs(fromIndex)===Infinity){fromIndex=0}if(fromIndex<0){fromIndex+=length;if(fromIndex<0){fromIndex=0}}for(;fromIndex<length;fromIndex++){if(arr[fromIndex]===searchElement){return fromIndex}}return-1};if(!Array.prototype.map){Array.prototype.map=function(){throw new Error("map is unimplemented for this js engine")}}exports.keys=function(obj){if(Object.prototype.keys){return obj.keys()}else{var keys=[];for(var k in obj){if(obj.hasOwnProperty(k)){keys.push(k)}}return keys}}})();(function(){var lib=modules["lib"];var Obj=modules["object"];var Frame=Obj.extend({init:function(parent){this.variables={};this.parent=parent},set:function(name,val,resolveUp){var parts=name.split(".");var obj=this.variables;var frame=this;if(resolveUp){if(frame=this.resolve(parts[0])){frame.set(name,val);return}frame=this}for(var i=0;i<parts.length-1;i++){var id=parts[i];if(!obj[id]){obj[id]={}}obj=obj[id]}obj[parts[parts.length-1]]=val},get:function(name){var val=this.variables[name];if(val!==undefined&&val!==null){return val}return null},lookup:function(name){var p=this.parent;var val=this.variables[name];if(val!==undefined&&val!==null){return val}return p&&p.lookup(name)},resolve:function(name){var p=this.parent;var val=this.variables[name];if(val!=null){return this}return p&&p.resolve(name)},push:function(){return new Frame(this)},pop:function(){return this.parent}});function makeMacro(argNames,kwargNames,func){return function(){var argCount=numArgs(arguments);var args;var kwargs=getKeywordArgs(arguments);if(argCount>argNames.length){args=Array.prototype.slice.call(arguments,0,argNames.length);var vals=Array.prototype.slice.call(arguments,args.length,argCount);for(var i=0;i<vals.length;i++){if(i<kwargNames.length){kwargs[kwargNames[i]]=vals[i]}}args.push(kwargs)}else if(argCount<argNames.length){args=Array.prototype.slice.call(arguments,0,argCount);for(var i=argCount;i<argNames.length;i++){var arg=argNames[i];args.push(kwargs[arg]);delete kwargs[arg]}args.push(kwargs)}else{args=arguments}return func.apply(this,args)}}function makeKeywordArgs(obj){obj.__keywords=true;return obj}function getKeywordArgs(args){var len=args.length;if(len){var lastArg=args[len-1];if(lastArg&&lastArg.hasOwnProperty("__keywords")){return lastArg}}return{}}function numArgs(args){var len=args.length;if(len===0){return 0}var lastArg=args[len-1];if(lastArg&&lastArg.hasOwnProperty("__keywords")){return len-1}else{return len}}function SafeString(val){if(typeof val!="string"){return val}this.val=val}SafeString.prototype=Object.create(String.prototype);SafeString.prototype.valueOf=function(){return this.val};SafeString.prototype.toString=function(){return this.val};function copySafeness(dest,target){if(dest instanceof SafeString){return new SafeString(target)}return target.toString()}function markSafe(val){var type=typeof val;if(type==="string"){return new SafeString(val)}else if(type!=="function"){return val}else{return function(){var ret=val.apply(this,arguments);if(typeof ret==="string"){return new SafeString(ret)}return ret}}}function suppressValue(val,autoescape){val=val!==undefined&&val!==null?val:"";if(autoescape&&typeof val==="string"){val=lib.escape(val)}return val}function memberLookup(obj,val){obj=obj||{};if(typeof obj[val]==="function"){return function(){return obj[val].apply(obj,arguments)}}return obj[val]}function callWrap(obj,name,args){if(!obj){throw new Error("Unable to call `"+name+"`, which is undefined or falsey")}else if(typeof obj!=="function"){throw new Error("Unable to call `"+name+"`, which is not a function")}return obj.apply(this,args)}function contextOrFrameLookup(context,frame,name){var val=frame.lookup(name);return val!==undefined&&val!==null?val:context.lookup(name)}function handleError(error,lineno,colno){if(error.lineno){return error}else{return new lib.TemplateError(error,lineno,colno)}}function asyncEach(arr,dimen,iter,cb){if(lib.isArray(arr)){var len=arr.length;lib.asyncIter(arr,function(item,i,next){switch(dimen){case 1:iter(item,i,len,next);break;case 2:iter(item[0],item[1],i,len,next);break;case 3:iter(item[0],item[1],item[2],i,len,next);break;default:item.push(i,next);iter.apply(this,item)}},cb)}else{lib.asyncFor(arr,function(key,val,i,len,next){iter(key,val,i,len,next)},cb)}}function asyncAll(arr,dimen,func,cb){var finished=0;var len;var outputArr;function done(i,output){finished++;outputArr[i]=output;if(finished==len){cb(null,outputArr.join(""))}}if(lib.isArray(arr)){len=arr.length;outputArr=new Array(len);if(len==0){cb(null,"")}else{for(var i=0;i<arr.length;i++){var item=arr[i];switch(dimen){case 1:func(item,i,len,done);break;case 2:func(item[0],item[1],i,len,done);break;case 3:func(item[0],item[1],item[2],i,len,done);break;default:item.push(i,done);func.apply(this,item)}}}}else{var keys=lib.keys(arr);len=keys.length;outputArr=new Array(len);if(len==0){cb(null,"")}else{for(var i=0;i<keys.length;i++){var k=keys[i];func(k,arr[k],i,len,done)}}}}modules["runtime"]={Frame:Frame,makeMacro:makeMacro,makeKeywordArgs:makeKeywordArgs,numArgs:numArgs,suppressValue:suppressValue,memberLookup:memberLookup,contextOrFrameLookup:contextOrFrameLookup,callWrap:callWrap,handleError:handleError,isArray:lib.isArray,keys:lib.keys,SafeString:SafeString,copySafeness:copySafeness,markSafe:markSafe,asyncEach:asyncEach,asyncAll:asyncAll}})();(function(){var Obj=modules["object"];var lib=modules["lib"];var Loader=Obj.extend({on:function(name,func){this.listeners=this.listeners||{};this.listeners[name]=this.listeners[name]||[];this.listeners[name].push(func)},emit:function(name){var args=Array.prototype.slice.call(arguments,1);if(this.listeners&&this.listeners[name]){lib.each(this.listeners[name],function(listener){listener.apply(null,args)})}}});modules["loader"]=Loader})();(function(){var Loader=modules["loader"];var WebLoader=Loader.extend({init:function(baseURL,neverUpdate){this.precompiled=window.nunjucksPrecompiled||{};this.baseURL=baseURL||"";this.neverUpdate=neverUpdate},getSource:function(name){if(this.precompiled[name]){return{src:{type:"code",obj:this.precompiled[name]},path:name}}else{var src=this.fetch(this.baseURL+"/"+name);if(!src){return null}return{src:src,path:name,noCache:!this.neverUpdate}}},fetch:function(url,callback){var ajax;var loading=true;var src;if(window.XMLHttpRequest){ajax=new XMLHttpRequest}else if(window.ActiveXObject){ajax=new ActiveXObject("Microsoft.XMLHTTP")}ajax.onreadystatechange=function(){if(ajax.readyState===4&&(ajax.status===0||ajax.status===200)&&loading){loading=false;src=ajax.responseText}};url+=(url.indexOf("?")===-1?"?":"&")+"s="+(new Date).getTime();ajax.open("GET",url,false);ajax.send();return src}});modules["web-loaders"]={WebLoader:WebLoader}})();(function(){if(typeof window==="undefined"||window!==this){modules["loaders"]=modules["node-loaders"]}else{modules["loaders"]=modules["web-loaders"]}})();(function(){var lib=modules["lib"];var r=modules["runtime"];var filters={abs:function(n){return Math.abs(n)},batch:function(arr,linecount,fill_with){var res=[];var tmp=[];for(var i=0;i<arr.length;i++){if(i%linecount===0&&tmp.length){res.push(tmp);tmp=[]}tmp.push(arr[i])}if(tmp.length){if(fill_with){for(var i=tmp.length;i<linecount;i++){tmp.push(fill_with)}}res.push(tmp)}return res},capitalize:function(str){var ret=str.toLowerCase();return r.copySafeness(str,ret.charAt(0).toUpperCase()+ret.slice(1))},center:function(str,width){width=width||80;if(str.length>=width){return str}var spaces=width-str.length;var pre=lib.repeat(" ",spaces/2-spaces%2);var post=lib.repeat(" ",spaces/2);return r.copySafeness(str,pre+str+post)},"default":function(val,def){return val?val:def},dictsort:function(val,case_sensitive,by){if(!lib.isObject(val)){throw new lib.TemplateError("dictsort filter: val must be an object")}var array=[];for(var k in val){array.push([k,val[k]])}var si;if(by===undefined||by==="key"){si=0}else if(by==="value"){si=1}else{throw new lib.TemplateError("dictsort filter: You can only sort by either key or value")}array.sort(function(t1,t2){var a=t1[si];var b=t2[si];if(!case_sensitive){if(lib.isString(a)){a=a.toUpperCase()}if(lib.isString(b)){b=b.toUpperCase()}}return a>b?1:a==b?0:-1});return array},escape:function(str){if(typeof str=="string"||str instanceof r.SafeString){return lib.escape(str)}return str},safe:function(str){return r.markSafe(str)},first:function(arr){return arr[0]},groupby:function(arr,attr){return lib.groupBy(arr,attr)},indent:function(str,width,indentfirst){width=width||4;var res="";var lines=str.split("\n");var sp=lib.repeat(" ",width);for(var i=0;i<lines.length;i++){if(i==0&&!indentfirst){res+=lines[i]+"\n"}else{res+=sp+lines[i]+"\n"}}return r.copySafeness(str,res)},join:function(arr,del,attr){del=del||"";if(attr){arr=lib.map(arr,function(v){return v[attr]})}return arr.join(del)},last:function(arr){return arr[arr.length-1]},length:function(arr){return arr!==undefined?arr.length:0},list:function(val){if(lib.isString(val)){return val.split("")}else if(lib.isObject(val)){var keys=[];if(Object.keys){keys=Object.keys(val)}else{for(var k in val){keys.push(k)}}return lib.map(keys,function(k){return{key:k,value:val[k]}})}else{throw new lib.TemplateError("list filter: type not iterable")}},lower:function(str){return str.toLowerCase()},random:function(arr){return arr[Math.floor(Math.random()*arr.length)]},replace:function(str,old,new_,maxCount){if(old instanceof RegExp){return str.replace(old,new_)}var res=str;var last=res;var count=1;res=res.replace(old,new_);while(last!=res){if(count>=maxCount){break}last=res;res=res.replace(old,new_);count++}return r.copySafeness(str,res)},reverse:function(val){var arr;if(lib.isString(val)){arr=filters.list(val)}else{arr=lib.map(val,function(v){return v})}arr.reverse();if(lib.isString(val)){return r.copySafeness(val,arr.join(""))}return arr},round:function(val,precision,method){precision=precision||0;var factor=Math.pow(10,precision);var rounder;if(method=="ceil"){rounder=Math.ceil}else if(method=="floor"){rounder=Math.floor}else{rounder=Math.round}return rounder(val*factor)/factor},slice:function(arr,slices,fillWith){var sliceLength=Math.floor(arr.length/slices);var extra=arr.length%slices;var offset=0;var res=[];for(var i=0;i<slices;i++){var start=offset+i*sliceLength;if(i<extra){offset++}var end=offset+(i+1)*sliceLength;var slice=arr.slice(start,end);if(fillWith&&i>=extra){slice.push(fillWith)}res.push(slice)}return res},sort:function(arr,reverse,caseSens,attr){arr=lib.map(arr,function(v){return v});arr.sort(function(a,b){var x,y;if(attr){x=a[attr];y=b[attr]}else{x=a;y=b}if(!caseSens&&lib.isString(x)&&lib.isString(y)){x=x.toLowerCase();y=y.toLowerCase()}if(x<y){return reverse?1:-1}else if(x>y){return reverse?-1:1}else{return 0}});return arr},string:function(obj){return r.copySafeness(obj,obj)},title:function(str){var words=str.split(" ");for(var i=0;i<words.length;i++){words[i]=filters.capitalize(words[i])}return r.copySafeness(str,words.join(" "))},trim:function(str){return r.copySafeness(str,str.replace(/^\s*|\s*$/g,""))},truncate:function(input,length,killwords,end){var orig=input;length=length||255;if(input.length<=length)return input;if(killwords){input=input.substring(0,length)}else{var idx=input.lastIndexOf(" ",length);if(idx===-1){idx=length}input=input.substring(0,idx)}input+=end!==undefined&&end!==null?end:"...";return r.copySafeness(orig,input)},upper:function(str){return str.toUpperCase()},urlencode:function(obj){var enc=encodeURIComponent;if(lib.isString(obj)){return enc(obj)}else{var parts;if(lib.isArray(obj)){parts=obj.map(function(item){return enc(item[0])+"="+enc(item[1])})}else{parts=[];for(var k in obj){if(obj.hasOwnProperty(k)){parts.push(enc(k)+"="+enc(obj[k]))}}}return parts.join("&")}},urlize:function(str,length,nofollow){if(isNaN(length))length=Infinity;var noFollowAttr=nofollow===true?' rel="nofollow"':"";var puncRE=/^(?:\(|<|&lt;)?(.*?)(?:\.|,|\)|\n|&gt;)?$/;var emailRE=/^[\w.!#$%&'*+\-\/=?\^`{|}~]+@[a-z\d\-]+(\.[a-z\d\-]+)+$/i;var httpHttpsRE=/^https?:\/\/.*$/;var wwwRE=/^www\./;var tldRE=/\.(?:org|net|com)(?:\:|\/|$)/;var words=str.split(/\s+/).filter(function(word){return word&&word.length}).map(function(word){var matches=word.match(puncRE);var possibleUrl=matches&&matches[1]||word;if(httpHttpsRE.test(possibleUrl))return'<a href="'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";if(wwwRE.test(possibleUrl))return'<a href="http://'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";if(emailRE.test(possibleUrl))return'<a href="mailto:'+possibleUrl+'">'+possibleUrl+"</a>";if(tldRE.test(possibleUrl))return'<a href="http://'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";return word});return words.join(" ")},wordcount:function(str){var words=str?str.match(/\w+/g):null;return words?words.length:null},"float":function(val,def){var res=parseFloat(val);return isNaN(res)?def:res},"int":function(val,def){var res=parseInt(val,10);return isNaN(res)?def:res}};filters.d=filters["default"];filters.e=filters.escape;modules["filters"]=filters})();(function(){function cycler(items){var index=-1;this.current=null;return{reset:function(){index=-1;this.current=null},next:function(){index++;if(index>=items.length){index=0}this.current=items[index];return this.current}}}function joiner(sep){sep=sep||",";var first=true;return function(){var val=first?"":sep;first=false;return val}}var globals={range:function(start,stop,step){if(!stop){stop=start;start=0;step=1}else if(!step){step=1}var arr=[];for(var i=start;i<stop;i+=step){arr.push(i)}return arr},cycler:function(){return cycler(Array.prototype.slice.call(arguments))},joiner:function(sep){return joiner(sep)}};modules["globals"]=globals})();(function(){var path=modules["path"];var lib=modules["lib"];var Obj=modules["object"];var lexer=modules["lexer"];var compiler=modules["compiler"];var builtin_filters=modules["filters"];var builtin_loaders=modules["loaders"];var runtime=modules["runtime"];var globals=modules["globals"];var Frame=runtime.Frame;var Environment=Obj.extend({init:function(loaders,opts){opts=opts||{};this.dev=!!opts.dev;this.lexerTags=opts.tags;this.autoesc=!!opts.autoescape;if(!loaders){if(builtin_loaders.FileSystemLoader){this.loaders=[new builtin_loaders.FileSystemLoader("views")]}else{this.loaders=[new builtin_loaders.WebLoader("/views")]}}else{this.loaders=lib.isArray(loaders)?loaders:[loaders]}this.initCache();this.filters={};this.asyncFilters=[];this.extensions={};this.extensionsList=[];for(var name in builtin_filters){this.addFilter(name,builtin_filters[name])}},initCache:function(){var cache={};lib.each(this.loaders,function(loader){if(typeof loader.on==="function"){loader.on("update",function(template){cache[template]=null})}});this.cache=cache},addExtension:function(name,extension){extension._name=name;this.extensions[name]=extension;this.extensionsList.push(extension)},getExtension:function(name){return this.extensions[name]},addGlobal:function(name,value){globals[name]=value},addFilter:function(name,func,async){var wrapped=func;if(async){this.asyncFilters.push(name)}this.filters[name]=wrapped},getFilter:function(name){if(!this.filters[name]){throw new Error("filter not found: "+name)}return this.filters[name]},getTemplate:function(name,eagerCompile,cb){if(name&&name.raw){name=name.raw}if(lib.isFunction(eagerCompile)){cb=eagerCompile;eagerCompile=false}if(typeof name!=="string"){throw new Error("template names must be a string: "+name)}var tmpl=this.cache[name];if(tmpl){if(eagerCompile){tmpl.compile()}if(cb){cb(null,tmpl)}else{return tmpl}}else{var syncResult;lib.asyncIter(this.loaders,function(loader,i,next,done){function handle(src){if(src){done(src)}else{next()}}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){cb(err)}else{throw err}}else{var tmpl=new Template(info.src,this,info.path,eagerCompile);if(!info.noCache){this.cache[name]=tmpl}if(cb){cb(null,tmpl)}else{syncResult=tmpl}}}.bind(this));return syncResult}},express:function(app){var env=this;function NunjucksView(name,opts){this.name=name;this.path=name;this.defaultEngine=opts.defaultEngine;this.ext=path.extname(name);if(!this.ext&&!this.defaultEngine)throw new Error("No default engine was specified and no extension was provided.");if(!this.ext)this.name+=this.ext=("."!==this.defaultEngine[0]?".":"")+this.defaultEngine}NunjucksView.prototype.render=function(opts,cb){env.render(this.name,opts,cb)};app.set("view",NunjucksView)},render:function(name,ctx,cb){if(lib.isFunction(ctx)){cb=ctx;ctx=null}var syncResult=null;this.getTemplate(name,function(err,tmpl){if(err&&cb){cb(err)}else if(err){throw err}else{tmpl.render(ctx,cb||function(err,res){if(err){throw err}syncResult=res})}});return syncResult},renderString:function(src,ctx,cb){var tmpl=new Template(src,this);return tmpl.render(ctx,cb)}});var Context=Obj.extend({init:function(ctx,blocks){this.ctx=ctx;this.blocks={};this.exported=[];for(var name in blocks){this.addBlock(name,blocks[name])}},lookup:function(name){if(name in globals&&!(name in this.ctx)){return globals[name]}else{return this.ctx[name]}},setVariable:function(name,val){this.ctx[name]=val},getVariables:function(){return this.ctx},addBlock:function(name,block){this.blocks[name]=this.blocks[name]||[];this.blocks[name].push(block)},getBlock:function(name){if(!this.blocks[name]){throw new Error('unknown block "'+name+'"')}return this.blocks[name][0]},getSuper:function(env,name,block,frame,runtime,cb){var idx=lib.indexOf(this.blocks[name]||[],block);var blk=this.blocks[name][idx+1];var context=this;if(idx==-1||!blk){throw new Error('no super block available for "'+name+'"')}blk(env,context,frame,runtime,cb)},addExport:function(name){this.exported.push(name)},getExported:function(){var exported={};for(var i=0;i<this.exported.length;i++){var name=this.exported[i];exported[name]=this.ctx[name]}return exported}});var Template=Obj.extend({init:function(src,env,path,eagerCompile){this.env=env||new Environment;if(lib.isObject(src)){switch(src.type){case"code":this.tmplProps=src.obj;break;case"string":this.tmplStr=src.obj;break}}else if(lib.isString(src)){this.tmplStr=src}else{throw new Error("src must be a string or an object describing "+"the source")}this.path=path;if(eagerCompile){lib.withPrettyErrors(this.path,this.env.dev,this._compile.bind(this))}else{this.compiled=false}},render:function(ctx,frame,cb){if(typeof ctx==="function"){cb=ctx;ctx={}}else if(typeof frame==="function"){cb=frame;frame=null}return lib.withPrettyErrors(this.path,this.env.dev,function(){this.compile();var context=new Context(ctx||{},this.blocks);var syncResult=null;this.rootRenderFunc(this.env,context,frame||new Frame,runtime,cb||function(err,res){if(err){throw err}syncResult=res});return syncResult}.bind(this))},getExported:function(cb){this.compile();var context=new Context({},this.blocks);this.rootRenderFunc(this.env,context,new Frame,runtime,function(){cb(null,context.getExported())})},compile:function(){if(!this.compiled){this._compile()}},_compile:function(){var props;if(this.tmplProps){props=this.tmplProps}else{var source=compiler.compile(this.tmplStr,this.env.asyncFilters,this.env.extensionsList,this.path,this.env.lexerTags);var func=new Function(source);props=func()}this.blocks=this._getBlocks(props);this.rootRenderFunc=props.root;this.compiled=true},_getBlocks:function(props){var blocks={};for(var k in props){if(k.slice(0,2)=="b_"){blocks[k.slice(2)]=props[k]}}return blocks}});modules["environment"]={Environment:Environment,Template:Template}})();var nunjucks;var lib=modules["lib"];var env=modules["environment"];var compiler=modules["compiler"];var parser=modules["parser"];var lexer=modules["lexer"];var runtime=modules["runtime"];var Loader=modules["loader"];var loaders=modules["loaders"];var precompile=modules["precompile"];nunjucks={};nunjucks.Environment=env.Environment;nunjucks.Template=env.Template;nunjucks.Loader=Loader;nunjucks.FileSystemLoader=loaders.FileSystemLoader;nunjucks.WebLoader=loaders.WebLoader;nunjucks.compiler=compiler;nunjucks.parser=parser;nunjucks.lexer=lexer;nunjucks.runtime=runtime;var e;nunjucks.configure=function(templatesPath,opts){opts=opts||{};if(lib.isObject(templatesPath)){opts=templatesPath;templatesPath=null}var noWatch="watch"in opts?!opts.watch:false;var loader=loaders.FileSystemLoader||loaders.WebLoader;e=new env.Environment(new loader(templatesPath,noWatch),opts);if(opts&&opts.express){e.express(opts.express)}return e};nunjucks.compile=function(src,env,path,eagerCompile){if(!e){nunjucks.configure()}return new nunjucks.Template(src,env,path,eagerCompile)};nunjucks.render=function(name,ctx,cb){if(!e){nunjucks.configure()}return e.render(name,ctx,cb)};nunjucks.renderString=function(src,ctx,cb){if(!e){nunjucks.configure()}return e.renderString(src,ctx,cb)};if(precompile){nunjucks.precompile=precompile.precompile;nunjucks.precompileString=precompile.precompileString}nunjucks.require=function(name){return modules[name]};if(typeof define==="function"&&define.amd){define(function(){return nunjucks})}else{window.nunjucks=nunjucks;if(typeof module!=="undefined")module.exports=nunjucks}})();
(function(){var modules={};(function(){"use strict";function extend(cls,name,props){var F=function(){};F.prototype=cls.prototype;var prototype=new F;var fnTest=/xyz/.test(function(){xyz})?/\bparent\b/:/.*/;props=props||{};for(var k in props){var src=props[k];var parent=prototype[k];if(typeof parent==="function"&&typeof src==="function"&&fnTest.test(src)){prototype[k]=function(src,parent){return function(){var tmp=this.parent;this.parent=parent;var res=src.apply(this,arguments);this.parent=tmp;return res}}(src,parent)}else{prototype[k]=src}}prototype.typename=name;var new_cls=function(){if(prototype.init){prototype.init.apply(this,arguments)}};new_cls.prototype=prototype;new_cls.prototype.constructor=new_cls;new_cls.extend=function(name,props){if(typeof name==="object"){props=name;name="anonymous"}return extend(new_cls,name,props)};return new_cls}modules["object"]=extend(Object,"Object",{})})();(function(){"use strict";var ArrayProto=Array.prototype;var ObjProto=Object.prototype;var escapeMap={"&":"&amp;",'"':"&quot;","'":"&#39;","<":"&lt;",">":"&gt;"};var escapeRegex=/[&"'<>]/g;var lookupEscape=function(ch){return escapeMap[ch]};var exports=modules["lib"]={};exports.withPrettyErrors=function(path,withInternals,func){try{return func()}catch(e){if(!e.Update){e=new exports.TemplateError(e)}e.Update(path);if(!withInternals){var old=e;e=new Error(old.message);e.name=old.name}throw e}};exports.TemplateError=function(message,lineno,colno){var err=this;if(message instanceof Error){err=message;message=message.name+": "+message.message}else{if(Error.captureStackTrace){Error.captureStackTrace(err)}}err.name="Template render error";err.message=message;err.lineno=lineno;err.colno=colno;err.firstUpdate=true;err.Update=function(path){var message="("+(path||"unknown path")+")";if(this.firstUpdate){if(this.lineno&&this.colno){message+=" [Line "+this.lineno+", Column "+this.colno+"]"}else if(this.lineno){message+=" [Line "+this.lineno+"]"}}message+="\n ";if(this.firstUpdate){message+=" "}this.message=message+(this.message||"");this.firstUpdate=false;return this};return err};exports.TemplateError.prototype=Error.prototype;exports.escape=function(val){return val.replace(escapeRegex,lookupEscape)};exports.isFunction=function(obj){return ObjProto.toString.call(obj)==="[object Function]"};exports.isArray=Array.isArray||function(obj){return ObjProto.toString.call(obj)==="[object Array]"};exports.isString=function(obj){return ObjProto.toString.call(obj)==="[object String]"};exports.isObject=function(obj){return ObjProto.toString.call(obj)==="[object Object]"};exports.groupBy=function(obj,val){var result={};var iterator=exports.isFunction(val)?val:function(obj){return obj[val]};for(var i=0;i<obj.length;i++){var value=obj[i];var key=iterator(value,i);(result[key]||(result[key]=[])).push(value)}return result};exports.toArray=function(obj){return Array.prototype.slice.call(obj)};exports.without=function(array){var result=[];if(!array){return result}var index=-1,length=array.length,contains=exports.toArray(arguments).slice(1);while(++index<length){if(exports.indexOf(contains,array[index])===-1){result.push(array[index])}}return result};exports.extend=function(obj,obj2){for(var k in obj2){obj[k]=obj2[k]}return obj};exports.repeat=function(char_,n){var str="";for(var i=0;i<n;i++){str+=char_}return str};exports.each=function(obj,func,context){if(obj==null){return}if(ArrayProto.each&&obj.each===ArrayProto.each){obj.forEach(func,context)}else if(obj.length===+obj.length){for(var i=0,l=obj.length;i<l;i++){func.call(context,obj[i],i,obj)}}};exports.map=function(obj,func){var results=[];if(obj==null){return results}if(ArrayProto.map&&obj.map===ArrayProto.map){return obj.map(func)}for(var i=0;i<obj.length;i++){results[results.length]=func(obj[i],i)}if(obj.length===+obj.length){results.length=obj.length}return results};exports.asyncIter=function(arr,iter,cb){var i=-1;function next(){i++;if(i<arr.length){iter(arr[i],i,next,cb)}else{cb()}}next()};exports.asyncFor=function(obj,iter,cb){var keys=exports.keys(obj);var len=keys.length;var i=-1;function next(){i++;var k=keys[i];if(i<len){iter(k,obj[k],i,len,next)}else{cb()}}next()};exports.indexOf=Array.prototype.indexOf?function(arr,searchElement,fromIndex){return Array.prototype.indexOf.call(arr,searchElement,fromIndex)}:function(arr,searchElement,fromIndex){var length=this.length>>>0;fromIndex=+fromIndex||0;if(Math.abs(fromIndex)===Infinity){fromIndex=0}if(fromIndex<0){fromIndex+=length;if(fromIndex<0){fromIndex=0}}for(;fromIndex<length;fromIndex++){if(arr[fromIndex]===searchElement){return fromIndex}}return-1};if(!Array.prototype.map){Array.prototype.map=function(){throw new Error("map is unimplemented for this js engine")}}exports.keys=function(obj){if(Object.prototype.keys){return obj.keys()}else{var keys=[];for(var k in obj){if(obj.hasOwnProperty(k)){keys.push(k)}}return keys}}})();(function(){"use strict";var lib=modules["lib"];var Obj=modules["object"];var Frame=Obj.extend({init:function(parent){this.variables={};this.parent=parent},set:function(name,val,resolveUp){var parts=name.split(".");var obj=this.variables;var frame=this;if(resolveUp){if(frame=this.resolve(parts[0])){frame.set(name,val);return}frame=this}for(var i=0;i<parts.length-1;i++){var id=parts[i];if(!obj[id]){obj[id]={}}obj=obj[id]}obj[parts[parts.length-1]]=val},get:function(name){var val=this.variables[name];if(val!==undefined&&val!==null){return val}return null},lookup:function(name){var p=this.parent;var val=this.variables[name];if(val!==undefined&&val!==null){return val}return p&&p.lookup(name)},resolve:function(name){var p=this.parent;var val=this.variables[name];if(val!==undefined&&val!==null){return this}return p&&p.resolve(name)},push:function(){return new Frame(this)},pop:function(){return this.parent}});function makeMacro(argNames,kwargNames,func){return function(){var argCount=numArgs(arguments);var args;var kwargs=getKeywordArgs(arguments);if(argCount>argNames.length){args=Array.prototype.slice.call(arguments,0,argNames.length);var vals=Array.prototype.slice.call(arguments,args.length,argCount);for(var i=0;i<vals.length;i++){if(i<kwargNames.length){kwargs[kwargNames[i]]=vals[i]}}args.push(kwargs)}else if(argCount<argNames.length){args=Array.prototype.slice.call(arguments,0,argCount);for(var i=argCount;i<argNames.length;i++){var arg=argNames[i];args.push(kwargs[arg]);delete kwargs[arg]}args.push(kwargs)}else{args=arguments}return func.apply(this,args)}}function makeKeywordArgs(obj){obj.__keywords=true;return obj}function getKeywordArgs(args){var len=args.length;if(len){var lastArg=args[len-1];if(lastArg&&lastArg.hasOwnProperty("__keywords")){return lastArg}}return{}}function numArgs(args){var len=args.length;if(len===0){return 0}var lastArg=args[len-1];if(lastArg&&lastArg.hasOwnProperty("__keywords")){return len-1}else{return len}}function SafeString(val){if(typeof val!=="string"){return val}this.val=val}SafeString.prototype=Object.create(String.prototype);SafeString.prototype.valueOf=function(){return this.val};SafeString.prototype.toString=function(){return this.val};function copySafeness(dest,target){if(dest instanceof SafeString){return new SafeString(target)}return target.toString()}function markSafe(val){var type=typeof val;if(type==="string"){return new SafeString(val)}else if(type!=="function"){return val}else{return function(){var ret=val.apply(this,arguments);if(typeof ret==="string"){return new SafeString(ret)}return ret}}}function suppressValue(val,autoescape){val=val!==undefined&&val!==null?val:"";if(autoescape&&typeof val==="string"){val=lib.escape(val)}return val}function memberLookup(obj,val){obj=obj||{};if(typeof obj[val]==="function"){return function(){return obj[val].apply(obj,arguments)}}return obj[val]}function callWrap(obj,name,args){if(!obj){throw new Error("Unable to call `"+name+"`, which is undefined or falsey")}else if(typeof obj!=="function"){throw new Error("Unable to call `"+name+"`, which is not a function")}return obj.apply(this,args)}function contextOrFrameLookup(context,frame,name){var val=frame.lookup(name);return val!==undefined&&val!==null?val:context.lookup(name)}function handleError(error,lineno,colno){if(error.lineno){return error}else{return new lib.TemplateError(error,lineno,colno)}}function asyncEach(arr,dimen,iter,cb){if(lib.isArray(arr)){var len=arr.length;lib.asyncIter(arr,function(item,i,next){switch(dimen){case 1:iter(item,i,len,next);break;case 2:iter(item[0],item[1],i,len,next);break;case 3:iter(item[0],item[1],item[2],i,len,next);break;default:item.push(i,next);iter.apply(this,item)}},cb)}else{lib.asyncFor(arr,function(key,val,i,len,next){iter(key,val,i,len,next)},cb)}}function asyncAll(arr,dimen,func,cb){var finished=0;var len;var outputArr;function done(i,output){finished++;outputArr[i]=output;if(finished===len){cb(null,outputArr.join(""))}}if(lib.isArray(arr)){len=arr.length;outputArr=new Array(len);if(len===0){cb(null,"")}else{for(var i=0;i<arr.length;i++){var item=arr[i];switch(dimen){case 1:func(item,i,len,done);break;case 2:func(item[0],item[1],i,len,done);break;case 3:func(item[0],item[1],item[2],i,len,done);break;default:item.push(i,done);func.apply(this,item)}}}}else{var keys=lib.keys(arr);len=keys.length;outputArr=new Array(len);if(len===0){cb(null,"")}else{for(var i=0;i<keys.length;i++){var k=keys[i];func(k,arr[k],i,len,done)}}}}modules["runtime"]={Frame:Frame,makeMacro:makeMacro,makeKeywordArgs:makeKeywordArgs,numArgs:numArgs,suppressValue:suppressValue,memberLookup:memberLookup,contextOrFrameLookup:contextOrFrameLookup,callWrap:callWrap,handleError:handleError,isArray:lib.isArray,keys:lib.keys,SafeString:SafeString,copySafeness:copySafeness,markSafe:markSafe,asyncEach:asyncEach,asyncAll:asyncAll}})();(function(){"use strict";var path=modules["path"];var Obj=modules["object"];var lib=modules["lib"];var Loader=Obj.extend({on:function(name,func){this.listeners=this.listeners||{};this.listeners[name]=this.listeners[name]||[];this.listeners[name].push(func)},emit:function(name){var args=Array.prototype.slice.call(arguments,1);if(this.listeners&&this.listeners[name]){lib.each(this.listeners[name],function(listener){listener.apply(null,args)})}},resolve:function(from,to){return path.resolve(path.dirname(from),to)},isRelative:function(filename){return filename.indexOf("./")===0||filename.indexOf("../")===0}});modules["loader"]=Loader})();(function(){"use strict";var Loader=modules["loader"];var WebLoader=Loader.extend({init:function(baseURL,neverUpdate){this.precompiled=window.nunjucksPrecompiled||{};this.baseURL=baseURL||"";this.neverUpdate=neverUpdate},getSource:function(name){if(this.precompiled[name]){return{src:{type:"code",obj:this.precompiled[name]},path:name}}else{var src=this.fetch(this.baseURL+"/"+name);if(!src){return null}return{src:src,path:name,noCache:!this.neverUpdate}}},fetch:function(url,callback){var ajax;var loading=true;var src;if(window.XMLHttpRequest){ajax=new XMLHttpRequest}else if(window.ActiveXObject){ajax=new ActiveXObject("Microsoft.XMLHTTP")}ajax.onreadystatechange=function(){if(ajax.readyState===4&&(ajax.status===0||ajax.status===200)&&loading){loading=false;src=ajax.responseText}};url+=(url.indexOf("?")===-1?"?":"&")+"s="+(new Date).getTime();ajax.open("GET",url,false);ajax.send();return src}});modules["web-loaders"]={WebLoader:WebLoader}})();(function(){if(typeof window==="undefined"||window!==this){modules["loaders"]=modules["node-loaders"]}else{modules["loaders"]=modules["web-loaders"]}})();(function(){"use strict";var lib=modules["lib"];var r=modules["runtime"];var filters={abs:function(n){return Math.abs(n)},batch:function(arr,linecount,fill_with){var res=[];var tmp=[];for(var i=0;i<arr.length;i++){if(i%linecount===0&&tmp.length){res.push(tmp);tmp=[]}tmp.push(arr[i])}if(tmp.length){if(fill_with){for(var i=tmp.length;i<linecount;i++){tmp.push(fill_with)}}res.push(tmp)}return res},capitalize:function(str){var ret=str.toLowerCase();return r.copySafeness(str,ret.charAt(0).toUpperCase()+ret.slice(1))},center:function(str,width){width=width||80;if(str.length>=width){return str}var spaces=width-str.length;var pre=lib.repeat(" ",spaces/2-spaces%2);var post=lib.repeat(" ",spaces/2);return r.copySafeness(str,pre+str+post)},"default":function(val,def){return val?val:def},dictsort:function(val,case_sensitive,by){if(!lib.isObject(val)){throw new lib.TemplateError("dictsort filter: val must be an object")}var array=[];for(var k in val){array.push([k,val[k]])}var si;if(by===undefined||by==="key"){si=0}else if(by==="value"){si=1}else{throw new lib.TemplateError("dictsort filter: You can only sort by either key or value")}array.sort(function(t1,t2){var a=t1[si];var b=t2[si];if(!case_sensitive){if(lib.isString(a)){a=a.toUpperCase()}if(lib.isString(b)){b=b.toUpperCase()}}return a>b?1:a===b?0:-1});return array},escape:function(str){if(typeof str==="string"||str instanceof r.SafeString){return lib.escape(str)}return str},safe:function(str){return r.markSafe(str)},first:function(arr){return arr[0]},groupby:function(arr,attr){return lib.groupBy(arr,attr)},indent:function(str,width,indentfirst){width=width||4;var res="";var lines=str.split("\n");var sp=lib.repeat(" ",width);for(var i=0;i<lines.length;i++){if(i===0&&!indentfirst){res+=lines[i]+"\n"}else{res+=sp+lines[i]+"\n"}}return r.copySafeness(str,res)},join:function(arr,del,attr){del=del||"";if(attr){arr=lib.map(arr,function(v){return v[attr]})}return arr.join(del)},last:function(arr){return arr[arr.length-1]},length:function(arr){return arr!==undefined?arr.length:0},list:function(val){if(lib.isString(val)){return val.split("")}else if(lib.isObject(val)){var keys=[];if(Object.keys){keys=Object.keys(val)}else{for(var k in val){keys.push(k)}}return lib.map(keys,function(k){return{key:k,value:val[k]}})}else if(lib.isArray(val)){return val}else{throw new lib.TemplateError("list filter: type not iterable")}},lower:function(str){return str.toLowerCase()},random:function(arr){return arr[Math.floor(Math.random()*arr.length)]},rejectattr:function(arr,attr){return arr.filter(function(item){return!item[attr]})},selectattr:function(arr,attr){return arr.filter(function(item){return!!item[attr]})},replace:function(str,old,new_,maxCount){if(old instanceof RegExp){return str.replace(old,new_)}var res=str;var last=res;var count=1;res=res.replace(old,new_);while(last!==res){if(count>=maxCount){break}last=res;res=res.replace(old,new_);count++}return r.copySafeness(str,res)},reverse:function(val){var arr;if(lib.isString(val)){arr=filters.list(val)}else{arr=lib.map(val,function(v){return v})}arr.reverse();if(lib.isString(val)){return r.copySafeness(val,arr.join(""))}return arr},round:function(val,precision,method){precision=precision||0;var factor=Math.pow(10,precision);var rounder;if(method==="ceil"){rounder=Math.ceil}else if(method==="floor"){rounder=Math.floor}else{rounder=Math.round}return rounder(val*factor)/factor},slice:function(arr,slices,fillWith){var sliceLength=Math.floor(arr.length/slices);var extra=arr.length%slices;var offset=0;var res=[];for(var i=0;i<slices;i++){var start=offset+i*sliceLength;if(i<extra){offset++}var end=offset+(i+1)*sliceLength;var slice=arr.slice(start,end);if(fillWith&&i>=extra){slice.push(fillWith)}res.push(slice)}return res},sort:function(arr,reverse,caseSens,attr){arr=lib.map(arr,function(v){return v});arr.sort(function(a,b){var x,y;if(attr){x=a[attr];y=b[attr]}else{x=a;y=b}if(!caseSens&&lib.isString(x)&&lib.isString(y)){x=x.toLowerCase();y=y.toLowerCase()}if(x<y){return reverse?1:-1}else if(x>y){return reverse?-1:1}else{return 0}});return arr},string:function(obj){return r.copySafeness(obj,obj)},title:function(str){var words=str.split(" ");for(var i=0;i<words.length;i++){words[i]=filters.capitalize(words[i])}return r.copySafeness(str,words.join(" "))},trim:function(str){return r.copySafeness(str,str.replace(/^\s*|\s*$/g,""))},truncate:function(input,length,killwords,end){var orig=input;length=length||255;if(input.length<=length)return input;if(killwords){input=input.substring(0,length)}else{var idx=input.lastIndexOf(" ",length);if(idx===-1){idx=length}input=input.substring(0,idx)}input+=end!==undefined&&end!==null?end:"...";return r.copySafeness(orig,input)},upper:function(str){return str.toUpperCase()},urlencode:function(obj){var enc=encodeURIComponent;if(lib.isString(obj)){return enc(obj)}else{var parts;if(lib.isArray(obj)){parts=obj.map(function(item){return enc(item[0])+"="+enc(item[1])})}else{parts=[];for(var k in obj){if(obj.hasOwnProperty(k)){parts.push(enc(k)+"="+enc(obj[k]))}}}return parts.join("&")}},urlize:function(str,length,nofollow){if(isNaN(length))length=Infinity;var noFollowAttr=nofollow===true?' rel="nofollow"':"";var puncRE=/^(?:\(|<|&lt;)?(.*?)(?:\.|,|\)|\n|&gt;)?$/;var emailRE=/^[\w.!#$%&'*+\-\/=?\^`{|}~]+@[a-z\d\-]+(\.[a-z\d\-]+)+$/i;var httpHttpsRE=/^https?:\/\/.*$/;var wwwRE=/^www\./;var tldRE=/\.(?:org|net|com)(?:\:|\/|$)/;var words=str.split(/\s+/).filter(function(word){return word&&word.length}).map(function(word){var matches=word.match(puncRE);var possibleUrl=matches&&matches[1]||word;if(httpHttpsRE.test(possibleUrl))return'<a href="'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";if(wwwRE.test(possibleUrl))return'<a href="http://'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";if(emailRE.test(possibleUrl))return'<a href="mailto:'+possibleUrl+'">'+possibleUrl+"</a>";if(tldRE.test(possibleUrl))return'<a href="http://'+possibleUrl+'"'+noFollowAttr+">"+possibleUrl.substr(0,length)+"</a>";return word});return words.join(" ")},wordcount:function(str){var words=str?str.match(/\w+/g):null;return words?words.length:null},"float":function(val,def){var res=parseFloat(val);return isNaN(res)?def:res},"int":function(val,def){var res=parseInt(val,10);return isNaN(res)?def:res}};filters.d=filters["default"];filters.e=filters.escape;modules["filters"]=filters})();(function(){"use strict";function cycler(items){var index=-1;return{current:null,reset:function(){index=-1;this.current=null},next:function(){index++;if(index>=items.length){index=0}this.current=items[index];return this.current}}}function joiner(sep){sep=sep||",";var first=true;return function(){var val=first?"":sep;first=false;return val}}var globals={range:function(start,stop,step){if(!stop){stop=start;start=0;step=1}else if(!step){step=1}var arr=[];for(var i=start;i<stop;i+=step){arr.push(i)}return arr},cycler:function(){return cycler(Array.prototype.slice.call(arguments))},joiner:function(sep){return joiner(sep)}};modules["globals"]=globals})();(function(){"use strict";var path=modules["path"];var lib=modules["lib"];var Obj=modules["object"];var lexer=modules["lexer"];var compiler=modules["compiler"];var builtin_filters=modules["filters"];var builtin_loaders=modules["loaders"];var runtime=modules["runtime"];var globals=modules["globals"];var Frame=runtime.Frame;var Environment=Obj.extend({init:function(loaders,opts){var opts=this.opts=opts||{};this.opts.dev=!!opts.dev;this.opts.autoescape=!!opts.autoescape;this.opts.trimBlocks=!!opts.trimBlocks;this.opts.lstripBlocks=!!opts.lstripBlocks;if(!loaders){if(builtin_loaders.FileSystemLoader){this.loaders=[new builtin_loaders.FileSystemLoader("views")]}else{this.loaders=[new builtin_loaders.WebLoader("/views")]}}else{this.loaders=lib.isArray(loaders)?loaders:[loaders]}this.initCache();this.filters={};this.asyncFilters=[];this.extensions={};this.extensionsList=[];for(var name in builtin_filters){this.addFilter(name,builtin_filters[name])}},initCache:function(){lib.each(this.loaders,function(loader){loader.cache={};if(typeof loader.on==="function"){loader.on("update",function(template){loader.cache[template]=null})}})},addExtension:function(name,extension){extension._name=name;this.extensions[name]=extension;this.extensionsList.push(extension)},getExtension:function(name){return this.extensions[name]},addGlobal:function(name,value){globals[name]=value},addFilter:function(name,func,async){var wrapped=func;if(async){this.asyncFilters.push(name)}this.filters[name]=wrapped},getFilter:function(name){if(!this.filters[name]){throw new Error("filter not found: "+name)}return this.filters[name]},resolveTemplate:function(loader,parentName,filename){var isRelative=loader.isRelative&&parentName?loader.isRelative(filename):false;return isRelative&&loader.resolve?loader.resolve(parentName,filename):filename},getTemplate:function(name,eagerCompile,parentName,cb){var that=this;var tmpl=null;if(name&&name.raw){name=name.raw}if(lib.isFunction(parentName)){cb=parentName;parentName=null;eagerCompile=eagerCompile||false}if(lib.isFunction(eagerCompile)){cb=eagerCompile;eagerCompile=false}if(typeof name!=="string"){throw new Error("template names must be a string: "+name)}for(var i=0;i<this.loaders.length;i++){var _name=this.resolveTemplate(this.loaders[i],parentName,name);tmpl=this.loaders[i].cache[_name];if(tmpl)break}if(tmpl){if(eagerCompile){tmpl.compile()}if(cb){cb(null,tmpl)}else{return tmpl}}else{var syncResult;lib.asyncIter(this.loaders,function(loader,i,next,done){function handle(src){if(src){src.loader=loader;done(src)}else{next()}}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){cb(err)}else{throw err}}else{var tmpl=new Template(info.src,this,info.path,eagerCompile);if(!info.noCache){info.loader.cache[name]=tmpl}if(cb){cb(null,tmpl)}else{syncResult=tmpl}}}.bind(this));return syncResult}},express:function(app){var env=this;function NunjucksView(name,opts){this.name=name;this.path=name;this.defaultEngine=opts.defaultEngine;this.ext=path.extname(name);if(!this.ext&&!this.defaultEngine)throw new Error("No default engine was specified and no extension was provided.");if(!this.ext)this.name+=this.ext=("."!==this.defaultEngine[0]?".":"")+this.defaultEngine}NunjucksView.prototype.render=function(opts,cb){env.render(this.name,opts,cb)};app.set("view",NunjucksView)},render:function(name,ctx,cb){if(lib.isFunction(ctx)){cb=ctx;ctx=null}var syncResult=null;this.getTemplate(name,function(err,tmpl){if(err&&cb){cb(err)}else if(err){throw err}else{tmpl.render(ctx,cb||function(err,res){if(err){throw err}syncResult=res})}});return syncResult},renderString:function(src,ctx,opts,cb){if(lib.isFunction(opts)){cb=opts;opts={}}opts=opts||{};var tmpl=new Template(src,this,opts.path);return tmpl.render(ctx,cb)}});var Context=Obj.extend({init:function(ctx,blocks){this.ctx=ctx;this.blocks={};this.exported=[];for(var name in blocks){this.addBlock(name,blocks[name])}},lookup:function(name){if(name in globals&&!(name in this.ctx)){return globals[name]}else{return this.ctx[name]}},setVariable:function(name,val){this.ctx[name]=val},getVariables:function(){return this.ctx},addBlock:function(name,block){this.blocks[name]=this.blocks[name]||[];this.blocks[name].push(block)},getBlock:function(name){if(!this.blocks[name]){throw new Error('unknown block "'+name+'"')}return this.blocks[name][0]},getSuper:function(env,name,block,frame,runtime,cb){var idx=lib.indexOf(this.blocks[name]||[],block);var blk=this.blocks[name][idx+1];var context=this;if(idx===-1||!blk){throw new Error('no super block available for "'+name+'"')}blk(env,context,frame,runtime,cb)},addExport:function(name){this.exported.push(name)},getExported:function(){var exported={};for(var i=0;i<this.exported.length;i++){var name=this.exported[i];exported[name]=this.ctx[name]}return exported}});var Template=Obj.extend({init:function(src,env,path,eagerCompile){this.env=env||new Environment;if(lib.isObject(src)){switch(src.type){case"code":this.tmplProps=src.obj;break;case"string":this.tmplStr=src.obj;break}}else if(lib.isString(src)){this.tmplStr=src}else{throw new Error("src must be a string or an object describing "+"the source")}this.path=path;if(eagerCompile){lib.withPrettyErrors(this.path,this.env.dev,this._compile.bind(this))}else{this.compiled=false}},render:function(ctx,frame,cb){if(typeof ctx==="function"){cb=ctx;ctx={}}else if(typeof frame==="function"){cb=frame;frame=null}return lib.withPrettyErrors(this.path,this.env.dev,function(){try{this.compile()}catch(e){if(cb)return cb(e);else throw e}var context=new Context(ctx||{},this.blocks);var syncResult=null;this.rootRenderFunc(this.env,context,frame||new Frame,runtime,cb||function(err,res){if(err){throw err}syncResult=res});return syncResult}.bind(this))},getExported:function(ctx,frame,cb){if(typeof ctx==="function"){cb=ctx;ctx={}}if(typeof frame==="function"){cb=frame;frame=null}try{this.compile()}catch(e){if(cb)return cb(e);else throw e}var context=new Context(ctx||{},this.blocks);this.rootRenderFunc(this.env,context,frame||new Frame,runtime,function(){cb(null,context.getExported())})},compile:function(){if(!this.compiled){this._compile()}},_compile:function(){var props;if(this.tmplProps){props=this.tmplProps}else{var source=compiler.compile(this.tmplStr,this.env.asyncFilters,this.env.extensionsList,this.path,this.env.opts);var func=new Function(source);props=func()}this.blocks=this._getBlocks(props);this.rootRenderFunc=props.root;this.compiled=true},_getBlocks:function(props){var blocks={};for(var k in props){if(k.slice(0,2)==="b_"){blocks[k.slice(2)]=props[k]}}return blocks}});modules["environment"]={Environment:Environment,Template:Template}})();var nunjucks;var lib=modules["lib"];var env=modules["environment"];var compiler=modules["compiler"];var parser=modules["parser"];var lexer=modules["lexer"];var runtime=modules["runtime"];var Loader=modules["loader"];var loaders=modules["loaders"];var precompile=modules["precompile"];nunjucks={};nunjucks.Environment=env.Environment;nunjucks.Template=env.Template;nunjucks.Loader=Loader;nunjucks.FileSystemLoader=loaders.FileSystemLoader;nunjucks.WebLoader=loaders.WebLoader;nunjucks.compiler=compiler;nunjucks.parser=parser;nunjucks.lexer=lexer;nunjucks.runtime=runtime;var e;nunjucks.configure=function(templatesPath,opts){opts=opts||{};if(lib.isObject(templatesPath)){opts=templatesPath;templatesPath=null}var noWatch="watch"in opts?!opts.watch:false;var loader=loaders.FileSystemLoader||loaders.WebLoader;e=new env.Environment(new loader(templatesPath,noWatch),opts);if(opts&&opts.express){e.express(opts.express)}return e};nunjucks.compile=function(src,env,path,eagerCompile){if(!e){nunjucks.configure()}return new nunjucks.Template(src,env,path,eagerCompile)};nunjucks.render=function(name,ctx,cb){if(!e){nunjucks.configure()}return e.render(name,ctx,cb)};nunjucks.renderString=function(src,ctx,cb){if(!e){nunjucks.configure()}return e.renderString(src,ctx,cb)};if(precompile){nunjucks.precompile=precompile.precompile;nunjucks.precompileString=precompile.precompileString}nunjucks.require=function(name){return modules[name]};if(typeof define==="function"&&define.amd){define(function(){return nunjucks})}else{window.nunjucks=nunjucks;if(typeof module!=="undefined")module.exports=nunjucks}})();
(function() {
var expect, Environment, Loader, templatesPath;
'use strict';
if(typeof require != 'undefined') {
var expect, util, Environment, Loader, templatesPath;
var path = require('path');
var os = require('os');
if(typeof require !== 'undefined') {
expect = require('expect.js');
util = require('./util');
Environment = require('../src/environment').Environment;

@@ -25,3 +30,28 @@ Loader = require('../src/node-loaders').FileSystemLoader;

});
it('should handle correctly relative paths', function() {
var env = new Environment(new Loader(templatesPath));
var child1 = env.getTemplate('relative/test1.html');
var child2 = env.getTemplate('relative/test2.html');
expect(child1.render()).to.be('FooTest1BazFizzle');
expect(child2.render()).to.be('FooTest2BazFizzle');
});
it('should handle correctly cache for relative paths', function() {
var env = new Environment(new Loader(templatesPath));
var test = env.getTemplate('relative/test-cache.html');
expect(util.normEOL(test.render())).to.be('Test1\nTest2');
});
it('should handle correctly relative paths in renderString', function() {
var env = new Environment(new Loader(templatesPath));
expect(env.renderString('{% extends "./relative/test1.html" %}{% block block1 %}Test3{% endblock %}', {}, {
path: path.resolve(templatesPath, 'string.html')
})).to.be('FooTest3BazFizzle');
});
});
})();
(function() {
'use strict';
var expect, util, Environment, Template, fs;
if(typeof require != 'undefined') {
if(typeof require !== 'undefined') {
expect = require('expect.js');

@@ -147,2 +149,8 @@ util = require('./util');

equal('{% ' + block + ' i in arr %}{{ i }}{% else %}empty{% ' + end + ' %}',
{ arr: [1, 2, 3, 4, 5] }, '12345');
equal('{% ' + block + ' i in arr %}{{ i }}{% else %}empty{% ' + end + ' %}',
{ arr: [] }, 'empty');
equal('{% ' + block + ' a, b, c in arr %}' +

@@ -285,2 +293,9 @@ '{{ a }},{{ b }},{{ c }}.{% ' + end + ' %}',

render('{% if test %}{{ tmpl | getContents }}{% endif %}oof',
{ tmpl: 'tests/templates/for-async-content.html' },
opts,
function(err, res) {
expect(res).to.be('oof');
});
render('{% if tmpl %}' +

@@ -361,2 +376,9 @@ '{% for i in [0, 1] %}{{ tmpl | getContents }}*{% endfor %}' +

equal('{% if 1 in [1, 2] %}yes{% endif %}', 'yes');
equal('{% if 1 in [2, 3] %}yes{% endif %}', '');
equal('{% if 1 not in [1, 2] %}yes{% endif %}', '');
equal('{% if 1 not in [2, 3] %}yes{% endif %}', 'yes');
equal('{% if "a" in vals %}yes{% endif %}',
{'vals': ['a', 'b']}, 'yes');
finish(done);

@@ -374,5 +396,5 @@ });

// equal('{% macro foo(x) %}{{ x|title }}{% endmacro %}' +
// '{{ foo("foo") }}',
// 'Foo');
equal('{% macro foo(x) %}{{ x|title }}{% endmacro %}' +
'{{ foo("foo") }}',
'Foo');

@@ -437,13 +459,47 @@ equal('{% macro foo(x, y) %}{{ y }}{% endmacro %}' +

equal('{% macro foo() %}{% include "include.html" %}{% endmacro %}' +
'{{ foo() }}',
{ name: 'james' },
'FooInclude james');
finish(done);
});
it('should compile call blocks', function(done) {
equal('{% macro wrap(el) %}' +
'<{{ el }}>{{ caller() }}</{{ el }}>' +
'{% endmacro %}' +
'{% call wrap("div") %}Hello{% endcall %}',
'<div>Hello</div>');
finish(done);
});
it('should compile call blocks with args', function(done) {
equal('{% macro list(items) %}' +
'<ul>{% for i in items %}' +
'<li>{{ caller(i) }}</li>' +
'{% endfor %}</ul>' +
'{% endmacro %}' +
'{% call(item) list(["a", "b"]) %}{{ item }}{% endcall %}',
'<ul><li>a</li><li>b</li></ul>');
finish(done);
});
it('should compile call blocks using imported macros', function(done) {
equal('{% import "import.html" as imp %}' +
'{% call imp.wrap("span") %}Hey{% endcall %}',
'<span>Hey</span>');
finish(done);
});
it('should import templates', function(done) {
equal('{% import "import.html" as imp %}' +
'{{ imp.foo() }} {{ imp.bar }}',
"Here's a macro baz");
'Here\'s a macro baz');
equal('{% from "import.html" import foo as baz, bar %}' +
'{{ bar }} {{ baz() }}',
"baz Here's a macro");
'baz Here\'s a macro');

@@ -464,2 +520,44 @@ // TODO: Should the for loop create a new frame for each

it('should import templates with context', function(done) {
equal('{% set bar = "BAR" %}' +
'{% import "import-context.html" as imp with context %}' +
'{{ imp.foo() }}',
'Here\'s BAR');
equal('{% set bar = "BAR" %}' +
'{% from "import-context.html" import foo with context %}' +
'{{ foo() }}',
'Here\'s BAR');
finish(done);
});
it('should import templates without context', function(done) {
equal('{% set bar = "BAR" %}' +
'{% import "import-context.html" as imp without context %}' +
'{{ imp.foo() }}',
'Here\'s ');
equal('{% set bar = "BAR" %}' +
'{% from "import-context.html" import foo without context %}' +
'{{ foo() }}',
'Here\'s ');
finish(done);
});
it('should default to importing without context', function(done) {
equal('{% set bar = "BAR" %}' +
'{% import "import-context.html" as imp %}' +
'{{ imp.foo() }}',
'Here\'s ');
equal('{% set bar = "BAR" %}' +
'{% from "import-context.html" import foo %}' +
'{{ foo() }}',
'Here\'s ');
finish(done);
});
it('should inherit templates', function(done) {

@@ -522,7 +620,7 @@ equal('{% extends "base.html" %}', 'FooBarBazFizzle');

equal('hello world {% include tmpl %}',
{ name: 'thedude', tmpl: "include.html" },
{ name: 'thedude', tmpl: 'include.html' },
'hello world FooInclude thedude');
equal('hello world {% include data.tmpl %}',
{ name: 'thedude', data: {tmpl: "include.html"} },
{ name: 'thedude', data: {tmpl: 'include.html'} },
'hello world FooInclude thedude');

@@ -533,2 +631,16 @@

/**
* This test checks that this issue is resolved: http://stackoverflow.com/questions/21777058/loop-index-in-included-nunjucks-file
*/
it('should have access to "loop" inside an include', function(done) {
equal('{% for item in [1,2,3] %}{% include "include-in-loop.html" %}{% endfor %}',
'1,0,true\n2,1,false\n3,2,false\n');
equal('{% for k,v in items %}{% include "include-in-loop.html" %}{% endfor %}',
{items: {'a': 'A', 'b': 'B'}},
'1,0,true\n2,1,false\n');
finish(done);
});
it('should maintain nested scopes', function(done) {

@@ -583,2 +695,29 @@ equal('{% for i in [1,2] %}' +

// `set` should only set within its current scope
equal('{% for i in [1] %}{% set val=5 %}{% endfor %}' +
'{{ val }}',
'');
equal('{% for i in [1,2,3] %}' +
'{% if not val %}{% set val=5 %}{% endif %}' +
'{% set val=val+1 %}{{ val }}' +
'{% endfor %}' +
'afterwards: {{ val }}',
'678afterwards: ');
// however, like Python, if a variable has been set in an
// above scope, any other set should correctly resolve to
// that frame
equal('{% set val=1 %}' +
'{% for i in [1] %}{% set val=5 %}{% endfor %}' +
'{{ val }}',
'5');
equal('{% set val=5 %}' +
'{% for i in [1,2,3] %}' +
'{% set val=val+1 %}{{ val }}' +
'{% endfor %}' +
'afterwards: {{ val }}',
'678afterwards: 8');
finish(done);

@@ -627,3 +766,3 @@ });

var content = parser.parseUntilBlocks("endtest");
var content = parser.parseUntilBlocks('endtest');
var tag = new nodes.CallExtension(this, 'run', null, [content]);

@@ -637,3 +776,3 @@ parser.advanceAfterBlockEnd();

// Reverse the string
return content().split("").reverse().join("");
return content().split('').reverse().join('');
};

@@ -664,3 +803,3 @@ }

// Reverse the string
return arg1.split("").reverse().join("");
return arg1.split('').reverse().join('');
};

@@ -701,6 +840,6 @@ }

this.run = function(context, body, intermediate) {
var output = body().split("").join(",");
var output = body().split('').join(',');
if(intermediate) {
// Reverse the string.
output += intermediate().split("").reverse().join("");
output += intermediate().split('').reverse().join('');
}

@@ -749,3 +888,3 @@ return output;

this.run = function(context, prefix, kwargs, body) {
if(typeof prefix == 'function') {
if(typeof prefix === 'function') {
body = prefix;

@@ -755,3 +894,3 @@ prefix = '';

}
else if(typeof kwargs == 'function') {
else if(typeof kwargs === 'function') {
body = kwargs;

@@ -854,2 +993,38 @@ kwargs = {};

it('should not autoescape when extension set false', function(done) {
function testExtension() {
this.tags = ['test'];
this.autoescape = false;
this.parse = function(parser, nodes) {
var tok = parser.nextToken();
var args = parser.parseSignature(null, true);
parser.advanceAfterBlockEnd(tok.value);
return new nodes.CallExtension(this, 'run', args, null);
};
this.run = function(context) {
// Reverse the string
return '<b>Foo</b>';
};
}
var opts = {
extensions: { 'testExtension': new testExtension() },
autoescape: true
};
render(
'{% test "123456" %}',
null,
opts,
function(err, res) {
expect(res).to.be('<b>Foo</b>');
}
);
finish(done);
});
it('should pass context as this to filters', function(done) {

@@ -869,3 +1044,13 @@ render(

});
it('should render regexs', function(done) {
equal('{{ r/name [0-9] \\// }}',
'/name [0-9] \\//');
equal('{{ r/x/gi }}',
'/x/gi');
finish(done);
});
});
})();
nunjucks.configure({ autoescape: true });
aboutTmpl({ poop: 'pooop<><>' }, function(err, res) {
console.log(res);
});
// aboutTmpl({ poop: 'pooop<><>' }, function(err, res) {
// console.log(res);
// });
(function() {
'use strict';
var expect, util, lib;
if(typeof require != 'undefined') {
if(typeof require !== 'undefined') {
expect = require('expect.js');

@@ -65,3 +67,3 @@ util = require('./util');

it("dictsort", function(done) {
it('dictsort', function(done) {
// no real foolproof way to test that a js obj has been transformed

@@ -77,8 +79,8 @@ // from unsorted -> sorted, as its enumeration ordering is undefined

items: {
"e": 1,
"d": 2,
"c": 3,
"a": 4,
"f": 5,
"b": 6
'e': 1,
'd': 2,
'c': 3,
'a': 4,
'f': 5,
'b': 6
}

@@ -92,9 +94,9 @@ },

items: {
"ABC": 6,
"ABc": 5,
"Abc": 1,
"abc": 2
'ABC': 6,
'ABc': 5,
'Abc': 1,
'abc': 2
}
},
"ABC,ABc,Abc,abc,");
'ABC,ABc,Abc,abc,');

@@ -105,6 +107,6 @@ // use values for sort

items: {
"a": 6,
"b": 5,
"c": 1,
"d": 2
'a': 6,
'b': 5,
'c': 1,
'd': 2
}

@@ -190,5 +192,14 @@ },

it('length handle undefined variables', function(done) {
equal('{{ blah|length }}', '0');
finish(done);
});
it('list', function(done) {
var person = {name: 'Joe', age: 83};
equal('{% for i in "foobar" | list %}{{ i }},{% endfor %}',
'f,o,o,b,a,r,');
equal('{% for pair in person | list %}{{ pair.key }}: {{ pair.value }} - {% endfor %}',
{person: person}, 'name: Joe - age: 83 - ');
equal('{% for i in [1, 2] | list %}{{ i }}{% endfor %}', '12');
finish(done);

@@ -213,2 +224,14 @@ });

it('rejectattr', function(done) {
var foods = [{tasty: true}, {tasty: false}, {tasty: true}];
equal('{{ foods | rejectattr("tasty") | length }}', {foods: foods}, '1');
finish(done);
});
it('selectattr', function(done) {
var foods = [{tasty: true}, {tasty: false}, {tasty: true}];
equal('{{ foods | selectattr("tasty") | length }}', {foods: foods}, '2');
finish(done);
});
it('replace', function(done) {

@@ -218,2 +241,7 @@ equal('{{ "aaabbbccc" | replace("a", "x") }}', 'xxxbbbccc');

equal('{{ "aaabbbbbccc" | replace("b", "y", 4) }}', 'aaayyyybccc');
equal('{{ "aabbbb" | replace(r/ab{2}/, "z") }}', 'azbb');
equal('{{ "aaaAAA" | replace(r/a/i, "z") }}', 'zaaAAA');
equal('{{ "aaaAAA" | replace(r/a/g, "z") }}', 'zzzAAA');
equal('{{ "aaaAAA" | replace(r/a/gi, "z") }}', 'zzzzzz');
finish(done);

@@ -324,3 +352,3 @@ });

'foo <a href="http://www.example.com/">' +
'http://www.example.com/</a> bar')
'http://www.example.com/</a> bar');

@@ -331,3 +359,2 @@ // additional tests

// http

@@ -391,2 +418,9 @@ equal('{{ "http://jinja.pocoo.org/docs/templates/" | urlize }}',

//periods in the text
equal('{{ "foo." | urlize }}', 'foo.');
equal('{{ "foo.foo" | urlize }}', 'foo.foo');
//markup in the text
equal('{{ "<b>what up</b>" | urlize }}', '<b>what up</b>');
finish(done);

@@ -393,0 +427,0 @@ });

(function() {
var expect, util, lib;
'use strict';
if(typeof require != 'undefined') {
var expect, util, lib, Environment, Loader, templatesPath;
if(typeof require !== 'undefined') {
expect = require('expect.js');
util = require('./util');
lib = require('../src/lib');
Environment = require('../src/environment').Environment;
Loader = require('../src/node-loaders').FileSystemLoader;
templatesPath = 'tests/templates';
}

@@ -13,2 +18,5 @@ else {

lib = nunjucks.require('lib');
Environment = nunjucks.Environment;
Loader = nunjucks.WebLoader;
templatesPath = '../templates';
}

@@ -47,2 +55,8 @@

equal('{% set cls = cycler("odd", "even") %}' +
'{{ cls.next() }}' +
'{{ cls.next() }}' +
'{{ cls.current }}',
'oddeveneven');
finish(done);

@@ -62,3 +76,15 @@ });

});
it('should allow addition of globals', function(done) {
var env = new Environment(new Loader(templatesPath));
env.addGlobal('hello', function(arg1) {
return 'Hello ' + arg1;
});
equal('{{ hello("World!") }}', 'Hello World!');
finish(done);
});
});
})();
(function() {
'use strict';
var expect, lib, lexer;
if(typeof require != 'undefined') {
if(typeof require !== 'undefined') {
expect = require('expect.js');

@@ -21,3 +23,3 @@ lib = require('../src/lib');

if(!ws) {
while(tok && tok.type == lexer.TOKEN_WHITESPACE) {
while(tok && tok.type === lexer.TOKEN_WHITESPACE) {
tok = tokens.nextToken();

@@ -75,2 +77,47 @@ }

it('should trim blocks', function () {
tokens = lexer.lex(' {% if true %}\n foo\n {% endif %}\n', {trimBlocks: true});
hasTokens(tokens,
[lexer.TOKEN_DATA, ' '],
lexer.TOKEN_BLOCK_START,
lexer.TOKEN_SYMBOL,
lexer.TOKEN_BOOLEAN,
lexer.TOKEN_BLOCK_END,
[lexer.TOKEN_DATA, ' foo\n '],
lexer.TOKEN_BLOCK_START,
lexer.TOKEN_SYMBOL,
lexer.TOKEN_BLOCK_END);
});
it('should lstrip and trim blocks', function () {
tokens = lexer.lex('test\n {% if true %}\n foo\n {% endif %}\n</div>', {
lstripBlocks: true,
trimBlocks: true
});
hasTokens(tokens,
[lexer.TOKEN_DATA, 'test\n'],
lexer.TOKEN_BLOCK_START,
lexer.TOKEN_SYMBOL,
lexer.TOKEN_BOOLEAN,
lexer.TOKEN_BLOCK_END,
[lexer.TOKEN_DATA, ' foo\n'],
lexer.TOKEN_BLOCK_START,
lexer.TOKEN_SYMBOL,
lexer.TOKEN_BLOCK_END,
[lexer.TOKEN_DATA, '</div>']);
});
it('should lstrip and not collapse whitespace between blocks', function () {
tokens = lexer.lex(' {% t %} {% t %}', {lstripBlocks: true});
hasTokens(tokens,
lexer.TOKEN_BLOCK_START,
lexer.TOKEN_SYMBOL,
lexer.TOKEN_BLOCK_END,
[lexer.TOKEN_DATA, ' '],
lexer.TOKEN_BLOCK_START,
lexer.TOKEN_SYMBOL,
lexer.TOKEN_BLOCK_END);
});
it('should parse variable start and end', function() {

@@ -86,2 +133,11 @@ tokens = lexer.lex('data {{ foo }} bar bizzle');

it('should treat the non-breaking space as valid whitespace', function() {
tokens = lexer.lex('{{\u00A0foo }}');
tok = tokens.nextToken();
tok = tokens.nextToken();
tok = tokens.nextToken();
expect(tok.type).to.be(lexer.TOKEN_SYMBOL);
expect(tok.value).to.be('foo');
});
it('should parse block start and end', function() {

@@ -98,3 +154,3 @@ tokens = lexer.lex('data {% foo %} bar bizzle');

it('should parse basic types', function() {
tokens = lexer.lex('{{ 3 4.5 true false foo "hello" \'boo\' }}');
tokens = lexer.lex('{{ 3 4.5 true false foo "hello" \'boo\' r/regex/ }}');
hasTokens(tokens,

@@ -109,2 +165,3 @@ lexer.TOKEN_VARIABLE_START,

lexer.TOKEN_STRING,
lexer.TOKEN_REGEX,
lexer.TOKEN_VARIABLE_END);

@@ -237,4 +294,82 @@ }),

lexer.TOKEN_DATA);
}),
it('should allow changing the variable start and end', function() {
tokens = lexer.lex('data {= var =}', {tags: {variableStart: '{=', variableEnd: '=}'}});
hasTokens(tokens,
lexer.TOKEN_DATA,
lexer.TOKEN_VARIABLE_START,
lexer.TOKEN_SYMBOL,
lexer.TOKEN_VARIABLE_END);
}),
it('should allow changing the block start and end', function() {
tokens = lexer.lex('{= =}', {tags: {blockStart: '{=', blockEnd: '=}'}});
hasTokens(tokens,
lexer.TOKEN_BLOCK_START,
lexer.TOKEN_BLOCK_END);
}),
it('should allow changing the variable start and end', function() {
tokens = lexer.lex('data {= var =}', {tags: {variableStart: '{=', variableEnd: '=}'}});
hasTokens(tokens,
lexer.TOKEN_DATA,
lexer.TOKEN_VARIABLE_START,
lexer.TOKEN_SYMBOL,
lexer.TOKEN_VARIABLE_END);
}),
it('should allow changing the comment start and end', function() {
tokens = lexer.lex('<!-- A comment! -->', {tags: {commentStart: '<!--', commentEnd: '-->'}});
hasTokens(tokens,
lexer.TOKEN_COMMENT);
}),
/**
* Test that this bug is fixed: https://github.com/mozilla/nunjucks/issues/235
*/
it('should have individual lexer tag settings for each environment', function() {
tokens = lexer.lex('{=', {tags: {variableStart: '{='}});
hasTokens(tokens, lexer.TOKEN_VARIABLE_START);
tokens = lexer.lex('{{');
hasTokens(tokens, lexer.TOKEN_VARIABLE_START);
tokens = lexer.lex('{{', {tags: {variableStart: '<<<'}});
hasTokens(tokens, lexer.TOKEN_DATA);
tokens = lexer.lex('{{');
hasTokens(tokens, lexer.TOKEN_VARIABLE_START);
});
it('should parse regular expressions', function() {
tokens = lexer.lex('{{ r/basic regex [a-z]/ }}');
hasTokens(tokens,
lexer.TOKEN_VARIABLE_START,
lexer.TOKEN_REGEX,
lexer.TOKEN_VARIABLE_END);
// A more complex regex with escaped slashes.
tokens = lexer.lex('{{ r/{a*b} \\/regex! [0-9]\\// }}');
hasTokens(tokens,
lexer.TOKEN_VARIABLE_START,
lexer.TOKEN_REGEX,
lexer.TOKEN_VARIABLE_END);
// This one has flags.
tokens = lexer.lex('{{ r/^x/gim }}');
hasTokens(tokens,
lexer.TOKEN_VARIABLE_START,
lexer.TOKEN_REGEX,
lexer.TOKEN_VARIABLE_END);
// This one has a valid flag then an invalid flag.
tokens = lexer.lex('{{ r/x$/iv }}');
hasTokens(tokens,
lexer.TOKEN_VARIABLE_START,
lexer.TOKEN_REGEX,
lexer.TOKEN_SYMBOL,
lexer.TOKEN_VARIABLE_END);
});
});
})();
(function() {
'use strict';
var expect, lib, nodes, parser;
if(typeof require != 'undefined') {
if(typeof require !== 'undefined') {
expect = require('expect.js');

@@ -16,3 +18,3 @@ lib = require('../src/lib');

}
function _isAST(node1, node2) {

@@ -76,2 +78,6 @@ // Compare ASTs

}
else if (ofield !== null && ofield instanceof RegExp) {
// This conditional check for RegExp is needed because /a/ != /a/
expect(String(ofield)).to.be(String(value));
}
else {

@@ -100,2 +106,6 @@ expect(ofield).to.be(value);

var type = ast[0];
// some nodes have fields (e.g. Compare.ops) which are plain arrays
if(type instanceof Array) {
return lib.map(ast, toNodes);
}
var F = function() {};

@@ -140,3 +150,3 @@ F.prototype = type.prototype;

isAST(parser.parse("{{ 'foo' }}"),
isAST(parser.parse('{{ \'foo\' }}'),
[nodes.Root,

@@ -146,3 +156,3 @@ [nodes.Output,

isAST(parser.parse("{{ true }}"),
isAST(parser.parse('{{ true }}'),
[nodes.Root,

@@ -152,3 +162,3 @@ [nodes.Output,

isAST(parser.parse("{{ false }}"),
isAST(parser.parse('{{ false }}'),
[nodes.Root,

@@ -158,10 +168,15 @@ [nodes.Output,

isAST(parser.parse("{{ foo }}"),
isAST(parser.parse('{{ foo }}'),
[nodes.Root,
[nodes.Output,
[nodes.Symbol, 'foo']]]);
isAST(parser.parse('{{ r/23/gi }}'),
[nodes.Root,
[nodes.Output,
[nodes.Literal, new RegExp('23', 'gi')]]]);
});
it('should parse aggregate types', function() {
isAST(parser.parse("{{ [1,2,3] }}"),
isAST(parser.parse('{{ [1,2,3] }}'),
[nodes.Root,

@@ -174,3 +189,3 @@ [nodes.Output,

isAST(parser.parse("{{ (1,2,3) }}"),
isAST(parser.parse('{{ (1,2,3) }}'),
[nodes.Root,

@@ -183,3 +198,3 @@ [nodes.Output,

isAST(parser.parse("{{ {foo: 1, 'two': 2} }}"),
isAST(parser.parse('{{ {foo: 1, \'two\': 2} }}'),
[nodes.Root,

@@ -204,2 +219,63 @@ [nodes.Output,

it('should parse operators', function() {
isAST(parser.parse('{{ x == y }}'),
[nodes.Root,
[nodes.Output,
[nodes.Compare,
[nodes.Symbol, 'x'],
[[nodes.CompareOperand, [nodes.Symbol, 'y'], '==']]]]]);
isAST(parser.parse('{{ x or y }}'),
[nodes.Root,
[nodes.Output,
[nodes.Or,
[nodes.Symbol, 'x'],
[nodes.Symbol, 'y']]]]);
isAST(parser.parse('{{ x in y }}'),
[nodes.Root,
[nodes.Output,
[nodes.In,
[nodes.Symbol, 'x'],
[nodes.Symbol, 'y']]]]);
isAST(parser.parse('{{ x not in y }}'),
[nodes.Root,
[nodes.Output,
[nodes.Not,
[nodes.In,
[nodes.Symbol, 'x'],
[nodes.Symbol, 'y']]]]]);
});
it('should parse operators with correct precedence', function() {
isAST(parser.parse('{{ x in y and z }}'),
[nodes.Root,
[nodes.Output,
[nodes.And,
[nodes.In,
[nodes.Symbol, 'x'],
[nodes.Symbol, 'y']],
[nodes.Symbol, 'z']]]]);
isAST(parser.parse('{{ x not in y or z }}'),
[nodes.Root,
[nodes.Output,
[nodes.Or,
[nodes.Not,
[nodes.In,
[nodes.Symbol, 'x'],
[nodes.Symbol, 'y']]],
[nodes.Symbol, 'z']]]]);
isAST(parser.parse('{{ x or y and z }}'),
[nodes.Root,
[nodes.Output,
[nodes.Or,
[nodes.Symbol, 'x'],
[nodes.And,
[nodes.Symbol, 'y'],
[nodes.Symbol, 'z']]]]]);
});
it('should parse blocks', function() {

@@ -220,2 +296,31 @@ var n = parser.parse('want some {% if hungry %}pizza{% else %}' +

it('should parse for loops', function() {
isAST(parser.parse('{% for x in [1, 2] %}{{ x }}{% endfor %}'),
[nodes.Root,
[nodes.For,
[nodes.Array,
[nodes.Literal, 1],
[nodes.Literal, 2]],
[nodes.Symbol, 'x'],
[nodes.NodeList,
[nodes.Output,
[nodes.Symbol, 'x']]]]]);
});
it('should parse for loops with else', function() {
isAST(parser.parse('{% for x in [] %}{{ x }}{% else %}empty{% endfor %}'),
[nodes.Root,
[nodes.For,
[nodes.Array],
[nodes.Symbol, 'x'],
[nodes.NodeList,
[nodes.Output,
[nodes.Symbol, 'x']]],
[nodes.NodeList,
[nodes.Output,
[nodes.TemplateData, 'empty']]]]]);
});
it('should parse filters', function() {

@@ -269,2 +374,50 @@ isAST(parser.parse('{{ foo | bar }}'),

it('should parse call blocks', function() {
var ast = parser.parse('{% call foo("bar") %}' +
'This is the caller' +
'{% endcall %}');
isAST(ast,
[nodes.Root,
[nodes.Output,
[nodes.FunCall,
[nodes.Symbol, 'foo'],
[nodes.NodeList,
[nodes.Literal, 'bar'],
[nodes.KeywordArgs,
[nodes.Pair,
[nodes.Symbol, 'caller'],
[nodes.Caller,
[nodes.Symbol, 'caller'],
[nodes.NodeList],
[nodes.NodeList,
[nodes.Output,
[nodes.TemplateData, 'This is the caller']]]]]]]]]]);
});
it('should parse call blocks with args', function() {
var ast = parser.parse('{% call(i) foo("bar", baz="foobar") %}' +
'This is {{ i }}' +
'{% endcall %}');
isAST(ast,
[nodes.Root,
[nodes.Output,
[nodes.FunCall,
[nodes.Symbol, 'foo'],
[nodes.NodeList,
[nodes.Literal, 'bar'],
[nodes.KeywordArgs,
[nodes.Pair,
[nodes.Symbol, 'baz'], [nodes.Literal, 'foobar']],
[nodes.Pair,
[nodes.Symbol, 'caller'],
[nodes.Caller,
[nodes.Symbol, 'caller'],
[nodes.NodeList, [nodes.Symbol, 'i']],
[nodes.NodeList,
[nodes.Output,
[nodes.TemplateData, 'This is ']],
[nodes.Output,
[nodes.Symbol, 'i']]]]]]]]]]);
});
it('should parse raw', function() {

@@ -303,3 +456,3 @@ isAST(parser.parse('{% raw %}hello {{ {% %} }}{% endraw %}'),

[nodes.FromImport,
[nodes.Literal, "foo/bar.html"],
[nodes.Literal, 'foo/bar.html'],
[nodes.NodeList,

@@ -428,3 +581,3 @@ [nodes.Symbol, 'baz'],

});
it('should parse custom tags', function() {

@@ -470,3 +623,3 @@

// Skip the name
parser.nextToken();
parser.nextToken();

@@ -483,3 +636,3 @@ args = parser.parseSignature(true);

new testargsExtension()];
isAST(parser.parse('{% testtag %}', extensions),

@@ -495,3 +648,3 @@ [nodes.Root,

[nodes.Output,
[nodes.TemplateData, "sdfd"]]]]]]);
[nodes.TemplateData, 'sdfd']]]]]]);

@@ -514,7 +667,7 @@ isAST(parser.parse('{% testblocktag %}{{ 123 }}{% endtestblocktag %}',

[nodes.Literal, 123],
[nodes.Literal, "abc"],
[nodes.KeywordArgs,
[nodes.Literal, 'abc'],
[nodes.KeywordArgs,
[nodes.Pair,
[nodes.Symbol, "foo"],
[nodes.Literal, "bar"]]]]]]);
[nodes.Symbol, 'foo'],
[nodes.Literal, 'bar']]]]]]);

@@ -521,0 +674,0 @@ isAST(parser.parse('{% testargs %}', extensions),

(function() {
'use strict';
var expect, util;
if(typeof require != 'undefined') {
if(typeof require !== 'undefined') {
expect = require('expect.js');

@@ -6,0 +8,0 @@ util = require('./util');

(function() {
'use strict';
var Environment, Template, loader, templatesPath, expect;
if(typeof require != 'undefined') {
if(typeof require !== 'undefined') {
Environment = require('../src/environment').Environment;

@@ -53,2 +55,7 @@ Template = require('../src/environment').Template;

function normEOL(str) {
if (!str) return str;
return str.replace(/\r\n|\r/g, "\n");
}
function render(str, ctx, opts, cb) {

@@ -72,3 +79,3 @@ if(!opts) {

e.addFilter(name, opts.filters[name]);
}
}
}

@@ -79,3 +86,3 @@

e.addFilter(name, opts.asyncFilters[name], true);
}
}
}

@@ -99,7 +106,7 @@

cb(err, res);
cb(err, normEOL(res));
doneAsyncs++;
if(numAsyncs == doneAsyncs && doneHandler) {
if(numAsyncs === doneAsyncs && doneHandler) {
doneHandler();

@@ -111,6 +118,7 @@ }

if(typeof module != 'undefined') {
if(typeof module !== 'undefined') {
module.exports.render = render;
module.exports.equal = equal;
module.exports.finish = finish;
module.exports.normEOL = normEOL;
}

@@ -121,5 +129,6 @@ else {

equal: equal,
finish: finish
finish: finish,
normEOL: normEOL
};
}
})();

@@ -429,5 +429,5 @@ ---

{{ forms.label('Username') }}
{{ forms.input('user') }}
{{ forms.field('user') }}
{{ forms.label('Password') }}
{{ forms.input('pass', type='password') }}
{{ forms.field('pass', type='password') }}
```

@@ -438,8 +438,8 @@

```jinja
{% from "forms.html" import input, label as description %}
{% from "forms.html" import field, label as description %}
{{ description('Username') }}
{{ input('user') }}
{{ field('user') }}
{{ description('Password') }}
{{ input('pass', type='password') }}
{{ field('pass', type='password') }}
```

@@ -477,3 +477,3 @@

jinja2 uses Python's keyword arguments support to allow keyword arguments in functions, filters, and macros. Nunjucks supports keyword arguments as well by introduction a new calling convention.
jinja2 uses Python's keyword arguments support to allow keyword arguments in functions, filters, and macros. Nunjucks supports keyword arguments as well by introducing a new calling convention.

@@ -728,3 +728,3 @@ Keyword arguments look like this:

* [rejectattr](http://jinja.pocoo.org/docs/templates/#rejectattr) (only the single-argument form)
* [replace](http://jinja.pocoo.org/docs/templates/#replace) (the first argument can take a regular expression)
* [replace](http://jinja.pocoo.org/docs/templates/#replace) (the first argument can take a JS regular expression)
* [reverse](http://jinja.pocoo.org/docs/templates/#reverse)

@@ -731,0 +731,0 @@ * [round](http://jinja.pocoo.org/docs/templates/#round)

{
"name": "nunjucks",
"description": "A powerful templating engine with inheritance, asynchronous control, and more (jinja2 inspired)",
"version": "1.3.0",
"version": "1.3.1",
"author": "James Long <longster@gmail.com>",

@@ -6,0 +6,0 @@ "dependencies": {

@@ -12,9 +12,4 @@ # Nunjucks

(View the [CHANGELOG](https://github.com/mozilla/nunjucks/blob/master/CHANGELOG.md))
(View the [CHANGELOG](https://github.com/mozilla/nunjucks/releases))
**Note**: 1.0 was just pushed out, so if you are currently using
nunjucks read the CHANGELOG. Especially important: the client-side
browser filenames have changed. [Read
here](http://mozilla.github.io/nunjucks/getting-started.html).
## Documentation

@@ -21,0 +16,0 @@

@@ -1,3 +0,1 @@

'use strict';
if(typeof window === 'undefined' || window !== this) {

@@ -4,0 +2,0 @@ module.exports = require('./node-loaders');

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc